Universes

Futures

Introduction

A Futures universe lets you select a basket of contracts for a single Future. LEAN models Future subscriptions as a universe of Future contracts. A Future universe is similar to an Option universe, except Future contracts don't have a strike price, so the universe filter primarily focuses on the contract expiration date.

Create Universes

To add a universe of Future contracts, in the Initialize method, call the AddFuture method. This method returns an Future object, which contains the continuous contract Symbol. The continuous contract Symbol is the key to access the contracts in the FutureChain that LEAN passes to the OnData method. When you create the Future subscription, save a reference to the continuous contract Symbol so you can use it later in your algorithm.

_future = AddFuture(Futures.Currencies.BTC);
_symbol = _future.Symbol;
self.future = self.AddFuture(Futures.Currencies.BTC)
self.symbol = self.future.Symbol

The following table describes the AddFuture method arguments:

Argument: ticker

The Future ticker. To view the supported assets in the US Futures dataset, see Supported Assets.

Data Type: stringstr | Default Value: None

Argument: resolution

The resolution of the market data. To view the supported resolutions, see Resolutions. If you don't provide a value, it uses Resolution.Minute by default.

Data Type: Resolution?Resolution/NoneType | Default Value: Nonenull

Argument: market

The Futures market. To view the supported markets in the US Futures dataset, see Supported Markets. If you don't provide a value, it uses the default Future market of your brokerage model.

Data Type: stringstr | Default Value: Nonenull

Argument: fillForward

If true, the current slice contains the last available data even if there is no data at the current time.

Data Type: bool | Default Value: Truetrue

Argument: leverage

The leverage for this Future.

Data Type: decimalfloat | Default Value: Security.NullLeverage

Argument: extendedMarketHours

If true, use data from the pre and post market sessions

Data Type: bool | Default Value: Falsefalse

Argument: dataMappingMode

The contract mapping mode to use for the continuous future contract

Data Type: DataMappingMode?DataMappingMode/NoneType | Default Value: Nonenull

Argument: dataNormalizationMode

The price scaling mode to use for the continuous future contract

Data Type: DataNormalizationMode?DataNormalizationMode/NoneType | Default Value: Nonenull

Argument: contractDepthOffset

The continuous future contract desired offset from the current front month. For example, 0 is the front month, 1 is the back month contract.

Data Type: int | Default Value: 0

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 property and a Mapped property. The price of the Symbol property is the adjusted price of the continuous contract. The price of the 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

To configure how LEAN identifies the current Future contract in the continuous series and how it forms the adjusted price between each contract, provide dataMappingMode, dataNormalizationMode, and contractDepthOffset arguments to the AddFuture method. The Future object that the AddFuture method returns contains a Mapped property that references the current contract in the continuous contract series. As the contracts roll over, the Mapped property references the next contract in the series and you receive a SymbolChangedEvent object in the OnData method. The SymbolChangedEvent references the old contract Symbol and the new contract Symbol.

public override void OnData(Slice slice)
{
    foreach (var changedEvent in slice.SymbolChangedEvents.Values)
    {
        Log($"Symbol changed: {changedEvent.OldSymbol} -> {changedEvent.NewSymbol}");
    }
}
def OnData(self, slice: Slice) -> None:
    for changed_event in slice.SymbolChangedEvents.Values:
        self.Log(f"Contract rollover from {changed_event.OldSymbol} to {changed_event.NewSymbol}")

Data Normalization Modes

The dataNormalizationMode argument defines how the price series of two contracts are stitched together when the contract rollovers occur. The following DataNormalizatoinMode enumeration members are available for continuous contracts:

We use the entire Futures history to adjust historical prices. This process ensures you get the same adjusted prices, regardless of the backtest end date.

Data Mapping Modes

The dataMappingMode argument defines when contract rollovers occur. The DataMappingMode enumeration has the following members:

Contract Depth Offsets

The contractDepthOffset argument defines which contract to use. 0 is the front month contract, 1 is the following back month contract, and 3 is the second back month contract.

