Lesson 1.2.3 · 65 min

Futures: specifications, margin, roll and contango

A future is a standardized commitment to buy or sell an asset on a date at a price set today. Nothing is paid on entry: collateral is deposited and the differences are collected or paid every day. This lesson takes apart a fictitious index contract, FIX, with seven years of settlement prices for all its expiries.

Fig. — Life of each FIX contract in 2024 and 2025: they trade for about nine months and are the front month (bar) only for the last three
03/07
Module
1.2 · Asset classes
Duration
65 min
Updated
Level 1 lessons
  1. 1.1 · How markets work

    1. 1.1.1 Market participants and trading venues
    2. 1.1.2 Sessions, auctions, holidays and calendars
    3. 1.1.3 Order book: bid, ask, spread and depth
    4. 1.1.4 Order types
    5. 1.1.5 Costs, settlement, leverage and margin
  2. 1.2 · Asset classes

    1. 1.2.1 Stocks: splits, dividends and corporate actions
    2. 1.2.2 ETFs: replication, tracking error, leveraged ETFs and UCITS
    3. 1.2.3 Futures: specifications, margin, roll and contango
    4. 1.2.4 Forex: pairs, pips, lots, rollover and CFDs
    5. 1.2.5 Options: calls, puts, intrinsic value and time value
    6. 1.2.6 Crypto: spot, perpetuals, funding and custody
    7. 1.2.7 Fixed income and interest rates; CFDs and leveraged products
  3. 1.3 · Market data sources

    1. 1.3.1 Types of market data: EOD, bars, ticks, order book and reference
    2. 1.3.2 Free market data sources
    3. 1.3.3 Retail and prosumer market data APIs
    4. 1.3.4 Professional market data providers
    5. 1.3.5 Crypto and on-chain data
    6. 1.3.6 Brokers as market data sources
    7. 1.3.7 Market data licensing and terms of use
    8. 1.3.8 How to choose a market data provider
  4. 1.4 · Financial data engineering

    1. 1.4.1 Downloading over REST and websockets: pagination, rate limits and retries
    2. 1.4.2 Data cleaning: missing values, bad ticks, gaps and time zones
    3. 1.4.3 Adjusting for splits and dividends: adjusted and unadjusted prices
    4. 1.4.4 Universes without survivorship bias: delistings, mergers and symbol changes
    5. 1.4.5 Building bars: time, tick, volume, dollar and imbalance
    6. 1.4.6 Continuous futures series: roll rules, difference adjustment and ratio adjustment
    7. 1.4.7 Storage: CSV, Parquet, partitioning, DuckDB, TimescaleDB and ArcticDB
    8. 1.4.8 Reproducible pipeline: download, validation, incremental updates and quality tests
  5. 1.5 · Fundamental and macro data

    1. 1.5.1 Financial statements, ratios, XBRL and SEC EDGAR
    2. 1.5.2 Macro data, economic calendars, estimates and transcripts
  6. 1.6 · Financial exploratory analysis

    1. 1.6.1 Returns, volatility, rolling correlations and drawdown
    2. 1.6.2 Stylized facts: fat tails, clustering, autocorrelation and leverage
    3. 1.6.3 Seasonality: day of the week, month, turn of the month and intraday sessions
  7. 1.7 · Programmed technical analysis

    1. 1.7.1 Technical indicators in Python
    2. 1.7.2 Your own implementation versus TA-Lib: validating results
    3. 1.7.3 Candlestick patterns and support and resistance
    4. 1.7.4 Multi-timeframe analysis without look-ahead

A standardized contract

A future is a contract by which two parties commit to buy and sell an asset (the underlying) on a future date (the expiry) at a price set today. Unlike a private forward contract (forward, lesson 1.2.4), a future is traded on an exchange, with identical terms for everyone, and a central counterparty stands between buyer and seller (lesson 1.1.1). The only thing that is negotiated is the price; everything else is set by the contract specifications.

The course data includes a fictitious future, FIX, on a price index of stocks (without dividends). Its specifications:

IN [01]python
import numpy as np
import pandas as pd

esp = pd.read_csv("fix_especificaciones.csv").iloc[0]
print(esp.drop("regla_vencimiento").to_string())
print(esp["regla_vencimiento"])
OUT [01]FIX specifications
multiplicador                50
tick                       0.25
valor_tick                 12.5
margen_inicial            16500
margen_mantenimiento      15000
meses                   H,M,U,Z
tercer viernes del mes del contrato (si no hay sesión, la anterior); liquidación final en efectivo al cierre del índice ese día; último día de negociación = vencimiento

