本人最近在尝试着发表 "以股票案例入门 Python 编程语言" 系列的文章, 在这些文章里, 将用 Python 工具绘制各种股票指标, 在讲述各股票指标的含义以及计算方式的同时, 验证基于各种指标的交易策略, 本文是第一篇, 通过 K 线和均线案例讲述 Numpy,Maplotlib 等相关库的用法, 并且还用代码案例来验证买卖的交易策略.
1 K 线整合均线的案例
均线也叫移动平均线 (Moving Average, 简称 MA), 是指某段时间内的平均股价(或指数) 连成的曲线, 通过它我们能清晰地看到股价的历史波动, 从而能进一步预测未来价格的发展趋势.
均线一般分短期, 中期和长期这三类.
1 通常把 5 天和 10 天移动平均线称为短期均线, 一般供短线投资者参照.
2 一般把 20 天, 30 天和 60 天移动平均线作为中期均线, 一般供中线投资者参考.
3 一般 120 天和 250 天 (甚至更长) 移动平均线称为长期均线, 一般供长线投资者参考.
不过在实践中, 我们一般需要综合地观察短期中期和长期均线, 从中能分析出市场的多空趋势. 比如, 如果某股价格的三类均线均上涨, 且短期中期长期均线是从上到下排列, 则说明该股价格趋势向上; 反之如果并列下跌, 且长期中期短期均线从上到下排列, 则说明股价趋势向下.
讲完概念了, 我们通过 rolling 方法绘制均线.
- #!/usr/bin/env python
- #coding=utf-8
- import pandas as pd
- import matplotlib.pyplot as plt
- from mpl_finance import candlestick_ochl
- # 从文件里得到数据
- df = pd.read_csv('D:/stockData/ch6/600895.csv',encoding='gbk')
- # 设置图的位置
- fig = plt.figure()
- ax = fig.subplot(111)
- # 调用方法, 绘制 K 线图
- candlestick_ochl(opens=df["Open"].values, closes=df["Close"].values, highs=df["High"].values, lows=df["Low"].values,width=0.75, colorup='red', colordown='green')
- df['Close'].rolling(Windows=3).mean().plot(color="red",label='3 天均线')
- df['Close'].rolling(Windows=5).mean().plot(color="blue",label='5 天均线')
- df['Close'].rolling(Windows=10).mean().plot(color="green",label='10 天均线')
- plt.legend(loc='best') #绘制图例
- # 设置 x 轴的标签
- plt.xticks(range(len(df.index.values)),df.index.values,rotation=30 )
- ax.grid(True) #带网格线
- plt.title("600895 张江高科的 K 线图")
- plt.show()
从第 13 行到第 15 行里, 通过 rolling 方法, 根据每天的收盘价, 计算了 3 天, 5 天和 10 天均线, 并为每种均线设置了图例, 在第 16 行里, 通过 legend 方法设置了图例的位置. 上述代码的运行效果如下图所示, 从中我们不仅能看到这段时间内的 K 线图, 还能看到 3 根均线.
2 K 线整合均线的改进版案例
在本例中, 我们将做如下两点改进, 其中请大家着重观察操作坐标轴的 ax 对象.
第一, 为了更灵活地得到股市数据, 这里是根据开始时间和结束时间, 先是调用 get_data_yahoo 接口, 从 yahoo 的接口里获取股票数据, 同时为了留一份数据, 所以会把从接口爬取到的数据保存到本地 CSV 文件, 做完之后再绘制图形.
第二, 在之前的案例中, x 轴的刻度是每个交易日的日期, 但如果显示的时间范围过长, 那么时间刻度就会太密集, 影响美观效果, 所以这里将只显示主刻度. 改进后的代码如下所示.
- #!/usr/bin/env python
- #coding=utf-8
- import pandas_datareader
- import pandas as pd
- import matplotlib.pyplot as plt
- from mpl_finance import candlestick2_ochl
- from matplotlib.ticker import MultipleLocator
- # 根据指定代码和时间范围, 获取股票数据
- code='600895.ss'
- stock = pandas_datareader.get_data_yahoo(code,'2019-01-01','2019-03-31')
- # 删除最后一行, 因为 get_data_yahoo 会多取一天数据
- stock.drop(stock.index[len(stock)-1],inplace=True)
- # 保存在本地
- stock.to_csv('D:\\stockData\ch7\\600895.csv')
- df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk',index_col=0)
- # 设置窗口大小
- fig, ax = plt.subplots(figsize=(10, 8))
- xmajorLocator = MultipleLocator(5) #将 x 轴主刻度设置为 5 的倍数
- ax.xaxis.set_major_locator(xmajorLocator)
- # 调用方法, 绘制 K 线图
- candlestick2_ochl(ax = ax,
- opens=df["Open"].values,closes=df["Close"].values, highs=df["High"].values, lows=df["Low"].values,width=0.75, colorup='red', colordown='green')
- # 如下是绘制 3 种均线
- df['Close'].rolling(Windows=3).mean().plot(color="red",label='3 天均线')
- df['Close'].rolling(Windows=5).mean().plot(color="blue",label='5 天均线')
- df['Close'].rolling(Windows=10).mean().plot(color="green",label='10 天均线')
- plt.legend(loc='best') #绘制图例
- ax.grid(True) #带网格线
- plt.title("600895 张江高科的 K 线图")
- plt.rcParams['font.sans-serif']=['SimHei']
- plt.setp(plt.gca().get_xticklabels(), rotation=30)
- 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 轴上设置每天的日期, 所以这里无需再调用 plt.xticks 方法, 但是得调用如第 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 日均线计算参考买点, 代码如下所示.
- #!/usr/bin/env python
- #coding=utf-8
- import pandas as pd
- # 从文件里得到数据
- df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk')
- maIntervalList = [3,5,10]
- # 虽然在后文里只用到了 5 日均线, 但这里演示设置 3 种均线
- for maInterval in maIntervalList:
- df['MA_' + str(maInterval)] = df['Close'].rolling(Windows=maInterval).mean()
- cnt=0
- while cnt<=len(df)-1:
- try:
- #规则 1, 收盘价连续三天上扬
- if df.iloc[cnt]['Close']<df.iloc[cnt+1]['Close'] and df.iloc[cnt+1]['Close']<df.iloc[cnt+2]['Close']:
- #规则 2,5 日均线连续三天上扬
- 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']:
- #规则 3, 第 3 天, 收盘价上穿 5 日均线
- if df.iloc[cnt+1]['MA_5']>df.iloc[cnt]['Close'] and df.iloc[cnt+2]['MA_5']<df.iloc[cnt+1]['Close']:
- print("Buy Point on:" + df.iloc[cnt]['Date'])
- except: #有几天是没 5 日均线的, 所以用 except 处理异常
- pass:
- 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 日之后的交易日里, 股价有一定程度的上涨, 所以能证实基于均线的 "买" 原则, 但影响股价的因素太多, 大家应全面分析, 切勿在实战中只用这原则来买卖股票.
5 通过 DataFrame 验证均线的卖点策略
同样地, 根据 5 日均线计算参考买点, 在如下案例中, 我们计算了张江高科 2019 年 1 月到 3 月内的卖点.
- #!/usr/bin/env python
- #coding=utf-8
- import pandas as pd
- # 从文件里得到数据
- df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk')
- maIntervalList = [3,5,10]
- # 虽然在后文里只用到了 5 日均线, 但这里演示设置 3 种均线
- for maInterval in maIntervalList:
- df['MA_' + str(maInterval)] = df['Close'].rolling(Windows=maInterval).mean()
- cnt=0
- while cnt<=len(df)-1:
- try:
- #规则 1, 收盘价连续三天下跌
- if df.iloc[cnt]['Close']>df.iloc[cnt+1]['Close'] and df.iloc[cnt+1]['Close']>df.iloc[cnt+2]['Close']:
- #规则 2,5 日均线连续三天下跌
- 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']:
- #规则 3, 第 3 天, 收盘价下穿 5 日均线
- if df.iloc[cnt+1]['MA_5']<df.iloc[cnt]['Close'] and df.iloc[cnt+2]['MA_5']>df.iloc[cnt+1]['Close']:
- print("Sell Point on:" + df.iloc[cnt]['Date'])
- except: #有几天是没 5 日均线的, 所以用 except 处理异常
- pass
- cnt=cnt+1
运行后, 我们能得到两个卖点: 2019-01-23 和 2019-01-23, 这同样能在上图描述的 K 线图里得到验证.
6 求推荐, 后文预告与版权说明
在本系列的后面文章中, 将陆续通过 python 绘制成交量, KDJ,MACD,RSI 和 OBV 等指标, 而且还会用 Python 编写针对这些指标的交易策略, 敬请关注.
本文用了我将近 3 个小时, 如果大家感觉好, 请帮忙推荐下.
关于转载有如下的说明.
1 本文文字和代码均属原创, 可转载, 但谢绝用于商业用户.
来源: https://www.cnblogs.com/JavaArchitect/p/11014215.html