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.
The Fund Portfolio Manager is the top-level layer that treats all strategies as a unified book. It tracks NAV, allocates capital, enforces fund-wide risk limits, and provides fund reporting.
Why It’s Needed
Individual strategies manage their own risk via RiskConfig, but a hedge fund needs:
- Unified NAV: what is the fund worth right now, across all strategies and exchanges?
- Capital allocation: how much capital should each strategy get?
- Fund-wide drawdown limits: if the fund is down 5% this month, reduce all exposure
- Cross-strategy awareness: two strategies might be making the same bet
Quick Start
from horizon.fund import FundManager, FundConfig, StrategyConfig
# Create the fund
fund = FundManager(FundConfig(
total_capital=100_000,
max_fund_drawdown_pct=15.0,
max_strategy_drawdown_pct=25.0,
))
# Add strategies
fund.add_strategy(StrategyConfig(
name="political_mm",
pipeline=[signal, quote],
markets=["will-x-win", "will-y-happen"],
mode="paper",
))
fund.add_strategy(StrategyConfig(
name="crypto_arb",
pipeline=[detect_arb, execute],
markets=["btc-100k"],
mode="paper",
))
# Start everything (deploys strategies + oversight loop)
fund.start()
# Check status
status = fund.status()
# {
# "running": True,
# "total_capital": 100000.0,
# "nav": 100250.0,
# "drawdown_pct": 0.0,
# "running_strategies": 2,
# "total_fees": 12.5,
# ...
# }
# Generate a full report
report = fund.report()
print(report.nav.total_nav)
print(report.strategies)
# Stop everything
fund.stop()
NAV Tracking
Real-time net asset value computed by aggregating across all strategy engines.
# NAV is computed each oversight cycle automatically
# You can also access it directly:
nav = fund.nav_engine.compute_nav(fund.controller.engines)
print(f"NAV: ${nav.total_nav:,.2f}")
print(f"Cash: ${nav.cash:,.2f}")
print(f"Positions: ${nav.positions_value:,.2f}")
print(f"Drawdown: {nav.drawdown_pct:.1f}%")
print(f"HWM: ${nav.high_water_mark:,.2f}")
# NAV history
history = fund.nav_history(limit=100)
for snap in history:
print(f" {snap.timestamp}: ${snap.total_nav:,.2f}")
NAV formula: NAV = initial_capital + sum(realized_pnl) + sum(unrealized_pnl) across all engines.
Capital Allocation
Multiple allocation methods:
| Method | Description |
|---|
| Equal weight | Split capital equally across strategies |
| Risk parity | Allocate inversely to each strategy’s volatility |
| Performance-weighted | More capital to higher-performing strategies |
| Custom | User-defined weights per strategy |
from horizon.fund import FundConfig, AllocationMethod
# Equal weight (default)
config = FundConfig(total_capital=100_000, allocation_method=AllocationMethod.EQUAL)
# Custom weights
config = FundConfig(
total_capital=100_000,
allocation_method=AllocationMethod.CUSTOM,
custom_weights={"political_mm": 0.6, "crypto_arb": 0.4},
)
# Dynamic weight updates
fund.allocator.set_custom_weight("political_mm", 0.7)
fund.allocator.set_custom_weight("crypto_arb", 0.3)
Fund Accounting
Fee tracking and P&L attribution per strategy.
# P&L attribution
attr = fund.pnl_attribution()
# {
# "political_mm": {"realized": 500.0, "unrealized": 150.0, "total": 650.0, "net": 640.0, "fees": 10.0},
# "crypto_arb": {"realized": 200.0, "unrealized": -50.0, "total": 150.0, "net": 145.0, "fees": 5.0},
# }
# Fee tracking
fund.accounting.record_fee(FeeType.EXCHANGE, 5.0, "political_mm")
print(f"Total fees: ${fund.accounting.total_fees():,.2f}")
print(f"Fees by strategy: {fund.accounting.fees_by_strategy()}")
# Management and performance fees are computed automatically
# during the oversight loop
Management fee: Annual fee accrued daily. Default 200 bps (2%).
Performance fee: Fee on profits above the high water mark. Default 20%.
Fund-Wide Risk
Automatic circuit breakers and risk alerts.
# Risk monitoring happens automatically in the oversight loop
# The FundRiskMonitor checks:
# 1. Fund-wide drawdown vs. limit -> activates kill switch
# 2. Per-strategy drawdown vs. limit -> pauses strategy
# 3. Multiple strategy failures -> alerts
# Manual override
fund.risk_monitor.reset_kill_switch()
fund.risk_monitor.clear_strategy_pause("political_mm")
# Check recent alerts
alerts = fund.risk_monitor.recent_alerts()
for alert in alerts:
print(f"[{alert.level}] {alert.message}")
| Trigger | Action |
|---|
| Fund drawdown >= limit | Kill switch: stop all strategies |
| Fund drawdown >= 80% of limit | Warning alert |
| Strategy drawdown >= limit | Pause that strategy |
| 3+ strategy failures | Critical alert |
Configuration Reference
| Parameter | Default | Description |
|---|
total_capital | 100,000 | Total fund capital in USD |
allocation_method | EQUAL | How to allocate capital |
custom_weights | Weights for CUSTOM method | |
max_strategies | 20 | Max concurrent strategies |
max_fund_drawdown_pct | 15.0 | Fund-wide drawdown limit |
max_strategy_drawdown_pct | 25.0 | Per-strategy drawdown limit |
max_correlation | 0.85 | Max pairwise correlation |
rebalance_interval_secs | 60.0 | Oversight loop interval |
management_fee_bps | 200 | Annual management fee (bps) |
performance_fee_pct | 20.0 | Performance fee (% of profits) |
| Tool | Description |
|---|
fund_status | NAV, returns, risk metrics, capital available |
allocate_capital | Move capital between strategies |
fund_report | Generate fund report |
fund_drawdown | Current drawdown metrics and limits |