| from fastapi import APIRouter, Depends, HTTPException |
| from typing import List, Dict, Any, Optional |
| import json |
| from sqlalchemy.orm import Session |
|
|
| from app.core.deps import get_db, get_current_user |
| from app.models.user import User |
| from app.models.backtest_result import BacktestResult |
| from app.schemas.backtest import ( |
| BacktestResultResponse, |
| BacktestDetailResponse |
| ) |
|
|
| router = APIRouter() |
|
|
|
|
| @router.get("/", response_model=List[BacktestResultResponse]) |
| async def get_backtest_results( |
| db: Session = Depends(get_db), |
| current_user: User = Depends(get_current_user), |
| strategy_id: Optional[int] = None, |
| skip: int = 0, |
| limit: int = 20 |
| ): |
| """获取回测结果列表""" |
| filters = {"user_id": current_user.id} |
| if strategy_id: |
| filters["strategy_id"] = strategy_id |
|
|
| results = await BacktestResult.filter( |
| **filters |
| ).prefetch_related("strategy").order_by( |
| "-created_at" |
| ).offset(skip).limit(limit).all() |
|
|
| response_results = [] |
| for result in results: |
| response_results.append({ |
| "id": result.id, |
| "strategy_id": result.strategy_id, |
| "strategy_name": result.strategy.name, |
| "start_date": result.start_date, |
| "end_date": result.end_date, |
| "initial_capital": result.initial_capital, |
| "final_capital": result.final_capital, |
| "total_return": result.total_return, |
| "annual_return": result.annual_return, |
| "sharpe_ratio": result.sharpe_ratio, |
| "max_drawdown": result.max_drawdown, |
| "win_rate": result.win_rate, |
| "created_at": result.created_at |
| }) |
|
|
| return response_results |
|
|
|
|
| @router.get("/{backtest_id}", response_model=BacktestDetailResponse) |
| async def get_backtest_result( |
| backtest_id: int, |
| db: Session = Depends(get_db), |
| current_user: User = Depends(get_current_user) |
| ): |
| """获取回测结果详情""" |
| result = await BacktestResult.filter( |
| id=backtest_id |
| ).prefetch_related("strategy").first() |
| if not result: |
| raise HTTPException(status_code=404, detail="回测结果不存在") |
|
|
| |
| if result.user_id != current_user.id and not current_user.is_admin: |
| raise HTTPException(status_code=403, detail="没有权限查看此回测结果") |
|
|
| |
| trades = [] |
| daily_values = [] |
|
|
| if result.results_data: |
| try: |
| results_data = json.loads(result.results_data) |
| trades = results_data.get("trades", []) |
| daily_values = results_data.get("daily_values", []) |
| except Exception: |
| |
| pass |
|
|
| return { |
| "id": result.id, |
| "strategy_id": result.strategy_id, |
| "strategy_name": result.strategy.name, |
| "user_id": result.user_id, |
| "start_date": result.start_date, |
| "end_date": result.end_date, |
| "initial_capital": result.initial_capital, |
| "final_capital": result.final_capital, |
| "total_return": result.total_return, |
| "annual_return": result.annual_return, |
| "sharpe_ratio": result.sharpe_ratio, |
| "max_drawdown": result.max_drawdown, |
| "win_rate": result.win_rate, |
| "trades": trades, |
| "daily_values": daily_values, |
| "created_at": result.created_at |
| } |
|
|
|
|
| @router.delete("/{backtest_id}", response_model=Dict[str, Any]) |
| async def delete_backtest_result( |
| backtest_id: int, |
| db: Session = Depends(get_db), |
| current_user: User = Depends(get_current_user) |
| ): |
| """删除回测结果""" |
| result = await BacktestResult.get(id=backtest_id) |
| if not result: |
| raise HTTPException(status_code=404, detail="回测结果不存在") |
|
|
| |
| if result.user_id != current_user.id and not current_user.is_admin: |
| raise HTTPException(status_code=403, detail="没有权限删除此回测结果") |
|
|
| |
| await result.delete() |
|
|
| return {"success": True, "message": "回测结果已删除"} |
|
|