From 7aec55c9d09ce22e49a319c91b3752904e9ba2b3 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Tue, 28 Apr 2026 08:49:52 +0800 Subject: [PATCH] auto-sync: 2026-04-28 08:49:52 --- logs/auto-sync.log | 1 + scripts/backtest-service/models.py | 6 +- scripts/backtest-service/models.py.bak | 95 ++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100755 scripts/backtest-service/models.py.bak diff --git a/logs/auto-sync.log b/logs/auto-sync.log index 80a7a8ad..14cc576c 100644 --- a/logs/auto-sync.log +++ b/logs/auto-sync.log @@ -5373,5 +5373,6 @@ + diff --git a/scripts/backtest-service/models.py b/scripts/backtest-service/models.py index a0d67448..8ec1bae5 100755 --- a/scripts/backtest-service/models.py +++ b/scripts/backtest-service/models.py @@ -3,7 +3,7 @@ """ from enum import Enum from datetime import date, datetime -from typing import Dict, Optional, Any, List +from typing import Dict, Optional, Any, List, Generic, TypeVar from pydantic import BaseModel, Field @@ -79,7 +79,9 @@ class TaskListResponse(BaseModel): tasks: List[BacktestTaskWithId] -class ApiResponse[T](BaseModel): +T = TypeVar("T") + +class ApiResponse(BaseModel, Generic[T]): """通用API响应包装""" code: int = Field(0, description="0表示成功,非0表示错误") msg: str = Field("success", description="响应消息") diff --git a/scripts/backtest-service/models.py.bak b/scripts/backtest-service/models.py.bak new file mode 100755 index 00000000..a0d67448 --- /dev/null +++ b/scripts/backtest-service/models.py.bak @@ -0,0 +1,95 @@ +""" +自动化回测服务 - 数据模型 +""" +from enum import Enum +from datetime import date, datetime +from typing import Dict, Optional, Any, List +from pydantic import BaseModel, Field + + +class TaskStatus(str, Enum): + """任务状态枚举""" + PENDING = "pending" + RUNNING = "running" + COMPLETED = "completed" + FAILED = "failed" + + +class BacktestTask(BaseModel): + """回测任务请求""" + strategy_name: str = Field(..., description="策略名称") + strategy_code: str = Field(..., description="策略完整Python代码") + symbol: str = Field(..., description="交易品种,例如 000001.SSE") + interval: str = Field(..., description="K线周期,例如 1d、1h") + start_date: date = Field(..., description="回测开始日期") + end_date: date = Field(..., description="回测结束日期") + parameters: Dict[str, Any] = Field(default_factory=dict, description="策略参数字典") + capital: float = Field(default=1_000_000, description="起始资金") + tick_size: Optional[float] = Field(None, description="最小价格变动,不指定则自动获取") + + +class BacktestTaskWithId(BacktestTask): + """带ID和状态的回测任务""" + task_id: str = Field(..., description="任务唯一ID") + status: TaskStatus = Field(..., description="任务状态") + created_at: str = Field(..., description="创建时间 ISO格式") + started_at: Optional[str] = Field(None, description="开始时间") + completed_at: Optional[str] = Field(None, description="完成时间") + + +class BacktestStatistics(BaseModel): + """回测结果统计""" + start_date: str + end_date: str + total_days: int + total_trades: int + winning_trades: int + losing_trades: int + win_rate: float + total_return: float # 总收益率 + annual_return: float # 年化收益率 + sharpe_ratio: float # 夏普比率 + max_drawdown: float # 最大回撤 + max_drawdown_start: Optional[str] = None + max_drawdown_end: Optional[str] = None + profit_factor: float # 收益因子(总盈利/总亏损) + calmar_ratio: float # 卡玛比率(年化收益/最大回撤) + + +class BacktestResult(BaseModel): + """完整回测结果""" + task_id: str + strategy_name: str + status: TaskStatus + statistics: Optional[BacktestStatistics] = None + result_csv_path: str # 每日净值CSV路径 + equity_curve_png_path: Optional[str] = None # 收益曲线图片路径 + trades_csv_path: Optional[str] = None # 成交记录CSV路径 + error_message: Optional[str] = None # 失败时的错误信息 + created_at: str + started_at: Optional[str] = None + completed_at: Optional[str] = None + + +class TaskListResponse(BaseModel): + """任务列表响应""" + total: int + page: int + page_size: int + tasks: List[BacktestTaskWithId] + + +class ApiResponse[T](BaseModel): + """通用API响应包装""" + code: int = Field(0, description="0表示成功,非0表示错误") + msg: str = Field("success", description="响应消息") + data: Optional[T] = Field(None, description="响应数据") + + +class HealthCheckResponse(BaseModel): + """健康检查响应""" + pending_count: int + running_count: int + completed_count: int + failed_count: int + max_workers: int