Ejemplo n.º 1
0
        /// <summary>
        ///     Получить исторические данные
        /// </summary>
        /// <param name="consumer">
        ///     Потребитель исторических данных
        /// </param>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="begin">
        ///     Начало диапазона
        /// </param>
        /// <param name="end">
        ///     Конец диапазона
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <param name="cancellationToken">
        ///     Токен отмены
        /// </param>
        /// <returns>
        ///     Исторические данные
        /// </returns>
        /// <remarks>
        ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
        ///     если он не в состоянии предоставить запрошенные данные.
        /// </remarks>
        /// <exception cref="NoHistoryDataException">
        ///     Бросается, если исторические данные за указанный период недоступны
        /// </exception>
        public async Task GetHistoryDataAsync(
            IHistoryDataConsumer consumer,
            Instrument instrument,
            DateTime begin,
            DateTime end,
            HistoryProviderSpan span,
            CancellationToken cancellationToken = new CancellationToken())
        {
            using (LogManager.Scope())
            {
                var instrumentData = await instrumentConverter.ResolveInstrumentAsync(this, instrument);

                if (instrumentData == null)
                {
                    consumer.Error($"Unable to resolve symbol for {instrument}");
                    return;
                }

                // Выгружаем список точек
                var points = await FetchHistoryDataAsync(instrumentData.Symbol, begin, end, span, cancellationToken);

                // Собираем результат
                var data = new HistoryData(instrument, begin, end, span);
                foreach (var p in points.OrderBy(_ => _.Point))
                {
                    data.Points.Add(p);
                }

                // Передаем результат потребителю
                consumer.Update(data, HistoryDataUpdateType.Batch);
            }
        }
Ejemplo n.º 2
0
        internal async Task <IList <HistoryDataPoint> > FetchHistoryDataBlock(
            IHistoryDataConsumer consumer,
            Contract contract,
            DateTime begin,
            DateTime end,
            HistoryProviderSpan span,
            CancellationToken cancellationToken = new CancellationToken())
        {
            // Формируем параметры запроса
            ApplyHistoryDataLimits(span, ref begin, ref end);

            // Ждем, чтобы не превысить лимиты по частоте запросов
            var request = new IBHistoricalDataRequest(
                this,
                consumer,
                contract: contract,
                begin: begin,
                end: end,
                span: span,
                whatToShow: "TRADES",
                useRth: 1,
                formatDate: 1
                );

            // Отправляем запрос
            var points = await request.ExecuteAsync(cancellationToken).ConfigureAwait(false);

            return(points);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Получить исторические данные
        /// </summary>
        /// <param name="consumer">
        ///     Потребитель исторических данных
        /// </param>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="begin">
        ///     Начало диапазона
        /// </param>
        /// <param name="end">
        ///     Конец диапазона
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <param name="cancellationToken">
        ///     Токен отмены
        /// </param>
        /// <returns>
        ///     Исторические данные
        /// </returns>
        /// <remarks>
        ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
        ///     если он не в состоянии предоставить запрошенные данные.
        /// </remarks>
        /// <exception cref="NoHistoryDataException">
        ///     Бросается, если исторические данные за указанный период недоступны
        /// </exception>
        public async Task GetHistoryDataAsync(
            IHistoryDataConsumer consumer,
            Instrument instrument,
            DateTime begin,
            DateTime end,
            HistoryProviderSpan span,
            CancellationToken cancellationToken = new CancellationToken())
        {
            var symbol = await adapter.ResolveSymbolAsync(instrument);

            if (symbol == null)
            {
                consumer.Error($"Unable to resolve symbol for {instrument}");
                return;
            }

            QLAdapter.Log.Debug().Print($"Candles request: {symbol}, span {span}, from {begin} to {end}");
            var dataRequestMessage = new QLHistoryDataRequest(symbol, span);
            var request            = new HistoryDataRequest(dataRequestMessage.id, instrument, begin, end, span);

            using (requestsLock.Lock())
            {
                requests[request.Id] = request;
            }

            // Поддержка отмены запроса
            cancellationToken.RegisterSafe(() => request.TrySetCanceled());

            adapter.SendMessage(dataRequestMessage);

            var data = await request.Task;

            QLAdapter.Log.Debug().Print("Push candles to consumer. ", LogFields.RequestId(request.Id));
            consumer.Update(data, HistoryDataUpdateType.Batch);
        }
Ejemplo n.º 4
0
        public void RequestHistoryData(string code, DateTime begin, DateTime end, HistoryProviderSpan span, string requestId)
        {
            var interval = span.ToTimeSpan();

            // Приводим begin и end к нормальному виду: переводим в правильную зону и округляем до периода
            begin = IQFeedParser.ToIQFeedTime(begin);
            begin = IQFeedParser.RoundDateTime(begin, interval);
            end   = IQFeedParser.ToIQFeedTime(end);
            end   = IQFeedParser.RoundDateTime(end, interval) + interval;

            string command;

            switch (span)
            {
            case HistoryProviderSpan.Minute:
                command = HistoryMessages.HIT(code, 60, begin, end, requestId);
                break;

            case HistoryProviderSpan.Minute5:
                command = HistoryMessages.HIT(code, 5 * 60, begin, end, requestId);
                break;

            case HistoryProviderSpan.Minute10:
                command = HistoryMessages.HIT(code, 10 * 60, begin, end, requestId);
                break;

            case HistoryProviderSpan.Minute15:
                command = HistoryMessages.HIT(code, 15 * 60, begin, end, requestId);
                break;

            case HistoryProviderSpan.Minute30:
                command = HistoryMessages.HIT(code, 30 * 60, begin, end, requestId);
                break;

            case HistoryProviderSpan.Hour:
                command = HistoryMessages.HIT(code, 3600, begin, end, requestId);
                break;

            case HistoryProviderSpan.Hour4:
                command = HistoryMessages.HIT(code, 4 * 3600, begin, end, requestId);
                break;

            case HistoryProviderSpan.Day:
                command = HistoryMessages.HDT(code, begin, end, requestId);
                break;

            case HistoryProviderSpan.Week:
                command = HistoryMessages.HWX(code, begin, end, requestId);
                break;

            case HistoryProviderSpan.Month:
                command = HistoryMessages.HMX(code, begin, end, requestId);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(span), span, null);
            }

            SendCommand(command);
        }
