feat(combined-book): FXHNT_COMBINED_BOOK_DATA_SOURCE flag + source factory; wire CLI

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-06-15 11:27:24 +02:00
parent c3c90881e0
commit 5a75effd8d
4 changed files with 34 additions and 1 deletions

View File

@@ -0,0 +1,12 @@
"""Composition helper: build the CombinedBookSource the settings select (the reversible cutover seam)."""
from __future__ import annotations
from fxhnt.application.combined_book_source import CombinedBookSource, RawFileSource, WarehouseSource
from fxhnt.config import Settings
def make_combined_book_source(settings: Settings, data_dir: str) -> CombinedBookSource:
if settings.combined_book_data_source == "warehouse":
from fxhnt.adapters.warehouse.duckdb_feature_store import DuckDbFeatureStore
return WarehouseSource(DuckDbFeatureStore(settings.warehouse_path))
return RawFileSource(data_dir)

View File

@@ -210,9 +210,11 @@ def forward_track(
"""Forward-validate the combined book: book today's realized return into the paper track. Run daily on
a cron alongside the data fetch — the forward NAV/Sharpe is the only ground truth before capital."""
from fxhnt.application.combined_book import CombinedBook
from fxhnt.application.combined_book_factory import make_combined_book_source
from fxhnt.application.forward_tracker import CombinedBookForwardTracker
book = CombinedBook(data_dir, _FUTURES_UNIVERSE)
book = CombinedBook(data_dir, _FUTURES_UNIVERSE,
source=make_combined_book_source(get_settings(), data_dir))
st = CombinedBookForwardTracker(book, state).step()
typer.echo(f"forward track since {st.inception} (last {st.last_date}): {st.forward_days} forward days, "
f"booked {st.booked_today} today")

View File

@@ -106,6 +106,9 @@ class Settings(BaseSettings):
analytical_path: str = Field(default=str(_DATA_DIR / "analytical.duckdb"))
# Warehouse (point-in-time SSOT: bars, funding, microstructure features) — DuckDB embedded file.
warehouse_path: str = Field(default=str(_DATA_DIR / "warehouse.duckdb"))
# Combined-book data path: "raw" (crypto_pit/.dbn files) or "warehouse" (SSOT). Default raw for safety;
# the B0 Dagster deploy sets FXHNT_COMBINED_BOOK_DATA_SOURCE=warehouse.
combined_book_data_source: str = Field(default="raw")
cost_bps_per_turnover: float = 10.0 # round-trip cost model (bps of traded notional)
gauntlet: GauntletSettings = Field(default_factory=GauntletSettings)

View File

@@ -0,0 +1,16 @@
"""The factory picks WarehouseSource vs RawFileSource from settings (combined_book_data_source)."""
from __future__ import annotations
from fxhnt.application.combined_book_factory import make_combined_book_source
from fxhnt.application.combined_book_source import RawFileSource, WarehouseSource
from fxhnt.config import Settings
def test_factory_raw_default(tmp_path) -> None:
s = Settings(combined_book_data_source="raw", warehouse_path=str(tmp_path / "wh.duckdb"))
assert isinstance(make_combined_book_source(s, "/data/surfer"), RawFileSource)
def test_factory_warehouse(tmp_path) -> None:
s = Settings(combined_book_data_source="warehouse", warehouse_path=str(tmp_path / "wh.duckdb"))
assert isinstance(make_combined_book_source(s, "/data/surfer"), WarehouseSource)