feat: AI市场分析功能
- 后端:AI分析服务、工具调用、定时任务 - 前端:报告列表、详情页、Mermaid图表支持 - 支持OpenAI API兼容模型 - 收盘后自动分析生成报告
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""AI 分析定时任务
|
||||
|
||||
收盘后自动触发 AI 分析:
|
||||
- 15:01 collector_loop 采集核心股+题材数据
|
||||
- 15:10 ai_analysis_loop 触发 AI 分析(等数据采集完成)
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import traceback
|
||||
from datetime import datetime, time as dtime, timezone, timedelta
|
||||
from typing import Optional
|
||||
|
||||
from database import get_connection
|
||||
|
||||
_CST = timezone(timedelta(hours=8))
|
||||
|
||||
CHECK_INTERVAL_SECONDS = 300 # 每5分钟检查
|
||||
AI_ANALYSIS_TIME = dtime(15, 10) # 15:10 后触发
|
||||
|
||||
|
||||
def _is_trading_day(d: datetime) -> bool:
|
||||
"""仅按工作日判断"""
|
||||
return d.weekday() < 5
|
||||
|
||||
|
||||
def _has_ai_report(trade_date: str) -> bool:
|
||||
"""检查某日是否已有 AI 分析报告"""
|
||||
conn = get_connection()
|
||||
try:
|
||||
row = conn.execute(
|
||||
"SELECT 1 FROM ai_reports WHERE trade_date = ? AND report_type = 'daily' LIMIT 1",
|
||||
(trade_date,)
|
||||
).fetchone()
|
||||
return row is not None
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
async def ai_analysis_loop(stop: Optional[asyncio.Event] = None) -> None:
|
||||
"""后台循环:每个交易日 15:10 后自动触发 AI 分析(幂等)"""
|
||||
while True:
|
||||
try:
|
||||
now = datetime.now(_CST)
|
||||
if _is_trading_day(now) and now.time() >= AI_ANALYSIS_TIME:
|
||||
trade_date = now.strftime("%Y-%m-%d")
|
||||
if not _has_ai_report(trade_date):
|
||||
print(f"[ai-collector] 开始 AI 分析 {trade_date}")
|
||||
from services.ai_service import collect_ai_analysis
|
||||
result = await collect_ai_analysis(trade_date)
|
||||
print(f"[ai-collector] AI 分析完成 {trade_date},token 消耗: {result.get('tokens_used', 0)}")
|
||||
except Exception:
|
||||
print("[ai-collector] AI 分析异常:")
|
||||
traceback.print_exc()
|
||||
if stop is not None and stop.is_set():
|
||||
break
|
||||
await asyncio.sleep(CHECK_INTERVAL_SECONDS)
|
||||
Reference in New Issue
Block a user