通过纯Python完成股票回测框架的搭建。
什么是回测框架?
无论是传统股票交易还是量化交易,无法避免的一个问题是我们需要检验自己的交易策略是否可行,而最简单的方式就是利用历史数据检验交易策略,而回测框架就是提供这样的一个平台让交易策略在历史数据中不断交易,最终生成最终结果,通过查看结果的策略收益,年化收益,最大回测等用以评估交易策略的可行性。
代码地址在最后。
本项目并不是一个已完善的项目, 还在不断的完善。
回测框架
回测框架应该至少包含两个部分, 回测类, 交易类.
回测类提供各种钩子函数,用于放置自己的交易逻辑,交易类用于模拟市场的交易平台,这个类提供买入,卖出的方法。
代码架构
以自己的回测框架为例。主要包含下面两个文件
backtest/
backtest.py
broker.py
backtest.py主要提供BackTest这个类用于提供回测框架,暴露以下钩子函数.
def initialize(self):
"""在回测开始前的初始化"""
pass
def before_on_tick(self, tick):
pass
def after_on_tick(self, tick):
pass
def before_trade(self, order):
"""在交易之前会调用此函数
可以在此放置资金管理及风险管理的代码
如果返回True就允许交易,否则放弃交易
"""
return True
def on_order_ok(self, order):
"""当订单执行成功后调用"""
pass
def on_order_timeout(self, order):
"""当订单超时后调用"""
pass
def finish(self):
"""在回测结束后调用"""
pass
@abstractmethod
def on_tick(self, bar):
"""
回测实例必须实现的方法,并编写自己的交易逻辑
"""
pass
玩过量化平台的回测框架或者开源框架应该对这些钩子函数不陌生,只是名字不一样而已,大多数功能是一致的,除了on_tick.
之所以是on_tick而不是on_bar, 是因为我希望交易逻辑是一个一个时间点的参与交易,在这个时间点我可以获取所有当前时间的所有股票以及之前的股票数据,用于判断是否交易,而不是一个时间点的一个一个股票参与交易逻辑。
而broker.py主要提供buy,sell两个方法用于交易。
def buy(self, code, price, shares, ttl=-1):
"""
限价提交买入订单
---------
Parameters:
code:str
股票代码
price:float or None
最高可买入的价格, 如果为None则按市价买入
shares:int
买入股票数量
ttl:int
订单允许存在的最大时间,默认为-1,永不超时
---------
return:
dict
{
"type": 订单类型, "buy",
"code": 股票代码,
"date": 提交日期,
"ttl": 存活时间, 当ttl等于0时则超时,往后不会在执行
"shares": 目标股份数量,
"price": 目标价格,
"deal_lst": 交易成功的历史数据,如
[{"price": 成交价格,
"date": 成交时间,
"commission": 交易手续费,
"shares": 成交份额
}]
""
}
"""
if price is None:
stock_info = self.ctx.tick_data[code]
price = stock_info[self.deal_price]
order = {
"type": "buy",
"code": code,
"date": self.ctx.now,
"ttl": ttl,
"share