在用python的matplotlib和numpy库绘制股票K线均线的整合效果(含从网络接口爬取数据和验证交易策略代码)一文里,我讲述了经过爬虫接口获得股票数据并绘制出K线均线图形的方式,在本文里,将在此基础上再引入成交量效果图,并结合量价理论,给出并验证一些交易策略。html
美国的股市分析家葛兰碧(Joe Granville)在他所著的《股票市场指标》一书里提出著名的“量价理论”。“量价理论”的核心思想是,任何对股价的分析,若是离开了对成交量的分析,都将是无本之木,无水之源,由于成交量的增长或萎缩都表现出必定的股价趋势。python
成交量是指时间单位内已经成交的股数或总手数。成交量能反应出股市交易中的供求关系,其中道理是比较浅显易懂的,当股票供不该求时,你们争相购买,成交量就很大了,反之当供过于求时,则说明市场交易冷淡,成交量必然萎缩。网络
广义的成交量包括成交股数(Volumn或Vol)、成交金额(AMOUNT,时间单位内已经成交的总金额数)和换手率(TUN,股票天天成交量除以股票的流通总股本所得的比率),而狭义则是指成交股数。咱们用yahoo接口获得的数据里,有表示成交股数的Volumn列,其中的单位是“手”,一手为100股,在本部分里,咱们是经过Volumn列数据绘制股票的成交量信息。less
在K线和均线整合成交量的效果图里,出于美观的考虑,咱们对整合的效果提出了以下三点要求。函数
第一,绘制上下两个子图,上图放K线和均线,下图放成交量效果。post
第二,上下两个子图共享x轴,也就是说,二者x轴的刻度标签和间隔应该是同样的。url
第三,经过柱状图来绘制成交量图,若是当天股票上涨,成交量图是红色,下跌则是绿色。 spa
在以下的drawKMAAndVol.py案例,咱们将实现增长成交量图的效果。code
1 #!/usr/bin/env python 2 #coding=utf-8 3 import pandas as pd 4 import matplotlib.pyplot as plt 5 from mpl import candlestick_ochl 6 from matplotlib import MultipleLocator 7 #根据指定代码和时间范围,获取股票数据 8 df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk') 9 #设置大小,共享x坐标轴 10 figure,(axPrice, axVol) = plt.subplots(2, sharex=True, figsize=(15,8)) 11 #调用方法,绘制K线图 12 candlestick_ochl(ax = axPrice, opens=df["Open"].values, closes=df["Close"].values, highs=df["High"].values, lows=df["Low"].values, 13 width=0.75, colorup='red', colordown='green') 14 axPrice.set_title("600895张江高科K线图和均线图")#设置子图标题 15 df['Close'].rolling(window=3).plot(ax=axPrice,color="red",label='3天均线') 16 df['Close'].rolling(window=5).plot(ax=axPrice,color="blue",label='5天均线') 17 df['Close'].rolling(window=10).plot(ax=axPrice,color="green",label='10天均线') 18 axPrice.legend(loc='best') #绘制图例 19 axPrice.set_ylabel("价格(单位:元)") 20 axPrice.grid(True) #带网格线 21 #以下绘制成交量子图 22 #直方图表示成交量,用for循环处理不一样的颜色 23 for index, row in df.iterrows(): 24 if(row['Close'] >= row['Open']): 25 axVol.bar(row['Date'],row['Volume']/1000000,width = 0.5,color='red') 26 else: 27 axVol.bar(row['Date'],row['Volume']/1000000,width = 0.5,color='green') 28 axVol.set_ylabel("成交量(单位:亿手)")#设置y轴标题 29 axVol.set_title("600895张江高科成交量")#设置子图的标题 30 axVol.set_ylim(0,df['Volume'].max()/100000000*1.2)#设置y轴范围 31 xmajorLocator = MultipleLocator(5) #将x轴主刻度设置为5的倍数 32 axVol.xaxis.set_major_locator(xmajorLocator) 33 axVol.grid(True) #带网格线 34 #旋转x轴的展现文字角度 35 for xtick in axVol.get_xticklabels(): 36 xtick.set_rotation(15) 37 plt.rcParams['font.sans-serif']=['SimHei'] 38 plt.show()
从第8行到第20行,咱们一方面是从csv文件里读取数据,另外一方面在第一个子图里绘制了K线和均线图。这部分的代码和以前很类似,不过请你们注意两个点。htm
第一,在第10行里,不只设置了绘图区域的大小,更经过sharex=True语句,设置了axPrice和axVol这两个子图共享x轴。
第二,第二,在第1四、1八、19和第20行,因为是在K线图和均线图的axPrice子图里操做,因此若干方法的调用主体是axPrice对象,而不是以前的pyplot.plt对象。
从第23行到第36行里,咱们在axVol子图里绘制了成交量图的效果。请你们注意第23行到第27行的for循环,在其中,咱们经过第24行的if语句,比较收盘价和开盘价,以判断当天股票是涨是跌,在此基础上,经过第25行或第27行的bar方法,设置当日成交量图的填充颜色。从上述代码能看出,成交量是在自于csv文件里的Volume列。
在绘制成交量图的时候有两个细节请你们注意一下。
第一,在第25行、第27行和第30行里,当咱们设置y轴的刻度值和范围时,咱们除以了一个相同的数,这是由于在第28行咱们设置y轴文字时,指定了y轴成交量的单位是“亿手“。
第二, 本次是经过第35行和第36行的for循环,设置了“x轴文字旋转”的效果,从代码里咱们能看到,本案例中的旋转角度是15度。
上述代码的运行效果以下图所示,从中你们能看两个x轴刻度一致的子图,且在成交量子图里,上涨日和下跌日的成交量填充色分别是红色和绿色。
成交量和股价间也存在着八大规律,经过下图,咱们能感觉到这些规律,其中纵坐标表示价(即股价),横坐标表示量(即成交量)。
咱们能看出量价之间的八种关系,即量增价平、量增价升、量平价升、量缩价升、量减价平、量缩价跌、量平价跌、量跌价升,随着上述周期过程,股价也完成了一个从涨到跌的完整循环,下面咱们来具体解释一下。
1.量增价平:股价通过持续下跌进入到低位状态,出现了成交量增长但股价平稳的现象,此时不一样天的成交量高度落差可能比较明显,这说明该股在底部积聚上涨动力。
2.量增价升:成交量在低价位区持续上升,同时伴随着股价上涨趋势,这说明股价上升获得了成交量的支撑,后市将继续看好,这是中短线的买入信号。
3.量平价升:在股价持续上涨的过程当中,若是多日的成交量保持等量水平,建议在这一阶段中能够适当增长仓位。
4.量缩价升:成交量开始减小,但股价依然在上升,此时应该视状况继续持股。但若是尚未买入的投资者就不宜再重仓介入,由于股价已经有了必定的涨幅,价位开始接近上限。
5.量减价平:股价经长期大幅度上涨后,成交量显著减小,股价也开始横向调整再也不上升,这是高位预警的信号。这个阶段里一旦有风吹草动,好比忽然拉出大阳线和大阴线,建议应出货离场,作到落袋为安。
6.量缩价跌:成交量在高位继续减小,股价也开始进入降低通道,这是明确的卖出信号。若是还出现缩量阴跌,这说明股价底部尚远,不会轻易止跌。
7.量平价跌:成交量中止减小,但股价却出现急速下滑现象,这说明市场并无造成一致看空的共识。股谚有“多头不死,跌势不止“的说法,出现“量平价跌”的状况,说明主力开始逐渐退出市场,这个阶段里,应继续观望或者出货,别轻易去买入以所谓的“抢反弹”。
8. 量增价跌:股价经长期大幅下跌以后,有可能出现成交量增长的状况,此时的操做原则是建议卖出,或者空仓观望。若是低价区成交量有增长,则说明有资金在此价位区间接盘,预示后期有望造成底部并出现反弹。但若是出现量增价跌,则建议应清仓出局。
在下文里,咱们将经过Python语言验证量价理论中的两个规则。
在以下的calBuyPointByVol.py案例中,咱们将验证“量增价平“的买点。在这段代码里咱们作了三件事,第一是经过yahoo接口获得了指定股票指定范围内的交易数据,第二经过pandas接口保存获得的数据,以便往后验证,第三经过遍历dataframe对象,计算量和价的关系,从而得到买点日期。
1 #!/usr/bin/env python 2 #coding=utf-8 3 import pandas_datareader 4 import pandas as pd 5 import numpy as np 6 #涨幅是否大于指定比率 7 def isMoreThanPer(lessVal,highVal,per): 8 if np.abs(highVal-lessVal)/lessVal>per/100: 9 return True 10 else: 11 return False 12 #涨幅是否小于指定比率 13 def isLessThanPer(lessVal,highVal,per): 14 if np.abs(highVal-lessVal)/lessVal<per/100: 15 return True 16 else: 17 return False 18 code='600895.ss' 19 stock = pandas_datareader.get_data_yahoo(code,'2018-09-01','2018-12-31') 20 #删除最后一行,由于get_data_yahoo会多取一天数据 21 stock.drop(stock.index[len(stock)-1],inplace=True) 22 #保存在本地 23 stock.to_csv('D:\\stockData\ch7\\60089520181231.csv') 24 #从文件里获得数据 25 df = pd.read_csv('D:/stockData/ch7/60089520181231.csv',encoding='gbk') 26 cnt=0 27 while cnt<=len(df)-1: 28 try: 29 #规则1,连续三天收盘价变更不超过3% 30 if isLessThanPer(df.iloc[cnt]['Close'],df.iloc[cnt+1]['Close'],3) and isLessThanPer(df.iloc[cnt]['close'],df.iloc[cnt+2]['Close'],3) : 31 #规则2,连续三天成交量涨幅超过75% 32 if isMoreThanPer(df.iloc[cnt]['Volume'],df.iloc[cnt+1]['volume'],75) and isMoreThanPer(df.iloc[cnt]['Volume'],df.iloc[cnt+2]['Volume'],75) : 33 print("Buy Point on:" + df.iloc[cnt]['Date']) 34 except: 35 pass 36 cnt=cnt+1
在第7行定义的isMoreThanPer方法里,咱们比较了高价和低价,以判断是否超过由参数per指定的涨幅。在第13行的isLessThanPer方法里,咱们判断了跌幅是否超过per指定的范围。因为这两个功能常常会用到,因此咱们把它们封装成函数。
从第18行到第25行,咱们完成了获取并保存数据的动做,并用df对象保存了待遍历的股票数据(即张江高科2018-09-01到2018-12-31的数据)。
在第27行到第36行按日期遍历股票数据时,咱们制定了以下规则,连续三天股票的收盘价变更范围不超过5%(即价平)且3天成交量的涨幅过75%(即量增),把知足条件的日期打印出来。运行后,咱们能看到11月2日这个买点。
在以前代码基础上改写下,把时间范围改为2018-09-01到2018-12-31,再运行下,能看到以下图所示的效果。
从中咱们能看到验证后的结果:在11月2日以后,股票的涨幅比较明显,确实是个合适的买点,从中咱们能看出 “量增价平”的指导意义。
在以下calSellPointByVol.py案例中,咱们一样是分析张江高科2018-09-01到2018-12-31的交易数据,本次咱们制定的策略是,第一,仍是连续三天股票的收盘价变更范围不超过5%(即价平),第二,较第一日相比,第二日和第三日的成交量降低幅度超过75%(即量减)。
1 #!/usr/bin/env python 2 #coding=utf-8 3 import pandas_datareader 4 import pandas as pd 5 import numpy as np 6 #涨幅是否大于指定比率 7 def isMoreThanPer(lessVal,highVal,per): 8 if np.abs(highVal-lessVal)/lessVal>per/100: 9 return True 10 else: 11 return False 12 #涨幅是否小于指定比率 13 def isLessThanPer(lessVal,highVal,per): 14 if np.abs(highVal-lessVal)/lessVal<per/100: 15 return True 16 else: 17 return False 18 #本次直接从文件里获得数据 19 df = pd.read_csv('D:/stockData/ch7/60089520181231.csv',encoding='gbk') 20 cnt=0 21 while cnt<=len(df)-1: 22 try: 23 #规则1,连续三天收盘价变更不超过3% 24 if isLessThanPer(df.iloc[cnt]['Close'],df.iloc[cnt+1]['Close'],3) and isLessThanPer(df.iloc[cnt]['Close'],df.iloc[cnt+2]['close'],3) : 25 #规则2,连续三天成交量跌幅超过75% 26 if isMoreThanPer(df.iloc[cnt+1]['Volume'],df.iloc[cnt]['Volume'],75) and isMoreThanPer(df.iloc[cnt+2]['Volume'],df.loc[cnt]['Volume'],75) : 27 print("Sell Point on:" + df.iloc[cnt]['Date']) 28 except: 29 pass 30 cnt=cnt+1
上述代码和以前calBuyPointByVol.py案例很类似,只不过咱们适当变动了第26行判断“成交量”的if条件。上述代码运行后,咱们能获得的卖点是2018-12-05,从上图里咱们能看出,在这段时间以后的若干交易日里,张江高科的股价确实有下跌现象。
在本系列的后面文章中,将陆续经过python绘制成交量、KDJ、MACD、RSI,BIAS和OBV等指标,并且还会用Python编写针对这些指标的交易策略,敬请关注。
本文用了我将近2个小时,若是你们感受好,请帮忙推荐下。
关于转载有以下的说明。
1 本文文字和代码均属原创,可转载,但谢绝用于商业用户。
2 转载时请用连接的方式,给出原文出处,同时写明原做者是hsm_computer。
3 在转载时,请原文转载 ,如要在转载修改本文,请事先告知,谢绝在转载时经过修改本文达到有利于转载者的目的。