/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using System.Collections.Generic; using System.Linq; using QuantConnect.Data; using QuantConnect.Data.UniverseSelection; using QuantConnect.Interfaces; using QuantConnect.Data.Auxiliary; using System.Collections; namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators { /// /// Enumerates live options symbol universe data into instances /// public class DataQueueOptionChainUniverseDataCollectionEnumerator : IEnumerator { private readonly SubscriptionRequest _subscriptionRequest; private readonly IDataQueueUniverseProvider _universeProvider; private readonly ITimeProvider _timeProvider; private bool _needNewCurrent; private DateTime _lastEmitTime; private OptionChainUniverseDataCollection _currentData; /// /// Gets the enumerator for the underlying asset /// public IEnumerator Underlying { get; } /// /// Initializes a new instance of the class. /// /// The subscription request to be used /// Underlying enumerator /// Symbol universe provider of the data queue /// The time provider to be used public DataQueueOptionChainUniverseDataCollectionEnumerator( SubscriptionRequest subscriptionRequest, IEnumerator underlying, IDataQueueUniverseProvider universeProvider, ITimeProvider timeProvider) { _subscriptionRequest = subscriptionRequest; Underlying = underlying; _universeProvider = universeProvider; _timeProvider = timeProvider; _needNewCurrent = true; } /// /// Returns current option chain enumerator position /// public OptionChainUniverseDataCollection Current { get; private set; } /// /// Returns current option chain enumerator position /// object IEnumerator.Current => Current; /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { Underlying.Dispose(); } /// /// Advances the enumerator to the next element of the collection. /// /// /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. /// public bool MoveNext() { Underlying.MoveNext(); if (Underlying.Current == null) { Current = null; return true; } if (!_needNewCurrent) { // refresh on date change (in exchange time zone) _needNewCurrent = _timeProvider.GetUtcNow().ConvertFromUtc(_subscriptionRequest.Configuration.ExchangeTimeZone).Date != _lastEmitTime.Date; } if (_needNewCurrent) { var localTime = _timeProvider.GetUtcNow() .RoundDown(_subscriptionRequest.Configuration.Increment) .ConvertFromUtc(_subscriptionRequest.Configuration.ExchangeTimeZone); // loading the list of futures contracts and converting them into zip entries var symbols = _universeProvider.LookupSymbols(_subscriptionRequest.Security.Symbol, false); var zipEntries = symbols.Select(x => new ZipEntryName { Time = localTime, Symbol = x } as BaseData).ToList(); _currentData = new OptionChainUniverseDataCollection { Symbol = _subscriptionRequest.Security.Symbol, Underlying = Underlying.Current, Data = zipEntries, Time = localTime, EndTime = localTime }; _lastEmitTime = localTime; Current = _currentData; _needNewCurrent = false; } else { if (Current == null) { Current = _currentData; } Current.Underlying = Underlying.Current; Current.Time = Underlying.Current.EndTime; Current.EndTime = Underlying.Current.EndTime; } return true; } /// /// Sets the enumerator to its initial position, which is before the first element in the collection. /// public void Reset() { Underlying.Reset(); _needNewCurrent = true; } } }