Fix realized pnl on backtest save + add tests (not all passing)

This commit is contained in:
2025-11-14 02:38:15 +07:00
parent 1f7d914625
commit 460a7bd559
34 changed files with 6012 additions and 500 deletions

View File

@@ -460,7 +460,7 @@ public class TradingBotBase : ITradingBot
if (!WalletBalances.ContainsKey(date))
{
var previousBalance = WalletBalances.First().Value;
WalletBalances[date] = previousBalance + GetProfitAndLoss();
WalletBalances[date] = previousBalance + TradingBox.GetTotalNetPnL(Positions);
}
}
@@ -1501,7 +1501,7 @@ public class TradingBotBase : ITradingBot
var closingVolume = brokerPosition.Open.Price * position.Open.Quantity *
position.Open.Leverage;
var totalBotFees = position.GasFees + position.UiFees +
TradingHelpers.CalculateClosingUiFees(closingVolume);
TradingBox.CalculateClosingUiFees(closingVolume);
var gmxNetPnl = brokerPosition.ProfitAndLoss.Realized; // This is already after GMX fees
position.ProfitAndLoss = new ProfitAndLoss
@@ -2099,67 +2099,6 @@ public class TradingBotBase : ITradingBot
}
}
public int GetWinRate()
{
// Optimized: Single iteration instead of multiple LINQ queries
int succeededPositions = 0;
int totalPositions = 0;
foreach (var position in Positions.Values)
{
if (position.IsValidForMetrics())
{
totalPositions++;
if (position.IsInProfit())
{
succeededPositions++;
}
}
}
if (totalPositions == 0)
return 0;
return (succeededPositions * 100) / totalPositions;
}
public decimal GetProfitAndLoss()
{
// Optimized: Single iteration instead of LINQ chaining
decimal netPnl = 0;
foreach (var position in Positions.Values)
{
if (position.IsValidForMetrics() && position.ProfitAndLoss != null)
{
netPnl += position.ProfitAndLoss.Net;
}
}
return netPnl;
}
/// <summary>
/// Calculates the total fees paid by the trading bot for each position.
/// Includes UI fees (0.1% of position size) and network fees ($0.15 for opening).
/// Closing fees are handled by oracle, so no network fee for closing.
/// </summary>
/// <returns>Returns the total fees paid as a decimal value.</returns>
public decimal GetTotalFees()
{
// Optimized: Avoid LINQ Where overhead, inline the check
decimal totalFees = 0;
foreach (var position in Positions.Values)
{
if (position.IsValidForMetrics())
{
totalFees += TradingHelpers.CalculatePositionFees(position);
}
}
return totalFees;
}
public async Task ToggleIsForWatchOnly()
{