Requesting Data
Universes
Introduction
The AddFuture
add_future
method enables you to select a basket of Future contracts for an underlying Future.
To form your universe of contracts, you can filter them down by their expiry.
If you want to subscribe to individual contracts one-by-one instead of a set of contracts, see Individual Contracts.
Create Universes
To add a universe of Future contracts, in the Initialize
initialize
method, call the AddFuture
add_future
method. This method returns an Future
object, which has a SetFilter
set_filter
method you can call to filter the set of tradable contract down to just the contracts you want.
public class BasicFutureAlgorithm : QCAlgorithm { private Future _future; public override void Initialize() { _future = AddFuture(Futures.Indices.SP500EMini, extendedMarketHours: true, dataMappingMode: DataMappingMode.OpenInterest, dataNormalizationMode: DataNormalizationMode.BackwardsRatio, contractDepthOffset: 0); _future.SetFilter(0, 182); } public override void OnData(Slice data) { data.Bars.TryGetValue(_future.Symbol, out var continuousTradeBar); data.Bars.TryGetValue(_future.Mapped, out var mappedTradeBar); foreach (var (continuousSymbol, chain) in data.FuturesChains) { foreach (var (symbol, contract) in chain.Contracts) { var expiry = contract.Expiry; } } } // Track events when security changes its ticker, allowing the algorithm to adapt to these changes. public override void OnSymbolChangedEvents(SymbolChangedEvents symbolChangedEvents) { foreach (var (symbol, changedEvent) in symbolChangedEvents) { var oldSymbol = changedEvent.OldSymbol; var newSymbol = changedEvent.NewSymbol; var quantity = Portfolio[oldSymbol].Quantity; // Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract var tag = $"Rollover - Symbol changed at {Time}: {oldSymbol} -> {newSymbol}"; Liquidate(oldSymbol, tag: tag); if (quantity != 0) MarketOrder(newSymbol, quantity, tag: tag); } } }
class BasicFutureAlgorithm(QCAlgorithm): def initialize(self): self._future = self.add_future(Futures.Indices.SP_500_E_MINI, extended_market_hours=True, data_mapping_mode=DataMappingMode.OPEN_INTEREST, data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO, contract_depth_offset=0) self._future.set_filter(0, 182) def on_data(self, data): continuous_trade_bar = data.bars.get(self._future.symbol) mapped_trade_bar = data.bars.get(self._future.mapped) for continuous_symbol, chain in data.future_chains.items(): for symbol, contract in chain.contracts.items(): expiry = contract.expiry # Track events when security changes its ticker allowing algorithm to adapt to these changes. def on_symbol_changed_events(self, symbol_changed_events): for symbol, changed_event in symbol_changed_events.items(): old_symbol = changed_event.old_symbol new_symbol = changed_event.new_symbol quantity = self.portfolio[old_symbol].quantity # Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract tag = f"Rollover - Symbol changed at {self.time}: {old_symbol} -> {new_symbol}" self.liquidate(old_symbol, tag=tag) if quantity: self.market_order(new_symbol, quantity, tag=tag)
For more information about the AddFuture
add_future
method, see Create Universes.
Continous Contracts
By default, LEAN only subscribes to the continuous Future contract. A continuous Future contract represents a series of separate contracts stitched together to form a continuous price. If you need a lot of historical data to warm up an indicator, apply the indicator to the continuous contract price series. The Future
object has a Symbol
symbol
property and a Mapped
mapped
property. The price of the Symbol
symbol
property is the adjusted price of the continuous contract. The price of the Mapped
mapped
property is the raw price of the currently selected contract in the continuous contract series.
// Get the adjusted price of the continuous contract var adjustedPrice = Securities[_future.Symbol].Price; // Get the raw price of the currently selected contract in the continuous contract series var rawPrice = Securities[_future.Mapped].Price;
# Get the adjusted price of the continuous contract adjusted_price = self.securities[self._future.symbol].price # Get the raw price of the currently selected contract in the continuous contract series raw_price = self.securities[self._future.mapped].price
The continuous Futures contract isn't a tradable security. You must place orders for a specific Futures contract. To access the currently selected contract in the continuous contract series, use the Mapped
mapped
property of the Future
object.
// Place a market order for the currently selected contract in the continuous contract series MarkerOrder(_future.Mapped, 1);
# Place a market order for the currently selected contract in the continuous contract series self.market_order(self._future.mapped, 1)
For more information, see Continous Contracts.
Filter by Contract Properties
To set a contract filter, in the Initialize
initialize
method, call the SetFilter
set_filter
method of the Future
object. The following table describes the available filter techniques:
SetFilter(int minExpiry, int maxExpiry) set_filter(minExpiry: int, maxExpiry: int) Selects the contracts that expire within the range you set. This filter runs asynchronously by default. |
SetFilter(Func<FutureFilterUniverse, FutureFilterUniverse> universeFunc) set_filter(universeFunc: Callable[[FutureFilterUniverse], FutureFilterUniverse]) Selects the contracts that a function selects. |
# Select the contracts which expire within 182 days self._future.set_filter(0, 182) # Select the front month contract self._future.set_filter(lambda future_filter_universe: future_filter_universe.front_month())
// Select the contracts which expire within 182 days _future.SetFilter(0, 182); // Select the front month contract _future.SetFilter(futureFilterUniverse => futureFilterUniverse.FrontMonth());
The following table describes the filter methods of the FutureFilterUniverse
class:
StandardsOnly() standards_only() Selects standard contracts |
IncludeWeeklys() include_weeklys() Selects non-standard weekly contracts |
WeeklysOnly() weeklys_only() Selects weekly contracts |
FrontMonth() front_month() Selects the front month contract |
BackMonths() back_months() Selects the non-front month contracts |
BackMonth() back_month() Selects the back month contracts |
Expiration(TimeSpan minExpiry, TimeSpan maxExpiry) expiration(min_expiry: timedelta, max_expiry: timedelta) Selects contracts that expire within a range of dates relative to the current day |
Expiration(int minExpiryDays, int maxExpiryDays) expiration(min_expiry_days: int, max_expiry_days: int) Selects contracts that expire within a range of dates relative to the current day |
Contracts(IEnumerable<Symbol> contracts) contracts(contracts: List[Symbol]) Selects a list of contracts |
Contracts(Func<IEnumerable<Symbol>, IEnumerable< Symbol>> contractSelector) contracts(contractSelector: Callable[[List[Symbol]], List[Symbol]]) Selects contracts that a selector function selects |
The preceding methods return an FutureFilterUniverse
, so you can chain the methods together.
// Select the front month standard contracts _future.SetFilter(futureFilterUniverse => futureFilterUniverse.StandardsOnly().FrontMonth());
# Select the front month standard contracts self._future.set_filter(lambda future_filter_universe: future_filter_universe.standards_only().front_month())
You can also define an isolated filter method.
// In Initialize _future.SetFilter(Selector); private FutureFilterUniverse Selector(FutureFilterUniverse futureFilterUniverse) { return futureFilterUniverse.StandardsOnly().FrontMonth(); }
# In Initialize self._future.set_filter(self._contract_selector) def _contract_selector(self, future_filter_universe: Callable[[FutureFilterUniverse], FutureFilterUniverse]) -> FutureFilterUniverse: return future_filter_universe.standards_only().front_month()
Default Filter
By default, LEAN doesn't add any contracts to the FuturesChain it passes to the OnData
on_data
method.