全实战进阶系列-CTA策略, 平台小鹅通,by 用 Python 的交易员
回测 Demo
基于 examples/cta_backtesting
两个 notebook
backtesting.ipynb: 常规的单标 CTAportfolio.ipynb: 组合回测
backtesting.ipynb- 创建回测
1
2
3engine = BacktestingEngine()
engine.set_parameters(...) # 回测参数
engine.add_strategy(AtrRsiStrategy, {}) # 添加策略 - 运行回测
1
2
3
4
5engine.load_data() # 载入数据
engine.run_backtesting() # 跑回测, 得到成交记录
df = engine.calculate_result() # 从成交记录到盯市盈亏
engine.calculate_statistics() # 计算统计指标
engine.show_chart() # 显示结果
- 创建回测
引擎(BacktestingEngine)代码
set_parameters: 仅仅保存参数add_strategy: 添加策略类(继承CtaTemplate)和实例化策略对象load_data: 载入历史数据, 保存在self.history_data, 会调用load_bar_data或者load_tick_data从数据库读取数据run_backtesting: 跑回测,本身支持 Tick / K 线,但是图形界面只支持 K 线- 调用 strategy (
CtaTemplate子类) 的on_init函数进行初始化 - 如果 strategy 调用了
self.load_bar,engine 则会把对应的历史数据推送给策略进行初始化 - 完成后 engine 标记
self.strategy.inited = True - 下一步,engine 调用
on_start函数启动策略 - 启动完成后,engine 标记
self.strategy.trading = True - 对于剩下的数据,调用
new_bar/new_tick将剩下的数据用于回测
- 调用 strategy (
calculate_result: 把交易聚合成逐日盈亏calculate_statistics: 基于逐日盈亏计算统计指标,比较多利用了 pandas 的向量化show_chart: 用matplotlib可视化指标new_bar/new_tick- 缓存最新的 K 线 / Tick 数据,模拟撮合限价单(
cross_limit_order)和停止单(cross_stop_order) - 将最新的 K 线 / Tick 推给
strategy.on_bar(防止未来函数,因为实盘走完 K 线之后才会下单) - 更新收盘价,方便计算逐日盯市盈亏
- 缓存最新的 K 线 / Tick 数据,模拟撮合限价单(
cross_limit_order(K 线)long_cross_price = self.bar.low_price, 对于 long (下在 bid), 如果最低价大于买单,则有成交机会short_cross_price = self.bar.high_price, 对于 short (下在 ask), 如果最高价大于卖单,则有成交机会long_best_price = self.bar.open_price,short_best_price = self.bar.open_price, 按 taker 模拟撮合, 可能按开盘价成交- 模拟撮合,遍历所有 limit order:
- 对于状态等于
Status.SUBMITTING的,更新为Status.NOTTRADED,调用on_order回调 - 若
order.price >= long_cross_price/order.price <= short_cross_price, 计算是否成交, 不成交则直接continue - 若成交, 则认为全部成交, 更新状态为
Status.ALLTRADED,调用on_order回调 - 按照限价单的 price, 以及 best_price, 计算成交价格
- 生成成交记录
TradeData, 维护strategy.pos, 调用on_trade回调
- 对于状态等于
cross_stop_order(K 线)long_cross_price = self.bar.high_price,short_cross_price = self.bar.low_price,short_best_price = long_best_price = self.bar.open_price- 模拟撮合,遍历所有 stop order:
- 若
order.price <= long_cross_price/order.price >= short_cross_price, 停止单触发,新增一个限价单OrderData - 按照停止单的 price, 以及 best_price, 计算成交价格
- 生成成交记录
TradeData - 更新原停止单状态为,
StopOrderStatus.TRIGGERED, 调用on_stop_order回调 - 对生成的限价单, 调用
on_order回调 - 维护
strategy.pos, 调用on_trade回调
- 若
Dual Thrust
- 根据上一天的 K 线, 定义多空入场位置(
long_entry,short_entry) - 收到每一根 K 线
- 如果开没有开过仓
- 价格到了开盘价以上, 在
long_entry下买入停止单 - 价格到了开盘价以下, 在
short_entry下卖出停止单
- 价格到了开盘价以上, 在
- 如果已经开仓
- 持多仓, 在
short_entry下卖出停止单平仓 - 持空仓, 在
long_entry下买入停止单平仓
- 持多仓, 在
- 对于每日要收盘的品种,如果时间到达了快要收盘的时候,无论如何,都要平仓
- 如果开没有开过仓