96 lines
3.3 KiB
Python
Executable File
96 lines
3.3 KiB
Python
Executable File
"""
|
|
自动化回测服务 - 数据模型
|
|
"""
|
|
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
|