⽤python的matplotlib和numpy库绘制股票K线均线
本⼈最近在尝试着发表“以股票案例⼊门Python编程语⾔”系列的⽂章,在这些⽂章⾥,将⽤Python⼯具绘制各种股票指标,在讲述各
股票指标的含义以及计算⽅式的同时,验证基于各种指标的交易策略,本⽂是第⼀篇,通过K线和均线案例讲述Numpy,Maplotlib等相关
库的⽤法,并且还⽤代码案例来验证买卖的交易策略。
1 K线整合均线的案例
均线也叫移动平均线(Moving Average,简称MA),是指某段时间内的平均股价(或指数)连成的曲线,通过它我们能清晰地看到股
价的历史波动,从⽽能进⼀步预测未来价格的发展趋势。
均线⼀般分短期、中期和长期这三类。
1 通常把5天和10天移动平均线称为短期均线,⼀般供短线投资者参照。
2⼀般把20天、30天和60天移动平均线作为中期均线,⼀般供中线投资者参考。
3 ⼀般120天和250天(甚⾄更长)移动平均线称为长期均线,⼀般供长线投资者参考。
不过在实践中,我们⼀般需要综合地观察短期中期和长期均线,从中能分析出市场的多空趋势。⽐如,如果某股价格的三类均线均上涨,
且短期中期长期均线是从上到下排列,则说明该股价格趋势向上;反之如果并列下跌,且长期中期短期均线从上到下排列,则说明股价趋势
向下。
讲完概念了,我们通过rolling⽅法绘制均线。
1 #!/usr/bin/env python
2 #coding=utf-8
3 import pandas as pd
4 import matplotlib.pyplot as plt
5 from mpl_finance import candlestick_ochl
6 #从⽂件⾥得到数据
7 df = pd.read_csv('D:/stockData/ch6/600895.csv',encoding='gbk')
8 #设置图的位置
9 fig = plt.figure()
10 ax = fig.subplot(111)
11 #调⽤⽅法,绘制K线图
12 candlestick_ochl(opens=df["Open"].values, closes=df["Close"].values, highs=df["High"].values, lows=df["Low"].values,width=0.75, colorup='red', colordown='gre
13 df['Close'].rolling(window=3).mean().plot(color="red",label='3天均线')
14 df['Close'].rolling(window=5).mean().plot(color="blue",label='5天均线')
15 df['Close'].rolling(window=10).mean().plot(color="green",label='10天均线')
16 plt.legend(loc='best') #绘制图例
17 #设置x轴的标签
icks(range(len(df.index.values)),df.index.values,rotation=30 )
id(True) #带⽹格线
20 plt.title("600895张江⾼科的K线图")
21 plt.show()
从第13⾏到第15⾏⾥,通过rolling⽅法,根据每天的收盘价,计算了3天、5天和10天均线,并为每种均线设置了图例,在第16⾏⾥,
通过legend⽅法设置了图例的位置。上述代码的运⾏效果如下图所⽰,从中我们不仅能看到这段时间内的K线图,还能看到3根均线。
2 K线整合均线的改进版案例
在本例中,我们将做如下两点改进,其中请⼤家着重观察操作坐标轴的ax对象。
第⼀,为了更灵活地得到股市数据,这⾥是根据开始时间和结束时间,先是调⽤get_data_yahoo接⼝,从yahoo的接⼝⾥获取股票数据,同时为了留⼀份数据,所以会把从接⼝爬取到的数据保存到本地csv⽂件,做完之后再绘制图形。
第⼆,在之前的案例中,x轴的刻度是每个交易⽇的⽇期,但如果显⽰的时间范围过长,那么时间刻度就会太密集,影响美观效果,所以这⾥将只显⽰主刻度。改进后的代码如下所⽰。
1 #!/usr/bin/env python
2 #coding=utf-8
3 import pandas_datareader
4 import pandas as pd
5 import matplotlib.pyplot as plt
6 from mpl_finance import candlestick2_ochl
7 from matplotlib.ticker import MultipleLocator
8 #根据指定代码和时间范围,获取股票数据
9 code='600895.ss'
10 stock = _data_yahoo(code,'2019-01-01','2019-03-31')
11 #删除最后⼀⾏,因为get_data_yahoo会多取⼀天数据
12 stock.drop(stock.index[len(stock)-1],inplace=True)
13 #保存在本地
_csv('D:\\stockData\ch7\\600895.csv')
15 df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk',index_col=0)
16 #设置窗⼝⼤⼩
17 fig, ax = plt.subplots(figsize=(10, 8))
18 xmajorLocator  = MultipleLocator(5) #将x轴主刻度设置为5的倍数
19 ax.xaxis.set_major_locator(xmajorLocator)
20 #调⽤⽅法,绘制K线图
21 candlestick2_ochl(ax = ax,
22 opens=df["Open"].values,closes=df["Close"].values, highs=df["High"].values, lows=df["Low"].values,width=0.75, colorup='red', colordown='green')
23 #如下是绘制3种均线
24 df['Close'].rolling(window=3).mean().plot(color="red",label='3天均线')
25 df['Close'].rolling(window=5).mean().plot(color="blue",label='5天均线')
26 df['Close'].rolling(window=10).mean().plot(color="green",label='10天均线')
27 plt.legend(loc='best') #绘制图例
id(True) #带⽹格线
29 plt.title("600895张江⾼科的K线图")
Params['font.sans-serif']=['SimHei']
31 plt.a().get_xticklabels(), rotation=30)
32 plt.show()
相⽐之前代码,这段代码有四个改进点。
第⼀,从第9⾏到第14⾏⾥,我们通过第五章分析过的get_data_yahoo⽅法,传⼊股票代码、开始和结束时间这三个参数,从yahoo接⼝⾥获得股票交易的数据。
请注意该⽅法返回的数据会⽐传⼊的结束时间多⼀天,⽐如我们传⼊的结束时间是2019-03-31,但它会返回后⼀天(即2019-04-01)的数据,所以得通过第12⾏的drop⽅法,删除stock对象(该对象类型是dataframe)最后⼀⾏的数据。删除的时候是通过
stock.index[len(stock)-1]指定删除长度减1的索引值,因为索引值是从0开始,⽽且需要指定inplace=True,否则的话,删除的结果⽆法更新到stock这个dataframe⾥。
第⼆,在第17⾏⾥,通过figsize⽅法设置了窗⼝的⼤⼩尺⼨。
第三,通过第18⾏和第19⾏的代码,设置了主刻度是5的倍数。之所以设置成5的倍数,是因为⼀般⼀周的交易⽇是5天。但这⾥不能简单地把主刻度设置成每周⼀,因为某些周⼀有可能是股市休市的法定假⽇。
第四,由于⽆需在x轴上设置每天的⽇期,所以这⾥⽆需再调⽤icks⽅法,但是得调⽤如第31⾏所⽰的代码,设置x轴刻度的旋转⾓度,否则x轴展⽰的时间依然有可能会重叠。
这段代码的运⾏效果如下图所⽰,从中⼤家能看到改进后的效果,⽽且,由于本次展⽰的股票时间段变长了(是3个⽉),所以相⽐drawKAndMA.py案例,均线的效果更为明显,尤其是三⽇均线,更是⼏乎贯穿于整个交易⽇范围。
3 葛兰碧均线⼋⼤买卖法则
在均线实践理论中,投资专家葛兰碧创造的⼋项买卖法则可谓经典,具体的细节如下图所⽰。
1 移动平均线从下降逐渐转为平⽔平,且有超上⽅抬头迹象,⽽股价从均线下⽅突破时,为买进信号,如上图中的A点。
2 股价于移动平均线之上运⾏时下跌,但未跌破均线,此时股价再次上扬,此时为买⼊信号,如图中
的C点。
3 股价位于均线上运⾏,下跌时破均线,但均线呈上升趋势,不久股价回到均线之上时,为买进信号,如图中的B点。
4 股价在均线下⽅运⾏时⼤跌,远离均线时向均线靠近,此时为买进时机,如图中的D点。
5 均线的上升趋势逐渐变平,且有向下迹象,⽽股价从均线上⽅向下穿均线,为卖出信号,如图中的E点。
6 股价向上穿过均线,不过均线依然保持下跌趋势,此后股价⼜下跌回均线下⽅,为卖出信号,如图中的F点。
7 股价运⾏在均线下⽅,出现上涨,但未过均线就再次下跌,此为卖出点,如图中的G点。
8 股价在均线的上⽅运⾏,连续上涨且继续远离均线,这种趋势说明随时会出现获利回吐的卖盘打压,此时是卖出的时机,如前图中的H 点。
4 通过DataFrame对象验证均线的买点策略
根据上述⼋⼤买卖原则,我们在张江⾼科2019年1⽉到3⽉的交易数据内,⽤pandas库⾥的dataframe等对象,根据5⽇均线计算参考买点,代码如下所⽰。
1 #!/usr/bin/env python
2 #coding=utf-8
3 import pandas as pd
4 #从⽂件⾥得到数据
5 df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk')
6 maIntervalList = [3,5,10]
7 #虽然在后⽂⾥只⽤到了5⽇均线,但这⾥演⽰设置3种均线
8 for maInterval in maIntervalList:
9    df['MA_' + str(maInterval)] = df['Close'].rolling(window=maInterval).mean()
10 cnt=0
11 while cnt<=len(df)-1:
12    try:
13        #规则1,收盘价连续三天上扬
14        if df.iloc[cnt]['Close']<df.iloc[cnt+1]['Close'] and df.iloc[cnt+1]['Close']<df.iloc[cnt+2]['Close']:
15            #规则2,5⽇均线连续三天上扬
16            if df.iloc[cnt]['MA_5']<df.iloc[cnt+1]['MA_5'] and df.iloc[cnt+1]['MA_5']<df.iloc[cnt+2]['MA_5']:
17                #规则3,第3天,收盘价上穿5⽇均线
18                if df.iloc[cnt+1]['MA_5']>df.iloc[cnt]['Close'] and df.iloc[cnt+2]['MA_5']<df.iloc[cnt+1]['Close']:
19                    print("Buy Point on:" + df.iloc[cnt]['Date'])
20    except: #有⼏天是没5⽇均线的,所以⽤except处理异常
21        pass:
22    cnt=cnt+1
虽然在计算参考买点时,只⽤到了5⽇均价,但在第8⾏和第9⾏的for循环⾥,我们通过rolling⽅法,还是计算了3⽇、5⽇和10⽇的均价,并把计算后的结果记录到当前⾏的MA_3、MA_5和MA_10这三列中,这样做的⽬的是为了演⽰动态创建列的做法。
在第11⾏到第22⾏的while循环⾥,我们依次遍历了每天的交易数据,并在第14⾏,第16⾏和第18⾏⾥,通过三个if语句,设置了3个规则。由于在前⼏天是没有5⽇均价了,且在遍历最后2天交易数据时,在执⾏诸如df.iloc[cnt+2]['Close']的语句中会出现索引越界,所以在while循环⾥我们⽤到了try…except异常处理语句。
运⾏上述代码,我们能看到的结果是:Buy Point on:2019-03-08,结合上图,我们能看到3⽉8⽇之后的交易⽇⾥,股价有⼀定程度的上涨,所以能证实基于均线的“买”原则,但影响股价的因素太多,⼤家应全⾯分析,切勿在实战中只⽤这原则来买卖股票。matplotlib中subplot
5 通过DataFrame验证均线的卖点策略
同样地,根据5⽇均线计算参考买点,在如下案例中,我们计算了张江⾼科2019年1⽉到3⽉内的卖点。
1 #!/usr/bin/env python
2 #coding=utf-8
3 import pandas as pd
4 #从⽂件⾥得到数据
5 df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk')
6 maIntervalList = [3,5,10]
7 #虽然在后⽂⾥只⽤到了5⽇均线,但这⾥演⽰设置3种均线
8 for maInterval in maIntervalList:
9    df['MA_' + str(maInterval)] = df['Close'].rolling(window=maInterval).mean()
10 cnt=0
11 while cnt<=len(df)-1:
12    try:
13        #规则1,收盘价连续三天下跌
14        if df.iloc[cnt]['Close']>df.iloc[cnt+1]['Close'] and df.iloc[cnt+1]['Close']>df.iloc[cnt+2]['Close']:
15            #规则2,5⽇均线连续三天下跌
16            if df.iloc[cnt]['MA_5']>df.iloc[cnt+1]['MA_5'] and df.iloc[cnt+1]['MA_5']>df.iloc[cnt+2]['MA_5']:
17                #规则3,第3天,收盘价下穿5⽇均线
18                if df.iloc[cnt+1]['MA_5']<df.iloc[cnt]['Close'] and df.iloc[cnt+2]['MA_5']>df.iloc[cnt+1]['Close']:
19                    print("Sell Point on:" + df.iloc[cnt]['Date'])
20    except: #有⼏天是没5⽇均线的,所以⽤except处理异常
21        pass
22    cnt=cnt+1
运⾏后,我们能得到两个卖点:2019-01-23和2019-01-23,这同样能在上图描述的K线图⾥得到验证。
6 后⽂预告与版权说明
在本系列的后⾯⽂章中,将陆续通过python绘制成交量、KDJ、MACD、RSI和OBV等指标,⽽且还会⽤Python编写针对这些指标的交易策略,敬请关注。
关于转载有如下的说明。
1 本⽂⽂字和代码均属原创,可转载,但谢绝⽤于商业⽤户。
2 转载时请⽤链接的⽅式,给出原⽂出处,同时写明原作者是hsm_computer。
3 在转载时,请原⽂转载 ,如要在转载修改本⽂,请事先告知,谢绝在转载时通过修改本⽂达到有利于转载者的⽬的。