protected override CandleMessage Process(MessageBuffer <CandleMessage> buffer) { var res = new TimeFrameCandleMessage { SecurityId = SecurityId, OpenTime = buffer.Time, LocalTime = buffer.Time, TotalVolume = Calculate(buffer, false, c => c.TotalVolume), OpenPrice = Calculate(buffer, true, m => m.OpenPrice), HighPrice = Calculate(buffer, true, m => m.HighPrice), LowPrice = Calculate(buffer, true, m => m.LowPrice), ClosePrice = Calculate(buffer, true, m => m.ClosePrice), State = CandleStates.Finished }; //res.Arg = IndexCandleBuilder.CloneArg(candle.Arg, Security); if (Security.CalculateExtended) { //res.TotalPrice = Calculate(buffer, c => c.TotalPrice); res.OpenVolume = Calculate(buffer, false, c => c.OpenVolume ?? 0); res.CloseVolume = Calculate(buffer, false, c => c.CloseVolume ?? 0); res.HighVolume = Calculate(buffer, false, c => c.HighVolume ?? 0); res.LowVolume = Calculate(buffer, false, c => c.LowVolume ?? 0); } return(res); }
public void ProcessMessage(TimeFrameCandleMessage message) { if(message.SecurityId.ToStringId() != _security.Id || (TimeSpan)message.Arg != _timeframe) return; var candle = _candles.LastOrDefault(); if(candle == null) _candles.Add(candle = NewCandleFromMessage(message)); else if (candle.OpenTime > message.OpenTime) throw new InvalidOperationException("received unordered candle"); else { if (!CheckSameCandle(candle, message)) { if (candle.State != CandleStates.Finished) { candle.State = CandleStates.Finished; Candle?.Invoke(candle); } _candles.Add(candle = NewCandleFromMessage(message)); } } candle.CloseTime = message.CloseTime; candle.OpenPrice = message.OpenPrice; candle.HighPrice = message.HighPrice; candle.LowPrice = message.LowPrice; candle.ClosePrice = message.ClosePrice; candle.TotalVolume = message.TotalVolume; Candle?.Invoke(candle); }
TimeFrameCandle GetCandle(TimeFrameCandleMessage msg) { var key = Tuple.Create(msg.SecurityId, msg.Arg); var candle = _lastCandles.TryGetValue(key); if (candle == null) { candle = NewCandleFromMessage(msg); } else if (candle.OpenTime != msg.OpenTime) { candle.State = CandleStates.Finished; Candle?.Invoke(candle); candle = NewCandleFromMessage(msg); } _lastCandles[key] = candle; candle.OpenPrice = msg.OpenPrice; candle.HighPrice = msg.HighPrice; candle.LowPrice = msg.LowPrice; candle.ClosePrice = msg.ClosePrice; candle.TotalVolume = msg.TotalVolume; candle.State = msg.State; return candle; }
private void OnSessionHistoricMarketDataReceived(string instructionId, List <Uri> uris) { var transactionId = TryParseTransactionId(instructionId); if (transactionId == null) { return; } foreach (var uri in uris) { _session.OpenUri(uri, (u, reader) => { using (var stream = new StreamReader(new GZipStream(reader.BaseStream, CompressionMode.Decompress), Encoding.UTF8)) { var rows = stream.ReadToEnd().Split("\n"); var index = 0; CultureInfo.InvariantCulture.DoInCulture(() => rows .Skip(1) .Select(row => row.Split(',')) .Where(cells => !cells[1].IsEmpty()) .ForEach(cells => { var message = new TimeFrameCandleMessage { OriginalTransactionId = transactionId.Value, OpenTime = TimeHelper.GregorianStart.AddMilliseconds(cells[0].To <long>()).ApplyTimeZone(TimeZoneInfo.Utc), IsFinished = index++ == (rows.Length - 2), State = CandleStates.Finished, }; if (cells.Length == 5) { message.OpenPrice = cells[1].To <decimal>(); message.OpenVolume = !cells[2].IsEmpty() ? cells[2].To <decimal>() : (decimal?)null; message.ClosePrice = cells[3].To <decimal>(); message.CloseVolume = !cells[4].IsEmpty() ? cells[4].To <decimal>() : (decimal?)null; } else { message.OpenPrice = cells[1].To <decimal>(); message.HighPrice = cells[2].To <decimal>(); message.LowPrice = cells[3].To <decimal>(); message.ClosePrice = cells[4].To <decimal>(); message.TotalVolume = cells[5].To <decimal>() + cells[6].To <decimal>() + cells[7].To <decimal>(); } SendOutMessage(message); })); } }, CreateErrorHandler("OpenUri")); System.Threading.Thread.Sleep(3000); } }
private TimeFrameCandle NewCandleFromMessage(TimeFrameCandleMessage msg) { return new TimeFrameCandle { Security = _security, OpenTime = msg.OpenTime, CloseTime = msg.OpenTime + _timeframe, TimeFrame = _timeframe, State = CandleStates.Active }; }
/// <summary> /// To process the new data. /// </summary> /// <param name="message">The message contains information about the time-frame candle.</param> /// <returns>A new candles changes.</returns> public IEnumerable <CandleMessage> Process(CandleMessage message) { TimeFrameCandleMessage lastCandle = null; foreach (var candle in _processParts.SelectMany(p => ProcessCandlePart(p, message)).ToArray().Cast <TimeFrameCandleMessage>()) { if (candle != lastCandle) { lastCandle = candle; yield return(candle); } } }
/// <inheritdoc /> public override IEnumerable <Message> Process(Message message) { switch (message.Type) { case MessageTypes.QuoteChange: var quotesMsg = (QuoteChangeMessage)message; foreach (var msg in ProcessMessage(Holder <QuoteChangeMessage> .Messages, quotesMsg.SecurityId, quotesMsg, quotes => new QuoteChangeMessage { SecurityId = SecurityId, ServerTime = quotesMsg.ServerTime, })) { yield return(msg); } break; case MessageTypes.Execution: var execMsg = (ExecutionMessage)message; switch (execMsg.ExecutionType) { case ExecutionTypes.OrderLog: { foreach (var msg in ProcessMessage(_ol, execMsg.SecurityId, execMsg, execMsgs => { var prices = new decimal[execMsgs.Length]; var volumes = new decimal[execMsgs.Length]; for (var i = 0; i < execMsgs.Length; i++) { var msg = execMsgs[i]; prices[i] = msg.OrderPrice; volumes[i] = msg.OrderVolume ?? 0; } return(new ExecutionMessage { SecurityId = SecurityId, ServerTime = execMsg.ServerTime, ExecutionType = execMsg.ExecutionType, OrderPrice = Calculate(prices, true), OrderVolume = Calculate(volumes, false), }); })) { yield return(msg); } break; } case ExecutionTypes.Tick: { foreach (var msg in ProcessMessage(_ticks, execMsg.SecurityId, execMsg, execMsgs => { var prices = new decimal[execMsgs.Length]; var volumes = new decimal[execMsgs.Length]; for (var i = 0; i < execMsgs.Length; i++) { var msg = execMsgs[i]; prices[i] = msg.TradePrice ?? 0; volumes[i] = msg.TradeVolume ?? 0; } return(new ExecutionMessage { SecurityId = SecurityId, ServerTime = execMsg.ServerTime, ExecutionType = execMsg.ExecutionType, TradePrice = Calculate(prices, true), TradeVolume = Calculate(volumes, false), }); })) { yield return(msg); } break; } } break; case MessageTypes.CandleTimeFrame: { var candleMsg = (CandleMessage)message; var dict = _candles.SafeAdd(candleMsg.OpenTime); dict[candleMsg.SecurityId] = (CandleMessage)candleMsg.Clone(); if (dict.Count == BasketLegs.Length) { var keys = _candles.Keys.Where(t => t <= candleMsg.OpenTime).ToArray(); foreach (var key in keys) { var d = _candles.GetAndRemove(key); if (d.Count < BasketLegs.Length && BasketSecurity.FillGapsByZeros) { continue; } var indexCandle = new TimeFrameCandleMessage(); FillIndexCandle(indexCandle, candleMsg, d.Values.ToArray()); yield return(indexCandle); } } break; } case MessageTypes.CandlePnF: { var candleMsg = (PnFCandleMessage)message; foreach (var msg in ProcessMessage(Holder <PnFCandleMessage> .Messages, candleMsg.SecurityId, candleMsg, candles => CreateBasketCandle(candles, candleMsg))) { yield return(msg); } break; } case MessageTypes.CandleRange: { var candleMsg = (RangeCandleMessage)message; foreach (var msg in ProcessMessage(Holder <RangeCandleMessage> .Messages, candleMsg.SecurityId, candleMsg, candles => CreateBasketCandle(candles, candleMsg))) { yield return(msg); } break; } case MessageTypes.CandleRenko: { var candleMsg = (RenkoCandleMessage)message; foreach (var msg in ProcessMessage(Holder <RenkoCandleMessage> .Messages, candleMsg.SecurityId, candleMsg, candles => CreateBasketCandle(candles, candleMsg))) { yield return(msg); } break; } case MessageTypes.CandleTick: { var candleMsg = (TickCandleMessage)message; foreach (var msg in ProcessMessage(Holder <TickCandleMessage> .Messages, candleMsg.SecurityId, candleMsg, candles => CreateBasketCandle(candles, candleMsg))) { yield return(msg); } break; } case MessageTypes.CandleVolume: { var candleMsg = (VolumeCandleMessage)message; foreach (var msg in ProcessMessage(Holder <VolumeCandleMessage> .Messages, candleMsg.SecurityId, candleMsg, candles => CreateBasketCandle(candles, candleMsg))) { yield return(msg); } break; } } //return Enumerable.Empty<Message>(); }
private void OnSessionHistoricMarketDataReceived(string instructionId, List<Uri> uris) { var transactionId = TryParseTransactionId(instructionId); if (transactionId == null) return; foreach (var uri in uris) { _session.OpenUri(uri, (u, reader) => { using (var stream = new StreamReader(new GZipStream(reader.BaseStream, CompressionMode.Decompress), Encoding.UTF8)) { var rows = stream.ReadToEnd().Split("\n"); var index = 0; CultureInfo.InvariantCulture.DoInCulture(() => rows .Skip(1) .Select(row => row.Split(',')) .Where(cells => !cells[1].IsEmpty()) .ForEach(cells => { var message = new TimeFrameCandleMessage { OriginalTransactionId = transactionId.Value, OpenTime = TimeHelper.GregorianStart.AddMilliseconds(cells[0].To<long>()).ApplyTimeZone(TimeZoneInfo.Utc), IsFinished = index++ == (rows.Length - 2), State = CandleStates.Finished, }; if (cells.Length == 5) { message.OpenPrice = cells[1].To<decimal>(); message.OpenVolume = !cells[2].IsEmpty() ? cells[2].To<decimal>() : (decimal?)null; message.ClosePrice = cells[3].To<decimal>(); message.CloseVolume = !cells[4].IsEmpty() ? cells[4].To<decimal>() : (decimal?)null; } else { message.OpenPrice = cells[1].To<decimal>(); message.HighPrice = cells[2].To<decimal>(); message.LowPrice = cells[3].To<decimal>(); message.ClosePrice = cells[4].To<decimal>(); message.TotalVolume = cells[5].To<decimal>() + cells[6].To<decimal>() + cells[7].To<decimal>(); } SendOutMessage(message); })); } }, CreateErrorHandler("OpenUri")); System.Threading.Thread.Sleep(3000); } }
private bool CheckSameCandle(TimeFrameCandle candle, TimeFrameCandleMessage msg) { return candle.Arg == msg.Arg && candle.OpenTime == msg.OpenTime; }
TimeFrameCandle NewCandleFromMessage(TimeFrameCandleMessage msg) { return new TimeFrameCandle { Security = GetSecurity(msg.SecurityId), OpenTime = msg.OpenTime, CloseTime = msg.CloseTime, OpenPrice = msg.OpenPrice, HighPrice = msg.HighPrice, LowPrice = msg.LowPrice, ClosePrice = msg.ClosePrice, TotalVolume = msg.TotalVolume, State = msg.State, }; }