Fix manual position open

This commit is contained in:
2025-08-07 14:47:36 +07:00
parent b1c1c8725d
commit 46a6cdcd87
4 changed files with 25 additions and 3 deletions

View File

@@ -24,6 +24,7 @@ namespace Managing.Application.Abstractions
decimal GetProfitAndLoss(); decimal GetProfitAndLoss();
decimal GetTotalFees(); decimal GetTotalFees();
Task LoadAccount(); Task LoadAccount();
Task LoadLastCandle();
Task<Position> OpenPositionManually(TradeDirection direction); Task<Position> OpenPositionManually(TradeDirection direction);
Task CloseTrade(LightSignal signal, Position position, Trade tradeToClose, decimal lastPrice, Task CloseTrade(LightSignal signal, Position position, Trade tradeToClose, decimal lastPrice,

View File

@@ -249,8 +249,8 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
throw new InvalidOperationException("Account name is required for live trading"); throw new InvalidOperationException("Account name is required for live trading");
} }
// Create the trading bot instance using var scope = _scopeFactory.CreateScope();
var logger = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<ILogger<TradingBotBase>>(); var logger = scope.ServiceProvider.GetRequiredService<ILogger<TradingBotBase>>();
var tradingBot = new TradingBotBase(logger, _scopeFactory, config); var tradingBot = new TradingBotBase(logger, _scopeFactory, config);
// Restore state from grain state // Restore state from grain state
@@ -261,6 +261,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
tradingBot.ExecutionCount = _state.State.ExecutionCount; tradingBot.ExecutionCount = _state.State.ExecutionCount;
tradingBot.Identifier = _state.State.Identifier; tradingBot.Identifier = _state.State.Identifier;
tradingBot.LastPositionClosingTime = _state.State.LastPositionClosingTime; tradingBot.LastPositionClosingTime = _state.State.LastPositionClosingTime;
tradingBot.LastCandle = _state.State.LastCandle;
return tradingBot; return tradingBot;
} }
@@ -311,6 +312,17 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
throw new InvalidOperationException("Bot is not running"); throw new InvalidOperationException("Bot is not running");
} }
// Ensure LastCandle is available for manual position opening
if (_tradingBot.LastCandle == null)
{
_logger.LogInformation("LastCandle is null, loading latest candle data for manual position opening");
await _tradingBot.LoadLastCandle();
// Sync the loaded candle to grain state
SyncStateFromBase();
await _state.WriteStateAsync();
}
return await _tradingBot.OpenPositionManually(direction); return await _tradingBot.OpenPositionManually(direction);
} }
catch (Exception ex) catch (Exception ex)
@@ -367,6 +379,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
_tradingBot.ExecutionCount = _state.State.ExecutionCount; _tradingBot.ExecutionCount = _state.State.ExecutionCount;
_tradingBot.Identifier = _state.State.Identifier; _tradingBot.Identifier = _state.State.Identifier;
_tradingBot.LastPositionClosingTime = _state.State.LastPositionClosingTime; _tradingBot.LastPositionClosingTime = _state.State.LastPositionClosingTime;
_tradingBot.LastCandle = _state.State.LastCandle;
} }
private void SyncStateFromBase() private void SyncStateFromBase()
@@ -379,6 +392,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
_state.State.ExecutionCount = _tradingBot.ExecutionCount; _state.State.ExecutionCount = _tradingBot.ExecutionCount;
_state.State.Identifier = _tradingBot.Identifier; _state.State.Identifier = _tradingBot.Identifier;
_state.State.LastPositionClosingTime = _tradingBot.LastPositionClosingTime; _state.State.LastPositionClosingTime = _tradingBot.LastPositionClosingTime;
_state.State.LastCandle = _tradingBot.LastCandle;
_state.State.Config = _tradingBot.Config; _state.State.Config = _tradingBot.Config;
} }

View File

@@ -107,7 +107,7 @@ public class TradingBotBase : ITradingBot
} }
} }
private async Task LoadLastCandle() public async Task LoadLastCandle()
{ {
await ServiceScopeHelpers.WithScopedService<IExchangeService>(_scopeFactory, async exchangeService => await ServiceScopeHelpers.WithScopedService<IExchangeService>(_scopeFactory, async exchangeService =>
{ {

View File

@@ -1,4 +1,5 @@
using Managing.Domain.Bots; using Managing.Domain.Bots;
using Managing.Domain.Candles;
using Managing.Domain.Indicators; using Managing.Domain.Indicators;
using Managing.Domain.Trades; using Managing.Domain.Trades;
using Managing.Domain.Users; using Managing.Domain.Users;
@@ -114,4 +115,10 @@ public class TradingBotGrainState
/// </summary> /// </summary>
[Id(17)] [Id(17)]
public DateTime? LastPositionClosingTime { get; set; } public DateTime? LastPositionClosingTime { get; set; }
/// <summary>
/// The last candle data used for trading decisions
/// </summary>
[Id(18)]
public Candle? LastCandle { get; set; }
} }