Universe Selection

Futures Universes

Introduction

A Future Universe Selection model selects contracts for a set of Futures.

Future Universe Selection

The FutureUniverseSelectionModel selects all the contracts for a set of Futures you specify. To use this model, provide a refreshInterval and a selector function. The refreshInterval defines how frequently LEAN calls the selector function. The selector function receives a DateTimedatetime object that represents the current Coordinated Universal Time (UTC) and returns a list of Symbol objects. The Symbol objects you return from the selector function are the Futures of the universe.

AddUniverseSelection(new FutureUniverseSelectionModel(refreshInterval, futureChainSymbolSelector));
from Selection.FutureUniverseSelectionModel import FutureUniverseSelectionModel

self.AddUniverseSelection(FutureUniverseSelectionModel(refreshInterval, futureChainSymbolSelector))

The following table describes the arguments the model accepts:

ArgumentData TypeDescriptionDefault Value
refreshIntervalTimeSpantimedeltaTime interval between universe refreshes
futureChainSymbolSelectorFunc<DateTime, IEnumerable<Symbol>>Callable[[datetime], List[Symbol]]A function that selects the Future symbols for a given Coordinated Universal Time (UTC). To view the supported assets in the US Futures dataset, see Supported Assets.
universeSettingsUniverseSettingsUniverse settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removednullNone

If you don't provide a universeSettings argument, the algorithm.UniverseSettings is used by default.

public override void Initialize()
{
    AddUniverseSelection(
        new FutureUniverseSelectionModel(TimeSpan.FromDays(1), SelectFutureChainSymbols)
    );
}

private static IEnumerable<Symbol> SelectFutureChainSymbols(DateTime utcTime)
{
    return new[] {
        QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME),
        QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX)
    };
}
from Selection.FutureUniverseSelectionModel import FutureUniverseSelectionModel

def Initialize(self) -> None:
    universe = FutureUniverseSelectionModel(timedelta(days=1), self.select_future_chain_symbols)
    self.SetUniverseSelection(universe)

def select_future_chain_symbols(self, utc_time: datetime) -> List[Symbol]:
    return [ Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME),
             Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX) ]

This model uses the default Future contract filter, which doesn't select any Futures contracts. To use a different filter, subclass the FutureUniverseSelectionModel and define a Filter method. The Filter method accepts and returns a FutureFilterUniverse object to select the Futures contracts. 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

Depending on how you define the contract filter, LEAN may call it once a day or at every time step.

// In Initialize
AddUniverseSelection(new FrontMonthFutureUniverseSelectionModel());

// Outside of the algorithm class
class FrontMonthFutureUniverseSelectionModel : FutureUniverseSelectionModel
{
    public FrontMonthFutureUniverseSelectionModel()
        : base(TimeSpan.FromDays(1), SelectFutureChainSymbols) {}

    private static IEnumerable<Symbol> SelectFutureChainSymbols(DateTime utcTime)
    {
        return new List<Symbol> {
            QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME),
            QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX)
        };
    }

    protected override FutureFilterUniverse Filter(FutureFilterUniverse filter)
    {
        return filter.FrontMonth().OnlyApplyFilterAtMarketOpen();
    }
}
from Selection.FutureUniverseSelectionModel import FutureUniverseSelectionModel

# In Initialize
self.AddUniverseSelection(FrontMonthFutureUniverseSelectionModel())

# Outside of the algorithm class
class FrontMonthFutureUniverseSelectionModel(FutureUniverseSelectionModel):
    def __init__(self) -> None:
        super().__init__(timedelta(1), self.select_future_chain_symbols)

    def select_future_chain_symbols(self, utc_time: datetime) -> List[Symbol]:
        return [ 
            Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME),
            Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX) 
        ]

    def Filter(self, filter: FutureFilterUniverse) -> FutureFilterUniverse:
        return filter.FrontMonth().OnlyApplyFilterAtMarketOpen()

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.

The AddUniverseSelection method doesn't return a Future object like the AddFuture method. The Future object contains Symbol and Mapped properties, which reference the continuous contract and the currently selected contract in the continuous contract series, respectively. To get the Future object, define the OnSecuritiesChanged method in your algorithm class or framework models and check the result of the IsCanonical method.

