Files
fxhnt/tests/unit/test_forward_recompute.py
2026-07-09 00:02:20 +02:00

42 lines
1.6 KiB
Python

import numpy as np
from fxhnt.application.forward_recompute import derive_nav, recompute_series
class _FakeStrategy:
def __init__(self, series):
self._series = series
def advance(self, last_date, extra):
return list(self._series), extra
def test_recompute_filters_to_since_t0():
strat = _FakeStrategy([("2026-07-06", 0.01), ("2026-07-07", 0.02), ("2026-07-08", -0.01)])
assert recompute_series(strat, "2026-07-07") == [("2026-07-07", 0.02), ("2026-07-08", -0.01)]
def test_recompute_is_deterministic():
strat = _FakeStrategy([("2026-07-07", 0.02), ("2026-07-06", 0.01)]) # unsorted input
a = recompute_series(strat, "2026-07-01")
b = recompute_series(strat, "2026-07-01")
assert a == b == [("2026-07-06", 0.01), ("2026-07-07", 0.02)] # sorted, both runs identical
def test_derive_nav_matches_forward_tracker_formula():
rows = [("2026-07-06", 0.01), ("2026-07-07", 0.02), ("2026-07-08", -0.01)]
nav_rows, summary = derive_nav(rows)
# nav compounds
assert abs(nav_rows[-1][1] - (1.01 * 1.02 * 0.99)) < 1e-12
assert summary["days"] == 3
assert abs(summary["nav"] - 1.01 * 1.02 * 0.99) < 1e-12
# sharpe uses per_period_sharpe * sqrt(365) for >=3 rows
from fxhnt.domain.gauntlet import per_period_sharpe
exp = float(per_period_sharpe(np.array([0.01, 0.02, -0.01])) * np.sqrt(365.0))
assert abs(summary["sharpe"] - exp) < 1e-9
def test_derive_nav_empty_is_wait_safe():
nav_rows, summary = derive_nav([])
assert nav_rows == [] and summary["days"] == 0 and summary["nav"] == 1.0 and summary["last_date"] is None