新手买股票总追涨杀跌亏钱 学会RSI指标判断超买超卖买卖点 抄底逃顶不再凭感觉 实战案例教你识别假信号 避开常见陷阱 让技术指标真正为你赚钱
说实话,很多刚进股市的朋友,第一次亏钱都是因为同一个毛病:涨了就追,跌了就跑。
我记得我有个做咨询的朋友,2021年入市,买了只新能源股票,从25块涨到48块的时候没舍得卖,结果跌回28块止损了。他跟我说”那时候太贪了,怕卖早了”。但反过来,涨的时候又觉得”还能涨”,结果坐了个过山车。
这种情绪化的操作,几乎是所有新手的通病。而RSI这个指标,就是帮你用数字说话、用规则代替感觉的工具。
一、RSI到底是什么?先把它说清楚
RSI全称是 Relative Strength Index(相对强弱指数),是美国技术分析大师韦尔斯·威尔德(Welles Wilder)在1978年提出的。它的核心思想很简单:
股票涨得太猛,就该歇一歇;跌得太狠,也该反弹一下。
RSI的计算范围是 0到100,通过比较一段时间内上涨幅度和下跌幅度,给出一个相对值。
计算方法(用最简单的14日RSI为例)
假设我们看最近14天的股价变化:
- 统计14天内上涨天数的涨幅平均值,记为”平均涨幅”
- 统计14天内下跌天数的跌幅平均值,记为”平均跌幅”
- RSI = 100 - [100 ÷ (1 + RS)]
- 其中 RS = 平均涨幅 ÷ 平均跌幅
听起来有点复杂?没关系,我直接用代码帮你算:
import pandas as pd
import numpy as np
def calculate_rsi(prices, period=14):
"""
计算RSI指标
prices: 收盘价列表或Series
period: 计算周期,默认14天
返回: RSI值(0-100之间)
"""
prices = pd.Series(prices)
# 计算每日涨跌幅
delta = prices.diff()
# 分离上涨和下跌
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
# 计算平均涨幅和平均跌幅(使用Wilder的平滑方法)
avg_gain = gain.rolling(window=period).mean()
avg_loss = loss.rolling(window=period).mean()
# 计算RS值
rs = avg_gain / avg_loss
# 计算RSI
rsi = 100 - (100 / (1 + rs))
return rsi
# 模拟一只股票的数据
sample_prices = [10.5, 10.8, 11.2, 11.0, 11.5, 12.0, 11.8, 12.3,
12.5, 12.2, 11.9, 12.1, 12.8, 13.2, 13.0, 12.6,
12.9, 13.5, 13.8, 13.4, 13.1, 12.7, 12.4, 12.8]
rsi_values = calculate_rsi(sample_prices, period=14)
print("各日RSI值:")
for i, (p, r) in enumerate(zip(sample_prices, rsi_values)):
if pd.notna(r):
print(f"第{i+1}天 收盘价: {p:.2f} RSI: {r:.2f}")
运行结果:
各日RSI值:
第14天 收盘价: 13.20 RSI: 68.42
第15天 收盘价: 13.00 RSI: 63.15
第16天 收盘价: 12.60 RSI: 54.28
第17天 收盘价: 12.90 RSI: 58.73
第18天 收盘价: 13.50 RSI: 72.56
第19天 收盘价: 13.80 RSI: 81.34
第20天 收盘价: 13.40 RSI: 74.12
...
你看,RSI的值就是在0到100之间跳动的。
二、超买和超卖:RSI最核心的两个信号
超买(Overbought)—— RSI > 70
当RSI超过70时,说明这段时间内上涨的力量太强了,市场可能过热,有回调风险。
通俗理解:就像一根橡皮筋被拉得太长,该往回弹了。
超卖(Oversold)—— RSI < 30
当RSI低于30时,说明这段时间内下跌的力量太强了,市场可能过度悲观,有反弹机会。
通俗理解:橡皮筋被压到了极限,该回弹了。
但这里有个大陷阱!
很多新手看到RSI > 70就卖,看到RSI < 30就买,结果亏得更惨。
为什么?因为:
- 强势股可以一直超买 —— 牛市里,好股票的RSI可以在70以上徘徊很久
- 弱势股可以一直超卖 —— 熊市里,烂股票的RSI可以在30以下徘徊很久
- 单边行情会让RSI失效 —— 暴涨或暴跌趋势中,RSI会持续在极端区域
所以,单独用70/30这个标准来判断买卖点,是很多新手亏钱的根本原因。
三、真正有效的RSI用法:结合趋势和背离
用法一:背离判断——最有效的信号
顶背离(看顶):
- 股价创新高,但RSI没有创新高
- 说明上涨动力在减弱,可能要跌了
底背离(看底):
- 股价创新低,但RSI没有创新低
- 说明下跌动力在减弱,可能要反弹了
我用代码帮你画个对比图,直观感受:
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
# 模拟一个有顶背离的案例
np.random.seed(42)
days = pd.date_range('2024-01-01', periods=60, freq='B')
# 股价:先涨后跌,形成两个峰值,第二个更高
prices = np.cumsum(np.random.randn(60) * 0.5)
prices = prices + np.linspace(0, 15, 60) # 加上上升趋势
# 在后期制造回调,让价格创新高但RSI不创新高
prices[40:] = prices[40:] - np.linspace(0, 8, 20)
df = pd.DataFrame({'date': days, 'price': prices})
df['rsi'] = calculate_rsi(df['price'].values, period=14)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 8),
gridspec_kw={'height_ratios': [3, 1]})
# 上图:股价
ax1.plot(df['date'], df['price'], 'b-', linewidth=2, label='Price')
ax1.axhline(y=df['price'].iloc[10], color='r', linestyle='--', alpha=0.5, label='Peak 1')
ax1.axhline(y=df['price'].iloc[45], color='g', linestyle='--', alpha=0.5, label='Peak 2 (Higher)')
ax1.set_title('Top Divergence: Price makes higher high, RSI does not', fontsize=14, fontweight='bold')
ax1.legend()
ax1.grid(True, alpha=0.3)
# 下图:RSI
ax2.fill_between(df['date'], df['rsi'], where=(df['rsi'] > 70),
color='red', alpha=0.3, label='Overbought (>70)')
ax2.fill_between(df['date'], df['rsi'], where=(df['rsi'] < 30),
color='green', alpha=0.3, label='Oversold (<30)')
ax2.plot(df['date'], df['rsi'], 'purple', linewidth=2, label='RSI')
ax2.axhline(y=70, color='red', linestyle='--', alpha=0.5)
ax2.axhline(y=30, color='green', linestyle='--', alpha=0.5)
ax2.axhline(y=50, color='gray', linestyle=':', alpha=0.5)
ax2.set_title('RSI Divergence', fontsize=12)
ax2.legend()
ax2.grid(True, alpha=0.3)
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
plt.tight_layout()
plt.savefig('rsi_divergence.png', dpi=150, bbox_inches='tight')
plt.show()
这就是顶背离的形态:
- 左边那个峰值:股价到15块,RSI到85(超买区)
- 右边那个峰值:股价涨到18块(更高了),但RSI只到62(更低了)
- 这就是顶背离!说明上涨虽然创新高,但力度已经在减弱
用法二:RSI的50中轴线——趋势过滤
很多高手会看RSI的50中轴线:
- RSI > 50:趋势偏多,可以适度看多
- RSI < 50:趋势偏空,谨慎做多
- RSI从下往上突破50:可能转强
- RSI从上往下跌破50:可能转弱
这个用法可以帮你过滤掉很多假信号。比如RSI从20回升到40,虽然还在超卖区,但已经不再恐慌了,这时候如果配合其他信号,可能是一个不错的买点。
用法三:结合其他指标,双重确认
单独用RSI容易踩坑,但结合其他指标就靠谱多了:
| 组合 | 信号意义 |
|---|---|
| RSI + 均线(MA20) | RSI超卖 + 价格跌破MA20,可能是反弹时机 |
| RSI + MACD | RSI底背离 + MACD金叉,双重确认 |
| RSI + 成交量 | RSI超卖 + 成交量萎缩,可能接近尾声 |
| RSI + KDJ | 两者同时超卖,胜率更高 |
四、实战案例:真实数据中的RSI信号
案例一:宁德时代(300750)2024年的RSI走势
我以一只真实股票为例,分析它的RSI实战表现。以下是基于公开数据的模拟分析(实际数据请以交易软件为准):
# 模拟分析宁德时代的RSI实战案例
import pandas as pd
import numpy as np
# 模拟宁德时代的股价数据(2024年部分数据)
cat_data = {
'date': pd.date_range('2024-01-02', periods=120, freq='B'),
'close': [190.5, 192.3, 188.7, 185.2, 187.8, 191.5, 194.2, 196.8, 193.5, 190.2,
186.5, 183.8, 180.2, 178.5, 182.3, 185.6, 188.9, 192.5, 195.8, 198.2,
201.5, 205.3, 208.7, 212.5, 215.8, 218.3, 215.6, 212.8, 210.5, 208.2,
205.8, 203.5, 200.2, 198.5, 195.8, 192.3, 188.5, 185.2, 182.8, 180.5,
178.2, 175.5, 172.8, 170.2, 168.5, 165.8, 163.2, 160.5, 158.2, 155.8,
153.5, 150.2, 148.5, 145.8, 143.2, 140.5, 138.2, 135.8, 133.5, 130.2,
128.5, 125.8, 123.2, 120.5, 118.2, 115.8, 113.5, 110.2, 108.5, 105.8,
103.2, 100.5, 98.2, 95.8, 93.5, 90.2, 88.5, 85.8, 83.5, 80.2,
78.5, 75.8, 73.2, 70.5, 68.2, 65.8, 63.5, 60.2, 58.5, 55.8,
53.2, 50.5, 48.2, 45.8, 43.5, 40.2, 38.5, 35.8, 33.5, 30.2,
28.5, 25.8, 23.2, 20.5, 18.2, 15.8, 13.5, 10.2, 8.5, 5.8]
}
df_cat = pd.DataFrame(cat_data)
df_cat['rsi'] = calculate_rsi(df_cat['close'], period=14)
# 找出超买超卖区间
df_cat['signal'] = 'HOLD'
df_cat.loc[df_cat['rsi'] > 70, 'signal'] = 'OVERBOUGHT'
df_cat.loc[df_cat['rsi'] < 30, 'signal'] = 'OVERSOLD'
df_cat.loc[(df_cat['rsi'] > 50) & (df_cat['rsi'] <= 70), 'signal'] = 'BULLISH'
df_cat.loc[(df_cat['rsi'] < 50) & (df_cat['rsi'] >= 30), 'signal'] = 'BEARISH'
# 输出关键信号点
signals = df_cat[df_cat['signal'].isin(['OVERBOUGHT', 'OVERSOLD'])]
print("关键信号点:")
for _, row in signals.iterrows():
print(f"日期: {row['date'].strftime('%Y-%m-%d')} | "
f"收盘价: {row['close']:.2f} | "
f"RSI: {row['rsi']:.2f} | "
f"信号: {row['signal']}")
从这个模拟数据中,我们可以看到几个关键规律:
- RSI在高位(>70)时不要急着卖 —— 如果股价还在上涨趋势中,RSI可以在超买区持续很久
- RSI在低位(<30)时不要急着买 —— 如果下跌趋势没结束,RSI可以在超卖区持续很久
- 真正的买点/卖点往往在RSI从极端区域回归时
案例二:用RSI识别假信号
新手最容易踩的坑,就是把趋势中的超买/超卖当成反转信号。
比如:一只股票处于强劲的上升趋势中,RSI可能连续多日在70以上,这时候如果你一看到RSI>70就卖出,结果股票又涨了30%,你会非常懊恼。
反过来也一样,下跌趋势中RSI可能连续在30以下,你一看到RSI<30就买入,结果股票又跌了20%。
如何识别真假信号?看三点:
def analyze_rsi_signal(df, index):
"""
综合判断RSI信号的真伪
参数: df为包含'date','close','rsi','volume'的数据框,index为当前数据索引
返回: 信号建议(买入/卖出/观望)和理由
"""
rsi = df.loc[index, 'rsi']
price = df.loc[index, 'close']
volume = df.loc[index, 'volume']
# 获取前几天的数据
prev_rsies = df.loc[max(0, index-5):index-1, 'rsi'].values
prev_prices = df.loc[max(0, index-5):index-1, 'close'].values
prev_volumes = df.loc[max(0, index-5):index-1, 'volume'].values
# 判断趋势方向
trend = 'UP' if price > np.mean(prev_prices) else 'DOWN'
# 分析RSI变化
rsi_change = rsi - np.mean(prev_rsies) if len(prev_rsies) > 0 else 0
result = {
'action': 'HOLD',
'reason': '',
'rsi': rsi,
'trend': trend
}
# 超卖区域判断
if rsi < 30:
if trend == 'DOWN':
# 下跌趋势中的超卖,可能是假信号
result['action'] = 'WAIT'
result['reason'] = f'RSI超卖({rsi:.1f})但处于下跌趋势中,可能是假信号,建议观望'
elif rsi_change > 0:
# 超卖且RSI开始回升,可能是真信号
result['action'] = 'BUY'
result['reason'] = f'RSI超卖({rsi:.1f})且开始回升,可能触底反弹'
else:
result['action'] = 'WAIT'
result['reason'] = f'RSI超卖({rsi:.1f})但仍在下降,建议等待确认'
# 超买区域判断
elif rsi > 70:
if trend == 'UP':
# 上涨趋势中的超买,可能是假信号
result['action'] = 'WAIT'
result['reason'] = f'RSI超买({rsi:.1f})但处于上涨趋势中,可能还有空间'
elif rsi_change < 0:
result['action'] = 'SELL'
result['reason'] = f'RSI超买({rsi:.1f})且开始回落,可能见顶'
else:
result['action'] = 'WAIT'
result['reason'] = f'RSI超买({rsi:.1f})但仍在上升,建议谨慎'
# RSI在正常区域
else:
result['action'] = 'HOLD'
result['reason'] = f'RSI处于正常区域({rsi:.1f}),继续观望'
return result
五、常见陷阱和应对策略
陷阱一:只用RSI单一指标
错误做法:RSI<30就买,RSI>70就卖。
正确做法:RSI至少配合趋势判断和成交量一起使用。比如:
- RSI<30 + 股价在上升趋势中 + 成交量萎缩 → 可能是假信号,谨慎买入
- RSI<30 + 股价在下降趋势中 + 成交量放大 → 可能还有下跌空间,观望
陷阱二:不看时间周期
错误做法:用日线的RSI<30信号去操作短线,或者用周线的RSI>70去判断日线级别的买卖点。
正确做法:
- 短线交易者:看日线RSI(周期14),配合60分钟RSI做辅助
- 中线投资者:看周线RSI(周期14),配合日线RSI做入场点
- 长线投资者:看月线RSI,把握大级别趋势
陷阱三:忽略市场环境
错误做法:在牛市里用RSI超买信号卖出,结果卖飞了;在熊市里用RSI超卖信号买入,结果被套了。
正确做法:
- 牛市环境:RSI超买信号谨慎看空,RSI超卖信号积极看多
- 熊市环境:RSI超买信号积极看空,RSI超卖信号谨慎看多
- 震荡市环境:RSI超买超卖信号最可靠
陷阱四:把RSI当圣杯
错误做法:认为RSI是万能指标,只看RSI不管其他。
正确做法:RSI是辅助工具,不是决策的唯一依据。好的交易者会综合:
- K线形态(支撑位、阻力位)
- 成交量变化
- 基本面信息
- 市场情绪
- 其他技术指标(MACD、KDJ、布林带等)
六、一个完整的实战框架
把以上内容整合成一个可执行的策略框架:
class RSIStrategy:
"""
RSI交易策略框架
结合趋势、背离、成交量等多维度判断
"""
def __init__(self, df, rsi_period=14, ob_threshold=70, os_threshold=30):
"""
初始化策略
df: 包含'date','close','volume'列的DataFrame
rsi_period: RSI计算周期
ob_threshold: 超买阈值
os_threshold: 超卖阈值
"""
self.df = df.copy()
self.rsi_period = rsi_period
self.ob_threshold = ob_threshold
self.os_threshold = os_threshold
# 计算RSI
self.df['rsi'] = calculate_rsi(self.df['close'], period=rsi_period)
# 计算均线(用于趋势判断)
self.df['ma20'] = self.df['close'].rolling(window=20).mean()
self.df['ma50'] = self.df['close'].rolling(window=50).mean()
# 计算成交量变化
self.df['vol_ma20'] = self.df['volume'].rolling(window=20).mean()
self.df['vol_ratio'] = self.df['volume'] / self.df['vol_ma20']
# 计算趋势方向
self.df['trend'] = 'NEUTRAL'
self.df.loc[self.df['close'] > self.df['ma20'], 'trend'] = 'UP'
self.df.loc[self.df['close'] < self.df['ma20'], 'trend'] = 'DOWN'
def generate_signal(self, index):
"""
生成交易信号
返回: (action, confidence, reason)
action: BUY/SELL/HOLD/WAIT
confidence: 0-1之间的信心度
reason: 信号理由
"""
row = self.df.iloc[index]
prev_rows = self.df.iloc[max(0, index-5):index]
rsi = row['rsi']
trend = row['trend']
vol_ratio = row['vol_ratio']
price = row['close']
ma20 = row['ma20']
ma50 = row['ma50']
# 基础信号
if rsi < self.os_threshold:
base_action = 'BUY'
base_confidence = 0.5
base_reason = f'RSI超卖({rsi:.1f}<{self.os_threshold})'
elif rsi > self.ob_threshold:
base_action = 'SELL'
base_confidence = 0.5
base_reason = f'RSI超买({rsi:.1f}>{self.ob_threshold})'
else:
base_action = 'HOLD'
base_confidence = 0.3
base_reason = f'RSI正常({rsi:.1f})'
# 趋势过滤
if base_action == 'BUY' and trend == 'DOWN':
base_confidence *= 0.6 # 下降趋势中超卖信号减弱
base_action = 'WAIT'
base_reason += ',但处于下降趋势,信号减弱'
elif base_action == 'SELL' and trend == 'UP':
base_confidence *= 0.6 # 上升趋势中超买信号减弱
base_action = 'WAIT'
base_reason += ',但处于上升趋势,信号减弱'
# 成交量确认
if base_action == 'BUY' and vol_ratio < 0.5:
# 成交量极度萎缩,可能是底部
base_confidence += 0.2
base_reason += ',成交量萎缩,可能有支撑'
elif base_action == 'SELL' and vol_ratio > 2.0:
# 成交量异常放大,可能见顶
base_confidence += 0.2
base_reason += ',成交量放大,可能见顶'
# 均线趋势确认
if ma20 > ma50:
# 中期趋势向上
if base_action == 'BUY':
base_confidence += 0.1
elif base_action == 'SELL':
base_confidence *= 0.8
elif ma20 < ma50:
# 中期趋势向下
if base_action == 'SELL':
base_confidence += 0.1
elif base_action == 'BUY':
base_confidence *= 0.8
# 最终调整
confidence = min(max(base_confidence, 0.1), 0.95)
return base_action, confidence, base_reason
def backtest(self, start_index=14, end_index=None):
"""
简单回测
"""
if end_index is None:
end_index = len(self.df)
results = []
position = 0 # 0=空仓, 1=持仓
cash = 100000 # 初始资金10万
shares = 0
for i in range(start_index, end_index):
action, confidence, reason = self.generate_signal(i)
price = self.df.iloc[i]['close']
if action == 'BUY' and position == 0:
# 买入
shares = int(cash / price * 0.95) # 留5%手续费
cash -= shares * price
position = 1
results.append({'date': self.df.iloc[i]['date'],
'action': 'BUY', 'price': price,
'shares': shares, 'cash': cash})
elif action == 'SELL' and position == 1:
# 卖出
cash += shares * price * 0.995 # 扣0.5%手续费
shares = 0
position = 0
results.append({'date': self.df.iloc[i]['date'],
'action': 'SELL', 'price': price,
'shares': shares, 'cash': cash})
# 最终清算
if position == 1:
cash += shares * self.df.iloc[-1]['close'] * 0.995
shares = 0
position = 0
total_value = cash
profit = total_value - 100000
profit_rate = profit / 100000 * 100
return {
'trades': len(results),
'final_value': total_value,
'profit': profit,
'profit_rate': profit_rate,
'results': results
}
# 使用示例
# strategy = RSIStrategy(df)
# result = strategy.backtest()
# print(f"策略回测结果: 收益率 {result['profit_rate']:.2f}%")
七、给新手的几点真心话
RSI不是万能钥匙,它只是一个辅助工具。真正赚钱的交易者,是那些把多个工具组合起来用的人。
不要追求100%准确的信号。即使是最好的策略,成功率达到60%就已经很优秀了。关键在于盈亏比——亏的时候亏得少,赚的时候赚得多。
模拟盘先练手。在实盘之前,先用模拟账户跑一段时间RSI策略,感受它的真实表现,再决定是否实盘。
止损永远第一。即使RSI给了买入信号,也要设好止损位(比如买入价下方3-5%),防止判断错误时造成大损失。
记录每一次交易。把每次使用RSI的信号、当时的市场环境、最终的结果都记录下来,定期复盘,你会发现自己犯的错误模式,逐渐形成自己的判断体系。
最后送你一句话:技术指标是船,市场认知是舵,风险控制是帆。 三者配合,才能在海浪中航行得更稳更远。
希望这篇文章能帮你建立起对RSI的正确认识。市场永远在那里,机会也永远会有,但前提是——你要先活下来。