---
title: "Full Tutorial"
description: "Step-by-step guide to running an autonomous prediction market fund with Horizon."
---

A complete walkthrough from installation to a running autonomous fund. By the end you will have a multi-strategy fund with risk controls, automated research, and monitoring.

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

## Step 1: Install

```bash
pip install horizon-sdk

# Verify
python -c "from horizon.fund import FundManager; print('Ready')"
```

## Step 2: Write Your Strategy

A strategy is a list of pipeline functions. Each function receives a `Context` with market data, positions, and parameters, and returns values that flow into the next function.

```python
"""my_fund.py"""

import math
import horizon as hz


def fair_value(ctx: hz.Context) -> float:
    """Estimate fair probability from the orderbook feed."""
    feed = ctx.feeds.get("book", hz.context.FeedData())
    mid = feed.price if feed.price > 0 else 0.50

    # Mean-reversion signal: fade extremes toward 0.50
    fair = mid + (0.50 - mid) * 0.3
    return max(0.05, min(0.95, fair))


def quoter(ctx: hz.Context, fair: float) -> list[hz.Quote]:
    """Quote both sides with Kelly sizing and inventory-adjusted spread."""
    inv = ctx.inventory.net if hasattr(ctx.inventory, "net") else 0.0
    spread = 0.04 + abs(inv) * 0.001

    size = hz.kelly(prob=fair, market_price=0.50, bankroll=10_000)
    size = max(1.0, min(20.0, size))

    return hz.quotes(fair, spread, size=size)


PIPELINE = [fair_value, quoter]
```

## Step 3: Configure the Fund

`FundConfig` sets fund-level capital, risk limits, fees, and timing.

```python
from horizon.fund import FundManager, FundConfig, StrategyConfig

fund = FundManager(FundConfig(
    total_capital=100_000,

    # Risk
    max_fund_drawdown_pct=15.0,
    max_strategy_drawdown_pct=25.0,
    max_correlation=0.85,

    # Timing
    rebalance_interval_secs=60.0,

    # Fees
    management_fee_bps=200,       # 2% annual
    performance_fee_pct=20.0,     # 20% of profits above HWM
))
```

## Step 4: Add Strategies

Each strategy gets its own engine with independent risk limits, feeds, and exchange connectivity.

```python
# Paper-mode market-making on political markets
fund.add_strategy(StrategyConfig(
    name="political_mm",
    pipeline=PIPELINE,
    markets=["will-x-win-2028", "will-y-pass"],
    mode="paper",
    max_drawdown_pct=20.0,
))

# Paper-mode directional on crypto predictions
fund.add_strategy(StrategyConfig(
    name="crypto_directional",
    pipeline=PIPELINE,
    markets=["btc-above-100k-june"],
    mode="paper",
    max_drawdown_pct=15.0,
))
```

To deploy on a live exchange, pass an exchange config and feeds:

```python
import os

fund.add_strategy(StrategyConfig(
    name="live_mm",
    pipeline=PIPELINE,
    markets=["will-x-win-2028"],
    exchange=hz.Polymarket(
        private_key=os.environ["POLYMARKET_PRIVATE_KEY"],
        api_key=os.environ.get("POLYMARKET_API_KEY"),
        api_secret=os.environ.get("POLYMARKET_API_SECRET"),
        api_passphrase=os.environ.get("POLYMARKET_API_PASSPHRASE"),
    ),
    feeds={"book": hz.PolymarketBook("will-x-win-2028")},
    mode="live",
))
```

## Step 5: Start the Fund

```python
fund.start()
```

This deploys all queued strategies and starts the background oversight loop. The loop runs every 60 seconds (configurable) and automatically handles:

- NAV computation and high-water mark tracking
- Fund-level drawdown checks and kill switch
- Strategy pause/resume on risk breaches
- Market settlement detection and cleanup
- Fee accrual
- Cross-strategy correlation alerts
- Adaptive execution tuning
- Research scanning for new opportunities

## Step 6: Check Fund Status

```python
status = fund.status()
print(f"NAV: ${status['nav']:,.2f}")
print(f"Drawdown: {status['drawdown_pct']:.1f}%")
print(f"Running strategies: {status['running_strategies']}")
print(f"Kill switch: {status['kill_switch']}")
```

For a detailed report:

```python
report = fund.report()
print(f"Total NAV: ${report.nav.total_nav:,.2f}")
print(f"Cash: ${report.nav.cash:,.2f}")
print(f"Unrealized PnL: ${report.nav.unrealized_pnl:,.2f}")

for s in report.strategies:
    print(f"  {s.name}: {s.state.value} pnl=${s.pnl:,.2f} dd={s.drawdown_pct:.1f}%")
```

## Step 7: Risk Dashboard

Get a consolidated risk view.

