PyAlgoTrade 介绍
PyAlgoTrade 可解释为python算法交易,简称PAT
随着这几年量化的兴起,出现了很多基于python的量化交易平台,但是大所述量化交易平台都是以线上为主,不能进行离线操作,比如国内的
聚宽、优矿、米筐、京东量化等,很少有线下的python量化平台供初学者学习和使用。
在这里对线上和线下的python量化平台进行一个简要的分析和对比
目前国内的量化平台诸如聚宽、优矿、米筐、京东量化等,各平台优缺点请自行百度。
进行量化分析最主要的是需要数据的支持,没有数据的支持和验证,再好的想法也很能实现为策略,然而线上量化平台为我们提供的丰富的数据支持,
以及API。带来便利性的同时让量化成了黑箱,不知其内部原理和机制,扩展性差,不能自定义一些技术指标和统计指标。
本站点选择以PAT为学习和研究的平台,主要基于以下几点:
1、PAT是一套相对完整、成熟的python量化系统,其中集成了大多数的技术指标和统计指标
2、完整的文档,丰富的实例
3、基于事件驱动的回测平台
4、可离线使用,扩展性强,可自行定制技术指标和统计指标
PyAlgoTrade 基于事件驱动的回测框架,在这里对事件驱动进行简要的说明。事件驱动机制,和普通函数调用的不同之处在于,应用程序不是主动的调用某个API完成处理,而是由事件监听器监听事件并进行相应的处理。
事件驱动程序的基本结构是由一个事件源、事件以及监听器构成,事件源产生事件、监听器监听事件并进行相应的处理和计算。当一个对象的状态发生变化时,所有依赖它的对象都得到通知并自动更新。当事件源的属性发生变化时,所有监听该事件的事件监听器都会接收到消息并作出响应。
在PyAlgoTrade中事件驱动贯穿整个框架之中,在后续技术指标时更加详细的说明。
PyAlgoTrade 安装
PyAlgoTrade的安装时比较简单的,可直接通过pip进行安装
pip install pyalgotrade
PyAlgoTrade 包含以下基本模块
Strategies: 策略,交易的逻辑以及交易的时机等。
DataSeries: 数据序列,管理时间序列数据的抽象类
Feeds: 数据源, CSV文件为主,可通过自己的数据类型进行扩展
Brokers: 交易模块,负责执行订单
Technical: 技术, 可根据数据集,进行技术指标的计算
StrategyAnalyzer: 分析,是对策略结果如收益率、夏普率等进行计算
Optimizer: 优化器,允许测试、使用不同的电脑以及集群,便于扩展
Feeds 数据源
PyAlgoTrade中数据又是以bar的类型进行组装,没个数据集被称之为一个bar,在本案例中,正对本站点提供的数据集对bar类进行简单的扩展,
以适应自己的数据集,如果读者有自己的数据集可进行相应的调整。
在本项目中对原有的csvfeed进行更改和扩充,并添加的从dataFrame数据集添加bar的方法。
在扩展barFeed时只需要更改__columnNames中对应的字段名称和__dateTimeFormat时间的类型。
class GenericBarFeed(BarFeed):
def __init__(self, frequency=bar.Frequency.DAY, timezone=None, maxLen=None):
super(GenericBarFeed, self).__init__(frequency, maxLen)
self.__timezone = timezone
# Assume bars don\'t have adjusted close. This will be set to True after
# loading the first file if the adj_close column is there.
self.__haveAdjClose = False
self.__barClass = bar.BasicBar
self.__dateTimeFormat = "%Y-%m-%d"
self.__columnNames = {
"datetime": "date",
"open": "open",
"high": "high",
"low": "low",
"close": "close",
"volume": "volume",
"adj_close": "adjust_price",
}
然后定义自己加载的方法,在本方法中,需要一个解析类,以及具体的方法,本方法中,具体的方法是在父类中完成。
def addBarsFromDataFrame(self, instrument, dataframe, timezone=None):
if timezone is None:
timezone = self.__timezone
rowParser = GenericRowParser(
self.__columnNames, self.__dateTimeFormat, self.getDailyBarTime(), self.getFrequency(),
timezone, self.__barClass
)
super(GenericBarFeed, self).addBarsFromDataFrame(instrument, dataframe, rowParser)
if rowParser.barsHaveAdjClose():
self.__haveAdjClose = True
elif self.__haveAdjClose:
raise Exception("Previous bars had adjusted close and these ones don\'t have.")
def addBarsFromDataFrame(self, instrument, dataframe, rowParser):
loadedBars = []
for index in range(len(dataframe)):
row = dataframe.ix[index]
bar_ = rowParser.parseBar(row)
if bar_ is not None and (self.__barFilter is None or self.__barFilter.includeBar(bar_)):
loadedBars.append(bar_)
self.addBarsFromSequence(instrument, loadedBars)
至此我们可以通过addBarsFromDataFrame方法将dataframe数据集添加到bar中,进行回测。详细代码参加trade.feed.genericbarfeed
Brokers: 交易模块,可以将brokers简单理解为经纪人
在对Brokers进行说明之前还有一个重要的类需要说明,这个类就是Order订单类
Order类是订单类,保存并记录订单的类型,订单的状态,以及订单的执行结果
MarketOrder 市价订单(按市场当时最优价或市价立即购买或出手一定数量的合约)
LinitOrder 限价单(给定最高阶或者最低价,当价格达到这个限价是触发交易)
StopOrder 止损单(停止损失的订单。预设一个固定的止损价格。一旦被触发的止损价,将会以市场单发送到市场上)
StopLimitOrder 限价止损单(当价格达到某一止损价格时﹐止损限价订单即转为限价订单)
在回测中Brokers可简单理解为经纪人,只对主要的几个方法进行简要说明
setCommission 设置手续费
getCash 账户余额
getShares 股票的数量
sybmitOrder 提交订单
Backtesting 回测模块,在回测框架中回测模块承担着重要的交易所的任务,
对提交的订单进行处理并对佣金、收益等计算。
对于PyalgoTrade的回测流程以及技术指标和统计分析将在下面单独进行讲解。