198 lines
5.6 KiB
Python
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 |