Fix ROI calculation for Strategy
This commit is contained in:
@@ -182,8 +182,8 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
_state.State.TotalFees = totalFees;
|
||||
|
||||
// Calculate wins/losses from position PnL
|
||||
var totalWins = positions.Count(p => (p.ProfitAndLoss?.Realized ?? 0) > 0);
|
||||
var totalLosses = positions.Count(p => (p.ProfitAndLoss?.Realized ?? 0) <= 0);
|
||||
var totalWins = positions.Count(p => (p.ProfitAndLoss?.Net ?? 0) > 0);
|
||||
var totalLosses = positions.Count(p => (p.ProfitAndLoss?.Net ?? 0) <= 0);
|
||||
|
||||
// Calculate ROI based on PnL minus fees
|
||||
var netPnL = totalPnL - totalFees;
|
||||
|
||||
@@ -791,12 +791,18 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
}
|
||||
}
|
||||
|
||||
var positionForMetrics = _tradingBot.Positions.Where(p => p.Value.IsValidForMetrics())
|
||||
.Select(p => p.Value).ToList();
|
||||
var positionForMetrics = await ServiceScopeHelpers.WithScopedService<ITradingService, List<Position>>(
|
||||
_scopeFactory,
|
||||
async tradingService =>
|
||||
{
|
||||
return (await tradingService.GetPositionsByInitiatorIdentifierAsync(this.GetPrimaryKey()))
|
||||
.Where(p => p.IsValidForMetrics()).ToList();
|
||||
});
|
||||
|
||||
// Calculate statistics using TradingBox helpers
|
||||
var (tradeWins, tradeLosses) = TradingBox.GetWinLossCount(positionForMetrics);
|
||||
var pnl = _tradingBot.GetProfitAndLoss();
|
||||
var fees = _tradingBot.GetTotalFees();
|
||||
var pnl = positionForMetrics.Sum(p => p.ProfitAndLoss.Realized);
|
||||
var fees = positionForMetrics.Sum(p => p.CalculateTotalFees());
|
||||
var netPnl = pnl - fees; // Net PnL after fees
|
||||
var volume = TradingBox.GetTotalVolumeTraded(positionForMetrics);
|
||||
|
||||
|
||||
@@ -400,8 +400,8 @@ public class TradingBotBase : ITradingBot
|
||||
}
|
||||
|
||||
Position internalPosition = null;
|
||||
List<Position> brokerPositions = null;
|
||||
await ServiceScopeHelpers.WithScopedService<ITradingService>(_scopeFactory, async tradingService =>
|
||||
var brokerPositions = await ServiceScopeHelpers.WithScopedService<ITradingService, List<Position>>(
|
||||
_scopeFactory, async tradingService =>
|
||||
{
|
||||
internalPosition = Config.IsForBacktest
|
||||
? positionForSignal
|
||||
@@ -409,13 +409,16 @@ public class TradingBotBase : ITradingBot
|
||||
|
||||
if (Config.IsForBacktest)
|
||||
{
|
||||
brokerPositions = new List<Position> { internalPosition };
|
||||
return new List<Position> { internalPosition };
|
||||
}
|
||||
else
|
||||
{
|
||||
brokerPositions = await ServiceScopeHelpers.WithScopedService<IExchangeService, List<Position>>(
|
||||
return await ServiceScopeHelpers.WithScopedService<IExchangeService, List<Position>>(
|
||||
_scopeFactory,
|
||||
async exchangeService => { return [.. await exchangeService.GetBrokerPositions(Account)]; });
|
||||
async exchangeService =>
|
||||
{
|
||||
return [.. await exchangeService.GetBrokerPositions(Account)];
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -629,7 +632,7 @@ public class TradingBotBase : ITradingBot
|
||||
});
|
||||
|
||||
var currentTime = Config.IsForBacktest ? lastCandle.Date : DateTime.UtcNow;
|
||||
var currentPnl = positionForSignal.ProfitAndLoss?.Realized ?? 0;
|
||||
var currentPnl = positionForSignal.ProfitAndLoss?.Net ?? 0;
|
||||
var pnlPercentage = positionForSignal.Open.Price * positionForSignal.Open.Quantity != 0
|
||||
? Math.Round((currentPnl / (positionForSignal.Open.Price * positionForSignal.Open.Quantity)) * 100,
|
||||
2)
|
||||
@@ -1592,11 +1595,11 @@ public class TradingBotBase : ITradingBot
|
||||
if (position.Open?.Status == TradeStatus.Filled)
|
||||
{
|
||||
Logger.LogInformation(
|
||||
$"✅ Position Closed Successfully\nPosition: `{position.SignalIdentifier}`\nPnL: `${position.ProfitAndLoss?.Realized:F2}`");
|
||||
$"✅ Position Closed Successfully\nPosition: `{position.SignalIdentifier}`\nPnL: `${position.ProfitAndLoss?.Net:F2}`");
|
||||
|
||||
if (position.ProfitAndLoss != null)
|
||||
{
|
||||
Config.BotTradingBalance += position.ProfitAndLoss.Realized;
|
||||
Config.BotTradingBalance += position.ProfitAndLoss.Net;
|
||||
|
||||
Logger.LogInformation(
|
||||
string.Format("💰 Balance Updated\nNew bot trading balance: `${0:F2}`",
|
||||
|
||||
@@ -142,13 +142,6 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
|
||||
var positionVolume = TradingHelpers.GetVolumeForPosition(position);
|
||||
totalVolume += positionVolume;
|
||||
|
||||
// Add to open interest for active positions only (only opening volume)
|
||||
if (position.Status.Equals(PositionStatus.Filled))
|
||||
{
|
||||
var openingVolume = position.Open.Price * position.Open.Quantity * position.Open.Leverage;
|
||||
totalOpenInterest += openingVolume;
|
||||
}
|
||||
|
||||
// Calculate fees and PnL for all positions
|
||||
totalFees += position.CalculateTotalFees();
|
||||
totalPnL += position.ProfitAndLoss?.Realized ?? 0;
|
||||
@@ -177,8 +170,11 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
|
||||
_state.State.PositionCountByAsset[ticker]++;
|
||||
|
||||
// Position count breakdown by direction - only count finished positions
|
||||
if (position.IsValidForMetrics())
|
||||
if (position.IsOpen())
|
||||
{
|
||||
var openingVolume = position.Open.Price * position.Open.Quantity * position.Open.Leverage;
|
||||
totalOpenInterest += openingVolume;
|
||||
|
||||
if (!_state.State.PositionCountByDirection.ContainsKey(direction))
|
||||
{
|
||||
_state.State.PositionCountByDirection[direction] = 0;
|
||||
|
||||
@@ -4,7 +4,7 @@ import {closeGmxPositionImpl, getClientForAddress} from '../../src/plugins/custo
|
||||
import {TradeDirection} from '../../src/generated/ManagingApiTypes'
|
||||
|
||||
test('GMX Position Closing', async (t) => {
|
||||
await t.test('should close a long position for BTC', async () => {
|
||||
await t.test('should close position', async () => {
|
||||
const sdk = await getClientForAddress('0x932167388dD9aad41149b3cA23eBD489E2E2DD78')
|
||||
|
||||
const result = await closeGmxPositionImpl(
|
||||
|
||||
Reference in New Issue
Block a user