Refactoring TradingBotBase.cs + clean architecture (#38)

* Refactoring TradingBotBase.cs + clean architecture

* Fix basic tests

* Fix tests

* Fix workers

* Fix open positions

* Fix closing position stucking the grain

* Fix comments

* Refactor candle handling to use IReadOnlyList for chronological order preservation across various components
This commit is contained in:
Oda
2025-12-01 19:32:06 +07:00
committed by GitHub
parent ab26260f6d
commit 9d536ea49e
74 changed files with 4525 additions and 2350 deletions

View File

@@ -123,7 +123,7 @@ public class BacktestExecutorTests : BaseTests, IDisposable
Timeframe = Timeframe.FifteenMinutes,
IsForWatchingOnly = false,
BotTradingBalance = 1000,
IsForBacktest = true,
TradingType = TradingType.BacktestFutures,
CooldownPeriod = 1,
MaxLossStreak = 0,
FlipPosition = false,
@@ -136,7 +136,7 @@ public class BacktestExecutorTests : BaseTests, IDisposable
// Act
var result = await _backtestExecutor.ExecuteAsync(
config,
candles.ToHashSet(),
candles, // candles is already a List, no conversion needed
_testUser,
save: false,
withCandles: false,
@@ -172,16 +172,16 @@ public class BacktestExecutorTests : BaseTests, IDisposable
Assert.NotNull(result);
Assert.IsType<LightBacktest>(result);
// Validate key metrics - Updated after bug fix in executor
// Validate key metrics - Updated after refactoring
Assert.Equal(1000.0m, result.InitialBalance);
Assert.Equal(45.30m, Math.Round(result.FinalPnl, 2));
Assert.Equal(32, result.WinRate);
Assert.Equal(-1.77m, Math.Round(result.GrowthPercentage, 2));
Assert.Equal(8.79m, Math.Round(result.FinalPnl, 2));
Assert.Equal(31, result.WinRate);
Assert.Equal(-6.14m, Math.Round(result.GrowthPercentage, 2));
Assert.Equal(-0.67m, Math.Round(result.HodlPercentage, 2));
Assert.Equal(59.97m, Math.Round(result.Fees, 2));
Assert.Equal(-17.74m, Math.Round(result.NetPnl, 2));
Assert.Equal(158.79m, Math.Round((decimal)result.MaxDrawdown, 2));
Assert.Equal(-0.004, Math.Round((double)(result.SharpeRatio ?? 0), 3));
Assert.Equal(66.46m, Math.Round(result.Fees, 2));
Assert.Equal(-61.36m, Math.Round(result.NetPnl, 2));
Assert.Equal(202.29m, Math.Round((decimal)result.MaxDrawdown, 2));
Assert.Equal(-0.015, Math.Round((double)(result.SharpeRatio ?? 0), 3));
Assert.True(Math.Abs(result.Score - 0.0) < 0.001,
$"Score {result.Score} should be within 0.001 of expected value 0.0");
@@ -218,7 +218,7 @@ public class BacktestExecutorTests : BaseTests, IDisposable
Timeframe = Timeframe.FifteenMinutes,
IsForWatchingOnly = false,
BotTradingBalance = 100000, // Increased balance for testing more candles
IsForBacktest = true,
TradingType = TradingType.BacktestFutures,
CooldownPeriod = 1,
MaxLossStreak = 0,
FlipPosition = false,
@@ -231,7 +231,7 @@ public class BacktestExecutorTests : BaseTests, IDisposable
// Act
var result = await _backtestExecutor.ExecuteAsync(
config,
candles.ToHashSet(),
candles, // candles is already a List, no conversion needed
_testUser,
save: false,
withCandles: false,
@@ -264,16 +264,16 @@ public class BacktestExecutorTests : BaseTests, IDisposable
Assert.NotNull(result);
Assert.IsType<LightBacktest>(result);
// Validate key metrics - Updated after bug fix in executor
// Validate key metrics - Updated after refactoring
Assert.Equal(100000.0m, result.InitialBalance);
Assert.Equal(-33978.09m, Math.Round(result.FinalPnl, 2));
Assert.Equal(21, result.WinRate);
Assert.Equal(-52.16m, Math.Round(result.GrowthPercentage, 2));
Assert.Equal(-17671.68m, Math.Round(result.FinalPnl, 2));
Assert.Equal(25, result.WinRate);
Assert.Equal(-39.91m, Math.Round(result.GrowthPercentage, 2));
Assert.Equal(-12.87m, Math.Round(result.HodlPercentage, 2));
Assert.Equal(18207.71m, Math.Round(result.Fees, 2));
Assert.Equal(-52156.26m, Math.Round(result.NetPnl, 2));
Assert.Equal(54523.55m, Math.Round((decimal)result.MaxDrawdown, 2));
Assert.Equal(-0.037, Math.Round((double)(result.SharpeRatio ?? 0), 3));
Assert.Equal(22285.98m, Math.Round(result.Fees, 2));
Assert.Equal(-39910.92m, Math.Round(result.NetPnl, 2));
Assert.Equal(40416.59m, Math.Round((decimal)result.MaxDrawdown, 2));
Assert.Equal(-0.023, Math.Round((double)(result.SharpeRatio ?? 0), 3));
Assert.True(Math.Abs(result.Score - 0.0) < 0.001,
$"Score {result.Score} should be within 0.001 of expected value 0.0");
@@ -308,7 +308,7 @@ public class BacktestExecutorTests : BaseTests, IDisposable
Timeframe = Timeframe.FifteenMinutes,
IsForWatchingOnly = false,
BotTradingBalance = 100000,
IsForBacktest = true,
TradingType = TradingType.BacktestFutures,
CooldownPeriod = 1,
MaxLossStreak = 0,
FlipPosition = false,
@@ -324,7 +324,7 @@ public class BacktestExecutorTests : BaseTests, IDisposable
// Act
var result = await _backtestExecutor.ExecuteAsync(
config,
candles.ToHashSet(),
candles, // candles is already a List, no conversion needed
_testUser,
save: false,
withCandles: false,
@@ -398,7 +398,7 @@ public class BacktestExecutorTests : BaseTests, IDisposable
Timeframe = Timeframe.FifteenMinutes,
IsForWatchingOnly = false,
BotTradingBalance = 100000,
IsForBacktest = true,
TradingType = TradingType.BacktestFutures,
CooldownPeriod = 1,
MaxLossStreak = 0,
FlipPosition = false,
@@ -414,7 +414,7 @@ public class BacktestExecutorTests : BaseTests, IDisposable
// Act
var result = await _backtestExecutor.ExecuteAsync(
config,
candles.ToHashSet(),
candles, // candles is already a List, no conversion needed
_testUser,
save: false,
withCandles: false,
@@ -451,12 +451,12 @@ public class BacktestExecutorTests : BaseTests, IDisposable
Console.WriteLine("Two-Scenarios Backtest Results:");
Console.WriteLine(json);
// Business Logic Baseline Assertions - Updated after bug fix in executor
// Business Logic Baseline Assertions - Updated after refactoring
// These values establish the expected baseline for the two-scenarios test
const decimal expectedFinalPnl = -35450.45m;
const decimal expectedFinalPnl = -30567.20m;
const double expectedScore = 0.0;
const int expectedWinRatePercent = 20; // 20% win rate
const decimal expectedGrowthPercentage = -49.76m;
const decimal expectedGrowthPercentage = -45.32m;
// Allow small tolerance for floating-point precision variations
const decimal pnlTolerance = 0.01m;

View File

@@ -24,3 +24,7 @@ DateTime,TestName,CandlesCount,ExecutionTimeSeconds,ProcessingRateCandlesPerSec,
2025-11-15T07:22:05Z,Telemetry_ETH_RSI_EMACROSS,5760,10.71,537.9,28.81,18.06,33.84,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,49a693b4,dev,development
2025-11-17T16:35:10Z,Telemetry_ETH_RSI_EMACROSS,5760,5.88,979.2,28.79,17.97,33.77,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,091f617e,dev,development
2025-11-17T16:49:22Z,Telemetry_ETH_RSI_EMACROSS,5760,4.61,1249.2,28.80,17.29,33.78,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,091f617e,dev,development
2025-12-01T10:46:58Z,Telemetry_ETH_RSI_EMACROSS,5760,2.76,2088.5,28.93,37.61,39.82,0.0,0,0.0,0.0,0.0,0.0,-30567.20,20,-45.32,0.00,93dc3e37,refactor-trading-bot,development
2025-12-01T10:49:46Z,Telemetry_ETH_RSI_EMACROSS,5760,2.94,1962.1,28.94,37.41,39.55,0.0,0,0.0,0.0,0.0,0.0,-30567.20,20,-45.32,0.00,93dc3e37,refactor-trading-bot,development
2025-12-01T10:50:15Z,Telemetry_ETH_RSI_EMACROSS,5760,2.98,1935.6,28.91,37.35,39.49,0.0,0,0.0,0.0,0.0,0.0,-30567.20,20,-45.32,0.00,93dc3e37,refactor-trading-bot,development
2025-12-01T10:50:46Z,Telemetry_ETH_RSI_EMACROSS,5760,2.30,2508.3,28.92,37.35,39.50,0.0,0,0.0,0.0,0.0,0.0,-30567.20,20,-45.32,0.00,93dc3e37,refactor-trading-bot,development
1 DateTime TestName CandlesCount ExecutionTimeSeconds ProcessingRateCandlesPerSec MemoryStartMB MemoryEndMB MemoryPeakMB SignalUpdatesCount SignalUpdatesSkipped SignalUpdateEfficiencyPercent BacktestStepsCount AverageSignalUpdateMs AverageBacktestStepMs FinalPnL WinRatePercent GrowthPercentage Score CommitHash GitBranch Environment
24 2025-11-15T07:22:05Z Telemetry_ETH_RSI_EMACROSS 5760 10.71 537.9 28.81 18.06 33.84 0.0 0 0.0 0.0 0.0 0.0 -35450.45 20 -49.76 0.00 49a693b4 dev development
25 2025-11-17T16:35:10Z Telemetry_ETH_RSI_EMACROSS 5760 5.88 979.2 28.79 17.97 33.77 0.0 0 0.0 0.0 0.0 0.0 -35450.45 20 -49.76 0.00 091f617e dev development
26 2025-11-17T16:49:22Z Telemetry_ETH_RSI_EMACROSS 5760 4.61 1249.2 28.80 17.29 33.78 0.0 0 0.0 0.0 0.0 0.0 -35450.45 20 -49.76 0.00 091f617e dev development
27 2025-12-01T10:46:58Z Telemetry_ETH_RSI_EMACROSS 5760 2.76 2088.5 28.93 37.61 39.82 0.0 0 0.0 0.0 0.0 0.0 -30567.20 20 -45.32 0.00 93dc3e37 refactor-trading-bot development
28 2025-12-01T10:49:46Z Telemetry_ETH_RSI_EMACROSS 5760 2.94 1962.1 28.94 37.41 39.55 0.0 0 0.0 0.0 0.0 0.0 -30567.20 20 -45.32 0.00 93dc3e37 refactor-trading-bot development
29 2025-12-01T10:50:15Z Telemetry_ETH_RSI_EMACROSS 5760 2.98 1935.6 28.91 37.35 39.49 0.0 0 0.0 0.0 0.0 0.0 -30567.20 20 -45.32 0.00 93dc3e37 refactor-trading-bot development
30 2025-12-01T10:50:46Z Telemetry_ETH_RSI_EMACROSS 5760 2.30 2508.3 28.92 37.35 39.50 0.0 0 0.0 0.0 0.0 0.0 -30567.20 20 -45.32 0.00 93dc3e37 refactor-trading-bot development

View File

@@ -69,3 +69,7 @@ DateTime,TestName,CandlesCount,ExecutionTimeSeconds,ProcessingRateCandlesPerSec,
2025-11-15T07:22:05Z,Telemetry_ETH_RSI,5760,7.49,766.2,28.80,20.86,34.90,5992.19,0,0.0,916.71,0.00,0.16,-30689.97,24,-51.70,0.00,49a693b4,dev,development
2025-11-17T16:35:10Z,Telemetry_ETH_RSI,5760,4.18,1373.1,29.03,20.63,36.17,3521.98,0,0.0,486.12,0.00,0.08,-30689.97,24,-51.70,0.00,091f617e,dev,development
2025-11-17T16:49:22Z,Telemetry_ETH_RSI,5760,2.885,1990.6,29.02,20.35,35.08,2530.49,0,0.0,226.92,0.00,0.04,-30689.97,24,-51.70,0.00,091f617e,dev,development
2025-12-01T10:46:58Z,Telemetry_ETH_RSI,5760,3.48,1653.0,28.92,24.25,41.11,3070.34,0,0.0,300.72,0.00,0.05,-9933.44,26,-36.30,0.00,93dc3e37,refactor-trading-bot,development
2025-12-01T10:49:46Z,Telemetry_ETH_RSI,5760,1.585,3624.2,28.91,24.57,40.82,1458.82,0,0.0,81.56,0.00,0.01,-9933.44,26,-36.30,0.00,93dc3e37,refactor-trading-bot,development
2025-12-01T10:50:15Z,Telemetry_ETH_RSI,5760,1.565,3670.7,28.90,24.34,41.31,1457.61,0,0.0,66.48,0.00,0.01,-9933.44,26,-36.30,0.00,93dc3e37,refactor-trading-bot,development
2025-12-01T10:50:46Z,Telemetry_ETH_RSI,5760,1.67,3442.1,28.90,23.95,41.13,1548.30,0,0.0,78.60,0.00,0.01,-9933.44,26,-36.30,0.00,93dc3e37,refactor-trading-bot,development
1 DateTime TestName CandlesCount ExecutionTimeSeconds ProcessingRateCandlesPerSec MemoryStartMB MemoryEndMB MemoryPeakMB SignalUpdatesCount SignalUpdatesSkipped SignalUpdateEfficiencyPercent BacktestStepsCount AverageSignalUpdateMs AverageBacktestStepMs FinalPnL WinRatePercent GrowthPercentage Score CommitHash GitBranch Environment
69 2025-11-15T07:22:05Z Telemetry_ETH_RSI 5760 7.49 766.2 28.80 20.86 34.90 5992.19 0 0.0 916.71 0.00 0.16 -30689.97 24 -51.70 0.00 49a693b4 dev development
70 2025-11-17T16:35:10Z Telemetry_ETH_RSI 5760 4.18 1373.1 29.03 20.63 36.17 3521.98 0 0.0 486.12 0.00 0.08 -30689.97 24 -51.70 0.00 091f617e dev development
71 2025-11-17T16:49:22Z Telemetry_ETH_RSI 5760 2.885 1990.6 29.02 20.35 35.08 2530.49 0 0.0 226.92 0.00 0.04 -30689.97 24 -51.70 0.00 091f617e dev development
72 2025-12-01T10:46:58Z Telemetry_ETH_RSI 5760 3.48 1653.0 28.92 24.25 41.11 3070.34 0 0.0 300.72 0.00 0.05 -9933.44 26 -36.30 0.00 93dc3e37 refactor-trading-bot development
73 2025-12-01T10:49:46Z Telemetry_ETH_RSI 5760 1.585 3624.2 28.91 24.57 40.82 1458.82 0 0.0 81.56 0.00 0.01 -9933.44 26 -36.30 0.00 93dc3e37 refactor-trading-bot development
74 2025-12-01T10:50:15Z Telemetry_ETH_RSI 5760 1.565 3670.7 28.90 24.34 41.31 1457.61 0 0.0 66.48 0.00 0.01 -9933.44 26 -36.30 0.00 93dc3e37 refactor-trading-bot development
75 2025-12-01T10:50:46Z Telemetry_ETH_RSI 5760 1.67 3442.1 28.90 23.95 41.13 1548.30 0 0.0 78.60 0.00 0.01 -9933.44 26 -36.30 0.00 93dc3e37 refactor-trading-bot development