python——金融商品多种均线指标综合运用模拟实现(MACD模型)

金融商品多种均线指标综合运用模拟实现

一、均线策略简介

1、均线

均线之间的距离叫作乖离率,当五日均线在十日均线上方,方向向上发展,且距离不断加大说明正在上升趋势中,乖离率太大有回档的可能,应设好止损点,逢 低介入 当五日均线在十日线下方,方向向下发展,距离不断扩大,说明是空头趋势,乖离太大有反弹的机会,应该逢反弹高点做空,均线走平或频繁交叉,说明没有趋势,是盘整,空仓观望 等待突破形成新的趋势或轻仓位短线来回。

2、简单移动平均

简单移动平均数求解算术平均数的方法,即先对一组数据的值求和,再用这个总和除以这组数据的个数得到算术平均数。同理,股价的简单移动平均数就是将一组股价值相加,再除以股价的个数。因此,需要先确定对哪几个数求平均数,即确定股价的个数n。一般以日、周为单位,比如求5日平均数,10日平均数,20日平均数或者3周平均数。此外,为了体现移动的作用,求得第一个平均数后,要求第二个平均数,就要把原来的一组数的最早一项股价减去,再加上一项新的股价,求和后再除以股价的个数,以得到第二个平均数。移动平均的期数的选择对简单移动平均的修匀效果影响很大,要确定移动平均的期数,一般需要从以下三方面考虑:
(1)事件发展的周期性,如果事件的发展具有周期性,一般应以周期长度作为移动平均的间隔长度。
(2)对趋势平均性的要求,一般来说,移动平均的期数越多,修匀效果越平均,表现出的趋势就越清晰。
(3)对趋势反映近期变化敏感程度的要求。用移动平均方法确定事件的发展趋势都具有一定的滞后性。移动平均的期数越多,滞后性越大,移动平均的期数越少,所得的趋势图对近期变化的反应就越敏感。因此,如果想得到长期趋势,最好做期数比较大的移动平均;如果想密切关注序列的短期趋势,最好做期数比较小的移动平均。

3、加权移动平均

加权移动平均数与简单移动平均数不同,其并不是简单地把股票价格相加,而是对股价赋予一定的权重再相加。对股票价格求平均的目的即是得到一条能够代表股票价格的相对平均的曲线。根据对股票市场的认知,昨天的数据会比10天前的价格更能反映今天的股价情况。离当前时间越近的数据越具有代表性,越久远的数据越没有代表性。因此,,在预测股价时,不同时期的股价数据具有不同的代表性。为了表示其代表性的高低,可以考虑先对股价赋予一定的权重,再求平均值。

4、MACD涉及的指标

指标名称 含义 计算公式
短期EMA 短期(例如12日)的收盘价指数移动平均值 EMA(12)=前一日EMA(12)11/13+今日收盘价2/13
长期EMA 长期(例如26日)的收盘价指数移动平均值 EMA(26)=前一日EMA(26)25/27+今日收盘价2/27
DIF 短期EMA和长期EMA的离差值 DIF=EMA(12)-EMA(26)
DEA DIF线的M日指数平滑移动平均线 今日DEA=(前一日DEA8/10+今日DIF2/10)
MACD DIF线与DEA线的差,有时是差的平方 MACD=DIF-DEA

