Rename strategy to indicators

This commit is contained in:
2025-06-16 22:09:23 +07:00
parent e4f4d078b2
commit 0f7df04813
45 changed files with 477 additions and 474 deletions

View File

@@ -249,12 +249,12 @@ public class RunBacktestRequest
public bool Save { get; set; } = false; public bool Save { get; set; } = false;
/// <summary> /// <summary>
/// The name of the money management strategy to use (optional if MoneyManagement is provided) /// The name of the money management to use (optional if MoneyManagement is provided)
/// </summary> /// </summary>
public string? MoneyManagementName { get; set; } public string? MoneyManagementName { get; set; }
/// <summary> /// <summary>
/// The money management strategy details (optional if MoneyManagementName is provided) /// The money management details (optional if MoneyManagementName is provided)
/// </summary> /// </summary>
public MoneyManagement? MoneyManagement { get; set; } public MoneyManagement? MoneyManagement { get; set; }
} }

View File

@@ -28,7 +28,7 @@ public class ScenarioController : BaseController
/// <param name="userService">The service for user-related operations.</param> /// <param name="userService">The service for user-related operations.</param>
public ScenarioController( public ScenarioController(
IScenarioService scenarioService, IScenarioService scenarioService,
IUserService userService) IUserService userService)
: base(userService) : base(userService)
{ {
_scenarioService = scenarioService; _scenarioService = scenarioService;
@@ -52,7 +52,8 @@ public class ScenarioController : BaseController
/// <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 async Task<ActionResult<Scenario>> CreateScenario(string name, List<string> strategies, int? loopbackPeriod = null) public async Task<ActionResult<Scenario>> CreateScenario(string name, List<string> strategies,
int? loopbackPeriod = null)
{ {
var user = await GetUser(); var user = await GetUser();
return Ok(_scenarioService.CreateScenarioForUser(user, name, strategies, loopbackPeriod)); return Ok(_scenarioService.CreateScenarioForUser(user, name, strategies, loopbackPeriod));
@@ -83,31 +84,31 @@ public class ScenarioController : BaseController
/// </summary> /// </summary>
/// <returns>A list of strategies.</returns> /// <returns>A list of strategies.</returns>
[HttpGet] [HttpGet]
[Route("strategy")] [Route("indicator")]
public async Task<ActionResult<IEnumerable<Strategy>>> GetStrategies() public async Task<ActionResult<IEnumerable<Indicator>>> GetIndicators()
{ {
var user = await GetUser(); var user = await GetUser();
return Ok(_scenarioService.GetStrategiesByUser(user)); return Ok(_scenarioService.GetIndicatorsByUser(user));
} }
/// <summary> /// <summary>
/// Creates a new strategy with specified parameters for the authenticated user. /// Creates a new indicator with specified parameters for the authenticated user.
/// </summary> /// </summary>
/// <param name="strategyType">The type of the strategy.</param> /// <param name="indicatorType">The type of the indicator.</param>
/// <param name="name">The name of the strategy.</param> /// <param name="name">The name of the indicator.</param>
/// <param name="period">The period for the strategy (optional).</param> /// <param name="period">The period for the indicator (optional).</param>
/// <param name="fastPeriods">The fast periods for the strategy (optional).</param> /// <param name="fastPeriods">The fast periods for the indicator (optional).</param>
/// <param name="slowPeriods">The slow periods for the strategy (optional).</param> /// <param name="slowPeriods">The slow periods for the indicator (optional).</param>
/// <param name="signalPeriods">The signal periods for the strategy (optional).</param> /// <param name="signalPeriods">The signal periods for the indicator (optional).</param>
/// <param name="multiplier">The multiplier for the strategy (optional).</param> /// <param name="multiplier">The multiplier for the indicator (optional).</param>
/// <param name="stochPeriods">The stochastic periods for the strategy (optional).</param> /// <param name="stochPeriods">The stochastic periods for the indicator (optional).</param>
/// <param name="smoothPeriods">The smooth periods for the strategy (optional).</param> /// <param name="smoothPeriods">The smooth periods for the indicator (optional).</param>
/// <param name="cyclePeriods">The cycle periods for the strategy (optional).</param> /// <param name="cyclePeriods">The cycle periods for the indicator (optional).</param>
/// <returns>The created strategy.</returns> /// <returns>The created indicator.</returns>
[HttpPost] [HttpPost]
[Route("strategy")] [Route("indicator")]
public async Task<ActionResult<Strategy>> CreateStrategy( public async Task<ActionResult<Indicator>> CreateIndicator(
StrategyType strategyType, IndicatorType indicatorType,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -119,9 +120,9 @@ public class ScenarioController : BaseController
int? cyclePeriods = null) int? cyclePeriods = null)
{ {
var user = await GetUser(); var user = await GetUser();
return Ok(_scenarioService.CreateStrategyForUser( return Ok(_scenarioService.CreateIndicatorForUser(
user, user,
strategyType, indicatorType,
name, name,
period, period,
fastPeriods, fastPeriods,
@@ -134,23 +135,23 @@ public class ScenarioController : BaseController
} }
/// <summary> /// <summary>
/// Deletes a strategy by name for the authenticated user. /// Deletes a indicator by name for the authenticated user.
/// </summary> /// </summary>
/// <param name="name">The name of the strategy to delete.</param> /// <param name="name">The name of the indicator to delete.</param>
/// <returns>An ActionResult indicating the outcome of the operation.</returns> /// <returns>An ActionResult indicating the outcome of the operation.</returns>
[HttpDelete] [HttpDelete]
[Route("strategy")] [Route("indicator")]
public async Task<ActionResult> DeleteStrategy(string name) public async Task<ActionResult> DeleteIndicator(string name)
{ {
var user = await GetUser(); var user = await GetUser();
return Ok(_scenarioService.DeleteStrategyByUser(user, name)); return Ok(_scenarioService.DeleteIndicatorByUser(user, name));
} }
// Update strategy // Update indicator
[HttpPut] [HttpPut]
[Route("strategy")] [Route("indicator")]
public async Task<ActionResult> UpdateStrategy( public async Task<ActionResult> Updateindicator(
StrategyType strategyType, IndicatorType indicatorType,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -162,9 +163,9 @@ public class ScenarioController : BaseController
int? cyclePeriods = null) int? cyclePeriods = null)
{ {
var user = await GetUser(); var user = await GetUser();
return Ok(_scenarioService.UpdateStrategyByUser( return Ok(_scenarioService.UpdateIndicatorByUser(
user, user,
strategyType, indicatorType,
name, name,
period, period,
fastPeriods, fastPeriods,

View File

@@ -4,9 +4,7 @@ namespace Managing.Api.Models.Requests
{ {
public class CreateScenarioRequest public class CreateScenarioRequest
{ {
[Required] [Required] public string Name { get; internal set; }
public string Name { get; internal set; } [Required] public List<string> Indicators { get; internal set; }
[Required]
public List<string> Strategies { get; internal set; }
} }
} }

View File

@@ -5,12 +5,8 @@ namespace Managing.Api.Models.Requests;
public class CreateStrategyRequest public class CreateStrategyRequest
{ {
[Required] [Required] public IndicatorType Type { get; internal set; }
public StrategyType Type { get; internal set; } [Required] public Timeframe Timeframe { get; internal set; }
[Required] [Required] public string Name { get; internal set; }
public Timeframe Timeframe { get; internal set; } [Required] public int Period { get; internal set; }
[Required] }
public string Name { get; internal set; }
[Required]
public int Period { get; internal set; }
}

View File

@@ -14,15 +14,15 @@ public interface ITradingRepository
Signal GetSignalByIdentifier(string identifier, User user = null); Signal GetSignalByIdentifier(string identifier, User user = null);
void InsertPosition(Position position); void InsertPosition(Position position);
void UpdatePosition(Position position); void UpdatePosition(Position position);
Strategy GetStrategyByName(string strategy); Indicator GetStrategyByName(string strategy);
void InsertScenario(Scenario scenario); void InsertScenario(Scenario scenario);
void InsertStrategy(Strategy strategy); void InsertStrategy(Indicator indicator);
IEnumerable<Scenario> GetScenarios(); IEnumerable<Scenario> GetScenarios();
IEnumerable<Strategy> GetStrategies(); IEnumerable<Indicator> GetIndicators();
void DeleteScenario(string name); void DeleteScenario(string name);
void DeleteStrategy(string name); void DeleteIndicator(string name);
void DeleteScenarios(); void DeleteScenarios();
void DeleteStrategies(); void DeleteIndicators();
Position GetPositionByIdentifier(string identifier); Position GetPositionByIdentifier(string identifier);
IEnumerable<Position> GetPositions(PositionInitiator positionInitiator); IEnumerable<Position> GetPositions(PositionInitiator positionInitiator);
IEnumerable<Position> GetPositionsByStatus(PositionStatus positionStatus); IEnumerable<Position> GetPositionsByStatus(PositionStatus positionStatus);
@@ -30,5 +30,5 @@ public interface ITradingRepository
void InsertFee(Fee fee); void InsertFee(Fee fee);
void UpdateFee(Fee fee); void UpdateFee(Fee fee);
void UpdateScenario(Scenario scenario); void UpdateScenario(Scenario scenario);
void UpdateStrategy(Strategy strategy); void UpdateStrategy(Indicator indicator);
} }

View File

@@ -14,11 +14,11 @@ public interface ITradingService
void InsertSignal(Signal signal); void InsertSignal(Signal signal);
void InsertPosition(Position position); void InsertPosition(Position position);
void UpdatePosition(Position position); void UpdatePosition(Position position);
Strategy GetStrategyByName(string strategy); Indicator GetStrategyByName(string strategy);
void InsertScenario(Scenario scenario); void InsertScenario(Scenario scenario);
void InsertStrategy(Strategy strategy); void InsertStrategy(Indicator indicator);
IEnumerable<Scenario> GetScenarios(); IEnumerable<Scenario> GetScenarios();
IEnumerable<Strategy> GetStrategies(); IEnumerable<Indicator> GetStrategies();
void DeleteScenario(string name); void DeleteScenario(string name);
void DeleteStrategy(string name); void DeleteStrategy(string name);
void DeleteScenarios(); void DeleteScenarios();
@@ -34,7 +34,7 @@ public interface ITradingService
IEnumerable<Trader> GetTradersWatch(); IEnumerable<Trader> GetTradersWatch();
void UpdateDeltaNeutralOpportunities(); void UpdateDeltaNeutralOpportunities();
void UpdateScenario(Scenario scenario); void UpdateScenario(Scenario scenario);
void UpdateStrategy(Strategy strategy); void UpdateStrategy(Indicator indicator);
Task<IEnumerable<Position>> GetBrokerPositions(Account account); Task<IEnumerable<Position>> GetBrokerPositions(Account account);
Task<PrivyInitAddressResponse> InitPrivyWallet(string publicAddress); Task<PrivyInitAddressResponse> InitPrivyWallet(string publicAddress);
} }

View File

@@ -61,8 +61,8 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var scenario = new Scenario("FlippingScenario"); var scenario = new Scenario("FlippingScenario");
var strategy = ScenarioHelpers.BuildStrategy(StrategyType.RsiDivergence, "RsiDiv", period: 14); var strategy = ScenarioHelpers.BuildIndicator(IndicatorType.RsiDivergence, "RsiDiv", period: 14);
scenario.AddStrategy(strategy); scenario.AddIndicator(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");
@@ -113,8 +113,8 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var scenario = new Scenario("ScalpingScenario"); var scenario = new Scenario("ScalpingScenario");
var strategy = ScenarioHelpers.BuildStrategy(StrategyType.RsiDivergence, "RsiDiv", period: 5); var strategy = ScenarioHelpers.BuildIndicator(IndicatorType.RsiDivergence, "RsiDiv", period: 5);
scenario.AddStrategy(strategy); scenario.AddIndicator(strategy);
var config = new TradingBotConfig var config = new TradingBotConfig
{ {
@@ -154,9 +154,9 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var scenario = new Scenario("ScalpingScenario"); var scenario = new Scenario("ScalpingScenario");
var strategy = ScenarioHelpers.BuildStrategy(StrategyType.MacdCross, "RsiDiv", fastPeriods: 12, var strategy = ScenarioHelpers.BuildIndicator(IndicatorType.MacdCross, "RsiDiv", fastPeriods: 12,
slowPeriods: 26, signalPeriods: 9); slowPeriods: 26, signalPeriods: 9);
scenario.AddStrategy(strategy); scenario.AddIndicator(strategy);
var moneyManagement = new MoneyManagement() var moneyManagement = new MoneyManagement()
{ {
@@ -198,9 +198,9 @@ namespace Managing.Application.Tests
} }
[Theory] [Theory]
[InlineData(Timeframe.FifteenMinutes, -6, StrategyType.Stc, BotType.ScalpingBot)] [InlineData(Timeframe.FifteenMinutes, -6, IndicatorType.Stc, BotType.ScalpingBot)]
//[InlineData(Timeframe.FifteenMinutes, -6, Enums.StrategyType.RsiDivergenceConfirm, Enums.BotType.FlippingBot)] //[InlineData(Timeframe.FifteenMinutes, -6, Enums.StrategyType.RsiDivergenceConfirm, Enums.BotType.FlippingBot)]
public void GetBestPeriodRsiForDivergenceFlippingBot(Timeframe timeframe, int days, StrategyType strategyType, public void GetBestPeriodRsiForDivergenceFlippingBot(Timeframe timeframe, int days, IndicatorType indicatorType,
BotType botType) BotType botType)
{ {
var result = new List<Tuple<string, int, decimal, decimal, decimal, decimal>>(); var result = new List<Tuple<string, int, decimal, decimal, decimal, decimal>>();
@@ -213,7 +213,7 @@ namespace Managing.Application.Tests
var periodRange = new List<int>() { 2, 7 }; var periodRange = new List<int>() { 2, 7 };
var stopLossRange = new List<decimal>() { 0.005m, 0.05m, 0.005m }; var stopLossRange = new List<decimal>() { 0.005m, 0.05m, 0.005m };
var takeProfitRange = new List<decimal>() { 0.01m, 0.1m, 0.02m }; var takeProfitRange = new List<decimal>() { 0.01m, 0.1m, 0.02m };
var fileIdentifier = $"{strategyType}-{timeframe}"; var fileIdentifier = $"{indicatorType}-{timeframe}";
var completedTest = 0; var completedTest = 0;
var totalTests = GetTotalTrades(periodRange, stopLossRange, takeProfitRange) * var totalTests = GetTotalTrades(periodRange, stopLossRange, takeProfitRange) *
Enum.GetNames(typeof(Ticker)).Length; Enum.GetNames(typeof(Ticker)).Length;
@@ -232,8 +232,8 @@ 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, "RsiDiv", period: i); var strategy = ScenarioHelpers.BuildIndicator(indicatorType, "RsiDiv", period: i);
scenario.AddStrategy(strategy); scenario.AddIndicator(strategy);
// -0.5 to -5 // -0.5 to -5
for (decimal s = stopLossRange[0]; s < stopLossRange[1]; s += stopLossRange[2]) for (decimal s = stopLossRange[0]; s < stopLossRange[1]; s += stopLossRange[2])
@@ -343,9 +343,9 @@ namespace Managing.Application.Tests
[Theory] [Theory]
[InlineData(Timeframe.OneHour, -30, StrategyType.MacdCross, BotType.FlippingBot)] [InlineData(Timeframe.OneHour, -30, IndicatorType.MacdCross, BotType.FlippingBot)]
[InlineData(Timeframe.OneHour, -30, StrategyType.MacdCross, BotType.ScalpingBot)] [InlineData(Timeframe.OneHour, -30, IndicatorType.MacdCross, BotType.ScalpingBot)]
public void GetBestMMForMacdFlippingBot(Timeframe timeframe, int days, StrategyType strategyType, public void GetBestMMForMacdFlippingBot(Timeframe timeframe, int days, IndicatorType indicatorType,
BotType botType) BotType botType)
{ {
var result = new List<Tuple<string, decimal, decimal, decimal, decimal>>(); var result = new List<Tuple<string, decimal, decimal, decimal, decimal>>();
@@ -357,7 +357,7 @@ namespace Managing.Application.Tests
var stopLossRange = new List<decimal>() { 0.005m, 0.05m, 0.005m }; var stopLossRange = new List<decimal>() { 0.005m, 0.05m, 0.005m };
var takeProfitRange = new List<decimal>() { 0.01m, 0.1m, 0.02m }; var takeProfitRange = new List<decimal>() { 0.01m, 0.1m, 0.02m };
var fileIdentifier = $"{strategyType}-{timeframe}-{botType}"; var fileIdentifier = $"{indicatorType}-{timeframe}-{botType}";
var completedTest = 0; var completedTest = 0;
var totalTests = GetTotalTradeForStopLossTakeProfit(stopLossRange, takeProfitRange) * var totalTests = GetTotalTradeForStopLossTakeProfit(stopLossRange, takeProfitRange) *
Enum.GetNames(typeof(Ticker)).Length; Enum.GetNames(typeof(Ticker)).Length;
@@ -374,9 +374,9 @@ namespace Managing.Application.Tests
return; return;
var scenario = new Scenario("ScalpingScenario"); var scenario = new Scenario("ScalpingScenario");
var strategy = ScenarioHelpers.BuildStrategy(strategyType, "RsiDiv", fastPeriods: 12, var strategy = ScenarioHelpers.BuildIndicator(indicatorType, "RsiDiv", fastPeriods: 12,
slowPeriods: 26, signalPeriods: 9); slowPeriods: 26, signalPeriods: 9);
scenario.AddStrategy(strategy); scenario.AddIndicator(strategy);
// -0.5 to -5 // -0.5 to -5
for (decimal s = stopLossRange[0]; s < stopLossRange[1]; s += stopLossRange[2]) for (decimal s = stopLossRange[0]; s < stopLossRange[1]; s += stopLossRange[2])
@@ -601,8 +601,8 @@ namespace Managing.Application.Tests
Console.WriteLine("\n=== EXAMPLE SCENARIOS ==="); Console.WriteLine("\n=== EXAMPLE SCENARIOS ===");
foreach (var scenario in scenarios.Take(3)) foreach (var scenario in scenarios.Take(3))
{ {
Console.WriteLine($"Scenario: {scenario.Name} ({scenario.Strategies.Count} strategies)"); Console.WriteLine($"Scenario: {scenario.Name} ({scenario.Indicators.Count} strategies)");
foreach (var strategy in scenario.Strategies) foreach (var strategy in scenario.Indicators)
{ {
Console.WriteLine($" - {strategy.Name} (Type: {strategy.Type})"); Console.WriteLine($" - {strategy.Name} (Type: {strategy.Type})");
} }
@@ -694,7 +694,7 @@ namespace Managing.Application.Tests
var scenarioResult = new ScenarioBacktestResult var scenarioResult = new ScenarioBacktestResult
{ {
ScenarioName = scenario.Name, ScenarioName = scenario.Name,
StrategyCount = scenario.Strategies.Count, StrategyCount = scenario.Indicators.Count,
Ticker = ticker.ToString(), Ticker = ticker.ToString(),
BotType = botType.ToString(), BotType = botType.ToString(),
FinalPnl = backtestResult.FinalPnl, FinalPnl = backtestResult.FinalPnl,
@@ -994,54 +994,56 @@ namespace Managing.Application.Tests
// Signal strategies // Signal strategies
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ {
Type = StrategyType.RsiDivergence, Name = "RSI_Divergence", ParameterSets = GetRsiDivergenceParameters() Type = IndicatorType.RsiDivergence, Name = "RSI_Divergence",
ParameterSets = GetRsiDivergenceParameters()
}); });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ {
Type = StrategyType.RsiDivergenceConfirm, Name = "RSI_Divergence_Confirm", Type = IndicatorType.RsiDivergenceConfirm, Name = "RSI_Divergence_Confirm",
ParameterSets = GetRsiDivergenceConfirmParameters() ParameterSets = GetRsiDivergenceConfirmParameters()
}); });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ Type = StrategyType.MacdCross, Name = "MACD_Cross", ParameterSets = GetMacdCrossParameters() }); { Type = IndicatorType.MacdCross, Name = "MACD_Cross", ParameterSets = GetMacdCrossParameters() });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ Type = StrategyType.EmaCross, Name = "EMA_Cross", ParameterSets = GetEmaCrossParameters() }); { Type = IndicatorType.EmaCross, Name = "EMA_Cross", ParameterSets = GetEmaCrossParameters() });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ {
Type = StrategyType.DualEmaCross, Name = "Dual_EMA_Cross", ParameterSets = GetDualEmaCrossParameters() Type = IndicatorType.DualEmaCross, Name = "Dual_EMA_Cross", ParameterSets = GetDualEmaCrossParameters()
}); });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ Type = StrategyType.SuperTrend, Name = "SuperTrend", ParameterSets = GetSuperTrendParameters() }); { Type = IndicatorType.SuperTrend, Name = "SuperTrend", ParameterSets = GetSuperTrendParameters() });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ {
Type = StrategyType.ChandelierExit, Name = "Chandelier_Exit", Type = IndicatorType.ChandelierExit, Name = "Chandelier_Exit",
ParameterSets = GetChandelierExitParameters() ParameterSets = GetChandelierExitParameters()
}); });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ Type = StrategyType.Stc, Name = "STC", ParameterSets = GetStcParameters() }); { Type = IndicatorType.Stc, Name = "STC", ParameterSets = GetStcParameters() });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ Type = StrategyType.LaggingStc, Name = "Lagging_STC", ParameterSets = GetLaggingStcParameters() }); { Type = IndicatorType.LaggingStc, Name = "Lagging_STC", ParameterSets = GetLaggingStcParameters() });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ {
Type = StrategyType.ThreeWhiteSoldiers, Name = "Three_White_Soldiers", Type = IndicatorType.ThreeWhiteSoldiers, Name = "Three_White_Soldiers",
ParameterSets = GetThreeWhiteSoldiersParameters() ParameterSets = GetThreeWhiteSoldiersParameters()
}); });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ {
Type = StrategyType.SuperTrendCrossEma, Name = "SuperTrend_Cross_EMA", Type = IndicatorType.SuperTrendCrossEma, Name = "SuperTrend_Cross_EMA",
ParameterSets = GetSuperTrendCrossEmaParameters() ParameterSets = GetSuperTrendCrossEmaParameters()
}); });
// Trend strategies // Trend strategies
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ Type = StrategyType.EmaTrend, Name = "EMA_Trend", ParameterSets = GetEmaTrendParameters() }); { Type = IndicatorType.EmaTrend, Name = "EMA_Trend", ParameterSets = GetEmaTrendParameters() });
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ {
Type = StrategyType.StochRsiTrend, Name = "StochRSI_Trend", ParameterSets = GetStochRsiTrendParameters() Type = IndicatorType.StochRsiTrend, Name = "StochRSI_Trend",
ParameterSets = GetStochRsiTrendParameters()
}); });
// Context strategies // Context strategies
strategies.Add(new StrategyConfiguration strategies.Add(new StrategyConfiguration
{ Type = StrategyType.StDev, Name = "Standard_Deviation", ParameterSets = GetStDevParameters() }); { Type = IndicatorType.StDev, Name = "Standard_Deviation", ParameterSets = GetStDevParameters() });
return strategies; return strategies;
} }
@@ -1097,7 +1099,7 @@ namespace Managing.Application.Tests
foreach (var (strategyConfig, parameterSet) in strategyParams) foreach (var (strategyConfig, parameterSet) in strategyParams)
{ {
var strategy = ScenarioHelpers.BuildStrategy( var strategy = ScenarioHelpers.BuildIndicator(
strategyConfig.Type, strategyConfig.Type,
$"{strategyConfig.Name}_{parameterSet.Name}", $"{strategyConfig.Name}_{parameterSet.Name}",
period: parameterSet.Period, period: parameterSet.Period,
@@ -1109,7 +1111,7 @@ namespace Managing.Application.Tests
smoothPeriods: parameterSet.SmoothPeriods, smoothPeriods: parameterSet.SmoothPeriods,
cyclePeriods: parameterSet.CyclePeriods); cyclePeriods: parameterSet.CyclePeriods);
scenario.AddStrategy(strategy); scenario.AddIndicator(strategy);
} }
return scenario; return scenario;
@@ -1449,7 +1451,7 @@ namespace Managing.Application.Tests
public class StrategyConfiguration public class StrategyConfiguration
{ {
public StrategyType Type { get; set; } public IndicatorType Type { get; set; }
public string Name { get; set; } public string Name { get; set; }
public List<ParameterSet> ParameterSets { get; set; } = new(); public List<ParameterSet> ParameterSets { get; set; } = new();
} }

