/// <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); } }
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); }
/// <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); }
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); }
// 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; } }
/// <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); }
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); }
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); } }
/// <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);
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; }
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; }
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); }
/// <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; }
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); }
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; }
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); }
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; }
/// <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); } }
/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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)); } }
/// <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);
public QLHistoryDataRequest(string code, HistoryProviderSpan span) { instrument = code; this.span = span; id = Guid.NewGuid(); }
/// <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); }
/// <summary> /// Определить оптимальную длину блока для запроса исторических данных /// </summary> /// <param name="instrument"> /// Инструмент /// </param> /// <param name="span"> /// Интервал свечей для исторических данных /// </param> /// <returns> /// Оптимальная длина блока либо null /// </returns> public TimeSpan?GetBestFetchBlockLength(Instrument instrument, HistoryProviderSpan span) => TimeSpan.FromDays(365);
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(); } }
public static TimeSpan?GetFetchBlockSize(HistoryProviderSpan span) { return(null); // return MaxBarsPerRequest; }