fix backtest below 10usdc + update trade
This commit is contained in:
@@ -33,4 +33,5 @@ public interface ITradingRepository
|
||||
Task UpdateStrategyAsync(IndicatorBase indicatorBase);
|
||||
Task<IndicatorBase> GetStrategyByNameUserAsync(string name, User user);
|
||||
Task<Scenario> GetScenarioByNameUserAsync(string scenarioName, User user);
|
||||
Task UpdateTradeAsync(Trade trade);
|
||||
}
|
||||
@@ -19,6 +19,7 @@ public interface ITradingService
|
||||
Task<Scenario> GetScenarioByNameAsync(string scenario);
|
||||
Task InsertPositionAsync(Position position);
|
||||
Task UpdatePositionAsync(Position position);
|
||||
Task UpdateTradeAsync(Trade trade);
|
||||
Task<IndicatorBase> GetIndicatorByNameAsync(string strategy);
|
||||
Task InsertScenarioAsync(Scenario scenario);
|
||||
Task InsertIndicatorAsync(IndicatorBase indicatorBase);
|
||||
|
||||
@@ -98,8 +98,8 @@ public class BacktestTradingBotGrain : Grain, IBacktestTradingBotGrain
|
||||
if (currentWalletBalance < Constants.GMX.Config.MinimumPositionAmount)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Backtest stopped early: Wallet balance fell below 10 USDC (Current: {CurrentBalance:F2} USDC) at candle {CurrentCandle}/{TotalCandles} from {CandleDate}",
|
||||
currentWalletBalance, currentCandle, totalCandles, candle.Date.ToString("yyyy-MM-dd HH:mm"));
|
||||
"Backtest stopped early: Wallet balance fell below {MinimumPositionAmount} USDC (Current: {CurrentBalance:F2} USDC) at candle {CurrentCandle}/{TotalCandles} from {CandleDate}",
|
||||
Constants.GMX.Config.MinimumPositionAmount, currentWalletBalance, currentCandle, totalCandles, candle.Date.ToString("yyyy-MM-dd HH:mm"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,6 +420,12 @@ public class TradingBotBase : ITradingBot
|
||||
if (!internalPosition.Status.Equals(PositionStatus.New))
|
||||
{
|
||||
internalPosition.Status = PositionStatus.Filled;
|
||||
|
||||
// Update Open trade status when position becomes Filled
|
||||
if (internalPosition.Open != null)
|
||||
{
|
||||
internalPosition.Open.SetStatus(TradeStatus.Filled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -431,7 +437,8 @@ public class TradingBotBase : ITradingBot
|
||||
|
||||
if (orders.Any())
|
||||
{
|
||||
if (orders.Count() >= 3)
|
||||
var ordersCount = orders.Count();
|
||||
if (ordersCount >= 3)
|
||||
{
|
||||
var currentTime = Config.IsForBacktest ? LastCandle?.Date ?? DateTime.UtcNow : DateTime.UtcNow;
|
||||
var timeSinceRequest = currentTime - positionForSignal.Open.Date;
|
||||
@@ -467,7 +474,7 @@ public class TradingBotBase : ITradingBot
|
||||
$"⏳ **Waiting for Orders**\nPosition has `{orders.Count()}` open orders\nElapsed: `{timeSinceRequest.TotalMinutes:F1}min`\nWaiting `{remainingMinutes:F1}min` more before canceling");
|
||||
}
|
||||
}
|
||||
else if (orders.Count() == 2 && Positions[internalPosition.Identifier].Status == PositionStatus.New)
|
||||
else if (ordersCount == 2)
|
||||
{
|
||||
// Check if position is already open on broker with 2 orders
|
||||
await LogInformation(
|
||||
@@ -488,7 +495,6 @@ public class TradingBotBase : ITradingBot
|
||||
UpdatePositionPnl(positionForSignal.Identifier, brokerPosition.ProfitAndLoss.Realized);
|
||||
await SetPositionStatus(signal.Identifier, PositionStatus.Filled);
|
||||
|
||||
|
||||
// Notify platform summary about the executed trade
|
||||
await NotifyAgentAndPlatformGrainAsync(AgentSummaryEventType.PositionOpened,
|
||||
$"Position found on broker with 2 orders: {internalPosition.Identifier}", internalPosition);
|
||||
@@ -1118,6 +1124,7 @@ public class TradingBotBase : ITradingBot
|
||||
{
|
||||
closingPrice = position.StopLoss.Price;
|
||||
position.StopLoss.SetDate(currentCandle.Date);
|
||||
position.StopLoss.SetStatus(TradeStatus.Filled);
|
||||
|
||||
Logger.LogInformation(
|
||||
$"🛑 **Stop Loss Execution Confirmed**\n" +
|
||||
@@ -1129,6 +1136,7 @@ public class TradingBotBase : ITradingBot
|
||||
{
|
||||
closingPrice = position.TakeProfit1.Price;
|
||||
position.TakeProfit1.SetDate(currentCandle.Date);
|
||||
position.TakeProfit1.SetStatus(TradeStatus.Filled);
|
||||
|
||||
Logger.LogInformation(
|
||||
$"🎯 **Take Profit Execution Confirmed**\n" +
|
||||
@@ -1154,10 +1162,12 @@ public class TradingBotBase : ITradingBot
|
||||
if (isManualCloseProfitable)
|
||||
{
|
||||
position.TakeProfit1.SetDate(currentCandle.Date);
|
||||
position.TakeProfit1.SetStatus(TradeStatus.Filled);
|
||||
}
|
||||
else
|
||||
{
|
||||
position.StopLoss.SetDate(currentCandle.Date);
|
||||
position.StopLoss.SetStatus(TradeStatus.Filled);
|
||||
}
|
||||
|
||||
Logger.LogInformation(
|
||||
@@ -1193,6 +1203,15 @@ public class TradingBotBase : ITradingBot
|
||||
|
||||
await SetPositionStatus(position.SignalIdentifier, PositionStatus.Finished);
|
||||
|
||||
// Update position in database with all trade changes
|
||||
if (!Config.IsForBacktest)
|
||||
{
|
||||
await ServiceScopeHelpers.WithScopedService<ITradingService>(_scopeFactory, async tradingService =>
|
||||
{
|
||||
await tradingService.UpdatePositionAsync(position);
|
||||
});
|
||||
}
|
||||
|
||||
// Update the last position closing time for cooldown period tracking
|
||||
LastPositionClosingTime = Config.IsForBacktest ? currentCandle.Date : DateTime.UtcNow;
|
||||
|
||||
@@ -1299,6 +1318,12 @@ public class TradingBotBase : ITradingBot
|
||||
Positions.Values.First(p => p.SignalIdentifier == signalIdentifier).Status = positionStatus;
|
||||
await LogInformation(
|
||||
$"📊 **Position Status Change**\nPosition: `{signalIdentifier}`\nStatus: `{position.Status}` → `{positionStatus}`");
|
||||
|
||||
// Update Open trade status when position becomes Filled
|
||||
if (positionStatus == PositionStatus.Filled && position.Open != null)
|
||||
{
|
||||
position.Open.SetStatus(TradeStatus.Filled);
|
||||
}
|
||||
}
|
||||
|
||||
SetSignalStatus(signalIdentifier,
|
||||
|
||||
@@ -184,6 +184,11 @@ public class TradingService : ITradingService
|
||||
await _tradingRepository.UpdatePositionAsync(position);
|
||||
}
|
||||
|
||||
public async Task UpdateTradeAsync(Trade trade)
|
||||
{
|
||||
await _tradingRepository.UpdateTradeAsync(trade);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Position>> GetPositionsAsync()
|
||||
{
|
||||
var positions = new List<Position>();
|
||||
|
||||
@@ -402,6 +402,52 @@ public class PostgreSqlTradingRepository : ITradingRepository
|
||||
: null;
|
||||
entity.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
// Update related trades
|
||||
if (position.Open != null)
|
||||
{
|
||||
await UpdateTradeAsync(position.Open);
|
||||
}
|
||||
|
||||
if (position.StopLoss != null)
|
||||
{
|
||||
await UpdateTradeAsync(position.StopLoss);
|
||||
}
|
||||
|
||||
if (position.TakeProfit1 != null)
|
||||
{
|
||||
await UpdateTradeAsync(position.TakeProfit1);
|
||||
}
|
||||
|
||||
if (position.TakeProfit2 != null)
|
||||
{
|
||||
await UpdateTradeAsync(position.TakeProfit2);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateTradeAsync(Trade trade)
|
||||
{
|
||||
var entity = _context.Trades
|
||||
.AsTracking()
|
||||
.FirstOrDefault(t => t.ExchangeOrderId == trade.ExchangeOrderId);
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
entity.Date = trade.Date;
|
||||
entity.Direction = trade.Direction;
|
||||
entity.Status = trade.Status;
|
||||
entity.TradeType = trade.TradeType;
|
||||
entity.Ticker = trade.Ticker;
|
||||
entity.Fee = trade.Fee;
|
||||
entity.Quantity = trade.Quantity;
|
||||
entity.Price = trade.Price;
|
||||
entity.Leverage = trade.Leverage;
|
||||
entity.ExchangeOrderId = trade.ExchangeOrderId;
|
||||
entity.Message = trade.Message;
|
||||
entity.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user