Coverage for api/v1/endpoints/trading.py: 33.92%
171 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-13 18:58 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-13 18:58 +0000
1"""
2交易管理API端点
3"""
5from typing import List, Optional
7from fastapi import APIRouter, Depends, HTTPException, Query
8from pydantic import BaseModel
10from core.middleware.auth_middleware import get_current_user
11from core.models.trading import (OrderStatus, PositionHistoryResponse,
12 SessionStatus, TradingOrderCreate,
13 TradingOrderResponse, TradingOrderUpdate,
14 TradingSessionCreate, TradingSessionResponse,
15 TradingSessionUpdate)
16from core.models.user import User
17from core.services.trading_service import TradingService
19router = APIRouter()
22# ===== 交易会话管理 =====
25@router.post("/sessions", response_model=TradingSessionResponse)
26async def create_trading_session(
27 session_data: TradingSessionCreate, current_user: User = Depends(get_current_user)
28):
29 """创建交易会话"""
30 trading_service = TradingService(current_user.id)
31 return trading_service.create_trading_session(session_data)
34@router.get("/sessions", response_model=List[TradingSessionResponse])
35async def get_trading_sessions(
36 status: Optional[SessionStatus] = Query(None, description="会话状态筛选"),
37 limit: int = Query(10, ge=1, le=100, description="每页数量"),
38 offset: int = Query(0, ge=0, description="偏移量"),
39 current_user: User = Depends(get_current_user),
40):
41 """获取交易会话列表"""
42 trading_service = TradingService(current_user.id)
43 return trading_service.get_user_trading_sessions(status, limit, offset)
46@router.get("/sessions/{session_id}", response_model=TradingSessionResponse)
47async def get_trading_session(
48 session_id: str, current_user: User = Depends(get_current_user)
49):
50 """获取交易会话详情"""
51 trading_service = TradingService(current_user.id)
52 session = trading_service.get_trading_session(session_id)
53 if not session:
54 raise HTTPException(status_code=404, detail="交易会话不存在")
55 return session
58@router.put("/sessions/{session_id}", response_model=TradingSessionResponse)
59async def update_trading_session(
60 session_id: str,
61 update_data: TradingSessionUpdate,
62 current_user: User = Depends(get_current_user),
63):
64 """更新交易会话"""
65 trading_service = TradingService(current_user.id)
66 session = trading_service.update_trading_session(session_id, update_data)
67 if not session:
68 raise HTTPException(status_code=404, detail="交易会话不存在")
69 return session
72@router.delete("/sessions/{session_id}")
73async def delete_trading_session(
74 session_id: str, current_user: User = Depends(get_current_user)
75):
76 """删除交易会话"""
77 trading_service = TradingService(current_user.id)
78 success = trading_service.delete_trading_session(session_id)
79 if not success:
80 raise HTTPException(status_code=404, detail="交易会话不存在")
81 return {"message": "交易会话已删除"}
84@router.post("/sessions/{session_id}/start", response_model=TradingSessionResponse)
85async def start_trading_session(
86 session_id: str, current_user: User = Depends(get_current_user)
87):
88 """启动交易会话"""
89 trading_service = TradingService(current_user.id)
90 session = trading_service.start_trading_session(session_id)
91 if not session:
92 raise HTTPException(status_code=404, detail="交易会话不存在或无法启动")
93 return session
96@router.post("/sessions/{session_id}/stop", response_model=TradingSessionResponse)
97async def stop_trading_session(
98 session_id: str, current_user: User = Depends(get_current_user)
99):
100 """停止交易会话"""
101 trading_service = TradingService(current_user.id)
102 session = trading_service.stop_trading_session(session_id)
103 if not session:
104 raise HTTPException(status_code=404, detail="交易会话不存在或无法停止")
105 return session
108@router.post("/sessions/{session_id}/pause", response_model=TradingSessionResponse)
109async def pause_trading_session(
110 session_id: str, current_user: User = Depends(get_current_user)
111):
112 """暂停交易会话"""
113 trading_service = TradingService(current_user.id)
114 session = trading_service.pause_trading_session(session_id)
115 if not session:
116 raise HTTPException(status_code=404, detail="交易会话不存在或无法暂停")
117 return session
120@router.post("/sessions/{session_id}/resume", response_model=TradingSessionResponse)
121async def resume_trading_session(
122 session_id: str, current_user: User = Depends(get_current_user)
123):
124 """恢复交易会话"""
125 trading_service = TradingService(current_user.id)
126 session = trading_service.resume_trading_session(session_id)
127 if not session:
128 raise HTTPException(status_code=404, detail="交易会话不存在或无法恢复")
129 return session
132# ===== 交易订单管理 =====
135@router.post("/orders", response_model=TradingOrderResponse)
136async def create_trading_order(
137 order_data: TradingOrderCreate, current_user: User = Depends(get_current_user)
138):
139 """创建交易订单"""
140 trading_service = TradingService(current_user.id)
141 order = trading_service.create_trading_order(order_data)
142 if not order:
143 raise HTTPException(status_code=400, detail="无法创建交易订单")
144 return order
147@router.get("/orders/{order_id}", response_model=TradingOrderResponse)
148async def get_trading_order(
149 order_id: str, current_user: User = Depends(get_current_user)
150):
151 """获取交易订单详情"""
152 trading_service = TradingService(current_user.id)
153 order = trading_service.get_trading_order(order_id)
154 if not order:
155 raise HTTPException(status_code=404, detail="交易订单不存在")
156 return order
159@router.put("/orders/{order_id}", response_model=TradingOrderResponse)
160async def update_trading_order(
161 order_id: str,
162 update_data: TradingOrderUpdate,
163 current_user: User = Depends(get_current_user),
164):
165 """更新交易订单"""
166 trading_service = TradingService(current_user.id)
167 order = trading_service.update_trading_order(order_id, update_data)
168 if not order:
169 raise HTTPException(status_code=404, detail="交易订单不存在")
170 return order
173@router.post("/orders/{order_id}/cancel")
174async def cancel_trading_order(
175 order_id: str, current_user: User = Depends(get_current_user)
176):
177 """取消交易订单"""
178 trading_service = TradingService(current_user.id)
179 success = trading_service.cancel_order(order_id)
180 if not success:
181 raise HTTPException(status_code=404, detail="交易订单不存在或无法取消")
182 return {"message": "交易订单已取消"}
185@router.get("/sessions/{session_id}/orders", response_model=List[TradingOrderResponse])
186async def get_session_orders(
187 session_id: str,
188 status: Optional[OrderStatus] = Query(None, description="订单状态筛选"),
189 limit: int = Query(100, ge=1, le=1000, description="每页数量"),
190 offset: int = Query(0, ge=0, description="偏移量"),
191 current_user: User = Depends(get_current_user),
192):
193 """获取会话订单列表"""
194 trading_service = TradingService(current_user.id)
195 return trading_service.get_session_orders(session_id, status, limit, offset)
198# ===== 持仓记录管理 =====
201@router.get(
202 "/sessions/{session_id}/positions", response_model=List[PositionHistoryResponse]
203)
204async def get_session_positions(
205 session_id: str,
206 limit: int = Query(100, ge=1, le=1000, description="每页数量"),
207 offset: int = Query(0, ge=0, description="偏移量"),
208 current_user: User = Depends(get_current_user),
209):
210 """获取会话持仓记录列表"""
211 trading_service = TradingService(current_user.id)
212 return trading_service.get_session_positions(session_id, limit, offset)
215@router.get("/sessions/{session_id}/positions/latest")
216async def get_latest_positions(
217 session_id: str, current_user: User = Depends(get_current_user)
218):
219 """获取最新持仓快照"""
220 trading_service = TradingService(current_user.id)
221 positions = trading_service.get_latest_positions(session_id)
222 return {"positions": positions}
225# ===== 策略日志管理 =====
228@router.get("/sessions/{session_id}/logs")
229async def get_session_logs(
230 session_id: str,
231 page: int = Query(1, ge=1, description="页码"),
232 pageSize: int = Query(20, ge=1, le=5000, description="每页数量"),
233 search: Optional[str] = Query(None, description="搜索关键词"),
234 startDate: Optional[str] = Query(None, description="开始日期(ISO格式)"),
235 endDate: Optional[str] = Query(None, description="结束日期(ISO格式)"),
236 component: Optional[str] = Query(None, description="组件名称过滤"),
237 current_user: User = Depends(get_current_user),
238):
239 """获取会话策略日志"""
240 trading_service = TradingService(current_user.id)
241 return trading_service.get_session_logs(
242 session_id, page, pageSize, search, startDate, endDate, component
243 )
246# ===== 模拟交易 =====
249@router.post("/simulation/orders", response_model=TradingOrderResponse)
250async def submit_simulation_order(
251 order_data: TradingOrderCreate, current_user: User = Depends(get_current_user)
252):
253 """提交模拟交易订单"""
254 trading_service = TradingService(current_user.id)
255 order = trading_service.submit_simulation_order(order_data)
256 if not order:
257 raise HTTPException(status_code=400, detail="无法提交模拟交易订单")
258 return order
261# ===== 性能分析 =====
264@router.get("/sessions/{session_id}/performance")
265async def get_session_performance(
266 session_id: str, current_user: User = Depends(get_current_user)
267):
268 """获取会话性能指标"""
269 trading_service = TradingService(current_user.id)
270 metrics = trading_service.calculate_performance_metrics(session_id)
271 if not metrics:
272 raise HTTPException(status_code=404, detail="无法计算性能指标")
273 return metrics
276# ===== 风险控制 =====
279@router.post("/orders/validate")
280async def validate_order_risk(
281 order_data: TradingOrderCreate, current_user: User = Depends(get_current_user)
282):
283 """验证订单风险"""
284 trading_service = TradingService(current_user.id)
285 return trading_service.validate_order_risk(order_data)
288# ===== 交易引擎状态 =====
291@router.get("/sessions/{session_id}/engine/status")
292async def get_trading_engine_status(
293 session_id: str, current_user: User = Depends(get_current_user)
294):
295 """获取交易引擎状态"""
296 trading_service = TradingService(current_user.id)
298 # 检查会话是否属于当前用户
299 session = trading_service.get_trading_session(session_id)
300 if not session:
301 raise HTTPException(status_code=404, detail="交易会话不存在")
303 return trading_service.get_trading_engine_status(session_id)
306# ===== 风险管理 =====
309@router.get("/sessions/{session_id}/risk/summary")
310async def get_session_risk_summary(
311 session_id: str, current_user: User = Depends(get_current_user)
312):
313 """获取会话风险摘要"""
314 trading_service = TradingService(current_user.id)
316 # 检查会话是否属于当前用户
317 session = trading_service.get_trading_session(session_id)
318 if not session:
319 raise HTTPException(status_code=404, detail="交易会话不存在")
321 risk_summary = trading_service.get_risk_summary(session_id)
322 if not risk_summary:
323 raise HTTPException(status_code=404, detail="风险管理引擎不存在")
325 return risk_summary
328@router.get("/sessions/{session_id}/risk/events")
329async def get_session_risk_events(
330 session_id: str,
331 limit: int = Query(100, ge=1, le=1000, description="事件数量限制"),
332 current_user: User = Depends(get_current_user),
333):
334 """获取会话风险事件"""
335 trading_service = TradingService(current_user.id)
337 # 检查会话是否属于当前用户
338 session = trading_service.get_trading_session(session_id)
339 if not session:
340 raise HTTPException(status_code=404, detail="交易会话不存在")
342 events = trading_service.get_risk_events(session_id, limit)
343 return {"events": events}
346@router.get("/sessions/{session_id}/risk/recommendations")
347async def get_session_risk_recommendations(
348 session_id: str, current_user: User = Depends(get_current_user)
349):
350 """获取会话风险建议"""
351 trading_service = TradingService(current_user.id)
353 # 检查会话是否属于当前用户
354 session = trading_service.get_trading_session(session_id)
355 if not session:
356 raise HTTPException(status_code=404, detail="交易会话不存在")
358 recommendations = trading_service.get_risk_recommendations(session_id)
359 return {"recommendations": recommendations}
362@router.post("/sessions/{session_id}/risk/reset-daily")
363async def reset_session_daily_risk_metrics(
364 session_id: str, current_user: User = Depends(get_current_user)
365):
366 """重置会话日度风险指标"""
367 trading_service = TradingService(current_user.id)
369 # 检查会话是否属于当前用户
370 session = trading_service.get_trading_session(session_id)
371 if not session:
372 raise HTTPException(status_code=404, detail="交易会话不存在")
374 success = trading_service.reset_daily_risk_metrics(session_id)
375 if not success:
376 raise HTTPException(status_code=404, detail="风险管理引擎不存在")
378 return {"message": "日度风险指标已重置"}