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

View File

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

View File

@@ -5,12 +5,8 @@ namespace Managing.Api.Models.Requests;
public class CreateStrategyRequest
{
[Required]
public StrategyType Type { get; internal set; }
[Required]
public Timeframe Timeframe { get; internal set; }
[Required]
public string Name { get; internal set; }
[Required]
public int Period { get; internal set; }
}
[Required] public IndicatorType Type { get; internal set; }
[Required] public Timeframe Timeframe { 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);
void InsertPosition(Position position);
void UpdatePosition(Position position);
Strategy GetStrategyByName(string strategy);
Indicator GetStrategyByName(string strategy);
void InsertScenario(Scenario scenario);
void InsertStrategy(Strategy strategy);
void InsertStrategy(Indicator indicator);
IEnumerable<Scenario> GetScenarios();
IEnumerable<Strategy> GetStrategies();
IEnumerable<Indicator> GetIndicators();
void DeleteScenario(string name);
void DeleteStrategy(string name);
void DeleteIndicator(string name);
void DeleteScenarios();
void DeleteStrategies();
void DeleteIndicators();
Position GetPositionByIdentifier(string identifier);
IEnumerable<Position> GetPositions(PositionInitiator positionInitiator);
IEnumerable<Position> GetPositionsByStatus(PositionStatus positionStatus);
@@ -30,5 +30,5 @@ public interface ITradingRepository
void InsertFee(Fee fee);
void UpdateFee(Fee fee);
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 InsertPosition(Position position);
void UpdatePosition(Position position);
Strategy GetStrategyByName(string strategy);
Indicator GetStrategyByName(string strategy);
void InsertScenario(Scenario scenario);
void InsertStrategy(Strategy strategy);
void InsertStrategy(Indicator indicator);
IEnumerable<Scenario> GetScenarios();
IEnumerable<Strategy> GetStrategies();
IEnumerable<Indicator> GetStrategies();
void DeleteScenario(string name);
void DeleteStrategy(string name);
void DeleteScenarios();
@@ -34,7 +34,7 @@ public interface ITradingService
IEnumerable<Trader> GetTradersWatch();
void UpdateDeltaNeutralOpportunities();
void UpdateScenario(Scenario scenario);
void UpdateStrategy(Strategy strategy);
void UpdateStrategy(Indicator indicator);
Task<IEnumerable<Position>> GetBrokerPositions(Account account);
Task<PrivyInitAddressResponse> InitPrivyWallet(string publicAddress);
}

View File

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

View File

