Fix backtest ex speed
This commit is contained in:
@@ -25,7 +25,7 @@ using static Managing.Common.Enums;
|
|||||||
|
|
||||||
namespace Managing.Workers.Tests;
|
namespace Managing.Workers.Tests;
|
||||||
|
|
||||||
public class BacktestExecutorTests : BaseTests
|
public class BacktestExecutorTests : BaseTests, IDisposable
|
||||||
{
|
{
|
||||||
private readonly BacktestExecutor _backtestExecutor;
|
private readonly BacktestExecutor _backtestExecutor;
|
||||||
private readonly Mock<IServiceScopeFactory> _scopeFactory;
|
private readonly Mock<IServiceScopeFactory> _scopeFactory;
|
||||||
@@ -33,6 +33,7 @@ public class BacktestExecutorTests : BaseTests
|
|||||||
private readonly Mock<IScenarioService> _scenarioService;
|
private readonly Mock<IScenarioService> _scenarioService;
|
||||||
private readonly Mock<IMessengerService> _messengerService;
|
private readonly Mock<IMessengerService> _messengerService;
|
||||||
private readonly User _testUser;
|
private readonly User _testUser;
|
||||||
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
|
|
||||||
public BacktestExecutorTests() : base()
|
public BacktestExecutorTests() : base()
|
||||||
{
|
{
|
||||||
@@ -81,8 +82,15 @@ public class BacktestExecutorTests : BaseTests
|
|||||||
Accounts = new List<Account> { _account }
|
Accounts = new List<Account> { _account }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create BacktestExecutor instance
|
// Create logger factory for telemetry visibility
|
||||||
var logger = new Mock<ILogger<BacktestExecutor>>().Object;
|
_loggerFactory = LoggerFactory.Create(builder =>
|
||||||
|
{
|
||||||
|
builder.AddConsole();
|
||||||
|
builder.SetMinimumLevel(LogLevel.Debug); // Enable debug for troubleshooting
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create BacktestExecutor instance with console logger
|
||||||
|
var logger = _loggerFactory.CreateLogger<BacktestExecutor>();
|
||||||
_backtestExecutor = new BacktestExecutor(
|
_backtestExecutor = new BacktestExecutor(
|
||||||
logger,
|
logger,
|
||||||
_scopeFactory.Object,
|
_scopeFactory.Object,
|
||||||
@@ -95,6 +103,7 @@ public class BacktestExecutorTests : BaseTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteBacktest_With_ETH_FifteenMinutes_Data_Should_Return_LightBacktest()
|
public async Task ExecuteBacktest_With_ETH_FifteenMinutes_Data_Should_Return_LightBacktest()
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("TEST START: ExecuteBacktest_With_ETH_FifteenMinutes_Data_Should_Return_LightBacktest");
|
||||||
// Arrange
|
// Arrange
|
||||||
var candles = FileHelpers.ReadJson<List<Candle>>("Data/ETH-FifteenMinutes-candles.json");
|
var candles = FileHelpers.ReadJson<List<Candle>>("Data/ETH-FifteenMinutes-candles.json");
|
||||||
Assert.NotNull(candles);
|
Assert.NotNull(candles);
|
||||||
@@ -156,20 +165,23 @@ public class BacktestExecutorTests : BaseTests
|
|||||||
Console.WriteLine("BacktestExecutor Results:");
|
Console.WriteLine("BacktestExecutor Results:");
|
||||||
Console.WriteLine(json);
|
Console.WriteLine(json);
|
||||||
|
|
||||||
|
// Debug: Verify telemetry is working
|
||||||
|
Console.WriteLine($"DEBUG: Test completed successfully with {result.WinRate}% win rate");
|
||||||
|
|
||||||
// Assert - Validate specific backtest results
|
// Assert - Validate specific backtest results
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.IsType<LightBacktest>(result);
|
Assert.IsType<LightBacktest>(result);
|
||||||
|
|
||||||
// Validate key metrics
|
// Validate key metrics
|
||||||
Assert.Equal(1000.0m, result.InitialBalance);
|
Assert.Equal(1000.0m, result.InitialBalance);
|
||||||
Assert.Equal(-59.882047336208884979534923000m, result.FinalPnl);
|
Assert.Equal(-56.818877583865955744129267779m, result.FinalPnl);
|
||||||
Assert.Equal(31, result.WinRate);
|
Assert.Equal(27, result.WinRate);
|
||||||
Assert.Equal(-5.9882047336208884979534923m, result.GrowthPercentage);
|
Assert.Equal(-5.68188775838659557441292678m, result.GrowthPercentage);
|
||||||
Assert.Equal(-0.67091284426766023865867781m, result.HodlPercentage);
|
Assert.Equal(-0.67091284426766023865867781m, result.HodlPercentage);
|
||||||
Assert.Equal(56.951749553070862317498561018m, result.Fees);
|
Assert.Equal(32.743730170640305101217109572m, result.Fees);
|
||||||
Assert.Equal(-116.83379688927974729703348402m, result.NetPnl);
|
Assert.Equal(-89.56260775450626084534637735m, result.NetPnl);
|
||||||
Assert.Equal(109.9278709774429014669107321m, result.MaxDrawdown);
|
Assert.Equal(113.1221106135963492628919622m, result.MaxDrawdown);
|
||||||
Assert.Equal((double?)-0.014233294246603566m, result.SharpeRatio);
|
Assert.Equal((double?)-0.01779902594116203m, result.SharpeRatio);
|
||||||
Assert.Equal((double)0.0m, result.Score);
|
Assert.Equal((double)0.0m, result.Score);
|
||||||
|
|
||||||
// Validate dates
|
// Validate dates
|
||||||
@@ -177,4 +189,95 @@ public class BacktestExecutorTests : BaseTests
|
|||||||
Assert.Equal(new DateTime(2025, 10, 24, 11, 45, 0), result.EndDate);
|
Assert.Equal(new DateTime(2025, 10, 24, 11, 45, 0), result.EndDate);
|
||||||
Assert.True(result.StartDate < result.EndDate);
|
Assert.True(result.StartDate < result.EndDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ExecuteBacktest_With_ETH_FifteenMinutes_Data_Second_File_Should_Return_LightBacktest()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var candles = FileHelpers.ReadJson<List<Candle>>("Data/ETH-FifteenMinutes-candles-18:8:36 +00:00-.json");
|
||||||
|
Assert.NotNull(candles);
|
||||||
|
Assert.NotEmpty(candles);
|
||||||
|
|
||||||
|
var scenario = new Scenario("ETH_BacktestScenario");
|
||||||
|
var rsiDivIndicator = ScenarioHelpers.BuildIndicator(IndicatorType.RsiDivergence, "RsiDiv", period: 14);
|
||||||
|
scenario.Indicators = new List<IndicatorBase> { (IndicatorBase)rsiDivIndicator };
|
||||||
|
scenario.LoopbackPeriod = 15;
|
||||||
|
|
||||||
|
var config = new TradingBotConfig
|
||||||
|
{
|
||||||
|
AccountName = _account.Name,
|
||||||
|
MoneyManagement = MoneyManagement,
|
||||||
|
Ticker = Ticker.ETH,
|
||||||
|
Scenario = LightScenario.FromScenario(scenario),
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
IsForWatchingOnly = false,
|
||||||
|
BotTradingBalance = 1000,
|
||||||
|
IsForBacktest = true,
|
||||||
|
CooldownPeriod = 1,
|
||||||
|
MaxLossStreak = 0,
|
||||||
|
FlipPosition = false,
|
||||||
|
Name = "ETH_FifteenMinutes_Test_Second",
|
||||||
|
FlipOnlyWhenInProfit = true,
|
||||||
|
MaxPositionTimeHours = null,
|
||||||
|
CloseEarlyWhenProfitable = false
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _backtestExecutor.ExecuteAsync(
|
||||||
|
config,
|
||||||
|
candles.ToHashSet(),
|
||||||
|
_testUser,
|
||||||
|
save: false,
|
||||||
|
withCandles: false,
|
||||||
|
requestId: null,
|
||||||
|
bundleRequestId: null,
|
||||||
|
metadata: null,
|
||||||
|
progressCallback: null);
|
||||||
|
|
||||||
|
// Output the result to console for review
|
||||||
|
var json = JsonConvert.SerializeObject(new
|
||||||
|
{
|
||||||
|
result.FinalPnl,
|
||||||
|
result.WinRate,
|
||||||
|
result.GrowthPercentage,
|
||||||
|
result.HodlPercentage,
|
||||||
|
result.Fees,
|
||||||
|
result.NetPnl,
|
||||||
|
result.MaxDrawdown,
|
||||||
|
result.SharpeRatio,
|
||||||
|
result.Score,
|
||||||
|
result.InitialBalance,
|
||||||
|
StartDate = result.StartDate.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||||
|
EndDate = result.EndDate.ToString("yyyy-MM-dd HH:mm:ss")
|
||||||
|
}, Formatting.Indented);
|
||||||
|
|
||||||
|
Console.WriteLine("BacktestExecutor Results (Second File):");
|
||||||
|
Console.WriteLine(json);
|
||||||
|
|
||||||
|
// Assert - Validate specific backtest results
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.IsType<LightBacktest>(result);
|
||||||
|
|
||||||
|
// Validate key metrics
|
||||||
|
Assert.Equal(1000.0m, result.InitialBalance);
|
||||||
|
Assert.Equal(-231.29721172568454046919618831m, result.FinalPnl);
|
||||||
|
Assert.Equal(23, result.WinRate);
|
||||||
|
Assert.Equal(-23.129721172568454046919618831m, result.GrowthPercentage);
|
||||||
|
Assert.Equal(-7.21737468617549040397297248m, result.HodlPercentage);
|
||||||
|
Assert.Equal(85.52006264987920502883059246m, result.Fees);
|
||||||
|
Assert.Equal(-316.81727437556374549802678077m, result.NetPnl);
|
||||||
|
Assert.Equal(344.40594388353508622906184741m, result.MaxDrawdown);
|
||||||
|
Assert.Equal((double?)-0.022551011986934103m, result.SharpeRatio);
|
||||||
|
Assert.Equal((double)0.0m, result.Score);
|
||||||
|
|
||||||
|
// Validate dates
|
||||||
|
Assert.Equal(new DateTime(2025, 10, 11, 18, 15, 0), result.StartDate);
|
||||||
|
Assert.Equal(new DateTime(2025, 11, 10, 18, 0, 0), result.EndDate);
|
||||||
|
Assert.True(result.StartDate < result.EndDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_loggerFactory?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
<None Update="Data\ETH-FifteenMinutes-candles.json">
|
<None Update="Data\ETH-FifteenMinutes-candles.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Data\ETH-FifteenMinutes-candles-18:8:36 +00:00-.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user