Each field answers a question:

FieldQuestionFIX
UnderlyingOn what?FIX price index
MultiplierHow much is one point worth?50 USD
TickWhat is the minimum price change?0.25 points
Tick valueHow much is gained or lost per tick and contract?0.25 × 50 = 12.50 USD
MonthsWhich expiries are there?March, June, September, December (H, M, U, Z)
ExpiryWhich day?Third Friday of the month (or the previous session)
Final settlementHow is it closed out?In cash, at the index close that day
MarginsWhat collateral is deposited?16,500 USD initial, 15,000 maintenance

The month codes (H March, M June, U September, Z December) are the convention of US exchanges; the FIXH24 contract is the March 2024 one. With a price and the specifications, everything else can be calculated:

IN [02]python
indice = pd.read_csv("fix_indice_diario.csv", parse_dates=["fecha"],
                     index_col="fecha")["indice"]
S = indice["2025-06-02"]
nominal = S * esp["multiplicador"]
print(f"Index: {S:.2f}  notional of one contract: {nominal:,.0f} USD")
print(f"Initial margin: {esp['margen_inicial']:,} USD"
      f" = {esp['margen_inicial'] / nominal:.1%} of notional")
print(f"Leverage: {nominal / esp['margen_inicial']:.1f} to 1")
print(f"1% of the index: {0.01 * nominal:,.0f} USD per contract")
OUT [02]Notional, tick and leverage
Index: 6359.10  notional of one contract: 317,955 USD
Initial margin: 16,500 USD = 5.2% of notional
Leverage: 19.3 to 1
1% of the index: 3,180 USD per contract

One contract controls 317,955 USD of index with 16,500 of collateral: leverage of 19.3 to 1. A 1% move in the index is 3,180 USD, almost a fifth of the margin. To size a futures position you always have to think in notional, never in margin (lesson 0.1.2).

Real contracts follow the same scheme. Some figures from their official specifications:

ContractMultiplierTickExpiry and final settlement
E-mini S&P 500 (CME)50 USD × index0.25 points = 12.50 USDCash; special opening quotation of the index on the third Friday of the month
IBEX 35 future (MEFF)10 EUR × indexSet by circularThird Friday; average of the index from 16:15 to 16:45, one value per minute
Mini IBEX 35 future (MEFF)1 EUR × index5 points = 5 EURThird Friday; same as the IBEX 35

FIX mimics the E-mini S&P 500 in multiplier and tick. The difference is in the final settlement: in the E-mini it is not the index close but a special quotation calculated with the opening prices of its stocks on expiry day (rule 35803.A of chapter 358), and trading in the expiring contract ends when the NYSE session starts that day. At MEFF, the daily settlement price of the first expiry is the volume-weighted average of the order book trades between 17:29 and 17:30. Details like these matter when comparing a future with its index on the expiry date.

Many live contracts at once

Every day several expiries of the same future trade. fix_contratos.parquet has one row per session and contract, with the daily settlement price (the one the clearing house sets at the close to calculate profits and losses), the volume and the open interest (live contracts, not closed out):

IN [03]python
fut = pd.read_parquet("fix_contratos.parquet")
fut["dias"] = (fut["vencimiento"] - fut["fecha"]).dt.days
dia = fut[fut["fecha"] == "2025-06-02"]
dia[["contrato", "vencimiento", "dias", "liquidacion", "volumen",
     "interes_abierto"]]
OUT [03]The live contracts on one day
     contrato vencimiento  dias  liquidacion  volumen  interes_abierto
4867   FIXM25  2025-06-20    18      6367.75   315854           786283
4868   FIXU25  2025-09-19   109      6419.00     4406            24548
4869   FIXZ25  2025-12-19   200      6462.50      729             3201

On June 2, 2025 there are three live expiries. The June one, 18 days out, concentrates almost everything: 786,283 contracts of open interest versus 24,548 for the September one. It is the front month. The others exist, but hardly anyone trades them until their turn approaches.

The header figure is the “ladder” of 2024 and 2025: each contract trades for about nine months, but it is only the front month during the last three. The thick line marks when each one has the largest open interest. They all expire on a Friday:

