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

1""" 

2交易管理API端点 

3""" 

4 

5from typing import List, Optional 

6 

7from fastapi import APIRouter, Depends, HTTPException, Query 

8from pydantic import BaseModel 

9 

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 

18 

19router = APIRouter() 

20 

21 

22# ===== 交易会话管理 ===== 

23 

24 

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) 

32 

33 

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) 

44 

45 

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 

56 

57 

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 

70 

71 

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": "交易会话已删除"} 

82 

83 

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 

94 

95 

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 

106 

107 

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 

118 

119 

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 

130 

131 

132# ===== 交易订单管理 ===== 

133 

134 

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 

145 

146 

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 

157 

158 

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 

171 

172 

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": "交易订单已取消"} 

183 

184 

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) 

196 

197 

198# ===== 持仓记录管理 ===== 

199 

200 

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) 

213 

214 

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} 

223 

224 

225# ===== 策略日志管理 ===== 

226 

227 

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 ) 

244 

245 

246# ===== 模拟交易 ===== 

247 

248 

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 

259 

260 

261# ===== 性能分析 ===== 

262 

263 

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 

274 

275 

276# ===== 风险控制 ===== 

277 

278 

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) 

286 

287 

288# ===== 交易引擎状态 ===== 

289 

290 

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) 

297 

298 # 检查会话是否属于当前用户 

299 session = trading_service.get_trading_session(session_id) 

300 if not session: 

301 raise HTTPException(status_code=404, detail="交易会话不存在") 

302 

303 return trading_service.get_trading_engine_status(session_id) 

304 

305 

306# ===== 风险管理 ===== 

307 

308 

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) 

315 

316 # 检查会话是否属于当前用户 

317 session = trading_service.get_trading_session(session_id) 

318 if not session: 

319 raise HTTPException(status_code=404, detail="交易会话不存在") 

320 

321 risk_summary = trading_service.get_risk_summary(session_id) 

322 if not risk_summary: 

323 raise HTTPException(status_code=404, detail="风险管理引擎不存在") 

324 

325 return risk_summary 

326 

327 

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) 

336 

337 # 检查会话是否属于当前用户 

338 session = trading_service.get_trading_session(session_id) 

339 if not session: 

340 raise HTTPException(status_code=404, detail="交易会话不存在") 

341 

342 events = trading_service.get_risk_events(session_id, limit) 

343 return {"events": events} 

344 

345 

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) 

352 

353 # 检查会话是否属于当前用户 

354 session = trading_service.get_trading_session(session_id) 

355 if not session: 

356 raise HTTPException(status_code=404, detail="交易会话不存在") 

357 

358 recommendations = trading_service.get_risk_recommendations(session_id) 

359 return {"recommendations": recommendations} 

360 

361 

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) 

368 

369 # 检查会话是否属于当前用户 

370 session = trading_service.get_trading_session(session_id) 

371 if not session: 

372 raise HTTPException(status_code=404, detail="交易会话不存在") 

373 

374 success = trading_service.reset_daily_risk_metrics(session_id) 

375 if not success: 

376 raise HTTPException(status_code=404, detail="风险管理引擎不存在") 

377 

378 return {"message": "日度风险指标已重置"}