33 lines
1.4 KiB
Python
33 lines
1.4 KiB
Python
"""All six kinds register on package import and run end-to-end through the backtest engine."""
|
|
from __future__ import annotations
|
|
|
|
import numpy as np
|
|
|
|
from fxhnt.domain.models import AssetClass, Market, PriceSeries, StrategySpec
|
|
from fxhnt.domain.strategies import available, get_strategy
|
|
|
|
|
|
def test_available_lists_all_six_kinds() -> None:
|
|
assert available() == ["breakout", "buy_hold", "mean_reversion", "seasonality", "trend",
|
|
"vol_managed_momentum"]
|
|
|
|
|
|
def test_each_new_kind_has_a_rationale() -> None:
|
|
for kind in ("breakout", "seasonality", "vol_managed_momentum"):
|
|
strat = get_strategy(kind)
|
|
assert isinstance(strat.rationale, str) and strat.rationale.strip()
|
|
|
|
|
|
def test_new_kinds_run_end_to_end_through_backtest() -> None:
|
|
from fxhnt.domain.backtest import run_backtest
|
|
rng = np.random.default_rng(3)
|
|
n = 400
|
|
close = 100.0 * np.cumprod(1.0 + (0.0004 + rng.normal(0, 0.01, n)))
|
|
dates = tuple(f"{2016 + i // 252}-{(i % 12) + 1:02d}-{(i % 27) + 1:02d}" for i in range(n))
|
|
ps = PriceSeries(market=Market(symbol="ES", asset_class=AssetClass.FUTURE), dates=dates,
|
|
close=np.asarray(close, float))
|
|
for kind in ("breakout", "seasonality", "vol_managed_momentum"):
|
|
res = run_backtest(ps, StrategySpec(kind=kind, params={}))
|
|
assert np.isfinite(res.stats.sharpe)
|
|
assert len(res.returns) == n
|