private void DataComing(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) { var DataComing = (IPair)e.NewItems[0]; var IsFinal = DataComing.Properties.Select(y => y.Key == "Final").First(); switch (this.Mode) { case CandleCollectionMode.Consolidated: if (DataComing.Last) { this.Open.Add(DataComing.Candle.Open.ChangeType <double>()); this.High.Add(DataComing.Candle.High.ChangeType <double>()); this.Low.Add(DataComing.Candle.Low.ChangeType <double>()); this.Close.Add(DataComing.Candle.Close.ChangeType <double>()); this.Volume.Add(DataComing.Candle.Volume.ChangeType <double>()); this.Pivot.Add(DataComing.Candle.Dpivot().ChangeType <double>()); this.Index = this.Open.Count(); this.Candles.Add(DataComing); CandleUpdate?.Invoke(this, new CandleEventArg(CandleEventType.NewCandle, DataComing, this)); this.IndexedCandle = new IndexedCandle(this.Candles.Select(y => y.Candle), this.Index - 1); GenerateLow(); GenerateHigh(); GeneratePattern(); } //if final candle break; case CandleCollectionMode.AllTicks: this.Open.Add(DataComing.Candle.Open.ChangeType <double>()); this.High.Add(DataComing.Candle.High.ChangeType <double>()); this.Low.Add(DataComing.Candle.Low.ChangeType <double>()); this.Close.Add(DataComing.Candle.Close.ChangeType <double>()); this.Volume.Add(DataComing.Candle.Volume.ChangeType <double>()); this.Pivot.Add(DataComing.Candle.Dpivot().ChangeType <double>()); this.Index = this.Open.Count(); this.Candles.Add(DataComing); CandleUpdate?.Invoke(this, new CandleEventArg(CandleEventType.NewCandle, DataComing, this)); break; } } }
private void ProcessCandleAsync(CandleUpdate candle, MarketType market) { var topic = $"candle.{market.ToString().ToLower()}.{candle.AssetPairId.ToLower()}.{candle.PriceType.ToString().ToLower()}.{candle.TimeInterval.ToString().ToLower()}"; var subject = _realm.Services.GetSubject <CandleClientMessage>(topic); subject.OnNext(new CandleClientMessage { AssetPairId = candle.AssetPairId, MarketType = market, PriceType = candle.PriceType, TimeInterval = candle.TimeInterval, Timestamp = candle.CandleTimestamp, Open = candle.Open, Close = candle.Close, High = candle.High, Low = candle.Low, TradingVolume = candle.TradingVolume, OppositeTradingVolume = candle.TradingOppositeVolume }); }
/// <summary>Parse a market data update message</summary> private void ApplyUpdate(CandleUpdate update) // Worker thread context { lock (CandleData) { // Push the update to the buffer m_pending.Add(update); // If the data hasn't had the initial snapshot applied yet, we're done if (CandleData.Count == 0) { return; } // Apply updates foreach (var upd in m_pending) { var idx = CandleData.BinarySearch(x => x.Time.CompareTo(upd.Kline.StartTime)); if (idx >= 0) { CandleData[idx] = upd.Kline; } else { CandleData.Insert(~idx, upd.Kline); } } // Cap the length of the candle data if (CandleData.Count > 1500) { CandleData.RemoveRange(0, 500); } // All pending updates have been applied m_pending.Clear(); } }
private string GetKey(CandleUpdate candle) { return($"{candle.AssetPairId}_{candle.PriceType}"); }
/// <summary> /// Process the incoming messages /// </summary> /// <param name="message">Incoming message</param> private void processMessage(string message) { // Deserialize the incoming command to check wich message has just arrived // The action property brings the command name switch (Command.Deserialize(message).action) { case KeepAlive.CLASSNAME: { // If it is a KeepAlive message, just answer Quantsis Conneciton Box another KeepAlive message //CheckAsyncTaskInProgress this.send(new KeepAlive().Serialize()); break; } case NewOrderResponse.CLASSNAME: { // If it is an NewOrderResponse message and it contains error, show the error message var cmd = NewOrderResponse.Deserialize(message); if (!cmd.success) { NotifyOMS(cmd.ToString()); } break; } case NewStopOrderResponse.CLASSNAME: { // If it is an NewStopOrderResponse message and it contains error, show the error message var cmd = NewStopOrderResponse.Deserialize(message); if (!cmd.success) { NotifyOMS(cmd.ToString()); } break; } case NewStopGainLossOrderResponse.CLASSNAME: { // If it is an NewStopGainLossOrderResponse message and it contains error, show the error message var cmd = NewStopGainLossOrderResponse.Deserialize(message); if (!cmd.success) { NotifyOMS(cmd.ToString()); } break; } case CancelOrderResponse.CLASSNAME: { // If it is an CancelOrderResponse message and it contains error, show the error message var cmd = CancelOrderResponse.Deserialize(message); if (!cmd.success) { NotifyOMS(cmd.ToString()); } break; } case ExecutionReport.CLASSNAME: { // If it is an ExecutionReport message, check if it was successful and updates the order list or show error message var cmd = ExecutionReport.Deserialize(message); if (cmd.success) { NotifyOMS(cmd.ToString()); } else { NotifyOMS(cmd.ToString()); } break; } case OrderListResponse.CLASSNAME: { // If it is an OrderListResponse, check if it was successful. In negative case show error message. var cmd = OrderListResponse.Deserialize(message); if (!cmd.success) { NotifyOMS(cmd.ToString()); } break; } case PositionResponse.CLASSNAME: { // If it is a Position Response, check if it was successful and updates the position list. In case of failure, show error messasge var cmd = PositionResponse.Deserialize(message); if (cmd.success) { NotifyOMS(cmd.ToString()); } else { NotifyOMS(cmd.ToString()); } break; } case QuoteResponse.CLASSNAME: { // If it is a Quote Response, check if it was successful and logs the message var cmd = QuoteResponse.Deserialize(message); if (cmd.success) { OnQuoteResponse(cmd); } else { NotifyQCB(cmd.ToString()); } break; } case QuoteUpdate.CLASSNAME: { // If it is a Quote Update, check if it was successful and logs the message var cmd = QuoteUpdate.Deserialize(message); if (cmd.success) { OnQuoteUpdate(cmd); } else { NotifyQCB(cmd.ToString()); } break; } case QuoteUnsubscribeResponse.CLASSNAME: { // If it is a Quote Unsubscribe Response, check if it was successful var cmd = QuoteUnsubscribeResponse.Deserialize(message); if (cmd.success) { NotifyOMS(cmd.ToString()); } else { NotifyOMS(cmd.ToString()); } break; } case CandleResponse.CLASSNAME: { // If it is a Quote Update, check if it was successful and logs the message var cmd = CandleResponse.Deserialize(message); if (cmd.success) { if (cmd.candles != null) { if (cmd.candles.Count <= 0) { NotifyOMS("Nenhum foi possivel retornar nenhum candle para " + cmd.security + " - Timeframe: " + cmd.timeframe); } else { NotifyOMS("Dados Historicos Intraday para: " + cmd.security + " - Qtd de Candles: " + cmd.candles.Count + " - Timeframe: " + cmd.timeframe); //foreach (Candle candle in cmd.candles) // this.mainForm.log(candle.ToString()); } } } else { NotifyOMS(cmd.ToString()); } break; } // Candle Update case CandleUpdate.CLASSNAME: { // If it is a Candle Update, check if it was successful and logs the message var cmd = CandleUpdate.Deserialize(message); if (cmd.success) { if (cmd.candle != null) { switch (cmd.timeframe) { case CandleUpdate.TIMEFRAME_INTRADAY_1_MIN: NotifyOMS("Candle Intraday Update: " + cmd.security + " - Last: " + cmd.candle.close + " - Time: " + cmd.candle.date); break; case CandleUpdate.TIMEFRAME_DAILY: NotifyOMS("Candle Daily Update: " + cmd.security + " - Last: " + cmd.candle.close + " - Time: " + cmd.candle.date); break; } } } //this.mainForm.updatePositions(cmd); else { NotifyOMS(cmd.ToString()); } break; } // QCB has disconnected (shut down) case Disconnect.CLASSNAME: this.disconnect(); break; } }