Markets: A Rigorous Course

Exercise · m07_hedge.py

Minimum-variance hedging and beta hedging with index futures

Implement each function, then press Run tests.

Read notes 7.6 first. Use numpy only.

Run locally

From the repository root, with the exercises environment installed:

cd exercises && .venv/bin/python -m pytest modules/M07-forwards-futures/tests/test_m07_hedge.py

Tests (8)

  • test_true_ratio_hull_jet_fuel
  • test_simulated_series_have_requested_moments
  • test_estimated_ratio_matches_truth
  • test_estimator_equals_ols_slope
  • test_beta_recovered_on_fat_tailed_index_returns
  • test_hedged_variance_minimised_at_h_star
  • test_beta_hedge_nifty_lots
  • test_tail_factor

Theory: M07 notes. Run with Ctrl/⌘+Enter.

not run yet

Not saved: sign up to keep your code
"""M07 exercise 2: minimum-variance hedging and beta hedging with index futures.

Implement each function, then run from the repo root:

    cd exercises && .venv/bin/python -m pytest modules/M07-forwards-futures/tests/test_m07_hedge.py

Read notes §7.6 first. Use numpy only.
"""

from __future__ import annotations

import math

import numpy as np


def simulate_correlated(n: int, sigma_s: float, sigma_f: float, rho: float, seed: int = 0) -> tuple[np.ndarray, np.ndarray]:
    """Draw n iid pairs (dS, dF) from a bivariate normal with mean 0, standard
    deviations sigma_s and sigma_f, and correlation rho.

    Construction (use exactly this so results are reproducible):
        rng = np.random.default_rng(seed); z = rng.standard_normal((2, n))
        dF = sigma_f * z[0]
        dS = sigma_s * (rho * z[0] + sqrt(1 - rho^2) * z[1])
    Return (dS, dF).
    """
    raise NotImplementedError


def true_hedge_ratio(sigma_s: float, sigma_f: float, rho: float) -> float:
    """Population minimum-variance hedge ratio h* = rho * sigma_S / sigma_F (Prop. 7.8, eq. 7.15)."""
    raise NotImplementedError


def min_variance_hedge_ratio(dS: np.ndarray, dF: np.ndarray) -> float:
    """Sample estimate h_hat = Cov(dS, dF) / Var(dF).

    This equals the OLS slope of dS on dF with an intercept. Use the same ddof
    in numerator and denominator.
    """
    raise NotImplementedError


def hedge_effectiveness(dS: np.ndarray, dF: np.ndarray) -> float:
    """Sample hedge effectiveness R^2 = rho_hat^2, the fraction of Var(dS) removed by the optimal hedge (eq. 7.16)."""
    raise NotImplementedError


def hedged_variance(h: float, sigma_s: float, sigma_f: float, rho: float) -> float:
    """Variance per unit of the hedged position: Var(dS - h dF) = s_S^2 - 2 h rho s_S s_F + h^2 s_F^2."""
    raise NotImplementedError


def optimal_contracts(h: float, Q_A: float, Q_F: float) -> float:
    """Optimal number of futures contracts N* = h* Q_A / Q_F (eq. 7.17).

    Q_A: units of the asset being hedged; Q_F: units of the underlying per contract.
    Do not round.
    """
    raise NotImplementedError


def beta_hedge_contracts(beta: float, V_P: float, F: float, lot_size: int, target_beta: float = 0.0) -> float:
    """Signed number of index futures contracts that moves a portfolio's beta from beta to target_beta (Prop. 7.9).

    N = (target_beta - beta) * V_P / (F * lot_size), where V_P is the portfolio
    value in rupees and F * lot_size is the value of one futures contract.
    Negative means sell. Do not round.
    """
    raise NotImplementedError


def tail_factor(r: float, tau: float) -> float:
    """Interest tailing factor exp(-r tau) applied to a futures hedge whose gains are
    realised daily but whose hedged exposure settles tau years later (§7.6.4)."""
    raise NotImplementedError

No runs yet

The stub's functions raise NotImplementedError until you write them. Fill in one, press Run tests, and watch its tests turn green.

Reference solution

Available after your first run, with an account approved for code runs.

Create a free account

Reading is open to everyone. An account keeps your progress, answers, notes and code drafts, and gives you the study plan, the journals and the simulator. Running code needs an account approved for it.