vnpy怎么创建策略并回测_vnpy笔记-回测引擎
回测是量化交易不可缺少的组成部分,本文是 vnpy 回测引擎原理笔记回测 Demovnpy 官方提供了两个 jupyter notebook 作为 Demo,代码文件在源代码中的 examples/cta_backtesting 目录: backtesting.ipynb: 常规的单标 CTAportfolio.ipynb: 组合回测backtesting.ipynb: 创建回测:engine 运
回测是量化交易不可缺少的组成部分,本文是 vnpy 回测引擎原理笔记
回测 Demo
vnpy 官方提供了两个 jupyter notebook 作为 Demo,代码文件在源代码中的 examples/cta_backtesting 目录:
backtesting.ipynb
: 常规的单标 CTAportfolio.ipynb
: 组合回测
backtesting.ipynb
:
创建回测:
engine = BacktestingEngine()
engine.set_parameters(...) # 回测参数
engine.add_strategy(AtrRsiStrategy, {}) # 添加策略
运行回测
engine.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
将剩下的数据用于回测
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 线之后才会下单) - 更新收盘价,方便计算逐日盯市盈亏
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
回调
- 若
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)