Pre-launch hardening: KOL module, Telegram, scanners, WS resilience
Big-picture changes since b941223:
KOL pipeline (new) — Substack/podcast/blog RSS → AI ticker extraction →
on-chain wallet diff → talks-vs-trades divergence detection. Daily polls,
19 feeds, divergence emits Post + Telegram fan-out.
Telegram push (new) — walletless free tier + wallet-linked Pro upgrade,
in-bot preference commands (/trump /btc /funding /kol /conf /quiet),
signed-envelope API for dashboard. Disconnect-wallet keeps free
subscription.
BTC funding-rate reversal scanner (new) — hourly cron, 30d cumulative
funding threshold + mean-revert + 7d price confirm, emits via
/api/signals/ingest. BTC bottom-reversal scanner promoted to System 2.
WS broadcast rewrite — per-client send timeout + parallel fan-out
(asyncio.gather). Fixes "Binance WS no close frame" reconnect storms +
APScheduler 11-min job misses, both caused by one slow client stalling
the kline loop.
Error visibility — three silent-error sites (trumpstruth/truth_social
fetchers, funding_reversal scanner) now include exception type name so
httpx ConnectError-style empty-message errors stop logging blank lines.
Telegram bot loop now classifies ReadTimeout vs network vs unknown +
logger.exception for the unknown bucket.
Security hygiene — trumpsignal.db untracked from git (held subscriber
wallets + encrypted HL keys + 22 bot trades); .gitignore now blocks
*.db/.next/backups. CORS only allows FRONTEND_URL in production.
New ops scripts —
- scripts/preflight.py: env/DB/Telegram/AI auth verification gate
- scripts/backup_db.sh: cron-friendly daily DB backup (SQLite + Postgres)
- scripts/seed_kol_wallets.py: idempotent KOL on-chain wallet seeder
15 new Alembic migrations (007-021) covering convex strategy fields,
phase-1 safety, two-system frozen exits, invalidation prices, dynamic
SYS2 leverage, staged de-risk + pyramiding, peak gain tracking, risk
mode, auto-trade + grow flags, KOL module, KOL on-chain, KOL divergence,
Telegram bindings + walletless.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+28
-2
@@ -83,7 +83,21 @@ async def fetch_historical(asset: str, symbol: str, interval: str = "1m", limit:
|
||||
|
||||
|
||||
async def run_binance_ws():
|
||||
"""Connect to Binance kline stream with exponential back-off on disconnect."""
|
||||
"""Connect to Binance kline stream with exponential back-off on disconnect.
|
||||
|
||||
Binance routinely cycles connections every ~24h, and intermediate proxies
|
||||
can drop without sending a close frame — both surface here as exceptions.
|
||||
The reconnect must be fast (sub-second) so price ticks aren't visibly
|
||||
stuck on the dashboard during a hiccup.
|
||||
|
||||
Resilience defenses:
|
||||
* ping_interval/ping_timeout — peer-of-record liveness check (websockets lib)
|
||||
* close_timeout — bound how long we wait for a clean close handshake
|
||||
* open_timeout — bound the initial connect handshake so a hung TCP doesn't
|
||||
permanently park this task
|
||||
* max_queue — drop frames if downstream can't keep up rather than back
|
||||
the WS receive buffer up indefinitely
|
||||
"""
|
||||
# Pre-fill with historical data
|
||||
await fetch_historical("BTC", "btcusdt", limit=500)
|
||||
await fetch_historical("ETH", "ethusdt", limit=500)
|
||||
@@ -96,15 +110,27 @@ async def run_binance_ws():
|
||||
settings.binance_ws_url,
|
||||
ping_interval=20,
|
||||
ping_timeout=10,
|
||||
close_timeout=5,
|
||||
open_timeout=10,
|
||||
max_queue=128,
|
||||
) as ws:
|
||||
backoff = 1 # reset on successful connection
|
||||
logger.info("Binance WebSocket connected.")
|
||||
async for message in ws:
|
||||
await _process_message(message)
|
||||
# If we exit the `async with` without an exception, the server
|
||||
# closed normally — reconnect immediately rather than backing off.
|
||||
logger.info("Binance WebSocket closed cleanly, reconnecting immediately.")
|
||||
except asyncio.CancelledError:
|
||||
logger.info("Binance WebSocket task cancelled.")
|
||||
return
|
||||
except Exception as exc:
|
||||
logger.error("Binance WebSocket error: %s. Reconnecting in %ds.", exc, backoff)
|
||||
# Use exception() once so a TRACE-back-with-context is logged the
|
||||
# first time something interesting happens; subsequent same-error
|
||||
# retries log compactly to avoid drowning the log.
|
||||
logger.warning(
|
||||
"Binance WebSocket error: %s (%s). Reconnecting in %ds.",
|
||||
type(exc).__name__, exc, backoff,
|
||||
)
|
||||
await asyncio.sleep(backoff)
|
||||
backoff = min(backoff * 2, 60)
|
||||
|
||||
Reference in New Issue
Block a user