Add netpnl and initialBalance to backtests

This commit is contained in:
2025-10-16 17:19:22 +07:00
parent 661f91f537
commit 472c507801
9 changed files with 50 additions and 10 deletions

View File

@@ -166,6 +166,8 @@ public class BacktestTradingBotGrain : Grain, IBacktestTradingBotGrain
Metadata = metadata,
StartDate = candles.FirstOrDefault()!.OpenTime,
EndDate = candles.LastOrDefault()!.OpenTime,
InitialBalance = tradingBot.WalletBalances.FirstOrDefault().Value,
NetPnl = finalPnl - fees,
};
if (save && user != null)
@@ -201,7 +203,9 @@ public class BacktestTradingBotGrain : Grain, IBacktestTradingBotGrain
Fees = backtest.Fees,
SharpeRatio = (double?)backtest.Statistics?.SharpeRatio,
Score = backtest.Score,
ScoreMessage = backtest.ScoreMessage
ScoreMessage = backtest.ScoreMessage,
InitialBalance = backtest.InitialBalance,
NetPnl = backtest.NetPnl
};
}

View File

@@ -172,7 +172,8 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
// Fallback: Get the first account for the user
if (_state.State.User == null)
{
throw new InvalidOperationException($"Bot '{config.Name}' (ID: {_state.State.Identifier}) has no user information. Cannot determine fallback account.");
throw new InvalidOperationException(
$"Bot '{config.Name}' (ID: {_state.State.Identifier}) has no user information. Cannot determine fallback account.");
}
var firstAccount = await ServiceScopeHelpers.WithScopedService<IAccountService, Account>(
@@ -183,8 +184,10 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
var account = userAccounts.FirstOrDefault();
if (account == null)
{
throw new InvalidOperationException($"User '{_state.State.User.Name}' has no accounts configured.");
throw new InvalidOperationException(
$"User '{_state.State.User.Name}' has no accounts configured.");
}
return account;
});
@@ -193,7 +196,8 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
_state.State.Config = config;
await _state.WriteStateAsync();
_logger.LogInformation("Bot '{BotName}' (ID: {BotId}) using fallback account '{AccountName}' for user '{UserName}'",
_logger.LogInformation(
"Bot '{BotName}' (ID: {BotId}) using fallback account '{AccountName}' for user '{UserName}'",
config.Name, _state.State.Identifier, firstAccount.Name, _state.State.User.Name);
}
@@ -461,6 +465,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
{
_logger.LogError(ex, "Error during coordinated balance check for bot {BotId}",
_state.State.Identifier);
SentrySdk.CaptureException(ex);
// Continue execution to avoid stopping the bot due to coordination errors
}
}
@@ -1046,7 +1051,8 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
{
if (_state.State.User == null)
{
throw new InvalidOperationException($"Bot '{_state.State.Config?.Name}' (ID: {_state.State.Identifier}) has no user information.");
throw new InvalidOperationException(
$"Bot '{_state.State.Config?.Name}' (ID: {_state.State.Identifier}) has no user information.");
}
return Task.FromResult(_state.State.User);