菜鸟de量化之路——(1)趋势跟踪策略
这是我第⼀篇博客,也是我的本科毕业课题--开发⼀个简易的量化系统,包括择时选股模块和回测模块。
所谓的量化系统,是指以数学模型代替⼈为判断,以程序交易替代⼈为操作,利⽤计算机的庞⼤的计算能⼒,制定能带来超额收益的交易策略。
趋势跟踪策略
趋势跟踪模型是⼤名⿍⿍的海归交易法则⾥⾯提到的⼀个经典量化模型,基本的策略是在⼀个上扬趋势刚刚开始的时候买⼊,在这个趋势即将结束之前退出系统。
⾸先我们选取苹果的历史两年股票数据作为数据来源:
from abupy import ABuSymbolPd
Apple_pd = ABuSymbolPd.make_kl_df('AAPL', n_folds=2)
Apple_pd.tail()
通过Apple_pd.tail()查看股票的数据结构和尾部数据如下图,可以看到包括close, high, low, p_change, op
en, pre_close,volume, date, date_week, key,atr21,atr14 等列 ,我们⽬前主要需要的是开盘价,最⾼价,最低价,收盘价,振幅的数据。
接下来使⽤seaborn库画出可视化的振幅变化图:
sns.set_context(rc={'figure.figzize':(14,7)})
plt.show()
下⾯使⽤abu内置的函数计算趋势⾓度⽅向:
start = 0
# 前1/4的数据
end = int(Apple_pd.shape[0] / 4)
# 将x也使⽤arange切割
x = np.arange(start, end)
# y根据start,end进⾏切⽚
y = Apple_pd.close.values[start:end]
plt.show()
deg = ABuRegUtil.calc_regress_deg(y)
print('趋势⾓度:' + str(deg))
得到下⾯的结果,可以看出前四分之⼀的股价呈现明显的上升趋势,且趋势⾓度为8.98:
经过初步分析,对这⼀段的数据,可以使⽤趋势跟踪策略,下⾯编写⼀个简单的趋势跟踪策略模型,趋势跟踪模型的两个参数是买⼊信号和卖出信号的确定,当天的收盘价格超过N天的最⾼价格作为买⼊持有信号,收盘价格低于N天的最低价格作为卖出抛售信号。⾸先设置42天的最⾼价格和21天的最低价格作为阈值,设置两个不同的阈值主要是为了保证⾮均衡的胜负收益。
# 当天收盘价格超过N1天内最⾼价格作为买⼊信号
N1 = 42
# 当天收盘价格超过N2天内最低价格作为卖出信号
N2 = 21
# 通过rolling_max⽅法计算最近N1个交易⽇的最⾼价
from abupy import pd_rolling_max,pd_expanding_max,pd_rolling_min, pd_expanding_min
Apple_pd['n1_high'] = pd_rolling_max(Apple_pd['high'], window=N1)
菜鸟编辑器pythonexpan_max = pd_expanding_max(Apple_pd['close'])
# fillna使⽤序列对应的expan_max
Apple_pd['n1_high'].fillna(value=expan_max, inplace=True)
Apple_pd['n2_low'] = pd_rolling_min(Apple_pd['low'], window=N2)
# expanding_min与expanding_max类似
expan_min = pd_expanding_min(Apple_pd['close'])
# fillna使⽤序列对应的eexpan_min
Apple_pd['n2_low'].fillna(value=expan_min, inplace=True)
# 当天收盘价格超过N天内的最⾼价或最低价, 超过最⾼价格作为买⼊信号买⼊股票持有
buy_index = Apple_pd[Apple_pd['close'] > Apple_pd['n1_high'].shift(1)].index
Apple_pd.loc[buy_index, 'signal'] = 1
# 当天收盘价格超过N天内的最⾼价或最低价, 超过最低价格作为卖出信号
sell_index = Apple_pd[Apple_pd['close'] < Apple_pd['n2_low'].shift(1)].index
Apple_pd.loc[sell_index, 'signal'] = 0
Apple_pd[0:5]
得到扩展后的新的股票数据:
接下来将操作信号转化成持股状态,计算基准收益,计算使⽤趋势突破策略的收益之后可视化收益情况:
"""
将信号操作序列移动⼀个单位,代表第⼆天再将操作信号执⾏,转换得到持股状态
这⾥不shift(1)也可以,代表信号产⽣当天执⾏,但是由于收盘价格是在收盘后
才确定的,计算突破使⽤了收盘价格,所以使⽤shift(1)更接近真实情况
"""
Apple_pd['keep'] = Apple_pd['signal'].shift(1)
Apple_pd['keep'].fillna(method='ffill', inplace=True)
# 计算基准收益
Apple_pd['benchmark_profit'] = np.log(
Apple_pd['close'] / Apple_pd['close'].shift(1))
# 计算使⽤趋势突破策略的收益
Apple_pd['trend_profit'] = Apple_pd['keep'] * Apple_pd['benchmark_profit']
# 可视化收益的情况对⽐
Apple_pd[['benchmark_profit', 'trend_profit']].cumsum().plot(grid=True,
figsize=(
14, 7));
得到如下的结果:
可以看出使⽤趋跟踪策略的盈利率略微⾼于benchmark值,但是还是处于负收益率期间,主要原因是测试数据整个阶段的股价处于下降阶段,仅仅⼀个趋势跟踪策略并不能违反市场盈利情况。
总结
⼀个单⼀的策略往往适⽤范围有限,考虑到股价在不同的阶段可能会处于不同的波动类型,如果能有更⾼级的策略模型⽤来判断股价的基本类型,从⽽对于不同的变化类型使⽤不同的⼦策略,可能会有不错的效果。Numpy, Pandas,Matplotlib, Seaborn是常⽤于Python量化系统的库,需要⼤量练习,重点掌握。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。