4442e97f28
New backend pipeline: 8 free public macro signals fetched in parallel,
upserted once per calendar day, served via /api/macro/{snapshot,history}.
- AHR999 (computed from Binance 200d klines)
- Altcoin Season Index (CoinGecko top-50 30d)
- Fear & Greed (alternative.me)
- BTC dominance, ETH/BTC ratio
- Stablecoin supply (DeFiLlama)
- Spot BTC ETF net flow (Farside)
- BTC perp open interest (Binance fapi)
Each fetcher is independently @_none_on_fail decorated so one outage
can't take down the snapshot; scoring renormalises across whichever
indicators returned a value. Daily cron at 03:00 UTC; on startup a
fire-and-forget bootstrap fills today's row if missing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
from datetime import datetime, timezone
|
|
|
|
from app.services.macro.fetchers import (
|
|
_drop_in_progress_daily_klines,
|
|
_latest_closed_daily_point,
|
|
_parse_farside_latest_total,
|
|
)
|
|
|
|
|
|
def test_drop_in_progress_daily_klines_removes_today_open_bar():
|
|
now = datetime(2026, 5, 25, 8, 0, tzinfo=timezone.utc)
|
|
rows = [
|
|
[1779494400000, 0, 0, 0, "76715.20"],
|
|
[1779580800000, 0, 0, 0, "77030.30"],
|
|
[1779667200000, 0, 0, 0, "77404.80"], # 2026-05-25 00:00 UTC, still open
|
|
]
|
|
|
|
filtered = _drop_in_progress_daily_klines(rows, now=now)
|
|
|
|
assert [row[0] for row in filtered] == [1779494400000, 1779580800000]
|
|
|
|
|
|
def test_latest_closed_daily_point_skips_today_point():
|
|
now = datetime(2026, 5, 25, 8, 0, tzinfo=timezone.utc)
|
|
rows = [
|
|
{"timestamp": 1779494400000, "sumOpenInterestValue": "1"},
|
|
{"timestamp": 1779580800000, "sumOpenInterestValue": "2"},
|
|
{"timestamp": 1779667200000, "sumOpenInterestValue": "3"},
|
|
]
|
|
|
|
latest = _latest_closed_daily_point(rows, now=now)
|
|
|
|
assert latest == rows[1]
|
|
|
|
|
|
def test_parse_farside_latest_total_uses_newest_date_not_first_row():
|
|
html = """
|
|
<table>
|
|
<tbody>
|
|
<tr><td>11 Jan 2024</td><td>0.0</td><td>655.3</td></tr>
|
|
<tr><td>24 May 2026</td><td>0.0</td><td>(12.5)</td></tr>
|
|
<tr><td>25 May 2026</td><td>0.0</td><td>321.0</td></tr>
|
|
</tbody>
|
|
</table>
|
|
"""
|
|
|
|
parsed = _parse_farside_latest_total(html)
|
|
|
|
assert parsed["value"] == 321_000_000.0
|
|
assert parsed["raw"]["date"] == "25 May 2026"
|