(1)MACD
MACD(Moving Average Convergenceand Divergence)即指数平滑移动平均线,由Geral Appel于1970年提出,属于大势趋势类指标,它由长期慢速均线DEA,短期快线的DIF,红色能量柱(多头),绿色能量柱(空头)、0轴(多空分界线)五部分组成,即“两线两柱一轴”组合起来形成。
MACD是从双指数移动平均线发展而来的,由快的指数移动平均线(EMA12)减去慢的指数移动平均线(EMA26)得到快线DIF,再用2×(快线DIF-DEA)得到MACD柱。MACD的意义和双移动平均线相似,即由快、慢均线的离散、聚合来显示当前的多空状态和股价可能的发展变化趋势并对买进、卖出时机作出研判,但MACD阅读起来更方便。当MACD从负数转向正数,即买入信号;当MACD从正数转向负数,即卖出信号;当MACD以大角度变化,表示快的移动平均线和慢的移动平均线的差距非常迅速的拉开,代表了一个市场大趋势的转变。
(2)DIF与DEA金叉的使用
A.当白线即短期快线DIF向上穿过黄色的长期慢线DEA时,即“快线高于慢线”,属于做多金叉信号。然而实际中需要进行“金叉+零轴”的综合考虑。
B.当零轴之下出现金叉时,股价属于弱势市场,金叉为弱势金叉,股价极有可能短期弱势反弹或暂时止跌后再度夭折,一般没有做多价值。
C.当零轴之上发生金叉时,股价属于强势市场,金叉为强势金叉,股价后市成功惯性上攻的概率较高。若零轴之上出现二次金叉信号时,又称零上二次红金叉,属于股价强势中的强势,此时跟进做多,股价往往容易出现加速上涨。属于短线极佳买点。
(3)DIF与DEA死叉的使用
当白线即短期快线DIF向下穿过黄色的长期慢线DEA时,即“快线低于慢线”,属于做空死叉信号,死叉同样需要结合零轴。当零轴之上出现死叉时,一般认为是股价上升趋势途中的短暂回调,后市股价仍有再次走强的可能。当零轴之下发生死叉时,一般认为是股价下跌趋势途中的继续回调,后市股价惯性下跌的概率较高,尤其是MACD零轴之下出现二次死叉时,股价更容易出现加速下跌行情,所以零轴之下,无论出现的是一次死叉或二次死叉,投资者都应当空仓观望,静观其变。

5、常用平均方法的比较

(1)使用全局数据还是局部数据
对于移动平均法,包括简单移动平均和加权移动平均所利用的数据都是局部的,即使用过去n期的数据进行平均。而指数加权移动平均法,使用的是全局全部数据。
(2)使用同等权重还是差别权重
加权移动平均法和指数加权移动平均法,皆对不同时点的数据赋予不同的权重;比如对于较近的数据赋予较大的权重,而对于时间间隔较远的数据则赋予较小的权重。因此,两种方法更加重视对近期信息的利用。虽然两者都可以对近期数据赋予较大的权重,但其权重的生成方法还是有差别的。
指数加权移动平均法中,各期权重随时间间隔的增大而呈指数衰减。而加权移动平均法权重的确定则相对主观一些,通常根据专家建议或者历史经验而确定。简单移动平均法则对每一个数据都赋予相同的权,即平均期数的倒数,简单移动平均法对于每个时点的历史数据都采取相同的重视程度。

6、均线时间跨度

无论是简单移动平均线、加权移动平均线还是指数移动平均线,时间跨度的选择都很重要。股票数据可以是日內实时数据,也可是以日为单位的数据。在时间跨度选择上,可以选择以分为单位,也可以选择以日,周,月,季度甚至年为单位。以日为单位,可以刻画5日均线,10日均线,20日均线,25日均线等;以周为单位,可以有5周均线,10周均线等;以月为单位,可以有3个月均线,12个月均线,24个月均线等。
均线的时间跨度选择根据实际要分析的问题来确定。不同时间跨度的均线对于价格趋势的刻画和敏感度会有差别。均线一般分为短期均线和长期均线,但所谓的短期和长期并没有明确的区分界限。与18个月的均线相比,22日均线可以看作短期均线。如果只在5日均线和22日均线中区分短期均线和长期均线,往往会把5日均线称为短期均线,22日均线称作长期均线。

二、获取云南白药(000538.SZ)交易数据

Out[1]:
Date
2019-01-03 -0.026971
2019-01-04 0.013716
2019-01-07 0.020437
2019-01-08 0.024724
2019-01-09 0.001617
2020-06-22 -0.005435
2020-06-23 0.022186
2020-06-24 0.006308
2020-06-29 0.002869
2020-06-30 -0.006251
Name: Close, Length: 358, dtype: float64

三、移动平均

(1)运用smaCal()函数计算_5日简单移动平均价格
Out[2]:
Date
2020-06-22 90.478000
2020-06-23 91.372000
2020-06-24 92.190001
2020-06-29 93.108000
2020-06-30 93.468001
dtype:float64
(2)绘制云南白药(000538.SZ)_5日简单移动平均图表
Out[3]:
在这里插入图片描述

