31 lines
1.3 KiB
Python
31 lines
1.3 KiB
Python
from fxhnt.application.basis_panel_builder import build_spot_panel
|
|
from fxhnt.adapters.data.crypto_pit_panel import CryptoPitPanelSource
|
|
|
|
|
|
class _FakeSpot:
|
|
def __init__(self, data): self._d = data
|
|
def daily_close(self, symbol, start_ms=0): return dict(self._d.get(symbol, {}))
|
|
|
|
|
|
def test_build_spot_panel_applies_guard():
|
|
panel = {"AAA": {100: (1.0, 5e6, 0.001), 101: (1.0, 5e6, 0.001),
|
|
102: (1.0, 5e6, 0.001), 103: (1.0, 5e6, 0.001)}}
|
|
spot = _FakeSpot({"AAA": {100: 1.001, 101: 0.999, 102: 50.0, 103: 1.0, 200: 8.87}})
|
|
sp = build_spot_panel(panel, spot, max_basis=0.30)
|
|
assert set(sp["AAA"]) == {100, 101, 103} # 102 rejected (relist), 200 out of window
|
|
|
|
|
|
def test_build_spot_panel_skips_coin_with_no_spot():
|
|
panel = {"AAA": {100: (1.0, 5e6, 0.001), 101: (1.0, 5e6, 0.001)},
|
|
"B": {100: (1.0, 5e6, 0.001), 101: (1.0, 5e6, 0.001)}}
|
|
spot = _FakeSpot({"AAA": {100: 1.0, 101: 1.0}}) # B has no spot
|
|
sp = build_spot_panel(panel, spot, max_basis=0.30)
|
|
assert set(sp) == {"AAA"} # B omitted -> funding-only downstream
|
|
|
|
|
|
def test_spot_panel_npz_roundtrip(tmp_path):
|
|
sp = {"AAA": {100: 1.5, 101: 1.7}, "B": {100: 2.0}}
|
|
CryptoPitPanelSource.write_spot_panel(sp, str(tmp_path))
|
|
loaded = CryptoPitPanelSource.load_spot_panel(str(tmp_path))
|
|
assert loaded == sp
|