internal async void UpdateTrades(IEnumerable <ITrade> tradesUpdate) { await tradesSemaphoreSlim.WaitAsync(symbolCancellationTokenSource.Token); try { if (Trades == null) { var result = await tradeHelper.CreateLocalTradeList <Trade>(Symbol, tradesUpdate, TradesDisplayCount, TradesChartDisplayCount, TradeLimit); Trades = result.Trades; TradesChart = result.TradesChart; if (IsLoadingTrades) { IsLoadingTrades = false; } } else { List <Trade> newTrades; tradeHelper.UpdateTrades(Symbol, tradesUpdate, Trades, TradesDisplayCount, TradesChartDisplayCount, out newTrades, ref tradesChart); Trades = newTrades; } } finally { tradesSemaphoreSlim.Release(); } }
public override async Task TradeNotificationsAsync(List <StrategyNotification> tradeNotifications) { await tradesSemaphoreSlim.WaitAsync(cancellationTokenSource.Token); try { if (cancellationTokenSource.IsCancellationRequested) { return; } if (Symbols != null) { IsLoadingTrades = false; List <MovingAverageTrade> tradesUpdate = null; foreach (var notification in tradeNotifications) { if (tradesUpdate == null) { tradesUpdate = JsonConvert.DeserializeObject <List <MovingAverageTrade> >(notification.Message); continue; } var updateTrades = JsonConvert.DeserializeObject <List <MovingAverageTrade> >(notification.Message); var newTrades = updateTrades.Except(tradesUpdate).ToList(); tradesUpdate.AddRange(newTrades.OrderBy(t => t.Time)); } var trade = tradesUpdate.First(); var symbol = Symbols.First(s => s.ExchangeSymbol.Equals(trade.Symbol)); var pricePrecision = symbol.PricePrecision; var quantityPrecision = symbol.QuantityPrecision; Func <ITrade, int, int, Trade> createSmaTrade = (t, p, q) => new Trade { Price = ((MovingAverageTrade)t).MovingAveragePrice.Trim(p), Time = t.Time.ToLocalTime(), Exchange = t.Exchange }; Func <ITrade, int, int, Trade> createBuyIndicator = (t, p, q) => new Trade { Price = ((MovingAverageTrade)t).BuyPrice.Trim(p), Time = t.Time.ToLocalTime(), Exchange = t.Exchange }; Func <ITrade, int, int, Trade> createSellIndicator = (t, p, q) => new Trade { Price = ((MovingAverageTrade)t).SellPrice.Trim(p), Time = t.Time.ToLocalTime(), Exchange = t.Exchange }; var tradesDisplayCount = Strategy.TradesDisplayCount; var tradesChartDisplayCount = Strategy.TradesChartDisplayCount; if (TradesChart == null) { var result = await tradeHelper.CreateLocalTradeList <Trade>(symbol, tradesUpdate, tradesDisplayCount, tradesChartDisplayCount, 0); Trades = result.Trades; TradesChart = result.TradesChart; SmaTradesChart = tradeHelper.CreateLocalChartTrades(tradesUpdate, createSmaTrade, tradesChartDisplayCount, pricePrecision, quantityPrecision); BuyIndicatorChart = tradeHelper.CreateLocalChartTrades(tradesUpdate, createBuyIndicator, tradesChartDisplayCount, pricePrecision, quantityPrecision); SellIndicatorChart = tradeHelper.CreateLocalChartTrades(tradesUpdate, createSellIndicator, tradesChartDisplayCount, pricePrecision, quantityPrecision); } else { List <Trade> newTrades; // Get the latest available trade - the first trade on the // trade list (which is also the last trade in the chart). var seed = Trades.First(); var seedTime = seed.Time; var seedId = seed.Id; tradeHelper.UpdateTrades(symbol, tradesUpdate, Trades, tradesDisplayCount, tradesChartDisplayCount, out newTrades, ref tradesChart); Trades = newTrades; tradeHelper.UpdateLocalChartTrades(tradesUpdate, createSmaTrade, seedTime, seedId, tradesChartDisplayCount, pricePrecision, quantityPrecision, ref smaTradesChart); tradeHelper.UpdateLocalChartTrades(tradesUpdate, createBuyIndicator, seedTime, seedId, tradesChartDisplayCount, pricePrecision, quantityPrecision, ref buyIndicatorChart); tradeHelper.UpdateLocalChartTrades(tradesUpdate, createSellIndicator, seedTime, seedId, tradesChartDisplayCount, pricePrecision, quantityPrecision, ref sellIndicatorChart); } } } catch (Exception ex) { OnException($"{Strategy.Name} : TradeNotificationsAsync - {ex.Message}", ex); } finally { tradesSemaphoreSlim.Release(); } }