public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
    foreach (var security in changes.AddedSecurities)
    {
        if (security.Symbol.IsCanonical())
        {
            _future = security as Future;
        }
    }
}
def OnSecuritiesChanged(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
    for security in changes.AddedSecurities:
        if security.Symbol.IsCanonical():
            self.future = security

To view the implementation of this model, see the LEAN GitHub repositoryLEAN GitHub repository.

Open Interest Future Universe Selection

The OpenInterestFutureUniverseSelectionModel is an extension of the FutureUniverseSelectionModel that selects the contract with the greatest open interest on a daily basis.

AddUniverseSelection(new OpenInterestFutureUniverseSelectionModel(algorithm, futureChainSymbolSelector));
self.AddUniverseSelection(OpenInterestFutureUniverseSelectionModel(algorithm, futureChainSymbolSelector));

The following table describes the arguments the model accepts:

ArgumentData TypeDescriptionDefault Value
algorithmIAlgorithmAlgorithm
futureChainSymbolSelector Func<DateTime, IEnumerable<Symbol>> Callable[[datetime], List[Symbol]]A function that selects the Future symbols for a given Coordinated Universal Time (UTC). To view the supported assets in the US Futures dataset, see Supported Assets.
chainContractsLookupLimit int? int/NoneTypeLimit on how many contracts to query for open interest6
resultsLimit int? int/NoneTypeLimit on how many contracts will be part of the universe1
public override void Initialize()
{
    var symbols = new[] {
        QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME),
        QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX)
    }; 
    AddUniverseSelection(new OpenInterestFutureUniverseSelectionModel(this, utcTime => symbols));
}
def Initialize(self):
    symbols = [
        Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME),
        Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX)
    ]
    universe = OpenInterestFutureUniverseSelectionModel(self, lambda utc_time: symbols)
    self.AddUniverseSelection(universe)

To move the selection functions outside of the algorithm class, create a universe selection model that inherits the OpenInterestFutureUniverseSelectionModel class.

// In Initialize
AddUniverseSelection(new GoldOpenInterestFutureUniverseSelectionModel(this));

// Outside of the algorithm class
class GoldOpenInterestFutureUniverseSelectionModel : OpenInterestFutureUniverseSelectionModel
{
    public GoldOpenInterestFutureUniverseSelectionModel(QCAlgorithm algorithm, 
        int? chainContractsLookupLimit = 6, int? resultsLimit = 1)
        : base(algorithm, SelectFutureChainSymbols, chainContractsLookupLimit, resultsLimit) {}

    private static IEnumerable<Symbol> SelectFutureChainSymbols(DateTime utcTime)
    {
        return new List<Symbol> { 
            QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX) 
        };
    }
}
# In Initialize
self.AddUniverseSelection(GoldOpenInterestFutureUniverseSelectionModel(self))
    
# Outside of the algorithm class
class GoldOpenInterestFutureUniverseSelectionModel(OpenInterestFutureUniverseSelectionModel):
    def __init__(self, algorithm: QCAlgorithm, chainContractsLookupLimit: int = 6, resultsLimit: int = 1):
        super().__init__(algorithm, self.select_future_chain_symbols, chainContractsLookupLimit, resultsLimit)

    def select_future_chain_symbols(self, utcTime: datetime) -> List[Symbol]:
        return [Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX)]

The AddUniverseSelection method doesn't return a Future object like the AddFuture method. The Future object contains Symbol and Mapped properties, which reference the continuous contract and the currently selected contract in the continuous contract series, respectively. To get the Future object, define the OnSecuritiesChanged method in your algorithm class or framework models and check the result of the IsCanonical method.

public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
    foreach (var security in changes.AddedSecurities)
    {
        if (security.Symbol.IsCanonical())
        {
            _future = security as Future;
        }
    }
}
def OnSecuritiesChanged(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
    for security in changes.AddedSecurities:
        if security.Symbol.IsCanonical():
            self.future = security

To view the implementation of this model, see the LEAN GitHub repository.

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: