From 94dbf791330282393a2ff17b1f2cf7e9cf554742 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Tue, 16 Jun 2026 06:36:46 +0200 Subject: [PATCH] feat(b1): market-data client ports Co-Authored-By: Claude Opus 4.8 (1M context) --- src/fxhnt/ports/market_data.py | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/fxhnt/ports/market_data.py diff --git a/src/fxhnt/ports/market_data.py b/src/fxhnt/ports/market_data.py new file mode 100644 index 0000000..4022e10 --- /dev/null +++ b/src/fxhnt/ports/market_data.py @@ -0,0 +1,41 @@ +# src/fxhnt/ports/market_data.py +"""Market-data client ports for the paper-forward strategies. Each has a urllib live adapter +(adapters/data/*) and a deterministic fake in tests. No network in the domain or in tests.""" +from __future__ import annotations + +from typing import Protocol + + +class DailyBarClient(Protocol): + def adj_closes(self, symbol: str) -> dict[str, float]: + """{ 'YYYY-MM-DD': adjusted_close } for a daily-bar history window.""" + ... + + +class BinanceFundingClient(Protocol): + def universe(self) -> list[str]: ... + def funding_daily(self, symbol: str) -> float: + """Most-recent funding as a per-DAY rate (sum of the day's intervals).""" + ... + def quote_volume_usd(self, symbol: str) -> float: ... + + +class CrossVenueFundingClient(Protocol): + def funding_by_venue(self) -> dict[str, dict[str, float]]: + """{ coin: { venue: daily_funding_rate } } across the supported venues.""" + ... + def volume_by_venue(self) -> dict[str, dict[str, float]]: + """{ coin: { venue: 24h_quote_volume_usd } }.""" + ... + + +class CryptoPerpBarClient(Protocol): + def panel(self) -> tuple[list[str], list[int], list[list[float]], list[list[float]], list[float]]: + """(symbols, epoch_days, close[d][s], open[d][s], funding_now[s]) for the top-liquid perps.""" + ... + + +class VolIndexClient(Protocol): + def dvol(self, currency: str) -> dict[int, float]: + """{ epoch_day: implied-vol-index } for BTC/ETH (Deribit DVOL).""" + ...