Files
AI-Trader/routes_news.py

198 lines
5.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
新闻路由
财经日历、快讯查询和WebSocket推送
"""
from fastapi import APIRouter, Query, WebSocket, WebSocketDisconnect
from fastapi.responses import JSONResponse
from typing import Optional
def create_news_routes():
"""创建新闻相关路由"""
router = APIRouter(prefix="/api/news", tags=["新闻"])
@router.get("/calendar")
async def get_calendar(
date: Optional[str] = Query(None, description="日期,格式: 2026-03-15,不传返回所有")
):
"""
获取财经日历
返回指定日期或所有日期的财经事件
"""
from market.market_event_monitor import get_market_event_monitor
monitor = get_market_event_monitor()
calendar = monitor.get_calendar(date)
return {
"status": "ok",
"date": date,
"count": len(calendar),
"data": calendar
}
@router.get("/upcoming")
async def get_upcoming(
hours: int = Query(24, description="未来多少小时内的事件")
):
"""
获取即将发布的重要事件
默认返回未来24小时内的重要财经事件
"""
from market.market_event_monitor import get_market_event_monitor
monitor = get_market_event_monitor()
events = monitor.get_upcoming_events(hours)
return {
"status": "ok",
"hours": hours,
"count": len(events),
"data": events
}
@router.get("/flash")
async def get_flash_news(
count: int = Query(20, description="获取数量,默认20")
):
"""
获取最新快讯
返回最近的有影响的快讯(关键人物讲话、重要事件)
"""
from market.market_event_monitor import get_market_event_monitor
monitor = get_market_event_monitor()
news_list = monitor.get_recent_news(count)
return {
"status": "ok",
"count": len(news_list),
"data": news_list
}
@router.get("/status")
async def get_status():
"""
获取新闻模块状态
"""
from market.market_event_monitor import get_market_event_monitor
monitor = get_market_event_monitor()
status = monitor.get_status()
return {
"status": "ok",
"data": status
}
@router.websocket("/ws")
async def news_websocket(websocket: WebSocket):
"""
市场事件WebSocket推送
推送内容类型:
- calendar_event_reminder: 财经日历事件发布前提醒
- calendar_update: 日历更新
- flash_news: 重要快讯
"""
from market.market_event_monitor import get_market_event_monitor
monitor = get_market_event_monitor()
await websocket.accept()
monitor.ws_manager.add_client(websocket)
try:
# 发送欢迎消息
await websocket.send_json({
"type": "connected",
"message": "已连接到市场事件推送服务"
})
# 保持连接,等待客户端消息或断开
while True:
# 接收客户端消息(心跳等)
data = await websocket.receive_text()
# 处理心跳
if data == "ping":
await websocket.send_json({"type": "pong"})
except WebSocketDisconnect:
pass
except Exception as e:
print(f"[MarketEventWebSocket] 连接异常: {e}")
finally:
monitor.ws_manager.remove_client(websocket)
@router.get("/impact/{symbol}")
async def get_symbol_impact(symbol: str):
"""
获取特定品种的相关事件
返回影响该品种的即将发布事件
"""
from market.market_event_monitor import get_market_event_monitor
from market.event_config import WATCH_SYMBOLS
if symbol not in WATCH_SYMBOLS:
return {
"status": "error",
"message": f"不支持的品种: {symbol}",
"supported_symbols": WATCH_SYMBOLS
}
monitor = get_market_event_monitor()
events = monitor.get_upcoming_events(72) # 未来3天
# 过滤相关事件
related_events = [
e for e in events
if symbol in e.get('symbols', [])
]
return {
"status": "ok",
"symbol": symbol,
"count": len(related_events),
"data": related_events
}
@router.post("/calendar/clear")
async def clear_calendar():
"""
清空财经日历数据
清空后需要EA重新推送日历数据(会应用时区转换)
"""
from market.market_event_monitor import get_market_event_monitor
monitor = get_market_event_monitor()
monitor.clear_calendar()
return {
"status": "ok",
"message": "财经日历数据已清空,请让EA重新推送日历数据"
}
@router.delete("/calendar")
async def clear_calendar_delete():
"""
清空财经日历数据 (DELETE方法)
清空后需要EA重新推送日历数据(会应用时区转换)
"""
from market.market_event_monitor import get_market_event_monitor
monitor = get_market_event_monitor()
monitor.clear_calendar()
return {
"status": "ok",
"message": "财经日历数据已清空,请让EA重新推送日历数据"
}
return router