在我刚开始学习股票的时候,是跟着b站上的视频学习的,当讲到macd的时候,up主反复强调macd是指标之王,股票里面有那么多的指标,但是却只有macd被称为指标之王,当macd出现金叉的时候,预示着股价即将上涨,是一个很好的买入信号,当macd出现死叉时,预示着股价即将下跌,是一个卖出信号。在看其他的书籍资料的时候,也都着重的介绍了macd,那么macd是什么,它是如何计算出来的,用它来作为交易的买卖信号到底靠不靠谱呢。下面先看一下macd是怎么计算的,然后再用python来验证用它来作为交易的买卖信号到底靠不靠谱。

MACD被称为异同移动平均线,在交易软件里面,我们可以看到,macd指标图如下图所示:

从图中可以看出,它是由两条曲线和一些红色绿色的柱子组成的,白色的曲线是dif线,黄色的曲线是dea线(不同的交易软件曲线颜色可能不一样),而红色绿色的柱子就是macd指标,柱子的高度就是macd的绝对值的大小,红色代表macd为正,绿色代表macd为负。dif是由快的指数移动平均线(EMA12)减去慢的指数移动平均线(EMA26)得到的,而dea则是dif的9日加权移动平均线,像这么说确实是很难看懂,还是看一下具体的是怎么计算的吧,首先看一下指数移动平均线的计算公式:

Y[t]=(1-alpha)*Y[t-1]+alpha*X[t],而alpha=2/(span+1),

其中Y[t]为t时刻的指数加权平均数,Y[t-1]为t-1时刻的指数加权平均数,X[t]为t时刻的数据的值,span为范围周期(即当计算EMA12时,span=12,计算EMA26时,span=26),知道了指数加权平均数的计算公式之后,就可以计算macd了,计算过程如下:

  1. 计算EMA12: EMA12=前一日的(EMA12)*11/13+2/13*当日收盘价
  2. 计算EMA26: EMA26=前一日的(EMA26)*25/27+2/27*当日收盘价
  3. 计算dif的值: dif=EMA12-EMA26
  4. 计算dea的值(即dif的EMA9): dea=前一日dea*8/10+2/10*当日dif
  5. 计算出红色绿色柱子的值: 2*(dif-dea)

知道了macd是怎么计算出来的之后,再来用python来验证一下用它来作为交易时候的买卖信号到底靠不靠谱,先来看一下000001(平安银行)这只股票在2010年1月1日到2020年12月31日这11年之间的表现,代码如下:

