---
title: "Fund Portfolio Manager"
description: "Fund-level NAV tracking, capital allocation, drawdown management, and accounting."
---

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

```python
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.

```python
# 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 |

```python
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.

```python
# 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.

```python
# 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) |

## MCP Tools

| 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 |