Ejemplo n.º 5
0
        // Result Format for HIX, HID, and HIT requests:
        //
        // +---------------+---------------------+
        // | Field         | Format              |
        // +---------------+---------------------+
        // | RequestID     | Text                |
        // | Timestamp     | CCYY-MM-DD HH:MM:SS |
        // | High          | decimal             |
        // | Low           | decimal             |
        // | Open          | decimal             |
        // | Close         | decimal             |
        // | Total Volume  | integer             |
        // | Period Volume | integer             |
        // +---------------+---------------------+
        //
        //
        // Result Format for HDX, HDT, HWX, and HMX requests:
        //
        // +---------------+---------------------+
        // | Field         | Format              |
        // +---------------+---------------------+
        // | RequestID     | Text                |
        // | Timestamp     | CCYY-MM-DD HH:MM:SS |
        // | High          | decimal             |
        // | Low           | decimal             |
        // | Open          | decimal             |
        // | Close         | decimal             |
        // | Period Volume | integer             |
        // | Open Interest | integer             |
        // +---------------+---------------------+

        public static void Parse(IQMessageArgs args, HistoryProviderSpan span, out HistoryMsg msg)
        {
            msg = new HistoryMsg();

            var isHitRequest = HistoryProviderSpan.Day > span;

            var fields = args.Message.Split(',');

            msg.Time  = IQFeedParser.ParseDateTime(fields[FIELD_TIME], "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
            msg.Time  = IQFeedParser.FromIQFeedTime(msg.Time) - span.ToTimeSpan(); // Переводим в нашу временную зону и сдвигаем все свечи на на величину периода, чтобы свечи были как везде
            msg.High  = IQFeedParser.ParseDecimal(fields[FIELD_HIGH]);
            msg.Low   = IQFeedParser.ParseDecimal(fields[FIELD_LOW]);
            msg.Open  = IQFeedParser.ParseDecimal(fields[FIELD_OPEN]);
            msg.Close = IQFeedParser.ParseDecimal(fields[FIELD_CLOSE]);
            if (isHitRequest)
            {
                msg.Volume       = IQFeedParser.ParseInt(fields[FIELD_VOLUME]);
                msg.OpenInterest = IQFeedParser.ParseInt(fields[FIELD_OPEN_INTEREST]);
            }
            else
            {
                msg.Volume       = IQFeedParser.ParseInt(fields[FIELD_VOLUME_HIT]);
                msg.OpenInterest = 0;
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        ///     Подписаться на исторические данные
        /// </summary>
        /// <param name="consumer">
        ///     Потребитель исторических данных
        /// </param>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="begin">
        ///     Начало диапазона
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <returns>
        ///     Подписка на исторические данные
        /// </returns>
        /// <remarks>
        ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
        ///     если он не в состоянии предоставить запрошенные данные.
        /// </remarks>
        public async Task <IHistoryDataSubscription> SubscribeToHistoryDataAsync(
            IHistoryDataConsumer consumer,
            Instrument instrument,
            DateTime begin,
            HistoryProviderSpan span)
        {
            var symbol = await adapter.ResolveSymbolAsync(instrument);

            if (symbol == null)
            {
                consumer.Error($"Unable to resolve symbol for {instrument}");
                return(new NullHistoryDataSubscription());
            }

            QLAdapter.Log.Debug().Print($"Candles subscription: {symbol}, span {span}, from {begin}");
            var subscriptionMessage = new QLHistoryDataSubscription(symbol, begin, span);
            var subscription        =
                new HistoryDataSubscription(subscriptionMessage.id, instrument, begin, span, adapter, consumer);

            using (requestsLock.Lock())
            {
                subscriptions[subscription.Id] = subscription;
            }

            adapter.SendMessage(subscriptionMessage);

            return(subscription);
        }
Ejemplo n.º 7
0
        internal async Task <IList <HistoryDataPoint> > FetchHistoryDataAsync(
            string instrumentSymbol,
            DateTime begin,
            DateTime end,
            HistoryProviderSpan span,
            CancellationToken cancellationToken)
        {
            // Создаем операцию для ожидания
            var operation = new HistoryRequest(span, begin, end);
            var requestId = HistorySocketWrapper.HistoryRequestIdPefix + Guid.NewGuid().ToString("N");

            using (historyRequestsLock.Lock())
            {
                historyRequests[requestId] = operation;
            }

            // Подписываемся на исторические данные
            historySocket.RequestHistoryData(instrumentSymbol, begin, end, span, requestId);

            // Разрешаем отмену операции
            cancellationToken.RegisterSafe(() => operation.TrySetCanceled());

            // Дожидаемся результатов
            var points = await operation.Task;

            return(points);
        }
Ejemplo n.º 8
0
        public IBHistoricalDataRequest(
            IBAdapter adapter,
            IHistoryDataConsumer consumer,
            Contract contract,
            DateTime begin,
            DateTime end,
            HistoryProviderSpan span,
            string whatToShow,
            int useRth,
            int formatDate)
        {
            this.adapter    = adapter;
            Consumer        = consumer;
            this.contract   = contract;
            this.begin      = begin;
            this.end        = end;
            this.span       = span;
            this.whatToShow = whatToShow;
            this.useRth     = useRth;
            this.formatDate = formatDate;

            TimeSpan?minDuration, maxDuration;

            IBHistoryDataLimits.GetHistoryDataLimits(span, out minDuration, out maxDuration);

            var durationTimespan = end - begin;

            switch (span)
            {
            case HistoryProviderSpan.Minute:
            case HistoryProviderSpan.Minute5:
            case HistoryProviderSpan.Minute10:
            case HistoryProviderSpan.Minute15:
            case HistoryProviderSpan.Minute30:
                if (durationTimespan >= maxDuration || durationTimespan > IBHistoryDataLimits.MaxBarsPerRequest)
                {
                    duration       = (int)Math.Ceiling(durationTimespan.TotalDays);
                    durationSuffix = " D";
                }
                else
                {
                    duration       = (int)Math.Ceiling(durationTimespan.TotalSeconds);
                    durationSuffix = " S";
                }
                break;

            case HistoryProviderSpan.Hour:
            case HistoryProviderSpan.Hour4:
            case HistoryProviderSpan.Day:
            case HistoryProviderSpan.Week:
            case HistoryProviderSpan.Month:
                duration       = (int)Math.Ceiling(durationTimespan.TotalDays);
                durationSuffix = " D";
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(span), span, null);
            }
        }
Ejemplo n.º 9
0
 /// <summary>
 ///     Получить исторические данные
 /// </summary>
 /// <param name="consumer">
 ///     Потребитель исторических данных
 /// </param>
 /// <param name="instrument">
 ///     Инструмент
 /// </param>
 /// <param name="begin">
 ///     Начало диапазона
 /// </param>
 /// <param name="end">
 ///     Конец диапазона
 /// </param>
 /// <param name="span">
 ///     Интервал свечей для исторических данных
 /// </param>
 /// <param name="cancellationToken">
 ///     Токен отмены
 /// </param>
 /// <returns>
 ///     Исторические данные
 /// </returns>
 /// <remarks>
 ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
 ///     если он не в состоянии предоставить запрошенные данные.
 /// </remarks>
 /// <exception cref="NoHistoryDataException">
 ///     Бросается, если исторические данные за указанный период недоступны
 /// </exception>
 public Task GetHistoryDataAsync(
     IHistoryDataConsumer consumer,
     Instrument instrument,
     DateTime begin,
     DateTime end,
     HistoryProviderSpan span,
     CancellationToken cancellationToken = new CancellationToken())
 => connector.Adapter.GetHistoryDataAsync(consumer, instrument, begin, end, span, cancellationToken);
Ejemplo n.º 10
0
 public QLHistoryDataSubscription(string code, DateTime since, HistoryProviderSpan span, SubscriptionAction action = SubscriptionAction.Subscribe)
 {
     instrument  = code;
     this.since  = new DateTime(since.Ticks, DateTimeKind.Local);
     this.span   = span;
     id          = Guid.NewGuid();
     this.Action = action;
 }
Ejemplo n.º 11
0
 public HistoryDataSubscription(Guid id, Instrument instrument, DateTime since, HistoryProviderSpan span, QLAdapter adapter, IHistoryDataConsumer consumer)
 {
     this.Id         = id;
     this.Instrument = instrument;
     this.Span       = span;
     this.Since      = since;
     this.adapter    = adapter;
     this.consumer   = consumer;
 }
Ejemplo n.º 12
0
        private static void ApplyHistoryDataLimits(HistoryProviderSpan span, ref DateTime begin, ref DateTime end)
        {
            // SEE https://www.interactivebrokers.com/en/software/api/apiguide/tables/historical_data_limitations.htm
            // В IB есть ограничения по историческим данным. Если их превысить, то данные не придут.
            // Применяем эти ограничения, чтобы не было ошибок

            TimeSpan?min, max;

            IBHistoryDataLimits.GetHistoryDataLimits(span, out min, out max);
            ClampHistoryDataDuration(ref begin, ref end, min, max);
        }
Ejemplo n.º 13
0
 /// <summary>
 ///     Конструктор
 /// </summary>
 /// <param name="instrument">
 ///     Инструмент
 /// </param>
 /// <param name="begin">
 ///     Начало диапазона
 /// </param>
 /// <param name="end">
 ///     Конец диапазона
 /// </param>
 /// <param name="span">
 ///     Интервал свечей для исторических данных
 /// </param>
 public HistoryData(
     [NotNull] Instrument instrument,
     DateTime begin,
     DateTime end,
     HistoryProviderSpan span)
 {
     Instrument = instrument;
     Begin      = begin;
     End        = end;
     Span       = span;
 }
Ejemplo n.º 14
0
        private static string GetBarSize(HistoryProviderSpan span)
        {
            string barSizeSetting;

            switch (span)
            {
            case HistoryProviderSpan.Minute:
                barSizeSetting = "1 min";
                break;

            case HistoryProviderSpan.Minute5:
                barSizeSetting = "5 mins";
                break;

            case HistoryProviderSpan.Minute10:
                barSizeSetting = "10 mins";
                break;

            case HistoryProviderSpan.Minute15:
                barSizeSetting = "15 mins";
                break;

            case HistoryProviderSpan.Minute30:
                barSizeSetting = "30 mins";
                break;

            case HistoryProviderSpan.Hour:
                barSizeSetting = "1 hour";
                break;

            case HistoryProviderSpan.Hour4:
                barSizeSetting = "4 hours";
                break;

            case HistoryProviderSpan.Day:
                barSizeSetting = "1 day";
                break;

            case HistoryProviderSpan.Week:
                barSizeSetting = "1 week";
                break;

            case HistoryProviderSpan.Month:
                barSizeSetting = "1 month";
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(span), span, null);
            }

            return(barSizeSetting);
        }
Ejemplo n.º 15
0
 public HistoryDataRequest(
     CQGCInstrumentHistoryProvider provider,
     IHistoryDataConsumer consumer,
     Instrument instrument,
     DateTime begin,
     DateTime end,
     HistoryProviderSpan span,
     TimeBarRequest message)
 {
     this.provider = provider;
     this.consumer = consumer;
     data          = new HistoryData(instrument, begin, end, span);
     this.message  = message;
 }
Ejemplo n.º 16
0
        public IBHistoryDataSubscription(
            IBAdapter adapter,
            IHistoryDataConsumer consumer,
            Instrument instrument,
            Contract contract,
            HistoryProviderSpan span
            )
        {
            this.adapter  = adapter;
            this.consumer = consumer;
            this.contract = contract;
            this.span     = span;

            historyData = new HistoryData(instrument, DateTime.Today, DateTime.Today, span);
        }
Ejemplo n.º 17
0
        public HistorySubscription(
            IQFeedGateway gateway,
            IHistoryDataConsumer consumer,
            Instrument instrument,
            string instrumentSymbol,
            HistoryProviderSpan span)
        {
            this.gateway          = gateway;
            this.consumer         = consumer;
            this.instrumentSymbol = instrumentSymbol;
            this.span             = span;

            data = new HistoryData(instrument, DateTime.Today, DateTime.Today, span);

            cts   = new CancellationTokenSource();
            token = cts.Token;
        }
Ejemplo n.º 18
0
        /// <summary>
        ///     Получить исторические данные
        /// </summary>
        /// <param name="consumer">
        ///     Потребитель исторических данных
        /// </param>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="begin">
        ///     Начало диапазона
        /// </param>
        /// <param name="end">
        ///     Конец диапазона
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <param name="cancellationToken">
        ///     Токен отмены
        /// </param>
        /// <returns>
        ///     Исторические данные
        /// </returns>
        /// <remarks>
        ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
        ///     если он не в состоянии предоставить запрошенные данные.
        /// </remarks>
        /// <exception cref="NoHistoryDataException">
        ///     Бросается, если исторические данные за указанный период недоступны
        /// </exception>
        public async Task GetHistoryDataAsync(
            IHistoryDataConsumer consumer,
            Instrument instrument,
            DateTime begin,
            DateTime end,
            HistoryProviderSpan span,
            CancellationToken cancellationToken = new CancellationToken())
        {
            using (LogManager.Scope())
            {
                // Получаем контракт по инструменту
                var contract = await connector.ContractContainer.GetContractAsync(instrument, cancellationToken : cancellationToken);

                if (contract == null)
                {
                    throw new InvalidOperationException($"Can't find instrument \"{instrument}\"");
                }

                // Загружаем блок исторических данных
                var points = await FetchHistoryDataBlock(consumer, contract, begin, end, span, cancellationToken);

                // Собираем объект HistoryData
                var minDate = DateTime.MaxValue;
                var maxDate = DateTime.MinValue;
                var data    = new HistoryData(instrument, begin, end, span);
                foreach (var point in points.OrderBy(_ => _.Point))
                {
                    data.Points.Add(point);

                    if (minDate > point.Point)
                    {
                        minDate = point.Point;
                    }

                    if (maxDate < point.Point)
                    {
                        maxDate = point.Point;
                    }
                }

                data.Begin = minDate;
                data.End   = maxDate;

                consumer.Update(data, HistoryDataUpdateType.Batch);
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        ///     Подписаться на исторические данные
        /// </summary>
        /// <param name="consumer">
        ///     Потребитель исторических данных
        /// </param>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="begin">
        ///     Начало диапазона
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <returns>
        ///     Подписка на исторические данные
        /// </returns>
        /// <remarks>
        ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
        ///     если он не в состоянии предоставить запрошенные данные.
        /// </remarks>
        public async Task <IHistoryDataSubscription> SubscribeToHistoryDataAsync(
            IHistoryDataConsumer consumer,
            Instrument instrument,
            DateTime begin,
            HistoryProviderSpan span)
        {
            var instrumentData = await instrumentConverter.ResolveInstrumentAsync(this, instrument);

            if (instrumentData == null)
            {
                consumer.Error($"Unable to resolve symbol for {instrument}");
                return(new NullHistoryDataSubscription());
            }

            // Создаем подписку
            var subscription = new HistorySubscription(this, consumer, instrument, instrumentData.Symbol, span);

            subscription.StartFetch(begin);
            return(subscription);
        }
Ejemplo n.º 20
0
        /// <summary>
        ///     Определить оптимальную длину блока для запроса исторических данных
        /// </summary>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <returns>
        ///     Оптимальная длина блока либо null
        /// </returns>
        public TimeSpan?GetBestFetchBlockLength(Instrument instrument, HistoryProviderSpan span)
        {
            switch (span)
            {
            case HistoryProviderSpan.Minute:
            case HistoryProviderSpan.Minute5:
            case HistoryProviderSpan.Minute10:
            case HistoryProviderSpan.Minute15:
            case HistoryProviderSpan.Minute30:
            case HistoryProviderSpan.Hour:
            case HistoryProviderSpan.Hour4:
            case HistoryProviderSpan.Day:
            case HistoryProviderSpan.Week:
            case HistoryProviderSpan.Month:
                return(TimeSpan.FromDays(365));

            default:
                return(null);
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        ///     Подписаться на исторические данные
        /// </summary>
        /// <param name="consumer">
        ///     Потребитель исторических данных
        /// </param>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="begin">
        ///     Начало диапазона
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <returns>
        ///     Подписка на исторические данные
        /// </returns>
        /// <remarks>
        ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
        ///     если он не в состоянии предоставить запрошенные данные.
        /// </remarks>
        public async Task <IHistoryDataSubscription> SubscribeToHistoryDataAsync(
            IHistoryDataConsumer consumer,
            Instrument instrument,
            DateTime begin,
            HistoryProviderSpan span)
        {
            // Получаем контракт по инструменту
            var contract = await connector.ContractContainer.GetContractAsync(instrument);

            if (contract == null)
            {
                throw new InvalidOperationException($"Can't find instrument \"{instrument}\"");
            }

            // Создаем подписку
            var subscription = new IBHistoryDataSubscription(this, consumer, instrument, contract, span);

            subscription.StartFetch(begin);
            return(subscription);
        }
Ejemplo n.º 22
0
        /// <summary>
        ///     Подписаться на исторические данные
        /// </summary>
        /// <param name="consumer">
        ///     Потребитель исторических данных
        /// </param>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="begin">
        ///     Начало диапазона
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <returns>
        ///     Подписка на исторические данные
        /// </returns>
        /// <remarks>
        ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
        ///     если он не в состоянии предоставить запрошенные данные.
        /// </remarks>
        public async Task <IHistoryDataSubscription> SubscribeToHistoryDataAsync(
            IHistoryDataConsumer consumer,
            Instrument instrument,
            DateTime begin,
            HistoryProviderSpan span)
        {
            using (LogManager.Scope())
            {
                var message = await PrepareTimeBarRequestAsync(instrument, begin, DateTime.Now, span, TimeBarRequest.RequestType.SUBSCRIBE);

                if (message == null)
                {
                    throw new ArgumentException($"Unable to resolve instrument {instrument}");
                }

                message.time_bar_parameters.to_utc_time = 0;

                var request = new HistoryDataSubscription(
                    this,
                    new HistoryData(instrument, begin, DateTime.Now, span),
                    consumer,
                    message.time_bar_parameters.contract_id,
                    message.request_id);

                using (requestsLock.Lock())
                {
                    requests[message.request_id] = request;
                }

                CQGCAdapter.Log.Debug().Print(
                    "Requesting history data stream",
                    LogFields.RequestId(message.request_id),
                    LogFields.ContractId(message.time_bar_parameters.contract_id));
                adapter.SendMessage(message);

                return(request);
            }
        }
        /// <summary>
        ///     Получить исторические данные
        /// </summary>
        /// <param name="consumer">
        ///     Потребитель исторических данных
        /// </param>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="begin">
        ///     Начало диапазона
        /// </param>
        /// <param name="end">
        ///     Конец диапазона
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <param name="cancellationToken">
        ///     Токен отмены
        /// </param>
        /// <returns>
        ///     Исторические данные
        /// </returns>
        /// <remarks>
        ///     Провайдер вправе переопределить параметры исторических графиков - диапазон, интервал,
        ///     если он не в состоянии предоставить запрошенные данные.
        /// </remarks>
        /// <exception cref="NoHistoryDataException">
        ///     Бросается, если исторические данные за указанный период недоступны
        /// </exception>
        public async Task GetHistoryDataAsync(
            IHistoryDataConsumer consumer,
            Instrument instrument,
            DateTime begin,
            DateTime end,
            HistoryProviderSpan span,
            CancellationToken cancellationToken = new CancellationToken())
        {
            var message =
                await PrepareTimeBarRequestAsync(instrument, begin, end, span, TimeBarRequest.RequestType.GET);

            if (message == null)
            {
                throw new ArgumentException($"Unable to resolve instrument {instrument}");
            }

            var request = new HistoryDataRequest(this, consumer, instrument, begin, end, span, message);

            using (requestsLock.Lock())
            {
                requests[message.request_id] = request;
            }

            CQGCAdapter.Log.Debug().Print(
                "Requesting history data block",
                LogFields.RequestId(message.request_id),
                LogFields.ContractId(message.time_bar_parameters.contract_id));
            adapter.SendMessage(message);

            // Поддержка отмены запроса
            cancellationToken.RegisterSafe(() => request.TrySetCanceled());

            var data = await request.Task;

            consumer.Update(data, HistoryDataUpdateType.Batch);
        }
Ejemplo n.º 24
0
        /// <summary>
        ///     Конвертирует размер свечи во временной интервал
        /// </summary>
        public static TimeSpan ToTimeSpan(this HistoryProviderSpan span)
        {
            switch (span)
            {
            case HistoryProviderSpan.Month:
                return(TimeSpan.FromDays(28));

            case HistoryProviderSpan.Week:
                return(TimeSpan.FromDays(7));

            case HistoryProviderSpan.Day:
                return(TimeSpan.FromDays(1));

            case HistoryProviderSpan.Hour4:
                return(TimeSpan.FromHours(4));

            case HistoryProviderSpan.Hour:
                return(TimeSpan.FromHours(1));

            case HistoryProviderSpan.Minute30:
                return(TimeSpan.FromMinutes(30));

            case HistoryProviderSpan.Minute15:
                return(TimeSpan.FromMinutes(15));

            case HistoryProviderSpan.Minute10:
                return(TimeSpan.FromMinutes(10));

            case HistoryProviderSpan.Minute5:
                return(TimeSpan.FromMinutes(5));

            default:
            case HistoryProviderSpan.Minute:
                return(TimeSpan.FromMinutes(1));
            }
        }
Ejemplo n.º 25
0
 /// <summary>
 ///     Определить оптимальную длину блока для запроса исторических данных
 /// </summary>
 /// <param name="instrument">
 ///     Инструмент
 /// </param>
 /// <param name="span">
 ///     Интервал свечей для исторических данных
 /// </param>
 /// <returns>
 ///     Оптимальная длина блока либо null
 /// </returns>
 public TimeSpan?GetBestFetchBlockLength(Instrument instrument, HistoryProviderSpan span) => connector.Adapter.GetBestFetchBlockLength(instrument, span);
Ejemplo n.º 26
0
 public QLHistoryDataRequest(string code, HistoryProviderSpan span)
 {
     instrument = code;
     this.span  = span;
     id         = Guid.NewGuid();
 }
Ejemplo n.º 27
0
        /// <summary>
        ///     Определить оптимальную длину блока для запроса исторических данных
        /// </summary>
        /// <param name="instrument">
        ///     Инструмент
        /// </param>
        /// <param name="span">
        ///     Интервал свечей для исторических данных
        /// </param>
        /// <returns>
        ///     Оптимальная длина блока либо null
        /// </returns>
        public TimeSpan?GetBestFetchBlockLength(Instrument instrument, HistoryProviderSpan span)
        {
            var size = IBHistoryDataLimits.GetFetchBlockSize(span);

            return(size);
        }
Ejemplo n.º 28
0
 /// <summary>
 ///     Определить оптимальную длину блока для запроса исторических данных
 /// </summary>
 /// <param name="instrument">
 ///     Инструмент
 /// </param>
 /// <param name="span">
 ///     Интервал свечей для исторических данных
 /// </param>
 /// <returns>
 ///     Оптимальная длина блока либо null
 /// </returns>
 public TimeSpan?GetBestFetchBlockLength(Instrument instrument, HistoryProviderSpan span) => TimeSpan.FromDays(365);
Ejemplo n.º 29
0
        public static void GetHistoryDataLimits(HistoryProviderSpan span, out TimeSpan?min, out TimeSpan?max)
        {
            switch (span)
            {
            case HistoryProviderSpan.Minute:
                // min: -
                // max: 1d
                min = null;
                max = Duration_1d;
                break;

            case HistoryProviderSpan.Minute5:
                // min: 5m
                // max: 1w
                min = Duration_5m;
                max = Duration_1w;
                break;

            case HistoryProviderSpan.Minute10:
                // min: 10m
                // max: 1w
                min = Duration_10m;
                max = Duration_1w;
                break;

            case HistoryProviderSpan.Minute15:
                // min: 15m
                // max: 2w
                min = Duration_15m;
                max = Duration_2w;
                break;

            case HistoryProviderSpan.Minute30:
                // min: 30m
                // max: 1M
                min = Duration_30m;
                max = Duration_1M;
                break;

            case HistoryProviderSpan.Hour:
                // min: 1h
                // max: 1M
                min = Duration_1h;
                max = Duration_1M;
                break;

            case HistoryProviderSpan.Hour4:
                // min: 8h
                // max: 1M
                min = Duration_8h;
                max = Duration_1M;
                break;

            case HistoryProviderSpan.Day:
                // min: 1d
                // max: 1Y
                min = Duration_1d;
                max = Duration_1Y;
                break;

            case HistoryProviderSpan.Week:
                // min: 1w
                // max: 1Y
                min = Duration_1w;
                max = Duration_1Y;
                break;

            case HistoryProviderSpan.Month:
                // min: 1M
                // max: 1Y
                min = Duration_1M;
                max = Duration_1Y;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Ejemplo n.º 30
0
 public static TimeSpan?GetFetchBlockSize(HistoryProviderSpan span)
 {
     return(null);
     // return MaxBarsPerRequest;
 }