---
title: "Quant Flow"
description: "Institutional-grade decision loop: regime detection, alpha modeling, hypothesis testing, signal ensemble, portfolio optimization, and performance attribution."
---

The Quant Flow upgrades the autonomous decision loop from simple heuristics to an quantitative pipeline. Ten modules replace hardcoded edge estimation with factor-based alpha modeling, formal hypothesis lifecycle management, regime-aware strategy selection, and constraint-aware portfolio optimization.

## Architecture

The quant flow wraps Rust primitives (`MarkovRegimeModel`, `VpinDetector`, `prediction_greeks`, `cornish_fisher_var`, etc.) into a cohesive pipeline that runs inside the oversight loop.

```
NAV Returns
    |
    v
RegimeDetector -----> ResearchIntelligence (triggers)
    |                         |
    v                         v
AlphaModel -----> SignalEnsemble -----> HypothesisManager
    |                                        |
    v                                        v
RiskAnalytics                          Autopilot (deploy)
    |                                        |
    v                                        v
PortfolioOptimizer              AlphaDecayTracker (retire)
    |
    v
PerformanceAttribution
```

## Regime Detection

Classifies fund-level market regime using a 3-state Hidden Markov Model (calm/volatile/crisis) with trend and mean-reversion overlays.

```python
from horizon.fund import RegimeDetector

detector = RegimeDetector()
snap = detector.update(nav_returns)
# snap.regime: "trending_up", "trending_down", "mean_reverting", "volatile", "quiet"
# snap.confidence: 0.0-1.0
# snap.volatility, snap.trend_strength, snap.mean_reversion_score
```

Regime transitions trigger research events. The research pipeline filters strategy types by regime: trending regimes favor directional strategies, quiet/mean-reverting regimes favor market-making.

| Regime | Strategy Preference | Position Scale |
|---|---|---|
| `quiet` | Market-making | 1.0x |
| `trending_up` / `trending_down` | Directional | 1.0x |
| `mean_reverting` | Market-making | 1.0x |
| `volatile` | Reduced exposure | 0.7x |
| `crisis` | Minimal exposure | 0.5x |

## Multi-Factor Alpha Model

Replaces the naive `edge = 0.05 * fitness` with a 7-factor model that self-calibrates using information coefficients (IC).

```python
from horizon.fund import AlphaModel

model = AlphaModel()
estimate = model.estimate_alpha(
    market_id="will-x-win",
    price=0.55,
    volume_24h=50_000,
    median_volume=30_000,
    days_to_expiry=14,
    current_spread=0.03,
    avg_spread=0.05,
)
# estimate.composite_alpha: weighted factor combination
# estimate.confidence: based on IC significance
# estimate.factor_values: per-factor breakdown
```

### Prediction Market Factors

| Factor | Signal | Computation |
|---|---|---|
| **Liquidity** | Volume ratio | `tanh(volume_24h / median_volume - 1)` |
| **Momentum** | Price trend | `tanh(price_change * 10)` |
| **Mean-reversion** | Distance from 0.5 | `1 - abs(price - 0.5) * 2` |
| **Event proximity** | Time to expiry | `1 / (1 + days_to_expiry)` |
| **Spread** | Spread vs. average | `tanh((avg - current) / avg)` |
| **Cross-market** | Exchange divergence | Price difference, clamped |
| **Entropy** | Uncertainty | `shannon_entropy(price)`, normalized |

Factor weights are proportional to IC_IR (mean IC / std IC). Factors with negative IC get sign-flipped. The model reweights automatically as outcomes are recorded.

```python
# Wire into research pipeline
research.set_edge_estimator(model.as_edge_estimator())

# Record outcomes for IC updating
model.record_outcome("will-x-win", 1.0)  # resolved YES
model.update_ics()  # recompute weights

# Inspect factor quality
for f in model.factor_report():
    print(f"  {f.name}: IC={f.ic:.3f} IR={f.ic_ir:.3f} sig={f.is_significant}")
```

