前面系列文章,我们把回测系统的主要部件作了详细的说明,这些部件构成了回测引擎的主体。如果把回测引擎比作一台机器,那么数据就是生产原料,而策略就是加工方法。
策略需要对原始数据进行计算,得到各种中间指标,比如均线,MACD,布林带等等。我们基于talib这个指标计算库,提供了相应的指标计算功能,另外还实现了金叉,死叉这种常用的时间序列状态判断。
有了上述这些准备工作,我们通过python eval功能,实现写文本表达式的方式来写策略,大大简化了代码。
比如:收盘价5日均线向上突破收盘价10日均线。
eval('cross_up(ma(close,5),ma(close,10')
有了这种灵活的表达方式,我们很容易就能够实现像海龟策略这种技术形态判断。
technical/indicators.py
如下代码可以看出,直接调用talib可以实现大部分的技术指标计算。
import talib
def rolling_max(se,n):
max_n = se.rolling(n).max()
return max_n
def rolling_min(se,n):
min_n = se.rolling(n).min()
return min_n
def ma(se,n):
ma_n = se.rolling(n).mean()
return ma_n
def ema(se,n):
ema_n = talib.EMA(se,n)
return ema_n
def macd(se,fast=12,slow=26,signal=9):
macd_n, macd_sig, macd_hist = talib.MACD(se,fast,slow,signal)
return macd_n,macd_sig,macd_hist
def rsi(se,n):
rsi_n = talib.RSI(se,n)
return rsi_n
def obv(se,volume,n):
obv_n = talib.OBV(se, volume)
return obv_n
def mom(se,n):
mom_n = talib.MOM(se,timeperiod=n)
return mom_n
def bbands(se,n):
upper, middle, lower = talib.BBANDS(
se.values,
timeperiod=n,
# number of non-biased standard deviations from the mean
nbdevup=2,
nbdevdn=2,
# Moving average type: simple moving average here
matype=0)
return upper,middle,lower
technical/cross.py
crossup实现了快线金叉慢线;而crossdown实现了快线向下突破慢线。
import numpy as np
import pandas as pd
def cross(fast, slow):
data = pd.DataFrame(index=fast.index)
data['signal'] = fast - slow # data[fast] - data[slow]
data['signal'] = np.where(data['signal'] > 0, 1, data['signal'])
data['signal'] = np.where(data['signal'] < 0, -1, data['signal'])
data['signal'] = data['signal'] - data['signal'].shift(1)
data['signal'] = np.where(data['signal'] > 0, 1, data['signal'])
data['signal'] = np.where(data['signal'] < 0, -1, data['signal'])
return data['signal']
def cross_up(fast, slow):
data = pd.DataFrame(index=fast.index)
data['signal'] = fast - slow # data[fast] - data[slow]
data['signal'] = np.where(data['signal'] > 0, 1, data['signal'])
data['signal'] = np.where(data['signal'] < 0, -1, data['signal'])
data['signal'] = data['signal'] - data['signal'].shift(1)
data['signal'] = np.where(data['signal'] > 0, 1, 0)
#data['signal'] = np.where(data['signal'] < 0, -1, data['signal'])
return data['signal']
def cross_down(fast, slow):
data = pd.DataFrame(index=fast.index)
data['signal'] = fast - slow # data[fast] - data[slow]
data['signal'] = np.where(data['signal'] > 0, 1, data['signal'])
data['signal'] = np.where(data['signal'] < 0, -1, data['signal'])
data['signal'] = data['signal'] - data['signal'].shift(1)
data['signal'] = np.where(data['signal'] < 0, -1,0)
return data['signal']
后续我们会对比ailabx与pyalgotrade书写策略的代码做对比,看看ailabx到底有多么简洁!
项目在github上开源,欢迎star。