IN [04]python
venc = fut.groupby("contrato")["vencimiento"].first()
venc = venc[venc.dt.year == 2025]
pd.DataFrame({"vencimiento": venc.dt.date,
              "dia": venc.dt.day_name()})
OUT [04]Expiry dates
         vencimiento     dia
contrato
FIXH25    2025-03-21  Friday
FIXM25    2025-06-20  Friday
FIXU25    2025-09-19  Friday
FIXZ25    2025-12-19  Friday

Margin and daily settlement

Buying a future does not cost its notional. Buyer and seller deposit collateral, the initial margin, and from then on the clearing house settles every day the difference between today's settlement price and yesterday's (mark to market): the winning side collects and the losing side pays, in cash, before the next session. The example in the MEFF specifications sums it up: buying 30 IBEX 35 futures at 10,000 with a settlement of 10,020 at the end of the session gives (10,020 − 10,000) × 30 × 10 = +6,000 euros that day.

daily settlementdaily settlementBuyerMemberSellerMemberClearing house
Mermaid source
flowchart LR
  C[Buyer] --> MC[Member]
  V[Seller] --> MV[Member]
  MC -- daily settlement --> K[Clearing house]
  MV -- daily settlement --> K

If the losses leave the account balance below the maintenance margin, the broker issues a margin call: cash has to be deposited until the account is back at the initial margin. If it is not deposited, the broker closes the position.

balance below minimumdeposits cashdoes not depositsold or expiresOpenCallClosed
Mermaid source
stateDiagram-v2
  [*] --> Open
  Open --> Call: balance below minimum
  Call --> Open: deposits cash
  Call --> Closed: does not deposit
  Open --> Closed: sold or expires
  Closed --> [*]

With the FIX settlement prices, the margin account of a long in the March 2025 contract can be simulated, opened on December 16, 2024 and held until expiry:

IN [05]python
def cuenta_margen(precios, contratos=1, lado=1):
    """Margin account balance with daily settlement.

    lado = 1 for a long, -1 for a short. If the balance falls below the
    maintenance margin, whatever is needed to return to the initial
    margin is deposited.
    """
    saldo, filas = float(esp["margen_inicial"]) * contratos, []
    anterior = precios.iloc[0]
    for fecha, precio in precios.items():
        puntos = lado * (precio - anterior)
        pyg = puntos * esp["multiplicador"] * contratos
        saldo += pyg
        aporte = 0.0
        if saldo < esp["margen_mantenimiento"] * contratos:
            aporte = esp["margen_inicial"] * contratos - saldo
            saldo += aporte
        filas.append((fecha, precio, pyg, aporte, saldo))
        anterior = precio
    cols = ["liquidacion", "pyg", "aporte", "saldo"]
    tabla = pd.DataFrame(filas, columns=["fecha"] + cols)
    return tabla.set_index("fecha")

h25 = fut[fut["contrato"] == "FIXH25"].set_index("fecha")["liquidacion"]
cm = cuenta_margen(h25.loc["2024-12-16":])
cm.loc["2025-02-26":"2025-03-07"]
OUT [05]Daily settlement of a long
            liquidacion     pyg  aporte    saldo
fecha
2025-02-26      5836.25 -1150.0  2500.0  16500.0
2025-02-27      5757.50 -3937.5  3937.5  16500.0
2025-02-28      5753.75  -187.5     0.0  16312.5
2025-03-03      5601.25 -7625.0  7812.5  16500.0
2025-03-04      5618.25   850.0     0.0  17350.0
2025-03-05      5503.50 -5737.5  4887.5  16500.0
2025-03-06      5334.50 -8450.0  8450.0  16500.0
2025-03-07      5234.75 -4987.5  4987.5  16500.0

At the end of February 2025 the index starts to fall sharply. Each day of large losses leaves the balance below 15,000 USD and forces a deposit to get back to 16,500: 2,500 USD on February 26, 3,937.50 on the 27th, 7,812.50 on March 3 and, from March 5 to 7, 4,887.50, 8,450 and 4,987.50. Over the six days in the table with a deposit, the account asks for 32,575 USD: almost twice the entire initial margin.

