Files
TradingBot-NewBot/engine/optimizer.py
T

63 lines
1.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Grid-search optimizer.
Iterates over a parameter grid, re-instantiates the strategy for each
combination, runs the backtest on the in-sample slice, and ranks by a
composite score (Sharpe × expectancy × return).
"""
from __future__ import annotations
import itertools
from dataclasses import dataclass
from typing import Any, Type
import numpy as np
import pandas as pd
from .backtest import BacktestEngine
from .metrics import Metrics, compute
@dataclass
class OptResult:
params: dict[str, Any]
metrics: Metrics
score: float
def grid_search(
StrategyClass: Type,
param_grid: dict[str, list],
df: pd.DataFrame,
engine: BacktestEngine,
*,
verbose: bool = False,
) -> list[OptResult]:
"""
Run every combination of parameters in `param_grid`.
Returns results sorted best-first by composite score.
"""
keys = list(param_grid.keys())
values = list(param_grid.values())
combos = list(itertools.product(*values))
results: list[OptResult] = []
for idx, combo in enumerate(combos):
params = dict(zip(keys, combo))
strategy = StrategyClass(**params)
trades, equity = engine.run(df, strategy)
m = compute(trades, equity, engine.initial_balance)
s = m.score()
results.append(OptResult(params=params, metrics=m, score=s))
if verbose and (idx + 1) % 50 == 0:
print(f" [{idx+1}/{len(combos)}] best so far: "
f"{max(results, key=lambda r: r.score).score:.4f}")
results.sort(key=lambda r: r.score, reverse=True)
return results