FundCluster

Multi-fund orchestration with shared risk budgeting

FundCluster is v1’s multi-fund orchestrator. You register multiple sub-funds (each one is its own strategy portfolio with its own capital budget), and the cluster coordinates them. shared risk budget enforcement, cross-fund correlation checks, centralized promotion management.

Why multi-fund?

Running many strategies as a single fund has limits:

  • Correlation control: if all strategies are equity mean-reversion, they’re correlated
  • Attribution noise: it’s hard to know which strategy is driving returns
  • Independent risk budgets: a blowup in strategy A shouldn’t take down strategy B
  • Different timeframes: daily and intraday strategies want different risk controls

A FundCluster lets you keep strategies separate at the risk and attribution level while coordinating at the capital allocation level.

API

python
from horizon.fund._multi_fund import FundCluster, SubFund, FundAllocation

cluster = FundCluster(
    name="horizon_main",
    total_capital_usd=10_000_000,
    risk_budget_pct=0.30,            # max 30% of capital at risk
)

# Register sub-funds
cluster.add_fund(SubFund(
    name="equity_mr",
    capital_allocation=3_000_000,
    asset_classes=["equity"],
    strategies=[BollingerMeanRev(window=20), TSMomentum(lookback=20)],
    risk_budget=0.10,
))

cluster.add_fund(SubFund(
    name="options_vol",
    capital_allocation=2_000_000,
    asset_classes=["option"],
    strategies=[StraddleStrategy()],
    risk_budget=0.08,
))

# Run all funds
results = cluster.run_all(
    mode="backtest",
    data_sources={...},
    backtest=hz.BacktestConfig(...),
)

# Per-fund results
for fund_name, result in results.items():
    print(f"{fund_name}:")
    print(f"  Sharpe: {result.sharpe:+.3f}")
    print(f"  Drawdown: {result.max_drawdown:.2%}")

Risk budgeting

Each sub-fund gets an independent risk budget (drawdown limit). The cluster enforces:

  • Per-fund drawdown: if a fund hits its individual drawdown cap, it’s halted independently
  • Cluster drawdown: if total cluster drawdown exceeds cluster_risk_budget, all funds halt
  • Cross-fund correlation: if funds become too correlated (e.g., all hitting their stops at the same time), the cluster reduces overall exposure
python
cluster_risk = cluster.snapshot_risk()
print(f"Cluster drawdown: {cluster_risk.cluster_drawdown:.2%}")
print(f"Per-fund drawdowns:")
for fund_name, dd in cluster_risk.fund_drawdowns.items():
    print(f"  {fund_name}: {dd:.2%}")

if cluster_risk.cross_fund_correlation > 0.8:
    print("⚠️ Funds highly correlated. reducing total exposure")

Dynamic reallocation

FundCluster supports dynamic reallocation: moving capital from underperforming funds to outperforming ones based on rolling Sharpe:

python
allocation = cluster.suggest_reallocation(
    method="sharpe_weighted",     # or "ic_weighted", "equal_risk"
    lookback_days=60,
)

for fund_name, new_pct in allocation.items():
    print(f"{fund_name}: {new_pct:.0%} of total")

cluster.apply_allocation(allocation)

Available methods:

MethodDescription
sharpe_weightedHigher Sharpe → more capital
ic_weightedHigher realized IC → more capital
equal_riskScale by 1/vol so each fund contributes equal risk
fixedNo reallocation

Integration with Horizon

Use FundCluster as a top-level controller when you have multiple logically-distinct strategy books:

python
import horizon as hz
from horizon.fund._multi_fund import FundCluster, SubFund
from horizon.quant import BollingerMeanRev, TSMomentum

cluster = FundCluster(
    name="production",
    total_capital_usd=1_000_000,
)

cluster.add_fund(SubFund(
    name="us_equity_mr",
    capital_allocation=400_000,
    asset_classes=["equity"],
    strategies=[BollingerMeanRev(window=20)],
))

cluster.add_fund(SubFund(
    name="us_equity_mom",
    capital_allocation=400_000,
    asset_classes=["equity"],
    strategies=[TSMomentum(lookback=20)],
))

# Run all funds concurrently, each with its own budget
results = cluster.run_all(mode="paper", ...)

# Risk snapshot across the cluster
print(cluster.snapshot_risk())

When to use

Multi-PM setups When different strategies have different owners or investment mandates, giving each its own sub-fund provides clean accounting and attribution.
Style diversification Equity book + options book + crypto book + prediction market book, each in its own sub-fund with its own risk budget.
Capital rotation Dynamic reallocation moves capital to whatever book is working best, subject to correlation constraints.

Pitfalls

Source

python/horizon/fund/_multi_fund.py. ~500 lines.

Next