```python
dashboard = fund.risk_dashboard()
print(f"NAV: ${dashboard['nav']:,.2f}")
print(f"Drawdown: {dashboard['drawdown_pct']:.1f}%")
print(f"VaR usage: {dashboard['var_budget']['usage_pct']:.1f}%")
print(f"Kill switch: {dashboard['kill_switch']}")

for pair in dashboard['correlations']:
    print(f"  {pair['a']} / {pair['b']}: {pair['corr']:.3f}")
```

## Step 8: Stress Testing

Run predefined or custom stress scenarios against your current portfolio.

```python
from horizon.fund import FundScenario

# Built-in scenarios (10/20% drawdown, correlation spike, liquidity crisis, etc.)
result = fund.stress_test()
for r in result.results:
    print(f"  {r.scenario.name}: loss=${r.estimated_loss:,.0f} {'PASS' if r.passes else 'FAIL'}")

# Custom scenario
result = fund.stress_test(scenarios=[
    FundScenario(
        name="flash_crash",
        description="All positions drop 30%",
        price_shock=-0.30,
        vol_shock=3.0,
    ),
])
```

## Step 9: Manage Strategy Lifecycle

```python
# Pause a strategy (stops trading, keeps positions)
fund.pause_strategy("crypto_directional")

# Resume it
fund.resume_strategy("crypto_directional")

# Scale capital allocation
fund.scale_strategy("political_mm", 60_000)

# Remove entirely (stops + cleans up)
fund.remove_strategy("crypto_directional")
```

## Step 10: P&L Attribution

```python
attribution = fund.pnl_attribution()
for name, metrics in attribution.items():
    print(f"  {name}: realized=${metrics.get('realized_pnl', 0):,.2f} "
          f"unrealized=${metrics.get('unrealized_pnl', 0):,.2f}")
```

## Step 11: Query Fund Memory

The fund remembers outcomes across restarts via SQLite.

```python
# What strategies worked?
for entry in fund.memory.query(category="strategy_outcome", limit=5):
    print(f"  {entry.key}: {entry.value}")

# Past failures
for entry in fund.memory.past_failures(limit=5):
    print(f"  {entry.key}: {entry.value}")

# Memory stats
stats = fund.memory.stats()
print(f"Total entries: {stats['total_entries']}")
```

## Step 12: NAV History

```python
for snap in fund.nav_history(limit=10):
    print(f"  {snap.timestamp:.0f}: NAV=${snap.total_nav:,.2f} DD={snap.drawdown_pct:.1f}%")
```

## Step 13: Shut Down

```python
fund.stop()   # stops oversight loop + all strategies
fund.close()  # releases SQLite connections
```

## Step 14: LLM Integration via MCP

Run the fund as an MCP server so an LLM can manage it through tool calls.

```json
{
  "mcpServers": {
    "horizon-fund": {
      "command": "python",
      "args": ["-m", "horizon.mcp_fund"],
      "env": {
        "HORIZON_FUND_MODE": "1",
        "HORIZON_FUND_CAPITAL": "100000"
      }
    }
  }
}
```

The LLM can call tools like `deploy_strategy`, `fund_status`, `research_scan`, `stress_test`, and `retire_strategy`. All actions go through the Decision Framework which enforces confidence thresholds, rate limits, and operating mode restrictions.

For more on operating modes (dry-run, supervised, autonomous) see the [Overview](autonomous/overview).

---

## Complete Script

Everything above in a single runnable file:

```python
"""my_fund.py"""

import time
import horizon as hz
from horizon.fund import FundManager, FundConfig, StrategyConfig


# Pipeline
def fair_value(ctx: hz.Context) -> float:
    feed = ctx.feeds.get("book", hz.context.FeedData())
    mid = feed.price if feed.price > 0 else 0.50
    fair = mid + (0.50 - mid) * 0.3
    return max(0.05, min(0.95, fair))


def quoter(ctx: hz.Context, fair: float) -> list[hz.Quote]:
    spread = 0.04
    size = max(1.0, min(20.0, hz.kelly(
        prob=fair, market_price=0.50, bankroll=10_000,
    )))
    return hz.quotes(fair, spread, size=size)


# Fund setup
fund = FundManager(FundConfig(total_capital=100_000))

fund.add_strategy(StrategyConfig(
    name="mm_politics",
    pipeline=[fair_value, quoter],
    markets=["will-x-win-2028"],
    mode="paper",
))

fund.start()

try:
    while fund.is_running:
        s = fund.status()
        print(f"NAV=${s['nav']:,.0f} DD={s['drawdown_pct']:.1f}% "
              f"strategies={s['running_strategies']}")
        time.sleep(60)
except KeyboardInterrupt:
    pass
finally:
    fund.close()
    print("Fund stopped")
```

```bash
python my_fund.py
```

The oversight loop handles everything in the background: NAV tracking, risk monitoring, correlation alerts, settlement detection, fee accrual, research scanning, and adaptive execution tuning all run automatically while your strategies trade.