因为5天均线取的是前5个交易日的均值,相当于做了一个平滑,所以图中股票价格的波动比5天均线的波动要大。由图中可以看出,股价回落,有跌破5日均线的趋势但是还没有跌破,这是可以结合大势和个股的基本面,继续持仓。
(3)运用wmaCal()函数加权移动平均函数
Out[4]:
Date
2020-06-19 90.256667
2020-06-22 90.934667
2020-06-23 91.952000
2020-06-24 92.868001
2020-06-29 93.601334
dtype:float64
(4)绘制云南白药(000538.SZ)_5日加权移动平均
Out[5]:
在这里插入图片描述

由图中可以看出,云南白药的价格的波动比五日均线的波动大,市价高于5日均线,释放出买入信号,第二天可以进行买入建仓或加仓。
四、双均线交叉交易策略
(1)云南白药(000538.SZ)股价数据与均线分析
Out[6]:
在这里插入图片描述

SMA、WMA、EMA、股价时序图中可以看出,四线的波动性股价的波动性最强,EMA的波动性最弱,此时可以根据EMA做长期投资。
(2)云南白药(000538.SZ)股价长、短均线分析
Out[7]:
在这里插入图片描述

当5日均线上穿22日均线时,视为买入信号,以第二天开盘价全仓买入;当5日均线下穿22日均线时,视为卖出信号,以第二天开盘价全仓卖出。从图中可以看出5日均线和22日均线没有出现交叉趋势,且5日均线在22日均线上方,方向向上发展,且距离不断加大,说明正在上升趋势中,乖离率太大有回档的可能,应设好止损点,逢低介入。
(3)异同移动平均线(MACD)
Out[8]:
winLrate: 22.73%
winSrate: 40.91%
winRate: 31.82%
CumSLtrade: -23.36%
根据异同移动平均线的结果可得,做长期交易的赢率为22.73%,做短期交易的赢率为40.91%,总的赢率为31.82%,但是总的积累贸易率为-23.36%。
Out[9]:
在这里插入图片描述

由图可以看出,2019年-2020年7月云南白药的交易变动趋势整体上比大盘的趋势好。
Out[10]:
在这里插入图片描述

由上图可以看出,12MA线有下穿26MA线的趋势,释放出卖出信号,根据DIF和DEA图可以看出,目前已经错过了DIF上穿DEA时的最佳买入点,此时有持仓的要选择适当的点将股票卖出。

五、多种均线指标综合运用模拟实现

Out[11]:
smaWinrate: 51.26%
Out[12]:
在这里插入图片描述

根据上图和smaWinrate的结果可以看出,要是现在买入持有云南白药股票的赢率为51.26%。
Out[13]:


winLrate: 48.28%
winSrate: 54.1%
winRate: 51.26%
CumSLtrade: 18.72%


Out[14]:
macdWinRate: 49.66%
根据异同移动平均线的结果可得,做长期交易的赢率为48.28%,做短期交易的赢率为54.1%,总的赢率为51.26%,总的积累贸易率为18.72%,MACD线的赢率为49.66%。
Out[15]:
在这里插入图片描述

Out[16]:


买进持有收益率: 54.47%
复式均线交易策略收益率: 102.11%
复式均线交易策略年化收益率: 12.63%


由结果可得,买进持有收益率为 54.47%;复式均线交易策略收益率为102.11%;复式均线交易策略年化收益率为 12.63%。

六、运行代码

# 获取云南白药(000538.SZ) 交易数据
import time
import datetime
import pandas_datareader as web
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
stock=input("输入股票代码=====>")
stockfile=stock+".SZ"
#from pandas_datareader import data as web
write=pd.ExcelWriter('D:/stock.xlsx')
starttime=time.perf_counter()
star=datetime.datetime(2019,1,1)
end=datetime.datetime(2020,6,30)
df=web.DataReader(stockfile,'yahoo',star,end)
df.to_excel(write,'stock')
write.save()
SS=pd.read_excel('D:/stock.xlsx')
Close=df.Close
ret000538=(Close-Close.shift(1))/Close.shift(1)
ret000538=ret000538.dropna()
ret000538
# *************************************************
#运用 smaCal( )函数计算简单移动平均价格
def smaCal(tsPrice,k):
    import pandas as pd
    Sma=pd.Series(0.0,index = tsPrice.index)
    for i in range(k-1,len(Close)):
        Sma[i] = sum(Close[(i-k+1):(i+1)])/k
    return(Sma)
