--- 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 1. 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 on `as_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. 2. 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. 3. 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 − dividends ``` ## Gotchas - 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_source` says 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.