1.移动平均线 在所有的技术指标中,移动平均线的应用最为广泛。因为它的构造方法简便,且成绩易于定量地检验:在技术图表分析中,关于市场趋势的分析在很大程度上是基于分析师的主观判断,因此很难在计算机上进行量化;而移动均线的规则却不随分析师的主观意志而改变,可以简易地编写为计算机程序,然后自动生成买入和卖出信号。 从本质上而言,移动平均线是一种追踪趋势的工具,可以用以识别和显示旧趋势的终结或反转,以及新趋势的萌生。因此,移动平均线从来不会预期市场的走向,而是对市场已经发生的事实做响应。一般而言,根据计算方式的不同,移动平均线被分为简单移动平均(SMA),线性加权移动平均(WMA)和指数加权移动平均(EMA)。其中,线性加权移动平均(WMA)应用在量化上时涉及浮点问题,容易出现漏洞,因此本文着重介绍简单移动平均和指数加权移动平均在量化上的应用。 首先是简单移动平均。所谓简单移动平均其实就是算数平均。根据定义,第k个时间单位的m阶移动平均值(k>m)为: 我们以BTC每日收盘价为例,在python上运行以下程序可以得到其均线图: import pandas as pd import numpy as np import matplotlib.pyplot as plt from pandas.plotting import register_matplotlib_converters register_matplotlib_converters() data = pd.read_csv(r'C:\Users \Desktop\量化策略代码\数据\csv\btc永续30min.csv') data.index = pd.to_datetime(data.iloc[:,0]) data_value = data.iloc[:,1] #提取收盘价数据 close = data_value #建立移动平均函数,获取移动平均值 def ma_function(k): #k为移动平均的滞后期数 #设置时间系列 MA_k = pd.Series(0,index=data.index) #使用for循环求职 for i in range(k-1,len(close)): MA_k[i] = sum(close[(i-k+1):(i+1)])/k return MA_k #在价格时序图上加入均线图 def picture_1(m,n): #m,n为移动平均滞后阶数,且m<n ma_1 = ma_function(m) ma_2 = ma_function(n) plt.rcParams['axes.unicode_minus'] = False plt.rcParams['font.sans-serif'] = 'SimHei' plt.plot(close[(n-1):],label='价格',color='k') plt.plot(ma_1[(n-1):],label='MA_1',color='r') plt.plot(ma_2[(n-1):],label='MA_2',color='y') plt.title('BTC移动平均线与价格时序图') plt.legend() #添加图例 plt.show() return 另一类是指数加权移动平均,加权移动平均数是一种也别的移动平均,它给后期的价格给以较大的权重,而前期的价格给以较小的权重,并且囊括了金融产品自上市以来的所有历史价格,其计算公式如下: 在python上用代码表示,并做出EMA图如下: #建立指数加权移动平均函数 def EMA_function(k,exponential=0.2): #k为滞后阶数,权重默认为0.2,可根据实际情况自行修改 ema_k = pd.Series(0,index=close.index) ema_k[k-1] = np.mean(close[:k]) for i in range(k,len(close)): ema_k[i] = exponential*close[i]+(1-exponential)*ema_k[i-1] return ema_k #在价格时序图上加入指数加权移动均线图 def picture_2(m): #m为移动平均滞后阶数 EMA = EMA_function(m) plt.rcParams['axes.unicode_minus'] = False plt.rcParams['font.sans-serif'] = 'SimHei' plt.plot(close[(m-1):],label='价格',color='k') plt.plot(EMA[(m-1):],label='EMA',color='r') plt.title('BTC移动平均线与价格时序图') plt.legend() #添加图例 plt.show() return 2.均线策略的使用 现在我们使用一个简单的双均线策略来构建一个简单的量化系统,这种技术被称为“双线相交法”: 当短期均线从下向上穿过长期均线时,为“黄金交叉”,释放买入信号; 当短期均线从上向下穿过长期均线时,为“死亡交叉”,释放卖出信号。 基于上述原理,我们构造如下交易系统(为方便调用,我们可以把交易系统封装成一个类,里面的各子系统再封装成函数): #构建均线交易系统 class MA: #使用类封装单条均线系统 def signal_1(self,m,n): #m,n为均线滞后阶数,且m>n ma_1 = ma_function(m) ma_2 = ma_function(n) signal = pd.Series(0,index=close.index) for i in range(1,len(ma_2.index)): #黄金交叉 if (ma_1[i]>ma_2[i]) & (ma_1[i-1]<ma_2[i-1]) : signal[i] = 1 #死亡交叉 elif (ma_1[i]<ma_2[i]) & (ma_1[i-1]>ma_2[i-1]) : signal[i] = -1 return signal # 计算收益率 global r r = close / close.shift(1) - 1 #构建交易系统 #黄金交叉买入 def trade_buy(self, m, n, k): #m,n为均线滞后阶数,且m>n; k 为信号滞后阶数 trade = self.signal_1(m, n).shift(k) buy = pd.Series(0, index=close.index) buy[trade == 1] = 1 #计算黄金交叉的收益率 r_buy = (buy*r).dropna() r_buy_cum = np.cumprod(1+r_buy)-1 return r_buy_cum #死亡交叉卖出 def trade_sell(self, m, n, k): # m,n为均线滞后阶数,且m>n; k 为信号滞后阶数 trade = self.signal_1(m, n).shift(k) sell = pd.Series(0, index=close.index) sell[trade == -1] = -1 # 计算死亡交叉的收益率 r_sell = (sell * r).dropna() r_sell_cum = np.cumprod(1 + r_sell) - 1 return r_sell_cum #综合收益率 def trade_all(self,m,n,k1,k2): # m,n为均线滞后阶数,且m>n; k1为买入信号滞后阶数,k2为卖出信号滞后阶数 trade_1 = self.signal_1(m, n).shift(k1) buy = pd.Series(0, index=close.index) buy[trade_1 == 1] = 1 trade_2 = self.signal_1(m, n).shift(k2) sell = pd.Series(0, index=close.index) sell[trade_2 == -1] = -1 all = buy + sell r_all = (all*r).dropna() r_all_cum = np.cumprod(1+r_all) - 1 return r_all_cum #市场同期收益率 def market(self): # m,n为均线滞后阶数,且m>n; k1为买入信号滞后阶数,k2为卖出信号滞后阶数 market_s = pd.Series(1, index=close.index) r_market = (market_s*r).dropna() r_m_cum = np.cumprod(1+r_market)-1 return r_m_cum #作图 def picture_ma_1(self,m,n,k1,k2): # m,n为均线滞后阶数,且m>n; k1为买入信号滞后阶数,k2为卖出信号滞后阶数 a = self.trade_buy(m, n, k1) b = self.trade_sell(m, n, k2) c = self.trade_all(m, n, k1, k2) # 设置字体为SimHei显示中文 plt.rcParams['font.sans-serif'] = 'SimHei' # 解决负坐标问题 plt.rcParams['axes.unicode_minus'] = False plt.plot(a, label='ma_buy',color='r') plt.plot(b, label='ma_sell', color='y') plt.plot(c, label='ma_all', color='k') plt.legend() plt.show() return #作图2 def picture_ma_2(self,m,n,k1,k2): # 设置字体为SimHei显示中文 plt.rcParams['font.sans-serif'] = 'SimHei' # 解决负坐标问题 plt.rcParams['axes.unicode_minus'] = False c = self.trade_all(m, n, k1, k2) d = self.market() plt.plot(c, label='ma_all', color='r') plt.plot(d, label='market', color='y') plt.legend() plt.title('均线策略累计收益率与市场同期累积收益率') plt.show() return 下面我们选取BTC季度合约30min收盘价数据,来测试上述均线策略的收益情况: #导入数据 data = pd.read_csv(r'C:\Users\Desktop\量化策略代码\数据\csv\btc永续30min_7月.csv') #调用均线策略类 a = MA() b = a.trade_buy(5,20,2) c = a.trade_sell(5,20,1) d = a.trade_all(5,20,2,1) e = a.market() data_ma = pd.DataFrame({'buy':b,'sell':c,'all':d,'market':e}) a.picture_ma_1(5,20,2,1) a.picture_ma_2(5,20,2,1) print(data_ma) 我们将“黄金交叉”点的买入累积收益、“死亡交叉”点的卖出累积收益和综合累积收益做对比,可以得到如下图所示,“黄金交叉”策略的收益更高一些。 另一方面,为了分析均线策略的实际效果,我们将均线策略的综合累积收益与市场累积收益做对比,结果如下: 从上图可以看出,相比于同期的市场收益情况,均线策略确实能取到一定的效果。 3.注意事项 均线策略多用在市场较为震荡的行情中,如果市场单一上涨或下跌,那么均线策略将发出错误信号。以BTC日收盘价为例,自今年3月以来,BTC一直上涨,累积涨幅目前高达3倍左右,如果使用均线策略,其收益便不如市场收益。 因此均线策略在日度策略中不建议常用,但可以用在15min、30min等高频以及高震荡的环境中。 —- 编译者/作者:OKEx Research 玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。 |
OKEx数字货币量化交易策略系列报告(二)-均线交易策略研究报告
2019-11-05 OKEx Research 来源:区块链网络
LOADING...
相关阅读:
- 8月5晚间行情视频解读:日内缩量反抽、操作上依旧把握区间机会2020-08-05
- 金生论币:8.5ETH晚间行情分析及操作策略2020-08-05
- 管交所BGOEX合约实战心得之选好币种和开仓点位2020-08-05
- 币圈少年的大起大落,诠释什么叫做“赌” | 币安1eo竟不是defi2020-08-05
- 盯上DeFi?SEC寻找区块链智能合约分析工具2020-08-05