Files
trade/engine/backtest/models.py
T
Rekey 4da520c14b feat(engine): 添加事件驱动回测引擎
- backtest/engine.py: 事件驱动回测引擎核心,支持 K 线推进/订单撮合/权益曲线
- backtest/models.py: 回测数据模型(订单/成交/持仓/账户快照)
- backtest/README.md: 回测模块使用说明
- backtest/STRATEGY.md: 策略开发指南与最佳实践
- backtest/TIMEFRAME_COMPARISON*.md: 多周期回测对比分析报告
2026-06-12 10:26:53 +08:00

147 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
回测引擎数据模型 — 配置、交易记录、绩效指标和结果
"""
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional
@dataclass
class BacktestConfig:
"""回测配置
Attributes:
symbol: 交易对(如 BTCUSDT
exchange: 交易所标识
interval: K 线周期
start_time: 回测起始时间(None 表示从最早可用数据开始)
end_time: 回测结束时间(None 表示到最新可用数据结束)
commission_pct: 手续费率(0.001 = 0.1%
slippage_pct: 滑点率(0.0005 = 0.05%
min_order_qty: 最小下单量
initial_capital: 初始资金(Quote 币种,如 USDT)
warmup_bars: 预热 K 线条数(策略初始化指标所需最少数据量)
"""
symbol: str
exchange: str = "binance"
interval: str = "1h"
start_time: Optional[datetime] = None
end_time: Optional[datetime] = None
# 交易成本
commission_pct: float = 0.001
slippage_pct: float = 0.0005
min_order_qty: float = 0.001
# 资金
initial_capital: float = 10_000.0
# 数据
warmup_bars: int = 100
@dataclass
class BacktestTrade:
"""单笔回测交易记录"""
timestamp: float
"""成交时间(Unix 毫秒)"""
symbol: str
"""交易对"""
side: str
"""方向:BUY / SELL"""
price: float
"""成交价格(含滑点)"""
quantity: float
"""成交数量(Base 币种)"""
notional: float
"""成交额(Quote 币种 = price × quantity"""
commission: float
"""手续费"""
slippage: float
"""滑点成本"""
pnl: Optional[float] = None
"""平仓盈亏(BUY 时为 None,SELL 时有效)"""
reason: str = ""
"""交易原因(来自 Signal.reason"""
@dataclass
class BacktestMetrics:
"""回测绩效指标"""
total_return_pct: float = 0.0
"""总收益率(%"""
annual_return_pct: float = 0.0
"""年化收益率(%"""
sharpe_ratio: float = 0.0
"""夏普比率(无风险利率假定为 0"""
max_drawdown_pct: float = 0.0
"""最大回撤(%),以负值表示"""
max_drawdown_duration_days: int = 0
"""最大回撤持续天数"""
win_rate: float = 0.0
"""胜率(0-1"""
profit_factor: float = 0.0
"""盈亏比(总盈利 / 总亏损绝对值)"""
total_trades: int = 0
"""总交易次数"""
avg_trade_pnl: float = 0.0
"""平均每笔盈亏"""
best_trade_pnl: float = 0.0
"""最佳单笔盈亏"""
worst_trade_pnl: float = 0.0
"""最差单笔盈亏"""
calmar_ratio: float = 0.0
"""卡尔玛比率(年化收益 / 最大回撤绝对值)"""
final_equity: float = 0.0
"""最终权益"""
@dataclass
class BacktestResult:
"""完整回测结果"""
config: BacktestConfig
"""回测配置"""
strategy_config: dict
"""策略配置(转为 dict 便于序列化)"""
metrics: BacktestMetrics
"""绩效指标"""
trades: list[BacktestTrade] = field(default_factory=list)
"""交易记录"""
equity_curve: list[dict] = field(default_factory=list)
"""资金曲线 [{"timestamp": float, "equity": float, "drawdown": float}, ...]"""
@property
def total_bars(self) -> int:
"""回测 K 线总数"""
return len(self.equity_curve)
def summary(self) -> str:
"""生成人类可读的摘要"""
m = self.metrics
lines = [
"=" * 60,
f" 回测结果摘要 — {self.config.symbol} {self.config.interval}",
"=" * 60,
f" 初始资金: {self.config.initial_capital:>12.2f} USDT",
f" 最终权益: {m.final_equity:>12.2f} USDT",
f" 总收益率: {m.total_return_pct:>11.2f}%",
f" 年化收益率: {m.annual_return_pct:>11.2f}%",
f" 夏普比率: {m.sharpe_ratio:>12.2f}",
f" 卡尔玛比率: {m.calmar_ratio:>12.2f}",
f" 最大回撤: {m.max_drawdown_pct:>11.2f}%",
f" 回撤持续: {m.max_drawdown_duration_days:>9}",
f" 总交易次数: {m.total_trades:>11}",
f" 胜率: {m.win_rate:>11.1%}",
f" 盈亏比: {m.profit_factor:>12.2f}",
f" 平均盈亏: {m.avg_trade_pnl:>12.4f} USDT",
f" 最佳盈亏: {m.best_trade_pnl:>12.4f} USDT",
f" 最差盈亏: {m.worst_trade_pnl:>12.4f} USDT",
"=" * 60,
]
return "\n".join(lines)