Skip to main content
Ultra Feature. Requires an Ultra subscription. Get started at api.mathematicalcompany.com

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

OLS Hedge Ratio

hz.hedge_ratio_ols() computes the hedge ratio from rolling price windows.

Effectiveness & Basis Risk

hz.hedge_effectiveness() and hz.basis_risk() measure how well the hedge is working.

Multi-Ticker Optimization

hz.multi_ticker_hedge() finds weights across multiple hedge instruments.

Scenario Analysis

hz.hedge_scenario() shows portfolio P&L under different spot moves.

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).
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}")
ParameterTypeDefaultDescription
spot_priceslist[float]requiredPrediction market price series
hedge_priceslist[float]requiredStock/ETF price series
windowint60Rolling 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.
corr = hz.rolling_correlation(spot_prices, stock_prices, window=30)
print(f"Current correlation: {corr[-1]:.4f}")
ParameterTypeDefaultDescription
series_alist[float]requiredFirst price series
series_blist[float]requiredSecond price series
windowint60Rolling 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.
he = hz.hedge_effectiveness(spot_returns, hedge_returns, hedge_ratio=0.5)
print(f"Effectiveness: {he:.4f}")  # 0.82 means 82% variance reduction
ParameterTypeDescription
spot_returnslist[float]Spot instrument return series
hedge_returnslist[float]Hedge instrument return series
hedge_ratiofloatHedge 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.
br = hz.basis_risk(spot_returns, hedge_returns, hedge_ratio=0.5)
print(f"Basis risk: {br:.6f}")
ParameterTypeDescription
spot_returnslist[float]Spot instrument return series
hedge_returnslist[float]Hedge instrument return series
hedge_ratiofloatHedge ratio

hz.optimal_hedge_size

Calculate optimal hedge notional with optional cap.
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
ParameterTypeDefaultDescription
spot_notionalfloatrequiredNotional value of the spot position
hedge_ratiofloatrequiredHedge ratio
max_hedge_notionalfloatinfMaximum hedge notional cap

hz.compute_hedge_sensitivities

Returns a HedgeSensitivities object with risk metrics.
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}")
FieldDescription
deltadV/dS via finite differences
cross_gammad²V/dSdF cross-gamma
betaOLS beta of hedge on spot
tracking_errorAnnualized std(residuals) × √252
hedge_decayDrift of recent hedge ratio from full-window ratio

hz.multi_ticker_hedge

Multi-instrument hedge optimization. Returns a MultiHedgeResult.
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}")
ParameterTypeDescription
spot_returnslist[float]Spot instrument return series
hedge_returns_matrixlist[list[float]]Return series for each hedge instrument
tickerslist[str]Ticker labels for each hedge instrument

hz.hedge_scenario

P&L projection under a given spot move.
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}")
ParameterTypeDefaultDescription
spot_positionfloatrequiredNumber of spot contracts
spot_pricefloatrequiredCurrent spot price
hedge_positionfloatrequiredNumber of hedge shares (negative = short)
hedge_pricefloatrequiredCurrent hedge instrument price
spot_move_pctfloatrequiredSpot move as decimal (e.g., -0.10 for -10%)
correlationfloat0.75Assumed correlation between spot and hedge
hedge_volfloat0.20Annualized hedge volatility
spot_volfloat0.30Annualized 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.
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],
)
ParameterTypeDefaultDescription
prediction_feedstrrequiredFeed name for the prediction market
stock_feedstrrequiredFeed name for the hedge instrument
windowint60Rolling window for calculations
Returns on each cycle:
{
    "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.
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.
tracker = hz.correlation_tracker(["fed_rate", "tlt", "spy"], window=30)
# Returns: {"correlations": {"fed_rate/tlt": 0.78, ...}, "top_pairs": [...]}
ParameterTypeDefaultDescription
feedslist[str]requiredFeed names to track
windowint60Rolling correlation window

hz.stock_hedge

Combines hedge_monitor + hedge_executor. Use this if you want both in one call.
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.
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}")
ParameterTypeDefaultDescription
spot_priceslist[float]requiredSpot price series
hedge_priceslist[float]requiredHedge price series
windowint60Rolling window
position_sizefloat1.0Position size for sensitivity calculation

hz.run_scenario

Run multiple scenarios at once:
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:
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

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

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

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

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

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.
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.
For multiple hedge instruments, the weight vector is:w = Σ_FF⁻¹ × Σ_FSWhere Σ_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.
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.
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.