From 68618a8628a332c48d390171226b6a04e351b1bb Mon Sep 17 00:00:00 2001 From: cryptooda Date: Sun, 27 Apr 2025 22:49:49 +0700 Subject: [PATCH] fix position initiator + pnl for trade --- src/Managing.Application/Bots/TradingBot.cs | 39 +++++++++++++------ .../Workflows/Flows/Trading/OpenPosition.cs | 13 ++----- src/Managing.Domain/Bots/Bot.cs | 14 ++++--- src/Managing.Domain/Trades/Position.cs | 6 +-- .../src/plugins/custom/gmx.ts | 2 +- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/Managing.Application/Bots/TradingBot.cs b/src/Managing.Application/Bots/TradingBot.cs index 2115923..65c7da3 100644 --- a/src/Managing.Application/Bots/TradingBot.cs +++ b/src/Managing.Application/Bots/TradingBot.cs @@ -126,7 +126,7 @@ public class TradingBot : Bot, ITradingBot await InitWorker(Run); } - Fee = TradingService.GetFee(Account, IsForBacktest); + // Fee = TradingService.GetFee(Account, IsForBacktest); } public async Task LoadAccount() @@ -249,14 +249,14 @@ public class TradingBot : Bot, ITradingBot private async Task AddSignal(Signal signal) { - Signals.Add(signal); - // if (!IsForBacktest) // TradingService.InsertSignal(signal); if (IsForWatchingOnly || (ExecutionCount < 1 && !IsForBacktest)) signal.Status = SignalStatus.Expired; + Signals.Add(signal); + var signalText = $"{ScenarioName} trigger a signal. Signal told you " + $"to {signal.Direction} {Ticker} on {Timeframe}. The confidence in this signal is {signal.Confidence}. Identifier : {signal.Identifier}"; @@ -285,9 +285,6 @@ public class TradingBot : Bot, ITradingBot private async Task ManagePositions() { - if (!IsForBacktest && ExecutionCount < 1) - return; - // Update position foreach (var signal in Signals.Where(s => s.Status == SignalStatus.PositionOpen)) { @@ -346,11 +343,26 @@ public class TradingBot : Bot, ITradingBot if (!IsForBacktest) { - position = positionsExchange.FirstOrDefault(p => p.Ticker == Ticker); - - if (position != null) + var brokerPosition = positionsExchange.FirstOrDefault(p => p.Ticker == Ticker); + if (brokerPosition != null) { - UpdatePositionPnl(positionForSignal.Identifier, position.ProfitAndLoss.Realized); + UpdatePositionPnl(positionForSignal.Identifier, brokerPosition.ProfitAndLoss.Realized); + + if (position.Status.Equals(PositionStatus.New)) + { + await SetPositionStatus(position.SignalIdentifier, PositionStatus.Filled); + } + + position = brokerPosition; + } + else + { + // No position, position close on the broker + if (!position.Status.Equals(PositionStatus.New)) + { + // Setup the previous status of the position + position.Status = PositionStatus.Filled; + } } } @@ -540,7 +552,7 @@ public class TradingBot : Bot, ITradingBot MoneyManagement, signal.Direction, Ticker, - IsForBacktest ? PositionInitiator.PaperTrading : PositionInitiator.Bot, + PositionInitiator.Bot, signal.Date, User, IsForBacktest, @@ -587,6 +599,8 @@ public class TradingBot : Bot, ITradingBot private bool CanOpenPosition(Signal signal) { + if (ExecutionCount < 1) + return false; if (Positions.Count == 0) return true; @@ -625,6 +639,7 @@ public class TradingBot : Bot, ITradingBot } else { + position.Initiator = PositionInitiator.Bot; var command = new ClosePositionCommand(position, lastPrice); try { @@ -826,7 +841,7 @@ public class TradingBot : Bot, ITradingBot IsForWatchingOnly = IsForWatchingOnly, WalletBalances = WalletBalances, MoneyManagement = MoneyManagement, - StartupTime = DateTime.Now + StartupTime = StartupTime, }; BotService.SaveOrUpdateBotBackup(Name, BotType, JsonConvert.SerializeObject(data)); } diff --git a/src/Managing.Application/Workflows/Flows/Trading/OpenPosition.cs b/src/Managing.Application/Workflows/Flows/Trading/OpenPosition.cs index 6973cdf..a1d2944 100644 --- a/src/Managing.Application/Workflows/Flows/Trading/OpenPosition.cs +++ b/src/Managing.Application/Workflows/Flows/Trading/OpenPosition.cs @@ -1,16 +1,15 @@ -using InfluxDB.Client.Api.Domain; -using Managing.Application.Abstractions; +using Managing.Application.Abstractions; +using Managing.Application.Abstractions.Repositories; using Managing.Application.Abstractions.Services; -using Managing.Application.Trading.Commands; using Managing.Application.Trading; +using Managing.Application.Trading.Commands; using Managing.Domain.Accounts; +using Managing.Domain.Candles; using Managing.Domain.Strategies; using Managing.Domain.Trades; using Managing.Domain.Workflows; using Newtonsoft.Json; using static Managing.Common.Enums; -using Managing.Domain.Candles; -using Managing.Application.Abstractions.Repositories; namespace Managing.Application.Workflows.Flows.Trading; @@ -64,10 +63,6 @@ public class OpenPosition : FlowBase var Positions = JsonConvert.DeserializeObject>(_cacheService.GetValue(POSITIONS_KEY)); var Signals = JsonConvert.DeserializeObject>(_cacheService.GetValue(POSITIONS_KEY)); - Fee = _cacheService.GetOrSave(FEE_KEY, - () => { return _tradingService.GetFee(Account, OpenPositionParameters.IsForBacktest); }, - TimeSpan.FromDays(1)); - await ExecuteOpenPosition(signal, Positions, Signals, Candles, Account); _cacheService.SaveValue(POSITIONS_KEY, JsonConvert.SerializeObject(Positions)); diff --git a/src/Managing.Domain/Bots/Bot.cs b/src/Managing.Domain/Bots/Bot.cs index fbf98b2..9bcab31 100644 --- a/src/Managing.Domain/Bots/Bot.cs +++ b/src/Managing.Domain/Bots/Bot.cs @@ -1,5 +1,4 @@ -using System.Collections.Concurrent; -using Managing.Domain.Users; +using Managing.Domain.Users; using static Managing.Common.Enums; namespace Managing.Domain.Bots @@ -16,10 +15,12 @@ namespace Managing.Domain.Bots public int Interval { get; set; } public BotStatus Status { get; set; } public User User { get; set; } + /// /// The time when the bot was started /// public DateTime StartupTime { get; private set; } + private CancellationTokenSource CancellationToken { get; set; } public Bot(string name) @@ -62,14 +63,15 @@ namespace Managing.Domain.Bots } catch (Exception ex) { + SentrySdk.CaptureException(ex); Console.WriteLine(ex.Message); } } }, CancellationToken.Token); } - catch (TaskCanceledException) + catch (TaskCanceledException ex) { - Console.WriteLine(); + Console.WriteLine($"Bot was cancelled: {ex.Message}"); } } @@ -94,7 +96,7 @@ namespace Managing.Domain.Bots { return Name; } - + /// /// Gets the total runtime of the bot since it was started /// @@ -103,7 +105,7 @@ namespace Managing.Domain.Bots { if (Status != BotStatus.Up || StartupTime == DateTime.MinValue) return TimeSpan.Zero; - + return DateTime.UtcNow - StartupTime; } diff --git a/src/Managing.Domain/Trades/Position.cs b/src/Managing.Domain/Trades/Position.cs index d361ab9..b915379 100644 --- a/src/Managing.Domain/Trades/Position.cs +++ b/src/Managing.Domain/Trades/Position.cs @@ -1,6 +1,6 @@ -using Managing.Domain.MoneyManagements; +using System.ComponentModel.DataAnnotations; +using Managing.Domain.MoneyManagements; using Managing.Domain.Users; -using System.ComponentModel.DataAnnotations; using static Managing.Common.Enums; namespace Managing.Domain.Trades @@ -34,7 +34,7 @@ namespace Managing.Domain.Trades [Required] public PositionStatus Status { get; set; } public string SignalIdentifier { get; set; } [Required] public string Identifier { get; set; } - [Required] public PositionInitiator Initiator { get; } + [Required] public PositionInitiator Initiator { get; set; } [Required] public User User { get; set; } public bool IsFinished() diff --git a/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts b/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts index f9db439..435bbd5 100644 --- a/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts +++ b/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts @@ -451,7 +451,7 @@ export const closeGmxPositionImpl = async ( indexPrice: 0n, collateralPrice: 0n, acceptablePrice: position.markPrice, - triggerOrderType: OrderType.LimitDecrease, + triggerOrderType: OrderType.MarketDecrease, triggerPrice: position.markPrice, }