diff --git a/KLHZ.Trader.Core/Exchange/Services/Trader.cs b/KLHZ.Trader.Core/Exchange/Services/Trader.cs index 1dc907b..ad71c17 100644 --- a/KLHZ.Trader.Core/Exchange/Services/Trader.cs +++ b/KLHZ.Trader.Core/Exchange/Services/Trader.cs @@ -29,6 +29,7 @@ namespace KLHZ.Trader.Core.Exchange.Services private readonly TraderDataProvider _tradeDataProvider; private readonly ILogger _logger; private readonly ConcurrentDictionary OpeningStops = new(); + private readonly ConcurrentDictionary ClosingStops = new(); private readonly ConcurrentDictionary Leverages = new(); private readonly decimal _futureComission; @@ -87,13 +88,14 @@ namespace KLHZ.Trader.Core.Exchange.Services { if (message.Figi == "FUTIMOEXF000") { + ProcessStops(message, currentTime); var windowMaxSize = 1000; await SellAssetsIfNeed(message); var data = await _tradeDataProvider.GetData(message.Figi, windowMaxSize); var state = ExchangeScheduler.GetCurrentState(message.Time); await ProcessClearing(data, state, message); - ProcessOpeningStops(message, currentTime); + await ProcessNewPriceIMOEXF(data, state, message, windowMaxSize); } } @@ -120,8 +122,8 @@ namespace KLHZ.Trader.Core.Exchange.Services { var profit = TradingCalculator.CaclProfit(asset.BoughtPrice, message.Value, GetComission(assetType), GetLeverage(message.Figi, asset.Count < 0), asset.Count < 0); - - if (message.Time - asset.BoughtAt > TimeSpan.FromMinutes(4) && profit < -66m) + var stoppingKey = message.Figi + asset.AccountId; + if (message.Time - asset.BoughtAt > TimeSpan.FromMinutes(4) && profit < -66m && !ClosingStops.ContainsKey(stoppingKey)) { await _dataBus.Broadcast(new TradeCommand() { @@ -134,11 +136,12 @@ namespace KLHZ.Trader.Core.Exchange.Services EnableMargin = false, }); OpeningStops[message.Figi] = DateTime.UtcNow.AddMinutes(10); + ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30); await LogDeclision(DeclisionTradeAction.CloseLong, message, profit); await LogDeclision(DeclisionTradeAction.CloseLongReal, message, profit); } - if (message.Time - asset.BoughtAt > TimeSpan.FromHours(4) && profit > 100) + if (message.Time - asset.BoughtAt > TimeSpan.FromHours(4) && profit > 100 && !ClosingStops.ContainsKey(stoppingKey)) { await _dataBus.Broadcast(new TradeCommand() { @@ -150,6 +153,7 @@ namespace KLHZ.Trader.Core.Exchange.Services RecomendPrice = null, EnableMargin = false, }); + ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30); await LogDeclision(DeclisionTradeAction.CloseLong, message, profit); await LogDeclision(DeclisionTradeAction.CloseLongReal, message, profit); } @@ -253,8 +257,10 @@ namespace KLHZ.Trader.Core.Exchange.Services profit = TradingCalculator.CaclProfit(asset.BoughtPrice, message.Value, GetComission(assetType), GetLeverage(message.Figi, asset.Count < 0), asset.Count < 0); } - if (profit > 0) + var stoppingKey = message.Figi + asset.AccountId; + if (profit > 0 && !ClosingStops.ContainsKey(stoppingKey)) { + ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30); await _dataBus.Broadcast(new TradeCommand() { AccountId = asset.AccountId, @@ -287,7 +293,7 @@ namespace KLHZ.Trader.Core.Exchange.Services } } - private void ProcessOpeningStops(INewPrice message, DateTime currentTime) + private void ProcessStops(INewPrice message, DateTime currentTime) { if (OpeningStops.TryGetValue(message.Figi, out var dt)) { @@ -296,6 +302,13 @@ namespace KLHZ.Trader.Core.Exchange.Services OpeningStops.TryRemove(message.Figi, out _); } } + if (ClosingStops.TryGetValue(message.Figi, out var dt2)) + { + if (dt2 < currentTime) + { + ClosingStops.TryRemove(message.Figi, out _); + } + } } private async Task LogPrice(INewPrice message, string processor, decimal value)