Remove timeframe from strategy (#13)

This commit is contained in:
Oda
2025-02-26 17:24:59 +07:00
committed by GitHub
parent 298b666a0b
commit 4302bb8435
39 changed files with 299 additions and 288 deletions

View File

@@ -206,7 +206,7 @@ public class BotController : ControllerBase
Timeframe = item.Timeframe, Timeframe = item.Timeframe,
Ticker = item.Ticker, Ticker = item.Ticker,
AccountName = item.AccountName, AccountName = item.AccountName,
Scenario = item.Scenario, Scenario = item.ScenarioName,
IsForWatchingOnly = item.IsForWatchingOnly, IsForWatchingOnly = item.IsForWatchingOnly,
BotType = item.BotType, BotType = item.BotType,
MoneyManagement = item.MoneyManagement MoneyManagement = item.MoneyManagement

View File

@@ -46,9 +46,9 @@ public class ScenarioController : ControllerBase
/// <param name="strategies">A list of strategy names to include in the scenario.</param> /// <param name="strategies">A list of strategy names to include in the scenario.</param>
/// <returns>The created scenario.</returns> /// <returns>The created scenario.</returns>
[HttpPost] [HttpPost]
public ActionResult<Scenario> CreateScenario(string name, List<string> strategies) public ActionResult<Scenario> CreateScenario(string name, List<string> strategies, int? loopbackPeriod = null)
{ {
return Ok(_scenarioService.CreateScenario(name, strategies)); return Ok(_scenarioService.CreateScenario(name, strategies, loopbackPeriod));
} }
/// <summary> /// <summary>
@@ -92,7 +92,6 @@ public class ScenarioController : ControllerBase
[Route("strategy")] [Route("strategy")]
public ActionResult<Strategy> CreateStrategy( public ActionResult<Strategy> CreateStrategy(
StrategyType strategyType, StrategyType strategyType,
Timeframe timeframe,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -105,7 +104,6 @@ public class ScenarioController : ControllerBase
{ {
return Ok(_scenarioService.CreateStrategy( return Ok(_scenarioService.CreateStrategy(
strategyType, strategyType,
timeframe,
name, name,
period, period,
fastPeriods, fastPeriods,

View File

@@ -51,7 +51,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var scenario = new Scenario("FlippingScenario"); var scenario = new Scenario("FlippingScenario");
var strategy = ScenarioHelpers.BuildStrategy(StrategyType.RsiDivergence, timeframe, "RsiDiv", period: 14); var strategy = ScenarioHelpers.BuildStrategy(StrategyType.RsiDivergence, "RsiDiv", period: 14);
scenario.AddStrategy(strategy); scenario.AddStrategy(strategy);
var localCandles = var localCandles =
FileHelpers.ReadJson<List<Candle>>($"{ticker.ToString()}-{timeframe.ToString()}-candles.json"); FileHelpers.ReadJson<List<Candle>>($"{ticker.ToString()}-{timeframe.ToString()}-candles.json");
@@ -83,7 +83,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var scenario = new Scenario("ScalpingScenario"); var scenario = new Scenario("ScalpingScenario");
var strategy = ScenarioHelpers.BuildStrategy(StrategyType.RsiDivergence, timeframe, "RsiDiv", period: 5); var strategy = ScenarioHelpers.BuildStrategy(StrategyType.RsiDivergence, "RsiDiv", period: 5);
scenario.AddStrategy(strategy); scenario.AddStrategy(strategy);
// Act // Act
@@ -104,7 +104,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var scenario = new Scenario("ScalpingScenario"); var scenario = new Scenario("ScalpingScenario");
var strategy = ScenarioHelpers.BuildStrategy(StrategyType.MacdCross, timeframe, "RsiDiv", fastPeriods: 12, var strategy = ScenarioHelpers.BuildStrategy(StrategyType.MacdCross, "RsiDiv", fastPeriods: 12,
slowPeriods: 26, signalPeriods: 9); slowPeriods: 26, signalPeriods: 9);
scenario.AddStrategy(strategy); scenario.AddStrategy(strategy);
@@ -163,7 +163,7 @@ namespace Managing.Application.Tests
Parallel.For(periodRange[0], periodRange[1], options, i => Parallel.For(periodRange[0], periodRange[1], options, i =>
{ {
var scenario = new Scenario("ScalpingScenario"); var scenario = new Scenario("ScalpingScenario");
var strategy = ScenarioHelpers.BuildStrategy(strategyType, timeframe, "RsiDiv", period: i); var strategy = ScenarioHelpers.BuildStrategy(strategyType, "RsiDiv", period: i);
scenario.AddStrategy(strategy); scenario.AddStrategy(strategy);
// -0.5 to -5 // -0.5 to -5
@@ -272,7 +272,7 @@ namespace Managing.Application.Tests
return; return;
var scenario = new Scenario("ScalpingScenario"); var scenario = new Scenario("ScalpingScenario");
var strategy = ScenarioHelpers.BuildStrategy(strategyType, timeframe, "RsiDiv", fastPeriods: 12, var strategy = ScenarioHelpers.BuildStrategy(strategyType, "RsiDiv", fastPeriods: 12,
slowPeriods: 26, signalPeriods: 9); slowPeriods: 26, signalPeriods: 9);
scenario.AddStrategy(strategy); scenario.AddStrategy(strategy);

View File

@@ -22,7 +22,7 @@ namespace Managing.Application.Tests
{ {
var account = GetAccount(exchange); var account = GetAccount(exchange);
// Arrange // Arrange
var rsiStrategy = new RSIDivergenceStrategy("unittest", timeframe, 5); var rsiStrategy = new RSIDivergenceStrategy("unittest", 5);
var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(-50), timeframe).Result; var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(-50), timeframe).Result;
var resultSignal = new List<Signal>(); var resultSignal = new List<Signal>();
@@ -56,7 +56,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var rsiStrategy = new RSIDivergenceStrategy("unittest", timeframe, 5); var rsiStrategy = new RSIDivergenceStrategy("unittest", 5);
var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(-50), timeframe).Result; var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(-50), timeframe).Result;
var resultSignal = new List<Signal>(); var resultSignal = new List<Signal>();
@@ -83,7 +83,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var rsiStrategy = new MacdCrossStrategy("unittest", timeframe, 12, 26, 9); var rsiStrategy = new MacdCrossStrategy("unittest", 12, 26, 9);
var candles = await _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe); var candles = await _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe);
var resultSignal = new List<Signal>(); var resultSignal = new List<Signal>();
@@ -110,7 +110,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var superTrendStrategy = new SuperTrendStrategy("unittest", timeframe, 10, 3); var superTrendStrategy = new SuperTrendStrategy("unittest", 10, 3);
var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe).Result; var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe).Result;
var resultSignal = new List<Signal>(); var resultSignal = new List<Signal>();
@@ -137,7 +137,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var chandelierExitStrategy = new ChandelierExitStrategy("unittest", timeframe, 22, 3); var chandelierExitStrategy = new ChandelierExitStrategy("unittest", 22, 3);
var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe).Result; var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe).Result;
var resultSignal = new List<Signal>(); var resultSignal = new List<Signal>();
@@ -164,7 +164,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var emaTrendSrategy = new EmaTrendStrategy("unittest", timeframe, 200); var emaTrendSrategy = new EmaTrendStrategy("unittest", 200);
var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe).Result; var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe).Result;
var resultSignal = new List<Signal>(); var resultSignal = new List<Signal>();
@@ -192,7 +192,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var stochRsiStrategy = new StochRsiTrendStrategy("unittest", timeframe, 14, 14, 3, 1); var stochRsiStrategy = new StochRsiTrendStrategy("unittest", 14, 14, 3, 1);
var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe).Result; var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe).Result;
var resultSignal = new List<Signal>(); var resultSignal = new List<Signal>();

View File

@@ -7,13 +7,13 @@ namespace Managing.Application.Abstractions
public interface IScenarioService public interface IScenarioService
{ {
IEnumerable<Scenario> GetScenarios(); IEnumerable<Scenario> GetScenarios();
Scenario CreateScenario(string name, List<string> strategies); Scenario CreateScenario(string name, List<string> strategies, int? loopbackPeriod = 1);
IEnumerable<Strategy> GetStrategies(); IEnumerable<Strategy> GetStrategies();
bool DeleteStrategy(string name); bool DeleteStrategy(string name);
bool DeleteScenario(string name); bool DeleteScenario(string name);
Scenario GetScenario(string name); Scenario GetScenario(string name);
Strategy CreateStrategy(StrategyType type, Strategy CreateStrategy(StrategyType type,
Timeframe timeframe,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -23,6 +23,7 @@ namespace Managing.Application.Abstractions
int? stochPeriods = null, int? stochPeriods = null,
int? smoothPeriods = null, int? smoothPeriods = null,
int? cyclePeriods = null); int? cyclePeriods = null);
bool DeleteStrategies(); bool DeleteStrategies();
bool DeleteScenarios(); bool DeleteScenarios();
} }

View File

@@ -17,7 +17,7 @@ namespace Managing.Application.Abstractions
Timeframe Timeframe { get; set; } Timeframe Timeframe { get; set; }
HashSet<IStrategy> Strategies { get; set; } HashSet<IStrategy> Strategies { get; set; }
Ticker Ticker { get; } Ticker Ticker { get; }
string Scenario { get; } string ScenarioName { get; }
string AccountName { get; } string AccountName { get; }
bool IsForWatchingOnly { get; set; } bool IsForWatchingOnly { get; set; }
MoneyManagement MoneyManagement { get; set; } MoneyManagement MoneyManagement { get; set; }
@@ -31,5 +31,6 @@ namespace Managing.Application.Abstractions
decimal GetProfitAndLoss(); decimal GetProfitAndLoss();
decimal GetTotalFees(); decimal GetTotalFees();
void LoadStrategies(IEnumerable<IStrategy> strategies); void LoadStrategies(IEnumerable<IStrategy> strategies);
void LoadScenario(string scenarioName);
} }
} }