## Hypothesis Framework

Tracks trading ideas through a formal lifecycle with Bayesian updating and statistical validation.

```python
from horizon.fund import HypothesisManager, HypothesisState

mgr = HypothesisManager()

# Form a hypothesis
hyp = mgr.form(
    market_id="will-x-win",
    statement="Market underprices YES due to recency bias",
    direction="yes",
    edge=0.08,
    confidence=0.6,
    source="alpha_model",
)

# Update with evidence (Bayesian posterior update)
hyp = mgr.update_evidence(hyp.hypothesis_id, observed_return=0.02)
# confidence moves toward 1.0 when evidence aligns with direction

# Validate with backtest results
hyp = mgr.validate(
    hyp.hypothesis_id,
    backtest_sharpe=1.5,
    p_value=0.02,
    walk_forward_pct=0.7,
)
# State: FORMED -> VALIDATED (if criteria met)
# Uses deflated Sharpe with multiple-testing correction
```

### Hypothesis Lifecycle

```
FORMED -> BACKTESTING -> VALIDATED -> MONITORING -> DECAYING -> RETIRED
                 |                                       |
                 +-----> stays FORMED (retry)      INVALIDATED
```

Competing hypotheses for the same market are tracked. The best hypothesis (highest `confidence * edge`) wins deployment priority. SQLite persistence survives restarts.

## Signal Ensemble

Combines multiple signal sources with IC-weighted blending and redundancy detection.

```python
from horizon.fund import SignalEnsemble, Signal
import time

ensemble = SignalEnsemble(min_signals=2)

# Submit signals from different sources
ensemble.submit(Signal(
    name="alpha_model", value=0.3, confidence=0.7,
    timestamp=time.time(), source="factors", market_id="will-x-win",
))
ensemble.submit(Signal(
    name="regime", value=0.5, confidence=0.8,
    timestamp=time.time(), source="hmm", market_id="will-x-win",
))

# Combine with redundancy penalty
output = ensemble.combine("will-x-win")
# output.combined_signal: IC-weighted average
# output.combined_confidence: adjusted for redundancy
# output.weights_used: {"alpha_model": 0.55, "regime": 0.45}
# output.redundancy_penalty: max pairwise correlation
```

Signals with correlation > 0.7 are penalized to avoid double-counting. IC and hit rate are tracked per signal for dynamic reweighting.

## Research Intelligence

Event-driven research triggers replace purely timer-based scanning.

```python
from horizon.fund import ResearchIntelligence

intel = ResearchIntelligence()

# Events fire triggers with priorities
intel.on_regime_change("quiet", "volatile")     # priority 1
intel.on_volume_spike("market-a", 100_000, 30_000)  # priority 2
intel.on_new_market("new-market-slug")           # priority 3

# Cross-market divergence detection
intel.register_pair("poly-btc-100k", "kalshi-btc-100k")
intel.update_prices({"poly-btc-100k": 0.45, "kalshi-btc-100k": 0.52})
# Emits cross_market_divergence trigger if divergence > threshold

# Consume highest-priority triggers
triggers = intel.consume_triggers(max_count=5)
for t in triggers:
    print(f"  [{t.priority}] {t.trigger_type}: {t.market_id}")
```

Attribution chains track which triggers led to profitable deployments, allowing the system to prioritize trigger types that generate alpha.

## Portfolio Optimization

Constraint-aware optimizer that replaces simple equal-weight allocation.

```python
from horizon.fund import PortfolioOptimizer, OptimizationConstraints

optimizer = PortfolioOptimizer(
    constraints=OptimizationConstraints(
        max_per_market=0.10,    # 10% max per market
        max_per_exchange=0.40,  # 40% max per exchange
        max_turnover=0.20,      # 20% max turnover per rebalance
        max_positions=50,
    ),
    total_capital=100_000,
)

result = optimizer.optimize(
    strategy_names=["mm_btc", "dir_eth", "mm_politics"],
    probs=[0.6, 0.7, 0.55],   # estimated probabilities
    prices=[0.5, 0.5, 0.5],   # current market prices
)
# result.target_weights: {"mm_btc": 35000, "dir_eth": 40000, "mm_politics": 25000}
# result.expected_return, result.expected_risk
# result.turnover, result.violations
```

