This commit is contained in:
k
2026-04-21 19:33:24 +08:00
parent 9a72566753
commit 3268080401
26 changed files with 1816 additions and 318 deletions
+84
View File
@@ -0,0 +1,84 @@
"""
批量回跑语义分析 — 验证新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())