/* * 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 QuantConnect.Data.UniverseSelection; namespace QuantConnect.Data.Market { /// /// Defines a single futures contract at a specific expiration /// public class FuturesContract : BaseContract { private FutureUniverse _universeData; private TradeBar _tradeBar; private QuoteBar _quoteBar; private Tick _tradeTick; private Tick _quoteTick; private Tick _openInterest; /// /// Gets the open interest /// public override decimal OpenInterest { get { // Contract universe data is prioritized if (_universeData != null) { return _universeData.OpenInterest; } return _openInterest?.Value ?? decimal.Zero; } } /// /// Gets the last price this contract traded at /// public override decimal LastPrice { get { if (_universeData != null) { return _universeData.Close; } if (_tradeBar == null && _tradeTick == null) { return decimal.Zero; } if (_tradeBar != null) { return _tradeTick != null && _tradeTick.EndTime > _tradeBar.EndTime ? _tradeTick.Price : _tradeBar.Close; } return _tradeTick.Price; } } /// /// Gets the last volume this contract traded at /// public override long Volume { get { if (_universeData != null) { return (long)_universeData.Volume; } return (long)(_tradeBar?.Volume ?? 0); } } /// /// Get the current bid price /// public override decimal BidPrice { get { if (_universeData != null) { return _universeData.Close; } if (_quoteBar == null && _quoteTick == null) { return decimal.Zero; } if (_quoteBar != null) { return _quoteTick != null && _quoteTick.EndTime > _quoteBar.EndTime ? _quoteTick.BidPrice : _quoteBar.Bid.Close; } return _quoteTick.BidPrice; } } /// /// Get the current bid size /// public override long BidSize { get { if (_quoteBar == null && _quoteTick == null) { return 0; } if (_quoteBar != null) { return (long)(_quoteTick != null && _quoteTick.EndTime > _quoteBar.EndTime ? _quoteTick.BidSize : _quoteBar.LastBidSize); } return (long)_quoteTick.BidSize; } } /// /// Gets the current ask price /// public override decimal AskPrice { get { if (_universeData != null) { return _universeData.Close; } if (_quoteBar == null && _quoteTick == null) { return decimal.Zero; } if (_quoteBar != null) { return _quoteTick != null && _quoteTick.EndTime > _quoteBar.EndTime ? _quoteTick.AskPrice : _quoteBar.Ask.Close; } return _quoteTick.AskPrice; } } /// /// Get the current ask size /// public override long AskSize { get { if (_quoteBar == null && _quoteTick == null) { return 0; } if (_quoteBar != null) { return (long)(_quoteTick != null && _quoteTick.EndTime > _quoteBar.EndTime ? _quoteTick.AskSize : _quoteBar.LastAskSize); } return (long)_quoteTick.AskSize; } } /// /// Initializes a new instance of the class /// /// The futures contract symbol public FuturesContract(Symbol symbol) : base(symbol) { } /// /// Initializes a new instance of the class /// /// The contract universe data public FuturesContract(FutureUniverse contractData) : base(contractData.Symbol) { _universeData = contractData; } /// /// Implicit conversion into /// /// The option contract to be converted public static implicit operator Symbol(FuturesContract contract) { return contract.Symbol; } /// /// Updates the future contract with the new data, which can be a or or /// internal override void Update(BaseData data) { switch (data) { case TradeBar tradeBar: _tradeBar = tradeBar; break; case QuoteBar quoteBar: _quoteBar = quoteBar; break; case Tick tick when tick.TickType == TickType.Trade: _tradeTick = tick; break; case Tick tick when tick.TickType == TickType.Quote: _quoteTick = tick; break; case Tick tick when tick.TickType == TickType.OpenInterest: _openInterest = tick; break; } } } }