Ejemplo n.º 1
0
        /// <inheritdoc />
        protected override HeikinAshiCandleMessage CreateCandle(MarketDataMessage message, HeikinAshiCandleMessage currentCandle, ICandleBuilderValueTransform transform)
        {
            var timeFrame = message.GetTimeFrame();

            var board  = ExchangeInfoProvider.GetOrCreateBoard(message.SecurityId.BoardCode);
            var bounds = timeFrame.GetCandleBounds(transform.Time, board, board.WorkingTime);

            if (transform.Time < bounds.Min)
            {
                return(null);
            }

            var openTime = bounds.Min;

            var candle = FirstInitCandle(message, new HeikinAshiCandleMessage
            {
                TimeFrame = timeFrame,
                OpenTime  = openTime,
                HighTime  = openTime,
                LowTime   = openTime,
                CloseTime = openTime,
            }, transform);

            if (currentCandle != null)
            {
                candle.OpenPrice = (currentCandle.OpenPrice + currentCandle.ClosePrice) / 2M;
            }

            return(candle);
        }
Ejemplo n.º 2
0
        private DateTimeOffset?LoadMessages(MarketDataMessage msg, DateTimeOffset?from, DateTimeOffset?to, long transactionId, Action <Message> newOutMessage)
        {
            void SendReply() => newOutMessage(new SubscriptionResponseMessage {
                OriginalTransactionId = transactionId
            });

            void SendOut(Message message)
            {
                message.OfflineMode = MessageOfflineModes.Ignore;
                newOutMessage(message);
            }

            DateTimeOffset?lastTime = null;

            var secId = msg.SecurityId;

            switch (msg.DataType)
            {
            case MarketDataTypes.Level1:
                if (msg.BuildMode != MarketDataBuildModes.Build)
                {
                    if (Settings.IsMode(StorageModes.Incremental))
                    {
                        lastTime = LoadMessages(Settings.GetStorage <Level1ChangeMessage>(secId, null), from, to, TimeSpan.Zero, transactionId, SendReply, SendOut);
                    }
                }
                else
                {
                    if (msg.BuildFrom == MarketDataTypes.OrderLog)
                    {
                        var storage = Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.OrderLog);

                        var range = GetRange(storage, from, to, TimeSpan.Zero);

                        if (range != null)
                        {
                            lastTime = LoadMessages(storage
                                                    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                    .ToLevel1(msg.DepthBuilder, msg.RefreshSpeed ?? default, msg.MaxDepth ?? int.MaxValue), range.Item1, transactionId, SendReply, SendOut);
                        }
                    }
                    else if (msg.BuildFrom == MarketDataTypes.MarketDepth)
                    {
                        var storage = Settings.GetStorage <QuoteChangeMessage>(secId, null);

                        var range = GetRange(storage, from, to, TimeSpan.Zero);

                        if (range != null)
                        {
                            lastTime = LoadMessages(storage
                                                    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                    .ToLevel1(), range.Item1, transactionId, SendReply, SendOut);
                        }
                    }
                }

                break;

            case MarketDataTypes.MarketDepth:
                if (msg.BuildMode != MarketDataBuildModes.Build)
                {
                    if (Settings.IsMode(StorageModes.Incremental))
                    {
                        lastTime = LoadMessages(Settings.GetStorage <QuoteChangeMessage>(secId, null), from, to, TimeSpan.Zero, transactionId, SendReply, SendOut);
                    }
                }
                else
                {
                    if (msg.BuildFrom == MarketDataTypes.OrderLog)
                    {
                        var storage = Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.OrderLog);

                        var range = GetRange(storage, from, to, TimeSpan.Zero);

                        if (range != null)
                        {
                            lastTime = LoadMessages(storage
                                                    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                    .ToOrderBooks(msg.DepthBuilder, msg.RefreshSpeed ?? default, msg.MaxDepth ?? int.MaxValue), range.Item1, transactionId, SendReply, SendOut);
                        }
                    }
                    else if (msg.BuildFrom == MarketDataTypes.Level1)
                    {
                        var storage = Settings.GetStorage <Level1ChangeMessage>(secId, null);

                        var range = GetRange(storage, from, to, TimeSpan.Zero);

                        if (range != null)
                        {
                            lastTime = LoadMessages(storage
                                                    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                    .ToOrderBooks(), range.Item1, transactionId, SendReply, SendOut);
                        }
                    }
                }

                break;

            case MarketDataTypes.Trades:
                if (msg.BuildMode != MarketDataBuildModes.Build)
                {
                    lastTime = LoadMessages(Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.Tick), from, to, Settings.DaysLoad, transactionId, SendReply, SendOut);
                }
                else
                {
                    if (msg.BuildFrom == MarketDataTypes.OrderLog)
                    {
                        var storage = Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.OrderLog);

                        var range = GetRange(storage, from, to, TimeSpan.Zero);

                        if (range != null)
                        {
                            lastTime = LoadMessages(storage
                                                    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                    .ToTicks(), range.Item1, transactionId, SendReply, SendOut);
                        }
                    }
                    else if (msg.BuildFrom == MarketDataTypes.Level1)
                    {
                        var storage = Settings.GetStorage <Level1ChangeMessage>(secId, null);

                        var range = GetRange(storage, from, to, TimeSpan.Zero);

                        if (range != null)
                        {
                            lastTime = LoadMessages(storage
                                                    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                    .ToTicks(), range.Item1, transactionId, SendReply, SendOut);
                        }
                    }
                }

                break;

            case MarketDataTypes.OrderLog:
                lastTime = LoadMessages(Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.OrderLog), from, to, Settings.DaysLoad, transactionId, SendReply, SendOut);
                break;

            case MarketDataTypes.News:
                lastTime = LoadMessages(Settings.GetStorage <NewsMessage>(default, null), from, to, Settings.DaysLoad, transactionId, SendReply, SendOut);
                break;

            case MarketDataTypes.Board:
                lastTime = LoadMessages(Settings.GetStorage <BoardStateMessage>(default, null), from, to, Settings.DaysLoad, transactionId, SendReply, SendOut);
                break;

            case MarketDataTypes.CandleTimeFrame:
                var tf = msg.GetTimeFrame();

                if (msg.IsBuildOnly())
                {
                    IMarketDataStorage storage;

                    switch (msg.BuildFrom)
                    {
                    case null:
                    case MarketDataTypes.Trades:
                        storage = Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.Tick);
                        break;

                    case MarketDataTypes.OrderLog:
                        storage = Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.OrderLog);
                        break;

                    case MarketDataTypes.Level1:
                        storage = Settings.GetStorage <Level1ChangeMessage>(secId, null);
                        break;

                    case MarketDataTypes.MarketDepth:
                        storage = Settings.GetStorage <QuoteChangeMessage>(secId, null);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(msg), msg.BuildFrom, LocalizedStrings.Str1219);
                    }

                    var range = GetRange(storage, from, to, TimeSpan.FromDays(2));

                    if (range != null)
                    {
                        var mdMsg = msg.TypedClone();
                        mdMsg.From = mdMsg.To = null;

                        switch (msg.BuildFrom)
                        {
                        case null:
                        case MarketDataTypes.Trades:
                            lastTime = LoadMessages(((IMarketDataStorage <ExecutionMessage>)storage)
                                                    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                    .ToCandles(mdMsg, candleBuilderProvider: CandleBuilderProvider), range.Item1, transactionId, SendReply, SendOut);

                            break;

                        case MarketDataTypes.OrderLog:
                        {
                            switch (msg.BuildField)
                            {
                            case null:
                            case Level1Fields.LastTradePrice:
                                lastTime = LoadMessages(((IMarketDataStorage <ExecutionMessage>)storage)
                                                        .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                        .ToCandles(mdMsg, candleBuilderProvider: CandleBuilderProvider), range.Item1, transactionId, SendReply, SendOut);

                                break;

                                // TODO
                                //case Level1Fields.SpreadMiddle:
                                //	lastTime = LoadMessages(((IMarketDataStorage<ExecutionMessage>)storage)
                                //	    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                //		.ToOrderBooks(OrderLogBuilders.Plaza2.CreateBuilder(security.ToSecurityId()))
                                //	    .ToCandles(mdMsg, false, exchangeInfoProvider: exchangeInfoProvider), range.Item1, transactionId, SendReply, SendOut);
                                //	break;
                            }

                            break;
                        }

                        case MarketDataTypes.Level1:
                            switch (msg.BuildField)
                            {
                            case null:
                            case Level1Fields.LastTradePrice:
                                lastTime = LoadMessages(((IMarketDataStorage <Level1ChangeMessage>)storage)
                                                        .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                        .ToTicks()
                                                        .ToCandles(mdMsg, candleBuilderProvider: CandleBuilderProvider), range.Item1, transactionId, SendReply, SendOut);
                                break;

                            case Level1Fields.BestBidPrice:
                            case Level1Fields.BestAskPrice:
                            case Level1Fields.SpreadMiddle:
                                lastTime = LoadMessages(((IMarketDataStorage <Level1ChangeMessage>)storage)
                                                        .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                        .ToOrderBooks()
                                                        .ToCandles(mdMsg, msg.BuildField.Value, candleBuilderProvider: CandleBuilderProvider), range.Item1, transactionId, SendReply, SendOut);
                                break;
                            }

                            break;

                        case MarketDataTypes.MarketDepth:
                            lastTime = LoadMessages(((IMarketDataStorage <QuoteChangeMessage>)storage)
                                                    .Load(range.Item1.Date, range.Item2.Date.EndOfDay())
                                                    .ToCandles(mdMsg, msg.BuildField ?? Level1Fields.SpreadMiddle, candleBuilderProvider: CandleBuilderProvider), range.Item1, transactionId, SendReply, SendOut);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(msg), msg.BuildFrom, LocalizedStrings.Str1219);
                        }
                    }
                }
                else
                {
                    var days = Settings.DaysLoad;

                    //if (tf.Ticks > 1)
                    //{
                    //	if (tf.TotalMinutes < 15)
                    //		days = TimeSpan.FromTicks(tf.Ticks * 10000);
                    //	else if (tf.TotalHours < 2)
                    //		days = TimeSpan.FromTicks(tf.Ticks * 1000);
                    //	else if (tf.TotalDays < 2)
                    //		days = TimeSpan.FromTicks(tf.Ticks * 100);
                    //	else
                    //		days = TimeSpan.FromTicks(tf.Ticks * 50);
                    //}

                    lastTime = LoadMessages(GetTimeFrameCandleMessageStorage(secId, tf, msg.AllowBuildFromSmallerTimeFrame), from, to, days, transactionId, SendReply, SendOut);
                }

                break;

            default:
            {
                if (msg.DataType.IsCandleDataType())
                {
                    var storage = (IMarketDataStorage <CandleMessage>)Settings.GetStorage(secId, msg.DataType.ToCandleMessage(), msg.Arg);

                    var range = GetRange(storage, from, to, Settings.DaysLoad);

                    if (range != null)
                    {
                        var messages = storage.Load(range.Item1.Date, range.Item2.Date.EndOfDay());
                        lastTime = LoadMessages(messages, range.Item1, transactionId, SendReply, SendOut);
                    }
                }

                break;
                // throw new ArgumentOutOfRangeException(nameof(msg), msg.DataType, LocalizedStrings.Str721);
            }
            }

            return(lastTime);
        }