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

1""" 

2风险管理API端点 

3""" 

4 

5from typing import Any, Dict, List, Optional 

6 

7from fastapi import APIRouter, Depends, HTTPException 

8from pydantic import BaseModel 

9 

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 

14 

15router = APIRouter() 

16 

17 

18class RiskConfigRequest(BaseModel): 

19 """风险配置请求""" 

20 

21 config: Dict[str, Any] 

22 

23 

24class RiskConfigResponse(BaseModel): 

25 """风险配置响应""" 

26 

27 valid: bool 

28 config: Dict[str, Any] = {} 

29 errors: List[str] = [] 

30 warnings: List[str] = [] 

31 

32 

33class RiskSummaryResponse(BaseModel): 

34 """风险摘要响应""" 

35 

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 

44 

45 

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() 

51 

52 

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) 

60 

61 if not preset: 

62 raise HTTPException(status_code=404, detail="风险配置预设不存在") 

63 

64 return preset 

65 

66 

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() 

72 

73 

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() 

79 

80 

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() 

86 

87 

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) 

95 

96 return RiskConfigResponse( 

97 valid=result["valid"], 

98 config=result["config"], 

99 errors=result["errors"], 

100 warnings=result["warnings"], 

101 ) 

102 

103 

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) 

111 

112 if not summary: 

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

114 

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 ) 

125 

126 

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) 

134 

135 if events is None: 

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

137 

138 return {"events": events} 

139 

140 

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) 

148 

149 if not success: 

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

151 

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

153 

154 

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) 

162 

163 if recommendations is None: 

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

165 

166 return {"recommendations": recommendations} 

167 

168 

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) 

177 

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 ) 

184 

185 # 更新配置 

186 success = risk_service.update_risk_config(session_id, request.config) 

187 

188 if not success: 

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

190 

191 return {"message": "风险配置已更新", "config": validation_result["config"]}