@@ -8,11 +8,11 @@ using static Managing.Common.Enums;
namespace Managing.Application.Tests
{
public class StrategyTests
public class IndicatorTests
{
private readonly IExchangeService _exchangeService;
public StrategyTests()
public IndicatorTests()
{
_exchangeService = TradingBaseTests.GetExchangeService();
}
@@ -24,7 +24,7 @@ namespace Managing.Application.Tests
{
var account = GetAccount(exchange);
// 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 resultSignal = new List<Signal>();
@@ -58,7 +58,7 @@ namespace Managing.Application.Tests
{
// Arrange
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 resultSignal = new List<Signal>();
@@ -85,7 +85,7 @@ namespace Managing.Application.Tests
{
// Arrange
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 resultSignal = new List<Signal>();
@@ -112,7 +112,7 @@ namespace Managing.Application.Tests
{
// Arrange
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 resultSignal = new List<Signal>();
@@ -139,7 +139,7 @@ namespace Managing.Application.Tests
{
// Arrange
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)
.Result;
var resultSignal = new List<Signal>();
@@ -167,7 +167,7 @@ namespace Managing.Application.Tests
{
// Arrange
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 resultSignal = new List<Signal>();
@@ -195,7 +195,7 @@ namespace Managing.Application.Tests
{
// Arrange
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 resultSignal = new List<Signal>();

View File

@@ -9,12 +9,12 @@ namespace Managing.Application.Abstractions
{
IEnumerable<Scenario> GetScenarios();
Scenario CreateScenario(string name, List<string> strategies, int? loopbackPeriod = 1);
IEnumerable<Strategy> GetStrategies();
IEnumerable<Indicator> GetStrategies();
bool DeleteStrategy(string name);
bool DeleteScenario(string name);
Scenario GetScenario(string name);
Strategy CreateStrategy(StrategyType type,
Indicator CreateStrategy(IndicatorType type,
string name,
int? period = null,
int? fastPeriods = null,
@@ -29,18 +29,18 @@ namespace Managing.Application.Abstractions
bool DeleteScenarios();
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);
IEnumerable<Scenario> GetScenariosByUser(User user);
Scenario CreateScenarioForUser(User user, string name, List<string> strategies, int? loopbackPeriod = 1);
IEnumerable<Strategy> GetStrategiesByUser(User user);
bool DeleteStrategyByUser(User user, string name);
IEnumerable<Indicator> GetIndicatorsByUser(User user);
bool DeleteIndicatorByUser(User user, string name);
bool DeleteScenarioByUser(User user, string name);
Scenario GetScenarioByUser(User user, string name);
Strategy CreateStrategyForUser(User user,
StrategyType type,
Indicator CreateIndicatorForUser(User user,
IndicatorType type,
string name,
int? period = null,
int? fastPeriods = null,
@@ -50,12 +50,13 @@ namespace Managing.Application.Abstractions
int? stochPeriods = null,
int? smoothPeriods = null,
int? cyclePeriods = null);
bool DeleteStrategiesByUser(User user);
bool DeleteScenariosByUser(User user);
bool UpdateScenarioByUser(User user, string name, List<string> strategies, int? loopbackPeriod);
bool UpdateStrategyByUser(User user, StrategyType strategyType, string name, int? period, int? fastPeriods,
int? slowPeriods, int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods, int? cyclePeriods);
bool UpdateIndicatorByUser(User user, IndicatorType indicatorType, string name, int? period, int? fastPeriods,
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; }
Account Account { get; set; }
HashSet<IStrategy> Strategies { get; set; }
HashSet<IIndicator> Indicators { get; set; }
FixedSizeQueue<Candle> OptimizedCandles { get; set; }
HashSet<Candle> Candles { get; set; }
HashSet<Signal> Signals { get; set; }
List<Position> Positions { 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 PreloadSince { get; set; }
int PreloadedCandlesCount { get; set; }
@@ -32,10 +32,10 @@ namespace Managing.Application.Abstractions
int GetWinRate();
decimal GetProfitAndLoss();
decimal GetTotalFees();
void LoadStrategies(IEnumerable<IStrategy> strategies);
void LoadIndicators(IEnumerable<IIndicator> indicators);
void LoadScenario(string scenarioName);
void LoadScenario(Scenario scenario);
void UpdateStrategiesValues();
void UpdateIndicatorsValues();
Task LoadAccount();
Task<Position> OpenPositionManually(TradeDirection direction);

View File

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

View File

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

View File

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

View File

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

View File

@@ -55,12 +55,12 @@ public class TradingService : ITradingService
public void DeleteStrategies()
{
_tradingRepository.DeleteStrategies();
_tradingRepository.DeleteIndicators();
}
public void DeleteStrategy(string name)
{
_tradingRepository.DeleteStrategy(name);
_tradingRepository.DeleteIndicator(name);
}
public Position GetPositionByIdentifier(string identifier)
@@ -89,12 +89,12 @@ public class TradingService : ITradingService
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);
}
@@ -114,9 +114,9 @@ public class TradingService : ITradingService
_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)
@@ -276,9 +276,9 @@ public class TradingService : ITradingService
_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)
@@ -385,7 +385,8 @@ public class TradingService : ITradingService
if (string.IsNullOrEmpty(publicAddress))
{
_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);

View File

@@ -30,7 +30,7 @@ public class RsiDiv : FlowBase
MapParameters();
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.Run();

View File

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

View File

@@ -24,7 +24,7 @@ public class Backtest
Signals = signals;
Candles = candles;
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
if (candles != null && candles.Count > 0)
@@ -55,7 +55,7 @@ public class Backtest
[Required] public List<KeyValuePair<DateTime, decimal>> WalletBalances { get; set; }
[Required] public MoneyManagement OptimizedMoneyManagement { 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; }
/// <summary>
@@ -130,12 +130,12 @@ public class Backtest
public string GetStringReport()
{
var timeBasedInfo = Config.MaxPositionTimeHours.HasValue
? $" | MaxTime: {Config.MaxPositionTimeHours}h"
var timeBasedInfo = Config.MaxPositionTimeHours.HasValue
? $" | MaxTime: {Config.MaxPositionTimeHours}h"
: " | MaxTime: Disabled";
var flipInfo = Config.FlipPosition
? $" | Flip: {(Config.FlipOnlyWhenInProfit ? "Profit-Only" : "Always")}"
var flipInfo = Config.FlipPosition
? $" | Flip: {(Config.FlipOnlyWhenInProfit ? "Profit-Only" : "Always")}"
: "";
return

View File

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

View File

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

View File

@@ -4,9 +4,9 @@ using Skender.Stock.Indicators;
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;
public class StrategiesResultBase
public class IndicatorsResultBase
{
public List<EmaResult> Ema { get; set; }
public List<EmaResult> FastEma { get; set; }

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Context;
public class StDevContext : Strategy
public class StDevContext : Indicator
{
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>();
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()
};

View File

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

View File

@@ -8,9 +8,9 @@ using static Managing.Common.Enums;
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;
Type = type;
@@ -20,7 +20,7 @@ namespace Managing.Domain.Strategies
public string Name { 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 int MinimumHistory { get; set; }
public int? Period { get; set; }
@@ -38,9 +38,9 @@ namespace Managing.Domain.Strategies
return new List<Signal>();
}
public virtual StrategiesResultBase GetStrategyValues()
public virtual IndicatorsResultBase GetStrategyValues()
{
return new StrategiesResultBase();
return new IndicatorsResultBase();
}
public void UpdateCandles(HashSet<Candle> newCandles)

View File

@@ -18,12 +18,12 @@ namespace Managing.Domain.Strategies
[Required] public string Identifier { get; }
[Required] public Ticker Ticker { get; }
[Required] public TradingExchanges Exchange { get; set; }
[Required] public StrategyType StrategyType { get; set; }
[Required] public IndicatorType IndicatorType { get; set; }
[Required] public SignalType SignalType { get; set; }
public User User { get; set; }
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;
Confidence = confidence;
@@ -32,10 +32,11 @@ namespace Managing.Domain.Strategies
Ticker = ticker;
Exchange = exchange;
Status = SignalStatus.WaitingForPosition;
StrategyType = strategyType;
IndicatorType = indicatorType;
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;
}

View File

@@ -7,11 +7,12 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals;
public class ChandelierExitStrategy : Strategy
public class ChandelierExitIndicator : Indicator
{
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>();
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(),
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;
public class DualEmaCrossStrategy : EmaBaseStrategy
public class DualEmaCrossIndicator : EmaBaseIndicator
{
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>();
FastPeriods = fastPeriod;
@@ -19,9 +19,9 @@ public class DualEmaCrossStrategy : EmaBaseStrategy
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(),
SlowEma = Candles.GetEma(SlowPeriods.Value).ToList()

View File

@@ -6,19 +6,19 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals;
public class EmaCrossStrategy : EmaBaseStrategy
public class EmaCrossIndicator : EmaBaseIndicator
{
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>();
Period = period;
}
public override StrategiesResultBase GetStrategyValues()
public override IndicatorsResultBase GetStrategyValues()
{
return new StrategiesResultBase()
return new IndicatorsResultBase()
{
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)
/// 3. Avoids look-ahead bias through proper rolling window implementation
/// </summary>
public class LaggingSTC : Strategy
public class LaggingSTC : Indicator
{
public List<Signal> Signals { get; set; }
public LaggingSTC(string name, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name,
StrategyType.LaggingStc)
IndicatorType.LaggingStc)
{
Signals = new List<Signal>();
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();
return new StrategiesResultBase
return new IndicatorsResultBase
{
Stc = stc
};

View File

@@ -7,12 +7,12 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals;
public class MacdCrossStrategy : Strategy
public class MacdCrossIndicator : Indicator
{
public List<Signal> Signals { get; set; }
public MacdCrossStrategy(string name, int fastPeriods, int slowPeriods, int signalPeriods) :
base(name, StrategyType.MacdCross)
public MacdCrossIndicator(string name, int fastPeriods, int slowPeriods, int signalPeriods) :
base(name, IndicatorType.MacdCross)
{
Signals = new List<Signal>();
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()
};

View File

@@ -7,11 +7,11 @@ using Candle = Managing.Domain.Candles.Candle;
namespace Managing.Domain.Strategies.Signals;
public class RsiDivergenceConfirmStrategy : Strategy
public class RsiDivergenceConfirmIndicator : Indicator
{
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;
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()
};

View File

@@ -7,14 +7,14 @@ using Candle = Managing.Domain.Candles.Candle;
namespace Managing.Domain.Strategies.Signals;
public class RsiDivergenceStrategy : Strategy
public class RsiDivergenceIndicator : Indicator
{
public List<Signal> Signals { get; set; }
public TradeDirection Direction { get; set; }
private const int UpperBand = 70;
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;
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()
};

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals;
public class StcStrategy : Strategy
public class StcIndicator : Indicator
{
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>();
FastPeriods = fastPeriods;
@@ -64,12 +64,12 @@ public class StcStrategy : Strategy
}
}
public override StrategiesResultBase GetStrategyValues()
public override IndicatorsResultBase GetStrategyValues()
{
if (FastPeriods != null && SlowPeriods != null)
{
var stc = Candles.GetStc(FastPeriods.Value, FastPeriods.Value, SlowPeriods.Value).ToList();
return new StrategiesResultBase
return new IndicatorsResultBase
{
Stc = stc
};

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals;
public class SuperTrendCrossEma : Strategy
public class SuperTrendCrossEma : Indicator
{
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>();
Period = period;
@@ -157,9 +157,9 @@ public class SuperTrendCrossEma : Strategy
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)
.ToList()

View File

@@ -7,11 +7,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Signals;
public class SuperTrendStrategy : Strategy
public class SuperTrendIndicator : Indicator
{
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>();
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)
.ToList()

View File

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

View File

@@ -6,11 +6,11 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Trends;
public class EmaTrendStrategy : EmaBaseStrategy
public class EmaTrendIndicator : EmaBaseIndicator
{
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>();
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()
};

View File

@@ -7,16 +7,16 @@ using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Trends;
public class StochRsiTrendStrategy : Strategy
public class StochRsiTrendIndicator : Indicator
{
public List<Signal> Signals { get; set; }
public StochRsiTrendStrategy(
public StochRsiTrendIndicator(
string name,
int period,
int stochPeriod,
int signalPeriod,
int smoothPeriods) : base(name, StrategyType.StochRsiTrend)
int smoothPeriods) : base(name, IndicatorType.StochRsiTrend)
{
Signals = new List<Signal>();
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)
.ToList()

View File

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

View File

@@ -7,7 +7,7 @@ namespace Managing.Infrastructure.Databases.MongoDb.Collections
public class ScenarioDto : Document
{
public string Name { get; set; }
public List<StrategyDto> Strategies { get; set; }
public List<IndicatorDto> Indicators { get; set; }
public int LoopbackPeriod { 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 SignalStatus Status { get; set; }
public Timeframe Timeframe { get; set; }
public StrategyType Type { get; set; }
public IndicatorType Type { get; set; }
public SignalType SignalType { get; set; }
public UserDto User { get; set; }
}
}
}

View File

@@ -370,7 +370,7 @@ public static class MongoMappers
Ticker = signal.Ticker,
Status = signal.Status,
Timeframe = signal.Timeframe,
Type = signal.StrategyType,
Type = signal.IndicatorType,
User = signal.User != null ? Map(signal.User) : null
};
}
@@ -412,7 +412,7 @@ public static class MongoMappers
return new ScenarioDto
{
Name = scenario.Name,
Strategies = Map(scenario.Strategies),
Indicators = Map(scenario.Indicators),
LoopbackPeriod = scenario.LoopbackPeriod ?? 1,
User = scenario.User != null ? Map(scenario.User) : null
};
@@ -430,64 +430,64 @@ public static class MongoMappers
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
};
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 new Strategy(strategyDto.Name, strategyDto.Type)
return new Indicator(indicatorDto.Name, indicatorDto.Type)
{
SignalType = strategyDto.SignalType,
MinimumHistory = strategyDto.MinimumHistory,
Period = strategyDto.Period,
FastPeriods = strategyDto.FastPeriods,
SlowPeriods = strategyDto.SlowPeriods,
SignalPeriods = strategyDto.SignalPeriods,
Multiplier = strategyDto.Multiplier,
SmoothPeriods = strategyDto.SmoothPeriods,
StochPeriods = strategyDto.StochPeriods,
CyclePeriods = strategyDto.CyclePeriods,
User = strategyDto.User != null ? Map(strategyDto.User) : null
SignalType = indicatorDto.SignalType,
MinimumHistory = indicatorDto.MinimumHistory,
Period = indicatorDto.Period,
FastPeriods = indicatorDto.FastPeriods,
SlowPeriods = indicatorDto.SlowPeriods,
SignalPeriods = indicatorDto.SignalPeriods,
Multiplier = indicatorDto.Multiplier,
SmoothPeriods = indicatorDto.SmoothPeriods,
StochPeriods = indicatorDto.StochPeriods,
CyclePeriods = indicatorDto.CyclePeriods,
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 new StrategyDto
return new IndicatorDto
{
Name = strategy.Name,
Type = strategy.Type,
SignalType = strategy.SignalType,
MinimumHistory = strategy.MinimumHistory,
Period = strategy.Period,
FastPeriods = strategy.FastPeriods,
SlowPeriods = strategy.SlowPeriods,
SignalPeriods = strategy.SignalPeriods,
Multiplier = strategy.Multiplier,
SmoothPeriods = strategy.SmoothPeriods,
StochPeriods = strategy.StochPeriods,
CyclePeriods = strategy.CyclePeriods,
User = strategy.User != null ? Map(strategy.User) : null
Name = indicator.Name,
Type = indicator.Type,
SignalType = indicator.SignalType,
MinimumHistory = indicator.MinimumHistory,
Period = indicator.Period,
FastPeriods = indicator.FastPeriods,
SlowPeriods = indicator.SlowPeriods,
SignalPeriods = indicator.SignalPeriods,
Multiplier = indicator.Multiplier,
SmoothPeriods = indicator.SmoothPeriods,
StochPeriods = indicator.StochPeriods,
CyclePeriods = indicator.CyclePeriods,
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
@@ -567,8 +567,8 @@ public static class MongoMappers
Scenario = new ScenarioDto
{
Name = spotlight.Scenario.Name,
Strategies =
spotlight.Scenario.Strategies.ConvertAll(
Indicators =
spotlight.Scenario.Indicators.ConvertAll(
spotlightScenarioStrategy => Map(spotlightScenarioStrategy))
},
TickerSignals = spotlight.TickerSignals.ConvertAll(spotlightTickerSignal => new TickerSignalDto
@@ -607,8 +607,8 @@ public static class MongoMappers
{
Scenario = new Scenario(name: spotlight.Scenario.Name)
{
Strategies =
spotlight.Scenario.Strategies.ConvertAll(
Indicators =
spotlight.Scenario.Indicators.ConvertAll(
spotlightScenarioStrategy => Map(spotlightScenarioStrategy))
},
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<SignalDto> _signalRepository;
private readonly IMongoRepository<PositionDto> _positionRepository;
private readonly IMongoRepository<StrategyDto> _strategyRepository;
private readonly IMongoRepository<IndicatorDto> _indicatorRepository;
private readonly IMongoRepository<FeeDto> _feeRepository;
public TradingRepository(
IMongoRepository<ScenarioDto> scenarioRepository,
IMongoRepository<SignalDto> signalRepository,
IMongoRepository<PositionDto> positionRepository,
IMongoRepository<StrategyDto> strategyRepository,
IMongoRepository<IndicatorDto> indicatorRepository,
IMongoRepository<FeeDto> feeRepository)
{
_scenarioRepository = scenarioRepository;
_signalRepository = signalRepository;
_positionRepository = positionRepository;
_strategyRepository = strategyRepository;
_indicatorRepository = indicatorRepository;
_feeRepository = feeRepository;
}
@@ -44,15 +44,15 @@ public class TradingRepository : ITradingRepository
_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);
_strategyRepository.DeleteById(strategy.Id.ToString());
var strategy = _indicatorRepository.FindOne(s => s.Name == name);
_indicatorRepository.DeleteById(strategy.Id.ToString());
}
public Position GetPositionByIdentifier(string identifier)
@@ -87,15 +87,15 @@ public class TradingRepository : ITradingRepository
return scenarios.Select(s => MongoMappers.Map(s));
}
public IEnumerable<Strategy> GetStrategies()
public IEnumerable<Indicator> GetIndicators()
{
var strategies = _strategyRepository.FindAll();
return strategies.Select(MongoMappers.Map);
var indicators = _indicatorRepository.FindAll();
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);
}
@@ -129,17 +129,17 @@ public class TradingRepository : ITradingRepository
$"Scenario with name '{scenario.Name}' already exists for user '{scenario.User?.Name}'");
}
var strategyDtos = new List<StrategyDto>();
foreach (var strategy in scenario.Strategies)
var strategyDtos = new List<IndicatorDto>();
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);
}
var scenarioDto = new ScenarioDto
{
Name = scenario.Name,
Strategies = strategyDtos,
Indicators = strategyDtos,
User = scenario.User != null ? MongoMappers.Map(scenario.User) : null
};
@@ -165,21 +165,21 @@ public class TradingRepository : ITradingRepository
_signalRepository.InsertOne(dto);
}
public void InsertStrategy(Strategy strategy)
public void InsertStrategy(Indicator indicator)
{
// Check if strategy already exists for the same user
var existingStrategy = _strategyRepository.FindOne(s =>
s.Name == strategy.Name &&
(strategy.User == null || (s.User != null && s.User.Name == strategy.User.Name)));
var existingStrategy = _indicatorRepository.FindOne(s =>
s.Name == indicator.Name &&
(indicator.User == null || (s.User != null && s.User.Name == indicator.User.Name)));
if (existingStrategy != null)
{
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);
_strategyRepository.InsertOne(dto);
var dto = MongoMappers.Map(indicator);
_indicatorRepository.InsertOne(dto);
}
public void InsertFee(Fee fee)
@@ -262,11 +262,11 @@ public class TradingRepository : ITradingRepository
_scenarioRepository.Update(dto);
}
public void UpdateStrategy(Strategy strategy)
public void UpdateStrategy(Indicator indicator)
{
var s = _strategyRepository.FindOne(s => s.Name == strategy.Name);
var dto = MongoMappers.Map(strategy);
var s = _indicatorRepository.FindOne(s => s.Name == indicator.Name);
var dto = MongoMappers.Map(indicator);
dto.Id = s.Id;
_strategyRepository.Update(dto);
_indicatorRepository.Update(dto);
}
}