View File

@@ -8,11 +8,11 @@ using static Managing.Common.Enums;
namespace Managing.Application.Tests namespace Managing.Application.Tests
{ {
public class StrategyTests public class IndicatorTests
{ {
private readonly IExchangeService _exchangeService; private readonly IExchangeService _exchangeService;
public StrategyTests() public IndicatorTests()
{ {
_exchangeService = TradingBaseTests.GetExchangeService(); _exchangeService = TradingBaseTests.GetExchangeService();
} }
@@ -24,7 +24,7 @@ namespace Managing.Application.Tests
{ {
var account = GetAccount(exchange); var account = GetAccount(exchange);
// Arrange // Arrange
var rsiStrategy = new RsiDivergenceStrategy("unittest", 5); var rsiStrategy = new RsiDivergenceIndicator("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>();
@@ -58,7 +58,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var rsiStrategy = new RsiDivergenceStrategy("unittest", 5); var rsiStrategy = new RsiDivergenceIndicator("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>();
@@ -85,7 +85,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var rsiStrategy = new MacdCrossStrategy("unittest", 12, 26, 9); var rsiStrategy = new MacdCrossIndicator("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>();
@@ -112,7 +112,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var superTrendStrategy = new SuperTrendStrategy("unittest", 10, 3); var superTrendStrategy = new SuperTrendIndicator("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>();
@@ -139,7 +139,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var chandelierExitStrategy = new ChandelierExitStrategy("unittest", 22, 3); var chandelierExitStrategy = new ChandelierExitIndicator("unittest", 22, 3);
var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe, false) var candles = _exchangeService.GetCandles(account, ticker, DateTime.Now.AddDays(days), timeframe, false)
.Result; .Result;
var resultSignal = new List<Signal>(); var resultSignal = new List<Signal>();
@@ -167,7 +167,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var emaTrendSrategy = new EmaTrendStrategy("unittest", 200); var emaTrendSrategy = new EmaTrendIndicator("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>();
@@ -195,7 +195,7 @@ namespace Managing.Application.Tests
{ {
// Arrange // Arrange
var account = GetAccount(exchange); var account = GetAccount(exchange);
var stochRsiStrategy = new StochRsiTrendStrategy("unittest", 14, 14, 3, 1); var stochRsiStrategy = new StochRsiTrendIndicator("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

@@ -9,12 +9,12 @@ namespace Managing.Application.Abstractions
{ {
IEnumerable<Scenario> GetScenarios(); IEnumerable<Scenario> GetScenarios();
Scenario CreateScenario(string name, List<string> strategies, int? loopbackPeriod = 1); Scenario CreateScenario(string name, List<string> strategies, int? loopbackPeriod = 1);
IEnumerable<Strategy> GetStrategies(); IEnumerable<Indicator> 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, Indicator CreateStrategy(IndicatorType type,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -29,18 +29,18 @@ namespace Managing.Application.Abstractions
bool DeleteScenarios(); bool DeleteScenarios();
bool UpdateScenario(string name, List<string> strategies, int? loopbackPeriod); bool UpdateScenario(string name, List<string> strategies, int? loopbackPeriod);
bool UpdateStrategy(StrategyType strategyType, string name, int? period, int? fastPeriods, int? slowPeriods, bool UpdateStrategy(IndicatorType indicatorType, string name, int? period, int? fastPeriods, int? slowPeriods,
int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods, int? cyclePeriods); int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods, int? cyclePeriods);
IEnumerable<Scenario> GetScenariosByUser(User user); IEnumerable<Scenario> GetScenariosByUser(User user);
Scenario CreateScenarioForUser(User user, string name, List<string> strategies, int? loopbackPeriod = 1); Scenario CreateScenarioForUser(User user, string name, List<string> strategies, int? loopbackPeriod = 1);
IEnumerable<Strategy> GetStrategiesByUser(User user); IEnumerable<Indicator> GetIndicatorsByUser(User user);
bool DeleteStrategyByUser(User user, string name); bool DeleteIndicatorByUser(User user, string name);
bool DeleteScenarioByUser(User user, string name); bool DeleteScenarioByUser(User user, string name);
Scenario GetScenarioByUser(User user, string name); Scenario GetScenarioByUser(User user, string name);
Strategy CreateStrategyForUser(User user, Indicator CreateIndicatorForUser(User user,
StrategyType type, IndicatorType type,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -50,12 +50,13 @@ namespace Managing.Application.Abstractions
int? stochPeriods = null, int? stochPeriods = null,
int? smoothPeriods = null, int? smoothPeriods = null,
int? cyclePeriods = null); int? cyclePeriods = null);
bool DeleteStrategiesByUser(User user); bool DeleteStrategiesByUser(User user);
bool DeleteScenariosByUser(User user); bool DeleteScenariosByUser(User user);
bool UpdateScenarioByUser(User user, string name, List<string> strategies, int? loopbackPeriod); bool UpdateScenarioByUser(User user, string name, List<string> strategies, int? loopbackPeriod);
bool UpdateStrategyByUser(User user, StrategyType strategyType, string name, int? period, int? fastPeriods, bool UpdateIndicatorByUser(User user, IndicatorType indicatorType, string name, int? period, int? fastPeriods,
int? slowPeriods, int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods, int? cyclePeriods); int? slowPeriods, int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods,
int? cyclePeriods);
} }
} }

View File

@@ -14,13 +14,13 @@ namespace Managing.Application.Abstractions
{ {
TradingBotConfig Config { get; set; } TradingBotConfig Config { get; set; }
Account Account { get; set; } Account Account { get; set; }
HashSet<IStrategy> Strategies { get; set; } HashSet<IIndicator> Indicators { get; set; }
FixedSizeQueue<Candle> OptimizedCandles { get; set; } FixedSizeQueue<Candle> OptimizedCandles { get; set; }
HashSet<Candle> Candles { get; set; } HashSet<Candle> Candles { get; set; }
HashSet<Signal> Signals { get; set; } HashSet<Signal> Signals { get; set; }
List<Position> Positions { get; set; } List<Position> Positions { get; set; }
Dictionary<DateTime, decimal> WalletBalances { get; set; } Dictionary<DateTime, decimal> WalletBalances { get; set; }
Dictionary<StrategyType, StrategiesResultBase> StrategiesValues { get; set; } Dictionary<IndicatorType, IndicatorsResultBase> IndicatorsValues { get; set; }
DateTime StartupTime { get; set; } DateTime StartupTime { get; set; }
DateTime PreloadSince { get; set; } DateTime PreloadSince { get; set; }
int PreloadedCandlesCount { get; set; } int PreloadedCandlesCount { get; set; }
@@ -32,10 +32,10 @@ namespace Managing.Application.Abstractions
int GetWinRate(); int GetWinRate();
decimal GetProfitAndLoss(); decimal GetProfitAndLoss();
decimal GetTotalFees(); decimal GetTotalFees();
void LoadStrategies(IEnumerable<IStrategy> strategies); void LoadIndicators(IEnumerable<IIndicator> indicators);
void LoadScenario(string scenarioName); void LoadScenario(string scenarioName);
void LoadScenario(Scenario scenario); void LoadScenario(Scenario scenario);
void UpdateStrategiesValues(); void UpdateIndicatorsValues();
Task LoadAccount(); Task LoadAccount();
Task<Position> OpenPositionManually(TradeDirection direction); Task<Position> OpenPositionManually(TradeDirection direction);

View File

@@ -30,7 +30,7 @@ namespace Managing.Application.Backtesting
IExchangeService exchangeService, IExchangeService exchangeService,
IBotFactory botFactory, IBotFactory botFactory,
IBacktestRepository backtestRepository, IBacktestRepository backtestRepository,
ILogger<Backtester> logger, ILogger<Backtester> logger,
IScenarioService scenarioService, IScenarioService scenarioService,
IAccountService accountService) IAccountService accountService)
{ {
@@ -74,9 +74,9 @@ namespace Managing.Application.Backtesting
{ {
var account = await GetAccountFromConfig(config); var account = await GetAccountFromConfig(config);
var candles = GetCandles(account, config.Ticker, config.Timeframe, startDate, endDate); var candles = GetCandles(account, config.Ticker, config.Timeframe, startDate, endDate);
var result = await RunBacktestWithCandles(config, candles, user); var result = await RunBacktestWithCandles(config, candles, user);
// Set start and end dates // Set start and end dates
result.StartDate = startDate; result.StartDate = startDate;
result.EndDate = endDate; result.EndDate = endDate;
@@ -115,9 +115,9 @@ namespace Managing.Application.Backtesting
{ {
// Set FlipPosition based on BotType // Set FlipPosition based on BotType
config.FlipPosition = config.BotType == BotType.FlippingBot; config.FlipPosition = config.BotType == BotType.FlippingBot;
var tradingBot = _botFactory.CreateBacktestTradingBot(config); var tradingBot = _botFactory.CreateBacktestTradingBot(config);
// Load scenario - prefer Scenario object over ScenarioName // Load scenario - prefer Scenario object over ScenarioName
if (config.Scenario != null) if (config.Scenario != null)
{ {
@@ -129,9 +129,10 @@ namespace Managing.Application.Backtesting
} }
else else
{ {
throw new ArgumentException("Either Scenario object or ScenarioName must be provided in TradingBotConfig"); throw new ArgumentException(
"Either Scenario object or ScenarioName must be provided in TradingBotConfig");
} }
tradingBot.User = user; tradingBot.User = user;
await tradingBot.LoadAccount(); await tradingBot.LoadAccount();
@@ -153,9 +154,9 @@ namespace Managing.Application.Backtesting
return account; return account;
} }
return new Account return new Account
{ {
Name = config.AccountName, Name = config.AccountName,
Exchange = TradingExchanges.GmxV2 Exchange = TradingExchanges.GmxV2
}; };
} }
@@ -191,7 +192,7 @@ namespace Managing.Application.Backtesting
} }
bot.Candles = new HashSet<Candle>(candles); bot.Candles = new HashSet<Candle>(candles);
bot.UpdateStrategiesValues(); bot.UpdateIndicatorsValues();
var strategies = _scenarioService.GetStrategies(); var strategies = _scenarioService.GetStrategies();
var strategiesValues = GetStrategiesValues(strategies, candles); var strategiesValues = GetStrategiesValues(strategies, candles);
@@ -228,21 +229,21 @@ namespace Managing.Application.Backtesting
WalletBalances = bot.WalletBalances.ToList(), WalletBalances = bot.WalletBalances.ToList(),
Statistics = stats, Statistics = stats,
OptimizedMoneyManagement = optimizedMoneyManagement, OptimizedMoneyManagement = optimizedMoneyManagement,
StrategiesValues = AggregateValues(strategiesValues, bot.StrategiesValues), StrategiesValues = AggregateValues(strategiesValues, bot.IndicatorsValues),
Score = score Score = score
}; };
return result; return result;
} }
private Dictionary<StrategyType, StrategiesResultBase> AggregateValues( private Dictionary<IndicatorType, IndicatorsResultBase> AggregateValues(
Dictionary<StrategyType, StrategiesResultBase> strategiesValues, Dictionary<IndicatorType, IndicatorsResultBase> strategiesValues,
Dictionary<StrategyType, StrategiesResultBase> botStrategiesValues) Dictionary<IndicatorType, IndicatorsResultBase> botStrategiesValues)
{ {
// Foreach strategy type, only retrieve the values where the strategy is not present already in the bot // Foreach strategy type, only retrieve the values where the strategy is not present already in the bot
// Then, add the values to the bot values // Then, add the values to the bot values
var result = new Dictionary<StrategyType, StrategiesResultBase>(); var result = new Dictionary<IndicatorType, IndicatorsResultBase>();
foreach (var strategy in strategiesValues) foreach (var strategy in strategiesValues)
{ {
// if (!botStrategiesValues.ContainsKey(strategy.Key)) // if (!botStrategiesValues.ContainsKey(strategy.Key))
@@ -259,10 +260,10 @@ namespace Managing.Application.Backtesting
return result; return result;
} }
private Dictionary<StrategyType, StrategiesResultBase> GetStrategiesValues(IEnumerable<Strategy> strategies, private Dictionary<IndicatorType, IndicatorsResultBase> GetStrategiesValues(IEnumerable<Indicator> strategies,
List<Candle> candles) List<Candle> candles)
{ {
var strategiesValues = new Dictionary<StrategyType, StrategiesResultBase>(); var strategiesValues = new Dictionary<IndicatorType, IndicatorsResultBase>();
var fixedCandles = new FixedSizeQueue<Candle>(10000); var fixedCandles = new FixedSizeQueue<Candle>(10000);
foreach (var candle in candles) foreach (var candle in candles)
{ {
@@ -273,7 +274,7 @@ namespace Managing.Application.Backtesting
{ {
try try
{ {
var s = ScenarioHelpers.BuildStrategy(strategy, 10000); var s = ScenarioHelpers.BuildIndicator(strategy, 10000);
s.Candles = fixedCandles; s.Candles = fixedCandles;
strategiesValues[strategy.Type] = s.GetStrategyValues(); strategiesValues[strategy.Type] = s.GetStrategyValues();
} }

View File

@@ -30,13 +30,13 @@ public class TradingBot : Bot, ITradingBot
public TradingBotConfig Config { get; set; } public TradingBotConfig Config { get; set; }
public Account Account { get; set; } public Account Account { get; set; }
public HashSet<IStrategy> Strategies { get; set; } public HashSet<IIndicator> Indicators { get; set; }
public FixedSizeQueue<Candle> OptimizedCandles { get; set; } public FixedSizeQueue<Candle> OptimizedCandles { get; set; }
public HashSet<Candle> Candles { get; set; } public HashSet<Candle> Candles { get; set; }
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 Dictionary<DateTime, decimal> WalletBalances { get; set; } public Dictionary<DateTime, decimal> WalletBalances { get; set; }
public Dictionary<StrategyType, StrategiesResultBase> StrategiesValues { get; set; } public Dictionary<IndicatorType, IndicatorsResultBase> IndicatorsValues { get; set; }
public DateTime StartupTime { get; set; } public DateTime StartupTime { get; set; }
public DateTime PreloadSince { get; set; } public DateTime PreloadSince { get; set; }
public int PreloadedCandlesCount { get; set; } public int PreloadedCandlesCount { get; set; }
@@ -71,13 +71,13 @@ public class TradingBot : Bot, ITradingBot
Config = config; Config = config;
Strategies = new HashSet<IStrategy>(); Indicators = new HashSet<IIndicator>();
Signals = new HashSet<Signal>(); Signals = new HashSet<Signal>();
OptimizedCandles = new FixedSizeQueue<Candle>(600); OptimizedCandles = new FixedSizeQueue<Candle>(600);
Candles = new HashSet<Candle>(); Candles = new HashSet<Candle>();
Positions = new List<Position>(); Positions = new List<Position>();
WalletBalances = new Dictionary<DateTime, decimal>(); WalletBalances = new Dictionary<DateTime, decimal>();
StrategiesValues = new Dictionary<StrategyType, StrategiesResultBase>(); IndicatorsValues = new Dictionary<IndicatorType, IndicatorsResultBase>();
if (!Config.IsForBacktest) if (!Config.IsForBacktest)
{ {
@@ -141,7 +141,7 @@ public class TradingBot : Bot, ITradingBot
else else
{ {
Scenario = scenario; Scenario = scenario;
LoadStrategies(ScenarioHelpers.GetStrategiesFromScenario(scenario)); LoadIndicators(ScenarioHelpers.GetIndicatorsFromScenario(scenario));
} }
} }
@@ -155,15 +155,15 @@ public class TradingBot : Bot, ITradingBot
else else
{ {
Scenario = scenario; Scenario = scenario;
LoadStrategies(ScenarioHelpers.GetStrategiesFromScenario(scenario)); LoadIndicators(ScenarioHelpers.GetIndicatorsFromScenario(scenario));
} }
} }
public void LoadStrategies(IEnumerable<IStrategy> strategies) public void LoadIndicators(IEnumerable<IIndicator> indicators)
{ {
foreach (var strategy in strategies) foreach (var strategy in indicators)
{ {
Strategies.Add(strategy); Indicators.Add(strategy);
} }
} }
@@ -205,7 +205,7 @@ public class TradingBot : Bot, ITradingBot
if (!Config.IsForBacktest) if (!Config.IsForBacktest)
{ {
SaveBackup(); SaveBackup();
UpdateStrategiesValues(); UpdateIndicatorsValues();
} }
UpdateWalletBalances(); UpdateWalletBalances();
@@ -219,11 +219,11 @@ public class TradingBot : Bot, ITradingBot
} }
} }
public void UpdateStrategiesValues() public void UpdateIndicatorsValues()
{ {
foreach (var strategy in Strategies) foreach (var strategy in Indicators)
{ {
StrategiesValues[strategy.Type] = ((Strategy)strategy).GetStrategyValues(); IndicatorsValues[strategy.Type] = ((Indicator)strategy).GetStrategyValues();
} }
} }
@@ -260,7 +260,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, Scenario.LoopbackPeriod); var signal = TradingBox.GetSignal(candles.ToHashSet(), Indicators, Signals, Scenario.LoopbackPeriod);
if (signal == null) return; if (signal == null) return;
signal.User = Account.User; signal.User = Account.User;
@@ -325,7 +325,7 @@ public class TradingBot : Bot, ITradingBot
candle: positionCandle, candle: positionCandle,
date: position.Open.Date, date: position.Open.Date,
exchange: Account.Exchange, exchange: Account.Exchange,
strategyType: StrategyType.Stc, // Use a valid strategy type for recreated signals indicatorType: IndicatorType.Stc, // Use a valid strategy type for recreated signals
signalType: SignalType.Signal signalType: SignalType.Signal
); );
@@ -1311,7 +1311,7 @@ public class TradingBot : Bot, ITradingBot
// Create a fake signal for manual position opening // Create a fake signal for manual position opening
var signal = new Signal(Config.Ticker, direction, Confidence.Low, lastCandle, lastCandle.Date, var signal = new Signal(Config.Ticker, direction, Confidence.Low, lastCandle, lastCandle.Date,
TradingExchanges.GmxV2, TradingExchanges.GmxV2,
StrategyType.Stc, SignalType.Signal); IndicatorType.Stc, SignalType.Signal);
signal.Status = SignalStatus.WaitingForPosition; // Ensure status is correct signal.Status = SignalStatus.WaitingForPosition; // Ensure status is correct
signal.User = Account.User; // Assign user signal.User = Account.User; // Assign user

View File

@@ -2,11 +2,10 @@
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Domain.Scenarios; using Managing.Domain.Scenarios;
using Managing.Domain.Strategies; using Managing.Domain.Strategies;
using Managing.Domain.Users;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MongoDB.Driver; using MongoDB.Driver;
using static Managing.Common.Enums; using static Managing.Common.Enums;
using System.Collections.Generic;
using Managing.Domain.Users;
namespace Managing.Application.Scenarios namespace Managing.Application.Scenarios
{ {
@@ -27,7 +26,7 @@ namespace Managing.Application.Scenarios
foreach (var strategy in strategies) foreach (var strategy in strategies)
{ {
scenario.AddStrategy(_tradingService.GetStrategyByName(strategy)); scenario.AddIndicator(_tradingService.GetStrategyByName(strategy));
} }
try try
@@ -43,8 +42,8 @@ namespace Managing.Application.Scenarios
return scenario; return scenario;
} }
public Strategy CreateStrategy( public Indicator CreateStrategy(
StrategyType type, IndicatorType type,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -55,7 +54,7 @@ namespace Managing.Application.Scenarios
int? smoothPeriods = null, int? smoothPeriods = null,
int? cyclePeriods = null) int? cyclePeriods = null)
{ {
var strategy = ScenarioHelpers.BuildStrategy( var strategy = ScenarioHelpers.BuildIndicator(
type, type,
name, name,
period, period,
@@ -80,7 +79,7 @@ namespace Managing.Application.Scenarios
return _tradingService.GetScenarioByName(name); return _tradingService.GetScenarioByName(name);
} }
public IEnumerable<Strategy> GetStrategies() public IEnumerable<Indicator> GetStrategies()
{ {
return _tradingService.GetStrategies(); return _tradingService.GetStrategies();
} }
@@ -146,10 +145,10 @@ namespace Managing.Application.Scenarios
try try
{ {
var scenario = _tradingService.GetScenarioByName(name); var scenario = _tradingService.GetScenarioByName(name);
scenario.Strategies.Clear(); scenario.Indicators.Clear();
foreach (var strategy in strategies) foreach (var strategy in strategies)
{ {
scenario.AddStrategy(_tradingService.GetStrategyByName(strategy)); scenario.AddIndicator(_tradingService.GetStrategyByName(strategy));
} }
scenario.LoopbackPeriod = loopbackPeriod ?? 1; scenario.LoopbackPeriod = loopbackPeriod ?? 1;
@@ -163,14 +162,14 @@ namespace Managing.Application.Scenarios
} }
} }
public bool UpdateStrategy(StrategyType strategyType, string name, int? period, int? fastPeriods, public bool UpdateStrategy(IndicatorType indicatorType, string name, int? period, int? fastPeriods,
int? slowPeriods, int? slowPeriods,
int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods, int? cyclePeriods) int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods, int? cyclePeriods)
{ {
try try
{ {
var strategy = _tradingService.GetStrategyByName(name); var strategy = _tradingService.GetStrategyByName(name);
strategy.Type = strategyType; strategy.Type = indicatorType;
strategy.Period = period; strategy.Period = period;
strategy.FastPeriods = fastPeriods; strategy.FastPeriods = fastPeriods;
strategy.SlowPeriods = slowPeriods; strategy.SlowPeriods = slowPeriods;
@@ -203,13 +202,13 @@ namespace Managing.Application.Scenarios
{ {
User = user User = user
}; };
foreach (var strategyName in strategies) foreach (var strategyName in strategies)
{ {
var strategy = _tradingService.GetStrategyByName(strategyName); var strategy = _tradingService.GetStrategyByName(strategyName);
if (strategy != null && strategy.User?.Name == user.Name) if (strategy != null && strategy.User?.Name == user.Name)
{ {
scenario.AddStrategy(strategy); scenario.AddIndicator(strategy);
} }
} }
@@ -217,13 +216,13 @@ namespace Managing.Application.Scenarios
return scenario; return scenario;
} }
public IEnumerable<Strategy> GetStrategiesByUser(User user) public IEnumerable<Indicator> GetIndicatorsByUser(User user)
{ {
var strategies = _tradingService.GetStrategies(); var strategies = _tradingService.GetStrategies();
return strategies.Where(s => s.User?.Name == user.Name); return strategies.Where(s => s.User?.Name == user.Name);
} }
public bool DeleteStrategyByUser(User user, string name) public bool DeleteIndicatorByUser(User user, string name)
{ {
var strategy = _tradingService.GetStrategyByName(name); var strategy = _tradingService.GetStrategyByName(name);
if (strategy != null && strategy.User?.Name == user.Name) if (strategy != null && strategy.User?.Name == user.Name)
@@ -231,6 +230,7 @@ namespace Managing.Application.Scenarios
_tradingService.DeleteStrategy(strategy.Name); _tradingService.DeleteStrategy(strategy.Name);
return true; return true;
} }
return false; return false;
} }
@@ -242,6 +242,7 @@ namespace Managing.Application.Scenarios
_tradingService.DeleteScenario(scenario.Name); _tradingService.DeleteScenario(scenario.Name);
return true; return true;
} }
return false; return false;
} }
@@ -251,35 +252,35 @@ namespace Managing.Application.Scenarios
return scenario != null && scenario.User?.Name == user.Name ? scenario : null; return scenario != null && scenario.User?.Name == user.Name ? scenario : null;
} }
public Strategy CreateStrategyForUser(User user, StrategyType type, string name, int? period = null, public Indicator CreateIndicatorForUser(User user, IndicatorType type, string name, int? period = null,
int? fastPeriods = null, int? slowPeriods = null, int? signalPeriods = null, int? fastPeriods = null, int? slowPeriods = null, int? signalPeriods = null,
double? multiplier = null, int? stochPeriods = null, int? smoothPeriods = null, double? multiplier = null, int? stochPeriods = null, int? smoothPeriods = null,
int? cyclePeriods = null) int? cyclePeriods = null)
{ {
// Create a new strategy using the existing implementation // Create a new strategy using the existing implementation
var strategy = CreateStrategy(type, name, period, fastPeriods, slowPeriods, signalPeriods, var strategy = CreateStrategy(type, name, period, fastPeriods, slowPeriods, signalPeriods,
multiplier, stochPeriods, smoothPeriods, cyclePeriods); multiplier, stochPeriods, smoothPeriods, cyclePeriods);
// Set the user // Set the user
strategy.User = user; strategy.User = user;
// Update the strategy to save the user property // Update the strategy to save the user property
_tradingService.UpdateStrategy(strategy); _tradingService.UpdateStrategy(strategy);
return strategy; return strategy;
} }
public bool DeleteStrategiesByUser(User user) public bool DeleteStrategiesByUser(User user)
{ {
try try
{ {
var strategies = GetStrategiesByUser(user); var strategies = GetIndicatorsByUser(user);
foreach (var strategy in strategies) foreach (var strategy in strategies)
{ {
_tradingService.DeleteStrategy(strategy.Name); _tradingService.DeleteStrategy(strategy.Name);
} }
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@@ -294,12 +295,12 @@ namespace Managing.Application.Scenarios
try try
{ {
var scenarios = GetScenariosByUser(user); var scenarios = GetScenariosByUser(user);
foreach (var scenario in scenarios) foreach (var scenario in scenarios)
{ {
_tradingService.DeleteScenario(scenario.Name); _tradingService.DeleteScenario(scenario.Name);
} }
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@@ -317,7 +318,7 @@ namespace Managing.Application.Scenarios
return false; return false;
} }
scenario.Strategies.Clear(); scenario.Indicators.Clear();
scenario.LoopbackPeriod = loopbackPeriod ?? 1; scenario.LoopbackPeriod = loopbackPeriod ?? 1;
foreach (var strategyName in strategies) foreach (var strategyName in strategies)
@@ -325,7 +326,7 @@ namespace Managing.Application.Scenarios
var strategy = _tradingService.GetStrategyByName(strategyName); var strategy = _tradingService.GetStrategyByName(strategyName);
if (strategy != null && strategy.User?.Name == user.Name) if (strategy != null && strategy.User?.Name == user.Name)
{ {
scenario.AddStrategy(strategy); scenario.AddIndicator(strategy);
} }
} }
@@ -333,8 +334,8 @@ namespace Managing.Application.Scenarios
return true; return true;
} }
public bool UpdateStrategyByUser(User user, StrategyType strategyType, string name, int? period, public bool UpdateIndicatorByUser(User user, IndicatorType indicatorType, string name, int? period,
int? fastPeriods, int? slowPeriods, int? signalPeriods, double? multiplier, int? fastPeriods, int? slowPeriods, int? signalPeriods, double? multiplier,
int? stochPeriods, int? smoothPeriods, int? cyclePeriods) int? stochPeriods, int? smoothPeriods, int? cyclePeriods)
{ {
var strategy = _tradingService.GetStrategyByName(name); var strategy = _tradingService.GetStrategyByName(name);
@@ -344,9 +345,9 @@ namespace Managing.Application.Scenarios
} }
// Use the existing update strategy logic // Use the existing update strategy logic
var result = UpdateStrategy(strategyType, name, period, fastPeriods, slowPeriods, var result = UpdateStrategy(indicatorType, name, period, fastPeriods, slowPeriods,
signalPeriods, multiplier, stochPeriods, smoothPeriods, cyclePeriods); signalPeriods, multiplier, stochPeriods, smoothPeriods, cyclePeriods);
return result; return result;
} }
} }