View File

@@ -58,7 +58,7 @@ namespace Managing.Application.Backtesting
{ {
var scalpingBot = _botFactory.CreateBacktestScalpingBot(account.Name, moneyManagement, ticker, "scenario", var scalpingBot = _botFactory.CreateBacktestScalpingBot(account.Name, moneyManagement, ticker, "scenario",
timeframe, isForWatchingOnly); timeframe, isForWatchingOnly);
scalpingBot.LoadStrategies(ScenarioHelpers.GetStrategiesFromScenario(scenario)); scalpingBot.LoadScenario(scenario.Name);
var candles = initialCandles ?? GetCandles(account, ticker, timeframe, days); var candles = initialCandles ?? GetCandles(account, ticker, timeframe, days);
var result = GetBacktestingResult(ticker, scenario, timeframe, scalpingBot, candles, balance, account, var result = GetBacktestingResult(ticker, scenario, timeframe, scalpingBot, candles, balance, account,
moneyManagement); moneyManagement);
@@ -88,8 +88,7 @@ namespace Managing.Application.Backtesting
{ {
var flippingBot = _botFactory.CreateBacktestFlippingBot(account.Name, moneyManagement, ticker, "scenario", var flippingBot = _botFactory.CreateBacktestFlippingBot(account.Name, moneyManagement, ticker, "scenario",
timeframe, false); timeframe, false);
var strategy = ScenarioHelpers.GetStrategiesFromScenario(scenario); flippingBot.LoadScenario(scenario.Name);
flippingBot.LoadStrategies(ScenarioHelpers.GetStrategiesFromScenario(scenario));
var candles = initialCandles ?? GetCandles(account, ticker, timeframe, days); var candles = initialCandles ?? GetCandles(account, ticker, timeframe, days);
var result = GetBacktestingResult(ticker, scenario, timeframe, flippingBot, candles, balance, account, var result = GetBacktestingResult(ticker, scenario, timeframe, flippingBot, candles, balance, account,
moneyManagement); moneyManagement);
@@ -107,7 +106,7 @@ namespace Managing.Application.Backtesting
var ticker = MiscExtensions.ParseEnum<Ticker>(candles.FirstOrDefault().Ticker); var ticker = MiscExtensions.ParseEnum<Ticker>(candles.FirstOrDefault().Ticker);
var bot = _botFactory.CreateBacktestScalpingBot(account.Name, moneyManagement, ticker, "scenario", var bot = _botFactory.CreateBacktestScalpingBot(account.Name, moneyManagement, ticker, "scenario",
timeframe, false); timeframe, false);
bot.LoadStrategies(ScenarioHelpers.GetStrategiesFromScenario(scenario)); bot.LoadScenario(scenario.Name);
var result = GetBacktestingResult(ticker, scenario, timeframe, bot, candles, balance, account, var result = GetBacktestingResult(ticker, scenario, timeframe, bot, candles, balance, account,
moneyManagement); moneyManagement);
return result; return result;
@@ -119,6 +118,7 @@ namespace Managing.Application.Backtesting
var ticker = MiscExtensions.ParseEnum<Ticker>(candles.FirstOrDefault().Ticker); var ticker = MiscExtensions.ParseEnum<Ticker>(candles.FirstOrDefault().Ticker);
var bot = _botFactory.CreateBacktestFlippingBot(account.Name, moneyManagement, ticker, "scenario", var bot = _botFactory.CreateBacktestFlippingBot(account.Name, moneyManagement, ticker, "scenario",
timeframe, false); timeframe, false);
bot.LoadScenario(scenario.Name);
var result = GetBacktestingResult(ticker, scenario, timeframe, bot, candles, balance, account, var result = GetBacktestingResult(ticker, scenario, timeframe, bot, candles, balance, account,
moneyManagement); moneyManagement);
return result; return result;

View File

@@ -1,8 +1,8 @@
using Managing.Application.Abstractions; using Managing.Application.Abstractions;
using Microsoft.Extensions.Logging;
using static Managing.Common.Enums;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Domain.MoneyManagements; using Managing.Domain.MoneyManagements;
using Microsoft.Extensions.Logging;
using static Managing.Common.Enums;
namespace Managing.Application.Bots namespace Managing.Application.Bots
{ {
@@ -11,7 +11,7 @@ namespace Managing.Application.Bots
public FlippingBot(string accountName, public FlippingBot(string accountName,
MoneyManagement moneyManagement, MoneyManagement moneyManagement,
string name, string name,
string scenario, string scenarioName,
IExchangeService exchangeService, IExchangeService exchangeService,
Ticker ticker, Ticker ticker,
ITradingService tradingService, ITradingService tradingService,
@@ -26,7 +26,7 @@ namespace Managing.Application.Bots
moneyManagement, moneyManagement,
name, name,
ticker, ticker,
scenario, scenarioName,
exchangeService, exchangeService,
logger, logger,
tradingService, tradingService,

View File

@@ -1,8 +1,8 @@
using Managing.Application.Abstractions; using Managing.Application.Abstractions;
using Microsoft.Extensions.Logging;
using static Managing.Common.Enums;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Domain.MoneyManagements; using Managing.Domain.MoneyManagements;
using Microsoft.Extensions.Logging;
using static Managing.Common.Enums;
namespace Managing.Application.Bots namespace Managing.Application.Bots
{ {
@@ -11,7 +11,7 @@ namespace Managing.Application.Bots
public ScalpingBot(string accountName, public ScalpingBot(string accountName,
MoneyManagement moneyManagement, MoneyManagement moneyManagement,
string name, string name,
string scenario, string scenarioName,
IExchangeService exchangeService, IExchangeService exchangeService,
Ticker ticker, Ticker ticker,
ITradingService tradingService, ITradingService tradingService,
@@ -26,7 +26,7 @@ namespace Managing.Application.Bots
moneyManagement, moneyManagement,
name, name,
ticker, ticker,
scenario, scenarioName,
exchangeService, exchangeService,
logger, logger,
tradingService, tradingService,

View File

@@ -33,7 +33,7 @@ public class TradingBot : Bot, ITradingBot
public HashSet<Signal> Signals { get; set; } public HashSet<Signal> Signals { get; set; }
public List<Position> Positions { get; set; } public List<Position> Positions { get; set; }
public Ticker Ticker { get; set; } public Ticker Ticker { get; set; }
public string Scenario { get; set; } public string ScenarioName { get; set; }
public string AccountName { get; set; } public string AccountName { get; set; }
public MoneyManagement MoneyManagement { get; set; } public MoneyManagement MoneyManagement { get; set; }
public Timeframe Timeframe { get; set; } public Timeframe Timeframe { get; set; }
@@ -44,6 +44,7 @@ public class TradingBot : Bot, ITradingBot
public int PreloadedCandlesCount { get; set; } public int PreloadedCandlesCount { get; set; }
public BotType BotType { get; set; } public BotType BotType { get; set; }
public decimal Fee { get; set; } public decimal Fee { get; set; }
public Scenario Scenario { get; set; }
public Dictionary<DateTime, decimal> WalletBalances { get; set; } public Dictionary<DateTime, decimal> WalletBalances { get; set; }
public TradingBot( public TradingBot(
@@ -51,7 +52,7 @@ public class TradingBot : Bot, ITradingBot
MoneyManagement moneyManagement, MoneyManagement moneyManagement,
string name, string name,
Ticker ticker, Ticker ticker,
string scenario, string scenarioName,
IExchangeService exchangeService, IExchangeService exchangeService,
ILogger<TradingBot> logger, ILogger<TradingBot> logger,
ITradingService tradingService, ITradingService tradingService,
@@ -75,7 +76,7 @@ public class TradingBot : Bot, ITradingBot
AccountName = accountName; AccountName = accountName;
MoneyManagement = moneyManagement; MoneyManagement = moneyManagement;
Ticker = ticker; Ticker = ticker;
Scenario = scenario; ScenarioName = scenarioName;
Timeframe = timeframe; Timeframe = timeframe;
IsForBacktest = isForBacktest; IsForBacktest = isForBacktest;
Logger = logger; Logger = logger;
@@ -101,7 +102,7 @@ public class TradingBot : Bot, ITradingBot
if (!IsForBacktest) if (!IsForBacktest)
{ {
LoadScenario(); LoadScenario(ScenarioName);
await PreloadCandles(); await PreloadCandles();
await CancelAllOrders(); await CancelAllOrders();
@@ -135,9 +136,9 @@ public class TradingBot : Bot, ITradingBot
} }
} }
public void LoadScenario() public void LoadScenario(string scenarioName)
{ {
var scenario = TradingService.GetScenarioByName(Scenario); var scenario = TradingService.GetScenarioByName(scenarioName);
if (scenario == null) if (scenario == null)
{ {
Logger.LogWarning("No scenario found for this scenario name"); Logger.LogWarning("No scenario found for this scenario name");
@@ -145,6 +146,7 @@ public class TradingBot : Bot, ITradingBot
} }
else else
{ {
Scenario = scenario;
LoadStrategies(ScenarioHelpers.GetStrategiesFromScenario(scenario)); LoadStrategies(ScenarioHelpers.GetStrategiesFromScenario(scenario));
} }
} }
@@ -158,10 +160,13 @@ public class TradingBot : Bot, ITradingBot
} }
public async Task Run() public async Task Run()
{
if (!IsForBacktest)
{ {
Logger.LogInformation($"____________________{Name}____________________"); Logger.LogInformation($"____________________{Name}____________________");
Logger.LogInformation( Logger.LogInformation(
$"Time : {DateTime.Now} - Server time {DateTime.Now.ToUniversalTime()} - Bot : {Name} - Type {BotType} - Ticker : {Ticker}"); $"Time : {DateTime.Now} - Server time {DateTime.Now.ToUniversalTime()} - Bot : {Name} - Type {BotType} - Ticker : {Ticker}");
}
var previousLastCandle = OptimizedCandles.LastOrDefault(); var previousLastCandle = OptimizedCandles.LastOrDefault();
@@ -213,7 +218,7 @@ public class TradingBot : Bot, ITradingBot
private async Task UpdateSignals(FixedSizeQueue<Candle> candles) private async Task UpdateSignals(FixedSizeQueue<Candle> candles)
{ {
var signal = TradingBox.GetSignal(candles.ToHashSet(), Strategies, Signals); var signal = TradingBox.GetSignal(candles.ToHashSet(), Strategies, Signals, Scenario.LoopbackPeriod);
if (signal == null) return; if (signal == null) return;
@@ -231,7 +236,7 @@ public class TradingBot : Bot, ITradingBot
if (IsForWatchingOnly || (ExecutionCount < 1 && !IsForBacktest)) if (IsForWatchingOnly || (ExecutionCount < 1 && !IsForBacktest))
signal.Status = SignalStatus.Expired; signal.Status = SignalStatus.Expired;
var signalText = $"{Scenario} trigger a signal. Signal told you " + var signalText = $"{ScenarioName} trigger a signal. Signal told you " +
$"to {signal.Direction} {Ticker} on {Timeframe}. The confidence in this signal is {signal.Confidence}. Identifier : {signal.Identifier}"; $"to {signal.Direction} {Ticker} on {Timeframe}. The confidence in this signal is {signal.Confidence}. Identifier : {signal.Identifier}";
Logger.LogInformation(signalText); Logger.LogInformation(signalText);
@@ -726,7 +731,7 @@ public class TradingBot : Bot, ITradingBot
Positions = Positions, Positions = Positions,
Timeframe = Timeframe, Timeframe = Timeframe,
Ticker = Ticker, Ticker = Ticker,
Scenario = Scenario, ScenarioName = ScenarioName,
AccountName = AccountName, AccountName = AccountName,
IsForWatchingOnly = IsForWatchingOnly, IsForWatchingOnly = IsForWatchingOnly,
WalletBalances = WalletBalances, WalletBalances = WalletBalances,
@@ -744,7 +749,7 @@ public class TradingBot : Bot, ITradingBot
MoneyManagement = data.MoneyManagement; MoneyManagement = data.MoneyManagement;
Timeframe = data.Timeframe; Timeframe = data.Timeframe;
Ticker = data.Ticker; Ticker = data.Ticker;
Scenario = data.Scenario; ScenarioName = data.ScenarioName;
AccountName = data.AccountName; AccountName = data.AccountName;
IsForWatchingOnly = data.IsForWatchingOnly; IsForWatchingOnly = data.IsForWatchingOnly;
} }
@@ -758,7 +763,7 @@ public class TradingBotBackup
public List<Position> Positions { get; set; } public List<Position> Positions { get; set; }
public Timeframe Timeframe { get; set; } public Timeframe Timeframe { get; set; }
public Ticker Ticker { get; set; } public Ticker Ticker { get; set; }
public string Scenario { get; set; } public string ScenarioName { get; set; }
public string AccountName { get; set; } public string AccountName { get; set; }
public bool IsForWatchingOnly { get; set; } public bool IsForWatchingOnly { get; set; }
public Dictionary<DateTime, decimal> WalletBalances { get; set; } public Dictionary<DateTime, decimal> WalletBalances { get; set; }

View File

@@ -128,7 +128,7 @@ namespace Managing.Application.ManageBot
scalpingBotData.MoneyManagement, scalpingBotData.MoneyManagement,
backupBot.Name, backupBot.Name,
scalpingBotData.Ticker, scalpingBotData.Ticker,
scalpingBotData.Scenario, scalpingBotData.ScenarioName,
scalpingBotData.Timeframe, scalpingBotData.Timeframe,
scalpingBotData.IsForWatchingOnly); scalpingBotData.IsForWatchingOnly);
botTask = Task.Run(() => ((ITradingBot)bot).Start()); botTask = Task.Run(() => ((ITradingBot)bot).Start());
@@ -140,7 +140,7 @@ namespace Managing.Application.ManageBot
flippingBotData.MoneyManagement, flippingBotData.MoneyManagement,
backupBot.Name, backupBot.Name,
flippingBotData.Ticker, flippingBotData.Ticker,
flippingBotData.Scenario, flippingBotData.ScenarioName,
flippingBotData.Timeframe, flippingBotData.Timeframe,
flippingBotData.IsForWatchingOnly); flippingBotData.IsForWatchingOnly);
botTask = Task.Run(() => ((ITradingBot)bot).Start()); botTask = Task.Run(() => ((ITradingBot)bot).Start());

View File

@@ -19,9 +19,9 @@ namespace Managing.Application.Scenarios
_tradingService = tradingService; _tradingService = tradingService;
} }
public Scenario CreateScenario(string name, List<string> strategies) public Scenario CreateScenario(string name, List<string> strategies, int? loopbackPeriod = 1)
{ {
var scenario = new Scenario(name); var scenario = new Scenario(name, loopbackPeriod);
foreach (var strategy in strategies) foreach (var strategy in strategies)
{ {
@@ -43,7 +43,6 @@ namespace Managing.Application.Scenarios
public Strategy CreateStrategy( public Strategy CreateStrategy(
StrategyType type, StrategyType type,
Timeframe timeframe,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -56,7 +55,6 @@ namespace Managing.Application.Scenarios
{ {
var strategy = ScenarioHelpers.BuildStrategy( var strategy = ScenarioHelpers.BuildStrategy(
type, type,
timeframe,
name, name,
period, period,
fastPeriods, fastPeriods,

View File

@@ -62,7 +62,7 @@ public class SettingsService : ISettingsService
SetupMoneyManagementsSeed(Timeframe.FifteenMinutes); SetupMoneyManagementsSeed(Timeframe.FifteenMinutes);
SetupMoneyManagementsSeed(Timeframe.OneHour); SetupMoneyManagementsSeed(Timeframe.OneHour);
SetupMoneyManagementsSeed(Timeframe.OneDay); SetupMoneyManagementsSeed(Timeframe.OneDay);
SetupScenariosSeed(Timeframe.FifteenMinutes); SetupScenariosSeed();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -82,30 +82,29 @@ public class SettingsService : ISettingsService
Leverage = 1, Leverage = 1,
StopLoss = 0.021m, StopLoss = 0.021m,
TakeProfit = 0.042m, TakeProfit = 0.042m,
Name = $"{timeframe} Money Management" Name = $"{timeframe}-MediumRisk",
}; };
await _moneyManagementService.CreateOrUpdateMoneyManagement(moneyManagement); await _moneyManagementService.CreateOrUpdateMoneyManagement(moneyManagement);
} }
private void SetupScenariosSeed(Timeframe timeframe) private void SetupScenariosSeed()
{ {
SetupMacd(timeframe); SetupMacd();
SetupRsiDiv(timeframe); SetupRsiDiv();
SetupRsiDivConfirm(timeframe); SetupRsiDivConfirm();
SetupSuperTrend(timeframe); SetupSuperTrend();
SetupChandelierExit(timeframe); SetupChandelierExit();
SetupStochRsiTrend(timeframe); SetupStochRsiTrend();
SetupStochSTCTrend(timeframe); SetupStochSTCTrend();
SetupEmaTrend(timeframe); SetupEmaTrend();
SetupEmaCross(timeframe); SetupEmaCross();
} }
private void SetupStochSTCTrend(Timeframe timeframe) private void SetupStochSTCTrend()
{ {
var name = "STCTrend"; var name = "STCTrend";
var strategy = _scenarioService.CreateStrategy(StrategyType.Stc, var strategy = _scenarioService.CreateStrategy(StrategyType.Stc,
timeframe,
name, name,
fastPeriods: 23, fastPeriods: 23,
slowPeriods: 50, slowPeriods: 50,
@@ -113,11 +112,10 @@ public class SettingsService : ISettingsService
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
} }
private void SetupMacd(Timeframe timeframe) private void SetupMacd()
{ {
var name = "MacdCross"; var name = "MacdCross";
var strategy = _scenarioService.CreateStrategy(StrategyType.MacdCross, var strategy = _scenarioService.CreateStrategy(StrategyType.MacdCross,
timeframe,
name, name,
fastPeriods: 12, fastPeriods: 12,
slowPeriods: 26, slowPeriods: 26,
@@ -125,53 +123,48 @@ public class SettingsService : ISettingsService
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
} }
private void SetupRsiDiv(Timeframe timeframe) private void SetupRsiDiv()
{ {
var name = "RsiDiv6"; var name = "RsiDiv6";
var strategy = _scenarioService.CreateStrategy(StrategyType.RsiDivergence, var strategy = _scenarioService.CreateStrategy(StrategyType.RsiDivergence,
timeframe,
name, name,
period: 6); period: 6);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
} }
private void SetupRsiDivConfirm(Timeframe timeframe) private void SetupRsiDivConfirm()
{ {
var name = "RsiDivConfirm6"; var name = "RsiDivConfirm6";
var strategy = _scenarioService.CreateStrategy(StrategyType.RsiDivergenceConfirm, var strategy = _scenarioService.CreateStrategy(StrategyType.RsiDivergenceConfirm,
timeframe,
name, name,
period: 6); period: 6);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
} }
private void SetupSuperTrend(Timeframe timeframe) private void SetupSuperTrend()
{ {
var name = "SuperTrend"; var name = "SuperTrend";
var strategy = _scenarioService.CreateStrategy(StrategyType.SuperTrend, var strategy = _scenarioService.CreateStrategy(StrategyType.SuperTrend,
timeframe,
name, name,
period: 10, period: 10,
multiplier: 3); multiplier: 3);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
} }
private void SetupChandelierExit(Timeframe timeframe) private void SetupChandelierExit()
{ {
var name = "ChandelierExit"; var name = "ChandelierExit";
var strategy = _scenarioService.CreateStrategy(StrategyType.ChandelierExit, var strategy = _scenarioService.CreateStrategy(StrategyType.ChandelierExit,
timeframe,
name, name,
period: 22, period: 22,
multiplier: 3); multiplier: 3);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
} }
private void SetupStochRsiTrend(Timeframe timeframe) private void SetupStochRsiTrend()
{ {
var name = "StochRsiTrend"; var name = "StochRsiTrend";
var strategy = _scenarioService.CreateStrategy(StrategyType.StochRsiTrend, var strategy = _scenarioService.CreateStrategy(StrategyType.StochRsiTrend,
timeframe,
name, name,
period: 14, period: 14,
stochPeriods: 14, stochPeriods: 14,
@@ -180,21 +173,19 @@ public class SettingsService : ISettingsService
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
} }
private void SetupEmaTrend(Timeframe timeframe) private void SetupEmaTrend()
{ {
var name = "Ema200Trend"; var name = "Ema200Trend";
var strategy = _scenarioService.CreateStrategy(StrategyType.EmaTrend, var strategy = _scenarioService.CreateStrategy(StrategyType.EmaTrend,
timeframe,
name, name,
period: 200); period: 200);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
} }
private void SetupEmaCross(Timeframe timeframe) private void SetupEmaCross()
{ {
var name = "Ema200Cross"; var name = "Ema200Cross";
var strategy = _scenarioService.CreateStrategy(StrategyType.EmaCross, var strategy = _scenarioService.CreateStrategy(StrategyType.EmaCross,
timeframe,
name, name,
period: 200); period: 200);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });

View File

@@ -30,7 +30,7 @@ public class RsiDiv : FlowBase
MapParameters(); MapParameters();
var candles = JsonConvert.DeserializeObject<HashSet<Candle>>(input); var candles = JsonConvert.DeserializeObject<HashSet<Candle>>(input);
var strategy = new RSIDivergenceStrategy(Name, RsiDivParameters.Timeframe, RsiDivParameters.Period); var strategy = new RSIDivergenceStrategy(Name, RsiDivParameters.Period);
strategy.UpdateCandles(candles); strategy.UpdateCandles(candles);
strategy.Run(); strategy.Run();

View File

@@ -4,14 +4,17 @@ namespace Managing.Domain.Scenarios
{ {
public class Scenario public class Scenario
{ {
public Scenario(string name) public Scenario(string name, int? loopbackPeriod = 1)
{ {
Name = name; Name = name;
Strategies = new List<Strategy>(); Strategies = new List<Strategy>();
LoopbackPeriod = loopbackPeriod;
} }
public string Name { get; set; } public string Name { get; set; }
public List<Strategy> Strategies { get; set; } public List<Strategy> Strategies { get; set; }
public int? LoopbackPeriod { get; set; }
public void AddStrategy(Strategy strategy) public void AddStrategy(Strategy strategy)
{ {
Strategies.Add(strategy); Strategies.Add(strategy);

View File

@@ -14,25 +14,25 @@ public static class ScenarioHelpers
{ {
IStrategy result = strategy.Type switch IStrategy result = strategy.Type switch
{ {
StrategyType.StDev => new StDevContext(strategy.Name, strategy.Timeframe, strategy.Period.Value), StrategyType.StDev => new StDevContext(strategy.Name, strategy.Period.Value),
StrategyType.RsiDivergence => new RSIDivergenceStrategy(strategy.Name, strategy.Timeframe, StrategyType.RsiDivergence => new RSIDivergenceStrategy(strategy.Name,
strategy.Period.Value), strategy.Period.Value),
StrategyType.RsiDivergenceConfirm => new RSIDivergenceConfirmStrategy(strategy.Name, strategy.Timeframe, StrategyType.RsiDivergenceConfirm => new RSIDivergenceConfirmStrategy(strategy.Name,
strategy.Period.Value), strategy.Period.Value),
StrategyType.MacdCross => new MacdCrossStrategy(strategy.Name, strategy.Timeframe, StrategyType.MacdCross => new MacdCrossStrategy(strategy.Name,
strategy.FastPeriods.Value, strategy.SlowPeriods.Value, strategy.SignalPeriods.Value), strategy.FastPeriods.Value, strategy.SlowPeriods.Value, strategy.SignalPeriods.Value),
StrategyType.EmaCross => new EmaCrossStrategy(strategy.Name, strategy.Timeframe, strategy.Period.Value), StrategyType.EmaCross => new EmaCrossStrategy(strategy.Name, strategy.Period.Value),
StrategyType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersStrategy(strategy.Name, strategy.Timeframe, StrategyType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersStrategy(strategy.Name,
strategy.Period.Value), strategy.Period.Value),
StrategyType.SuperTrend => new SuperTrendStrategy(strategy.Name, strategy.Timeframe, StrategyType.SuperTrend => new SuperTrendStrategy(strategy.Name,
strategy.Period.Value, strategy.Multiplier.Value), strategy.Period.Value, strategy.Multiplier.Value),
StrategyType.ChandelierExit => new ChandelierExitStrategy(strategy.Name, strategy.Timeframe, StrategyType.ChandelierExit => new ChandelierExitStrategy(strategy.Name,
strategy.Period.Value, strategy.Multiplier.Value), strategy.Period.Value, strategy.Multiplier.Value),
StrategyType.EmaTrend => new EmaTrendStrategy(strategy.Name, strategy.Timeframe, strategy.Period.Value), StrategyType.EmaTrend => new EmaTrendStrategy(strategy.Name, strategy.Period.Value),
StrategyType.StochRsiTrend => new StochRsiTrendStrategy(strategy.Name, strategy.Timeframe, StrategyType.StochRsiTrend => new StochRsiTrendStrategy(strategy.Name,
strategy.Period.Value, strategy.StochPeriods.Value, strategy.SignalPeriods.Value, strategy.Period.Value, strategy.StochPeriods.Value, strategy.SignalPeriods.Value,
strategy.SmoothPeriods.Value), strategy.SmoothPeriods.Value),
StrategyType.Stc => new STCStrategy(strategy.Name, strategy.Timeframe, strategy.CyclePeriods.Value, StrategyType.Stc => new STCStrategy(strategy.Name, strategy.CyclePeriods.Value,
strategy.FastPeriods.Value, strategy.SlowPeriods.Value), strategy.FastPeriods.Value, strategy.SlowPeriods.Value),
_ => throw new NotImplementedException(), _ => throw new NotImplementedException(),
}; };
@@ -46,7 +46,6 @@ public static class ScenarioHelpers
public static Strategy BuildStrategy( public static Strategy BuildStrategy(
StrategyType type, StrategyType type,
Timeframe timeframe,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -57,7 +56,7 @@ public static class ScenarioHelpers
int? smoothPeriods = null, int? smoothPeriods = null,
int? cyclePeriods = null) int? cyclePeriods = null)
{ {
var strategy = new Strategy(name, timeframe, type); var strategy = new Strategy(name, type);
switch (type) switch (type)
{ {

View File

@@ -10,7 +10,7 @@ namespace Managing.Domain.Shared.Helpers;
public static class TradingBox public static class TradingBox
{ {
public static Signal GetSignal(HashSet<Candle> newCandles, HashSet<IStrategy> strategies, public static Signal GetSignal(HashSet<Candle> newCandles, HashSet<IStrategy> strategies,
HashSet<Signal> previousSignal) HashSet<Signal> previousSignal, int? loopbackPeriod = 1)
{ {
var signalOnCandles = new HashSet<Signal>(); var signalOnCandles = new HashSet<Signal>();
var limitedCandles = newCandles.ToList().TakeLast(600).ToList(); var limitedCandles = newCandles.ToList().TakeLast(600).ToList();
@@ -21,7 +21,9 @@ public static class TradingBox
if (signals == null || signals.Count == 0) continue; if (signals == null || signals.Count == 0) continue;
foreach (var signal in signals.Where(s => s.Date == newCandles.Last().Date)) var candleLoopback = limitedCandles.TakeLast(loopbackPeriod ?? 1).ToList();
foreach (var signal in signals.Where(s => s.Date >= candleLoopback.FirstOrDefault()?.Date))
{ {
if (previousSignal.SingleOrDefault(s => s.Identifier == signal.Identifier) == null) if (previousSignal.SingleOrDefault(s => s.Identifier == signal.Identifier) == null)
{ {
@@ -68,7 +70,6 @@ public static class TradingBox
signals.Last().Candle, signals.Last().Candle,
signals.Last().Date, signals.Last().Date,
signals.Last().Exchange, signals.Last().Exchange,
timeframe,
StrategyType.Composite, SignalType.Signal); StrategyType.Composite, SignalType.Signal);
} }
else if (signals.All(s => s.Direction == TradeDirection.Short) && else if (signals.All(s => s.Direction == TradeDirection.Short) &&
@@ -81,7 +82,6 @@ public static class TradingBox
signals.Last().Candle, signals.Last().Candle,
signals.Last().Date, signals.Last().Date,
signals.Last().Exchange, signals.Last().Exchange,
timeframe,
StrategyType.Composite, SignalType.Signal); StrategyType.Composite, SignalType.Signal);
} }
} }

View File

@@ -6,7 +6,7 @@ namespace Managing.Domain.Strategies.Base;
public abstract class EmaBaseStrategy : Strategy public abstract class EmaBaseStrategy : Strategy
{ {
protected EmaBaseStrategy(string name, Enums.Timeframe timeframe, Enums.StrategyType type) : base(name, timeframe, type) protected EmaBaseStrategy(string name, Enums.StrategyType type) : base(name, type)
{ {
} }
@@ -29,6 +29,7 @@ public abstract class EmaBaseStrategy : Strategy
}); });
} }
} }
return emaList; return emaList;
} }

View File

@@ -9,7 +9,8 @@ namespace Managing.Domain.Strategies;
public class ChandelierExitStrategy : Strategy public class ChandelierExitStrategy : Strategy
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public ChandelierExitStrategy(string name, Timeframe timeframe, int period, double multiplier) : base(name, timeframe, StrategyType.ChandelierExit)
public ChandelierExitStrategy(string name, int period, double multiplier) : base(name, StrategyType.ChandelierExit)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -39,7 +40,8 @@ public class ChandelierExitStrategy : Strategy
private void GetSignals(ChandelierType chandelierType) private void GetSignals(ChandelierType chandelierType)
{ {
var chandelier = Candles.GetChandelier(Period.Value, Multiplier.Value, chandelierType).Where(s => s.ChandelierExit.HasValue).ToList(); var chandelier = Candles.GetChandelier(Period.Value, Multiplier.Value, chandelierType)
.Where(s => s.ChandelierExit.HasValue).ToList();
var chandelierCandle = MapChandelierToCandle(chandelier, Candles.TakeLast(MinimumHistory)); var chandelierCandle = MapChandelierToCandle(chandelier, Candles.TakeLast(MinimumHistory));
var previousCandle = chandelierCandle[0]; var previousCandle = chandelierCandle[0];
@@ -51,7 +53,7 @@ public class ChandelierExitStrategy : Strategy
currentCandle.Close < previousCandle.Open && currentCandle.Close < previousCandle.Open &&
chandelierType == ChandelierType.Short) chandelierType == ChandelierType.Short)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
} }
// Long // Long
@@ -60,7 +62,7 @@ public class ChandelierExitStrategy : Strategy
currentCandle.Close > currentCandle.Open && currentCandle.Close > currentCandle.Open &&
chandelierType == ChandelierType.Long) chandelierType == ChandelierType.Long)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
} }
previousCandle = currentCandle; previousCandle = currentCandle;
@@ -90,7 +92,8 @@ public class ChandelierExitStrategy : Strategy
return superTrends; return superTrends;
} }
private void AddSignal(CandleChandelier candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence) private void AddSignal(CandleChandelier candleSignal, TradeDirection direction,
Confidence confidence)
{ {
var signal = new Signal( var signal = new Signal(
MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker),
@@ -99,7 +102,6 @@ public class ChandelierExitStrategy : Strategy
candleSignal, candleSignal,
candleSignal.Date, candleSignal.Date,
candleSignal.Exchange, candleSignal.Exchange,
timeframe,
Type, SignalType); Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))
{ {

View File

@@ -10,7 +10,7 @@ public class EmaCrossStrategy : EmaBaseStrategy
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public EmaCrossStrategy(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.EmaCross) public EmaCrossStrategy(string name, int period) : base(name, StrategyType.EmaCross)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -37,13 +37,13 @@ public class EmaCrossStrategy : EmaBaseStrategy
if (previousCandle.Close > (decimal)currentCandle.Ema && if (previousCandle.Close > (decimal)currentCandle.Ema &&
currentCandle.Close < (decimal)currentCandle.Ema) currentCandle.Close < (decimal)currentCandle.Ema)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
} }
if (previousCandle.Close < (decimal)currentCandle.Ema && if (previousCandle.Close < (decimal)currentCandle.Ema &&
currentCandle.Close > (decimal)currentCandle.Ema) currentCandle.Close > (decimal)currentCandle.Ema)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
} }
previousCandle = currentCandle; previousCandle = currentCandle;
@@ -57,10 +57,10 @@ public class EmaCrossStrategy : EmaBaseStrategy
} }
} }
private void AddSignal(CandleEma candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence) private void AddSignal(CandleEma candleSignal, TradeDirection direction, Confidence confidence)
{ {
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence, var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType); candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))
{ {
Signals.AddItem(signal); Signals.AddItem(signal);

View File

@@ -10,7 +10,7 @@ public class EmaTrendStrategy : EmaBaseStrategy
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public EmaTrendStrategy(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.EmaTrend) public EmaTrendStrategy(string name, int period) : base(name, StrategyType.EmaTrend)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -36,11 +36,11 @@ public class EmaTrendStrategy : EmaBaseStrategy
{ {
if (currentCandle.Close > (decimal)currentCandle.Ema) if (currentCandle.Close > (decimal)currentCandle.Ema)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.None); AddSignal(currentCandle, TradeDirection.Long, Confidence.None);
} }
else else
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.None); AddSignal(currentCandle, TradeDirection.Short, Confidence.None);
} }
previousCandle = currentCandle; previousCandle = currentCandle;
@@ -54,9 +54,10 @@ public class EmaTrendStrategy : EmaBaseStrategy
} }
} }
public void AddSignal(CandleEma candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence) public void AddSignal(CandleEma candleSignal, TradeDirection direction, Confidence confidence)
{ {
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence, candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType); var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))
{ {
Signals.AddItem(signal); Signals.AddItem(signal);

View File

@@ -10,8 +10,8 @@ public class MacdCrossStrategy : Strategy
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public MacdCrossStrategy(string name, Timeframe timeframe, int fastPeriods, int slowPeriods, int signalPeriods) : public MacdCrossStrategy(string name, int fastPeriods, int slowPeriods, int signalPeriods) :
base(name, timeframe, StrategyType.MacdCross) base(name, StrategyType.MacdCross)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
FastPeriods = fastPeriods; FastPeriods = fastPeriods;
@@ -39,12 +39,12 @@ public class MacdCrossStrategy : Strategy
{ {
if (previousCandle.Histogram > 0 && currentCandle.Histogram < 0 && currentCandle.Macd < 0) if (previousCandle.Histogram > 0 && currentCandle.Histogram < 0 && currentCandle.Macd < 0)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
} }
if (previousCandle.Histogram < 0 && currentCandle.Histogram > 0 && currentCandle.Macd > 0) if (previousCandle.Histogram < 0 && currentCandle.Histogram > 0 && currentCandle.Macd > 0)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
} }
previousCandle = currentCandle; previousCandle = currentCandle;
@@ -82,11 +82,11 @@ public class MacdCrossStrategy : Strategy
return macdList; return macdList;
} }
private void AddSignal(CandleMacd candleSignal, Timeframe timeframe, TradeDirection direction, private void AddSignal(CandleMacd candleSignal, TradeDirection direction,
Confidence confidence) Confidence confidence)
{ {
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence, var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType); candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))
{ {
Signals.AddItem(signal); Signals.AddItem(signal);

View File

@@ -10,7 +10,7 @@ public class RSIDivergenceConfirmStrategy : Strategy
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public RSIDivergenceConfirmStrategy(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.RsiDivergenceConfirm) public RSIDivergenceConfirmStrategy(string name, int period) : base(name, StrategyType.RsiDivergenceConfirm)
{ {
Period = period; Period = period;
Signals = new List<Signal>(); Signals = new List<Signal>();
@@ -88,7 +88,7 @@ public class RSIDivergenceConfirmStrategy : Strategy
// Price go down but RSI go up // Price go down but RSI go up
if (currentCandle.Close < lowPrices.TakeLast(Period.Value).Min(p => p.Close)) if (currentCandle.Close < lowPrices.TakeLast(Period.Value).Min(p => p.Close))
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.None); AddSignal(currentCandle, TradeDirection.Long, Confidence.None);
} }
} }
else else
@@ -163,7 +163,7 @@ public class RSIDivergenceConfirmStrategy : Strategy
// Price go up but RSI go down // Price go up but RSI go down
if (currentCandle.Close > highPrices.TakeLast(Period.Value).Max(p => p.Close)) if (currentCandle.Close > highPrices.TakeLast(Period.Value).Max(p => p.Close))
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.None); AddSignal(currentCandle, TradeDirection.Short, Confidence.None);
} }
} }
else else
@@ -209,21 +209,22 @@ public class RSIDivergenceConfirmStrategy : Strategy
{ {
if (direction == TradeDirection.Short && currentCandle.Close < signal.Candle.Open) if (direction == TradeDirection.Short && currentCandle.Close < signal.Candle.Open)
{ {
AddSignal(currentCandle, Timeframe, direction, Confidence.High); AddSignal(currentCandle, direction, Confidence.High);
Signals.FirstOrDefault(s => s.Identifier == signal.Identifier).Status = SignalStatus.Expired; Signals.FirstOrDefault(s => s.Identifier == signal.Identifier).Status = SignalStatus.Expired;
} }
if (direction == TradeDirection.Long && currentCandle.Close > signal.Candle.Open) if (direction == TradeDirection.Long && currentCandle.Close > signal.Candle.Open)
{ {
AddSignal(currentCandle, Timeframe, direction, Confidence.High); AddSignal(currentCandle, direction, Confidence.High);
Signals.FirstOrDefault(s => s.Identifier == signal.Identifier).Status = SignalStatus.Expired; Signals.FirstOrDefault(s => s.Identifier == signal.Identifier).Status = SignalStatus.Expired;
} }
} }
} }
private void AddSignal(CandleRsi candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence) private void AddSignal(CandleRsi candleSignal, TradeDirection direction, Confidence confidence)
{ {
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence, candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType); var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))
{ {
Signals.AddItem(signal); Signals.AddItem(signal);
@@ -233,7 +234,6 @@ public class RSIDivergenceConfirmStrategy : Strategy
private List<CandleRsi> MapRsiToCandle(IReadOnlyCollection<RsiResult> rsiResult, private List<CandleRsi> MapRsiToCandle(IReadOnlyCollection<RsiResult> rsiResult,
IEnumerable<Candle> candles) IEnumerable<Candle> candles)
{ {
return candles.Select(c => new CandleRsi() return candles.Select(c => new CandleRsi()
{ {
Close = c.Close, Close = c.Close,

View File

@@ -13,7 +13,7 @@ public class RSIDivergenceStrategy : Strategy
private const int UpperBand = 70; private const int UpperBand = 70;
private const int LowerBand = 30; private const int LowerBand = 30;
public RSIDivergenceStrategy(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.RsiDivergence) public RSIDivergenceStrategy(string name, int period) : base(name, StrategyType.RsiDivergence)
{ {
Period = period; Period = period;
Signals = new List<Signal>(); Signals = new List<Signal>();
@@ -91,7 +91,7 @@ public class RSIDivergenceStrategy : Strategy
// Price go down but RSI go up // Price go down but RSI go up
if (currentCandle.Close < lowPrices.TakeLast(Period.Value).Min(p => p.Close)) if (currentCandle.Close < lowPrices.TakeLast(Period.Value).Min(p => p.Close))
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long); AddSignal(currentCandle, TradeDirection.Long);
} }
} }
else else
@@ -164,7 +164,7 @@ public class RSIDivergenceStrategy : Strategy
// Price go up but RSI go down // Price go up but RSI go down
if (currentCandle.Close > highPrices.TakeLast(Period.Value).Max(p => p.Close)) if (currentCandle.Close > highPrices.TakeLast(Period.Value).Max(p => p.Close))
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short); AddSignal(currentCandle, TradeDirection.Short);
} }
} }
else else
@@ -194,9 +194,10 @@ public class RSIDivergenceStrategy : Strategy
} }
} }
private void AddSignal(CandleRsi candleSignal, Timeframe timeframe, TradeDirection direction) private void AddSignal(CandleRsi candleSignal, TradeDirection direction)
{ {
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, Confidence.Low, candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType); var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, Confidence.Low,
candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (Signals.Count(s => s.Identifier == signal.Identifier) < 1) if (Signals.Count(s => s.Identifier == signal.Identifier) < 1)
{ {
@@ -216,7 +217,6 @@ public class RSIDivergenceStrategy : Strategy
private List<CandleRsi> MapRsiToCandle(IReadOnlyCollection<RsiResult> rsiResult, private List<CandleRsi> MapRsiToCandle(IReadOnlyCollection<RsiResult> rsiResult,
IEnumerable<Candle> candles) IEnumerable<Candle> candles)
{ {
return candles.Select(c => new CandleRsi() return candles.Select(c => new CandleRsi()
{ {
Close = c.Close, Close = c.Close,

View File

@@ -10,7 +10,7 @@ public class STCStrategy : Strategy
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public STCStrategy(string name, Timeframe timeframe, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name, timeframe, StrategyType.Stc) public STCStrategy(string name, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name, StrategyType.Stc)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
FastPeriods = fastPeriods; FastPeriods = fastPeriods;
@@ -38,12 +38,12 @@ public class STCStrategy : Strategy
{ {
if (previousCandle.Stc > 75 && currentCandle.Stc <= 75) if (previousCandle.Stc > 75 && currentCandle.Stc <= 75)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
} }
if (previousCandle.Stc < 25 && currentCandle.Stc >= 25) if (previousCandle.Stc < 25 && currentCandle.Stc >= 25)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
} }
previousCandle = currentCandle; previousCandle = currentCandle;
@@ -76,10 +76,11 @@ public class STCStrategy : Strategy
}); });
} }
} }
return sctList; return sctList;
} }
private void AddSignal(CandleSct candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence) private void AddSignal(CandleSct candleSignal, TradeDirection direction, Confidence confidence)
{ {
var signal = new Signal( var signal = new Signal(
MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker),
@@ -88,7 +89,6 @@ public class STCStrategy : Strategy
candleSignal, candleSignal,
candleSignal.Date, candleSignal.Date,
candleSignal.Exchange, candleSignal.Exchange,
timeframe,
Type, SignalType); Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))
{ {

View File

@@ -1,37 +1,26 @@
using Managing.Core; using System.ComponentModel.DataAnnotations;
using Managing.Core;
using Managing.Domain.Candles; using Managing.Domain.Candles;
using System.ComponentModel.DataAnnotations;
using static Managing.Common.Enums; using static Managing.Common.Enums;
namespace Managing.Domain.Strategies namespace Managing.Domain.Strategies
{ {
public class Signal : ValueObject public class Signal : ValueObject
{ {
[Required] [Required] public SignalStatus Status { get; set; }
public SignalStatus Status { get; set; } [Required] public TradeDirection Direction { get; }
[Required] [Required] public Confidence Confidence { get; private set; }
public TradeDirection Direction { get; } [Required] public Timeframe Timeframe { get; }
[Required] [Required] public DateTime Date { get; private set; }
public Confidence Confidence { get; private set; } [Required] public Candle Candle { get; }
[Required] [Required] public string Identifier { get; }
public Timeframe Timeframe { get; } [Required] public Ticker Ticker { get; }
[Required] [Required] public TradingExchanges Exchange { get; set; }
public DateTime Date { get; private set; } [Required] public StrategyType StrategyType { get; set; }
[Required] [Required] public SignalType SignalType { get; set; }
public Candle Candle { get; }
[Required]
public string Identifier { get; }
[Required]
public Ticker Ticker { get; }
[Required]
public TradingExchanges Exchange { get; set; }
[Required]
public StrategyType StrategyType { get; set; }
[Required]
public SignalType SignalType { get; set; }
public Signal(Ticker ticker, TradeDirection direction, Confidence confidence, Candle candle, DateTime date, public Signal(Ticker ticker, TradeDirection direction, Confidence confidence, Candle candle, DateTime date,
TradingExchanges exchange, Timeframe timeframe, StrategyType strategyType, SignalType signalType) TradingExchanges exchange, StrategyType strategyType, SignalType signalType)
{ {
Direction = direction; Direction = direction;
Confidence = confidence; Confidence = confidence;
@@ -40,10 +29,9 @@ namespace Managing.Domain.Strategies
Ticker = ticker; Ticker = ticker;
Exchange = exchange; Exchange = exchange;
Status = SignalStatus.WaitingForPosition; Status = SignalStatus.WaitingForPosition;
Timeframe = timeframe;
StrategyType = strategyType; StrategyType = strategyType;
Identifier = $"{StrategyType}-{direction}-{ticker}-{Timeframe}-{candle?.Close}-{date:yyyyMMdd-HHmmss}"; Identifier = $"{StrategyType}-{direction}-{ticker}-{candle?.Close}-{date:yyyyMMdd-HHmmss}";
SignalType = signalType; SignalType = signalType;
} }

View File

@@ -10,7 +10,7 @@ public class StDevContext : Strategy
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public StDevContext(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.StDev) public StDevContext(string name, int period) : base(name, StrategyType.StDev)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -35,7 +35,7 @@ public class StDevContext : Strategy
if (lastCandle.ZScore is < 1.2 and > (-1.2)) if (lastCandle.ZScore is < 1.2 and > (-1.2))
{ {
AddSignal(lastCandle, Timeframe, TradeDirection.None, Confidence.Medium); AddSignal(lastCandle, TradeDirection.None, Confidence.Medium);
} }
else else
{ {
@@ -72,10 +72,12 @@ public class StDevContext : Strategy
}); });
} }
} }
return sctList; return sctList;
} }
private void AddSignal(CandleStDev candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence) private void AddSignal(CandleStDev candleSignal, TradeDirection direction,
Confidence confidence)
{ {
var signal = new Signal( var signal = new Signal(
MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker),
@@ -84,7 +86,6 @@ public class StDevContext : Strategy
candleSignal, candleSignal,
candleSignal.Date, candleSignal.Date,
candleSignal.Exchange, candleSignal.Exchange,
timeframe,
Type, SignalType); Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))
{ {

View File

@@ -12,11 +12,10 @@ public class StochRsiTrendStrategy : Strategy
public StochRsiTrendStrategy( public StochRsiTrendStrategy(
string name, string name,
Timeframe timeframe,
int period, int period,
int stochPeriod, int stochPeriod,
int signalPeriod, int signalPeriod,
int smoothPeriods) : base(name, timeframe, StrategyType.StochRsiTrend) int smoothPeriods) : base(name, StrategyType.StochRsiTrend)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
StochPeriods = stochPeriod; StochPeriods = stochPeriod;
@@ -34,7 +33,9 @@ public class StochRsiTrendStrategy : Strategy
try try
{ {
var stochRsi = Candles.GetStochRsi(Period.Value, StochPeriods.Value, SignalPeriods.Value, SmoothPeriods.Value).RemoveWarmupPeriods().ToList(); var stochRsi = Candles
.GetStochRsi(Period.Value, StochPeriods.Value, SignalPeriods.Value, SmoothPeriods.Value)
.RemoveWarmupPeriods().ToList();
var stochRsiCandles = MapStochRsiToCandle(stochRsi, Candles.TakeLast(Period.Value)); var stochRsiCandles = MapStochRsiToCandle(stochRsi, Candles.TakeLast(Period.Value));
if (stochRsi.Count == 0) if (stochRsi.Count == 0)
@@ -45,11 +46,11 @@ public class StochRsiTrendStrategy : Strategy
{ {
if (currentCandle.Signal < 20) if (currentCandle.Signal < 20)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.None); AddSignal(currentCandle, TradeDirection.Long, Confidence.None);
} }
else if (currentCandle.Signal > 80) else if (currentCandle.Signal > 80)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.None); AddSignal(currentCandle, TradeDirection.Short, Confidence.None);
} }
previousCandle = currentCandle; previousCandle = currentCandle;
@@ -83,10 +84,11 @@ public class StochRsiTrendStrategy : Strategy
}); });
} }
} }
return emaList; return emaList;
} }
private void AddSignal(CandleStochRsi candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence) private void AddSignal(CandleStochRsi candleSignal, TradeDirection direction, Confidence confidence)
{ {
var signal = new Signal( var signal = new Signal(
MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker),
@@ -95,7 +97,6 @@ public class StochRsiTrendStrategy : Strategy
candleSignal, candleSignal,
candleSignal.Date, candleSignal.Date,
candleSignal.Exchange, candleSignal.Exchange,
timeframe,
Type, Type,
SignalType); SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))