Sma5 = smaCal(Close ,5) 
Sma5.tail() 
# *************************************************
#云南白药(000538.SZ) _5 日简单移动平均
for i in range(4,len(Close)):
    Sma5[i]=np.mean(Close[(i-4):(i+1)])
#************************************************ 
plt.plot(Close[4:],label = 'Close',color = 'g')
plt.plot(Sma5[4:],label ='Sma5', \
         color = 'r',linestyle = 'dashed')
plt.xlabel('date')
plt.ylabel('Price')
plt.title('2019-000538.SZ\
          Price and Sma5 ')
plt.ylim(55,95)
plt.legend()
plt.show()
# *************************************************
# 30.2.2 云南白药(000538.SZ) _5 日加权移动平均函数
b = np.array([1,2,3,4,5])
w = b / sum(b)
w
#******************************************
Wma5 = pd.Series(0.0,index = Close.index)
for i in range(4,len(Close)):
    Wma5[i] = sum(w*Close[(i-4):(i+1)])
Wma5[-6:-1]
# *************************************************
# 云南白药(000538.SZ) _5 日加权移动平均
plt.plot(Close[4:],label = 'Close',color = 'b')
plt.plot(wma5[4:],label ='wma5', color = 'r',linestyle = 'dashed')
plt.xlabel('date')
plt.ylabel('Price')
plt.title('2019-(000538.SZ) \
          price and Wma5 ')
plt.ylim(55,95)
plt.legend()
plt.show()
# *************************************************
# 30.2.3 加权移动平均函数
def wmaCal(tsPrice,weight):
    import pandas as pd
    import numpy as np
    k = len(weight)
    arrWeight = np.array(weight)
    Wma = pd.Series(0.0,index = tsPrice.index)
    for i in range(k-1,len(tsPrice.index)):
        Wma[i] = sum(arrWeight*tsPrice[(i-k+1):(i+1)])
    return(Wma)
#************************************************
wma5 = wmaCal(Close,w) 
Wma5[4:9]
wma5 = wmaCal(Close,[0.1,0.15,0.2,0.25,0.3])
wma5.tail()
# *************************************************
import pandas as pd
import numpy as np
#******************************************************
def smaCal(tsPrice,k):
    Sma=pd.Series(0.0,index=tsPrice.index)
    for i in range(k-1,len(tsPrice)):
        Sma[i]=sum(tsPrice[(i-k+1):(i+1)])/k
    return(Sma)          
Sma10 = smaCal(Close,10)
Sma10.tail()
# *************************************************
def wmaCal(tsPrice,weight):
    k=len(weight)
    arrWeight=np.array(weight)
    Wma=pd.Series(0.0,index=tsPrice.index)
    for i in range(k-1,len(tsPrice.index)):
        Wma[i]=sum(arrWeight*tsPrice[(i-k+1):(i+1)])
    return(Wma)
weight = np.array(range(1,11))/sum(range(1,11))
Wma10 = wmaCal(Close,weight)
Wma10.tail()
# *************************************************
def ewmaCal(tsprice,period=5,exponential=0.2):
    Ewma=pd.Series(0.0,index=tsprice.index)
    Ewma[period-1]=np.mean(tsprice[0:period])
    for i in range(period,len(tsprice)):
        Ewma[i]=exponential*tsprice[i]+(1-exponential)*Ewma[i-1]
    return(Ewma)
expo = 2/(len(Close)+1)
Ema10 = ewmaCal(Close,10,expo)
Ema10.tail()
# *************************************************
#云南白药(000538.SZ)股价数据与均线分析
plt.plot(Close[10:],label="Close",color='k')
plt.plot(Sma10[10:],label="Sma10",color='r',ls ='dashed')
plt.plot(Wma10[10:],label
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值