QSSS_new / backend /app /api /v1 /endpoints /backtests.py
misonL's picture
特性:实现对话框、表单、输入框、标签、下拉菜单、分隔线、骨架屏、滑块、表格、文本区域的 UI 组件
c78ce9e
Raw
History Blame Contribute Delete
4.1 kB
from fastapi import APIRouter, Depends, HTTPException
from typing import List, Dict, Any, Optional
import json # 导入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": "回测结果已删除"}