Compare Strategies

Test multiple strategies on the same data and pick the winner

hz.quick.compare() runs multiple strategies on identical data and returns a ranked comparison.

Basic comparison

python
import horizon as hz

report = hz.quick.compare(
    strategies=["mean_reversion", "momentum", "ma_cross", "rsi"],
    tickers=["AAPL", "MSFT", "NVDA", "GOOGL", "AMZN"],
)

print(report.summary())

Each strategy gets the same tickers, same bars, same seed, same sizer, same risk. The only variable is the strategy logic.

Reading results

python
# Summary table
print(report.summary())

# Best strategy by Sharpe
print(f"Winner: {report.best}")

# Access individual results
for name, result in report.results.items():
    print(f"{name}: Sharpe={result.sharpe:+.3f}, DD={result.max_drawdown:.2%}")

Compare your own strategy vs built-ins

Pass a mix of built-in names and Strategy instances:

python
from horizon import Strategy, Signal
from horizon.asset_classes import Equity
from horizon.features import Zscore

class MyCustom(Strategy):
    name = "my_custom"
    asset_classes = [Equity]
    features = {"z": Zscore(10)}
    def evaluate(self, f, universe):
        return [Signal.from_score(m, score=-f.z[m.id], edge_per_stdev=25, horizon="2d")
                for m in universe if abs(f.z[m.id]) > 1.5]

report = hz.quick.compare(
    strategies=["mean_reversion", "momentum", MyCustom()],
    tickers=["AAPL", "MSFT"],
    bars=300,
)
print(report.summary())

Customizing the comparison

python
report = hz.quick.compare(
    strategies=["mean_reversion", "momentum"],
    tickers=["AAPL", "MSFT", "NVDA"],
    bars=500,
    cash=200_000,
    sizer="carver",          # use Carver vol-targeting instead of Kelly
    risk="conservative",     # tighter risk
    seed=7,                  # different random path
)

Next