Files
sanguo_vnpy_v2/sanguo_web/api/routes/trades.py
T
claude_dev 653472def3 feat: VeighNa Web 前端对等实现
对齐 VeighNa 4.4 原生 Qt UI,新增成交监控、资金监控、网关管理、全局配置等页面与 API,功能对等性 98.5%。

- 新增 API: /api/v1/trades, /api/v1/accounts, /api/v1/settings, 网关扩展
- 新增前端页面: 成交、资金、合约、网关、全局配置、微信通知
- 扩展导航菜单与实时数据推送
- 补充需求分析与实现计划文档
2026-07-04 20:13:03 +08:00

163 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
成交监控路由
处理成交记录查询
"""
from fastapi import APIRouter, Depends, HTTPException, status
from typing import List, Optional
from datetime import datetime
import logging
from ..deps import get_current_user, get_vn_service
logger = logging.getLogger(__name__)
router = APIRouter()
@router.get("/", response_model=List[dict])
async def get_all_trades(
current_user: dict = Depends(get_current_user),
vn_service=Depends(get_vn_service)
):
"""
获取所有成交记录
返回所有成交记录,包括成交号、委托号、合约代码、方向、开平、价格、数量、时间等信息
"""
trades = await vn_service.get_trades()
return [
{
"tradeid": t.get("trade_id", ""),
"orderid": t.get("order_id", ""),
"symbol": t.get("symbol", ""),
"exchange": t.get("exchange", ""),
"direction": t.get("direction", ""),
"offset": t.get("offset", ""),
"price": t.get("price", 0.0),
"volume": t.get("volume", 0),
"datetime": _format_datetime(t.get("time")),
"gateway_name": t.get("gateway_name", ""),
}
for t in trades
]
@router.get("/latest", response_model=List[dict])
async def get_latest_trades(
limit: int = 50,
current_user: dict = Depends(get_current_user),
vn_service=Depends(get_vn_service)
):
"""
获取最新的成交记录
- **limit**: 返回记录数量,默认 50 条
"""
trades = await vn_service.get_trades()
# 按时间降序排序,取最新的 limit 条
sorted_trades = sorted(
trades,
key=lambda x: x.get("time", datetime.min),
reverse=True
)[:limit]
return [
{
"tradeid": t.get("trade_id", ""),
"orderid": t.get("order_id", ""),
"symbol": t.get("symbol", ""),
"exchange": t.get("exchange", ""),
"direction": t.get("direction", ""),
"offset": t.get("offset", ""),
"price": t.get("price", 0.0),
"volume": t.get("volume", 0),
"datetime": _format_datetime(t.get("time")),
"gateway_name": t.get("gateway_name", ""),
}
for t in sorted_trades
]
@router.get("/order/{vt_orderid}", response_model=List[dict])
async def get_trades_by_order(
vt_orderid: str,
current_user: dict = Depends(get_current_user),
vn_service=Depends(get_vn_service)
):
"""
获取指定委托的所有成交记录
- **vt_orderid**: 委托号(格式:gateway_name.orderid
"""
all_trades = await vn_service.get_trades()
filtered_trades = [
t for t in all_trades
if t.get("order_id", "") == vt_orderid
]
return [
{
"tradeid": t.get("trade_id", ""),
"orderid": t.get("order_id", ""),
"symbol": t.get("symbol", ""),
"exchange": t.get("exchange", ""),
"direction": t.get("direction", ""),
"offset": t.get("offset", ""),
"price": t.get("price", 0.0),
"volume": t.get("volume", 0),
"datetime": _format_datetime(t.get("time")),
"gateway_name": t.get("gateway_name", ""),
}
for t in filtered_trades
]
@router.get("/symbol/{symbol}", response_model=List[dict])
async def get_trades_by_symbol(
symbol: str,
current_user: dict = Depends(get_current_user),
vn_service=Depends(get_vn_service)
):
"""
获取指定合约的所有成交记录
- **symbol**: 合约代码
"""
all_trades = await vn_service.get_trades()
filtered_trades = [
t for t in all_trades
if t.get("symbol", "") == symbol
]
return [
{
"tradeid": t.get("trade_id", ""),
"orderid": t.get("order_id", ""),
"symbol": t.get("symbol", ""),
"exchange": t.get("exchange", ""),
"direction": t.get("direction", ""),
"offset": t.get("offset", ""),
"price": t.get("price", 0.0),
"volume": t.get("volume", 0),
"datetime": _format_datetime(t.get("time")),
"gateway_name": t.get("gateway_name", ""),
}
for t in filtered_trades
]
def _format_datetime(dt: Optional[datetime]) -> str:
"""格式化 datetime 对象为字符串"""
if dt is None:
return ""
if isinstance(dt, datetime):
return dt.strftime("%Y-%m-%d %H:%M:%S")
return str(dt)
__all__ = ["router"]