Filter Contracts

By default, LEAN doesn't add any contracts to the FuturesChain it passes to the OnData method. To add a universe of Future contracts, in the Initialize method, call the SetFilter method of the Future object. The following table describes the available filter techniques:

Method
Description
SetFilter(int minExpiryDays, int maxExpiryDays)SetFilter(minExpiryDays: int, maxExpiryDays: int)Selects the contracts that expire within the range you set.
SetFilter(Func<FutureFilterUniverse, FutureFilterUniverse> universeFunc)SetFilter(universeFunc: Callable[[FutureFilterUniverse], FutureFilterUniverse])Selects the contracts that a function selects.
# Select the contracts which expire within 182 days
self.future.SetFilter(0, 182)

# Select the front month contract
self.future.SetFilter(lambda future_filter_universe: future_filter_universe.FrontMonth())
// 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:

MethodDescription
StandardsOnly()Selects standard contracts
IncludeWeeklys()Selects non-standard weekly contracts
WeeklysOnly()Selects weekly contracts
FrontMonth()Selects the front month contract
BackMonths()Selects the non-front month contracts
BackMonth()Selects the back month contracts
Expiration(TimeSpan minExpiry, TimeSpan maxExpiry)Expiration(minExpiry: timedelta, maxExpiry: timedelta)Selects contracts that expire within a range of dates relative to the current day
Expiration(int minExpiryDays, int maxExpiryDays)Expiration(minExpiryDays: int, maxExpiryDays: 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
OnlyApplyFilterAtMarketOpen()Instructs the engine to only filter contracts on the first time step of each market day

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.SetFilter(lambda future_filter_universe: future_filter_universe.StandardsOnly().FrontMonth())

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.SetFilter(self.contract_selector)
    
def contract_selector(self, 
    future_filter_universe: Callable[[FutureFilterUniverse], FutureFilterUniverse]) -> FutureFilterUniverse:
    return future_filter_universe.StandardsOnly().FrontMonth()

Some of the preceding filter methods only set an internal enumeration in the FutureFilterUniverse that it uses later on in the filter process. This subset of filter methods don't immediately reduce the number of contract Symbol objects in the FutureFilterUniverse.

By default, LEAN adds contracts to the FutureChain that pass the filter criteria at every time step in your algorithm. If a contract has been in the universe for a duration that matches the MinimumTimeInUniverse setting and it no longer passes the filter criteria, LEAN removes it from the chain

Navigate Futures Chains

FuturesChain objects represent an entire chain of contracts for a single underlying Future. They have the following properties:

To get the FuturesChain, index the FuturesChains property of the Slice with the continuous contract Symbol.

public override void OnData(Slice slice)
{
    if (slice.FuturesChains.TryGetValue(_symbol, out var chain))
    {
        // Example: Select the contract with the greatest open interest
        var contract = chain.OrderBy(x => x.OpenInterest).Last();
    }
}
def OnData(self, slice: Slice) -> None:
    chain = slice.FuturesChains.get(self.symbol)
    if chain:
        # Example: Select the contract with the greatest open interest
        contract = sorted(chain, key=lambda contract: contract.OpenInterest, reverse=True)[0]

You can also loop through the FuturesChains property to get each FuturesChain.

public override void OnData(Slice slice)
{
    foreach (var kvp in slice.FuturesChains)
    {
        var continuousContractSymbol = kvp.Key;
        var chain = kvp.Value;
    }
}

public void OnData(FuturesChains futuresChains)
{
    foreach (var kvp in futuresChains)
    {
        var continuousContractSymbol = kvp.Key;
        var chain = kvp.Value;
    }
}
def OnData(self, slice: Slice) -> None:
    for continuous_contract_symbol, chain in slice.FuturesChains.items():
        pass

Selection Frequency

By default, Futures universes run at every time step to select their contracts. If you add the OnlyApplyFilterAtMarketOpen method to your contract filter, the universe selects contracts once a day at the first time step.

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: