Documentation Index
Fetch the complete documentation index at: https://mathematicalcompany.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
A market maker that uses a Hidden Markov Model to detect market regimes and adapts its quoting strategy: tight spreads in calm markets, wide spreads in volatile markets, and no quotes during crises.
Full Code
"""Regime-adaptive market maker using HMM regime detection."""
import horizon as hz
from horizon.context import FeedData
# Markov regime detector: 3 states (calm, volatile, crisis)
regime = hz.markov_regime(
feed_name="polymarket",
n_states=3,
lookback=100,
labels=["calm", "volatile", "crisis"],
)
def quoter(ctx: hz.Context, fair: float) -> list[hz.Quote]:
"""Adjust spread and size based on detected regime."""
current_regime = ctx.params.get("regime_label", "calm")
regime_probs = ctx.params.get("regime_probabilities", [1.0, 0.0, 0.0])
if current_regime == "calm":
# Tight spread, large size - capture spread in quiet markets
spread = 0.02
size = 15.0
elif current_regime == "volatile":
# Wide spread, small size - compensate for adverse selection
spread = 0.06
size = 5.0
else:
# Crisis: don't quote at all
print(f" Crisis regime detected (prob={regime_probs[2]:.2f}), pausing quotes")
return []
print(f" Regime: {current_regime} | probs={[f'{p:.2f}' for p in regime_probs]} | spread={spread}")
return hz.quotes(fair, spread, size=size)
hz.run(
name="regime_adaptive_mm",
markets=["election-winner"],
feeds={
"polymarket": hz.PolymarketBook("election-winner"),
},
pipeline=[regime, quoter],
risk=hz.Risk(max_position=100, max_drawdown_pct=5),
interval=1.0,
mode="paper",
)
How It Works
markov_regime() fits an HMM to recent price returns from the feed
- Each cycle, it classifies the market into one of 3 states and stores the label + probabilities in
ctx.params
- The quoter reads the regime and adjusts:
- Calm - tight 2-cent spread, 15 contracts (maximize fill rate)
- Volatile - wide 6-cent spread, 5 contracts (reduce adverse selection)
- Crisis - no quotes (preserve capital)
- Regime probabilities provide confidence: if the model is 90% sure it’s calm, you can trust the tight spread
Standalone HMM
You can also use the Rust HMM directly for research:
import horizon as hz
# Convert prices to log returns
prices = [0.50, 0.51, 0.49, 0.52, 0.48, 0.53, 0.47, 0.55, 0.45, 0.50]
returns = hz.prices_to_returns(prices)
# Fit a 3-state HMM
model = hz.MarkovRegimeModel(n_states=3)
model.fit(returns, max_iter=100)
# Predict current regime
state = model.predict(returns)
probs = model.state_probabilities(returns)
print(f"Current state: {state}")
print(f"State probabilities: {[f'{p:.3f}' for p in probs]}")
print(f"Transition matrix:")
for row in model.transition_matrix():
print(f" {[f'{x:.3f}' for x in row]}")
Run It
python examples/regime_adaptive_strategy.py
Extending
Combine regime detection with inventory skew for a more robust strategy:
hz.run(
name="regime_skew_mm",
markets=["btc-100k"],
feeds={
"polymarket": hz.PolymarketBook("btc-100k"),
},
pipeline=[
regime,
hz.inventory_skewer(gamma=0.15),
quoter,
],
risk=hz.Risk(max_position=100, max_drawdown_pct=5),
interval=1.0,
mode="paper",
)
See Markov Regime Detection for the full HMM reference.