name: hfmd-term-structure description: Fetch and analyse a futures term structure (curve) from HF Market Data — contango vs backwardation, spreads and annualised roll yield between contracts, curve shape changes between two dates, with a chart. Use when the user asks about the futures curve, contango/backwardation, calendar spreads, roll yield or "plot the CL/NG/VX term structure".
hfmd-term-structure
The term structure is the set of prices of all listed contracts of one root on one day, ordered by expiry. Its slope is the market's price for time: storage, financing, convenience yield and expected supply.
Vocabulary
- Contango: later contracts priced above nearer ones (upward slope). Normal for storable commodities (storage + financing cost) and for VIX most of the time. A long rolling position pays the roll (negative roll yield).
- Backwardation: later contracts below nearer ones (downward slope). Signals tightness / high convenience yield (e.g. CL in 2022). Long rollers earn the roll.
- Spread (M2 − M1) in price and in %; annualised roll yield ≈ −(M2 − M1)/M1 × 365/days between expiries (positive = the roll pays you).
- Curves can be humped (NG winter premium, ZC harvest lows): describe by segment.
When to use
- "Plot me the CL term structure", "is natural gas in contango?", "how did the curve change since January?", "what's the VX roll cost right now?"
Steps
- Get the curve:
python3 scripts/term_structure.py --root CL [--as-of 2025-09-01] [--compare 2025-01-02] --plot cl_curve.png- calls
/v1/futures/{root}/term-structure?as_of=(v2). If the endpoint is not deployed (404) the script rebuilds the curve from/v1/futures/{root}/contracts+ each contract's last close onas_of(one request per contract — API key recommended). - prints: as-of date actually used, contracts with expiry / days-to-expiry / price / spread vs front (points and %) / annualised roll yield per leg / volume / OI, then the verdict (contango, backwardation or mixed with the segments), slope statistics (front–6th %, avg annualised carry), and — with
--compare— the parallel shift, twist (front vs back change) and which legs moved most.
- calls
- Interpret in the user's context (hedger vs long-only roller vs spread trader) using only the numbers printed. Note if a leg has no price (illiquid deferred months) — it is left blank, not interpolated.
- Chart: price vs expiry (x = expiry date), both dates when
--compare, front-month annotated.
Examples
bash
python3 scripts/term_structure.py --root CL --plot cl.png
python3 scripts/term_structure.py --root NG --as-of 2025-08-29 --compare 2025-02-28 --plot ng_vs.png
python3 scripts/term_structure.py --root VX --depth 8 --json vx.json # machine-readable
python3 scripts/term_structure.py --root ES --as-of 2024-06-14 # equity index: slope ≈ rates − dividendsGotchas
- Quote the as-of date the API used (
meta.as_of): asking for a weekend returns the previous session. - Deferred contracts often have zero volume — their settlement is an exchange mark; say so when OI is tiny.
- Days-to-expiry uses the contract's
expiration_date(rule-based or from data when the rule is unknown —expiration_sourcesays which). - Equity index curves (ES, NQ) are about financing minus dividends, not storage; VX is about the variance risk premium — do not talk about "inventories" there.
- Compare curves in percent of the front, not points, across dates when the price level moved a lot.