Files
fxhnt/tests/unit/test_backtest_ref_alias.py
jgrusewski 02317a14ab fix(exec): skip recording on blocked rebalance; alias exec track's reconciliation ref to modeled multistrat (C1)
A blocked RebalancePlan places zero orders but the account keeps its prior positions, so
plan_and_record must not advance the multistrat_exec_pos basis or book a forward_record in that
case — otherwise every subsequent executed return is computed against a phantom target book that
was never placed. Also wires CockpitBacktestRefProvider to alias multistrat_exec -> multistrat so
the reconciliation gate actually reconciles the executed track against the modeled book's
basis-matched backtest reference, as the registry comment already (incorrectly) claimed. Plus a
doc comment clarifying positions_after is the intended target basis, and type-annotated locals in
compute_exec_return to keep the inferred return type float instead of Any.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 00:12:17 +02:00

43 lines
1.5 KiB
Python

"""C1: the EXECUTED multistrat track (`multistrat_exec`) has no `backtest_summary` row of its own — it must
alias to the MODELED multistrat's basis-matched reference (persisted under sid `multistrat`) so the
reconciliation gate can catch execution decay (spec §4)."""
from __future__ import annotations
from fxhnt.application.forward_ingest import CockpitBacktestRefProvider
class _FakeSummary:
def __init__(self, strategy_id: str, cagr: float) -> None:
self.strategy_id = strategy_id
self.cagr = cagr
class _FakeRepo:
def __init__(self, summaries: list[_FakeSummary]) -> None:
self._summaries = summaries
def all_backtest_summaries(self) -> list[_FakeSummary]:
return self._summaries
def test_multistrat_exec_aliases_to_modeled_multistrat_reference() -> None:
repo = _FakeRepo([_FakeSummary("multistrat", 0.20)])
provider = CockpitBacktestRefProvider(repo)
ref = provider.reference("multistrat_exec", 30)
assert ref is not None
expected = (1.0 + 0.20) ** (30 / 365.0) - 1.0
assert abs(ref.expected_window_return - expected) < 1e-12
# sanity: the alias doesn't change the modeled track's own reference
direct = provider.reference("multistrat", 30)
assert direct is not None
assert abs(direct.expected_window_return - expected) < 1e-12
def test_track_with_no_alias_and_no_row_returns_none() -> None:
repo = _FakeRepo([_FakeSummary("multistrat", 0.20)])
provider = CockpitBacktestRefProvider(repo)
assert provider.reference("some_other_track", 30) is None