最近刚开始学习量化交易,在聚宽网上看了几篇教程,对操作流程有了大致的了解,接下来打算好好研究一下交易策略。
据大奖章基金的Simons透露,他那个每年收益率20%以上的系统,一点都不费解(complicated),但是非常复杂(complex)。
我的理解是,一个好的量化交易系统,不一定要用到高深的算法和技术,但是必须包含很多种简单的算法和技术。
换句话说,你得从最基础的算法开始,一个模块一个模块地加上去,选股、择时、风控、资金管理,每个方向都要综合考虑好几种不同的指标,才能打造出一个不费解但很复杂(not complicated but complex)的交易系统。
爱因斯坦说过,上帝只做加法。
也许基于人工智能(AI)的交易系统构造起来不用这么麻烦,这个以后有空再研究。
眼下先从择时技术开始,先看看最简单的MACD,也就是双均线策略。
MACD指标
MACD系列指标由三个指标沟构成,分别是DIF,DEA和HIST。
DIF是12日指数移动平均线(EMA12,又称快线)与26日指数移动平均线(EMA26,又称慢线)的背离程度: $$DIF=EMA(12)−EMA(26)$$
DEA是DIF的9日指数移动平均线: $$DEA=EMA(DIF,9)$$
HIST是DIF与DEA的差值乘以2: $$HIST=(DIF−DEA)×2$$
HIST又称MACD柱,是MACD系列指标中最重要的一个,有些人只根据它来决定是否买入卖出,但我查询了一番文献,还进行了一系列的试错,发现还是综合考虑另外两个指标更好。
废话不多说了,上代码。
Python代码
第一步:导入各种库
import numpy as npimport pandas as pdimport talib as ta # 这个是聚宽网(joinquant)的数据下载API,免费账户每天能下载100万条数据from jqdatasdk import *# 登录验证auth("你的手机号", "你的密码")import matplotlib.pyplot as plt%matplotlib inline
第二步:下载数据
# 下载-的沪深300指数,频率为每天,只要收盘价price = get_price("000300.XSHG", start_date="-01-01", end_date="-12-31", frequency="daily", fields=["close"])["close"]# 用python自带的tseries库中的pct_change()函数计算日收益率ret = price.pct_change()# 画图plt.figure(figsize=(18,8))ax1 = plt.subplot(2,1,1)ax1.plot(price)ax2 = plt.subplot(2,1,2)ax2.plot(ret)plt.show()
沪深300指数和日收益率
这4年间,沪深300指数的走势还是很典型的:暴涨暴跌,-两年间温和上涨,快速下跌。
第三步:计算指标
# 用talib库中的相应函数计算MACD指标dif, dea, hist = ta.MACD(price)# 计算EMA12和EMA26ema12 = ta.EMA(price, 12)ema26 = ta.EMA(price, 26)
第四步:生成交易信号
这里只考虑做多,不考虑做空的情况。
为了方便比较,我尝试了集中不同的策略。
# sig1只考虑HIST指标,HIST转正时开仓买入,转负时清仓sig1 = (hist>0)# sig2同时考虑HIST指标和DEA指标,只有当HIST转正,且DEA在0以上时,才开仓买入,任何一个指标变负即清仓。# 这是文献中建议的方法sig2 = (hist>0) & (dea>0)# sig3同时考虑HIST和EMA指标,只有当HIST为正,而且当前价格在慢线(26日指数加权平均价)上方时,才开仓买入,任何一个指标转负即清仓。# 网上有人建议过这种方法(如果我没有理解错的话)sig3 = (hist>0) & (price>ema26)
接下来,我们来直观地比较一下这三个交易信号。
plt.figure(figsize=(18,12))ax1=plt.subplot(4,1,1)ax1.plot(price)ax2=plt.subplot(4,1,2)ax2.bar(x=sig1.index, height=sig1.values)ax3=plt.subplot(4,1,3)ax3.bar(x=sig2.index, height=sig2.values)ax4=plt.subplot(4,1,4)ax4.bar(x=sig3.index, height=sig3.values)plt.show()
交易信号
看起来策略1最激进,策略2最保守。后者完美地避开了和的两段暴跌,期间一次买入指令也没有发出过,但在16-的缓慢回升中,参与度似有不足。
第五步:模拟交易
简单起见,这里不考虑手续费。
以策略2为例,作图比较该策略和“买入-持有”策略的表现。
# sig2滞后一期、去除空值、转换成整数sig2_lag = sig2.shift(1).fillna(0).astype(int)# sig2_lag与股票日收益率相乘,即可得策略日收益率。python能自动对齐时间序列的日期。sig2_ret = sig2_lag*ret# 计算策略累计收益cum_sig2_ret = (1+sig2_ret).cumprod()# 把股票价格转换成从1开始,方便比较price_norm = price/price[0]# 开始作图plt.figure(figsize=(18,8))plt.plot(price_norm)plt.plot(cum_sig2_ret)plt.legend(["benchmark", "strategy cumulative return"], loc="upper left")plt.show()
累计收益率
由此可见,策略2在股市暴涨暴跌期间表现出色,它几乎完整地抓住了上半年的暴涨,却完美地避开了下半年和的暴跌。但是,在股市温和上涨的16、,该策略的表现却落后于大盘。
总而言之,该策略简单归简单,表现却不俗,在大盘下跌近20%的4年中,实现了近60%的收益,目测最大回测不超过10%。
当然,这款策略还有改进的余地,比如说,如果把交易频率调低,也许表现会更好。
接下来,我打算寻找:
1. 一个更加适应温和上涨行情的策略;
2. 一个能有效区分暴涨暴跌行情和温和涨跌行情的指标。
请大家积极发言献策!
如果觉得《python量化交易策略入门(一):MACD的威力》对你有帮助,请点赞、收藏,并留下你的观点哦!