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

一、均线策略简介

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 pdSma=pd.Series(0.0,index = tsPrice.index)for i in range(k-1,len(Close)):Sma[i] = sum(Close[(i-k+1):(i+1)])/kreturn(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 pdimport numpy as npk = 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)])/kreturn(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="Wma10",color='b',ls =':')
plt.plot(Ema10[10:],label="Ema10",color='g',ls ='-.')
plt.title("云南白药(000538.SZ)股价数据均线")
plt.ylim(55,95)
plt.legend()
plt.show()
# *************************************************
# 30.7.1 云南白药(000538.SZ)股价长、短均线分析
Sma5 = smaCal(Close,5)
Sma22 = smaCal(Close,22)
#************************************************
plt.plot(Close[:],label="Close",color='b')
plt.plot(Sma5[5:],label="Sma5",color='r',ls ='dashed')
plt.plot(Sma22[22:],label="Sma22",color='g',ls ='-.')
plt.title("云南白药(000538.SZ)股价长、短均线")
plt.show()
# *************************************************
#************************************************
# 30.8.2 云南白药(000538.SZ) 双均线交叉交易策略
#short and long
Ssma3 = smaCal(Close,3);
Lsma10= smaCal(Close,10);
SLSignal = pd.Series(0,index = Lsma10.index)
for i in range(1,len(Lsma10)):if all([Ssma3[i] > Lsma10[i],Ssma3[i-1] < Lsma10[i-1]]):SLSignal[i] = 1elif all([Ssma3[i] < Lsma10[i],Ssma3[i-1] > Lsma10[i-1]]):SLSignal[i] = -1
#************************************************
SLSignal[SLSignal == 1]
SLSignal[SLSignal == -1]
SLTrade = SLSignal.shift(1)
#************************************************
Lsma22= smaCal(Close,22);
Long = pd.Series(0,index = Lsma22.index)
Long[SLTrade == 1] = 1
Ret = Close / Close.shift(1)-1
LongRet = (Long*Ret).dropna()
winLrate = len(LongRet[LongRet > 0])/len(LongRet[LongRet != 0])
# *************************************************
Short = pd.Series(0,index = Lsma22.index)
Short[SLTrade == -1] = -1
ShortRet = (Short*Ret).dropna()
winSrate = len(ShortRet[ShortRet > 0])/len(ShortRet[ShortRet !=0 ])
winSrate
# *************************************************
SLtradeRet = (SLTrade*Ret).dropna()
winRate = len(SLtradeRet[SLtradeRet > 0])/len(\
SLtradeRet[SLtradeRet !=0])
#*****************************************************
cumLong = np.cumprod(1+LongRet)-1
cumShort = np.cumprod(1+ShortRet)-1
cumSLtrade = np.cumprod(1+SLtradeRet)-1
CumSLtrade = cumSLtrade[-1]
#******************************************************
print('winLrate : ',round(winLrate*100,2), '%' )
print('winSrate : ',round(winSrate*100,2), '%' )
print('winRate : ',round(winRate*100,2), '%' )
print('CumSLtrade : ',round(CumSLtrade*100,2), '%' )
# *************************************************
plt.plot(cumSLtrade,label="cumSLtrade",color='k')
plt.plot(cumLong, label="cumStock",\color='b',linestyle='dashed')
plt.plot(cumShort,label="cumTrade",\color='r',linestyle=':')
plt.title("云南白药(000538.SZ)长短期均线交易累计收益率")
plt.legend(loc='best')
plt.show()
# *************************************************
# 30.9.2 云南白药(000538.SZ) K线 & MACD 代码
import pandas as pd
import pmdarima as pm
import matplotlib.pyplot as plt
import yfinance as yf
import datetime
now = datetime.datetime.now()
start = "2019-01-01"
StockID = input("输入股票代号 ENTER FULL names of Stock : ====>")
Stockdata = yf.download(StockID,start = start, end = now)
# *************************************************
df = Stockdata
df.describe()
WK = df
High = WK.High
Low = WK.Low
Open = WK.Open
Close = WK.Close
Volume = WK.Volume
ndate = len(Close)
#***********************************************
WKlist = list()
for i in range(len(WK)):WKlist.append(WK.iloc[i,:5])
WKlist
# **************** plot ********************
import datetime as dt
import numpy as np
import matplotlib
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas_datareader as web
import mpl_finance as mpf
from mpl_finance import candlestick_ohlc
matplotlib.use('TkAgg')
#************************************************
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
%matplotlib inline
#************************************************
# ========= MACD 的求值過程 =========
# ========= DIF =========
# ========= Ewma12 =========
exponential = 2 / (12 + 1)
def ewmaCal(tsPrice, period= 12 , exponential = 0.15384615384615385) :Ewma = pd.Series([np.nan]*len(tsPrice),index=tsPrice.index)Ewma[period-1] =np.mean(tsPrice[:period])for i in range(period, len(tsPrice)) :Ewma[i] = exponential*tsPrice[i] + (1 - exponential)*Ewma[i-1]return (Ewma)
Ewma12 = pd.Series([np.nan] * len(Close),index=Close.index)
Ewma12[11] =np.mean(Close[:11])
for i in range(12, len(Close)) :Ewma12[i] = exponential* Close[i]+ (1- exponential)*Ewma12[i-1]
#************************************************
# ========= Ewma26 =========
exponential = 2 / (26 + 1)
def ewmaCal(tsPrice, period= 26 , exponential=0.07407407407407407) :Ewma = pd.Series([np.nan]*len(tsPrice),index=tsPrice.index)Ewma[period-1] =np.mean(tsPrice[:period])for i in range(period, len(tsPrice)) :Ewma[i] = exponential*tsPrice[i] + (1 - exponential)*Ewma[i-1]return (Ewma)
Ewma26 = pd.Series([np.nan] * len(Close),index=Close.index)
Ewma26[25] =np.mean(Close[:25])
#index 25 is out of bounds for axis 0 with size 0
for i in range(26, len(Close)) :Ewma26[i] = exponential* Close[i]+ (1- exponential)*Ewma26[i-1]
#************************************************
DIF = (Ewma12 - Ewma26)
# ========= DEA =========
DIF = DIF.dropna()
exponential = 2 / (9 + 1)
def ewmaCal(DIF, period= 9 , exponential=0.2) :Ewma = pd.Series([np.nan]*len(DIF),index=DIF.index)Ewma[period-1] =np.mean(DIF[:period])for i in range(period, len(DIF)) :Ewma[i] = exponential*DIF[i] + (1 - exponential)*Ewma[i-1]return (Ewma)
EwmaDIF = pd.Series([np.nan] * len(DIF),index=DIF.index)
EwmaDIF[8] =np.mean(DIF[:8])
for i in range(9, len(DIF)) :EwmaDIF[i] = exponential* DIF[i]+ (1- exponential)*EwmaDIF[i-1]
DEA = EwmaDIF
DEA = DEA.dropna()
#************************************************
# ========= MACD = DIF - DEA =========
MACD = DIF - DEA
MACD = MACD.dropna()
#****************** plot *********************
import datetime as dt
import matplotlib
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas_datareader as web
import mpl_finance as mpf
from mpl_finance import candlestick_ohlc
matplotlib.use('TkAgg')
%matplotlib inline
#*************************************************************
WKlist = list()
for i in range(len(WK)):WKlist.append(WK.iloc[i,:5])
WKlist
#*************************************************************
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
# *************************************************
# Extracting Data for plotting
Ma12 = Close.rolling(window = 12).mean()
Ma26 = Close.rolling(window = 26).mean()
WK = df[['Open', 'High', 'Low', 'Close','Volume']]
WK.reset_index(inplace=True)
WK['Date'] = WK['Date'].map(mdates.date2num)
fig = plt.figure(figsize=(24, 8))
ax = fig.add_subplot(3, 1, 1)
candlestick_ohlc(ax, WK.values, width=0.5, colorup='g', colordown='r')
ax.xaxis_date()
ax.grid(True)
ax.set_axisbelow(True)
ax.plot(Ma12, label='12MA')
ax.plot(Ma26, label='26MA')
plt.ylabel(' PRICE ')
plt.title(StockID + ' Stock K-CHART & 12-26 MA ')
plt.grid(True,axis = 'both')
plt.legend();
#************************************************
ax1 = fig.add_subplot(3, 1, 2)
plt.plot(DIF, label = ' DIF ')
plt.plot(DEA, label = ' DEA ')
plt.title(' 信號線 DIF 與 DEA ')
plt.legend()
#************************************************
ax2 = fig.add_subplot(3, 1, 3)
plt.bar(range(1,len(MACD)+1), MACD , label = ' MACD ')
ax2.set_xticks(range(0, len(Close.index), 45))
ax2.set_xticklabels(Close.index[::45],rotation=10)
plt.title(' MACD 柱狀圖 ')
plt.legend()
plt.show()
# *************************************************
#  均线系统交易策略绩效
#云南白药(000538.SZ)
import pandas as pd
import pmdarima as pm
import matplotlib.pyplot as plt
import yfinance as yf
import datetime
now = datetime.datetime.now()
start = "2015-01-01"
StockID = input("输入股票代号 ENTER FULL names of Stock : ====>")
Stockdata = yf.download(StockID,start = start, end = now)
# *************************************************
df = Stockdata
df.describe()
WK = df
High = WK.High
Low = WK.Low
Open = WK.Open
Close = WK.Close
Volume = WK.Volume
ndate = len(Close)
WKlist = list()
for i in range(len(WK)):WKlist.append(WK.iloc[i,:5])
WKlist
# **************** plot ********************
import datetime as dt
import matplotlib
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas_datareader as web
import mpl_finance as mpf
from mpl_finance import candlestick_ohlc
matplotlib.use('TkAgg')
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
%matplotlib inline
#************************************************
#trading-sma5 and close
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)])/kreturn(Sma)
Sma5 = smaCal(Close,5)
Sma5.tail()
Sma5 = smaCal(Close,5)
Sma12 = smaCal(Close,12)
SmaSignal = pd.Series(0,index = Close.index)
for i in range(5,len(Close)):if all([Sma5[i] > Sma12[i],Sma5[i-1] < Sma12[i-1]]):SmaSignal[i] = 1 ;elif all([Sma5[i] < Sma12[i],Sma5[i-1] > Sma12[i-1]]):SmaSignal[i] = -1 ;
SmaSignal
SmaTrade = SmaSignal.shift(1).dropna()
SmaBuy = SmaTrade[SmaTrade == 1]
SmaSell = SmaTrade[SmaTrade == -1]
#************************************************
Ret = Close/Close.shift(1)-1
SmaRet = (Ret * SmaTrade).dropna()
#************************************************
cumStock = np.cumprod(1 + Ret[Ret.index[0]:])-1
cumTrade = np.cumprod(1 + SmaRet[SmaRet.index[0]:])-1
cumdata = pd.DataFrame({'cumTrade':cumTrade,\'cumStock':cumStock})
#************************************************
plt.plot(cumStock,label = "cumStock",color = 'g')
plt.plot(cumTrade,label = "cumTrade",color='r',linestyle = ':')
plt.title("<BH>买进持有与均线交易的累积收益率")
plt.legend()
# *************************************************
SmaRet[SmaRet == (-0)] = 0
smaWinrate = len(SmaRet[SmaRet>0])/len(SmaRet[SmaRet != 0])
smaWinrate
print('smaWinrate : ' , round(smaWinrate*100,2), '%')
# *************************************************
#short and long
Ssma5 = smaCal(Close,5);
Lsma12 = smaCal(Close,12);
SLSignal = pd.Series(0,index = Lsma12.index)
for i in range(1,len(Lsma12)):if all([Ssma5[i] > Lsma12[i],Ssma5[i-1] < Lsma12[i-1]]):SLSignal[i] = 1elif all([Ssma5[i] < Lsma12[i],Ssma5[i-1] > Lsma12[i-1]]):SLSignal[i] = -1
SLSignal[SLSignal == 1]
SLSignal[SLSignal == -1]
SLTrade = SLSignal.shift(1)
#************************************************
Long = pd.Series(0,index = Lsma12.index)
Long[SLTrade == 1] = 1
Ret = Close / Close.shift(1)-1
LongRet = (Long*Ret).dropna()
winLrate = len(LongRet[LongRet > 0])/len(LongRet[LongRet != 0])
#************************************************
Short = pd.Series(0,index = Lsma12.index)
Short[SLTrade == -1] = -1
ShortRet = (Short*Ret).dropna()
winSrate = len(ShortRet[ShortRet > 0])/len(ShortRet[ShortRet != 0 ])
winSrate
#************************************************
SLtradeRet = (SLTrade*Ret).dropna()
winRate = len(SLtradeRet[SLtradeRet > 0])/len(\SLtradeRet[SLtradeRet != 0])
#************************************************
cumLong = np.cumprod(1+LongRet)-1
cumShort = np.cumprod(1+ShortRet)-1
cumSLtrade = np.cumprod(1+SLtradeRet)-1
CumSLtrade = cumSLtrade[-1]
print('***************************************')
print('winLrate : ',round(winLrate*100,2), '%' )
print('winSrate : ',round(winSrate*100,2), '%' )
print('winRate : ',round(winRate*100,2), '%' )
print('CumSLtrade : ',round(CumSLtrade*100,2), '%' )
print('***************************************')
# *********** MACD 的求值過程 ***************
# *********** DIF **************************
# *********** Ewma5 **********************
exponential = 2 / ( 5 + 1)
def ewmaCal(tsPrice, period= 5 , exponential = 0.333333 ) :Ewma = pd.Series([np.nan]*len(tsPrice),index=tsPrice.index)Ewma[period-1] =np.mean(tsPrice[:period])for i in range(period, len(tsPrice)) :Ewma[i] = exponential*tsPrice[i] + (1 - exponential)*Ewma[i-1]return (Ewma)
Ewma5 = pd.Series([np.nan] * len(Close),index=Close.index)
Ewma5[4] =np.mean(Close[:4])
for i in range(5, len(Close)) :Ewma5[i] = exponential* Close[i]+ (1- exponential)*Ewma5[i-1]
# ***************** Ewma12 ***********************
exponential = 2 / (12 + 1)
def ewmaCal(tsPrice, period= 10 , exponential = 0.153846) :Ewma = pd.Series([np.nan]*len(tsPrice),index=tsPrice.index)Ewma[period-1] =np.mean(tsPrice[:period])for i in range(period, len(tsPrice)) :Ewma[i] = exponential*tsPrice[i] + (1 - exponential)*Ewma[i-1]return (Ewma)
Ewma12 = pd.Series([np.nan] * len(Close),index = Close.index)
Ewma12[11] = np.mean(Close[:11])
for i in range(12, len(Close)) :Ewma12[i] = exponential * Close[i] + (1- exponential)*Ewma12[i-1]
#****************************************************
DIF = (Ewma5 - Ewma12)
# ***************** DEA *******************************
DIF = DIF.dropna()
exponential = 2 / (5 + 1)
def ewmaCal(DIF, period= 5 , exponential = 0.33333333) :Ewma = pd.Series([np.nan]*len(DIF),index=DIF.index)Ewma[period-1] = np.mean(DIF[:period])for i in range(period, len(DIF)) :Ewma[i] = exponential*DIF[i] + (1 - exponential)*Ewma[i-1]return (Ewma)
EwmaDIF = pd.Series([np.nan] * len(DIF),index = DIF.index)
EwmaDIF[4] =np.mean(DIF[:4])
for i in range(5, len(DIF)) :EwmaDIF[i] = exponential* DIF[i]+ (1- exponential)*EwmaDIF[i-1]
DEA = EwmaDIF
DEA = DEA.dropna()
# *********** MACD = DIF - DEA *********************
MACD = DIF - DEA
MACD = MACD.dropna()
#************************************************
macddata = pd.DataFrame()
macddata['DIF'] = DIF
macddata['DEA'] = DEA
macddata['MACD'] = MACD
#************************************************
macdSignal= pd.Series(0,index = MACD.index)
for i in range(1,len(MACD)):if all([DIF[i] > DEA[i] > 0.0,DIF[i-1] < DEA[i-1]]):macdSignal[i] = 1elif all([DIF[i] < DEA[i] < 0.0,DIF[i-1] > DEA[i-1]]):macdSignal[i] = -1
#************************************************
macdSignal
macdTrade = macdSignal.shift(1)
Ret = Close/Close.shift(1)-1
macdRet = (Ret*macdTrade).dropna()
macdRet[macdRet == -0] = 0
macdWinRate = len(macdRet[macdRet > 0])/len(macdRet[macdRet != 0])
print('macdWinRate : ' , round(macdWinRate*100,2), '%')
# ***************************************************
AllSignal= pd.Series(0,index = macdSignal.index)
AllSignal = SLSignal + macdSignal
for i in AllSignal.index:if AllSignal[i] >= 1 :AllSignal[i] = 1elif AllSignal[i] <= -1 :AllSignal[i] = -1else:AllSignal[i] = 0
#************************************************
AllSignal[AllSignal == 1]
AllSignal[AllSignal == -1]
AllSignal = AllSignal.dropna()
# ****************** Long Signal 2 *******************
LongSignal = pd.Series(0, index = AllSignal.index)
for i in range(1, len(AllSignal)) :if AllSignal[i] == 1 and AllSignal[i-1] != 1:LongSignal[i] = 1else :LongSignal[i] = 0
LongSignal[LongSignal == 1]
# ****************** Sell signal *************************
SellSignal = pd.Series(0, index = LongSignal.index)
for i in range(1, len(LongSignal)) :if (LongSignal[i]- LongSignal[i-1])== -1:SellSignal[i] = 1else :SellSignal[i] = LongSignal[i]
# ****************** Trade Fee *************************
Selltime = pd.Series(0, index = LongSignal.index)
for i in range(1, len(LongSignal)) :if LongSignal[i] == -1 and LongSignal[i-1] !=- 1:Selltime[i] = 1else :Selltime[i] = 0
# ****************** data process ****************
# ****************** BH ************************
WKRet = ( Close / Close.shift(1)) -1
WKWinRate = len(WKRet[WKRet > 0]) / len(WKRet[WKRet != 0])
LongSignalRet = (SellSignal * WKRet)
LongSignalRet = LongSignalRet.dropna()
LongSignalRet[LongSignalRet == -0 ] = 0
LongWinRate = len(LongSignalRet[LongSignalRet > 0]) / len(LongSignalRet[:])
TradeFee1 = Selltime*-0.0020954
TradeFee1 [TradeFee1 == -0] = 0
totalLongSignalRet = LongSignalRet + TradeFee1
LSTradeRet = (totalLongSignalRet).dropna()
LSTradeRet[LSTradeRet ==-0] = 0
LSTradeWinRate = len(LSTradeRet[LSTradeRet > 0]) / len(LSTradeRet[:])
# ************ performance ****************
cumStock = np.cumprod(1+WKRet[WKRet.index[0]:])-1
cumLSTradeRet = np.cumsum(LSTradeRet)
AnncumLSTradeRet =(( 1+cumLSTradeRet[-1:]) **(244/len(Close)))-1
# Extracting Data for plotting
Ma5 = Close.rolling(window = 5).mean()
Ma12 = Close.rolling(window = 12).mean()
WK = df[['Open', 'High', 'Low', 'Close']]
WK.reset_index(inplace=True)
WK['Date'] = WK['Date'].map(mdates.date2num)
fig = plt.figure(figsize = (24, 8))
ax = fig.add_subplot(2, 1, 1)
candlestick_ohlc(ax, WK.values, width = 0.5, colorup='g', colordown='r')
ax.xaxis_date()
ax.grid(True)
ax.set_axisbelow(True)
ax.plot(Ma5, label='5MA')
ax.plot(Ma12, label='12MA')
plt.ylabel(' PRICE ')
plt.title(StockID +' Stock K-CHART & 5-12 MA ')
plt.grid(True,axis = 'both')
plt.legend();
#*****************************************************
ax2 = fig.add_subplot(2, 1, 2)
ax2.set_xticks(range(0, len(WK.index), 22))
ax2.set_xticklabels(WK.index[::22],rotation=60)
plt.plot(cumStock,label = ' <BH>买进持有 ')
plt.plot(cumLSTradeRet,label = ' 复式均线交易策略收益率 ')
plt.ylabel(' Cumulative Return ')
plt.title(' <BH>买进持有 and 复式均线 Strategy> ')
plt.grid(True,axis = 'both')
plt.legend()
plt.show()
print('***************************************')
print('< BH >买进持有收益率 : ' , round(cumStock[-1]*100,2), '%')
print('复式均线交易策略收益率 :' , round(cumLSTradeRet[-1]*100,2), '%')
print('复式均线交易策略年化收益率 :' , round(AnncumLSTradeRet[-1]*100,2), '%')
print('***************************************')
# ********************************************** End
cumLSTradeRet = np.cumsum(LSTradeRet)
AnncumLSTradeRet =(( 1+cumLSTradeRet[-1:]) **(244/len(Close)))-1
# Extracting Data for plotting
Ma5 = Close.rolling(window = 5).mean()
Ma12 = Close.rolling(window = 12).mean()
WK = df[['Open', 'High', 'Low', 'Close']]
WK.reset_index(inplace=True)
WK['Date'] = WK['Date'].map(mdates.date2num)
fig = plt.figure(figsize = (24, 8))
ax = fig.add_subplot(2, 1, 1)
candlestick_ohlc(ax, WK.values, width = 0.5, colorup='g', colordown='r')
ax.xaxis_date()
ax.grid(True)
ax.set_axisbelow(True)
ax.plot(Ma5, label='5MA')
ax.plot(Ma12, label='12MA')
plt.ylabel(' PRICE ')
plt.title(StockID +' Stock K-CHART & 5-12 MA ')
plt.grid(True,axis = 'both')
plt.legend();
#*************************************************
ax2 = fig.add_subplot(2, 1, 2)
ax2.set_xticks(range(0, len(WK.index), 22))
ax2.set_xticklabels(WK.index[::22],rotation=60)
plt.plot(cumStock,label = ' <BH>买进持有 ')
plt.plot(cumLSTradeRet,label = ' 复式均线交易策略收益率 ')
plt.ylabel(' Cumulative Return ')
plt.title(' <BH>买进持有 and 复式均线 Strategy> ')
plt.grid(True,axis = 'both')
plt.legend()
plt.show()
print('***************************************')
print('< BH >买进持有收益率 : ' , round(cumStock[-1]*100,2), '%')
print('复式均线交易策略收益率 :' , round(cumLSTradeRet[-1]*100,2), '%')
print('复式均线交易策略年化收益率 :' , round(AnncumLSTradeRet[-1]*100,2), '%')
print('***************************************')
# ********************************************** End

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

  1. python——金融商品收益率GARCH 模型构建(GARCH 模型)

    一.GARCH简介 GARCH模型是Bollerslev在1986年提出来的,全称为广义自回归条件异方差模型,Generalized Autoregressive Conditionally Hete ...

  2. python做var模型_【Python金融量化】VaR系列(五):Copula模型估计组合VaR

    作者:量化小白H     Python爱好者社区专栏作者 个人公众号:量化小白上分记 前文传送门: 之前总结的大部分模型都是基于正态性的假设,但实际上,正态性假设并不非常符合金融时间序列的特征.如果从 ...

  3. python做var模型_【Python金融量化】VaR系列(五):Copula模型估计组合VaR-阿里云开发者社区...

    1. 资产组合VaR建模方法回顾 文章中总结了通过DCC模型估计组合向前一日VaR的方法,整体思路如下: ●  通过Garch族模型估计各资产的波动率 ●  通过DCC模型估计各资产间的相关系数,结合 ...

  4. python金融量化风险_【手把手教你】Python量化策略风险指标

    如何衡量一个量化策略的好坏?一是比较稳定的收益,二是有严谨的回测,三是有清晰的逻辑.--刘富兵 引言 尽管过去不能代表未来,通过历史回测来评估量化策略仍然是量化投资非常重要的一环.量化回测过程中常用到 ...

  5. ML之FE:金融风控—基于预处理(PSI+标签编码+文本型抽数字+缺失值RF模型拟合填充)+多种筛选指标(PCA/IV值/Gini/熵/丰富度)利用CatBoost实现贷款违约二分类预测案例之详细攻略

    ML之FE:金融风控-基于预处理(PSI+标签编码+文本型抽数字+缺失值RF模型拟合填充)+多种筛选指标(PCA/IV值/Gini/熵/丰富度)利用CatBoost实现贷款违约二分类预测案例之详细攻略 ...

  6. python金融量化分析 | 闲杂笔记

    最近事情好像有点多,处理得心不在焉.之前国庆计划把张五常老师的经济解释卷二看完,但也是只把第三章生产的成本看了一下,哈哈~ 这是一篇python金融量化分析的闲杂且入门的笔记,感觉学习价值较低,我只是 ...

  7. 消费金融五类风控指标详解

    一.序言 现在消费金融.现金贷发展的非常迅猛,几乎渗透于任何场景.最近一两年以来,国家对P2P的政策管制和对校园贷款.现金贷的政策越来越严格,笔者作为消费类金融从业者,需要学习的知识更多. 目前市面上 ...

  8. python金融工程的工具包_金融工程及其Python应用

    目 录 第1章 金融工程导论 1 1.1 金融工程的概念 2 1.2 国外现代主流金融理论发展历程 2 1.3 国内金融的发展 3 1.4 现代主流金融理论简介 4 1.4.1 投资组合理论 4 1. ...

  9. python 金融可视化_用 Python 进行金融数据可视化

    Python量化的关键是金融数据可视化,不管是传统的K线图,仍是如今的策略分析,都须要大量的可视化图表.具体到编程代码,就是使用Python绘图模块库绘图,好比传统的Python绘图模块库有Matpl ...

  10. Python金融数据分析入门到实战-视频课程

    大家好!很荣幸能够在CSDN上和各位同学分享这门课程. 本课程的核心为Python金融数据的分析,首先课程提取了数据分析工具NumPy.Pandas及可视化工具Matplotlib的关键点进行详细讲解 ...