IN [06]python
llamadas = cm[cm["aporte"] > 0]
print("Margin calls:", len(llamadas))
print(f"Cash deposited: {llamadas['aporte'].sum():,.2f} USD")
print(f"Position P&L: {cm['pyg'].sum():,.2f} USD")
print(f"Final account balance: {cm['saldo'].iloc[-1]:,.2f} USD")
OUT [06]Summary of the margin calls
Margin calls: 12
Cash deposited: 64,112.50 USD
Position P&L: -65,332.50 USD
Final account balance: 15,280.00 USD
Fig. — A long FIXH25 position from 16 December 2024 to expiry: cumulative P&L and cash paid in on margin calls

The position loses 65,332.50 USD: four times the initial margin. The investor has had to deposit 64,112.50 USD in 12 calls, and at expiry has 15,280 left in the account. The numbers add up: 16,500 + 64,112.50 − 65,332.50 = 15,280. The initial margin is not the maximum loss: it is only what the clearing house asks for to cover one or two bad days.

Basis, cost of carry and convergence

Why does a future trade at a price different from spot? Because buying the future and buying the index are not the same. Whoever buys the index pays its full value today (and stops earning interest on that money) and receives the dividends; whoever buys the future pays nothing today and does not receive dividends. For there to be no arbitrage, the future has to compensate for that difference, the cost of carry:

Ft=St e(r−q) τF_t = S_t \, e^{(r - q)\,\tau}

where StS_t is the index, rr the interest rate, qq the dividend yield of the index and τ\tau the time to expiry in years. The difference Ft−StF_t - S_t is the basis. On June 2, 2025, with the three-month rate from the course curve and a dividend yield of 1.35%:

IN [07]python
curva = pd.read_csv("curva_tipos_diaria.csv", parse_dates=["fecha"],
                    index_col="fecha")
r = curva.loc["2025-06-02", "3m"] / 100
q = 0.0135
dia = dia.assign(teorico=S * np.exp((r - q) * dia["dias"] / 365))
dia["base"] = dia["liquidacion"] - S
print(f"Index {S}, r = {r:.3%}, q = {q:.2%}")
dia[["contrato", "dias", "liquidacion", "teorico", "base"]].round(2)
OUT [07]Theoretical price versus settlement
Index 6359.1, r = 4.354%, q = 1.35%
     contrato  dias  liquidacion  teorico    base
4867   FIXM25    18      6367.75  6368.53    8.65
4868   FIXU25   109      6419.00  6416.40   59.90
4869   FIXZ25   200      6462.50  6464.64  103.40

The three settlement prices are less than three points from their theoretical value: the difference is rounding to the tick and a little noise. The basis grows with maturity: 8.65 points at 18 days, 59.90 at 109 and 103.40 at 200. And since the time to expiry shortens every day, a contract's basis is gradually used up until it disappears:

IN [08]python
z25 = fut[fut["contrato"] == "FIXZ25"].set_index("fecha")
base = (z25["liquidacion"] - indice.reindex(z25.index)).rename("base")
pd.concat([z25["dias"], base.round(2)], axis=1).iloc[[0, 50, 100,
                                                      150, -2, -1]]
OUT [08]FIXZ25 basis until its expiry
            dias    base
fecha
2025-03-19   275  109.70
2025-05-30   203  103.12
2025-08-12   129   63.00
2025-10-22    58   27.06
2025-12-18     1    0.65
2025-12-19     0    0.00
Fig. — Basis of the FIXZ25 future against the index, from its first trading day to its expiry

FIXZ25 starts trading in March 2025 with a basis of 109.70 points at 275 days and ends on December 19 with zero basis: its final settlement is the index close. That is why an index future “loses” against the index when the rate exceeds the dividend yield: it is not a poor return, it is the interest the buyer of the future does not pay and that the unspent money does earn.

Contango and backwardation

The term structure is the price of each expiry on the same day. It has two basic shapes:

  • Contango: the far expiries trade more expensive than the near ones (and than spot). In an index, when r>qr > q.
  • Backwardation: the far expiries trade cheaper. In an index, when r<qr < q.
IN [09]python
def curva_futuros(fecha):
    d = fut[(fut["fecha"] == fecha) & (fut["dias"] > 0)]
    s = indice[fecha]
    return d.assign(sobre_contado_pct=100 * (d["liquidacion"] / s - 1))

for fecha in ["2021-06-01", "2025-06-02"]:
    print(fecha, f"3m rate: {curva.loc[fecha, '3m']:.2f} %")
    print(curva_futuros(fecha)[["contrato", "dias", "liquidacion",
                                "sobre_contado_pct"]].round(2))
