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:
@@ -1,6 +1,11 @@
|
||||
"""
|
||||
历史帖子价格回溯
|
||||
对 DB 中没有价格数据的帖子,从 Binance 拉历史 K 线计算涨跌幅
|
||||
Historical price backfill for already-relevant posts.
|
||||
|
||||
Important safety rule:
|
||||
This job only fills missing price fields. It must NEVER rewrite the post's
|
||||
semantic classification (`relevant`, `sentiment`, signal direction) from a
|
||||
keyword heuristic, otherwise historical truth rows become a mixed dataset of
|
||||
AI-scored rows + script-guessed rows.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
@@ -53,17 +58,21 @@ def _pct_change(klines: list, from_ms: int, delta_minutes: int) -> Optional[floa
|
||||
|
||||
|
||||
async def backfill_price_impact(db_session_factory, asset: str = "BTC") -> None:
|
||||
"""
|
||||
对 DB 中 relevant=True 但没有价格数据的帖子补充价格回溯。
|
||||
对 relevant=False 的帖子,做简单判断(标题含 crypto/bitcoin/btc 关键词则标记为相关)。
|
||||
"""Fill price-impact fields for posts that are already relevant.
|
||||
|
||||
The semantic label must come from the original analyzer, not from this
|
||||
backfill job. This task only enriches rows with price-at-post and
|
||||
subsequent returns.
|
||||
"""
|
||||
symbol = "BTCUSDT" if asset == "BTC" else "ETHUSDT"
|
||||
|
||||
async with db_session_factory() as db:
|
||||
# 拿所有没有价格数据的帖子
|
||||
# Only touch rows whose semantic classification already exists.
|
||||
result = await db.execute(
|
||||
select(Post)
|
||||
.where(Post.relevant == True)
|
||||
.where(Post.price_at_post == None)
|
||||
.where(Post.price_impact_asset == asset)
|
||||
.order_by(Post.published_at.asc())
|
||||
)
|
||||
posts = result.scalars().all()
|
||||
@@ -72,18 +81,6 @@ async def backfill_price_impact(db_session_factory, asset: str = "BTC") -> None:
|
||||
if not posts:
|
||||
return
|
||||
|
||||
# 关键词判断是否与加密相关(快速,不用 Claude API)
|
||||
crypto_keywords = [
|
||||
"bitcoin", "btc", "crypto", "cryptocurrency", "blockchain",
|
||||
"ethereum", "eth", "digital currency", "defi", "coinbase",
|
||||
"sec", "regulation", "tariff", "dollar", "inflation", "fed",
|
||||
"economy", "market", "trade", "sanctions", "iran", "china",
|
||||
]
|
||||
|
||||
def is_relevant(text: str) -> bool:
|
||||
t = text.lower()
|
||||
return any(kw in t for kw in crypto_keywords)
|
||||
|
||||
saved = 0
|
||||
errors = 0
|
||||
|
||||
@@ -95,18 +92,6 @@ async def backfill_price_impact(db_session_factory, asset: str = "BTC") -> None:
|
||||
|
||||
start_ms = int(published_at.timestamp() * 1000)
|
||||
|
||||
# 判断相关性(用关键词,不消耗 Claude API)
|
||||
relevant = is_relevant(post.text)
|
||||
sentiment = "neutral"
|
||||
if relevant:
|
||||
t = post.text.lower()
|
||||
bullish_kw = ["great", "win", "winning", "strong", "best", "love", "beautiful", "tremendous", "amazing", "pro-crypto", "bitcoin reserve"]
|
||||
bearish_kw = ["bad", "terrible", "war", "crisis", "sanction", "ban", "regulate", "crack", "fraud", "scam"]
|
||||
if any(k in t for k in bullish_kw):
|
||||
sentiment = "bullish"
|
||||
elif any(k in t for k in bearish_kw):
|
||||
sentiment = "bearish"
|
||||
|
||||
# 拉 Binance 历史价格
|
||||
klines = await _fetch_klines(symbol, start_ms, limit=FETCH_WINDOW_MINUTES)
|
||||
|
||||
@@ -120,13 +105,10 @@ async def backfill_price_impact(db_session_factory, asset: str = "BTC") -> None:
|
||||
result = await db.execute(select(Post).where(Post.id == post.id))
|
||||
p = result.scalar_one_or_none()
|
||||
if p:
|
||||
p.relevant = relevant
|
||||
p.sentiment = sentiment
|
||||
p.price_impact_asset = asset if relevant else None
|
||||
p.price_at_post = price_at_post
|
||||
p.price_impact_m5 = m5 if relevant else None
|
||||
p.price_impact_m15 = m15 if relevant else None
|
||||
p.price_impact_m1h = m1h if relevant else None
|
||||
p.price_impact_m5 = m5
|
||||
p.price_impact_m15 = m15
|
||||
p.price_impact_m1h = m1h
|
||||
await db.commit()
|
||||
saved += 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user