本人股市多年的老韭菜,各种股票分析书籍,技术指标书籍阅历无数,萌发想法,何不自己开发个股票预测分析软件,选择python因为够强大,它提供了很多高效便捷的数据分析工具包,
我们已经初步的接触与学习其中数据分析中常见的3大利器---Numpy,Pandas,Matplotlib库。
也简单介绍一下数据获取的二种方法,通过金融数据接口和爬虫获取。
上一章初步的介绍了股票分析常见的技术指标和算法模型,这一章重点讲一下指标之王MACD,
在学习MACD之前必须先安装和了解一下ta-lib库
我们进行技术分析计算的时候很多情况引入第三方Python包,ta-lib就是其中之一。ta-lib全称是Technical Analysis Library,翻译为中文就是技术分析库,它是Python金融量化领域的一个高级库,被广泛应用在金融市场数据进行技术分析,其内部实现了150多种股票、期货交易中常用的技术分析指标,如SMA、MACD、RSI、KDJ、动量指标、布林带等。
pip install Ta-Lib
根据技术指标的不同特征,talib库一共有10个指标函数组,各个指标函数组中包含了诸多的指标函数。下表是talib库包含的10个指标函数组及每个指标组中包含的指标函数。
指标函数组名称 |
指标函数组中包含的指标函数 |
Cycle Indicators(循环指标函数组) |
HT_DCPERIOD, HT_DCPHASE, HT_PHASOR, HT_SINE, |
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 |
注:指标函数提供了各种技术指标参数
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)
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)
代码实现MACD图:
import pandas as pd
import talib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111)
df = pd.read_csv("600271.csv")
df['date'] = pd.to_datetime(df['date'])
df['date'] = df['date'].apply(lambda x: x.strftime('%Y-%m-%d'))
dif, dea, bar = talib.MACD(df['close'].values, fastperiod=12, slowperiod=26, signalperiod=9)
dif[np.isnan(dif)], dea[np.isnan(dea)], bar[np.isnan(bar)] = 0, 0, 0
ax.plot(np.arange(0, len(df)), dif)
ax.plot(np.arange(0, len(df)), dea)
red_bar = np.where(bar > 0, 2 * bar, 0)
blue_bar = np.where(bar < 0, 2 * bar, 0)
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.show()
简单地对应市场上的说法如下:
(1)MACD 金叉:DIF 由下向上突破DEA,为买入信号。
(2)MACD 死叉:DIF 由上向下突破DEA,为卖出信号。
针对这两条的说法,我需要提出MACD 具有一定的滞后情况,即比市场的反应要慢。因为MACD 是一个中长期的指标,而不是个短期指标,不适合短期涨跌浮动太大的证券。
3.MACD 柱状图为红,即DIF与DEA 均为正值,即都在零轴线以上时,市场趋势属多头市场,若此时DIF 向上继续突破DEA,即红色柱状越来越长,可作买入信号,该出手就出手。
4. MACD 柱状图为绿,即DIF与DEA 均为负值,即都在零轴线以下时,市场趋势属空头市场,若此时DIF 向下继续跌破DEA,即绿色柱状越来越长,可作卖出信号,该割肉就割肉
代码案例:
import baostock as bs
import pandas as pd
import talib as ta
import matplotlib.pyplot as plt
def computeMACD(code, startdate, enddate):
# 获取股票日 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.600118'
startdate = '2022-03-01'
enddate = '2023-12-20'
(dif, dea, hist) = computeMACD(code, startdate, enddate)
#显示结果:MACD 金叉的日期:2023-02-21
MACD 金叉的日期:2023-05-10
MACD 金叉的日期:2023-05-17
MACD 金叉的日期:2023-05-29
MACD 金叉的日期:2023-08-31
MACD 金叉的日期:2023-10-10
MACD 金叉的日期:2023-11-03
注意:既然macd贵为指标之王,也就是刚用的时候指标很灵验,现在用的人多了,指标数据可以人为控制,股市还是二八定律,所有macd的金叉死叉的成功率50%左右,必须结合其他指标来判断
顶背离和底背离的概念:
MACD指标的背离就是指MACD指标的图形的走势正好和K线图的走势方向正好相反。MACD指标的背离有顶背离和底背离两种。
当股价K线图上的股票走势一峰比一峰高,股价一直在向上涨,而MACD指标图形上的由红柱构成的图形的走势是一峰比一峰低,即当股价的高点比前一次的高点高、而MACD指标的高点比指标的前一次高点低,这叫顶背离现象。顶背离现象一般是股价在高位即将反转转势的信号,表明股价短期内即将下跌,是卖出股票的信号。
python 代码:
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('000271.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']])
底背离一般出现在股价的低位区。当股价K线图上的股票走势,股价还在下跌,而MACD指标图形上的由绿柱构成的图形的走势是一底比一底高,即当股价的低点比前一次低点底,而指标的低点却比前一次的低点高,这叫底背离现象。底背离现象一般是预示股价在低位可能反转向上的信号,表明股价短期内可能反弹向上,是短期买入股票的信号。
python代码:
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('000271.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']])
注意:MACD的顶背离成功率远远大于底背离,特别顶部放量的背离基本准确率90%以上,底背离还是要结合其他技术指标来判断。因为底背离可能出现几次 才能反转的情况很多
MACD指标的“M顶”形态是一种常见的卖出信号,通常出现在股价上涨趋势中。当股价在MACD指标的零轴线上方形成“M顶”形态时,通常预示着股价即将下跌。
以下是使用Python计算MACD的“M顶”形态的示例代码:
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('000271.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']])
MACD指标的“W底”形态是一种常见的买入信号,通常出现在股价下跌趋势中。当股价在MACD指标的零轴线下方形成“W底”形态时,通常预示着股价即将反弹。
以下是使用Python计算MACD的“W底”形态的示例代码:
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('002711.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']])
其他还有多种反转指标,比如绿柱消失红柱出现买入信号,记住,所有指标都要结合其他指标使用,来提高的成功率,因为股市本质上就是概率游戏。
谢谢大家,不足之处还请多指教,相互学习进步!!!