View File

@@ -101,7 +101,7 @@ public class SettingsService : ISettingsService
private void SetupStochSTCTrend() private void SetupStochSTCTrend()
{ {
var name = "STCTrend"; var name = "STCTrend";
var strategy = _scenarioService.CreateStrategy(StrategyType.Stc, var strategy = _scenarioService.CreateStrategy(IndicatorType.Stc,
name, name,
fastPeriods: 23, fastPeriods: 23,
slowPeriods: 50, slowPeriods: 50,
@@ -112,7 +112,7 @@ public class SettingsService : ISettingsService
private void SetupMacd() private void SetupMacd()
{ {
var name = "MacdCross"; var name = "MacdCross";
var strategy = _scenarioService.CreateStrategy(StrategyType.MacdCross, var strategy = _scenarioService.CreateStrategy(IndicatorType.MacdCross,
name, name,
fastPeriods: 12, fastPeriods: 12,
slowPeriods: 26, slowPeriods: 26,
@@ -123,7 +123,7 @@ public class SettingsService : ISettingsService
private void SetupRsiDiv() private void SetupRsiDiv()
{ {
var name = "RsiDiv6"; var name = "RsiDiv6";
var strategy = _scenarioService.CreateStrategy(StrategyType.RsiDivergence, var strategy = _scenarioService.CreateStrategy(IndicatorType.RsiDivergence,
name, name,
period: 6); period: 6);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
@@ -132,7 +132,7 @@ public class SettingsService : ISettingsService
private void SetupRsiDivConfirm() private void SetupRsiDivConfirm()
{ {
var name = "RsiDivConfirm6"; var name = "RsiDivConfirm6";
var strategy = _scenarioService.CreateStrategy(StrategyType.RsiDivergenceConfirm, var strategy = _scenarioService.CreateStrategy(IndicatorType.RsiDivergenceConfirm,
name, name,
period: 6); period: 6);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
@@ -141,7 +141,7 @@ public class SettingsService : ISettingsService
private void SetupSuperTrend() private void SetupSuperTrend()
{ {
var name = "SuperTrend"; var name = "SuperTrend";
var strategy = _scenarioService.CreateStrategy(StrategyType.SuperTrend, var strategy = _scenarioService.CreateStrategy(IndicatorType.SuperTrend,
name, name,
period: 10, period: 10,
multiplier: 3); multiplier: 3);
@@ -151,7 +151,7 @@ public class SettingsService : ISettingsService
private void SetupChandelierExit() private void SetupChandelierExit()
{ {
var name = "ChandelierExit"; var name = "ChandelierExit";
var strategy = _scenarioService.CreateStrategy(StrategyType.ChandelierExit, var strategy = _scenarioService.CreateStrategy(IndicatorType.ChandelierExit,
name, name,
period: 22, period: 22,
multiplier: 3); multiplier: 3);
@@ -161,7 +161,7 @@ public class SettingsService : ISettingsService
private void SetupStochRsiTrend() private void SetupStochRsiTrend()
{ {
var name = "StochRsiTrend"; var name = "StochRsiTrend";
var strategy = _scenarioService.CreateStrategy(StrategyType.StochRsiTrend, var strategy = _scenarioService.CreateStrategy(IndicatorType.StochRsiTrend,
name, name,
period: 14, period: 14,
stochPeriods: 14, stochPeriods: 14,
@@ -173,7 +173,7 @@ public class SettingsService : ISettingsService
private void SetupEmaTrend() private void SetupEmaTrend()
{ {
var name = "Ema200Trend"; var name = "Ema200Trend";
var strategy = _scenarioService.CreateStrategy(StrategyType.EmaTrend, var strategy = _scenarioService.CreateStrategy(IndicatorType.EmaTrend,
name, name,
period: 200); period: 200);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
@@ -182,7 +182,7 @@ public class SettingsService : ISettingsService
private void SetupEmaCross() private void SetupEmaCross()
{ {
var name = "Ema200Cross"; var name = "Ema200Cross";
var strategy = _scenarioService.CreateStrategy(StrategyType.EmaCross, var strategy = _scenarioService.CreateStrategy(IndicatorType.EmaCross,
name, name,
period: 200); period: 200);
_scenarioService.CreateScenario(name, new List<string> { strategy.Name }); _scenarioService.CreateScenario(name, new List<string> { strategy.Name });
@@ -212,9 +212,9 @@ public class SettingsService : ISettingsService
await _moneyManagementService.CreateOrUpdateMoneyManagement(user, defaultMoneyManagement); await _moneyManagementService.CreateOrUpdateMoneyManagement(user, defaultMoneyManagement);
// Create default Strategy (StcTrend) // Create default Strategy (StcTrend)
var defaultStrategy = _scenarioService.CreateStrategyForUser( var defaultStrategy = _scenarioService.CreateIndicatorForUser(
user, user,
StrategyType.Stc, IndicatorType.Stc,
"Stc", "Stc",
period: null, period: null,
fastPeriods: 23, fastPeriods: 23,

View File

@@ -55,12 +55,12 @@ public class TradingService : ITradingService
public void DeleteStrategies() public void DeleteStrategies()
{ {
_tradingRepository.DeleteStrategies(); _tradingRepository.DeleteIndicators();
} }
public void DeleteStrategy(string name) public void DeleteStrategy(string name)
{ {
_tradingRepository.DeleteStrategy(name); _tradingRepository.DeleteIndicator(name);
} }
public Position GetPositionByIdentifier(string identifier) public Position GetPositionByIdentifier(string identifier)
@@ -89,12 +89,12 @@ public class TradingService : ITradingService
return _tradingRepository.GetScenarios(); return _tradingRepository.GetScenarios();
} }
public IEnumerable<Strategy> GetStrategies() public IEnumerable<Indicator> GetStrategies()
{ {
return _tradingRepository.GetStrategies(); return _tradingRepository.GetIndicators();
} }
public Strategy GetStrategyByName(string strategy) public Indicator GetStrategyByName(string strategy)
{ {
return _tradingRepository.GetStrategyByName(strategy); return _tradingRepository.GetStrategyByName(strategy);
} }
@@ -114,9 +114,9 @@ public class TradingService : ITradingService
_tradingRepository.InsertSignal(signal); _tradingRepository.InsertSignal(signal);
} }
public void InsertStrategy(Strategy strategy) public void InsertStrategy(Indicator indicator)
{ {
_tradingRepository.InsertStrategy(strategy); _tradingRepository.InsertStrategy(indicator);
} }
public async Task<Position> ManagePosition(Account account, Position position) public async Task<Position> ManagePosition(Account account, Position position)
@@ -276,9 +276,9 @@ public class TradingService : ITradingService
_tradingRepository.UpdateScenario(scenario); _tradingRepository.UpdateScenario(scenario);
} }
public void UpdateStrategy(Strategy strategy) public void UpdateStrategy(Indicator indicator)
{ {
_tradingRepository.UpdateStrategy(strategy); _tradingRepository.UpdateStrategy(indicator);
} }
public async Task<IEnumerable<Position>> GetBrokerPositions(Account account) public async Task<IEnumerable<Position>> GetBrokerPositions(Account account)
@@ -385,7 +385,8 @@ public class TradingService : ITradingService
if (string.IsNullOrEmpty(publicAddress)) if (string.IsNullOrEmpty(publicAddress))
{ {
_logger.LogWarning("Attempted to initialize Privy wallet with null or empty public address"); _logger.LogWarning("Attempted to initialize Privy wallet with null or empty public address");
return new PrivyInitAddressResponse { Success = false, Error = "Public address cannot be null or empty" }; return new PrivyInitAddressResponse
{ Success = false, Error = "Public address cannot be null or empty" };
} }
return await _evmManager.InitAddress(publicAddress); return await _evmManager.InitAddress(publicAddress);

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.Period); var strategy = new RsiDivergenceIndicator(Name, RsiDivParameters.Period);
strategy.UpdateCandles(candles); strategy.UpdateCandles(candles);
strategy.Run(); strategy.Run();

View File

@@ -48,7 +48,7 @@ public static class Enums
FlippingBot FlippingBot
} }
public enum StrategyType public enum IndicatorType
{ {
RsiDivergence, RsiDivergence,
RsiDivergenceConfirm, RsiDivergenceConfirm,

View File

@@ -24,7 +24,7 @@ public class Backtest
Signals = signals; Signals = signals;
Candles = candles; Candles = candles;
WalletBalances = new List<KeyValuePair<DateTime, decimal>>(); WalletBalances = new List<KeyValuePair<DateTime, decimal>>();
StrategiesValues = new Dictionary<StrategyType, StrategiesResultBase>(); StrategiesValues = new Dictionary<IndicatorType, IndicatorsResultBase>();
// Initialize start and end dates if candles are provided // Initialize start and end dates if candles are provided
if (candles != null && candles.Count > 0) if (candles != null && candles.Count > 0)
@@ -55,7 +55,7 @@ public class Backtest
[Required] public List<KeyValuePair<DateTime, decimal>> WalletBalances { get; set; } [Required] public List<KeyValuePair<DateTime, decimal>> WalletBalances { get; set; }
[Required] public MoneyManagement OptimizedMoneyManagement { get; set; } [Required] public MoneyManagement OptimizedMoneyManagement { get; set; }
[Required] public User User { get; set; } [Required] public User User { get; set; }
[Required] public Dictionary<StrategyType, StrategiesResultBase> StrategiesValues { get; set; } [Required] public Dictionary<IndicatorType, IndicatorsResultBase> StrategiesValues { get; set; }
[Required] public double Score { get; set; } [Required] public double Score { get; set; }
/// <summary> /// <summary>
@@ -130,12 +130,12 @@ public class Backtest
public string GetStringReport() public string GetStringReport()
{ {
var timeBasedInfo = Config.MaxPositionTimeHours.HasValue var timeBasedInfo = Config.MaxPositionTimeHours.HasValue
? $" | MaxTime: {Config.MaxPositionTimeHours}h" ? $" | MaxTime: {Config.MaxPositionTimeHours}h"
: " | MaxTime: Disabled"; : " | MaxTime: Disabled";
var flipInfo = Config.FlipPosition var flipInfo = Config.FlipPosition
? $" | Flip: {(Config.FlipOnlyWhenInProfit ? "Profit-Only" : "Always")}" ? $" | Flip: {(Config.FlipOnlyWhenInProfit ? "Profit-Only" : "Always")}"
: ""; : "";
return return

View File

@@ -8,18 +8,18 @@ namespace Managing.Domain.Scenarios
public Scenario(string name, int? loopbackPeriod = 1) public Scenario(string name, int? loopbackPeriod = 1)
{ {
Name = name; Name = name;
Strategies = new List<Strategy>(); Indicators = new List<Indicator>();
LoopbackPeriod = loopbackPeriod; LoopbackPeriod = loopbackPeriod;
} }
public string Name { get; set; } public string Name { get; set; }
public List<Strategy> Strategies { get; set; } public List<Indicator> Indicators { get; set; }
public int? LoopbackPeriod { get; set; } public int? LoopbackPeriod { get; set; }
public User User { get; set; } public User User { get; set; }
public void AddStrategy(Strategy strategy) public void AddIndicator(Indicator indicator)
{ {
Strategies.Add(strategy); Indicators.Add(indicator);
} }
} }
} }

View File

@@ -10,48 +10,48 @@ namespace Managing.Domain.Scenarios;
public static class ScenarioHelpers public static class ScenarioHelpers
{ {
public static IEnumerable<IStrategy> GetStrategiesFromScenario(Scenario scenario) public static IEnumerable<IIndicator> GetIndicatorsFromScenario(Scenario scenario)
{ {
var strategies = new List<IStrategy>(); var strategies = new List<IIndicator>();
foreach (var strategy in scenario.Strategies) foreach (var strategy in scenario.Indicators)
{ {
var result = BuildStrategy(strategy); var result = BuildIndicator(strategy);
strategies.Add(result); strategies.Add(result);
} }
return strategies; return strategies;
} }
public static IStrategy BuildStrategy(Strategy strategy, int size = 600) public static IIndicator BuildIndicator(Indicator indicator, int size = 600)
{ {
IStrategy result = strategy.Type switch IIndicator result = indicator.Type switch
{ {
StrategyType.StDev => new StDevContext(strategy.Name, strategy.Period.Value), IndicatorType.StDev => new StDevContext(indicator.Name, indicator.Period.Value),
StrategyType.RsiDivergence => new RsiDivergenceStrategy(strategy.Name, IndicatorType.RsiDivergence => new RsiDivergenceIndicator(indicator.Name,
strategy.Period.Value), indicator.Period.Value),
StrategyType.RsiDivergenceConfirm => new RsiDivergenceConfirmStrategy(strategy.Name, IndicatorType.RsiDivergenceConfirm => new RsiDivergenceConfirmIndicator(indicator.Name,
strategy.Period.Value), indicator.Period.Value),
StrategyType.MacdCross => new MacdCrossStrategy(strategy.Name, IndicatorType.MacdCross => new MacdCrossIndicator(indicator.Name,
strategy.FastPeriods.Value, strategy.SlowPeriods.Value, strategy.SignalPeriods.Value), indicator.FastPeriods.Value, indicator.SlowPeriods.Value, indicator.SignalPeriods.Value),
StrategyType.EmaCross => new EmaCrossStrategy(strategy.Name, strategy.Period.Value), IndicatorType.EmaCross => new EmaCrossIndicator(indicator.Name, indicator.Period.Value),
StrategyType.DualEmaCross => new DualEmaCrossStrategy(strategy.Name, IndicatorType.DualEmaCross => new DualEmaCrossIndicator(indicator.Name,
strategy.FastPeriods.Value, strategy.SlowPeriods.Value), indicator.FastPeriods.Value, indicator.SlowPeriods.Value),
StrategyType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersStrategy(strategy.Name, IndicatorType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersIndicator(indicator.Name,
strategy.Period.Value), indicator.Period.Value),
StrategyType.SuperTrend => new SuperTrendStrategy(strategy.Name, IndicatorType.SuperTrend => new SuperTrendIndicator(indicator.Name,
strategy.Period.Value, strategy.Multiplier.Value), indicator.Period.Value, indicator.Multiplier.Value),
StrategyType.ChandelierExit => new ChandelierExitStrategy(strategy.Name, IndicatorType.ChandelierExit => new ChandelierExitIndicator(indicator.Name,
strategy.Period.Value, strategy.Multiplier.Value), indicator.Period.Value, indicator.Multiplier.Value),
StrategyType.EmaTrend => new EmaTrendStrategy(strategy.Name, strategy.Period.Value), IndicatorType.EmaTrend => new EmaTrendIndicator(indicator.Name, indicator.Period.Value),
StrategyType.StochRsiTrend => new StochRsiTrendStrategy(strategy.Name, IndicatorType.StochRsiTrend => new StochRsiTrendIndicator(indicator.Name,
strategy.Period.Value, strategy.StochPeriods.Value, strategy.SignalPeriods.Value, indicator.Period.Value, indicator.StochPeriods.Value, indicator.SignalPeriods.Value,
strategy.SmoothPeriods.Value), indicator.SmoothPeriods.Value),
StrategyType.Stc => new StcStrategy(strategy.Name, strategy.CyclePeriods.Value, IndicatorType.Stc => new StcIndicator(indicator.Name, indicator.CyclePeriods.Value,
strategy.FastPeriods.Value, strategy.SlowPeriods.Value), indicator.FastPeriods.Value, indicator.SlowPeriods.Value),
StrategyType.LaggingStc => new LaggingSTC(strategy.Name, strategy.CyclePeriods.Value, IndicatorType.LaggingStc => new LaggingSTC(indicator.Name, indicator.CyclePeriods.Value,
strategy.FastPeriods.Value, strategy.SlowPeriods.Value), indicator.FastPeriods.Value, indicator.SlowPeriods.Value),
StrategyType.SuperTrendCrossEma => new SuperTrendCrossEma(strategy.Name, IndicatorType.SuperTrendCrossEma => new SuperTrendCrossEma(indicator.Name,
strategy.Period.Value, strategy.Multiplier.Value), indicator.Period.Value, indicator.Multiplier.Value),
_ => throw new NotImplementedException(), _ => throw new NotImplementedException(),
}; };
@@ -59,8 +59,8 @@ public static class ScenarioHelpers
return result; return result;
} }
public static Strategy BuildStrategy( public static Indicator BuildIndicator(
StrategyType type, IndicatorType type,
string name, string name,
int? period = null, int? period = null,
int? fastPeriods = null, int? fastPeriods = null,
@@ -71,98 +71,98 @@ public static class ScenarioHelpers
int? smoothPeriods = null, int? smoothPeriods = null,
int? cyclePeriods = null) int? cyclePeriods = null)
{ {
var strategy = new Strategy(name, type); var indicator = new Indicator(name, type);
switch (type) switch (type)
{ {
case StrategyType.RsiDivergence: case IndicatorType.RsiDivergence:
case StrategyType.RsiDivergenceConfirm: case IndicatorType.RsiDivergenceConfirm:
case StrategyType.EmaTrend: case IndicatorType.EmaTrend:
case StrategyType.EmaCross: case IndicatorType.EmaCross:
case StrategyType.StDev: case IndicatorType.StDev:
if (!period.HasValue) if (!period.HasValue)
{ {
throw new Exception($"Missing period for {strategy.Type} strategy type"); throw new Exception($"Missing period for {indicator.Type} strategy type");
} }
else else
{ {
strategy.Period = period.Value; indicator.Period = period.Value;
} }
break; break;
case StrategyType.MacdCross: case IndicatorType.MacdCross:
if (!fastPeriods.HasValue || !slowPeriods.HasValue || !signalPeriods.HasValue) if (!fastPeriods.HasValue || !slowPeriods.HasValue || !signalPeriods.HasValue)
{ {
throw new Exception( throw new Exception(
$"Missing fastPeriods or slowPeriods or signalPeriods, for {strategy.Type} strategy type"); $"Missing fastPeriods or slowPeriods or signalPeriods, for {indicator.Type} strategy type");
} }
else else
{ {
strategy.FastPeriods = fastPeriods; indicator.FastPeriods = fastPeriods;
strategy.SlowPeriods = slowPeriods; indicator.SlowPeriods = slowPeriods;
strategy.SignalPeriods = signalPeriods; indicator.SignalPeriods = signalPeriods;
} }
break; break;
case StrategyType.DualEmaCross: case IndicatorType.DualEmaCross:
if (!fastPeriods.HasValue || !slowPeriods.HasValue) if (!fastPeriods.HasValue || !slowPeriods.HasValue)
{ {
throw new Exception( throw new Exception(
$"Missing fastPeriods or slowPeriods for {strategy.Type} strategy type"); $"Missing fastPeriods or slowPeriods for {indicator.Type} strategy type");
} }
else else
{ {
strategy.FastPeriods = fastPeriods; indicator.FastPeriods = fastPeriods;
strategy.SlowPeriods = slowPeriods; indicator.SlowPeriods = slowPeriods;
} }
break; break;
case StrategyType.ThreeWhiteSoldiers: case IndicatorType.ThreeWhiteSoldiers:
break; break;
case StrategyType.SuperTrend: case IndicatorType.SuperTrend:
case StrategyType.SuperTrendCrossEma: case IndicatorType.SuperTrendCrossEma:
case StrategyType.ChandelierExit: case IndicatorType.ChandelierExit:
if (!period.HasValue || !multiplier.HasValue) if (!period.HasValue || !multiplier.HasValue)
{ {
throw new Exception($"Missing period or multiplier, for {strategy.Type} strategy type"); throw new Exception($"Missing period or multiplier, for {indicator.Type} strategy type");
} }
else else
{ {
strategy.Period = period; indicator.Period = period;
strategy.Multiplier = multiplier; indicator.Multiplier = multiplier;
} }
break; break;
case StrategyType.StochRsiTrend: case IndicatorType.StochRsiTrend:
if (!period.HasValue if (!period.HasValue
|| !stochPeriods.HasValue || !stochPeriods.HasValue
|| !signalPeriods.HasValue || !signalPeriods.HasValue
|| !smoothPeriods.HasValue) || !smoothPeriods.HasValue)
{ {
throw new Exception( throw new Exception(
$"Missing period, stochPeriods, signalPeriods, smoothPeriods for {strategy.Type} strategy type"); $"Missing period, stochPeriods, signalPeriods, smoothPeriods for {indicator.Type} strategy type");
} }
else else
{ {
strategy.Period = period; indicator.Period = period;
strategy.StochPeriods = stochPeriods; indicator.StochPeriods = stochPeriods;
strategy.SignalPeriods = signalPeriods; indicator.SignalPeriods = signalPeriods;
strategy.SmoothPeriods = smoothPeriods; indicator.SmoothPeriods = smoothPeriods;
} }
break; break;
case StrategyType.Stc: case IndicatorType.Stc:
case StrategyType.LaggingStc: case IndicatorType.LaggingStc:
if (!fastPeriods.HasValue || !slowPeriods.HasValue || !cyclePeriods.HasValue) if (!fastPeriods.HasValue || !slowPeriods.HasValue || !cyclePeriods.HasValue)
{ {
throw new Exception( throw new Exception(
$"Missing fastPeriods or slowPeriods or cyclePeriods, for {strategy.Type} strategy type"); $"Missing fastPeriods or slowPeriods or cyclePeriods, for {indicator.Type} strategy type");
} }
else else
{ {
strategy.FastPeriods = fastPeriods; indicator.FastPeriods = fastPeriods;
strategy.SlowPeriods = slowPeriods; indicator.SlowPeriods = slowPeriods;
strategy.CyclePeriods = cyclePeriods; indicator.CyclePeriods = cyclePeriods;
} }
break; break;
@@ -170,28 +170,28 @@ public static class ScenarioHelpers
break; break;
} }
return strategy; return indicator;
} }
public static SignalType GetSignalType(StrategyType type) public static SignalType GetSignalType(IndicatorType type)
{ {
return type switch return type switch
{ {
StrategyType.RsiDivergence => SignalType.Signal, IndicatorType.RsiDivergence => SignalType.Signal,
StrategyType.RsiDivergenceConfirm => SignalType.Signal, IndicatorType.RsiDivergenceConfirm => SignalType.Signal,
StrategyType.MacdCross => SignalType.Signal, IndicatorType.MacdCross => SignalType.Signal,
StrategyType.EmaCross => SignalType.Signal, IndicatorType.EmaCross => SignalType.Signal,
StrategyType.DualEmaCross => SignalType.Signal, IndicatorType.DualEmaCross => SignalType.Signal,
StrategyType.ThreeWhiteSoldiers => SignalType.Signal, IndicatorType.ThreeWhiteSoldiers => SignalType.Signal,
StrategyType.SuperTrend => SignalType.Signal, IndicatorType.SuperTrend => SignalType.Signal,
StrategyType.ChandelierExit => SignalType.Signal, IndicatorType.ChandelierExit => SignalType.Signal,
StrategyType.EmaTrend => SignalType.Trend, IndicatorType.EmaTrend => SignalType.Trend,
StrategyType.Composite => SignalType.Signal, IndicatorType.Composite => SignalType.Signal,
StrategyType.StochRsiTrend => SignalType.Trend, IndicatorType.StochRsiTrend => SignalType.Trend,
StrategyType.Stc => SignalType.Signal, IndicatorType.Stc => SignalType.Signal,
StrategyType.StDev => SignalType.Context, IndicatorType.StDev => SignalType.Context,
StrategyType.LaggingStc => SignalType.Signal, IndicatorType.LaggingStc => SignalType.Signal,
StrategyType.SuperTrendCrossEma => SignalType.Signal, IndicatorType.SuperTrendCrossEma => SignalType.Signal,
_ => throw new NotImplementedException(), _ => throw new NotImplementedException(),
}; };
} }

View File

@@ -10,7 +10,7 @@ namespace Managing.Domain.Shared.Helpers;
/// <summary> /// <summary>
/// Configuration for strategy combination logic /// Configuration for strategy combination logic
/// </summary> /// </summary>
public class StrategyComboConfig public class IndicatorComboConfig
{ {
/// <summary> /// <summary>
/// Minimum percentage of trend strategies that must agree for strong trend (default: 66%) /// Minimum percentage of trend strategies that must agree for strong trend (default: 66%)
@@ -47,16 +47,16 @@ public class StrategyComboConfig
public static class TradingBox public static class TradingBox
{ {
private static readonly StrategyComboConfig _defaultConfig = new(); private static readonly IndicatorComboConfig _defaultConfig = new();
public static Signal GetSignal(HashSet<Candle> newCandles, HashSet<IStrategy> strategies, public static Signal GetSignal(HashSet<Candle> newCandles, HashSet<IIndicator> strategies,
HashSet<Signal> previousSignal, int? loopbackPeriod = 1) HashSet<Signal> previousSignal, int? loopbackPeriod = 1)
{ {
return GetSignal(newCandles, strategies, previousSignal, _defaultConfig, loopbackPeriod); return GetSignal(newCandles, strategies, previousSignal, _defaultConfig, loopbackPeriod);
} }
public static Signal GetSignal(HashSet<Candle> newCandles, HashSet<IStrategy> strategies, public static Signal GetSignal(HashSet<Candle> newCandles, HashSet<IIndicator> strategies,
HashSet<Signal> previousSignal, StrategyComboConfig config, int? loopbackPeriod = 1) HashSet<Signal> previousSignal, IndicatorComboConfig config, 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();
@@ -120,14 +120,14 @@ public static class TradingBox
data.Timeframe, config); data.Timeframe, config);
} }
public static Signal ComputeSignals(HashSet<IStrategy> strategies, HashSet<Signal> signalOnCandles, Ticker ticker, public static Signal ComputeSignals(HashSet<IIndicator> strategies, HashSet<Signal> signalOnCandles, Ticker ticker,
Timeframe timeframe) Timeframe timeframe)
{ {
return ComputeSignals(strategies, signalOnCandles, ticker, timeframe, _defaultConfig); return ComputeSignals(strategies, signalOnCandles, ticker, timeframe, _defaultConfig);
} }
public static Signal ComputeSignals(HashSet<IStrategy> strategies, HashSet<Signal> signalOnCandles, Ticker ticker, public static Signal ComputeSignals(HashSet<IIndicator> strategies, HashSet<Signal> signalOnCandles, Ticker ticker,
Timeframe timeframe, StrategyComboConfig config) Timeframe timeframe, IndicatorComboConfig config)
{ {
if (strategies.Count == 1) if (strategies.Count == 1)
{ {
@@ -179,15 +179,15 @@ public static class TradingBox
lastSignal?.Candle, lastSignal?.Candle,
lastSignal?.Date ?? DateTime.UtcNow, lastSignal?.Date ?? DateTime.UtcNow,
lastSignal?.Exchange ?? config.DefaultExchange, lastSignal?.Exchange ?? config.DefaultExchange,
StrategyType.Composite, IndicatorType.Composite,
SignalType.Signal); SignalType.Signal);
} }
/// <summary> /// <summary>
/// Validates context strategies based on confidence levels indicating market condition quality /// Validates context strategies based on confidence levels indicating market condition quality
/// </summary> /// </summary>
private static bool ValidateContextStrategies(HashSet<IStrategy> allStrategies, List<Signal> contextSignals, private static bool ValidateContextStrategies(HashSet<IIndicator> allStrategies, List<Signal> contextSignals,
StrategyComboConfig config) IndicatorComboConfig config)
{ {
var contextStrategiesCount = allStrategies.Count(s => s.SignalType == SignalType.Context); var contextStrategiesCount = allStrategies.Count(s => s.SignalType == SignalType.Context);
@@ -210,7 +210,7 @@ public static class TradingBox
/// <summary> /// <summary>
/// Evaluates trend direction using majority voting with neutral handling /// Evaluates trend direction using majority voting with neutral handling
/// </summary> /// </summary>
private static TradeDirection EvaluateTrendDirection(List<Signal> trendSignals, StrategyComboConfig config) private static TradeDirection EvaluateTrendDirection(List<Signal> trendSignals, IndicatorComboConfig config)
{ {
if (!trendSignals.Any()) if (!trendSignals.Any())
{ {
@@ -241,7 +241,7 @@ public static class TradingBox
/// <summary> /// <summary>
/// Evaluates signal direction using weighted majority voting /// Evaluates signal direction using weighted majority voting
/// </summary> /// </summary>
private static TradeDirection EvaluateSignalDirection(List<Signal> signalStrategies, StrategyComboConfig config) private static TradeDirection EvaluateSignalDirection(List<Signal> signalStrategies, IndicatorComboConfig config)
{ {
if (!signalStrategies.Any()) if (!signalStrategies.Any())
{ {
@@ -270,7 +270,7 @@ public static class TradingBox
TradeDirection trendDirection, TradeDirection trendDirection,
List<Signal> signalStrategies, List<Signal> signalStrategies,
List<Signal> trendStrategies, List<Signal> trendStrategies,
StrategyComboConfig config) IndicatorComboConfig config)
{ {
// Priority 1: If we have signal strategies, they take precedence // Priority 1: If we have signal strategies, they take precedence
if (signalDirection != TradeDirection.None) if (signalDirection != TradeDirection.None)

View File

@@ -4,9 +4,9 @@ using Skender.Stock.Indicators;
namespace Managing.Domain.Strategies.Base; namespace Managing.Domain.Strategies.Base;
public abstract class EmaBaseStrategy : Strategy public abstract class EmaBaseIndicator : Indicator
{ {
protected EmaBaseStrategy(string name, Enums.StrategyType type) : base(name, type) protected EmaBaseIndicator(string name, Enums.IndicatorType type) : base(name, type)
{ {
} }

View File

@@ -2,7 +2,7 @@ using Skender.Stock.Indicators;
namespace Managing.Domain.Strategies.Base; namespace Managing.Domain.Strategies.Base;
public class StrategiesResultBase public class IndicatorsResultBase
{ {
public List<EmaResult> Ema { get; set; } public List<EmaResult> Ema { get; set; }
public List<EmaResult> FastEma { get; set; } public List<EmaResult> FastEma { get; set; }

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Context; namespace Managing.Domain.Strategies.Context;
public class StDevContext : Strategy public class StDevContext : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public StDevContext(string name, int period) : base(name, StrategyType.StDev) public StDevContext(string name, int period) : base(name, IndicatorType.StDev)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -73,9 +73,9 @@ public class StDevContext : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
var test = new StrategiesResultBase() var test = new IndicatorsResultBase()
{ {
StdDev = Candles.GetStdDev(Period.Value).ToList() StdDev = Candles.GetStdDev(Period.Value).ToList()
}; };

View File

@@ -5,10 +5,10 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies namespace Managing.Domain.Strategies
{ {
public interface IStrategy public interface IIndicator
{ {
string Name { get; set; } string Name { get; set; }
StrategyType Type { get; set; } IndicatorType Type { get; set; }
SignalType SignalType { get; set; } SignalType SignalType { get; set; }
int? Period { get; set; } int? Period { get; set; }
int? FastPeriods { get; set; } int? FastPeriods { get; set; }
@@ -17,7 +17,7 @@ namespace Managing.Domain.Strategies
FixedSizeQueue<Candle> Candles { get; set; } FixedSizeQueue<Candle> Candles { get; set; }
List<Signal> Run(); List<Signal> Run();
StrategiesResultBase GetStrategyValues(); IndicatorsResultBase GetStrategyValues();
void UpdateCandles(HashSet<Candle> newCandles); void UpdateCandles(HashSet<Candle> newCandles);
string GetName(); string GetName();
} }

View File

@@ -8,9 +8,9 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies namespace Managing.Domain.Strategies
{ {
public class Strategy : IStrategy public class Indicator : IIndicator
{ {
public Strategy(string name, StrategyType type) public Indicator(string name, IndicatorType type)
{ {
Name = name; Name = name;
Type = type; Type = type;
@@ -20,7 +20,7 @@ namespace Managing.Domain.Strategies
public string Name { get; set; } public string Name { get; set; }
[JsonIgnore] public FixedSizeQueue<Candle> Candles { get; set; } [JsonIgnore] public FixedSizeQueue<Candle> Candles { get; set; }
public StrategyType Type { get; set; } public IndicatorType Type { get; set; }
public SignalType SignalType { get; set; } public SignalType SignalType { get; set; }
public int MinimumHistory { get; set; } public int MinimumHistory { get; set; }
public int? Period { get; set; } public int? Period { get; set; }
@@ -38,9 +38,9 @@ namespace Managing.Domain.Strategies
return new List<Signal>(); return new List<Signal>();
} }
public virtual StrategiesResultBase GetStrategyValues() public virtual IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase(); return new IndicatorsResultBase();
} }
public void UpdateCandles(HashSet<Candle> newCandles) public void UpdateCandles(HashSet<Candle> newCandles)

View File

@@ -18,12 +18,12 @@ namespace Managing.Domain.Strategies
[Required] public string Identifier { get; } [Required] public string Identifier { get; }
[Required] public Ticker Ticker { get; } [Required] public Ticker Ticker { get; }
[Required] public TradingExchanges Exchange { get; set; } [Required] public TradingExchanges Exchange { get; set; }
[Required] public StrategyType StrategyType { get; set; } [Required] public IndicatorType IndicatorType { get; set; }
[Required] public SignalType SignalType { get; set; } [Required] public SignalType SignalType { get; set; }
public User User { get; set; } public User User { 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, StrategyType strategyType, SignalType signalType, User user = null) TradingExchanges exchange, IndicatorType indicatorType, SignalType signalType, User user = null)
{ {
Direction = direction; Direction = direction;
Confidence = confidence; Confidence = confidence;
@@ -32,10 +32,11 @@ namespace Managing.Domain.Strategies
Ticker = ticker; Ticker = ticker;
Exchange = exchange; Exchange = exchange;
Status = SignalStatus.WaitingForPosition; Status = SignalStatus.WaitingForPosition;
StrategyType = strategyType; IndicatorType = indicatorType;
User = user; User = user;
Identifier = $"{StrategyType}-{direction}-{ticker}-{candle?.Close.ToString(CultureInfo.InvariantCulture)}-{date:yyyyMMdd-HHmmss}"; Identifier =
$"{IndicatorType}-{direction}-{ticker}-{candle?.Close.ToString(CultureInfo.InvariantCulture)}-{date:yyyyMMdd-HHmmss}";
SignalType = signalType; SignalType = signalType;
} }

View File

@@ -7,11 +7,12 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class ChandelierExitStrategy : Strategy public class ChandelierExitIndicator : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public ChandelierExitStrategy(string name, int period, double multiplier) : base(name, StrategyType.ChandelierExit) public ChandelierExitIndicator(string name, int period, double multiplier) : base(name,
IndicatorType.ChandelierExit)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -39,9 +40,9 @@ public class ChandelierExitStrategy : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
ChandelierLong = Candles.GetChandelier(Period.Value, Multiplier.Value, ChandelierType.Long).ToList(), ChandelierLong = Candles.GetChandelier(Period.Value, Multiplier.Value, ChandelierType.Long).ToList(),
ChandelierShort = Candles.GetChandelier(Period.Value, Multiplier.Value, ChandelierType.Short).ToList() ChandelierShort = Candles.GetChandelier(Period.Value, Multiplier.Value, ChandelierType.Short).ToList()

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class DualEmaCrossStrategy : EmaBaseStrategy public class DualEmaCrossIndicator : EmaBaseIndicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public DualEmaCrossStrategy(string name, int fastPeriod, int slowPeriod) : base(name, StrategyType.DualEmaCross) public DualEmaCrossIndicator(string name, int fastPeriod, int slowPeriod) : base(name, IndicatorType.DualEmaCross)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
FastPeriods = fastPeriod; FastPeriods = fastPeriod;
@@ -19,9 +19,9 @@ public class DualEmaCrossStrategy : EmaBaseStrategy
MinimumHistory = Math.Max(fastPeriod, slowPeriod) * 2; MinimumHistory = Math.Max(fastPeriod, slowPeriod) * 2;
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
FastEma = Candles.GetEma(FastPeriods.Value).ToList(), FastEma = Candles.GetEma(FastPeriods.Value).ToList(),
SlowEma = Candles.GetEma(SlowPeriods.Value).ToList() SlowEma = Candles.GetEma(SlowPeriods.Value).ToList()

View File

@@ -6,19 +6,19 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class EmaCrossStrategy : EmaBaseStrategy public class EmaCrossIndicator : EmaBaseIndicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public EmaCrossStrategy(string name, int period) : base(name, StrategyType.EmaCross) public EmaCrossIndicator(string name, int period) : base(name, IndicatorType.EmaCross)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
Ema = Candles.GetEma(Period.Value).ToList() Ema = Candles.GetEma(Period.Value).ToList()
}; };

View File

@@ -14,12 +14,12 @@ namespace Managing.Domain.Strategies.Signals;
/// 2. Long signals on STC rebound from oversold (25- → ≥25) with recent compressed volatility (max <11) /// 2. Long signals on STC rebound from oversold (25- → ≥25) with recent compressed volatility (max <11)
/// 3. Avoids look-ahead bias through proper rolling window implementation /// 3. Avoids look-ahead bias through proper rolling window implementation
/// </summary> /// </summary>
public class LaggingSTC : Strategy public class LaggingSTC : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public LaggingSTC(string name, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name, public LaggingSTC(string name, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name,
StrategyType.LaggingStc) IndicatorType.LaggingStc)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
FastPeriods = fastPeriods; FastPeriods = fastPeriods;
@@ -89,10 +89,10 @@ public class LaggingSTC : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
var stc = Candles.GetStc(FastPeriods.Value, FastPeriods.Value, SlowPeriods.Value).ToList(); var stc = Candles.GetStc(FastPeriods.Value, FastPeriods.Value, SlowPeriods.Value).ToList();
return new StrategiesResultBase return new IndicatorsResultBase
{ {
Stc = stc Stc = stc
}; };

View File

@@ -7,12 +7,12 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class MacdCrossStrategy : Strategy public class MacdCrossIndicator : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public MacdCrossStrategy(string name, int fastPeriods, int slowPeriods, int signalPeriods) : public MacdCrossIndicator(string name, int fastPeriods, int slowPeriods, int signalPeriods) :
base(name, StrategyType.MacdCross) base(name, IndicatorType.MacdCross)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
FastPeriods = fastPeriods; FastPeriods = fastPeriods;
@@ -59,9 +59,9 @@ public class MacdCrossStrategy : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
Macd = Candles.GetMacd(FastPeriods.Value, SlowPeriods.Value, SignalPeriods.Value).ToList() Macd = Candles.GetMacd(FastPeriods.Value, SlowPeriods.Value, SignalPeriods.Value).ToList()
}; };

View File

@@ -7,11 +7,11 @@ using Candle = Managing.Domain.Candles.Candle;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class RsiDivergenceConfirmStrategy : Strategy public class RsiDivergenceConfirmIndicator : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public RsiDivergenceConfirmStrategy(string name, int period) : base(name, StrategyType.RsiDivergenceConfirm) public RsiDivergenceConfirmIndicator(string name, int period) : base(name, IndicatorType.RsiDivergenceConfirm)
{ {
Period = period; Period = period;
Signals = new List<Signal>(); Signals = new List<Signal>();
@@ -49,9 +49,9 @@ public class RsiDivergenceConfirmStrategy : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
Rsi = Candles.GetRsi(Period.Value).ToList() Rsi = Candles.GetRsi(Period.Value).ToList()
}; };

View File

@@ -7,14 +7,14 @@ using Candle = Managing.Domain.Candles.Candle;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class RsiDivergenceStrategy : Strategy public class RsiDivergenceIndicator : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public TradeDirection Direction { get; set; } public TradeDirection Direction { get; set; }
private const int UpperBand = 70; private const int UpperBand = 70;
private const int LowerBand = 30; private const int LowerBand = 30;
public RsiDivergenceStrategy(string name, int period) : base(name, StrategyType.RsiDivergence) public RsiDivergenceIndicator(string name, int period) : base(name, IndicatorType.RsiDivergence)
{ {
Period = period; Period = period;
Signals = new List<Signal>(); Signals = new List<Signal>();
@@ -52,9 +52,9 @@ public class RsiDivergenceStrategy : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
Rsi = Candles.GetRsi(Period.Value).ToList() Rsi = Candles.GetRsi(Period.Value).ToList()
}; };

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class StcStrategy : Strategy public class StcIndicator : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public StcStrategy(string name, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name, StrategyType.Stc) public StcIndicator(string name, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name, IndicatorType.Stc)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
FastPeriods = fastPeriods; FastPeriods = fastPeriods;
@@ -64,12 +64,12 @@ public class StcStrategy : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
if (FastPeriods != null && SlowPeriods != null) if (FastPeriods != null && SlowPeriods != null)
{ {
var stc = Candles.GetStc(FastPeriods.Value, FastPeriods.Value, SlowPeriods.Value).ToList(); var stc = Candles.GetStc(FastPeriods.Value, FastPeriods.Value, SlowPeriods.Value).ToList();
return new StrategiesResultBase return new IndicatorsResultBase
{ {
Stc = stc Stc = stc
}; };

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class SuperTrendCrossEma : Strategy public class SuperTrendCrossEma : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public SuperTrendCrossEma(string name, int period, double multiplier) : base(name, StrategyType.SuperTrendCrossEma) public SuperTrendCrossEma(string name, int period, double multiplier) : base(name, IndicatorType.SuperTrendCrossEma)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -157,9 +157,9 @@ public class SuperTrendCrossEma : Strategy
return superTrends; return superTrends;
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
SuperTrend = Candles.GetSuperTrend(Period.Value, Multiplier.Value).Where(s => s.SuperTrend.HasValue) SuperTrend = Candles.GetSuperTrend(Period.Value, Multiplier.Value).Where(s => s.SuperTrend.HasValue)
.ToList() .ToList()

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals; namespace Managing.Domain.Strategies.Signals;
public class SuperTrendStrategy : Strategy public class SuperTrendIndicator : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public SuperTrendStrategy(string name, int period, double multiplier) : base(name, StrategyType.SuperTrend) public SuperTrendIndicator(string name, int period, double multiplier) : base(name, IndicatorType.SuperTrend)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -61,9 +61,9 @@ public class SuperTrendStrategy : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
SuperTrend = Candles.GetSuperTrend(Period.Value, Multiplier.Value).Where(s => s.SuperTrend.HasValue) SuperTrend = Candles.GetSuperTrend(Period.Value, Multiplier.Value).Where(s => s.SuperTrend.HasValue)
.ToList() .ToList()

View File

@@ -6,10 +6,10 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals namespace Managing.Domain.Strategies.Signals
{ {
public class ThreeWhiteSoldiersStrategy : Strategy public class ThreeWhiteSoldiersIndicator : Indicator
{ {
public ThreeWhiteSoldiersStrategy(string name, int period) public ThreeWhiteSoldiersIndicator(string name, int period)
: base(name, StrategyType.ThreeWhiteSoldiers) : base(name, IndicatorType.ThreeWhiteSoldiers)
{ {
Period = period; Period = period;
} }
@@ -52,7 +52,7 @@ namespace Managing.Domain.Strategies.Signals
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@@ -6,11 +6,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Trends; namespace Managing.Domain.Strategies.Trends;
public class EmaTrendStrategy : EmaBaseStrategy public class EmaTrendIndicator : EmaBaseIndicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public EmaTrendStrategy(string name, int period) : base(name, StrategyType.EmaTrend) public EmaTrendIndicator(string name, int period) : base(name, IndicatorType.EmaTrend)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
Period = period; Period = period;
@@ -54,9 +54,9 @@ public class EmaTrendStrategy : EmaBaseStrategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
Ema = Candles.GetEma(Period.Value).ToList() Ema = Candles.GetEma(Period.Value).ToList()
}; };

View File

@@ -7,16 +7,16 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Trends; namespace Managing.Domain.Strategies.Trends;
public class StochRsiTrendStrategy : Strategy public class StochRsiTrendIndicator : Indicator
{ {
public List<Signal> Signals { get; set; } public List<Signal> Signals { get; set; }
public StochRsiTrendStrategy( public StochRsiTrendIndicator(
string name, string name,
int period, int period,
int stochPeriod, int stochPeriod,
int signalPeriod, int signalPeriod,
int smoothPeriods) : base(name, StrategyType.StochRsiTrend) int smoothPeriods) : base(name, IndicatorType.StochRsiTrend)
{ {
Signals = new List<Signal>(); Signals = new List<Signal>();
StochPeriods = stochPeriod; StochPeriods = stochPeriod;
@@ -65,9 +65,9 @@ public class StochRsiTrendStrategy : Strategy
} }
} }
public override StrategiesResultBase GetStrategyValues() public override IndicatorsResultBase GetStrategyValues()
{ {
return new StrategiesResultBase() return new IndicatorsResultBase()
{ {
StochRsi = Candles.GetStochRsi(Period.Value, StochPeriods.Value, SignalPeriods.Value, SmoothPeriods.Value) StochRsi = Candles.GetStochRsi(Period.Value, StochPeriods.Value, SignalPeriods.Value, SmoothPeriods.Value)
.ToList() .ToList()

View File

@@ -4,10 +4,10 @@ using static Managing.Common.Enums;
namespace Managing.Infrastructure.Databases.MongoDb.Collections namespace Managing.Infrastructure.Databases.MongoDb.Collections
{ {
[BsonCollection("Strategies")] [BsonCollection("Indicators")]
public class StrategyDto : Document public class IndicatorDto : Document
{ {
public StrategyType Type { get; set; } public IndicatorType Type { get; set; }
public Timeframe Timeframe { get; set; } public Timeframe Timeframe { get; set; }
public string Name { get; set; } public string Name { get; set; }
public int MinimumHistory { get; set; } public int MinimumHistory { get; set; }
@@ -22,4 +22,4 @@ namespace Managing.Infrastructure.Databases.MongoDb.Collections
public SignalType SignalType { get; set; } public SignalType SignalType { get; set; }
public UserDto User { get; set; } public UserDto User { get; set; }
} }
} }

View File

@@ -7,7 +7,7 @@ namespace Managing.Infrastructure.Databases.MongoDb.Collections
public class ScenarioDto : Document public class ScenarioDto : Document
{ {
public string Name { get; set; } public string Name { get; set; }
public List<StrategyDto> Strategies { get; set; } public List<IndicatorDto> Indicators { get; set; }
public int LoopbackPeriod { get; set; } public int LoopbackPeriod { get; set; }
public UserDto User { get; set; } public UserDto User { get; set; }
} }

View File

@@ -15,8 +15,8 @@ namespace Managing.Infrastructure.Databases.MongoDb.Collections
public Ticker Ticker { get; set; } public Ticker Ticker { get; set; }
public SignalStatus Status { get; set; } public SignalStatus Status { get; set; }
public Timeframe Timeframe { get; set; } public Timeframe Timeframe { get; set; }
public StrategyType Type { get; set; } public IndicatorType Type { get; set; }
public SignalType SignalType { get; set; } public SignalType SignalType { get; set; }
public UserDto User { get; set; } public UserDto User { get; set; }
} }
} }

View File

@@ -370,7 +370,7 @@ public static class MongoMappers
Ticker = signal.Ticker, Ticker = signal.Ticker,
Status = signal.Status, Status = signal.Status,
Timeframe = signal.Timeframe, Timeframe = signal.Timeframe,
Type = signal.StrategyType, Type = signal.IndicatorType,
User = signal.User != null ? Map(signal.User) : null User = signal.User != null ? Map(signal.User) : null
}; };
} }
@@ -412,7 +412,7 @@ public static class MongoMappers
return new ScenarioDto return new ScenarioDto
{ {
Name = scenario.Name, Name = scenario.Name,
Strategies = Map(scenario.Strategies), Indicators = Map(scenario.Indicators),
LoopbackPeriod = scenario.LoopbackPeriod ?? 1, LoopbackPeriod = scenario.LoopbackPeriod ?? 1,
User = scenario.User != null ? Map(scenario.User) : null User = scenario.User != null ? Map(scenario.User) : null
}; };
@@ -430,64 +430,64 @@ public static class MongoMappers
var scenario = new Scenario(d.Name, d.LoopbackPeriod) var scenario = new Scenario(d.Name, d.LoopbackPeriod)
{ {
Strategies = d.Strategies.Select(s => Map(s)).ToList(), Indicators = d.Indicators.Select(s => Map(s)).ToList(),
User = d.User != null ? Map(d.User) : null User = d.User != null ? Map(d.User) : null
}; };
return scenario; return scenario;
} }
private static List<StrategyDto> Map(List<Strategy> strategies) private static List<IndicatorDto> Map(List<Indicator> indicators)
{ {
return strategies.ConvertAll(strategy => Map(strategy)); return indicators.ConvertAll(strategy => Map(strategy));
} }
internal static Strategy Map(StrategyDto strategyDto) internal static Indicator Map(IndicatorDto indicatorDto)
{ {
if (strategyDto == null) if (indicatorDto == null)
return null; return null;
return new Strategy(strategyDto.Name, strategyDto.Type) return new Indicator(indicatorDto.Name, indicatorDto.Type)
{ {
SignalType = strategyDto.SignalType, SignalType = indicatorDto.SignalType,
MinimumHistory = strategyDto.MinimumHistory, MinimumHistory = indicatorDto.MinimumHistory,
Period = strategyDto.Period, Period = indicatorDto.Period,
FastPeriods = strategyDto.FastPeriods, FastPeriods = indicatorDto.FastPeriods,
SlowPeriods = strategyDto.SlowPeriods, SlowPeriods = indicatorDto.SlowPeriods,
SignalPeriods = strategyDto.SignalPeriods, SignalPeriods = indicatorDto.SignalPeriods,
Multiplier = strategyDto.Multiplier, Multiplier = indicatorDto.Multiplier,
SmoothPeriods = strategyDto.SmoothPeriods, SmoothPeriods = indicatorDto.SmoothPeriods,
StochPeriods = strategyDto.StochPeriods, StochPeriods = indicatorDto.StochPeriods,
CyclePeriods = strategyDto.CyclePeriods, CyclePeriods = indicatorDto.CyclePeriods,
User = strategyDto.User != null ? Map(strategyDto.User) : null User = indicatorDto.User != null ? Map(indicatorDto.User) : null
}; };
} }
internal static StrategyDto Map(Strategy strategy) internal static IndicatorDto Map(Indicator indicator)
{ {
if (strategy == null) if (indicator == null)
return null; return null;
return new StrategyDto return new IndicatorDto
{ {
Name = strategy.Name, Name = indicator.Name,
Type = strategy.Type, Type = indicator.Type,
SignalType = strategy.SignalType, SignalType = indicator.SignalType,
MinimumHistory = strategy.MinimumHistory, MinimumHistory = indicator.MinimumHistory,
Period = strategy.Period, Period = indicator.Period,
FastPeriods = strategy.FastPeriods, FastPeriods = indicator.FastPeriods,
SlowPeriods = strategy.SlowPeriods, SlowPeriods = indicator.SlowPeriods,
SignalPeriods = strategy.SignalPeriods, SignalPeriods = indicator.SignalPeriods,
Multiplier = strategy.Multiplier, Multiplier = indicator.Multiplier,
SmoothPeriods = strategy.SmoothPeriods, SmoothPeriods = indicator.SmoothPeriods,
StochPeriods = strategy.StochPeriods, StochPeriods = indicator.StochPeriods,
CyclePeriods = strategy.CyclePeriods, CyclePeriods = indicator.CyclePeriods,
User = strategy.User != null ? Map(strategy.User) : null User = indicator.User != null ? Map(indicator.User) : null
}; };
} }
internal static IEnumerable<Strategy> Map(IEnumerable<StrategyDto> strategies) internal static IEnumerable<Indicator> Map(IEnumerable<IndicatorDto> indicators)
{ {
return strategies.Select(strategy => Map(strategy)); return indicators.Select(indicator => Map(indicator));
} }
#endregion #endregion
@@ -567,8 +567,8 @@ public static class MongoMappers
Scenario = new ScenarioDto Scenario = new ScenarioDto
{ {
Name = spotlight.Scenario.Name, Name = spotlight.Scenario.Name,
Strategies = Indicators =
spotlight.Scenario.Strategies.ConvertAll( spotlight.Scenario.Indicators.ConvertAll(
spotlightScenarioStrategy => Map(spotlightScenarioStrategy)) spotlightScenarioStrategy => Map(spotlightScenarioStrategy))
}, },
TickerSignals = spotlight.TickerSignals.ConvertAll(spotlightTickerSignal => new TickerSignalDto TickerSignals = spotlight.TickerSignals.ConvertAll(spotlightTickerSignal => new TickerSignalDto
@@ -607,8 +607,8 @@ public static class MongoMappers
{ {
Scenario = new Scenario(name: spotlight.Scenario.Name) Scenario = new Scenario(name: spotlight.Scenario.Name)
{ {
Strategies = Indicators =
spotlight.Scenario.Strategies.ConvertAll( spotlight.Scenario.Indicators.ConvertAll(
spotlightScenarioStrategy => Map(spotlightScenarioStrategy)) spotlightScenarioStrategy => Map(spotlightScenarioStrategy))
}, },
TickerSignals = spotlight.TickerSignals.ConvertAll(spotlightTickerSignal => new TickerSignal TickerSignals = spotlight.TickerSignals.ConvertAll(spotlightTickerSignal => new TickerSignal

View File

@@ -16,20 +16,20 @@ public class TradingRepository : ITradingRepository
private readonly IMongoRepository<ScenarioDto> _scenarioRepository; private readonly IMongoRepository<ScenarioDto> _scenarioRepository;
private readonly IMongoRepository<SignalDto> _signalRepository; private readonly IMongoRepository<SignalDto> _signalRepository;
private readonly IMongoRepository<PositionDto> _positionRepository; private readonly IMongoRepository<PositionDto> _positionRepository;
private readonly IMongoRepository<StrategyDto> _strategyRepository; private readonly IMongoRepository<IndicatorDto> _indicatorRepository;
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,
IMongoRepository<PositionDto> positionRepository, IMongoRepository<PositionDto> positionRepository,
IMongoRepository<StrategyDto> strategyRepository, IMongoRepository<IndicatorDto> indicatorRepository,
IMongoRepository<FeeDto> feeRepository) IMongoRepository<FeeDto> feeRepository)
{ {
_scenarioRepository = scenarioRepository; _scenarioRepository = scenarioRepository;
_signalRepository = signalRepository; _signalRepository = signalRepository;
_positionRepository = positionRepository; _positionRepository = positionRepository;
_strategyRepository = strategyRepository; _indicatorRepository = indicatorRepository;
_feeRepository = feeRepository; _feeRepository = feeRepository;
} }
@@ -44,15 +44,15 @@ public class TradingRepository : ITradingRepository
_scenarioRepository.DropCollection(); _scenarioRepository.DropCollection();
} }
public void DeleteStrategies() public void DeleteIndicators()
{ {
_strategyRepository.DropCollection(); _indicatorRepository.DropCollection();
} }
public void DeleteStrategy(string name) public void DeleteIndicator(string name)
{ {
var strategy = _strategyRepository.FindOne(s => s.Name == name); var strategy = _indicatorRepository.FindOne(s => s.Name == name);
_strategyRepository.DeleteById(strategy.Id.ToString()); _indicatorRepository.DeleteById(strategy.Id.ToString());
} }
public Position GetPositionByIdentifier(string identifier) public Position GetPositionByIdentifier(string identifier)
@@ -87,15 +87,15 @@ public class TradingRepository : ITradingRepository
return scenarios.Select(s => MongoMappers.Map(s)); return scenarios.Select(s => MongoMappers.Map(s));
} }
public IEnumerable<Strategy> GetStrategies() public IEnumerable<Indicator> GetIndicators()
{ {
var strategies = _strategyRepository.FindAll(); var indicators = _indicatorRepository.FindAll();
return strategies.Select(MongoMappers.Map); return indicators.Select(MongoMappers.Map);
} }
public Strategy GetStrategyByName(string name) public Indicator GetStrategyByName(string name)
{ {
var strategy = _strategyRepository.FindOne(s => s.Name == name); var strategy = _indicatorRepository.FindOne(s => s.Name == name);
return MongoMappers.Map(strategy); return MongoMappers.Map(strategy);
} }
@@ -129,17 +129,17 @@ public class TradingRepository : ITradingRepository
$"Scenario with name '{scenario.Name}' already exists for user '{scenario.User?.Name}'"); $"Scenario with name '{scenario.Name}' already exists for user '{scenario.User?.Name}'");
} }
var strategyDtos = new List<StrategyDto>(); var strategyDtos = new List<IndicatorDto>();
foreach (var strategy in scenario.Strategies) foreach (var strategy in scenario.Indicators)
{ {
var dto = _strategyRepository.FindOne(s => s.Name == strategy.Name); var dto = _indicatorRepository.FindOne(s => s.Name == strategy.Name);
strategyDtos.Add(dto); strategyDtos.Add(dto);
} }
var scenarioDto = new ScenarioDto var scenarioDto = new ScenarioDto
{ {
Name = scenario.Name, Name = scenario.Name,
Strategies = strategyDtos, Indicators = strategyDtos,
User = scenario.User != null ? MongoMappers.Map(scenario.User) : null User = scenario.User != null ? MongoMappers.Map(scenario.User) : null
}; };
@@ -165,21 +165,21 @@ public class TradingRepository : ITradingRepository
_signalRepository.InsertOne(dto); _signalRepository.InsertOne(dto);
} }
public void InsertStrategy(Strategy strategy) public void InsertStrategy(Indicator indicator)
{ {
// Check if strategy already exists for the same user // Check if strategy already exists for the same user
var existingStrategy = _strategyRepository.FindOne(s => var existingStrategy = _indicatorRepository.FindOne(s =>
s.Name == strategy.Name && s.Name == indicator.Name &&
(strategy.User == null || (s.User != null && s.User.Name == strategy.User.Name))); (indicator.User == null || (s.User != null && s.User.Name == indicator.User.Name)));
if (existingStrategy != null) if (existingStrategy != null)
{ {
throw new InvalidOperationException( throw new InvalidOperationException(
$"Strategy with name '{strategy.Name}' already exists for user '{strategy.User?.Name}'"); $"Strategy with name '{indicator.Name}' already exists for user '{indicator.User?.Name}'");
} }
var dto = MongoMappers.Map(strategy); var dto = MongoMappers.Map(indicator);
_strategyRepository.InsertOne(dto); _indicatorRepository.InsertOne(dto);
} }
public void InsertFee(Fee fee) public void InsertFee(Fee fee)
@@ -262,11 +262,11 @@ public class TradingRepository : ITradingRepository
_scenarioRepository.Update(dto); _scenarioRepository.Update(dto);
} }
public void UpdateStrategy(Strategy strategy) public void UpdateStrategy(Indicator indicator)
{ {
var s = _strategyRepository.FindOne(s => s.Name == strategy.Name); var s = _indicatorRepository.FindOne(s => s.Name == indicator.Name);
var dto = MongoMappers.Map(strategy); var dto = MongoMappers.Map(indicator);
dto.Id = s.Id; dto.Id = s.Id;
_strategyRepository.Update(dto); _indicatorRepository.Update(dto);
} }
} }