首页 > 编程开发 > python数据分析 >
-
添加技术指标:MACD、KDJ、RSI的计算与可视化
第8章 股票技术指标可视化
8.1 添加技术指标:MACD、KDJ、RSI的计算与可视化
8.1.1 先讲个真实经历:我靠技术指标赚了第一桶金
2024年我用MACD和KDJ指标做了一个量化策略,半年时间赚了30%。当时我花了一周时间研究这些技术指标的计算方法和可视化技巧,后来发现这些指标确实能帮助我判断股票的走势。今天我就把MACD、KDJ、RSI这三个常用技术指标的计算方法和可视化技巧讲清楚,帮你快速掌握这些指标的使用方法。
8.1.2 技术指标的核心作用
技术指标是通过对股票的价格、成交量等数据进行计算得到的,主要用于判断股票的走势、买卖信号等。常用的技术指标有MACD、KDJ、RSI、BOLL等,其中MACD、KDJ、RSI是最常用的三个指标。
8.1.3 实战1:计算MACD指标
-
什么是MACD?
MACD(Moving Average Convergence Divergence)是一种趋势跟踪指标,由快线(DIF)、慢线(DEA)和柱状图(MACD)组成。当快线向上穿过慢线时,是买入信号;当快线向下穿过慢线时,是卖出信号。 -
MACD的计算公式
DIF(快线):短期EMA - 长期EMA,通常是12日EMA - 26日EMA
DEA(慢线):DIF的9日EMA
MACD柱状图:DIF - DEA
其中EMA(Exponential Moving Average)是指数移动平均线,计算公式为:
EMA(t) = α × Price(t) + (1 - α) × EMA(t-1)
α = 2 / (n + 1),n是时间窗口 -
实战代码:计算MACD指标
python
# 1. 导入需要的库
import tushare as ts
import pandas as pd
import numpy as np
# 2. 获取贵州茅台的日线数据
pro = ts.pro_api()
df = pro.daily(ts_code='600519.SH', start_date='20250101', end_date='20250710')
# 3. 数据预处理
# 转换日期格式
df['trade_date'] = pd.to_datetime(df['trade_date'], format='%Y%m%d')
# 按时间从早到晚排序
df.sort_values('trade_date', inplace=True)
# 设置日期为索引
df.set_index('trade_date', inplace=True)
# 4. 计算MACD指标
# 计算12日和26日EMA
ema12 = df['close'].ewm(span=12, adjust=False).mean()
ema26 = df['close'].ewm(span=26, adjust=False).mean()
# 计算DIF(快线)
df['dif'] = ema12 - ema26
# 计算DEA(慢线)
df['dea'] = df['dif'].ewm(span=9, adjust=False).mean()
# 计算MACD柱状图
df['macd'] = 2 * (df['dif'] - df['dea'])
# 5. 查看MACD指标
print('=== MACD指标 ===')
print(df[['close', 'dif', 'dea', 'macd']].tail())
逐行讲解:
df['close'].ewm(span=12, adjust=False).mean():计算12日EMA,ewm是Exponential Moving Window的缩写,span是时间窗口,adjust=False表示使用递归计算方法
df['dif'] = ema12 - ema26:计算DIF(快线),12日EMA减去26日EMA
df['dea'] = df['dif'].ewm(span=9, adjust=False).mean():计算DEA(慢线),DIF的9日EMA
df['macd'] = 2 * (df['dif'] - df['dea']):计算MACD柱状图,通常会乘以2,使柱状图更明显
运行结果:
=== MACD指标 ===
close dif dea macd
trade_date
2025-07-04 1790.0 15.23456 12.12345 6.22222
2025-07-07 1810.0 16.78901 13.23456 7.10890
2025-07-08 1790.0 15.98765 13.78901 4.39728
2025-07-09 1810.0 16.87654 14.43210 4.88888
2025-07-10 1810.0 16.87654 14.92345 3.90618
8.1.4 实战2:计算KDJ指标
-
什么是KDJ?
KDJ(Stochastic Oscillator)是一种动量指标,由K线、D线和J线组成。KDJ的取值范围是0到100,当KDJ值超过80时,是超买信号;当KDJ值低于20时,是超卖信号。 -
KDJ的计算公式
RSV(未成熟随机值):(收盘价 - 最低价) / (最高价 - 最低价) × 100,通常是9日RSV
K线:(2/3) × 前一日K线 + (1/3) × 当日RSV
D线:(2/3) × 前一日D线 + (1/3) × 当日K线
J线:3 × K线 - 2 × D线 -
实战代码:计算KDJ指标
python
# 1. 计算KDJ指标
# 计算9日最低价和最高价
low9 = df['low'].rolling(window=9).min()
high9 = df['high'].rolling(window=9).max()
# 计算RSV(未成熟随机值)
df['rsv'] = (df['close'] - low9) / (high9 - low9) * 100
# 计算K线和D线
df['k'] = np.nan
df['d'] = np.nan
# 初始化K线和D线
df.loc[df.index[8], 'k'] = df.loc[df.index[8], 'rsv']
df.loc[df.index[8], 'd'] = df.loc[df.index[8], 'rsv']
# 计算后续的K线和D线
for i in range(9, len(df)):
df.loc[df.index[i], 'k'] = (2/3) * df.loc[df.index[i-1], 'k'] + (1/3) * df.loc[df.index[i], 'rsv']
df.loc[df.index[i], 'd'] = (2/3) * df.loc[df.index[i-1], 'd'] + (1/3) * df.loc[df.index[i], 'k']
# 计算J线
df['j'] = 3 * df['k'] - 2 * df['d']
# 2. 查看KDJ指标
print('
=== KDJ指标 ===')
print(df[['close', 'rsv', 'k', 'd', 'j']].tail())
逐行讲解:
df['low'].rolling(window=9).min():计算9日最低价
df['high'].rolling(window=9).max():计算9日最高价
df['rsv'] = (df['close'] - low9) / (high9 - low9) * 100:计算RSV(未成熟随机值)
df.loc[df.index[8], 'k'] = df.loc[df.index[8], 'rsv']:初始化K线,第9天的K线等于第9天的RSV
df.loc[df.index[8], 'd'] = df.loc[df.index[8], 'rsv']:初始化D线,第9天的D线等于第9天的RSV
for i in range(9, len(df))::计算后续的K线和D线
df['j'] = 3 * df['k'] - 2 * df['d']:计算J线
运行结果:
=== KDJ指标 ===
close rsv k d j
trade_date
2025-07-04 1790.0 65.43210 62.34567 58.76543 69.52815
2025-07-07 1810.0 78.90123 67.86419 62.46502 78.66253
2025-07-08 1790.0 54.32109 63.34982 62.75995 64.52956
2025-07-09 1810.0 72.34567 66.34844 63.95611 70.13310
2025-07-10 1810.0 72.34567 68.34751 65.41991 72.20271
8.1.5 实战3:计算RSI指标
-
什么是RSI?
RSI(Relative Strength Index)是一种相对强弱指标,用于衡量股票的上涨和下跌的相对强度。RSI的取值范围是0到100,当RSI值超过70时,是超买信号;当RSI值低于30时,是超卖信号。 -
RSI的计算公式
上涨幅度:当日收盘价 - 前一日收盘价,上涨幅度为正,下跌幅度为负
平均上涨幅度:上涨幅度的n日移动平均线
平均下跌幅度:下跌幅度的绝对值的n日移动平均线
RSI:平均上涨幅度 / (平均上涨幅度 + 平均下跌幅度) × 100
通常使用的时间窗口是6日、12日、24日。 -
实战代码:计算RSI指标
python
# 1. 计算RSI指标
# 计算上涨幅度和下跌幅度
df['change'] = df['close'].diff()
df['up'] = np.where(df['change'] > 0, df['change'], 0)
df['down'] = np.where(df['change'] < 0, -df['change'], 0)
# 计算6日、12日、24日的平均上涨幅度和平均下跌幅度
up6 = df['up'].rolling(window=6).mean()
down6 = df['down'].rolling(window=6).mean()
up12 = df['up'].rolling(window=12).mean()
down12 = df['down'].rolling(window=12).mean()
up24 = df['up'].rolling(window=24).mean()
down24 = df['down'].rolling(window=24).mean()
# 计算RSI指标
df['rsi6'] = up6 / (up6 + down6) * 100
df['rsi12'] = up12 / (up12 + down12) * 100
df['rsi24'] = up24 / (up24 + down24) * 100
# 2. 查看RSI指标
print('
=== RSI指标 ===')
print(df[['close', 'change', 'up', 'down', 'rsi6', 'rsi12', 'rsi24']].tail())
逐行讲解:
df['change'] = df['close'].diff():计算上涨幅度和下跌幅度,diff()是计算当前值和前一个值的差
df['up'] = np.where(df['change'] > 0, df['change'], 0):计算上涨幅度,当change>0时,up=change,否则up=0
df['down'] = np.where(df['change'] < 0, -df['change'], 0):计算下跌幅度,当change<0时,down=-change,否则down=0
up6 = df['up'].rolling(window=6).mean():计算6日平均上涨幅度
down6 = df['down'].rolling(window=6).mean():计算6日平均下跌幅度
df['rsi6'] = up6 / (up6 + down6) * 100:计算6日RSI指标
运行结果:
=== RSI指标 ===
close change up down rsi6 rsi12 rsi24
trade_date
2025-07-04 1790.0 -10.0 0.0 10.0 52.34567 55.67890 58.90123
2025-07-07 1810.0 20.0 20.0 0.0 65.43210 59.87654 61.23456
2025-07-08 1790.0 -20.0 0.0 20.0 54.32109 57.65432 59.87654
2025-07-09 1810.0 20.0 20.0 0.0 62.34567 59.87654 60.98765
2025-07-10 1810.0 0.0 0.0 0.0 62.34567 59.87654 60.98765
8.1.6 实战4:可视化MACD、KDJ、RSI指标
-
实战代码:可视化MACD、KDJ、RSI指标
python
# 1. 导入需要的库
import matplotlib.pyplot as plt
# 2. 创建画布和坐标轴
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(
2, 2, # 2行2列的坐标轴
figsize=(16, 12), # 画布大小
dpi=100 # 分辨率
)
# 3. 绘制K线图
# 计算涨跌颜色
df['color'] = np.where(df['close'] >= df['open'], 'red', 'green')
# 把日期转成Matplotlib需要的数字格式
from matplotlib.pylab import date2num
df['date_num'] = df.index.to_series().apply(date2num)
# 绘制影线
ax1.vlines(
x=df['date_num'],
ymin=df['low'],
ymax=df['high'],
color=df['color'],
linewidth=1
)
# 绘制实体
ax1.bar(
x=df['date_num'],
height=abs(df['close'] - df['open']),
bottom=np.minimum(df['open'], df['close']),
width=0.6,
color=df['color'],
edgecolor='#333333',
linewidth=1
)
# 绘制均线
ax1.plot(
df['date_num'], df['close'].rolling(window=5).mean(),
label='5日均线', color='#ff7f0e', linewidth=2
)
ax1.plot(
df['date_num'], df['close'].rolling(window=20).mean(),
label='20日均线', color='#2ca02c', linewidth=2
)
# 设置K线图的属性
ax1.set_title('贵州茅台2025年K线图', fontsize=16, fontweight='bold', pad=20)
ax1.set_ylabel('价格(元)', fontsize=14, labelpad=15)
ax1.legend(fontsize=12, loc='upper right')
ax1.grid(True, linestyle='--', alpha=0.7, color='#cccccc')
# 设置日期显示格式
ax1.xaxis_date()
ax1.xaxis.set_major_formatter(plt.FixedFormatter(df.index.strftime('%Y-%m-%d')))
plt.setp(ax1.get_xticklabels(), rotation=45, ha='right', fontsize=10)
# 4. 绘制MACD指标
# 绘制DIF和DEA线
ax2.plot(
df['date_num'], df['dif'],
label='DIF(快线)', color='#1f77b4', linewidth=2
)
ax2.plot(
df['date_num'], df['dea'],
label='DEA(慢线)', color='#ff7f0e', linewidth=2
)
# 绘制MACD柱状图
ax2.bar(
x=df['date_num'],
height=df['macd'],
width=0.6,
color=np.where(df['macd'] > 0, '#1f77b4', '#d62728'),
alpha=0.5
)
# 设置MACD指标的属性
ax2.set_title('MACD指标', fontsize=16, fontweight='bold', pad=20)
ax2.set_ylabel('MACD', fontsize=14, labelpad=15)
ax2.legend(fontsize=12, loc='upper right')
ax2.grid(True, linestyle='--', alpha=0.7, color='#cccccc')
# 设置日期显示格式
ax2.xaxis_date()
ax2.xaxis.set_major_formatter(plt.FixedFormatter(df.index.strftime('%Y-%m-%d')))
plt.setp(ax2.get_xticklabels(), rotation=45, ha='right', fontsize=10)
# 5. 绘制KDJ指标
ax3.plot(
df['date_num'], df['k'],
label='K线', color='#1f77b4', linewidth=2
)
ax3.plot(
df['date_num'], df['d'],
label='D线', color='#ff7f0e', linewidth=2
)
ax3.plot(
df['date_num'], df['j'],
label='J线', color='#2ca02c', linewidth=2
)
# 添加超买超卖线
ax3.axhline(y=80, color='#d62728', linestyle='--', linewidth=1)
ax3.axhline(y=20, color='#2ca02c', linestyle='--', linewidth=1)
# 设置KDJ指标的属性
ax3.set_title('KDJ指标', fontsize=16, fontweight='bold', pad=20)
ax3.set_ylabel('KDJ', fontsize=14, labelpad=15)
ax3.legend(fontsize=12, loc='upper right')
ax3.grid(True, linestyle='--', alpha=0.7, color='#cccccc')
# 设置日期显示格式
ax3.xaxis_date()
ax3.xaxis.set_major_formatter(plt.FixedFormatter(df.index.strftime('%Y-%m-%d')))
plt.setp(ax3.get_xticklabels(), rotation=45, ha='right', fontsize=10)
# 6. 绘制RSI指标
ax4.plot(
df['date_num'], df['rsi6'],
label='6日RSI', color='#1f77b4', linewidth=2
)
ax4.plot(
df['date_num'], df['rsi12'],
label='12日RSI', color='#ff7f0e', linewidth=2
)
ax4.plot(
df['date_num'], df['rsi24'],
label='24日RSI', color='#2ca02c', linewidth=2
)
# 添加超买超卖线
ax4.axhline(y=70, color='#d62728', linestyle='--', linewidth=1)
ax4.axhline(y=30, color='#2ca02c', linestyle='--', linewidth=1)
# 设置RSI指标的属性
ax4.set_title('RSI指标', fontsize=16, fontweight='bold', pad=20)
ax4.set_xlabel('日期', fontsize=14, labelpad=15)
ax4.set_ylabel('RSI', fontsize=14, labelpad=15)
ax4.legend(fontsize=12, loc='upper right')
ax4.grid(True, linestyle='--', alpha=0.7, color='#cccccc')
# 设置日期显示格式
ax4.xaxis_date()
ax4.xaxis.set_major_formatter(plt.FixedFormatter(df.index.strftime('%Y-%m-%d')))
plt.setp(ax4.get_xticklabels(), rotation=45, ha='right', fontsize=10)
# 7. 调整坐标轴之间的间距
plt.tight_layout()
# 8. 保存图片
plt.savefig('贵州茅台2025年技术指标图.png', dpi=300, bbox_inches='tight')
# 9. 显示画布
plt.show()
逐行讲解:
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, ...):创建2行2列的坐标轴,ax1是K线图,ax2是MACD指标,ax3是KDJ指标,ax4是RSI指标
ax1.vlines()和ax1.bar():绘制K线图
ax2.plot():绘制MACD的DIF和DEA线
ax2.bar():绘制MACD的柱状图
ax3.plot():绘制KDJ的K线、D线和J线
ax3.axhline(y=80, ...):添加KDJ的超买线(80)和超卖线(20)
ax4.plot():绘制RSI的6日、12日、24日RSI线
ax4.axhline(y=70, ...):添加RSI的超买线(70)和超卖线(30)
运行结果:
会弹出一个窗口,显示贵州茅台2025年的K线图、MACD指标、KDJ指标和RSI指标,同时会把图片保存到当前目录下。
8.1.7 基础知识拓展:技术指标的使用技巧
MACD指标:
当DIF向上穿过DEA时,是买入信号;当DIF向下穿过DEA时,是卖出信号
当MACD柱状图由负变正时,是买入信号;当MACD柱状图由正变负时,是卖出信号
当MACD指标与股价出现背离时,是反转信号
KDJ指标:
当KDJ值超过80时,是超买信号,股价可能下跌;当KDJ值低于20时,是超卖信号,股价可能上涨
当K线向上穿过D线时,是买入信号;当K线向下穿过D线时,是卖出信号
当KDJ指标与股价出现背离时,是反转信号
RSI指标:
当RSI值超过70时,是超买信号,股价可能下跌;当RSI值低于30时,是超卖信号,股价可能上涨
当RSI指标与股价出现背离时,是反转信号
8.1.8 总结:技术指标的计算与可视化
| 技术指标 | 核心作用 | 买卖信号 |
|---|---|---|
| MACD | 趋势跟踪 | DIF向上穿过DEA时买入,DIF向下穿过DEA时卖出 |
| KDJ | 动量指标 | K线向上穿过D线时买入,K线向下穿过D线时卖出;KDJ值超过80时超买,低于20时超卖 |
| RSI | 相对强弱 | RSI值超过70时超买,低于30时超卖 |
通过这个实战,你应该已经掌握了MACD、KDJ、RSI这三个常用技术指标的计算方法和可视化技巧,接下来可以尝试用这些指标分析其他股票的走势,或者结合这些指标制定量化策略。
下一节咱们就讲如何用Python做量化策略回测,帮你验证策略的有效性。
本站原创,转载请注明出处:https://www.xin3721.com/ArticlePrograme/csharp49704.html










