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:
k
2026-05-29 11:57:19 +08:00
parent 6471e44aac
commit d6c802ef26
40 changed files with 1833 additions and 209 deletions
+61
View File
@@ -73,6 +73,16 @@ SEED_WALLETS: list[dict] = [
"label": "Arthur Hayes (secondary)",
"source_url": "https://etherscan.io/address/0x534a0076fb7c2b1f83fa21497429ad7ad3bd7587",
},
# ⚠️ ORPHANED: the two entries below have VERIFIED on-chain attribution
# but their `handle` does NOT match any handle in KOL_FEEDS, so the
# divergence scanner has no post-side data to join against — they produce
# ZERO divergence detections today. They are kept (a) because the wallet
# attribution is sound and (b) so that if/when X/Twitter ingestion or a
# matching RSS feed is added under these handles, the wallets light up
# automatically. The cross-check in main() prints a warning for these.
# • andrewkang — publishes on X/@Rewkang only (no Substack) → needs
# X ingestion before post-side data exists.
# • murad — not currently in KOL_FEEDS at all.
{
"handle": "andrewkang",
"chain": "ethereum",
@@ -152,6 +162,57 @@ async def main() -> int:
print()
print(f"Inserted {inserted} wallets, skipped {skipped} existing.")
# ── Coverage cross-check ─────────────────────────────────────────────
# A wallet is only useful for divergence detection if its handle has a
# matching post-side feed in KOL_FEEDS. Flag any orphans loudly, and
# report which feeds still have no wallet at all (the real coverage gap).
try:
from app.services.kol_substack import KOL_FEEDS
feed_handles = {f["handle"] for f in KOL_FEEDS}
except Exception as exc: # pragma: no cover - diagnostic only
print(f"\n(could not import KOL_FEEDS for cross-check: {exc})")
return 0
wallet_handles = {e["handle"] for e in SEED_WALLETS}
orphaned = sorted(wallet_handles - feed_handles)
feeds_without_wallet = sorted(feed_handles - wallet_handles)
print()
print(f"Coverage: {len(wallet_handles - set(orphaned))}/{len(feed_handles)} "
f"KOL_FEEDS handles have ≥1 wallet.")
# ── Orphan reconciliation ────────────────────────────────────────────
# An orphaned wallet (handle ∉ KOL_FEEDS) can NEVER produce a divergence
# because there's no post-side data to join against — but kol_onchain
# still burns a scan cycle (HL clearinghouseState + Etherscan) on it every
# run. Park such rows as active=False so the scanner skips them. This is
# REVERSIBLE: the row + its verified attribution stay in the DB, and the
# moment a matching feed (e.g. X/Twitter ingestion) is added, flip it back.
if orphaned:
async with AsyncSessionLocal() as session:
res = await session.execute(
select(KolWallet).where(
KolWallet.handle.in_(orphaned),
KolWallet.active.is_(True),
)
)
rows = res.scalars().all()
for row in rows:
row.active = False
await session.commit()
deactivated = len(rows)
print()
print(f"⚠️ ORPHANED wallets (handle not in KOL_FEEDS → ZERO divergence) "
f"— deactivated {deactivated} so the scanner skips them:")
for h in orphaned:
print(f" {h} — re-activate once a feed under this handle exists.")
if feeds_without_wallet:
print()
print(f"📭 {len(feeds_without_wallet)} feeds have NO wallet (no on-chain "
f"divergence possible):")
print(" " + ", ".join(feeds_without_wallet))
print()
print("Next step: edit SEED_WALLETS above and re-run. Each new wallet")
print("MUST cite a public attestation in source_url — see the docstring.")