性能问题
Python在2016年里可以说是风靡国内量化投资圈,目前整个生态链已经初具规模:
- 交易:vn.py、easytrader、at_py
- 数据:tushare
- 回测:rqalpha
- 在线平台:UQER、RiceQuant、JoinQuant
随着用户越来越多,Python语言的性能问题也就逐渐成为整个社区关注的重点,经常遇到新手问:Python写的量化交易程序是不是很慢啊?
在他们心中,Python估计是这个样子:
(即使作为破旧自行车,我也深表怀疑这辆能不能骑好吧)
网上关于如何提升Python程序性能的文章不少,但大多不成体系只是非常简单的例子,总有点隔靴搔痒的感觉,和现实中应用的距离比较远。
作者一看,填补市场空白(装逼)的机会来了!!
在这篇文章里,将会通过实际的例子展示如何对一段量化策略常用的代码实现百倍加速。
一段常用的代码
接下来要用的例子相信几乎所有做量化策略的人都写过类似的代码:对时间序列求算术移动平均值。
这里我们先初始化即将用到的数据:10万个数据点(随机整数),遍历计算窗口为500的算术移动平均值,每种算法运行10次求平均耗时。
# 这个测试目标在于仿造一个类似于实盘中,不断有新的数据推送过来,
# 然后需要计算移动平均线数值,这么一个比较常见的任务。
from __future__ import division
import time
import random
# 生成测试用的数据
data = []
data_length = 100000 # 总数据量
ma_length = 500 # 移动均线的窗口
test_times = 10 # 测试次数
for i in range(data_length):
data.append(random.randint(1, 100))
在每次测试中,我们都通过遍历测试用数据的方式来模拟实盘中策略不断收到新数据推送的情况(同样适用于事件驱动的回测模式),将计算出的移动平均值不断保存到一个列表list中作为最终结果返回。
测试用电脑的配置情况:Core i7-6700K 4.0G/16G/Windows 7。
第一步我们以最简单、最原始的方式来计算移动平均值:
# 计算500期的移动均线,并将结果保存到一个列表里返回
def ma_basic(data, ma_length):
# 用于保存均线输出结果的列表
ma = []
# 计算均线用的数据窗口
data_window = data[:ma_length]
# 测试用数据(去除了之前初始化用的部分)
test_data = data[ma_length:]
# 模拟实盘不断收到新数据推送的情景,遍历历史数据计算均线
for new_tick in test_data:
# 移除最老的数据点并增加最新的数据点
data_window.pop(0)
data_window.append(new_tick)
# 遍历求均线
sum_tick = 0
for tick in data_window:
sum_tick += tick
ma.append(sum_tick/ma_length)
# 返回数据
return ma
# 运行测试
start = time.time()
for i in range(test_times):
result = ma_basic(data, ma_length)
time_per_test = (time.time()-start)/test_times
time_per_point = time_per_test/(data_length - ma_length)
print u'单次耗时:%s秒' %time_per