fix: pre-launch hardening — HYPE price feed, KOL wallet cleanup, Telegram Trump alert, rate limiting, brittle test
Batch of the pre-launch audit campaign (BUG-01…14 plus three new features): Pricing / TP-SL protection - Add app/services/hl_price_feed.py: supplemental HL allMids poller for HL-native assets (HYPE, PURR) not listed on Binance. Pumps price_store + tp_sl_monitor.on_price_tick so bot trades on these assets keep full stop-loss / take-profit / trailing protection instead of max-hold only. - Wire feed into main.py lifespan (startup task + graceful shutdown cancel). Telegram - Add format_trump_mention + PATH B in _dispatch: crypto-relevant Trump posts with no directional signal (relevant=True, signal=hold) now alert the public channel only (no per-subscriber noise). - Rate limiter (slowapi) on the API; assorted bot/digest fixes. KOL on-chain - seed_kol_wallets.py: KOL_FEEDS coverage cross-check; reversibly deactivate orphaned wallets (handle not in KOL_FEEDS → can never produce divergence) so the scanner stops burning cycles on them. Tests / misc - Fix brittle test_macro_ahr999_uses_same_formula_as_scanner: mock now uses realistic ms timestamps so the in-progress-day drop fires, matching the fetcher's bar count (was 0.3179 vs 0.3178 off-by-one). - Refresh stale notify_signal comment in truth_social.py. Frontend reduce-action type fix lives in the sibling repo. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,7 @@ from datetime import datetime, timedelta, timezone
|
||||
from typing import Any, Optional
|
||||
|
||||
import httpx
|
||||
from app.services.bottom_indicators import ahr999 as compute_ahr999
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -119,17 +120,20 @@ def _parse_farside_latest_total(html: str) -> dict:
|
||||
|
||||
|
||||
# ── 1. AHR999 ───────────────────────────────────────────────────────────────
|
||||
# Formula: AHR999 = (price / 200d MA) × (price / age_fit_price)
|
||||
# age_fit_price = 10 ** (5.84 * log10(days_since_2009_01_03) - 17.01)
|
||||
# Below 0.45 historically marks accumulation zones; above 1.2 marks
|
||||
# "expensive" regime that invalidates a bottom thesis.
|
||||
|
||||
_AHR999_GENESIS = datetime(2009, 1, 3, tzinfo=timezone.utc)
|
||||
# IMPORTANT: this macro-panel AHR999 MUST stay formula-identical to the
|
||||
# live BTC bottom scanner, otherwise the displayed value can disagree with the
|
||||
# actual trigger logic. Reuse the canonical implementation from
|
||||
# app.services.bottom_indicators instead of re-implementing it here.
|
||||
|
||||
|
||||
@_none_on_fail("ahr999")
|
||||
async def fetch_ahr999() -> dict:
|
||||
"""Compute AHR999 from the last 200 daily BTC closes (Binance fapi)."""
|
||||
"""Compute the SAME AHR999 used by the BTC bottom scanner.
|
||||
|
||||
Raw input source stays the same (Binance daily BTCUSDT closes); only the
|
||||
formula source-of-truth is centralized so the UI cannot drift from the
|
||||
trading logic.
|
||||
"""
|
||||
end_ms = int(datetime.now(timezone.utc).timestamp() * 1000)
|
||||
start_ms = end_ms - 260 * 24 * 3600 * 1000 # extra buffer after dropping in-progress day
|
||||
async with httpx.AsyncClient(timeout=DEFAULT_TIMEOUT) as c:
|
||||
@@ -144,12 +148,12 @@ async def fetch_ahr999() -> dict:
|
||||
if len(closes) < 200:
|
||||
return {"value": None, "raw": {"error": "insufficient candles", "have": len(closes)}}
|
||||
price = closes[-1]
|
||||
ma200 = sum(closes[-200:]) / 200
|
||||
|
||||
days = (datetime.now(timezone.utc) - _AHR999_GENESIS).total_seconds() / 86400
|
||||
ma200 = sum(closes[-200:]) / 200 # kept in raw for operator intuition only
|
||||
days = (datetime.now(timezone.utc) - datetime(2009, 1, 3, tzinfo=timezone.utc)).total_seconds() / 86400
|
||||
age_fit = 10 ** (5.84 * math.log10(days) - 17.01)
|
||||
|
||||
ahr = (price / ma200) * (price / age_fit)
|
||||
ahr = compute_ahr999(closes)
|
||||
if ahr is None:
|
||||
return {"value": None, "raw": {"error": "ahr999 computation returned null"}}
|
||||
return {
|
||||
"value": round(ahr, 4),
|
||||
"raw": {"price": price, "ma200": round(ma200, 2),
|
||||
|
||||
Reference in New Issue
Block a user