/* * 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 QuantConnect.Data; using QuantConnect.Orders.Fees; using QuantConnect.Orders.Fills; using QuantConnect.Orders.Slippage; using Python.Runtime; using QuantConnect.Util; using QuantConnect.Data.UniverseSelection; namespace QuantConnect.Securities.Future { /// /// Futures Security Object Implementation for Futures Assets /// /// public class Future : Security, IContinuousSecurity { private bool _isTradable; /// /// Gets or sets whether or not this security should be considered tradable /// /// Canonical futures are not tradable public override bool IsTradable { get { // once a future is removed it is no longer tradable return _isTradable && !Symbol.IsCanonical(); } set { _isTradable = value; } } /// /// The default number of days required to settle a futures sale /// public const int DefaultSettlementDays = 1; /// /// The default time of day for settlement /// public static readonly TimeSpan DefaultSettlementTime = new TimeSpan(6, 0, 0); /// /// Constructor for the Future security /// /// Defines the hours this exchange is open /// The cash object that represent the quote currency /// The subscription configuration for this security /// The symbol properties for this security /// Currency converter used to convert /// instances into units of the account currency /// Provides all data types registered in the algorithm public Future(SecurityExchangeHours exchangeHours, SubscriptionDataConfig config, Cash quoteCurrency, SymbolProperties symbolProperties, ICurrencyConverter currencyConverter, IRegisteredSecurityDataTypesProvider registeredTypes ) : base(config, quoteCurrency, symbolProperties, new FutureExchange(exchangeHours), new FutureCache(), new SecurityPortfolioModel(), new FutureFillModel(), new InteractiveBrokersFeeModel(), NullSlippageModel.Instance, new FutureSettlementModel(), Securities.VolatilityModel.Null, null, new SecurityDataFilter(), new SecurityPriceVariationModel(), currencyConverter, registeredTypes, Securities.MarginInterestRateModel.Null ) { BuyingPowerModel = new FutureMarginModel(0, this); // for now all futures are cash settled as we don't allow underlying (Live Cattle?) to be posted on the account SettlementType = SettlementType.Cash; Holdings = new FutureHolding(this, currencyConverter); ContractFilter = new EmptyContractFilter(); } /// /// Constructor for the Future security /// /// The subscription security symbol /// Defines the hours this exchange is open /// The cash object that represent the quote currency /// The symbol properties for this security /// Currency converter used to convert /// instances into units of the account currency /// Provides all data types registered in the algorithm /// Cache to store security information public Future(Symbol symbol, SecurityExchangeHours exchangeHours, Cash quoteCurrency, SymbolProperties symbolProperties, ICurrencyConverter currencyConverter, IRegisteredSecurityDataTypesProvider registeredTypes, SecurityCache securityCache) : base(symbol, quoteCurrency, symbolProperties, new FutureExchange(exchangeHours), securityCache, new SecurityPortfolioModel(), new FutureFillModel(), new InteractiveBrokersFeeModel(), NullSlippageModel.Instance, new FutureSettlementModel(), Securities.VolatilityModel.Null, null, new SecurityDataFilter(), new SecurityPriceVariationModel(), currencyConverter, registeredTypes, Securities.MarginInterestRateModel.Null ) { BuyingPowerModel = new FutureMarginModel(0, this); // for now all futures are cash settled as we don't allow underlying (Live Cattle?) to be posted on the account SettlementType = SettlementType.Cash; Holdings = new FutureHolding(this, currencyConverter); ContractFilter = new EmptyContractFilter(); } /// /// Returns true if this is the future chain security, false if it is a specific future contract /// public bool IsFutureChain => Symbol.IsCanonical(); /// /// Returns true if this is a specific future contract security, false if it is the future chain security /// public bool IsFutureContract => !Symbol.IsCanonical(); /// /// Gets the expiration date /// public DateTime Expiry { get { return Symbol.ID.Date; } } /// /// Specifies if futures contract has physical or cash settlement on settlement /// public SettlementType SettlementType { get; set; } /// /// Gets or sets the currently mapped symbol for the security /// public Symbol Mapped { get; set; } /// /// Gets or sets the contract filter /// public IDerivativeSecurityFilter ContractFilter { get; set; } /// /// Sets the to be used for this . /// This is the source of this instance's time. /// /// The source of this 's time. public override void SetLocalTimeKeeper(LocalTimeKeeper localTimeKeeper) { base.SetLocalTimeKeeper(localTimeKeeper); var model = SettlementModel as FutureSettlementModel; if (model != null) { model.SetLocalDateTimeFrontier(LocalTime); } } /// /// Sets the to a new instance of the filter /// using the specified expiration range values /// /// The minimum time until expiry to include, for example, TimeSpan.FromDays(10) /// would exclude contracts expiring in less than 10 days /// The maximum time until expiry to include, for example, TimeSpan.FromDays(10) /// would exclude contracts expiring in more than 10 days public void SetFilter(TimeSpan minExpiry, TimeSpan maxExpiry) { SetFilterImp(universe => universe.Expiration(minExpiry, maxExpiry)); } /// /// Sets the to a new instance of the filter /// using the specified expiration range values /// /// The minimum time, expressed in days, until expiry to include, for example, 10 /// would exclude contracts expiring in less than 10 days /// The maximum time, expressed in days, until expiry to include, for example, 10 /// would exclude contracts expiring in more than 10 days public void SetFilter(int minExpiryDays, int maxExpiryDays) { SetFilterImp(universe => universe.Expiration(minExpiryDays, maxExpiryDays)); } /// /// Sets the to a new universe selection function /// /// new universe selection function public void SetFilter(Func universeFunc) { SetFilterImp(universeFunc); ContractFilter.Asynchronous = false; } /// /// Sets the to a new universe selection function /// /// new universe selection function public void SetFilter(PyObject universeFunc) { var pyUniverseFunc = PythonUtil.ToFunc(universeFunc); SetFilter(pyUniverseFunc); } private void SetFilterImp(Func universeFunc) { Func, IDerivativeSecurityFilterUniverse> func = universe => { var futureUniverse = universe as FutureFilterUniverse; var result = universeFunc(futureUniverse); return result.ApplyTypesFilter(); }; ContractFilter = new FuncSecurityDerivativeFilter(func); } } }