深入解析移动平均线:追踪趋势的关键技术指标
1.移动平均线
在所有技术指标中,移动平均线的应用最为广泛。因为其构造方法简单,结果易于定量检验:在技术图表分析中,对市场走势的分析很大程度上是基于分析师的主观判断,因此很难在计算机上量化;而移动平均线的规则不随分析师的主观意愿而改变。它们可以轻松地写入计算机程序,然后自动生成买入和卖出信号。
从本质上讲,移动平均线是一种趋势跟踪工具,可用于识别和显示旧趋势的结束或逆转,以及新趋势的出现。因此,移动平均线从不预测市场的走向,而是对市场已经发生的事实作出反应。一般来说,根据计算方法的不同,移动平均线分为简单移动平均线(SMA)、线性加权移动平均线(WMA)和指数加权移动平均线(EMA)。其中,线性加权移动平均线(WMA)在量化中的应用涉及浮点问题,容易出现漏洞。因此,本文重点讨论简单移动平均线和指数加权移动平均线在量化中的应用。
第一个是简单移动平均线。所谓简单移动平均线,其实就是算术平均线。根据定义,第k个时间单元的m阶移动平均(k>m)为:
我们以BTC每日收盘价为例。对其运行以下程序以获得其移动平均线图表:
作为PD
numpy 作为 np
。作为PLT
从。
()
data = pd.(r'C:\Users\\量化策略代码\Data\csv\btc永续30min.csv')
data.index = pd.(data.iloc[:,0])
= data.iloc[:,1]
#提取收盘价数据
关闭=
#建立移动平均函数并获取移动平均线
(k):#k为移动平均线的滞后期数
#设置时间序列
MA_k = pd.(0,索引=数据.索引)
#使用for循环申请工作
对于范围内的 i(k-1,len(close)):
MA_k[i]= sum(close[(i-k+1):(i+1)])/k
MA_k
#将移动平均线图添加到价格时间序列图
(m,n):#m,n为移动平均滞后阶数,m
ma_1 = (米)
ma_2 = (n)
plt.['轴。']=False
plt.['font.sans-serif']=''
plt.plot(close[(n-1):],label='价格',color='k')
plt.plot(ma_1[(n-1):],标签='MA_1',颜色='r')
plt.plot(ma_2[(n-1):],标签='MA_2',颜色='y')
plt.title('BTC均线及价格时间序列图')
plt.()#添加图例
plt.show()
另一种类型是指数加权移动平均线。加权移动平均线是另一种移动平均线。后期价格权重较大,前期价格权重较小,包含金融产品。上市以来所有历史价格计算如下:
用代码来表示,制作EMA图如下:
#创建指数加权移动平均函数
(k,=0.2):#k为滞后阶数,权重默认0.2,可根据实际情况修改
ema_k = pd.(0,index=close.index)
ema_k[k-1]= np.mean(close[:k])
对于范围内的 i(k,len(close)):
ema_k[i]= *关闭[i]+(1-)*ema_k[i-1]
EMA_K
#在价格时间序列图表中添加指数加权移动平均线图表
(m): #m 是移动平均滞后阶数
EMA = (米)
plt.['轴。']=False
plt.['font.sans-serif']=''
plt.plot(close[(m-1):],label='价格',color='k')
plt.plot(EMA[(m-1):],标签='EMA',颜色='r')
plt.title('BTC均线及价格时间序列图')
plt.()#添加图例
plt.show()
2. 均线策略的运用
现在我们使用简单的双移动平均线策略来构建一个简单的量化系统。这种技术称为“双线相交法”:
(1)当短期均线自下而上穿越长期均线时,为“金叉”,释放买入信号;
(2)当短期均线自上而下穿越长期均线时,为“死亡交叉”,释放卖出信号。
基于以上原理,我们构建了如下的交易系统(为了方便调用,我们可以将交易系统封装成一个类,然后将各个子系统封装成函数):
#构建均线交易系统
class MA: #使用类封装单一均线系统
(self,m,n):#m,n为移动平均线的滞后阶数,且m>n
ma_1 = (米)
ma_2 = (n)
= pd.(0,index=close.index)
对于范围内的 i(1,len(ma_2.index)):
#金十字
if(ma_1[i]>ma_2[i])&(ma_1[i-1]n; k 是信号滞后阶数
贸易 = self.(m, n).shift(k)
买入 = pd.(0, 指数=收盘指数)
购买[交易==1]=1
#计算金叉的回报率
r_buy =(买*r).()
= np.(1+r_buy)-1
#
(self, m, n, k): # m,n为移动平均线的滞后阶数,且m>n; k 是信号的滞后阶数
贸易 = self.(m, n).shift(k)
卖出 = pd.(0, 指数=收盘指数)
卖出[交易 =-1]=-1
# 计算死亡交叉的回报率
=(卖出 * r).()
= np.(1+ )-1
#综合回报率
(self,m,n,k1,k2): # m,n为移动平均线的滞后阶数,且m>n; k1 是买入信号的滞后阶数,k2 是卖出信号的滞后阶数
= self.(m, n).shift(k1)
买入 = pd.(0, 指数=收盘指数)
购买[==1]=1
= self.(m, n).shift(k2)
卖出 = pd.(0, 指数=收盘指数)
卖出[==-1]=-1
全部=买入+卖出
r_all =(全部*r).()
= np.(1+r_all)-1
#同期市场收益率
(self):# m,n为移动平均线的滞后阶数,且m>n; k1 是买入信号的滞后阶数,k2 是卖出信号的滞后阶数
= pd.(1, 索引=close.index)
=(*r).()
= np.(1+)-1
#绘画
(self,m,n,k1,k2):# m,n为移动平均线的滞后阶数,且m>n; k1 是买入信号的滞后阶数,k2 是卖出信号的滞后阶数
a = 自身。(m, n, k1)
b = 自身。(m, n, k2)
c = self.(m, n, k1, k2)
# 设置显示中文的字体
plt.['font.sans-serif']=''
# 解决负坐标问题
plt.['轴。']=False
plt.plot(a, 标签='',颜色='r')
plt.plot(b, 标签='', 颜色='y')
plt.plot(c, 标签='', 颜色='k')
plt.()
plt.show()
#绘图2
(自我,m,n,k1,k2):
# 设置显示中文的字体
plt.['font.sans-serif']=''
# 解决负坐标问题
plt.['轴。']=False
c = self.(m, n, k1, k2)
d = 自我。()
plt.plot(c, 标签='', 颜色='r')
plt.plot(d, 标签='', 颜色='y')
plt.()
plt.title('均线策略累计收益率与同期市场累计收益率')
plt.show()
下面我们选取BTC季度合约的30分钟收盘价数据来测试上述均线策略的收益:
#导入数据
data = pd.(r'C:\Users\\量化策略代码\Data\csv\btc永续月.csv')
#调用均线策略类
a = MA()
b = a.(5,20,2)
c = a.(5,20,1)
d = a.(5,20,2,1)
e = a.()
= pd.({'买入':b,'卖出':c,'全部':d,'':e})
a.(5,20,2,1)
a.(5,20,2,1)
打印()
我们比较“金叉”点买入的累计收益、“死亡十字”点卖出的累计收益以及综合累计收益。如下图所示,“金十字”策略的回报较高。
另一方面,为了分析均线策略的实际效果,我们将均线策略的综合累计收益与累计市场收益进行了比较。结果如下:
从上图可以看出,与同期市场收益相比,均线策略确实能够取得一定的效果。
3、注意事项
移动平均线策略主要用于波动的市场条件。如果市场单独上涨或下跌,均线策略就会发出错误的信号。以BTC日收盘价为例,BTC自今年3月份以来一直在上涨,目前累计涨幅高达3倍左右。如果采用均线策略,收益将不如市场收益。
因此,均线策略不建议在日常策略中常用,但可以在15min、30min等高频、波动较大的环境下使用。