/* * 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; using System.Collections.Generic; using System.Linq; using QuantConnect.Securities.Option; using QuantConnect.Util; namespace QuantConnect.Data.Market { /// /// Represents an entire chain of option contracts for a single underying security. /// This type is /// public class OptionChain : BaseData, IEnumerable { private readonly Dictionary>> _auxiliaryData = new Dictionary>>(); /// /// Gets the most recent trade information for the underlying. This may /// be a or a /// public BaseData Underlying { get; internal set; } /// /// Gets all ticks for every option contract in this chain, keyed by option symbol /// public Ticks Ticks { get; private set; } /// /// Gets all trade bars for every option contract in this chain, keyed by option symbol /// public TradeBars TradeBars { get; private set; } /// /// Gets all quote bars for every option contract in this chain, keyed by option symbol /// public QuoteBars QuoteBars { get; private set; } /// /// Gets all contracts in the chain, keyed by option symbol /// public OptionContracts Contracts { get; private set; } /// /// Gets the set of symbols that passed the /// public HashSet FilteredContracts { get; private set; } /// /// Initializes a new default instance of the class /// private OptionChain() { DataType = MarketDataType.OptionChain; } /// /// Initializes a new instance of the class /// /// The symbol for this chain. /// The time of this chain public OptionChain(Symbol canonicalOptionSymbol, DateTime time) { Time = time; Symbol = canonicalOptionSymbol; DataType = MarketDataType.OptionChain; Ticks = new Ticks(time); TradeBars = new TradeBars(time); QuoteBars = new QuoteBars(time); Contracts = new OptionContracts(time); FilteredContracts = new HashSet(); Underlying = new QuoteBar(); } /// /// Initializes a new instance of the class /// /// The symbol for this chain. /// The time of this chain /// The most recent underlying trade data /// All trade data for the entire option chain /// All quote data for the entire option chain /// All contracts for this option chain /// The filtered list of contracts for this option chain public OptionChain(Symbol canonicalOptionSymbol, DateTime time, BaseData underlying, IEnumerable trades, IEnumerable quotes, IEnumerable contracts, IEnumerable filteredContracts) { Time = time; Underlying = underlying; Symbol = canonicalOptionSymbol; DataType = MarketDataType.OptionChain; FilteredContracts = filteredContracts.ToHashSet(); Ticks = new Ticks(time); TradeBars = new TradeBars(time); QuoteBars = new QuoteBars(time); Contracts = new OptionContracts(time); foreach (var trade in trades) { var tick = trade as Tick; if (tick != null) { List ticks; if (!Ticks.TryGetValue(tick.Symbol, out ticks)) { ticks = new List(); Ticks[tick.Symbol] = ticks; } ticks.Add(tick); continue; } var bar = trade as TradeBar; if (bar != null) { TradeBars[trade.Symbol] = bar; } } foreach (var quote in quotes) { var tick = quote as Tick; if (tick != null) { List ticks; if (!Ticks.TryGetValue(tick.Symbol, out ticks)) { ticks = new List(); Ticks[tick.Symbol] = ticks; } ticks.Add(tick); continue; } var bar = quote as QuoteBar; if (bar != null) { QuoteBars[quote.Symbol] = bar; } } foreach (var contract in contracts) { Contracts[contract.Symbol] = contract; } } /// /// Gets the auxiliary data with the specified type and symbol /// /// The type of auxiliary data /// The symbol of the auxiliary data /// The last auxiliary data with the specified type and symbol public T GetAux(Symbol symbol) { List list; Dictionary> dictionary; if (!_auxiliaryData.TryGetValue(typeof(T), out dictionary) || !dictionary.TryGetValue(symbol, out list)) { return default(T); } return list.OfType().LastOrDefault(); } /// /// Gets all auxiliary data of the specified type as a dictionary keyed by symbol /// /// The type of auxiliary data /// A dictionary containing all auxiliary data of the specified type public DataDictionary GetAux() { Dictionary> d; if (!_auxiliaryData.TryGetValue(typeof(T), out d)) { return new DataDictionary(); } var dictionary = new DataDictionary(); foreach (var kvp in d) { var item = kvp.Value.OfType().LastOrDefault(); if (item != null) { dictionary.Add(kvp.Key, item); } } return dictionary; } /// /// Gets all auxiliary data of the specified type as a dictionary keyed by symbol /// /// The type of auxiliary data /// A dictionary containing all auxiliary data of the specified type public Dictionary> GetAuxList() { Dictionary> dictionary; if (!_auxiliaryData.TryGetValue(typeof(T), out dictionary)) { return new Dictionary>(); } return dictionary; } /// /// Gets a list of auxiliary data with the specified type and symbol /// /// The type of auxiliary data /// The symbol of the auxiliary data /// The list of auxiliary data with the specified type and symbol public List GetAuxList(Symbol symbol) { List list; Dictionary> dictionary; if (!_auxiliaryData.TryGetValue(typeof(T), out dictionary) || !dictionary.TryGetValue(symbol, out list)) { return new List(); } return list.OfType().ToList(); } /// /// Returns an enumerator that iterates through the collection. /// /// /// An enumerator that can be used to iterate through the collection. /// public IEnumerator GetEnumerator() { return Contracts.Values.GetEnumerator(); } /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used to iterate through the collection. /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// Return a new instance clone of this object, used in fill forward /// /// A clone of the current object public override BaseData Clone() { return new OptionChain { Underlying = Underlying, Ticks = Ticks, Contracts = Contracts, QuoteBars = QuoteBars, TradeBars = TradeBars, FilteredContracts = FilteredContracts, Symbol = Symbol, Time = Time, DataType = DataType, Value = Value }; } /// /// Adds the specified auxiliary data to this option chain /// /// The auxiliary data to be added internal void AddAuxData(BaseData baseData) { var type = baseData.GetType(); Dictionary> dictionary; if (!_auxiliaryData.TryGetValue(type, out dictionary)) { dictionary = new Dictionary>(); _auxiliaryData[type] = dictionary; } List list; if (!dictionary.TryGetValue(baseData.Symbol, out list)) { list = new List(); dictionary[baseData.Symbol] = list; } list.Add(baseData); } } }