feat(orchestration): wire stablecoin_rotation_nav into nightly job + cockpit
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -208,6 +208,23 @@ def crypto_tstrend_nav(context: AssetExecutionContext) -> dict: # type: ignore[
|
||||
)
|
||||
|
||||
|
||||
@asset
|
||||
def stablecoin_rotation_nav(context: AssetExecutionContext) -> dict: # type: ignore[type-arg]
|
||||
"""Paper-forward stablecoin peg-reversion (short-rich daily treasury rotation, Binance spot)."""
|
||||
from fxhnt.adapters.data.binance_spot_history import BinanceSpotHistory
|
||||
from fxhnt.application.stablecoin_strategy import StableRotationForward
|
||||
|
||||
def load_panel() -> dict: # type: ignore[type-arg]
|
||||
h = BinanceSpotHistory()
|
||||
return {s: h.daily_close(s) for s in ("FDUSDUSDT", "TUSDUSDT", "USDPUSDT")}
|
||||
|
||||
return _run_paper_tracker(
|
||||
context, "stablecoin_rotation_nav",
|
||||
lambda: StableRotationForward(load_panel),
|
||||
"stablecoin_rotation_state",
|
||||
)
|
||||
|
||||
|
||||
@asset
|
||||
def unlock_nav(context: AssetExecutionContext) -> dict: # type: ignore[type-arg]
|
||||
"""Paper-forward token-unlock dilution shorts (market-neutral): short insider/investor cliff names
|
||||
@@ -224,7 +241,7 @@ def unlock_nav(context: AssetExecutionContext) -> dict: # type: ignore[type-arg
|
||||
return _run_paper_tracker(context, "unlock_nav", lambda: UnlockShortForward(cal), "unlock_state")
|
||||
|
||||
|
||||
@asset(deps=[combined_forward_nav, sixtyforty_nav, xsfunding_nav, unlock_nav, crypto_tstrend_nav])
|
||||
@asset(deps=[combined_forward_nav, sixtyforty_nav, xsfunding_nav, unlock_nav, crypto_tstrend_nav, stablecoin_rotation_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
|
||||
|
||||
@@ -11,6 +11,7 @@ from fxhnt.adapters.orchestration.assets import (
|
||||
crypto_tstrend_nav,
|
||||
futures_bars,
|
||||
sixtyforty_nav,
|
||||
stablecoin_rotation_nav,
|
||||
unlock_nav,
|
||||
xsfunding_nav,
|
||||
)
|
||||
@@ -19,7 +20,7 @@ combined_book_job = define_asset_job(
|
||||
name="combined_book_forward_job",
|
||||
selection=[
|
||||
crypto_bars, futures_bars, combined_forward_nav, sixtyforty_nav,
|
||||
xsfunding_nav, unlock_nav, crypto_tstrend_nav,
|
||||
xsfunding_nav, unlock_nav, crypto_tstrend_nav, stablecoin_rotation_nav,
|
||||
cockpit_forward,
|
||||
],
|
||||
)
|
||||
@@ -35,7 +36,7 @@ daily_combined_book_schedule = ScheduleDefinition(
|
||||
defs = Definitions(
|
||||
assets=[
|
||||
crypto_bars, futures_bars, combined_forward_nav, sixtyforty_nav,
|
||||
xsfunding_nav, unlock_nav, crypto_tstrend_nav,
|
||||
xsfunding_nav, unlock_nav, crypto_tstrend_nav, stablecoin_rotation_nav,
|
||||
cockpit_forward,
|
||||
],
|
||||
jobs=[combined_book_job],
|
||||
|
||||
@@ -24,9 +24,10 @@ def test_definitions_load_with_assets_and_schedule() -> None:
|
||||
assert "xsfunding_nav" in asset_keys, f"missing xsfunding_nav asset: {asset_keys}"
|
||||
assert "unlock_nav" in asset_keys, f"missing unlock_nav asset: {asset_keys}"
|
||||
assert "crypto_tstrend_nav" in asset_keys, f"missing crypto_tstrend_nav asset: {asset_keys}"
|
||||
# 8 assets: crypto_bars, futures_bars, combined_forward_nav, sixtyforty_nav,
|
||||
# xsfunding_nav, unlock_nav, crypto_tstrend_nav, cockpit_forward
|
||||
assert len(asset_keys) == 8, f"expected 8 assets, got {len(asset_keys)}: {asset_keys}"
|
||||
assert "stablecoin_rotation_nav" in asset_keys, f"missing stablecoin_rotation_nav: {asset_keys}"
|
||||
# 9 assets: crypto_bars, futures_bars, combined_forward_nav, sixtyforty_nav,
|
||||
# xsfunding_nav, unlock_nav, crypto_tstrend_nav, stablecoin_rotation_nav, cockpit_forward
|
||||
assert len(asset_keys) == 9, f"expected 9 assets, got {len(asset_keys)}: {asset_keys}"
|
||||
|
||||
# --- schedule present with the right cron ---
|
||||
# defs.schedules is a list[ScheduleDefinition] (or None when empty)
|
||||
@@ -44,5 +45,5 @@ 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", "xsfunding_nav", "unlock_nav", "sixtyforty_nav", "crypto_tstrend_nav"}
|
||||
expected_upstream = {"combined_forward_nav", "xsfunding_nav", "unlock_nav", "sixtyforty_nav", "crypto_tstrend_nav", "stablecoin_rotation_nav"}
|
||||
assert expected_upstream <= upstream, f"cockpit_forward missing upstream: {expected_upstream - upstream}"
|
||||
|
||||
10
tests/integration/test_stablecoin_wiring.py
Normal file
10
tests/integration/test_stablecoin_wiring.py
Normal file
@@ -0,0 +1,10 @@
|
||||
def test_asset_importable():
|
||||
from fxhnt.adapters.orchestration.assets import stablecoin_rotation_nav
|
||||
assert stablecoin_rotation_nav is not None
|
||||
|
||||
|
||||
def test_definitions_include_stablecoin():
|
||||
from fxhnt.adapters.orchestration.assets import stablecoin_rotation_nav
|
||||
from fxhnt.adapters.orchestration.definitions import combined_book_job, defs
|
||||
assert stablecoin_rotation_nav in defs.assets
|
||||
assert combined_book_job is not None
|
||||
Reference in New Issue
Block a user