Fix volume when position not open

This commit is contained in:
2025-10-05 17:14:47 +07:00
parent faec7e2e5a
commit 976c1a6580

View File

@@ -368,6 +368,16 @@ public class TradingBotBase : ITradingBot
{
try
{
// Skip processing if position is already canceled or rejected (never filled)
if (positionForSignal.Status == PositionStatus.Canceled ||
positionForSignal.Status == PositionStatus.Rejected)
{
Logger.LogDebug(
"Skipping update for position {PositionId} - status is {Status} (never filled)",
positionForSignal.Identifier, positionForSignal.Status);
return;
}
Position internalPosition = null;
List<Position> brokerPositions = null;
await ServiceScopeHelpers.WithScopedService<ITradingService>(_scopeFactory, async tradingService =>
@@ -566,8 +576,12 @@ public class TradingBotBase : ITradingBot
else
{
await LogWarning(
$"❌ **Position Closed**\nNo position on exchange and no orders\nSignal: `{signal.Identifier}`\nPosition have been closed.");
await HandleClosedPosition(positionForSignal);
$"❌ **Position Never Filled**\nNo position on exchange and no orders\nSignal: `{signal.Identifier}`\nPosition was never filled and will be marked as canceled.");
// Position was never filled (still in New status), so just mark it as canceled
// Don't call HandleClosedPosition as that would incorrectly add volume/PnL
await SetPositionStatus(signal.Identifier, PositionStatus.Canceled);
SetSignalStatus(signal.Identifier, SignalStatus.Expired);
}
}
else if (internalPosition.Status == PositionStatus.Finished ||
@@ -1395,22 +1409,44 @@ public class TradingBotBase : ITradingBot
{
position.Status = PositionStatus.Finished;
await UpdatePositionDatabase(position);
await NotifyAgentAndPlatformGrainAsync(NotificationEventType.PositionClosed, position);
// Only send PositionClosed notification if the position was actually filled
// Check if Open trade was filled (means position was opened on the broker)
if (position.Open?.Status == TradeStatus.Filled)
{
await NotifyAgentAndPlatformGrainAsync(NotificationEventType.PositionClosed, position);
// Update the last position closing time for cooldown period tracking
// Only update if position was actually filled
LastPositionClosingTime = Config.IsForBacktest ? currentCandle.Date : DateTime.UtcNow;
}
else
{
Logger.LogDebug(
"Skipping PositionClosed notification for position {PositionId} - position was never filled (Open trade status: {OpenStatus})",
position.Identifier, position.Open?.Status);
}
}
// Update the last position closing time for cooldown period tracking
LastPositionClosingTime = Config.IsForBacktest ? currentCandle.Date : DateTime.UtcNow;
Logger.LogInformation(
$"✅ **Position Closed Successfully**\nPosition: `{position.SignalIdentifier}`\nPnL: `${position.ProfitAndLoss?.Realized:F2}`");
if (position.ProfitAndLoss != null)
// Only update balance and log success if position was actually filled
if (position.Open?.Status == TradeStatus.Filled)
{
Config.BotTradingBalance += position.ProfitAndLoss.Realized;
Logger.LogInformation(
string.Format("💰 **Balance Updated**\nNew bot trading balance: `${0:F2}`",
Config.BotTradingBalance));
$"✅ **Position Closed Successfully**\nPosition: `{position.SignalIdentifier}`\nPnL: `${position.ProfitAndLoss?.Realized:F2}`");
if (position.ProfitAndLoss != null)
{
Config.BotTradingBalance += position.ProfitAndLoss.Realized;
Logger.LogInformation(
string.Format("💰 **Balance Updated**\nNew bot trading balance: `${0:F2}`",
Config.BotTradingBalance));
}
}
else
{
Logger.LogInformation(
$"✅ **Position Cleanup**\nPosition: `{position.SignalIdentifier}` was never filled - no balance or PnL changes");
}
}
else