最新文章

  1. ABAP和Go语言的初始化操作, Kubernetes的Init Container
  2. 【CodeForces - 124C】Prime Permutation(数学,思维,小结论)
  3. matlab2c使用c++实现matlab函数系列教程-hankel函数
  4. 《那些事之Log4j》什么是log4j?【专题一】
  5. python装饰器用法
  6. opencv实现图像目标对象区域挖掘
  7. AXI总线简介(二)
  8. ps4正在连接ea服务器,ps4极品飞车19连不上ea服务器 | 手游网游页游攻略大全
  9. dvi线支持多少分辨率_dvi接口有哪几种_dvi支持最大分辨率
  10. Android ItemTouchHelper实现RecyclerView交互动画
  11. 系统的入门脑机接口神经科学,一个网站就够了 - NeuroTechEDU
  12. 解决Win 7安装Power Shell报错问题
  13. 证件照制作:使用PS打印一寸照片
  14. 读书笔记:机器学习实战(2)——章3的决策树代码和个人理解与注释
  15. 糊滤镜给人物脸部磨皮教程
  16. 塔式服务器内存升级记录
  17. hackbar“学习版”
  18. MySQL如何实现双字段拼接成一个字段
  19. v-if与v-show的区别
  20. 分享一个易企CMS在线客服

热门文章

  1. swift 选取图库中的图片
  2. 暑期开箱评测Wifi Pineapple(大菠萝)
  3. 民兴商学院:适合工薪族的信用卡推荐!
  4. win10安装navisworks失败,怎么强力卸载删除注册表并重新安装
  5. hp450 g8摄像头打开后黑屏
  6. unity将指定UI图片置为灰色
  7. recover 没有捕获异常_Golang学习笔记之错误处理error、panic (抛出错误),recover(捕获错误...
  8. 关于Android图形系统的一些事实真相
  9. 中国黑客窃取《地狱之门》源代码公开叫卖
  10. 【SpringBoot实现企业微信会话内容存档】linux部署