基于RSI值生成无重叠Signal列的Pandas/Numpy实现问题
解决RSI信号重叠问题的实现方案
问题分析
你遇到的核心问题是连续触发相同信号(比如连续多日RSI<20都标记BUY),以及数据中可能存在的RSI同时<20和>80的异常情况。下面给出两种常用解决思路,分别对应字符串型和数值型信号场景。
方案1:生成字符串型过滤后信号
假设你的DataFrame已包含RSI列,执行以下代码:
import pandas as pd import numpy as np # 1. 生成初始信号,容错处理异常RSI值(理论上RSI范围0-100) df['Signal'] = np.where( df['RSI'] > 80, 'SELL', np.where(df['RSI'] < 20, 'BUY', np.nan) ) # 2. 过滤连续重复信号:仅保留信号首次出现的行,后续相同信号置为空 df['Signal'] = df['Signal'].where(df['Signal'] != df['Signal'].shift(1))
效果:连续多日RSI<20时,仅第一行标记BUY,后续行信号为空;直到RSI回到20-80区间后再次跌破20,才会重新标记BUY。
方案2:生成数值型过滤后信号
如果需要用数值(1=BUY,-1=SELL,0=无信号)表示信号:
# 1. 生成初始数值信号 df['Signal_num'] = np.where( df['RSI'] > 80, -1, np.where(df['RSI'] < 20, 1, 0) ) # 2. 过滤连续重复的非0信号:仅保留信号发生变化的行,其余非0信号置为0 df['Signal_num'] = np.where( (df['Signal_num'] != 0) & (df['Signal_num'].diff() != 0), df['Signal_num'], 0 ) # 处理第一行diff()结果为NaN的情况 df['Signal_num'] = df['Signal_num'].fillna(0)
效果:连续触发的相同数值信号会被置为0,仅保留信号首次触发和反向切换的行。
关键逻辑说明
- 互斥信号处理:通过嵌套
np.where确保一行不会同时被标记为BUY和SELL,同时过滤异常RSI值。 - 去重逻辑:利用
shift()对比当前行与前一行的信号,或用diff()计算信号变化量,仅保留信号发生变化的行,彻底解决连续重复信号问题。
内容的提问来源于stack exchange,提问作者SARVAGYA
相关产品推荐
相关产品推荐