import configparser
import pymysql
import pandas as pd
from matplotlib import pyplot as plt # 设置字体,解决matplotlib中文乱码问题
plt.rcParams['font.sans-serif'] = ['SimHei'] # 配置文件路径
conf = 'configuration/config.ini' # 读取配置文件
cf = configparser.ConfigParser()
cf.read(conf)
# 获取mysql连接信息
user = cf.get('mysql', 'user')
password = cf.get('mysql', 'password')
host = cf.get('mysql', 'host')
port = cf.get('mysql', 'port')
port = int(port)
# print('user=%s, password=%s, host=%s, port=%s' % (user, password, host, port)) # 连接mysql数据库
try:
conn = pymysql.connect(
user=user,
password=password,
host=host,
port=port
)
cur = conn.cursor()
# 查出指定股票在2010年至2020年之间的交易信息
ssql = "select dt, close from stocks.stock_price" \
" where stock_code = '000001'" \
" and dt >= '2010-01-01'" \
" and dt <= '2020-12-31'"
cur.execute(ssql)
df = cur.fetchall()
finally:
cur.close()
conn.close() df = pd.DataFrame(df, columns=['dt', 'close'])
# 计算EMA12
df['EMA12'] = df['close'].ewm(span=12, adjust=False).mean()
# 计算EMA26
df['EMA26'] = df['close'].ewm(span=26, adjust=False).mean()
# 计算dif线
df['dif'] = df['EMA12'] - df['EMA26']
# 计算dea线
df['dea'] = df['dif'].ewm(span=9, adjust=False).mean()
# 计算macd的值
df['macd'] = 2 * (df['dif'] - df['dea'])
# print(df.head(10)) # macd图出现金叉时,其实就是当天的macd大于等于0,并且前一天的macd小于0
handle1 = df['macd'] > 0
handle2 = df['macd'].shift(1) <= 0
# 当出现金叉时,信号设置为1
df.loc[handle1 & handle2, 'signal'] = 1
# macd图出现死叉时,判断方法与出现金叉时相反
handle1 = df['macd'] < 0
handle2 = df['macd'].shift(1) >= 0
# 当出现死叉时,信号设置为0
df.loc[handle1 & handle2, 'signal'] = 0
# 计算这只股票1日,5日,10日,20日之后的涨跌幅
day_list = [1, 5, 10, 20]
for i in day_list:
df['{}日后的涨跌幅'.format(i)] = (df['close'].shift(-i)-df['close']) / df['close']
# 将涨跌幅数据类型设置为float并保留两位小数
df['{}日后的涨跌幅'.format(i)] = df['{}日后的涨跌幅'.format(i)].astype(float)
df['{}日后的涨跌幅'.format(i)] = df['{}日后的涨跌幅'.format(i)].round(4)
# 判断股票在n日之后是否上涨
df['{}日之后是否上涨'.format(i)] = df['{}日后的涨跌幅'.format(i)] > 0
df['{}日之后是否上涨'.format(i)].fillna(value=False, inplace=True)
# df.to_csv('data/macd.csv')
# 创建两个空列,分别存放macd出现金叉后的1天,5天,10天,20天的上涨和下跌的情况
up_list = []
down_list = []
# 按macd信号分组
for signal, group in df.groupby('signal'):
if signal == 1:
# 计算macd出现金叉的次数
cnt = group.shape[0]
print('期间macd一共出现过{}次金叉'.format(cnt))
for i in day_list:
# macd出现金叉时执行
if signal == 1:
# 计算期间macd出现金叉后上涨的次数
up_cnt = group[group['{}日后的涨跌幅'.format(i)] > 0].shape[0]
# 分别计算出macd出现金叉后1天,5天,10天,20天的上涨的概率并保留4位小数
up_rate = up_cnt/cnt
up_rate = round(up_rate, 4)
# print('{}日后上涨的概率'.format(i), up_rate)
# print(up_rate)
up_list.append(up_rate) # 计算期间macd出现金叉之后下跌的次数
down_cnt = group[group['{}日后的涨跌幅'.format(i)] < 0].shape[0]
# 分别计算出macd出现金叉后1天,5天,10天,20天的下跌的概率并保留4位小数
down_rate = down_cnt/cnt
down_rate = round(down_rate, 4)
print('macd出现金叉%2d日后,上涨了%2d次,上涨的概率:' % (i, up_cnt), up_rate, ' 下跌了%2d次,下跌的概率:' % (down_cnt), down_rate)
# print(down_rate)
down_list.append(down_rate) # 画出涨跌图像
# 设置x轴和y轴范围
plt.xlim(0, 5)
plt.ylim(0, 0.7)
# 画出涨跌图
plt.bar([0.9, 1.9, 2.9, 3.9], up_list, width=0.2, color='red', alpha=0.7)
plt.bar([1.1, 2.1, 3.1, 4.1], down_list, width=0.2, color='green', alpha=0.7)
# 设置图例
plt.legend(['macd出现金叉后上涨的概率', 'macd出现金叉后下跌的概率'], loc='best')
# 显实涨跌数据
for x, y in enumerate(up_list):
plt.text(x+0.55, y+0.01, y)
for x, y in enumerate(down_list):
plt.text(x+1, y+0.01, y)
plt.plot([0, 5], [0.5, 0.5], '--', color='blue', alpha=0.3)
# 设置主图名称
plt.title('MACD出现金叉后涨跌概率图', fontsize=14)
# 设置x轴和y轴名称
plt.xlabel('macd出现金叉', fontsize=14)
plt.ylabel('上涨/下跌的概率', fontsize=14)
# 设置x轴坐标显实格式
plt.xticks([1, 2, 3, 4], ['一天后', '五天后', '十天后', '二十天后'])
plt.yticks([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7],
[0, '10%', '20%', '30%', '40%', '50%', '60%', '70%'])
plt.show()

得到的结果如下图:

根据数据显实,从2010年1月1日到2020年12月31日11年间,平安银行一共出现过97次金叉,从上图中可以看到,在macd出现金叉一天之后和五天之后,下跌的概率比上涨的概率高一些,而十天之后和二十天之后,上涨和下跌的概率都在50%左右。

再来看一下出现死叉之后的表现,直接看图如下:

从图中可以看出,macd出现死叉一天后,五天后,十天后和二十天之后的上涨和下跌的概率都差不多,都集中的50%左右。

之后我又测试了一些其它的股票,感觉当macd出现金叉和死叉,在之后的一天,五天,十天,二十天的涨跌幅都是比较接近的,而且都是趋于50%左右,后面有时间可以把这个程序改一下,来验证一下目前A股4000多只股票的综合情况。

根据得出的数据,我觉得在交易过程中,可以把macd看成一个参考指标,但是不能作为买卖时候的交易信号,因为这个涨跌概率其实就是和抛硬币差不多,还不如抛硬币来的直接。在交易的时候,不管是用什么指标,都应该结合其它指标来看,而不是只看单一的指标。

