""" 批量回跑语义分析 — 验证新prompt效果 用法: python scripts/reanalyze_sample.py """ import asyncio import sys import os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from app.services.analysis import analyze_post from app.database import AsyncSessionLocal from app.models import Post from sqlalchemy import select async def main(): async with AsyncSessionLocal() as db: result = await db.execute( select(Post) .order_by(Post.published_at.desc()) .limit(60) ) posts = result.scalars().all() print(f"分析 {len(posts)} 条帖子 (model: claude-sonnet-4-6)\n") signals = {"buy": 0, "sell": 0, "short": 0, "hold": 0} relevant_count = 0 correct_m5, checked_m5 = 0, 0 correct_m15, checked_m15 = 0, 0 correct_m1h, checked_m1h = 0, 0 for i, post in enumerate(posts): analysis = await analyze_post(post.text) signals[analysis["signal"]] += 1 if analysis["relevant"]: relevant_count += 1 if analysis["relevant"]: sig = analysis["signal"].upper() conf = analysis["confidence"] actual_m5 = post.price_impact_m5 actual_m15 = post.price_impact_m15 actual_m1h = post.price_impact_m1h def dir_ok(actual, signal): if actual is None: return None if signal == "buy": return actual > 0 if signal == "short": return actual < 0 return None m5_ok = dir_ok(actual_m5, analysis["signal"]) m15_ok = dir_ok(actual_m15, analysis["signal"]) m1h_ok = dir_ok(actual_m1h, analysis["signal"]) if m5_ok is not None: checked_m5 += 1; correct_m5 += int(m5_ok) if m15_ok is not None: checked_m15 += 1; correct_m15 += int(m15_ok) if m1h_ok is not None: checked_m1h += 1; correct_m1h += int(m1h_ok) # accuracy marks marks = "" if m5_ok is not None: marks += f" 5m:{'✅' if m5_ok else '❌'}" if m15_ok is not None: marks += f" 15m:{'✅' if m15_ok else '❌'}" if m1h_ok is not None: marks += f" 1h:{'✅' if m1h_ok else '❌'}" print(f"[{i+1:03d}] {post.published_at.strftime('%m-%d %H:%M')} | {sig:5s} {conf:3d}% |{marks}") print(f" {post.text[:110]}") print(f" → {analysis['reasoning'][:200]}") print() await asyncio.sleep(0.2) print("=" * 70) print(f"总计: {len(posts)} 帖 | Relevant: {relevant_count} ({relevant_count/len(posts)*100:.0f}%)") print(f"信号: BUY={signals['buy']} SHORT={signals['short']} SELL={signals['sell']} HOLD={signals['hold']}") print() if checked_m5: print(f"准确率 5m: {correct_m5}/{checked_m5} = {correct_m5/checked_m5*100:.0f}%") if checked_m15: print(f"准确率 15m: {correct_m15}/{checked_m15} = {correct_m15/checked_m15*100:.0f}%") if checked_m1h: print(f"准确率 1h: {correct_m1h}/{checked_m1h} = {correct_m1h/checked_m1h*100:.0f}%") if __name__ == "__main__": asyncio.run(main())