OUT [09]Term structure on two dates
2021-06-01 3m rate: 0.16 %
     contrato  dias  liquidacion  sobre_contado_pct
1836   FIXM21    17      4040.75              -0.07
1837   FIXU21   108      4022.25              -0.52
1838   FIXZ21   199      4010.75              -0.81
2025-06-02 3m rate: 4.35 %
     contrato  dias  liquidacion  sobre_contado_pct
4867   FIXM25    18      6367.75               0.14
4868   FIXU25   109      6419.00               0.94
4869   FIXZ25   200      6462.50               1.63
Fig. — Term structure of the FIX futures on two dates: backwardation in 2021 and contango in 2025

On June 1, 2021, with the three-month rate at 0.16%, below the dividend yield, the curve slopes down: backwardation. On June 2, 2025, with the rate at 4.35%, it slopes up: contango. To measure the periods with all the data, it is enough to compare the two nearest expiries each day and annualize the difference:

IN [10]python
vivos = fut[fut["dias"] > 0].sort_values(["fecha", "vencimiento"])
dos = vivos.groupby("fecha").head(2)
par = dos.groupby("fecha").agg(f1=("liquidacion", "first"),
                               f2=("liquidacion", "last"),
                               d1=("dias", "first"),
                               d2=("dias", "last"))
par["carry"] = np.log(par["f2"] / par["f1"]) / ((par["d2"] - par["d1"])
                                                 / 365)
anual = par.groupby(par.index.year)["carry"]
pd.DataFrame({"contango_pct_dias": 100 * anual.apply(lambda x:
                                                     (x > 0).mean()),
              "carry_medio_pct": 100 * anual.mean()}).round(1)
OUT [10]Contango and backwardation year by year
       contango_pct_dias  carry_medio_pct
fecha
2019                62.7              0.2
2020                 0.0             -1.4
2021                 0.0             -1.4
2022                62.5              0.7
2023               100.0              3.5
2024               100.0              3.5
2025               100.0              2.7

All of 2020 and 2021 in backwardation, with an average carry of −1.4% a year: rates were close to zero and the index dividend weighed more. All of 2023, 2024 and 2025 in contango, with a carry of 2.7 to 3.5 points a year. 2019 and 2022 are transition years, with 63% of sessions in contango.

What changes for an investor? Whoever holds a long futures position and rolls it every quarter sells the expiring contract (close to spot) and buys the next one (more expensive in contango). That “roll cost” is not an extra loss: it is the same cost of carry that the basis gradually uses up, and it is offset by the interest on the cash that has not been invested. Comparing the return of a future with that of the index without adding that interest makes the future look as if it returns less than it does.

The roll: when liquidity moves

A few days before expiry, most positions are moved to the next contract: the front one is closed and the next one is opened, often with a single calendar spread order. Volume and open interest migrate:

IN [11]python
roll = fut[fut["contrato"].isin(["FIXM25", "FIXU25"])
           & fut["fecha"].between("2025-06-05", "2025-06-23")]
tabla = roll.pivot(index="fecha", columns="contrato",
                   values="interes_abierto")
cruce = tabla[tabla["FIXU25"] > tabla["FIXM25"]].index[0]
print("The next contract overtakes the front one on", cruce.date())
tabla
OUT [11]The June 2025 roll
The next contract overtakes the front one on 2025-06-13
contrato      FIXM25    FIXU25
fecha
2025-06-05  778177.0   34906.0
2025-06-06  764556.0   49050.0
2025-06-09  734660.0   79671.0
2025-06-10  672936.0  141139.0
2025-06-11  563376.0  247645.0
2025-06-12  413715.0  393825.0
2025-06-13  263789.0  540829.0
2025-06-16  153647.0  648266.0
2025-06-17   90019.0  709669.0
2025-06-18   58420.0  741939.0
2025-06-20   44111.0  763316.0
2025-06-23       NaN  805582.0
Fig. — The June 2025 roll: open interest (top) and volume (bottom) of the expiring contract, FIXM25, and the next one, FIXU25