量化交易——MACD是什么,用python来验证交易时把它作为买卖信号到底靠不靠谱的更多相关文章

  1. 用python的matplotlib和numpy库绘制股票K线均线和成交量的整合效果(含量化验证交易策略代码)

    在用python的matplotlib和numpy库绘制股票K线均线的整合效果(含从网络接口爬取数据和验证交易策略代码)一文里,我讲述了通过爬虫接口得到股票数据并绘制出K线均线图形的方式,在本文里,将 ...

  2. python在读取文件时出现 'gbk' codec can't decode byte 0x89 in position 68: illegal multibyte sequence

    python在读取文件时出现“UnicodeDecodeError:'gbk' codec can't decode byte 0x89 in position 68: illegal multiby ...

  3. 第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解

    第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解 信号一般使用信号分发器dispatcher.connect(),来设置信号,和信号触发函数,当捕获到信号时执行 ...

  4. Python决定一个变量时局部的,还是全局的,是在编译期

    Python中的变量名是在编译时就解析好的,换句话说,在编译时(也就是在交互控制台输入代码是或者import文件时),Python就已经决定一个变量应该是局部变量,还是全局变量.来看下面的例子: &g ...

  5. python登录验证程序

    自己写的一个python登录验证程序: 基础需求: 让用户输入用户名密码 认证成功后显示欢迎信息 输错三次后退出程序 升级需求: 可以支持多个用户登录 (提示,通过列表存多个账户信息) 用户3次认证失 ...

  6. python读取ini文件时,特殊字符的读取

    前言: 使用python在读取配置文件时,由于配置文件中存在特殊字符,读取时出现了以下错误: configparser.InterpolationSyntaxError: '%' must be fo ...

  7. Python文本文件读写操作时的字符编码问题

    说明:文本文件的字符编码问题只存在t模式中,如:open('a.txt', mode='rt') 编码(encode): 我们输入的任何字符想要以文件(如.txt)的形式保存在计算机的硬盘上, 必须先 ...

  8. PyQt(Python+Qt)学习随笔:使用pyqtConfigure建立信号和槽的连接

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在PyQt中,一般信号和槽的连接是通过connect方法建立的,语法如下: connect(slot ...

  9. python安装whl包时出现的问题解决:is not a supported wheel on this platform

    @ 目录 一.问题 二.查找问题 三.问题解决 一.问题 1.下载一个twisted包 安装Twisted,进入https://www.lfd.uci.edu/~gohlke/pythonlibs 下 ...

  10. 用python解决打标签时将xml文件的标签名打错

    用python解决打标签时将xml文件的标签名打错 问题描述:再进行达标签时将magnetic_tile的标签名错误的打成了magnetic_title,又不想一张一张的修改 出现问题的xml文件 & ...

随机推荐

  1. maven jar包新版本检测工具推荐

    为什么需要 经常使用maven来构建项目的朋友,应该遇到过类似这样的情况:项目通过maven引入了很多jar包,随着时间推移,这些jar包都有了更优的新版本出来,想升级,但又觉得很繁琐.主要是因为两方 ...

  2. 其他计算机&网络&行业知识

    互联网数据中心(IDC)   VIDC(端口映射) CVM云服务器(Cloud Virtual Machine)  IDE 集成开发环境: 开发工具 QA:Quality Assurance,直译为质 ...

  3. BIP查询框添加查询条件

    // 搜索框添加查询条件 viewModel.on("afterMount", function (data) { let agentId = viewModel.getParam ...

  4. Excel error - the macros in this project are disabled, please refer to the online help or documentation of the host application to determine how to enable macros.

    alt+F11 进入vba界面,F5运行macro后报错. Sub 合并当前工作簿下的所有工作表() Application.ScreenUpdating = False For j = 1 To S ...

  5. nginx转发端口路由器再转发

    场景 nginx 转发端口 路由器二次转发了,端口不一样 (shiro 或者其他一些权限控制架构会自动跳转,导致的端口不对.) proxy_set_header Host $host:$proxy_p ...

  6. linux 网络操作 route iptables ufw

    linux 网络操作 route iptables ufw sudo ufw status sudo ufw allow ssh sudo ufw allow http sudo ufw deny h ...

  7. exe可执行文件反编译成py文件

    记录一下exe文件反编译的问题 准备工作 1. 安装第三方包 uncompyle6 (pip install uncompyle6==3.7.4) 2. 下载pyinstxtractor.py文件 3 ...

  8. 原生js实现折线图

    不借助Echarts等图形框架原生JS快速实现折线图效果 1. 折线图效果预览 例如下图所示的折线图效果实现就很简单: 调用下面这段JS代码中的方法就好了: 假设页面上需要连接的所有点元素集合是ele ...

  9. python学习之路---基础概念扩展:变量,表达式,算法,语句,函数,模块,字符串

    对于学过一点编程语言的人,学习python基础知识不难,基本大同小异 本章是根据一本书来学习python的编程(强烈推荐)来记录学习python中的有意思的总结 Python 基础教程(第三版)    ...

  10. 手把手教你用Typora自动上传到picgo图床【教程与排坑】

    手把手教你用Typora自动上传到picgo图床[教程与排坑] 参考链接: 1. https://blog.csdn.net/disILLL/article/details/104944710?utm ...