Files
fxhnt/tests/unit/test_bybit_cost_basis_consistent.py
jgrusewski a213edb800 fix(0b): single-source the Bybit reconciliation cost (bybit_cost_bps=5.5)
The standalone Bybit sleeve tracks (positioning/xsfunding/unlock) AND the two 4-edge
book tracks (bybit_4edge/bybit_4edge_levered) charged cost_bps_per_turnover=10.0 in
their forward nav assets, while their reconciliation ref (_persist_bybit_book) computed
the backtest at 5.5 — a forward-charged-more-than-ref mismatch that biases the gate
toward WAIT on a cost artifact (safe direction, but could permanently WAIT a real edge).
New Settings.bybit_cost_bps=5.5 (the measured liquid-book cost — the mirage finding) is
the SINGLE source for every Bybit forward track + its ref; registry cost_bps 10->5.5 +
definition_version 1->2 (visible deterministic re-inception). Equity/tradfi tracks keep
cost_bps_per_turnover (different venue). Invariant test locks all 5 Bybit sids. Full
suite 2058 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 21:27:42 +02:00

25 lines
1.6 KiB
Python

"""Invariant: every Bybit sleeve/book forward track and its reconciliation ref must use ONE Bybit cost
basis (`Settings.bybit_cost_bps`, the measured liquid-book cost — the "mirage" finding: Sharpe 2.11 at
5.5bp drag). Before this fix the standalone sleeve tracks (positioning/xsfunding/unlock) AND the two
4-edge book tracks (bybit_4edge/bybit_4edge_levered) charged `cost_bps_per_turnover` (10.0) in their
forward asset while `_persist_bybit_book` computed their reconciliation ref at 5.5 — a forward-charged-
more-than-its-ref mismatch that biases the reconciliation gate toward WAIT on a cost artifact, not a real
divergence (see project_fxhnt_measured_cost_mirage_and_postgres)."""
from fxhnt.config import Settings
from fxhnt.registry import STRATEGY_REGISTRY
# Every Bybit forward track whose reconciliation ref is computed by `_persist_bybit_book` (== cli.py's
# `_BYBIT_BOOK_SIDS`) — the standalone sleeves (positioning/xsfunding/unlock) plus the two 4-edge book
# variants (naive/levered), which also override cost_bps in their nav assets and must stay in lockstep.
_BYBIT_SLEEVE_SIDS = ("positioning", "xsfunding", "unlock", "bybit_4edge", "bybit_4edge_levered")
def test_bybit_sleeve_tracks_use_the_single_bybit_cost():
c = Settings().bybit_cost_bps
assert c == 5.5
for sid in _BYBIT_SLEEVE_SIDS:
params = STRATEGY_REGISTRY[sid]["definition"]["params"]
assert params["cost_bps"] == c, (
f"{sid} registry cost_bps={params['cost_bps']} != bybit_cost_bps={c}"
f"track and reconciliation ref would use different costs")