EqualWeight
The baseline sizer: equal USD notional per signal
EqualWeight allocates equal USD notional to every signal, capped by max_positions. Hard to beat in backtests: always use it as your null hypothesis.
Import
python
from horizon.portfolio import EqualWeight
Signature
python
EqualWeight(
max_positions: int = 20,
gross_fraction_of_equity: float = 1.0,
)
max_positionsintMaximum number of concurrent positions. Signals are ranked by confidence; the top N are selected.
gross_fraction_of_equityfloatTotal gross exposure as a fraction of equity. `1.0` = full equity; `0.5` = 50% gross.
The math
gross_budget = max_gross_notional_usd (from constraints, or equity × gross_fraction_of_equity)
per_slot = gross_budget / min(len(selected), max_positions)
Each signal gets per_slot × direction.sign as its target notional.
Use it
python
import horizon as hz
from horizon.portfolio import EqualWeight
result = hz.run(
portfolio=EqualWeight(max_positions=10, gross_fraction_of_equity=0.8),
...
)
Why it’s the baseline
EqualWeight makes zero assumptions about edge estimates, vol, or correlation. If your fancy sizer doesn’t beat EqualWeight, your strategy doesn’t have real edge: the complexity is just overfitting.
Always compare your chosen sizer against EqualWeight:
python
r_complex = hz.run(portfolio=KellyOptimizer(...), ...)
r_baseline = hz.run(portfolio=EqualWeight(), ...)
if r_complex.sharpe < r_baseline.sharpe:
print("Your complex sizer is not worth it")
When to use
Null hypothesis Your first backtest should use EqualWeight to establish a baseline.
When you don't trust your edge estimates If `expected_edge_bps` is noisy, Kelly will size positions weirdly. EqualWeight ignores the noise.
Very small portfolios With 2-3 positions, sophisticated optimization doesn't help much. EqualWeight is fine.