python股票分析挖掘预测技术指标知识大全之MACD详解
本人股市多年的老韭菜,各种股票分析书籍,技术指标书籍阅历无数,萌发想法,何不自己开发个股票预测分析软件,选择python因为够强大,它提供了很多高效便捷的数据分析工具包,
这一章重点讲一下使用指标之王MACD分析股票的买卖点:
在此之前我们先安装和了解一下ta-lib库
(1)TA-Lib库
我们进行技术分析计算的时候很多情况引入第三方Python包,ta-lib就是其中之一。ta-lib全称是Technical Analysis Library,翻译为中文就是技术分析库,它是Python金融量化领域的一个高级库,被广泛应用在金融市场数据进行技术分析,其内部实现了150多种股票、期货交易中常用的技术分析指标,如SMA、MACD、RSI、KDJ、动量指标、布林带等。
(1)Ta_Lib安装
pip install Ta-Lib
(2) ta_lib函数
根据技术指标的不同特征,talib库一共有10个指标函数组,各个指标函数组中包含了诸多的指标函数。下表是talib库包含的10个指标函数组及每个指标组中包含的指标函数。
| 指标函数组名称 | 指标函数组中包含的指标函数 |
|---|---|
| Cycle Indicators(循环指标函数组) | HT_DCPERIOD, HT_DCPHASE, HT_PHASOR, HT_SINE, HT_TRENDMODE |
| Math Operators(数学运算函数组) | ADD, DIV, MAX, MAXINDEX, MIN, MININDEX, MINMAX, MINMAXINDEX, MULT, SUB, SUM |
| Math Transform(数学变换函数组) | ACOS, ASIN, ATAN, CEIL, COS, COSH, EXP, FLOOR, LN, LOG10, SIN, SINH, SQRT, TAN, TANH |
| Momentum Indicators(动量指标函数组) | ADX, ADXR, APO, AROON, AROONOSC, BOP, CCI, CMO, DX, MACD, MACDEXT, MACDFIX, MFI, MINUS_DI, MINUS_DM, MOM, PLUS_DI, PLUS_DM, PPO, ROC, ROCP, ROCR, ROCR100, RSI, STOCH, STOCHF, STOCHRSI, TRIX, ULTOSC, WILLR |
| Overlap Studies(重叠研究函数组) | BBANDS, DEMA, EMA, HT_TRENDLINE, KAMA, MA, MAMA, MAVP, MIDPOINT, MIDPRICE, SAR, SAREXT, SMA, T3, TEMA, TRIMA, WMA |
| Pattern Recognition(模式识别函数组) | CDL2CROWS, CDL3BLACKCROWS, CDL3INSIDE, CDL3LINESTRIKE, CDL3OUTSIDE, CDL3STARSINSOUTH, CDL3WHITESOLDIERS, CDLABANDONEDBABY, CDLADVANCEBLOCK, CDLBELTHOLD, CDLBREAKAWAY, CDLCLOSINGMARUBOZU, CDLCONCEALBABYSWALL, CDLCOUNTERATTACK, CDLDARKCLOUDCOVER, CDLDOJI, CDLDOJISTAR, CDLDRAGONFLYDOJI, CDLENGULFING, CDLEVENINGDOJISTAR, CDLEVENINGSTAR, CDLGAPSIDESIDEWHITE, CDLGRAVESTONEDOJI, CDLHAMMER, CDLHANGINGMAN, CDLHARAMI, CDLHARAMICROSS, CDLHIGHWAVE, CDLHIKKAKE, CDLHIKKAKEMOD, CDLHOMINGPIGEON, CDLIDENTICAL3CROWS, CDLINNECK, CDLINVERTEDHAMMER, CDLKICKING, CDLKICKINGBYLENGTH, CDLLADDERBOTTOM, CDLLONGLEGGEDDOJI, CDLLONGLINE, CDLMARUBOZU, CDLMATCHINGLOW, CDLMATHOLD, CDLMORNINGDOJISTAR, CDLMORNINGSTAR, CDLONNECK, CDLPIERCING, CDLRICKSHAWMAN, CDLRISEFALL3METHODS, CDLSEPARATINGLINES, CDLSHOOTINGSTAR, CDLSHORTLINE, CDLSPINNINGTOP, CDLSTALLEDPATTERN, CDLSTICKSANDWICH, CDLTAKURI, CDLTASUKIGAP, CDLTHRUSTING, CDLTRISTAR, CDLUNIQUE3RIVER, CDLUPSIDEGAP2CROWS, CDLXSIDEGAP3METHODS |
| Price Transform(价格变换函数组) | AVGPRICE, MEDPRICE, TYPPRICE, WCLPRICE |
| Statistic Functions(统计函数函数组) | BETA, CORREL, LINEARREG, LINEARREG_ANGLE, LINEARREG_INTERCEPT, LINEARREG_SLOPE, STDDEV, TSF, VAR |
| Volatility Indicators(波动性指标函数组) | ATR, NATR, TRANGE |
| Volume Indicators(成交量指标函数组) | AD, ADOSC, OBV |
(3) 使用ta-lib库中的指标函数
from talib import abstract
import numpy as np
price_arrays = {
'open': np.random.random(100),
'close': np.random.random(100),
'high': np.random.random(100),
'low': np.random.random(100),
}
# 计算开盘价的25日SMA均线
open_sma_price = abstract.SMA(price_arrays, timeperiod=25, price='open')
# 计算收盘价的25日SMA均线
close_sma_price = abstract.SMA(price_arrays, timeperiod=25, price='close')
# 计算最高价的25日SMA均线
high_sma_price = abstract.SMA(price_arrays, timeperiod=25, price='high')
# 计算最低价的25日SMA均线
low_sma_price = abstract.SMA(price_arrays, timeperiod=25, price='low')
print('开盘价25日均价:', open_sma_price)
print('收盘价25日均价:', close_sma_price)
print('最高价25日均价:', high_sma_price)
print('最低价25日均价:', low_sma_price)
(3) MACD指标详解
(1) MACD 指标简介
MACD称为异同移动平均线,是从双指数移动平均线发展而来的,由快的指数移动平均线(EMA12)减去慢的指数移动平均线(EMA26)得到快线DIF,再用2×(快线DIF-DIF的9日加权移动均线DEA)得到MACD柱。MACD的意义和双移动平均线基本相同,即由快、慢均线的离散、聚合表征当前的多空状态和股价可能的发展变化趋势,但阅读起来更方便。MACD的变化代表着市场趋势的变化,不同K线级别的MACD代表当前级别周期中的买卖趋势。
(2)MACD 指标计算
MACD由DIF、DEA以及柱状图组成,其中DIF由EMA1与EMA2相减得到。所以,我们首先需要计算EMA1与EMA2的值。需要注意的是,EMA不同于普通的均线,它是指数加权的移动平均线,也就是EMA1的窗口周期为12日,EMA2的窗口周期为26日。计算公式如下:
EMA1(12日收盘价移动平均线)=前一日EM1(12)11/13+今日收盘价2/13
EMA2(26日收盘价移动平均线)=前一日EMA2(26)25/27+今日收盘价2/27
得到EMA1与EMA2之后,我们就可以计算出DIF与DEA的值。通常DEA的窗口周期为9日,具体公式如下:
DIF(差离值)=EMA1-EMA2
DEA(差离平均值)=前一日DEA8/10+今日DIF2/10
最后,通过DIF与DEA得到柱状图,具体公式如下:
BAR(柱状值)=2*(DIF-DEA)
python代码:
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111)
df = pd.read_excel("歌尔股份k.xlsx")
df['date'] = pd.to_datetime(df['date'])
df['date'] = df['date'].apply(lambda x: x.strftime('%Y-%m-%d'))
EMA1=df["close"].ewm(span=12, adjust=False).mean()
EMA2=df["close"].ewm(span=26, adjust=False).mean()
DIF = EMA1 - EMA2
DEA = DIF.ewm(span=9, adjust=False).mean()
BAR = 2 * (DIF - DEA)
red_bar = np.where(BAR > 0, BAR, 0)
blue_bar = np.where(BAR < 0, BAR, 0)
ax.plot(np.arange(0, len(df)), DIF)
ax.plot(np.arange(0, len(df)), DEA)
ax.bar(np.arange(0, len(df)), red_bar, color="red")
ax.bar(np.arange(0, len(df)), blue_bar, color="blue")
ax.xaxis.set_major_locator(ticker.MaxNLocator(20))
def format_date(x, pos=None):
if x < 0 or x > len(df['date']) - 1:
return ''
return df['date'][int(x)]
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
plt.title("MACD")
plt.show()
(4) MACD金叉死叉买卖技术
简单地对应市场上的说法如下:
(1)MACD 金叉: DIF 由下向上突破 DEA,为买入信号。
(2)MACD 死叉: DIF 由上向下突破 DEA,为卖出信号。
针对这两条的说法,我需要提出 MACD 具有一定的滞后情况,即比市场的反应要慢。因为 MACD 是一个中长期的指标,而不是个短期指标,不适合短期涨跌浮动太大的证券。
接下来,3 种说法更靠谱些:
3. MACD 柱状图为红,即 DIF 与 DEA 均为正值,即都在零轴线以上时,市场趋势属多头市场,若此时 DIF 向上继续突破 DEA,即红色柱状越来越长,可作买入信号,该出手就出手。
4. MACD 柱状图为绿,即 DIF 与 DEA 均为负值,即都在零轴线以下时,市场趋势属空头市场,若此时 DIF 向下继续跌破 DEA,即绿色柱状越来越长,可作卖出信号,该割肉就割肉。
Python 代码:
import baostock as bs
import pandas as pd
import talib as ta
import matplotlib.pyplot as plt
def computeMACD(code, startdate, enddate):
login_result = bs.login(user_id='anonymous', password='123456')
print(login_result)
# 获取股票日 K 线数据
rs = bs.query_history_k_data(code,
"date,code,close,tradeStatus",
start_date=startdate,
end_date=enddate,
frequency="d", adjustflag="3")
# 打印结果集
result_list = []
while (rs.error_code == '0') & rs.next():
# 获取一条记录,将记录合并在一起
result_list.append(rs.get_row_data())
df = pd.DataFrame(result_list, columns=rs.fields)
# 剔除停盘数据
df2 = df[df['tradeStatus'] == '1']
# 获取 dif,dea,hist,它们的数据类似是 tuple,且跟 df2 的 date 日期一一对应
# 记住了 dif,dea,hist 前 33 个为 Nan,所以推荐用于计算的数据量一般为你所求日期之间数据量的 3 倍
# 这里计算的 hist 就是 dif-dea,而很多证券商计算的 MACD=hist*2=(difdea)*2
dif, dea, hist = ta.MACD(df2['close'].astype(float).values, fastperiod=12, slowperiod=26, signalperiod=9)
df3 = pd.DataFrame({'dif': dif[33:], 'dea': dea[33:], 'hist':hist[33:]},index=df2['date'][33:], columns=['dif', 'dea','hist'])
df3.plot(title='MACD')
plt.show()
# 寻找 MACD 金叉和死叉
datenumber = int(df3.shape[0])
for i in range(datenumber - 1):
if ((df3.iloc[i, 0] <= df3.iloc[i, 1]) & (df3.iloc[i + 1, 0] >= df3.iloc[i + 1, 1])):
print("MACD 金叉的日期:" + df3.index[i + 1])
if ((df3.iloc[i, 0] >= df3.iloc[i, 1]) & (df3.iloc[i + 1, 0] <=df3.iloc[i + 1, 1])):
print("MACD 死叉的日期:" + df3.index[i + 1])
bs.logout()
return (dif, dea, hist)
if name == 'main':
code = 'sh.600000'
startdate = '2017-03-01'
enddate = '2017-12-01'
(dif, dea, hist) = computeMACD(code, startdate, enddate)
注意:金叉死叉的预测成功率也就5成左右,所有完全靠这个指标操作的朋友能难成功,需要其他指标技术辅助。
(5) MACD顶底背离技术
顶背离和底背离的概念:
MACD指标的背离就是指MACD指标的图形的走势正好和K线图的走势方向正好相反。MACD指标的背离有顶背离和底背离两种。
(1)顶背离
当股价K线图上的股票走势一峰比一峰高,股价一直在向上涨,而MACD指标图形上的由红柱构成的图形的走势是一峰比一峰低,即当股价的高点比前一次的高点高、而MACD指标的高点比指标的前一次高点低,这叫顶背离现象。顶背离现象一般是股价在高位即将反转转势的信号,表明股价短期内即将下跌,是卖出股票的信号。
代码:
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('data.csv')
# 计算MACD
data['ema12'] = data['close'].ewm(span=12, min_periods=1, adjust=False).mean()
data['ema26'] = data['close'].ewm(span=26, min_periods=1, adjust=False).mean()
data['macd'] = data['ema12'] - data['ema26']
# 计算顶背离卖点
data['sell_signal'] = data[(data['close'] > data['close'].shift(1)) & (data['macd'] < data['macd'].shift(1))]
# 输出结果
print(data[['close', 'macd', 'sell_signal']])
(2)底背离
底背离一般出现在股价的低位区。当股价K线图上的股票走势,股价还在下跌,而MACD指标图形上的由绿柱构成的图形的走势是一底比一底高,即当股价的低点比前一次低点底,而指标的低点却比前一次的低点高,这叫底背离现象。底背离现象一般是预示股价在低位可能反转向上的信号,表明股价短期内可能反弹向上,是短期买入股票的信号。
代码:
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('data.csv')
# 计算MACD
data['ema12'] = data['close'].ewm(span=12, min_periods=1, adjust=False).mean()
data['ema26'] = data['close'].ewm(span=26, min_periods=1, adjust=False).mean()
data['macd'] = data['ema12'] - data['ema26']
# 计算底背离买点
data['buy_signal'] = data[(data['close'] < data['close'].shift(1)) & (data['macd'] > data['macd'].shift(1))]
# 输出结果
print(data[['close', 'macd', 'buy_signal']])
(3)W低寻找买点
MACD指标的“W底”形态是一种常见的买入信号,通常出现在股价下跌趋势中。当股价在MACD指标的零轴线下方形成“W底”形态时,通常预示着股价即将反弹。
代码
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('data.csv')
# 计算MACD
data['ema12'] = data['close'].ewm(span=12, min_periods=1, adjust=False).mean()
data['ema26'] = data['close'].ewm(span=26, min_periods=1, adjust=False).mean()
data['macd'] = data['ema12'] - data['ema26']
# 计算“W底”形态的买点
data['buy_signal'] = data[(data['macd'] < 0) & (data['close'].shift(1) > data['close']) & (data['close'].shift(1) > data['macd'].shift(1))]
# 输出结果
print(data[['close', 'macd', 'buy_signal']])
(4)M顶寻找卖点
MACD指标的“M顶”形态是一种常见的卖出信号,通常出现在股价上涨趋势中。当股价在MACD指标的零轴线上方形成“M顶”形态时,通常预示着股价即将下跌。
以下是使用Python计算MACD的“M顶”形态的示例代码:
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('data.csv')
# 计算MACD
data['ema12'] = data['close'].ewm(span=12, min_periods=1, adjust=False).mean()
data['ema26'] = data['close'].ewm(span=26, min_periods=1, adjust=False).mean()
data['macd'] = data['ema12'] - data['ema26']
# 计算“M顶”形态的卖点
data['sell_signal'] = data[(data['macd'] > 0) & (data['close'].shift(1) < data['close']) & (data['close'].shift(1) < data['macd'].shift(1))]
# 输出结果
print(data[['close', 'macd', 'sell_signal']])