A 股量化回测框架,基于 polars 高性能计算,模拟 T+1 交易规则。
- T+1 延迟执行:T 日信号 → T+1 日开盘价成交,无前瞻偏差
- A 股规则:涨跌停限制、100 股手数约束、印花税仅卖出收取、板块识别(主板/创业板/科创板/北交所)
- Signal/Order 分离:策略输出交易意图(Signal),框架负责仓位计算(PositionSizer)
- Order 状态机:
transition_to()守卫,防止非法状态转换 - 风控模块:仓位比例、总暴露度、最大亏损、每日交易次数限制
- 动态滑点:基于成交量和波动率自动调整
- 绩效分析:Sharpe、Sortino、Calmar、最大回撤、月度收益分解、换手率
- 结构化日志:集成 cells-log,按模块分层,支持 JSON/text 输出
from backtest import BacktestEngine, DualMAPriceDeductionStrategy, FixedLotSizer
from backtest.logging_config import setup_logging
setup_logging(level="INFO")
# 默认策略:雷公双均线 + 扣价系统
strategy = DualMAPriceDeductionStrategy(
symbol="600519",
period_short=20,
period_mid=60,
period_long=120,
strength_buy=1.0, # 保守买入强度
strength_active=0.5, # 主动买入强度
)
engine = BacktestEngine.from_csv(
csv_path="600519.csv",
strategy=strategy,
symbol="600519",
initial_capital=500_000,
sizer=FixedLotSizer(buy_shares=500),
)
report = engine.run()
print(f"总收益: {report.total_return:.2%}")
print(f"夏普比率: {report.sharpe_ratio:.2f}")
print(f"最大回撤: {report.max_drawdown:.2%}")DualMAPriceDeductionStrategy 基于 EMA/SMA 三档周期(20/60/120)+ 扣价(k 日前最低价)构建多级确认信号。
买入条件:
- 保守买入:Uptrend_20 + Uptrend_60 + 价格 > bl_20 & bl_60 + EMA20 > EMA60
- 主动买入:EMA20 金叉 SMA20 + 价格 > bl_20
卖出条件:
- EMA20 死叉 SMA20 + 价格 < bl_20
- Uptrend_20 由真转假(EMA20 跌破 SMA20)
完整规则详见 DualMA-PriceDeduction-Rules.md。
继承 BaseStrategy,返回 list[Signal]:
from backtest.strategy import BaseStrategy
from backtest.models import Signal
from backtest.enums import SignalDirection
class MyStrategy(BaseStrategy):
def generate_signals(self, data, current_idx, portfolio):
if should_buy(data, current_idx, portfolio):
return [Signal(
timestamp=data["date"][current_idx],
symbol="600519",
direction=SignalDirection.BUY,
strength=0.8,
reason="自定义逻辑",
)]
return []# 测试
python -m pytest tests/ -v
# 示例
python -m examples.example_01_basic
python -m examples.example_02_dataclass
python -m examples.example_03_custom_strategy| date | open | high | low | close | volume |
|---|---|---|---|---|---|
| 2024-01-02 | 10.50 | 11.00 | 10.20 | 10.80 | 50000 |
- Python >= 3.12
- polars >= 1.0