Requesting Data
Individual Contracts
Introduction
The AddFutureContract
add_future_contract
method enables you to add an individual Future contract to your algorithm.
To check which contracts are currently available to add to your algorithm, use the FutureChainProvider.GetFutureContractList
future_chain_provider.get_future_contract_list
method.
If you want to subscribe to a set of contracts instead of individual contracts one-by-one, see Universes.
Create Subscriptions
Before you can subscribe to a Future contract, you must have the underlying Future Symbol
to get the contract Symbol
.
public class BasicFutureAlgorithm : QCAlgorithm { private Symbol _continuous, _contractSymbol; public override void Initialize() { SetStartDate(2020, 1, 1); _continuous = AddFuture(Futures.Indices.SP500EMini).Symbol; } public override void OnData(Slice data) { if (_contractSymbol == null) { var contractSymbols = FutureChainProvider.GetFutureContractList(_continuous, Time); var expiry = contractSymbols.Min(symbol => symbol.ID.Date); _contractSymbol = contractSymbols.FirstOrDefault(symbol => symbol.ID.Date == expiry); AddFutureContract(_contractSymbol); } } }
class BasicFutureAlgorithm(QCAlgorithm): def initialize(self): self.set_start_date(2020, 1, 1) self._continuous = self.add_future(Futures.Indices.SP_500_E_MINI).symbol self._contract_symbol = None def on_data(self, data): if not self._contract_symbol: contract_symbols = self.future_chain_provider.get_future_contract_list(self._continuous, self.time) expiry = min([symbol.id.date for symbol in contract_symbols]) self._contract_symbol = next(symbol for symbol in contract_symbols if symbol.id.date == expiry) self.add_future_contract(self._contract_symbol)
Get Contract Symbols
To subscribe to a Future contract, you need the contract Symbol
.
The preferred method to getting Future contract Symbol
objects is to use the FutureChainProvider
future_chain_provider
.
The GetFutureContractList
get_future_contract_list
method of FutureChainProvider
future_chain_provider
returns a list of Symbol
objects for a given date and underlying Future, which you can then sort and filter to find the specific contract(s) you want to trade.
var contractSymbols = FutureChainProvider.GetFutureContractList(_continuous, Time); var expiry = contractSymbols.Min(symbol => symbol.ID.Date); _contractSymbol = contractSymbols.FirstOrDefault(symbol => symbol.ID.Date == expiry);
contract_symbols = self.future_chain_provider.get_future_contract_list(self._continuous, self.time) expiry = min([symbol.id.date for symbol in contract_symbols]) self._contract_symbol = next(symbol for symbol in contract_symbols if symbol.id.date == expiry)
Subscribe to Contracts
To create an Future contract subscription, pass the contract Symbol
to the AddFutureContract
add_future_contract
method. Save a reference to the contract Symbol
symbol
so you can easily access the Future contract in the FutureChain that LEAN passes to the OnData
on_data
method. This method returns an Future
object.
AddFutureContract(_contractSymbol);
self.add_future_contract(self._contract_symbol)
The AddFutureContract
add_future_contract
method creates a subscription for a single Future contract and adds it to your user-defined universe. To create a dynamic universe of Futures contracts, add an Future universe or an Future Universe Selection model.
Warm Up Contract Prices
If you subscribe to an Future contract with AddFutureContract
add_future_contract
, you'll need to wait until the next Slice
to receive data and trade the contract. To trade the contract in the same time step you subscribe to the contract, set the current price of the contract in a security initializer.
var seeder = new FuncSecuritySeeder(GetLastKnownPrices); SetSecurityInitializer(new BrokerageModelSecurityInitializer(BrokerageModel, seeder));
seeder = FuncSecuritySeeder(self.get_last_known_prices) self.set_security_initializer(BrokerageModelSecurityInitializer(self.brokerage_model, seeder))
Supported Assets
To view the supported assets in the Futures dataset, see the Supported Assets.
Resolutions
The following table shows the available resolutions and data formats for Futures subscriptions:
Resolution | TradeBar | QuoteBar | Trade Tick | Quote Tick |
---|---|---|---|---|
Tick TICK | ||||
Second SECOND | ||||
Minute MINUTE | ||||
Hour HOUR | ||||
Daily DAILY |
The default resolution for Futures contract subscriptions is Resolution.Minute
Resolution.MINUTE
. To change the resolution, pass a resolution
argument to the AddFutureContract
add_future_contract
method.
AddFutureContract(_contractSymbol, Resolution.Daily);
self.add_future_contract(self._contract_symbol, Resolution.DAILY)
To create custom resolution periods, see Consolidating Data.
Supported Markets
The following Market
enumeration members are available for Futures:
Historical data for backtesting is unavailable for ICE
, INDIA
, SGX
and NYSELIFFE
. In live trading, LEAN sources this data from your brokerage or a third-party data provider.
You don't need to pass a market
argument to the AddFutureContract
add_future_contract
method because the contract Symbol
already contains the market.
Fill Forward
Fill forward means if there is no data point for the current slice, LEAN uses the previous data point. Fill forward is the default data setting. If you disable fill forward, you may get stale fills or you may see trade volume as zero.
To disable fill forward for a security, set the fillForward
fill_forward
argument to false when you create the security subscription.
AddFutureContract(_contractSymbol, fillForward: false);
self.add_future_contract(self._contract_symbol, fill_forward=False)
Margin and Leverage
LEAN models buying power and margin calls to ensure your algorithm stays within the margin requirements. Futures are already leveraged products, so you can't change their leverage with the default margin model.
Extended Market Hours
By default, your security subscriptions only cover regular trading hours. To subscribe to pre and post-market trading hours for a specific asset, enable the extendedMarketHours
extended_market_hours
argument when you create the security subscription.
AddFutureContract(_contractSymbol, extendedMarketHours: true);
self.add_future_contract(self._contract_symbol, extended_market_hours=True)
You only receive extended market hours data if you create the subscription with minute, second, or tick resolution. If you create the subscription with daily or hourly resolution, the bars only reflect the regular trading hours.
To view the schedule of regular and extended market hours, see Market Hours.
In general, we model most Futures market hours with the following segments:
Market Segment | Time |
---|---|
Pre-market | 00:00:00 to 09:30:00 |
Market | 09:30:00 to 17:00:00 |
Post-market | 18:00:00 to 00:00:00 |
We model it this way because some Futures, like VIX, have pre- and post-market hours, so we standardized it. With this segmentation, if you set a Scheduled Events for the market open, it's set for 9:30 AM instead of midnight.
Continuous Contracts
A continuous Futures contract represents a single contract that maps to other contracts over time as the rollover rules are met. For more information about continuous Futures contracts, see Continuous Contracts.
Data Normalization
The data normalization mode doesn't affect the data that LEAN passes to OnData
on_data
or the data from history request for Futures contracts. If you change the data normalization mode, it won't change the outcome.
The following data normalization modes are available for continuous Futures contracts:
Examples
The following examples demonstrate some common practices for requesting individual Future contract data.
Example 1: Add the Front-Month Contract
The following algorithm adds the front-month contract for the E-Mini S&P 500 Future and plots the daily closing price of the contract.
public class FutureExampleAlgorithm : QCAlgorithm { private Future _future; private Symbol _contractSymbol; public override void Initialize() { SetStartDate(2022, 1, 1); // Add the E-mini Future. _future = AddFuture(Futures.Indices.SP500EMini); // Get all the contracts that are currently tradable. var contractSymbols = FutureChainProvider.GetFutureContractList(_future.Symbol, Time); // Get the contract with the closest expiry. _contractSymbol = contractSymbols.MinBy(x => x.ID.Date); // Add the front-month Futures contract. AddFutureContract(_contractSymbol); // Plot the contract price. PlotIndicator("Price", Identity(_contractSymbol, Resolution.Daily)); // Stop the algorithm when the contract expires. SetEndDate(_contractSymbol.ID.Date); } }
class FutureExampleAlgorithm(QCAlgorithm): def initialize(self): self.set_start_date(2022, 1, 1) # Add a Future. self._future = self.add_future(Futures.Indices.SP_500_E_MINI) # Get all the contracts that are currently tradable. contract_symbols = self.future_chain_provider.get_future_contract_list(self._future.symbol, self.time) # Get the contract with the closest expiry. self._contract_symbol = min(contract_symbols, key=lambda x: x.id.date) # Add the Futures contract. self.add_future_contract(self._contract_symbol) # Plot the contract price. self.plot_indicator("Price", self.identity(self._contract_symbol, Resolution.DAILY)) # Stop the algorithm when the contract expires. self.set_end_date(self._contract_symbol.id.date)