View File

@@ -8,16 +8,14 @@ namespace Managing.Domain.Strategies
{ {
public class Strategy : IStrategy public class Strategy : IStrategy
{ {
public Strategy(string name, Timeframe timeframe, StrategyType type) public Strategy(string name, StrategyType type)
{ {
Name = name; Name = name;
Timeframe = timeframe;
Type = type; Type = type;
SignalType = ScenarioHelpers.GetSignalType(type); SignalType = ScenarioHelpers.GetSignalType(type);
} }
public string Name { get; set; } public string Name { get; set; }
public Timeframe Timeframe { get; set; }
[JsonIgnore] public FixedSizeQueue<Candle> Candles { get; set; } [JsonIgnore] public FixedSizeQueue<Candle> Candles { get; set; }
public StrategyType Type { get; set; } public StrategyType Type { get; set; }
public SignalType SignalType { get; set; } public SignalType SignalType { get; set; }

View File

@@ -10,7 +10,7 @@ public class SuperTrendStrategy : Strategy
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public SuperTrendStrategy(string name, Timeframe timeframe, int period, double multiplier) : base(name, timeframe, StrategyType.SuperTrend) public SuperTrendStrategy(string name, int period, double multiplier) : base(name, StrategyType.SuperTrend)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -27,7 +27,8 @@ public class SuperTrendStrategy : Strategy
try try
{ {
var superTrend = Candles.GetSuperTrend(Period.Value, Multiplier.Value).Where(s => s.SuperTrend.HasValue).ToList(); var superTrend = Candles.GetSuperTrend(Period.Value, Multiplier.Value).Where(s => s.SuperTrend.HasValue)
.ToList();
var superTrendCandle = MapSuperTrendToCandle(superTrend, Candles.TakeLast(MinimumHistory)); var superTrendCandle = MapSuperTrendToCandle(superTrend, Candles.TakeLast(MinimumHistory));
if (superTrendCandle.Count == 0) if (superTrendCandle.Count == 0)
@@ -39,13 +40,13 @@ public class SuperTrendStrategy : Strategy
// Short // Short
if (currentCandle.Close < previousCandle.SuperTrend && previousCandle.Close > previousCandle.SuperTrend) if (currentCandle.Close < previousCandle.SuperTrend && previousCandle.Close > previousCandle.SuperTrend)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
} }
// Long // Long
if (currentCandle.Close > previousCandle.SuperTrend && previousCandle.Close < previousCandle.SuperTrend) if (currentCandle.Close > previousCandle.SuperTrend && previousCandle.Close < previousCandle.SuperTrend)
{ {
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium); AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
} }
previousCandle = currentCandle; previousCandle = currentCandle;
@@ -84,10 +85,11 @@ public class SuperTrendStrategy : Strategy
return superTrends; return superTrends;
} }
private void AddSignal(CandleSuperTrend candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence) private void AddSignal(CandleSuperTrend candleSignal, TradeDirection direction, Confidence confidence)
{ {
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence, candleSignal, candleSignal.Date, var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
candleSignal.Exchange, timeframe, Type, SignalType); candleSignal, candleSignal.Date,
candleSignal.Exchange, Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier)) if (!Signals.Any(s => s.Identifier == signal.Identifier))
{ {
Signals.AddItem(signal); Signals.AddItem(signal);

View File

@@ -7,8 +7,8 @@ namespace Managing.Domain.Strategies
{ {
public class ThreeWhiteSoldiersStrategy : Strategy public class ThreeWhiteSoldiersStrategy : Strategy
{ {
public ThreeWhiteSoldiersStrategy(string name, Timeframe timeframe, int period) public ThreeWhiteSoldiersStrategy(string name, int period)
: base(name, timeframe, StrategyType.ThreeWhiteSoldiers) : base(name, StrategyType.ThreeWhiteSoldiers)
{ {
Period = period; Period = period;
} }

View File

@@ -8,5 +8,6 @@ namespace Managing.Infrastructure.Databases.MongoDb.Collections
{ {
public string Name { get; set; } public string Name { get; set; }
public List<StrategyDto> Strategies { get; set; } public List<StrategyDto> Strategies { get; set; }
public int LoopbackPeriod { get; set; }
} }
} }

View File

@@ -342,7 +342,7 @@ public static class MongoMappers
internal static Signal Map(SignalDto bSignal) internal static Signal Map(SignalDto bSignal)
{ {
return new Signal(ticker: bSignal.Ticker, direction: bSignal.Direction, confidence: bSignal.Confidence, return new Signal(ticker: bSignal.Ticker, direction: bSignal.Direction, confidence: bSignal.Confidence,
candle: Map(bSignal.Candle), date: bSignal.Date, exchange: default, timeframe: bSignal.Timeframe, candle: Map(bSignal.Candle), date: bSignal.Date, exchange: default,
strategyType: bSignal.Type, signalType: bSignal.SignalType) strategyType: bSignal.Type, signalType: bSignal.SignalType)
{ {
Status = bSignal.Status Status = bSignal.Status
@@ -359,6 +359,7 @@ public static class MongoMappers
{ {
Name = scenario.Name, Name = scenario.Name,
Strategies = Map(scenario.Strategies), Strategies = Map(scenario.Strategies),
LoopbackPeriod = scenario.LoopbackPeriod ?? 1
}; };
} }
@@ -372,7 +373,8 @@ public static class MongoMappers
return new Scenario(d.Name) return new Scenario(d.Name)
{ {
Name = d.Name, Name = d.Name,
Strategies = Map(d.Strategies).ToList() Strategies = Map(d.Strategies).ToList(),
LoopbackPeriod = d.LoopbackPeriod > 0 ? d.LoopbackPeriod : 1
}; };
} }
@@ -383,7 +385,7 @@ public static class MongoMappers
internal static Strategy Map(StrategyDto strategyDto) internal static Strategy Map(StrategyDto strategyDto)
{ {
return new Strategy(name: strategyDto.Name, timeframe: strategyDto.Timeframe, type: strategyDto.Type) return new Strategy(name: strategyDto.Name, type: strategyDto.Type)
{ {
Period = strategyDto.Period, Period = strategyDto.Period,
FastPeriods = strategyDto.FastPeriods, FastPeriods = strategyDto.FastPeriods,
@@ -401,7 +403,6 @@ public static class MongoMappers
var dto = new StrategyDto var dto = new StrategyDto
{ {
Type = strategy.Type, Type = strategy.Type,
Timeframe = strategy.Timeframe,
Name = strategy.Name, Name = strategy.Name,
SignalType = strategy.SignalType SignalType = strategy.SignalType
}; };

View File

@@ -1,5 +1,4 @@
using Managing.Application.Abstractions.Repositories; using Managing.Application.Abstractions.Repositories;
using Managing.Common;
using Managing.Domain.Scenarios; using Managing.Domain.Scenarios;
using Managing.Domain.Strategies; using Managing.Domain.Strategies;
using Managing.Domain.Trades; using Managing.Domain.Trades;
@@ -19,7 +18,6 @@ public class TradingRepository : ITradingRepository
private readonly IMongoRepository<StrategyDto> _strategyRepository; private readonly IMongoRepository<StrategyDto> _strategyRepository;
private readonly IMongoRepository<FeeDto> _feeRepository; private readonly IMongoRepository<FeeDto> _feeRepository;
public TradingRepository( public TradingRepository(
IMongoRepository<ScenarioDto> scenarioRepository, IMongoRepository<ScenarioDto> scenarioRepository,
IMongoRepository<SignalDto> signalRepository, IMongoRepository<SignalDto> signalRepository,
@@ -69,7 +67,7 @@ public class TradingRepository : ITradingRepository
return positions.Select(MongoMappers.Map); return positions.Select(MongoMappers.Map);
} }
public IEnumerable<Position> GetPositionsByStatus(Enums.PositionStatus positionStatus) public IEnumerable<Position> GetPositionsByStatus(PositionStatus positionStatus)
{ {
var filter = Builders<PositionDto>.Filter.Eq(p => p.Status, positionStatus); var filter = Builders<PositionDto>.Filter.Eq(p => p.Status, positionStatus);
var positions = _positionRepository.FilterBy(filter); var positions = _positionRepository.FilterBy(filter);

View File

@@ -8,7 +8,6 @@ namespace Managing.Infrastructure.MongoDb.Collections
public class StrategyDto : Document public class StrategyDto : Document
{ {
public StrategyType Type { get; set; } public StrategyType Type { get; set; }
public Timeframe Timeframe { get; set; }
public string Name { get; set; } public string Name { get; set; }
public int? Period { get; set; } public int? Period { get; set; }
public int? FastPeriods { get; set; } public int? FastPeriods { get; set; }

View File

@@ -1073,10 +1073,12 @@ export class ScenarioClient extends AuthorizedApiBase {
return Promise.resolve<Scenario[]>(null as any); return Promise.resolve<Scenario[]>(null as any);
} }
scenario_CreateScenario(name: string | null | undefined, strategies: string[]): Promise<Scenario> { scenario_CreateScenario(name: string | null | undefined, loopbackPeriod: number | null | undefined, strategies: string[]): Promise<Scenario> {
let url_ = this.baseUrl + "/Scenario?"; let url_ = this.baseUrl + "/Scenario?";
if (name !== undefined && name !== null) if (name !== undefined && name !== null)
url_ += "name=" + encodeURIComponent("" + name) + "&"; url_ += "name=" + encodeURIComponent("" + name) + "&";
if (loopbackPeriod !== undefined && loopbackPeriod !== null)
url_ += "loopbackPeriod=" + encodeURIComponent("" + loopbackPeriod) + "&";
url_ = url_.replace(/[?&]$/, ""); url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(strategies); const content_ = JSON.stringify(strategies);
@@ -1191,16 +1193,12 @@ export class ScenarioClient extends AuthorizedApiBase {
return Promise.resolve<Strategy[]>(null as any); return Promise.resolve<Strategy[]>(null as any);
} }
scenario_CreateStrategy(strategyType: StrategyType | undefined, timeframe: Timeframe | undefined, name: string | null | undefined, period: number | null | undefined, fastPeriods: number | null | undefined, slowPeriods: number | null | undefined, signalPeriods: number | null | undefined, multiplier: number | null | undefined, stochPeriods: number | null | undefined, smoothPeriods: number | null | undefined, cyclePeriods: number | null | undefined): Promise<Strategy> { scenario_CreateStrategy(strategyType: StrategyType | undefined, name: string | null | undefined, period: number | null | undefined, fastPeriods: number | null | undefined, slowPeriods: number | null | undefined, signalPeriods: number | null | undefined, multiplier: number | null | undefined, stochPeriods: number | null | undefined, smoothPeriods: number | null | undefined, cyclePeriods: number | null | undefined): Promise<Strategy> {
let url_ = this.baseUrl + "/Scenario/strategy?"; let url_ = this.baseUrl + "/Scenario/strategy?";
if (strategyType === null) if (strategyType === null)
throw new Error("The parameter 'strategyType' cannot be null."); throw new Error("The parameter 'strategyType' cannot be null.");
else if (strategyType !== undefined) else if (strategyType !== undefined)
url_ += "strategyType=" + encodeURIComponent("" + strategyType) + "&"; url_ += "strategyType=" + encodeURIComponent("" + strategyType) + "&";
if (timeframe === null)
throw new Error("The parameter 'timeframe' cannot be null.");
else if (timeframe !== undefined)
url_ += "timeframe=" + encodeURIComponent("" + timeframe) + "&";
if (name !== undefined && name !== null) if (name !== undefined && name !== null)
url_ += "name=" + encodeURIComponent("" + name) + "&"; url_ += "name=" + encodeURIComponent("" + name) + "&";
if (period !== undefined && period !== null) if (period !== undefined && period !== null)
@@ -1583,7 +1581,7 @@ export class TradingClient extends AuthorizedApiBase {
let options_: RequestInit = { let options_: RequestInit = {
body: content_, body: content_,
method: "GET", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Accept": "application/json" "Accept": "application/json"
@@ -2206,11 +2204,11 @@ export interface Spotlight {
export interface Scenario { export interface Scenario {
name?: string | null; name?: string | null;
strategies?: Strategy[] | null; strategies?: Strategy[] | null;
loopbackPeriod?: number | null;
} }
export interface Strategy { export interface Strategy {
name?: string | null; name?: string | null;
timeframe?: Timeframe;
type?: StrategyType; type?: StrategyType;
signalType?: SignalType; signalType?: SignalType;
minimumHistory?: number; minimumHistory?: number;

View File

@@ -1,13 +1,30 @@
import type { import type {TableInstance, UsePaginationInstanceProps, UsePaginationState, UseSortByInstanceProps,} from 'react-table'
TableInstance,
UsePaginationInstanceProps,
UsePaginationState,
UseSortByInstanceProps,
} from 'react-table'
import type {Edge, Node} from 'reactflow' import type {Edge, Node} from 'reactflow'
import type { Account, AccountType, Backtest, Balance, BotType, Candle, FlowOutput, FlowType, IFlow, KeyValuePairOfDateTimeAndDecimal, MoneyManagement, Position, RiskLevel, Scenario, Signal, Ticker, Timeframe, TradeDirection, TradingBot, TradingExchanges } from '../generated/ManagingApi' import type {
import { ReactNode, FC } from 'react' Account,
AccountType,
Backtest,
Balance,
BotType,
Candle,
FlowOutput,
FlowType,
IFlow,
KeyValuePairOfDateTimeAndDecimal,
MoneyManagement,
Position,
RiskLevel,
Scenario,
Signal,
Ticker,
Timeframe,
TradeDirection,
TradingBot,
TradingExchanges
} from '../generated/ManagingApi'
import {FC, ReactNode} from 'react'
export type TabsType = { export type TabsType = {
label: string label: string
index: number index: number
@@ -156,6 +173,7 @@ export type IBotList = {
export type IScenarioFormInput = { export type IScenarioFormInput = {
name: string name: string
strategies: string[] strategies: string[]
loopbackPeriod: number | undefined
} }
export type IScenarioList = { export type IScenarioList = {
list: Scenario[] list: Scenario[]

View File

@@ -22,7 +22,7 @@ const ScenarioList: React.FC = () => {
async function createScenario(form: IScenarioFormInput) { async function createScenario(form: IScenarioFormInput) {
const t = new Toast('Creating scenario') const t = new Toast('Creating scenario')
await client await client
.scenario_CreateScenario(form.name, form.strategies) .scenario_CreateScenario(form.name, form.loopbackPeriod, form.strategies)
.then((data: Scenario) => { .then((data: Scenario) => {
t.update('success', 'Scenario created') t.update('success', 'Scenario created')
setScenarios((arr) => [...arr, data]) setScenarios((arr) => [...arr, data])
@@ -97,6 +97,17 @@ const ScenarioList: React.FC = () => {
</select> </select>
</div> </div>
</div> </div>
<div className="form-control mb-5">
<div className="input-group">
<label htmlFor="name" className="label mr-6">
Loopback period
</label>
<input
className="bg-inherit w-full max-w-xs"
{...register('loopbackPeriod')}
></input>
</div>
</div>
<div className="modal-action"> <div className="modal-action">
<button type="submit" className="btn"> <button type="submit" className="btn">
Build Build

View File

@@ -6,11 +6,7 @@ import 'react-toastify/dist/ReactToastify.css'
import useApiUrlStore from '../../app/store/apiStore' import useApiUrlStore from '../../app/store/apiStore'
import {Toast} from '../../components/mollecules' import {Toast} from '../../components/mollecules'
import type {Strategy} from '../../generated/ManagingApi' import type {Strategy} from '../../generated/ManagingApi'
import { import {ScenarioClient, StrategyType, Timeframe,} from '../../generated/ManagingApi'
StrategyType,
ScenarioClient,
Timeframe,
} from '../../generated/ManagingApi'
import StrategyTable from './strategyTable' import StrategyTable from './strategyTable'
@@ -43,7 +39,6 @@ const StrategyList: React.FC = () => {
await scenarioClient await scenarioClient
.scenario_CreateStrategy( .scenario_CreateStrategy(
form.type, form.type,
form.timeframe,
form.name, form.name,
form.period, form.period,
form.fastPeriods, form.fastPeriods,