---
title: "Stock Market Hedging"
description: "Hedge prediction market exposure with correlated stock positions using Alpaca Markets. OLS hedge ratio, effectiveness metrics, multi-ticker optimization, and scenario analysis."
icon: "shield-halved"
---

<Warning>
  **Ultra Feature.** Requires an Ultra subscription. [Get started at api.mathematicalcompany.com](https://api.mathematicalcompany.com)
</Warning>

# Stock Market Hedging

Prediction market positions often correlate with traditional financial assets. A trader long "Will the Fed cut rates?" can hedge with bond ETFs (TLT) or rate-sensitive stocks. Horizon's hedge module covers ratio calculation, effectiveness tracking, multi-ticker optimization, and automated rebalancing. All math is in Rust.

## Overview

<CardGroup cols={2}>
  <Card title="OLS Hedge Ratio" icon="chart-line">
    `hz.hedge_ratio_ols()` computes the hedge ratio from rolling price windows.
  </Card>
  <Card title="Effectiveness & Basis Risk" icon="gauge-high">
    `hz.hedge_effectiveness()` and `hz.basis_risk()` measure how well the hedge is working.
  </Card>
  <Card title="Multi-Ticker Optimization" icon="scale-balanced">
    `hz.multi_ticker_hedge()` finds weights across multiple hedge instruments.
  </Card>
  <Card title="Scenario Analysis" icon="flask-vial">
    `hz.hedge_scenario()` shows portfolio P&L under different spot moves.
  </Card>
</CardGroup>

---

## Core Functions

All math runs in Rust. Every output is guarded against NaN/Inf.

### hz.hedge_ratio_ols

Compute the hedge ratio: h* = Cov(dS, dF) / Var(dF).

```python
import horizon as hz

h = hz.hedge_ratio_ols(
    spot_prices=[0.55, 0.56, 0.57, 0.58, 0.59],
    hedge_prices=[100.0, 101.0, 102.0, 103.0, 104.0],
    window=4,
)
print(f"Hedge ratio: {h:.4f}")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `spot_prices` | `list[float]` | required | Prediction market price series |
| `hedge_prices` | `list[float]` | required | Stock/ETF price series |
| `window` | `int` | `60` | Rolling window size for return calculation |

Returns 0.0 if fewer than 2 data points or zero variance in hedge returns.

### hz.rolling_correlation

Rolling Pearson correlation between two price series.

```python
corr = hz.rolling_correlation(spot_prices, stock_prices, window=30)
print(f"Current correlation: {corr[-1]:.4f}")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `series_a` | `list[float]` | required | First price series |
| `series_b` | `list[float]` | required | Second price series |
| `window` | `int` | `60` | Rolling window size |

Returns a list of correlation values, one per window. Empty if insufficient data.

### hz.hedge_effectiveness

Hedge effectiveness: HE = 1 − Var(hedged) / Var(unhedged). Values close to 1.0 indicate a good hedge.

```python
he = hz.hedge_effectiveness(spot_returns, hedge_returns, hedge_ratio=0.5)
print(f"Effectiveness: {he:.4f}")  # 0.82 means 82% variance reduction
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `spot_returns` | `list[float]` | Spot instrument return series |
| `hedge_returns` | `list[float]` | Hedge instrument return series |
| `hedge_ratio` | `float` | Hedge ratio (from `hedge_ratio_ols`) |

Returns 0.0 for empty input or zero unhedged variance.

### hz.basis_risk

Residual variance after hedging. Lower is better.

```python
br = hz.basis_risk(spot_returns, hedge_returns, hedge_ratio=0.5)
print(f"Basis risk: {br:.6f}")
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `spot_returns` | `list[float]` | Spot instrument return series |
| `hedge_returns` | `list[float]` | Hedge instrument return series |
| `hedge_ratio` | `float` | Hedge ratio |

### hz.optimal_hedge_size

Calculate optimal hedge notional with optional cap.

```python
size = hz.optimal_hedge_size(
    spot_notional=10000.0,
    hedge_ratio=0.45,
    max_hedge_notional=50000.0,
)
print(f"Hedge size: ${size:.2f}")  # $4500.00
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `spot_notional` | `float` | required | Notional value of the spot position |
| `hedge_ratio` | `float` | required | Hedge ratio |
| `max_hedge_notional` | `float` | `inf` | Maximum hedge notional cap |

### hz.compute_hedge_sensitivities

Returns a `HedgeSensitivities` object with risk metrics.

```python
sens = hz.compute_hedge_sensitivities(
    spot_prices=[0.55, 0.56, 0.57, 0.58, 0.59],
    hedge_prices=[100.0, 101.0, 102.0, 103.0, 104.0],
    position_size=1.0,
    window=4,
)
print(f"Delta: {sens.delta:.4f}")
print(f"Beta: {sens.beta:.4f}")
print(f"Tracking error: {sens.tracking_error:.4f}")
```

| Field | Description |
|-------|-------------|
| `delta` | dV/dS via finite differences |
| `cross_gamma` | d²V/dSdF cross-gamma |
| `beta` | OLS beta of hedge on spot |
| `tracking_error` | Annualized std(residuals) × √252 |
| `hedge_decay` | Drift of recent hedge ratio from full-window ratio |

### hz.multi_ticker_hedge

Multi-instrument hedge optimization. Returns a `MultiHedgeResult`.

```python
result = hz.multi_ticker_hedge(
    spot_returns=spot_ret,
    hedge_returns_matrix=[tlt_ret, spy_ret, gld_ret],
    tickers=["TLT", "SPY", "GLD"],
)
print(f"Weights: {dict(zip(result.tickers, result.weights))}")
print(f"Effectiveness: {result.hedge_effectiveness:.4f}")
print(f"Tracking error: {result.tracking_error:.4f}")
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `spot_returns` | `list[float]` | Spot instrument return series |
| `hedge_returns_matrix` | `list[list[float]]` | Return series for each hedge instrument |
| `tickers` | `list[str]` | Ticker labels for each hedge instrument |

### hz.hedge_scenario

P&L projection under a given spot move.

```python
outcome = hz.hedge_scenario(
    spot_position=1000, spot_price=0.65,
    hedge_position=-50, hedge_price=100.0,
    spot_move_pct=-0.10,
    correlation=0.75,
)
print(f"Portfolio P&L: ${outcome.portfolio_pnl:.2f}")
print(f"Unhedged P&L: ${outcome.unhedged_pnl:.2f}")
print(f"Hedge benefit: ${outcome.hedge_benefit:.2f}")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `spot_position` | `float` | required | Number of spot contracts |
| `spot_price` | `float` | required | Current spot price |
| `hedge_position` | `float` | required | Number of hedge shares (negative = short) |
| `hedge_price` | `float` | required | Current hedge instrument price |
| `spot_move_pct` | `float` | required | Spot move as decimal (e.g., -0.10 for -10%) |
| `correlation` | `float` | `0.75` | Assumed correlation between spot and hedge |
| `hedge_vol` | `float` | `0.20` | Annualized hedge volatility |
| `spot_vol` | `float` | `0.30` | Annualized spot volatility |

---

## Pipeline Functions

These functions return callables for use inside `hz.run()` pipelines. Call the factory to configure, get back a function you can put in the pipeline list.

### hz.hedge_monitor

Computes hedge metrics each cycle. Returns a dict passed to the next pipeline stage.

```python
monitor = hz.hedge_monitor(
    prediction_feed="fed_rate",
    stock_feed="tlt",
    window=60,
)

# Use in a pipeline
hz.run(
    name="monitored_strategy",
    exchange=[hz.Polymarket(), hz.Alpaca(paper=True)],
    feeds={
        "fed_rate": hz.PolymarketBook("will-fed-cut-rates"),
        "tlt": hz.AlpacaFeed(symbols=["TLT"]),
    },
    pipeline=[monitor, my_strategy],
)
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `prediction_feed` | `str` | required | Feed name for the prediction market |
| `stock_feed` | `str` | required | Feed name for the hedge instrument |
| `window` | `int` | `60` | Rolling window for calculations |

Returns on each cycle:

```python
{
    "hedge_ratio": 0.45,
    "hedge_effectiveness": 0.82,
    "basis_risk": 0.0003,
    "correlation": 0.78,
    "recommended_hedge_size": 0.45,
    "spread_zscore": -1.2,
}
```

### hz.hedge_executor

Monitors hedge drift and flags rebalancing. With `auto_rebalance=True`, generates `OrderRequest` objects for Alpaca.

```python
executor = hz.hedge_executor(hz.HedgeConfig(
    prediction_feed="fed_rate",
    stock_feed="tlt",
    stock_symbol="TLT",
    rebalance_threshold=0.05,
    auto_rebalance=True,
))
```

### hz.correlation_tracker

Track pairwise correlations across multiple feeds.

```python
tracker = hz.correlation_tracker(["fed_rate", "tlt", "spy"], window=30)
# Returns: {"correlations": {"fed_rate/tlt": 0.78, ...}, "top_pairs": [...]}
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `feeds` | `list[str]` | required | Feed names to track |
| `window` | `int` | `60` | Rolling correlation window |

### hz.stock_hedge

Combines `hedge_monitor` + `hedge_executor`. Use this if you want both in one call.

```python
hz.run(
    name="rate_hedge",
    exchange=[hz.Polymarket(), hz.Alpaca(paper=True)],
    feeds={
        "fed_rate": hz.PolymarketBook("will-fed-cut-rates"),
        "tlt": hz.AlpacaFeed(symbols=["TLT"]),
    },
    pipeline=[
        hz.stock_hedge(hz.HedgeConfig(
            prediction_feed="fed_rate",
            stock_feed="tlt",
            stock_symbol="TLT",
            window=60,
            rebalance_threshold=0.05,
            auto_rebalance=True,
        )),
        my_strategy,
    ],
)
```

---

## Standalone Analysis

These functions run outside `hz.run()` for research and one-off analysis.

### hz.compute_hedge_report

Returns a full hedge report as a dictionary.

```python
import horizon as hz

report = hz.compute_hedge_report(
    spot_prices=fed_prices,
    hedge_prices=tlt_prices,
    window=30,
)
print(f"Hedge ratio: {report['hedge_ratio']:.4f}")
print(f"Effectiveness: {report['hedge_effectiveness']:.4f}")
print(f"Tracking error: {report['sensitivities']['tracking_error']:.4f}")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `spot_prices` | `list[float]` | required | Spot price series |
| `hedge_prices` | `list[float]` | required | Hedge price series |
| `window` | `int` | `60` | Rolling window |
| `position_size` | `float` | `1.0` | Position size for sensitivity calculation |

### hz.run_scenario

Run multiple scenarios at once:

```python
results = hz.run_scenario(
    spot_position=1000, spot_price=0.65,
    hedge_position=-50, hedge_price=100.0,
    spot_moves=[-0.20, -0.10, -0.05, 0.0, 0.05, 0.10, 0.20],
)
for r in results:
    print(f"  Spot {r['spot_move_pct']:+.0%}: P&L ${r['portfolio_pnl']:+.2f}")
```

---

## Cost Tracking

The `HedgeCostTracker` tracks cumulative rebalancing costs:

```python
tracker = hz.HedgeCostTracker()
tracker.record_trade(notional=10000, commission=0, slippage=5.0)
print(f"Total cost: ${tracker.total_cost():.2f}")
print(f"Cost %: {tracker.cost_as_pct_of_notional():.4f}%")
print(f"Avg per rebalance: ${tracker.avg_cost_per_rebalance():.2f}")
```

---

## Examples

### Basic Hedge Ratio Calculation

```python
import horizon as hz

# Historical price data
spot_prices = [0.55, 0.56, 0.57, 0.58, 0.57, 0.59, 0.60, 0.61, 0.62]
tlt_prices = [95.0, 95.5, 96.0, 96.5, 96.2, 97.0, 97.5, 98.0, 98.5]

h = hz.hedge_ratio_ols(spot_prices, tlt_prices, window=8)
print(f"Hedge ratio: {h:.4f}")

# How effective is this hedge?
spot_returns = [(b - a) / a for a, b in zip(spot_prices, spot_prices[1:])]
tlt_returns = [(b - a) / a for a, b in zip(tlt_prices, tlt_prices[1:])]

he = hz.hedge_effectiveness(spot_returns, tlt_returns, h)
print(f"Effectiveness: {he:.2%}")
```

### Multi-Ticker Portfolio Hedge

```python
import horizon as hz

# Find optimal hedge weights across three instruments
result = hz.multi_ticker_hedge(
    spot_returns=fed_returns,
    hedge_returns_matrix=[tlt_returns, spy_returns, gld_returns],
    tickers=["TLT", "SPY", "GLD"],
)

print("Optimal weights:")
for ticker, weight in zip(result.tickers, result.weights):
    print(f"  {ticker}: {weight:.4f}")
print(f"Hedge effectiveness: {result.hedge_effectiveness:.4f}")
print(f"Tracking error: {result.tracking_error:.4f}")
```

### Scenario Analysis

```python
import horizon as hz

# What happens under different spot moves?
results = hz.run_scenario(
    spot_position=1000,
    spot_price=0.60,
    hedge_position=-50,
    hedge_price=96.0,
    spot_moves=[-0.20, -0.10, -0.05, 0.0, 0.05, 0.10, 0.20],
    correlation=0.75,
)

print("Scenario Analysis:")
for s in results:
    print(f"  Spot {s['spot_move_pct']:+.0%}: "
          f"Portfolio ${s['portfolio_pnl']:+.2f}, "
          f"Unhedged ${s['unhedged_pnl']:+.2f}, "
          f"Benefit ${s['hedge_benefit']:+.2f}")
```

### Hedged Pipeline Strategy

```python
import horizon as hz

def my_strategy(ctx):
    """Market-make on the prediction market while hedged."""
    if ctx.feeds.get("fed_rate") is None:
        return []
    fair = ctx.feeds["fed_rate"].price
    if fair <= 0:
        return []
    return hz.quotes(fair=fair, spread=0.04, size=10)

hz.run(
    name="hedged_mm",
    exchange=[hz.Polymarket(), hz.Alpaca(paper=True)],
    feeds={
        "fed_rate": hz.PolymarketBook("will-fed-cut-rates"),
        "tlt": hz.AlpacaFeed(symbols=["TLT"]),
    },
    pipeline=[
        hz.stock_hedge(hz.HedgeConfig(
            prediction_feed="fed_rate",
            stock_feed="tlt",
            stock_symbol="TLT",
            window=60,
            rebalance_threshold=0.05,
            auto_rebalance=False,
        )),
        my_strategy,
    ],
)
```

---

## Mathematical Background

<AccordionGroup>
  <Accordion title="Minimum-Variance Hedge Ratio">
    The OLS hedge ratio minimizes the variance of the hedged portfolio:

    **h* = Cov(dS, dF) / Var(dF)**

    Where dS and dF are log returns of the spot and hedge instruments. This is the slope from regressing spot returns on hedge returns. The ratio is recomputed over a rolling window so it adjusts as correlations shift.
  </Accordion>
  <Accordion title="Hedge Effectiveness">
    Hedge effectiveness measures how much variance the hedge removes:

    **HE = 1 − Var(hedged) / Var(unhedged)**

    Where hedged return = spot return − h × hedge return. Values near 1.0 mean the hedge is working well. Values below 0.5 mean the hedge instrument is a poor match for the spot position.
  </Accordion>
  <Accordion title="Multi-Ticker Optimization">
    For multiple hedge instruments, the weight vector is:

    **w = Σ_FF⁻¹ × Σ_FS**

    Where Σ_FF is the covariance matrix of hedge returns and Σ_FS is the cross-covariance vector between hedge and spot returns. Solved via Cholesky decomposition, with fallback to diagonal solve when the matrix is near-singular.
  </Accordion>
  <Accordion title="Scenario Analysis Model">
    P&L under a hypothetical spot move:

   - **Spot P&L** = position × price × move
   - **Hedge move** = correlation × (spot_vol / hedge_vol) × spot_move
   - **Hedge P&L** = hedge_position × hedge_price × hedge_move
   - **Portfolio P&L** = Spot P&L + Hedge P&L
   - **Hedge benefit** = Portfolio P&L − Unhedged P&L

    The hedge response is scaled by the volatility ratio since prediction markets and equities move on different scales.
  </Accordion>
</AccordionGroup>

<Warning>
  Hedge ratios are estimated from historical data and can shift quickly. A hedge that worked in calm markets may not hold up during a selloff. Monitor `hedge_effectiveness` and `hedge_decay` in production, and use `hz.correlation_tracker()` to catch correlation changes early.
</Warning>