Uses Kelly-based expected returns + Ledoit-Wolf shrinkage covariance + projected gradient descent with constraint projection. Drift-based rebalancing replaces time-only rebalancing.

Enable in FundConfig:

```python
config = FundConfig(
    total_capital=100_000,
    optimization_enabled=True,  # Use PortfolioOptimizer instead of CapitalAllocator
)
```

## Risk Analytics

Regime-conditional risk limits, Cornish-Fisher tail risk, and portfolio Greeks.

```python
from horizon.fund import RiskAnalytics

risk = RiskAnalytics()

# Regime-conditional limits
limits = risk.dynamic_limits("volatile")
# limits.position_scale: 0.7 (reduce exposure)
# limits.var_limit: tighter
# limits.spread_multiplier: 1.3 (widen spreads)

# Tail risk with Cornish-Fisher adjustment
report = risk.tail_risk(returns)
# report.cf_var, report.cf_cvar: adjusts for skewness and kurtosis
# report.historical_var, report.historical_cvar: empirical percentile
# report.skewness, report.kurtosis, report.tail_ratio

# Portfolio Greeks (prediction market positions)
greeks = risk.portfolio_greeks([
    {"strategy_name": "mm_btc", "price": 0.55, "size": 100, "is_yes": True},
    {"strategy_name": "dir_eth", "price": 0.70, "size": 50, "is_yes": True},
])
# greeks.total_delta, greeks.total_gamma, greeks.total_theta, greeks.total_vega
# greeks.per_strategy: breakdown by strategy
```

Enable regime-conditional risk in FundConfig:

```python
config = FundConfig(
    regime_risk_enabled=True,   # Dynamic position limits based on HMM regime
)
```

## Alpha Decay Tracking

Monitors edge erosion and predicts when strategies should be retired.

```python
from horizon.fund import AlphaDecayTracker

tracker = AlphaDecayTracker()

# Record edge observations over time
tracker.record_edge("mm_btc", 0.08, timestamp=t0)
tracker.record_edge("mm_btc", 0.06, timestamp=t1)
tracker.record_edge("mm_btc", 0.04, timestamp=t2)

# Fit exponential decay
profile = tracker.fit_decay("mm_btc")
# profile.half_life_days: estimated time to lose half the edge
# profile.predicted_zero_crossing: when edge drops below 0.005
# profile.edge_type: "structural", "temporary", or "unknown"
# profile.r_squared: fit quality

# Check if strategy should be retired
if tracker.should_retire("mm_btc", min_edge=0.01):
    fund.remove_strategy("mm_btc")

# Automated alerts
for alert in tracker.check_alerts():
    print(f"  {alert.alert_type}: {alert.strategy_name} - {alert.message}")
```

The autopilot uses decay tracking to auto-retire strategies whose edge has decayed below threshold.

## Execution Intelligence

VPIN toxicity detection, inventory risk management, and execution scheduling.

```python
from horizon.fund import ExecutionIntelligence

exec_intel = ExecutionIntelligence(vpin_threshold=0.7)

# Per-market toxicity monitoring
alert = exec_intel.update_toxicity("btc-100k", price=0.55, volume=500, is_buy=True)
if alert:
    # alert.recommended_action: "widen_spread", "reduce_size", or "halt_trading"
    print(f"VPIN={alert.vpin:.2f} -> {alert.recommended_action}")

# Inventory risk for market-making
report = exec_intel.inventory_risk(
    market_id="btc-100k",
    mid_price=0.55,
    net_inventory=200,
    volatility=0.15,
)
# report.reservation_price: inventory-adjusted fair value
# report.optimal_spread: Avellaneda-Stoikov optimal spread
# report.recommended_bid, report.recommended_ask

# Execution scheduling
schedule = exec_intel.schedule_execution(
    market_id="btc-100k",
    total_size=1000,
    urgency=0.3,     # patient
    depth=5000,
)
# schedule.method: "twap"
# schedule.slice_sizes, schedule.interval_secs
```

