feat(xsfunding): register xsfunding paper track + Dagster asset in daily book

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-06-19 07:50:19 +02:00
parent 9e9fe2a13c
commit 94da2c6a6b
4 changed files with 27 additions and 4 deletions

View File

@@ -242,8 +242,21 @@ def eqfactor_tilt_nav(context: AssetExecutionContext, eqfactor_scores: dict) ->
return {"forward_days": st.forward_days, "last_date": st.last_date}
@asset
def xsfunding_nav(context: AssetExecutionContext) -> dict: # type: ignore[type-arg]
"""Paper-forward cross-sectional crypto funding-dispersion (executable construction):
live delta-neutral funding+basis book through the gate."""
from fxhnt.adapters.data.binance_xsfunding_live import BinanceXsFundingLive
from fxhnt.application.xsfunding_strategy import XsFundingForward
from fxhnt.application.forward_tracker import ForwardTracker
st = ForwardTracker(XsFundingForward(BinanceXsFundingLive()), f"{_data_dir()}/xsfunding_state.json").step()
context.log.info(f"xsfunding_nav: {st.forward_days}d through {st.last_date}")
return {"forward_days": st.forward_days, "last_date": st.last_date}
@asset(deps=[combined_forward_nav, sixtyforty_nav, multistrat_nav, gd_nav, funding_nav, poc_nav,
eqfactor_long_nav, eqfactor_tilt_nav])
eqfactor_long_nav, eqfactor_tilt_nav, xsfunding_nav])
def cockpit_forward(context: AssetExecutionContext) -> None:
"""Normalize tracker state files and upsert rows + summary into the operational cockpit DB."""
from fxhnt.application.forward_ingest import ingest_forward_state

View File

@@ -17,6 +17,7 @@ from fxhnt.adapters.orchestration.assets import (
multistrat_nav,
poc_nav,
sixtyforty_nav,
xsfunding_nav,
)
combined_book_job = define_asset_job(
@@ -25,6 +26,7 @@ combined_book_job = define_asset_job(
crypto_bars, futures_bars, combined_forward_nav,
sixtyforty_nav, multistrat_nav, gd_nav, funding_nav, poc_nav,
eqfactor_scores, eqfactor_long_nav, eqfactor_tilt_nav,
xsfunding_nav,
cockpit_forward,
],
)
@@ -42,6 +44,7 @@ defs = Definitions(
crypto_bars, futures_bars, combined_forward_nav,
sixtyforty_nav, multistrat_nav, gd_nav, funding_nav, poc_nav,
eqfactor_scores, eqfactor_long_nav, eqfactor_tilt_nav,
xsfunding_nav,
cockpit_forward,
],
jobs=[combined_book_job],

View File

@@ -45,4 +45,9 @@ STRATEGY_REGISTRY: dict[str, dict] = {
"venue": "us-equity", "state_file": "eqfactor_tilt_state",
"gate_spec": {"min_days": 60, "min_total_return": 0.0, "min_sharpe": 0.3},
},
"xsfunding": {
"display_name": "Crypto funding — cross-sectional", "sleeve": "crypto-funding",
"venue": "binance-perp", "state_file": "xsfunding_state",
"gate_spec": {"min_days": 60, "min_total_return": 0.0, "min_sharpe": 0.5},
},
}

View File

@@ -21,9 +21,11 @@ def test_definitions_load_with_assets_and_schedule() -> None:
eqfactor = {"eqfactor_long_nav", "eqfactor_tilt_nav"}
assert eqfactor <= asset_keys, f"missing equity-factor assets: {eqfactor - asset_keys}"
assert "eqfactor_ls_nav" not in asset_keys, "eqfactor_ls_nav must be retired (B3b)"
# B2.1: the shared scores asset is wired in (fetched once, consumed by the sleeves) — 12 total
# XSFP T3: the cross-sectional crypto funding sleeve is wired into the graph
assert "xsfunding_nav" in asset_keys, f"missing xsfunding_nav asset: {asset_keys}"
# B2.1: the shared scores asset is wired in (fetched once, consumed by the sleeves) — 13 total
assert "eqfactor_scores" in asset_keys, f"missing eqfactor_scores asset: {asset_keys}"
assert len(asset_keys) == 12, f"expected 12 assets, got {len(asset_keys)}: {asset_keys}"
assert len(asset_keys) == 13, f"expected 13 assets, got {len(asset_keys)}: {asset_keys}"
# --- schedule present with the right cron ---
# defs.schedules is a list[ScheduleDefinition] (or None when empty)
@@ -41,7 +43,7 @@ def test_definitions_load_with_assets_and_schedule() -> None:
cockpit_def = repo.assets_defs_by_key[AssetKey("cockpit_forward")]
deps = cockpit_def.asset_deps[AssetKey("cockpit_forward")]
upstream = {k.to_user_string() for k in deps}
expected_upstream = {"combined_forward_nav"} | paper | eqfactor
expected_upstream = {"combined_forward_nav", "xsfunding_nav"} | paper | eqfactor
assert expected_upstream <= upstream, f"cockpit_forward missing upstream: {expected_upstream - upstream}"
# --- each equity-factor nav sleeve depends on the shared eqfactor_scores asset (fetched once) ---