On June 5, FIXM25 has 778,177 open contracts and FIXU25, 34,906. A week later they cross: on June 12 they are almost level (413,715 versus 393,825) and on Friday the 13th the September contract already has more open interest. That same day the volume of FIXU25 shoots up (807,106 contracts): it is the busiest day of the roll. On June 20, expiry day, FIXM25 has 44,111 contracts left, 6% of the peak, which are settled in cash at the index close.

For a trading system, this has two consequences. First, whoever trades the front contract during the roll week does so in a contract that is emptying: spreads widen and the cost rises. Second, to have a long series you have to chain contracts, and the rule for jumping from one to the next (by date, by volume, by open interest) and how the price jump between them is corrected are decisions that change the results of a backtest. That construction is lesson 1.4.6.

What this changes in your data

  • The price of a future is a settlement price. The standard daily data point is not the last trade, but the price the clearing house sets. To compare with the index you have to know at what time and how each one is calculated.
  • Size is measured in notional. One FIX contract is about 300,000 USD; the margin is collateral, not the risk.
  • Cash in reserve is part of the strategy. Margin calls happen on bad days and can add up to several times the initial margin.
  • The basis is not return. Future and index differ by the cost of carry; the return of a future is compared with that of the index minus the interest rate, not with the index alone.
  • Continuous series are built. There is no ten-year “futures price”: there is a roll rule and an adjustment (lesson 1.4.6).

Exercises

  1. Repeat the margin account simulation for a short in FIXH25 from December 16, 2024. How many margin calls does it receive and how much cash does the account accumulate by expiry?
Solution
IN [12]python
corto = cuenta_margen(h25.loc["2024-12-16":], lado=-1)
print("Margin calls:", (corto["aporte"] > 0).sum())
print(f"Deposited: {corto['aporte'].sum():,.2f} USD")
print(f"P&L: {corto['pyg'].sum():,.2f} USD")
print(f"Final balance: {corto['saldo'].iloc[-1]:,.2f} USD")
OUT [12]The short in FIXH25
Margin calls: 5
Deposited: 9,987.50 USD
P&L: 65,332.50 USD
Final balance: 91,820.00 USD

The short gains exactly what the long loses, 65,332.50 USD, and ends with 91,820 USD in the account. But the path is not comfortable: it receives 5 margin calls, for 9,987.50 USD: four in the second half of December 2024 and one on February 19, 2025, days on which the index rises. A future is a zero-sum game between buyer and seller before costs; the clearing house only moves the cash from one to the other every day.

  1. For each 2024 expiry, find the first day on which the open interest of the next contract exceeds that of the expiring one. How many sessions before expiry does it happen?
Solution
IN [13]python
oi = fut.pivot(index="fecha", columns="contrato",
               values="interes_abierto")
sesiones = indice.index
pares = [("FIXH24", "FIXM24"), ("FIXM24", "FIXU24"),
         ("FIXU24", "FIXZ24"), ("FIXZ24", "FIXH25")]
for viejo, nuevo in pares:
    v = fut.loc[fut["contrato"] == viejo, "vencimiento"].iloc[0]
    x = oi[[viejo, nuevo]].dropna()
    x = x[x.index > v - pd.Timedelta(days=30)]  # the last month
    dia_cruce = x[x[nuevo] > x[viejo]].index[0]
    antes = ((sesiones > dia_cruce) & (sesiones <= v)).sum()
    print(viejo, "->", nuevo, dia_cruce.date(), f"({antes} sessions)")
OUT [13]Open interest crossover in each 2024 roll
FIXH24 -> FIXM24 2024-03-11 (4 sessions)
FIXM24 -> FIXU24 2024-06-14 (4 sessions)
FIXU24 -> FIXZ24 2024-09-16 (4 sessions)
FIXZ24 -> FIXH25 2024-12-16 (4 sessions)

In the four 2024 rolls the crossover happens four sessions before expiry (counting expiry day itself), in the previous week. A roll rule “by open interest” would switch contracts on those days; a “fixed date” rule, for example eight sessions before, would do so earlier, when the new contract still has less liquidity. The last-month filter is needed: when the new contract starts trading, nine months earlier, both are far expiries and their small open interest can cross by chance.

  1. A colleague says that ETFs on index futures “lose money at every roll because of contango”. Explain which part of the statement is correct and what is missing.
Solution

