Coverage for api/v1/endpoints/risk_management.py: 51.11%
90 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 Any, Dict, List, Optional
7from fastapi import APIRouter, Depends, HTTPException
8from pydantic import BaseModel
10from core.middleware.auth_middleware import get_current_user
11from core.models.risk_config import RiskConfigModel
12from core.models.user import User
13from core.services.risk_service import RiskService
15router = APIRouter()
18class RiskConfigRequest(BaseModel):
19 """风险配置请求"""
21 config: Dict[str, Any]
24class RiskConfigResponse(BaseModel):
25 """风险配置响应"""
27 valid: bool
28 config: Dict[str, Any] = {}
29 errors: List[str] = []
30 warnings: List[str] = []
33class RiskSummaryResponse(BaseModel):
34 """风险摘要响应"""
36 user_id: str
37 risk_config: Dict[str, Any]
38 daily_turnover: float
39 daily_pnl: float
40 current_drawdown: float
41 max_portfolio_value: float
42 risk_events_count: int
43 last_risk_event: Optional[Dict[str, Any]] = None
46@router.get("/presets", response_model=List[Dict[str, Any]])
47async def get_risk_presets(current_user: User = Depends(get_current_user)):
48 """获取风险配置预设"""
49 risk_service = RiskService(current_user.id)
50 return risk_service.get_risk_presets()
53@router.get("/presets/{preset_name}")
54async def get_risk_preset_by_name(
55 preset_name: str, current_user: User = Depends(get_current_user)
56):
57 """根据名称获取风险配置预设"""
58 risk_service = RiskService(current_user.id)
59 preset = risk_service.get_risk_preset_by_name(preset_name)
61 if not preset:
62 raise HTTPException(status_code=404, detail="风险配置预设不存在")
64 return preset
67@router.get("/default", response_model=Dict[str, Any])
68async def get_default_risk_config(current_user: User = Depends(get_current_user)):
69 """获取默认风险配置"""
70 risk_service = RiskService(current_user.id)
71 return risk_service.get_default_risk_config()
74@router.get("/conservative", response_model=Dict[str, Any])
75async def get_conservative_risk_config(current_user: User = Depends(get_current_user)):
76 """获取保守风险配置"""
77 risk_service = RiskService(current_user.id)
78 return risk_service.get_conservative_risk_config()
81@router.get("/aggressive", response_model=Dict[str, Any])
82async def get_aggressive_risk_config(current_user: User = Depends(get_current_user)):
83 """获取激进风险配置"""
84 risk_service = RiskService(current_user.id)
85 return risk_service.get_aggressive_risk_config()
88@router.post("/validate", response_model=RiskConfigResponse)
89async def validate_risk_config(
90 request: RiskConfigRequest, current_user: User = Depends(get_current_user)
91):
92 """验证风险配置"""
93 risk_service = RiskService(current_user.id)
94 result = risk_service.validate_risk_config(request.config)
96 return RiskConfigResponse(
97 valid=result["valid"],
98 config=result["config"],
99 errors=result["errors"],
100 warnings=result["warnings"],
101 )
104@router.get("/sessions/{session_id}/summary", response_model=RiskSummaryResponse)
105async def get_session_risk_summary(
106 session_id: str, current_user: User = Depends(get_current_user)
107):
108 """获取会话风险摘要"""
109 risk_service = RiskService(current_user.id)
110 summary = risk_service.get_risk_summary(session_id)
112 if not summary:
113 raise HTTPException(status_code=404, detail="风险管理引擎不存在")
115 return RiskSummaryResponse(
116 user_id=summary["user_id"],
117 risk_config=summary["risk_config"],
118 daily_turnover=float(summary["daily_turnover"]),
119 daily_pnl=float(summary["daily_pnl"]),
120 current_drawdown=float(summary["current_drawdown"]),
121 max_portfolio_value=float(summary["max_portfolio_value"]),
122 risk_events_count=summary["risk_events_count"],
123 last_risk_event=summary["last_risk_event"],
124 )
127@router.get("/sessions/{session_id}/events")
128async def get_session_risk_events(
129 session_id: str, limit: int = 100, current_user: User = Depends(get_current_user)
130):
131 """获取会话风险事件"""
132 risk_service = RiskService(current_user.id)
133 events = risk_service.get_risk_events(session_id, limit)
135 if events is None:
136 raise HTTPException(status_code=404, detail="风险管理引擎不存在")
138 return {"events": events}
141@router.post("/sessions/{session_id}/reset-daily")
142async def reset_session_daily_risk_metrics(
143 session_id: str, current_user: User = Depends(get_current_user)
144):
145 """重置会话日度风险指标"""
146 risk_service = RiskService(current_user.id)
147 success = risk_service.reset_daily_risk_metrics(session_id)
149 if not success:
150 raise HTTPException(status_code=404, detail="风险管理引擎不存在")
152 return {"message": "日度风险指标已重置"}
155@router.get("/sessions/{session_id}/recommendations")
156async def get_session_risk_recommendations(
157 session_id: str, current_user: User = Depends(get_current_user)
158):
159 """获取会话风险建议"""
160 risk_service = RiskService(current_user.id)
161 recommendations = risk_service.get_risk_recommendations(session_id)
163 if recommendations is None:
164 raise HTTPException(status_code=404, detail="风险管理引擎不存在")
166 return {"recommendations": recommendations}
169@router.put("/sessions/{session_id}/config")
170async def update_session_risk_config(
171 session_id: str,
172 request: RiskConfigRequest,
173 current_user: User = Depends(get_current_user),
174):
175 """更新会话风险配置"""
176 risk_service = RiskService(current_user.id)
178 # 验证配置
179 validation_result = risk_service.validate_risk_config(request.config)
180 if not validation_result["valid"]:
181 raise HTTPException(
182 status_code=400, detail=f"风险配置验证失败: {validation_result['errors']}"
183 )
185 # 更新配置
186 success = risk_service.update_risk_config(session_id, request.config)
188 if not success:
189 raise HTTPException(status_code=404, detail="风险管理引擎不存在")
191 return {"message": "风险配置已更新", "config": validation_result["config"]}