Files
fxhnt/tests/unit/test_forward_definition.py
jgrusewski 810ebdc105 feat(0b): migrate xsfunding to a Bybit single-sleeve forward track (venue-consistent ref)
Adds a generic build_bybit_sleeve_forward_nav(repo, store, sleeve, ...) builder in
assets.py, refactors build_positioning_forward_nav to delegate to it, and moves
xsfunding_nav off the standalone Binance XsFundingForward(BinanceXsFundingLive())
construction onto its own Bybit single-sleeve forward track (mirrors positioning
exactly). xsfunding still runs unchanged as a sleeve inside the bybit_4edge deploy
book (_DEFAULT_BYBIT_SLEEVES untouched).

- bybit_forward_track.py: bybit_report_sid_kwargs() gains an xsfunding case.
- cli.py: _BYBIT_BOOK_SIDS += "xsfunding" (routing only, series already computed).
- registry.py: xsfunding -> venue bybit-perp, backtest.kind sleeve->report, params
  mirror positioning's shape, record_mode observed->recompute (required for the
  deterministic-engine recompute path; confirmed by the exhaustive observed-mode
  pin in test_forward_definition.py, updated accordingly).
- migration_builders.py: replaced the xsfunding lambda:None stub (valid only under
  the old observed record_mode) with a real single-sleeve Bybit builder, mirroring
  positioning's, to avoid a latent crash if the one-time forward migration is ever
  re-run.

Tests: new tests/unit/test_bybit_sleeve_forward_builder.py (TDD, brief-verbatim);
full tests/unit + tests/integration sweep: 2056 passed, 0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 20:25:03 +02:00

35 lines
1.7 KiB
Python

from fxhnt.application.forward_definition import definition_hash, track_definition
from fxhnt.registry import STRATEGY_REGISTRY
def test_hash_is_stable_under_key_reordering():
assert definition_hash({"a": 1, "b": 2}, 1) == definition_hash({"b": 2, "a": 1}, 1)
def test_hash_changes_when_a_param_changes():
# the BTC-drop case: instruments 6 -> 5 must change the hash
six = definition_hash({"instruments": ["SPY", "IEF", "GLD", "PDBC", "DBMF", "BTC-USD"]}, 1)
five = definition_hash({"instruments": ["SPY", "IEF", "GLD", "PDBC", "DBMF"]}, 1)
assert six != five
def test_hash_changes_when_version_bumps():
assert definition_hash({"a": 1}, 1) != definition_hash({"a": 1}, 2)
def test_every_active_track_declares_a_definition():
for sid in STRATEGY_REGISTRY:
params, version, mode = track_definition(sid)
assert isinstance(params, dict) and isinstance(version, int)
assert mode in ("recompute", "observed")
def test_observed_mode_is_exactly_the_executed_twins():
# Pin is deliberately exhaustive: whenever a new track adopts record_mode="observed", update this set
# (C2 Task 3 added bybit_4edge_exec; Task 7 added vrp_exec) so the change is reviewed, not silently
# absorbed. `xsfunding` moved OFF observed (Phase 0b venue consolidation: standalone Binance
# `XsFundingForward` -> its own Bybit single-sleeve `recompute` track, mirroring `positioning`) — the
# remaining observed tracks are the OBSERVED-fills executed twins (fills are observed, not recomputable).
observed = {sid for sid in STRATEGY_REGISTRY if track_definition(sid)[2] == "observed"}
assert observed == {"multistrat_exec", "bybit_4edge_exec", "vrp_exec"}