Skip to content
All library documents

A Futures Strategy That Opens One Contract and Holds to Expiry

Code Lumibot

Summary

This Lumibot example demonstrates a simple futures holding strategy. It configures a US futures market, checks for the first trading iteration, then creates and submits a buy-to-open order for one futures contract with a specified symbol and expiration date. The strategy is intended to enter once and make no further purchases, with a daily iteration schedule.

The document is implementation-focused and provides no performance results or analysis of the return profile. Its sample backtest spans a short date range and names an index benchmark, but gives no outcome data. It also leaves important trading details unspecified, including how the position is monitored, how expiry or settlement is handled, and how risk or margin is managed. The example therefore illustrates order setup and lifecycle structure, rather than a complete, validated futures trading plan.

Key ideas

  • The strategy opens one futures position on its first iteration.
  • The contract symbol and expiration are configurable parameters.
  • The example uses a daily schedule and selects the US futures market.
  • No exit, margin, risk management, or settlement procedure is described.
  • The included backtest setup reports no performance evidence.

Tags

Full text
# futures_hold_to_expiry.py


```py
from datetime import datetime

from lumibot.credentials import IS_BACKTESTING
from lumibot.entities import Asset
from lumibot.strategies.strategy import Strategy

"""
Strategy Description

An example strategy for buying a future and holding it to expiry.
"""


class FuturesHoldToExpiry(Strategy):
    parameters = {
        "buy_symbol": "ES",
        "expiry": datetime(2025, 3, 21),
    }

    # =====Overloading lifecycle methods=============

    def initialize(self):
        # Set the initial variables or constants

        # Built in Variables
        self.sleeptime = "1D"
        self.set_market("us_futures")

    def on_trading_iteration(self):
        """Buys the self.buy_symbol once, then never again"""

        buy_symbol = self.parameters["buy_symbol"]
        expiry = self.parameters["expiry"]

        underlying_asset = Asset(
            symbol=buy_symbol,
            asset_type="index"
        )

        # What to do each iteration
        #underlying_price = self.get_last_price(underlying_asset)
        #self.log_message(f"The value of {buy_symbol} is {underlying_price}")

        if self.first_iteration:
            # Calculate the strike price (round to nearest 1)

            # Create futures asset
            asset = Asset(
                symbol=buy_symbol,
                asset_type="future",
                expiration=expiry,
                multiplier=50
            )

            # Create order
            order = self.create_order(
                asset,
                1,
                "buy_to_open",
            )

            # Submit order
            self.submit_order(order)

            # Log a message
            self.log_message(f"Bought {order.quantity} of {asset}")


if __name__ == "__main__":
    if IS_BACKTESTING:
        from lumibot.backtesting import PolygonDataBacktesting

        # Backtest this strategy
        backtesting_start = datetime(2023, 10, 19)
        backtesting_end = datetime(2023, 10, 24)

        results = FuturesHoldToExpiry.backtest(
            PolygonDataBacktesting,
            backtesting_start,
            backtesting_end,
            benchmark_asset="SPY",
            polygon_api_key="YOUR_POLYGON_API_KEY_HERE",  # Add your polygon API key here
        )

    else:
        strategy = FuturesHoldToExpiry()
        strategy.run_live()

```

Shown in full with attribution under the source's licence. Licence: GPL-3.0

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