It is true that in contango the new contract costs more than the expiring one, and that the price of a long future “falls” toward spot as expiry approaches. What is missing is that this contango is, in a financial future, the cost of carry: the interest rate minus the dividend yield. Whoever buys the future instead of the index does not pay out the notional and earns interest on that cash, which offsets the basis. If the interest on the cash is added (as a well-managed ETF does), the return resembles that of the total return index, minus costs. In commodities, where the term structure reflects storage and expectations, the roll can indeed cost much more than the interest.

Each answer is folded under its question

Self-assessment

  1. The FIX future trades at 6,400 points with a multiplier of 50 USD and a tick of 0.25. How much does one contract gain or lose per tick and what is its notional?

    • A0.25 USD per tick; notional of 6,400 USD
    • B12.50 USD per tick; notional of 320,000 USD
    • C50 USD per tick; notional of 320,000 USD
    • D12.50 USD per tick; notional of 16,500 USD
    Show answer

    Answer B. 12.50 USD per tick; notional of 320,000 USD

    Tick value = 0.25 × 50 = 12.50 USD; notional = 6,400 × 50 = 320,000 USD. The 16,500 USD is the initial margin: what is deposited, not what is controlled.

  2. An account has an initial margin of 16,500 USD and a maintenance margin of 15,000. After a daily loss, the balance is 14,200 USD. What happens?

    • AMargin call: 2,300 USD has to be deposited to get back to the initial margin
    • BNothing: there is still a positive balance
    • CMargin call: 800 USD has to be deposited to get back to maintenance
    • DThe position is closed automatically
    Show answer

    Answer A. Margin call: 2,300 USD has to be deposited to get back to the initial margin

    When it falls below maintenance, the account has to return to the initial margin: 16,500 − 14,200 = 2,300 USD. If it is not deposited in time, the broker can close the position.

  3. With an interest rate of 4.35% and an index dividend yield of 1.35%, what term structure is expected in the futures on that index?

    • ABackwardation: the far expiries cheaper
    • BFlat: all expiries at the same price
    • CContango: the far expiries more expensive, around 3% a year above spot
    • DIt cannot be known without knowing the market's opinion
    Show answer

    Answer C. Contango: the far expiries more expensive, around 3% a year above spot

    By no-arbitrage, F = S·e^((r−q)τ). With r − q = 3%, each expiry trades approximately 3% a year above spot. In a financial future the curve is set by the cost of carry, not by a forecast.

  4. What happens to the basis (future − spot) on the expiry date?

    • AIt equals the pending dividend
    • BIt equals the initial margin
    • CIt depends on that day's volume
    • DIt is zero: the final settlement price is set with the index itself
    Show answer

    Answer D. It is zero: the final settlement price is set with the index itself

    In FIX, the final settlement is the index close that day, so the basis vanishes. In real contracts the reference changes (the special opening quotation in the E-mini S&P 500, an average of the IBEX 35 between 16:15 and 16:45 at MEFF), but the idea is the same.

  5. In the June 2025 roll week, the open interest of FIXU25 overtakes that of FIXM25 on June 13. Why does it matter for a trading system?

    • AIt does not matter: the two contracts are the same asset
    • BBecause the front contract stops trading that day
    • CBecause from then on the liquidity is in the next expiry: staying in the front contract makes execution more expensive, and a continuous series has to decide when to switch
    • DBecause the margin doubles
    Show answer

    Answer C. Because from then on the liquidity is in the next expiry: staying in the front contract makes execution more expensive, and a continuous series has to decide when to switch

    The front contract keeps trading until expiry (June 20), but with less and less open interest. When and how to move from one contract to the next is the central decision of a continuous series (lesson 1.4.6).

Key points

  • The contract sets everything except the price: underlying, multiplier, tick, months, last day and settlement method. In FIX, 50 USD per point and 12.50 USD per tick: a notional of over 300,000 USD with 16,500 of margin.
  • Daily settlement turns every move into cash. A long in FIXH25 from mid-December 2024 lost 65,332 USD until expiry and received 12 margin calls: the initial margin is not the maximum loss.
  • In a financial future, F = S·e^((r−q)τ): the basis is the cost of carry and it vanishes at expiry.
  • Contango (far expiries more expensive) when the rate exceeds the dividend yield; backwardation when it does not. In FIX, backwardation throughout 2020 and 2021, with rates close to zero; contango since 2023.
  • In the ~8 sessions before expiry, volume and open interest move to the next contract. Who rolls and when conditions any continuous series.

Resources

Data