Skip to content
All library documents

Selecting Futures Contracts with Expiration Filters and Chain Data

Article Strategy library · Author: QuantConnect

Summary

This QuantConnect example demonstrates how to subscribe to futures on an underlying asset, restrict the available contracts by expiration, and select a contract from the futures chain. It adds E-mini S&P 500 and gold futures with an expiration window extending up to 182 days, then searches for a front-month contract that expires at least 90 days after the current date. If a matching contract is found, the algorithm submits a market order and later liquidates the portfolio.

The example also sets an equity benchmark, seeds securities with known prices, checks that newly added contracts have data, and inspects the selected contract's buying power model and margin requirements. These are useful mechanics for futures data access and contract selection, rather than a trading signal or tested strategy. The sample runs only over a short 2013 date range and provides no evidence about returns, execution quality, or how this selection rule performs across markets.

Key ideas

  • Futures subscriptions can be filtered by a minimum and maximum time to expiration.
  • The example selects a front-month contract whose expiration is at least 90 days away.
  • It demonstrates order submission, liquidation, price seeding, and checks for loaded contract data.
  • The algorithm inspects initial and maintenance margin requirements but provides no performance evaluation.

Tags

Full text
# BasicTemplateFuturesAlgorithm


# BasicTemplateFuturesAlgorithm









This example demonstrates how to add futures for a given underlying asset. It also shows how you can prefilter contracts easily based on expirations, and how you can inspect the futures chain to pick a specific contract to trade.

## Source (Apache-2.0)

```python
# 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.

from AlgorithmImports import *

### <summary>
### This example demonstrates how to add futures for a given underlying asset.
### It also shows how you can prefilter contracts easily based on expirations, and how you
### can inspect the futures chain to pick a specific contract to trade.
### </summary>
### <meta name="tag" content="using data" />
### <meta name="tag" content="benchmarks" />
### <meta name="tag" content="futures" />
class BasicTemplateFuturesAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2013, 10, 8)
        self.set_end_date(2013, 10, 10)
        self.set_cash(1000000)

        self.contract_symbol = None

        # Subscribe and set our expiry filter for the futures chain
        futureSP500 = self.add_future(Futures.Indices.SP_500_E_MINI)
        future_gold = self.add_future(Futures.Metals.GOLD)

        # set our expiry filter for this futures chain
        # SetFilter method accepts timedelta objects or integer for days.
        # The following statements yield the same filtering criteria
        futureSP500.set_filter(timedelta(0), timedelta(182))
        future_gold.set_filter(0, 182)

        benchmark = self.add_equity("SPY")
        self.set_benchmark(benchmark.symbol)

        seeder = FuncSecuritySeeder(self.get_last_known_prices)
        self.set_security_initializer(lambda security: seeder.seed_security(security))

    def on_data(self,slice):
        if not self.portfolio.invested:
            for chain in slice.future_chains:
                # Get the front contract expiring no earlier than in 90 days, if any, and trade it
                front = next(iter(chain.value.expiring_after(self.time + timedelta(90)).front_month()), None)
                if front is None: continue

                self.contract_symbol = front.symbol
                self.market_order(front.symbol , 1)
        else:
            self.liquidate()

    def on_end_of_algorithm(self):
        # Get the margin requirements
        buying_power_model = self.securities[self.contract_symbol].buying_power_model
        name = type(buying_power_model).__name__
        if name != 'FutureMarginModel':
            raise AssertionError(f"Invalid buying power model. Found: {name}. Expected: FutureMarginModel")

        initial_overnight = buying_power_model.initial_overnight_margin_requirement
        maintenance_overnight = buying_power_model.maintenance_overnight_margin_requirement
        initial_intraday = buying_power_model.initial_intraday_margin_requirement
        maintenance_intraday = buying_power_model.maintenance_intraday_margin_requirement

    def on_securities_changed(self, changes):
        for added_security in changes.added_securities:
            if added_security.symbol.security_type == SecurityType.FUTURE and not added_security.symbol.is_canonical() and not added_security.has_data:
                raise AssertionError(f"Future contracts did not work up as expected: {added_security.symbol}")

```

Shown in full with attribution under the source's licence. Licence: Apache-2.0

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.