Fix status for position and SLTP

This commit is contained in:
2025-09-24 12:55:12 +07:00
parent d2a4bd4426
commit 38a58abc5f

View File

@@ -402,6 +402,12 @@ public class TradingBotBase : ITradingBot
internalPosition.ProfitAndLoss = brokerPosition.ProfitAndLoss;
internalPosition.Status = PositionStatus.Filled;
// Update Open trade status when position is found on broker
if (internalPosition.Open != null)
{
internalPosition.Open.SetStatus(TradeStatus.Filled);
}
if (internalPosition.Status.Equals(PositionStatus.New))
{
await SetPositionStatus(internalPosition.SignalIdentifier, PositionStatus.Filled);
@@ -493,6 +499,13 @@ public class TradingBotBase : ITradingBot
$"✅ **Position Found on Broker**\nPosition is already open on broker\nUpdating position status to Filled");
UpdatePositionPnl(positionForSignal.Identifier, brokerPosition.ProfitAndLoss.Realized);
// Update Open trade status when position is found on broker with 2 orders
if (internalPosition.Open != null)
{
internalPosition.Open.SetStatus(TradeStatus.Filled);
}
await SetPositionStatus(signal.Identifier, PositionStatus.Filled);
// Notify platform summary about the executed trade
@@ -568,56 +581,130 @@ public class TradingBotBase : ITradingBot
{
if (positionForSignal.StopLoss.Price >= lastCandle.Low)
{
await LogInformation(
$"🛑 **Stop Loss Hit**\nClosing LONG position\nPrice: `${positionForSignal.StopLoss.Price}`");
await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss,
positionForSignal.StopLoss.Price, true);
// Use actual execution price (lastCandle.Low for SL hit)
var executionPrice = lastCandle.Low;
positionForSignal.StopLoss.SetPrice(executionPrice, 2);
positionForSignal.StopLoss.SetDate(lastCandle.Date);
positionForSignal.StopLoss.SetStatus(TradeStatus.Filled);
// Cancel TP trades when SL is hit
if (positionForSignal.TakeProfit1 != null)
{
positionForSignal.TakeProfit1.SetStatus(TradeStatus.Cancelled);
}
if (positionForSignal.TakeProfit2 != null)
{
positionForSignal.TakeProfit2.SetStatus(TradeStatus.Cancelled);
}
await LogInformation(
$"🛑 **Stop Loss Hit**\nClosing LONG position\nPrice: `${executionPrice:F2}` (was `${positionForSignal.StopLoss.Price:F2}`)");
await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss,
executionPrice, true);
}
else if (positionForSignal.TakeProfit1.Price <= lastCandle.High &&
positionForSignal.TakeProfit1.Status != TradeStatus.Filled)
{
await LogInformation(
$"🎯 **Take Profit 1 Hit**\nClosing LONG position\nPrice: `${positionForSignal.TakeProfit1.Price}`");
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1,
positionForSignal.TakeProfit1.Price, positionForSignal.TakeProfit2 == null);
// Use actual execution price (lastCandle.High for TP hit)
var executionPrice = lastCandle.High;
positionForSignal.TakeProfit1.SetPrice(executionPrice, 2);
positionForSignal.TakeProfit1.SetDate(lastCandle.Date);
positionForSignal.TakeProfit1.SetStatus(TradeStatus.Filled);
// Cancel SL trade when TP is hit
if (positionForSignal.StopLoss != null)
{
positionForSignal.StopLoss.SetStatus(TradeStatus.Cancelled);
}
await LogInformation(
$"🎯 **Take Profit 1 Hit**\nClosing LONG position\nPrice: `${executionPrice:F2}` (was `${positionForSignal.TakeProfit1.Price:F2}`)");
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1,
executionPrice, positionForSignal.TakeProfit2 == null);
}
else if (positionForSignal.TakeProfit2?.Price <= lastCandle.High)
{
await LogInformation(
$"🎯 **Take Profit 2 Hit**\nClosing LONG position\nPrice: `${positionForSignal.TakeProfit2.Price}`");
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2,
positionForSignal.TakeProfit2.Price, true);
// Use actual execution price (lastCandle.High for TP hit)
var executionPrice = lastCandle.High;
positionForSignal.TakeProfit2.SetPrice(executionPrice, 2);
positionForSignal.TakeProfit2.SetDate(lastCandle.Date);
positionForSignal.TakeProfit2.SetStatus(TradeStatus.Filled);
// Cancel SL trade when TP is hit
if (positionForSignal.StopLoss != null)
{
positionForSignal.StopLoss.SetStatus(TradeStatus.Cancelled);
}
await LogInformation(
$"🎯 **Take Profit 2 Hit**\nClosing LONG position\nPrice: `${executionPrice:F2}` (was `${positionForSignal.TakeProfit2.Price:F2}`)");
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2,
executionPrice, true);
}
}
else if (positionForSignal.OriginDirection == TradeDirection.Short)
{
if (positionForSignal.StopLoss.Price <= lastCandle.High)
{
await LogInformation(
$"🛑 **Stop Loss Hit**\nClosing SHORT position\nPrice: `${positionForSignal.StopLoss.Price}`");
await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss,
positionForSignal.StopLoss.Price, true);
// Use actual execution price (lastCandle.High for SL hit on SHORT)
var executionPrice = lastCandle.High;
positionForSignal.StopLoss.SetPrice(executionPrice, 2);
positionForSignal.StopLoss.SetDate(lastCandle.Date);
positionForSignal.StopLoss.SetStatus(TradeStatus.Filled);
// Cancel TP trades when SL is hit
if (positionForSignal.TakeProfit1 != null)
{
positionForSignal.TakeProfit1.SetStatus(TradeStatus.Cancelled);
}
if (positionForSignal.TakeProfit2 != null)
{
positionForSignal.TakeProfit2.SetStatus(TradeStatus.Cancelled);
}
await LogInformation(
$"🛑 **Stop Loss Hit**\nClosing SHORT position\nPrice: `${executionPrice:F2}` (was `${positionForSignal.StopLoss.Price:F2}`)");
await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss,
executionPrice, true);
}
else if (positionForSignal.TakeProfit1.Price >= lastCandle.Low &&
positionForSignal.TakeProfit1.Status != TradeStatus.Filled)
{
await LogInformation(
$"🎯 **Take Profit 1 Hit**\nClosing SHORT position\nPrice: `${positionForSignal.TakeProfit1.Price}`");
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1,
positionForSignal.TakeProfit1.Price, positionForSignal.TakeProfit2 == null);
// Use actual execution price (lastCandle.Low for TP hit on SHORT)
var executionPrice = lastCandle.Low;
positionForSignal.TakeProfit1.SetPrice(executionPrice, 2);
positionForSignal.TakeProfit1.SetDate(lastCandle.Date);
positionForSignal.TakeProfit1.SetStatus(TradeStatus.Filled);
// Cancel SL trade when TP is hit
if (positionForSignal.StopLoss != null)
{
positionForSignal.StopLoss.SetStatus(TradeStatus.Cancelled);
}
await LogInformation(
$"🎯 **Take Profit 1 Hit**\nClosing SHORT position\nPrice: `${executionPrice:F2}` (was `${positionForSignal.TakeProfit1.Price:F2}`)");
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1,
executionPrice, positionForSignal.TakeProfit2 == null);
}
else if (positionForSignal.TakeProfit2?.Price >= lastCandle.Low)
{
await LogInformation(
$"🎯 **Take Profit 2 Hit**\nClosing SHORT position\nPrice: `${positionForSignal.TakeProfit2.Price}`");
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2,
positionForSignal.TakeProfit2.Price, true);
// Use actual execution price (lastCandle.Low for TP hit on SHORT)
var executionPrice = lastCandle.Low;
positionForSignal.TakeProfit2.SetPrice(executionPrice, 2);
positionForSignal.TakeProfit2.SetDate(lastCandle.Date);
positionForSignal.TakeProfit2.SetStatus(TradeStatus.Filled);
// Cancel SL trade when TP is hit
if (positionForSignal.StopLoss != null)
{
positionForSignal.StopLoss.SetStatus(TradeStatus.Cancelled);
}
await LogInformation(
$"🎯 **Take Profit 2 Hit**\nClosing SHORT position\nPrice: `${executionPrice:F2}` (was `${positionForSignal.TakeProfit2.Price:F2}`)");
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2,
executionPrice, true);
}
}
}
@@ -676,6 +763,12 @@ public class TradingBotBase : ITradingBot
internalPosition.Status = PositionStatus.Filled;
internalPosition.ProfitAndLoss = internalPosition.ProfitAndLoss;
// Update Open trade status when position is updated to Filled
if (internalPosition.Open != null)
{
internalPosition.Open.SetStatus(TradeStatus.Filled);
}
// Save updated position to database
await tradingService.UpdatePositionAsync(internalPosition);
});
@@ -1137,26 +1230,52 @@ public class TradingBotBase : ITradingBot
if (wasStopLossHit)
{
closingPrice = position.StopLoss.Price;
// Use actual execution price based on direction
closingPrice = position.OriginDirection == TradeDirection.Long
? minPriceRecent // For LONG, SL hits at the low
: maxPriceRecent; // For SHORT, SL hits at the high
position.StopLoss.SetPrice(closingPrice, 2);
position.StopLoss.SetDate(currentCandle.Date);
position.StopLoss.SetStatus(TradeStatus.Filled);
// Cancel TP trades when SL is hit
if (position.TakeProfit1 != null)
{
position.TakeProfit1.SetStatus(TradeStatus.Cancelled);
}
if (position.TakeProfit2 != null)
{
position.TakeProfit2.SetStatus(TradeStatus.Cancelled);
}
Logger.LogInformation(
$"🛑 **Stop Loss Execution Confirmed**\n" +
$"Position: `{position.Identifier}`\n" +
$"SL Price: `${position.StopLoss.Price:F2}` was hit\n" +
$"SL Price: `${closingPrice:F2}` was hit (was `${position.StopLoss.Price:F2}`)\n" +
$"Recent Low: `${minPriceRecent:F2}` | Recent High: `${maxPriceRecent:F2}`");
}
else if (wasTakeProfitHit)
{
closingPrice = position.TakeProfit1.Price;
// Use actual execution price based on direction
closingPrice = position.OriginDirection == TradeDirection.Long
? maxPriceRecent // For LONG, TP hits at the high
: minPriceRecent; // For SHORT, TP hits at the low
position.TakeProfit1.SetPrice(closingPrice, 2);
position.TakeProfit1.SetDate(currentCandle.Date);
position.TakeProfit1.SetStatus(TradeStatus.Filled);
// Cancel SL trade when TP is hit
if (position.StopLoss != null)
{
position.StopLoss.SetStatus(TradeStatus.Cancelled);
}
Logger.LogInformation(
$"🎯 **Take Profit Execution Confirmed**\n" +
$"Position: `{position.Identifier}`\n" +
$"TP Price: `${position.TakeProfit1.Price:F2}` was hit\n" +
$"TP Price: `${closingPrice:F2}` was hit (was `${position.TakeProfit1.Price:F2}`)\n" +
$"Recent Low: `${minPriceRecent:F2}` | Recent High: `${maxPriceRecent:F2}`");
}
else
@@ -1176,13 +1295,31 @@ public class TradingBotBase : ITradingBot
if (isManualCloseProfitable)
{
position.TakeProfit1.SetPrice(closingPrice, 2);
position.TakeProfit1.SetDate(currentCandle.Date);
position.TakeProfit1.SetStatus(TradeStatus.Filled);
// Cancel SL trade when TP is used for manual close
if (position.StopLoss != null)
{
position.StopLoss.SetStatus(TradeStatus.Cancelled);
}
}
else
{
position.StopLoss.SetPrice(closingPrice, 2);
position.StopLoss.SetDate(currentCandle.Date);
position.StopLoss.SetStatus(TradeStatus.Filled);
// Cancel TP trades when SL is used for manual close
if (position.TakeProfit1 != null)
{
position.TakeProfit1.SetStatus(TradeStatus.Cancelled);
}
if (position.TakeProfit2 != null)
{
position.TakeProfit2.SetStatus(TradeStatus.Cancelled);
}
}
Logger.LogInformation(