VPIN alerts feed into the adaptive execution tuner as Rule 5 (toxicity-driven spread widening).

## Performance Attribution

Fund-level alpha/beta decomposition, strategy contribution, and cost analysis.

```python
from horizon.fund import PerformanceAttribution

attr = PerformanceAttribution()

# Feed returns each cycle
attr.update(portfolio_return=0.002, benchmark_return=0.001)

# Compute decomposition
snap = attr.compute()
# snap.alpha_beta.alpha: excess return above benchmark
# snap.alpha_beta.beta: market sensitivity
# snap.alpha_beta.information_ratio: alpha / tracking error

# Per-strategy contribution
for s in snap.strategy_attributions:
    print(f"  {s.strategy_name}: contribution={s.contribution:.1%} sharpe={s.sharpe:.2f}")

# Cost breakdown
cost = snap.cost
# cost.spread_cost, cost.slippage_cost, cost.fee_cost, cost.cost_pct
```

## Oversight Loop Integration

All 10 modules are wired into the FundManager oversight loop automatically:

| Tick | Step | Module |
|---|---|---|
| Every | 7b | `RegimeDetector.update()` -- regime transitions fire research triggers |
| Every | 8c | `RiskAnalytics.dynamic_limits()` -- regime-conditional position limits |
| 5 | 8d | `RiskAnalytics.portfolio_greeks()` -- fund-level Greeks snapshot |
| Every | 9b | `ExecutionIntelligence.update_toxicity()` -- per-market VPIN |
| N | 10 | `PortfolioOptimizer.optimize()` -- replaces allocator when enabled |
| N | 13 | `AlphaModel` + `HypothesisManager` + `AlphaDecayTracker` -- enhanced research-to-deploy |
| 60 | 14b | `AlphaDecayTracker.check_alerts()` + `HypothesisManager.check_decay()` |
| Every | 18 | `ResearchIntelligence.consume_triggers()` -- event-driven research |
| 60 | 19 | `PerformanceAttribution.compute()` -- attribution snapshot |

## Configuration

Three new fields on `FundConfig` control the quant flow:

```python
from horizon.fund import FundConfig

config = FundConfig(
    total_capital=500_000,
    optimization_enabled=True,         # Use PortfolioOptimizer (default: False)
    regime_risk_enabled=True,          # Regime-conditional risk limits (default: False)
    attribution_interval_ticks=60,     # Attribution snapshot frequency (default: 60)
)
```

The quant modules are always instantiated and available via properties (`fund.regime_detector`, `fund.alpha_model`, etc.) even when `optimization_enabled` and `regime_risk_enabled` are False. The flags only control whether they replace the defaults in the oversight loop.

## Rust Primitives Used

| Python Module | Rust Functions |
|---|---|
| `RegimeDetector` | `MarkovRegimeModel` (3-state HMM) |
| `AlphaModel` | `information_coefficient`, `edge`, `shannon_entropy` |
| `AlphaDecayTracker` | `signal_half_life` |
| `HypothesisManager` | `deflated_sharpe`, `benjamini_hochberg` |
| `SignalEnsemble` | `combine_signals`, `information_coefficient`, `signal_half_life` |
| `PortfolioOptimizer` | `multi_kelly`, `ledoit_wolf_shrinkage` |
| `RiskAnalytics` | `cornish_fisher_var`, `cornish_fisher_cvar`, `prediction_greeks` |
| `ExecutionIntelligence` | `VpinDetector`, `OfiTracker`, `reservation_price`, `optimal_spread`, `mm_size` |
