/// <summary> /// Adds the specified symbols to the subscription: new IQLevel1WatchItem("IBM", true) /// </summary> /// <param name="job">Job we're subscribing for:</param> /// <param name="symbols">The symbols to be added keyed by SecurityType</param> public void Subscribe(LiveNodePacket job, IEnumerable <Symbol> symbols) { try { foreach (var symbol in symbols) { if (CanSubscribe(symbol)) { lock (_sync) { Log.Trace("IQFeed.Subscribe(): Subscribe Request: " + symbol.ToString()); if (_symbols.Add(symbol)) { // processing canonical option symbol to subscribe to underlying prices var subscribeSymbol = symbol; if (symbol.ID.SecurityType == SecurityType.Option && symbol.IsCanonical()) { subscribeSymbol = symbol.Underlying; _underlyings.Add(subscribeSymbol, symbol); } if (symbol.ID.SecurityType == SecurityType.Future && symbol.IsCanonical()) { // do nothing for now. Later might add continuous contract symbol. return; } var ticker = _symbolUniverse.GetBrokerageSymbol(subscribeSymbol); if (!string.IsNullOrEmpty(ticker)) { _level1Port.Subscribe(ticker); Log.Trace("IQFeed.Subscribe(): Subscribe Processed: {0} ({1})", symbol.Value, ticker); } else { Log.Error("IQFeed.Subscribe(): Symbol {0} was not found in IQFeed symbol universe", symbol.Value); } } } } } } catch (Exception err) { Log.Error("IQFeed.Subscribe(): " + err.Message); } }
/// <summary> /// Populate request data /// </summary> public IEnumerable <Slice> ProcessHistoryRequests(HistoryRequest request) { // skipping universe and canonical symbols if (!CanHandle(request.Symbol) || (request.Symbol.ID.SecurityType == SecurityType.Option && request.Symbol.IsCanonical()) || (request.Symbol.ID.SecurityType == SecurityType.Future && request.Symbol.IsCanonical())) { yield break; } // Set this process status _inProgress = true; var ticker = _symbolUniverse.GetBrokerageSymbol(request.Symbol); var start = request.StartTimeUtc.ConvertFromUtc(TimeZones.NewYork); DateTime?end = request.EndTimeUtc.ConvertFromUtc(TimeZones.NewYork); var exchangeTz = request.ExchangeHours.TimeZone; // if we're within a minute of now, don't set the end time if (request.EndTimeUtc >= DateTime.UtcNow.AddMinutes(-1)) { end = null; } Log.Trace($"HistoryPort.ProcessHistoryJob(): Submitting request: {request.Symbol.SecurityType.ToStringInvariant()}-{ticker}: " + $"{request.Resolution.ToStringInvariant()} {start.ToStringInvariant()}->{(end ?? DateTime.UtcNow.AddMinutes(-1)).ToStringInvariant()}" ); int id; var reqid = string.Empty; switch (request.Resolution) { case Resolution.Tick: id = RequestTickData(ticker, start, end, true); reqid = CreateRequestID(LookupType.REQ_HST_TCK, id); break; case Resolution.Daily: id = RequestDailyData(ticker, start, end, true); reqid = CreateRequestID(LookupType.REQ_HST_DWM, id); break; default: var interval = new Interval(GetPeriodType(request.Resolution), 1); id = RequestIntervalData(ticker, interval, start, end, true); reqid = CreateRequestID(LookupType.REQ_HST_INT, id); break; } _requestDataByRequestId[reqid] = request; while (_inProgress) { continue; } // After all data arrive, we pass it to the algorithm through memory and write to a file foreach (var key in _currentRequest.Keys) { List <BaseData> tradeBars; if (_currentRequest.TryRemove(key, out tradeBars)) { foreach (var tradeBar in tradeBars) { // Returns IEnumerable<Slice> object yield return(new Slice(tradeBar.EndTime, new[] { tradeBar }, tradeBar.EndTime.ConvertToUtc(exchangeTz))); } } } }