根据rsi值[Pandas,Numpy]派生列信号



我想创建信号

其中rsi>80信号列值为sell,且

其中rsi<20信号列值为买入,且

要对重叠信号进行滤波

已使用np.where

创建列low = where rsi<20 1 for true 0 for false

high = where rsi>80 -1为真0为假

low+high = low和high列的和,我们可以将low+high值1表示买,-1表示卖,0表示非,

但问题是我们得到了重叠信号,如果我们将-1映射为卖出,1映射为买入

和使用diff()我无法生成没有重叠的信号

RSI LOW HIGH  LOW+HIGH
79  0   0     0
80  0   0     0
80  0   0     0
81  0   -1    -1
60  0   0     0
19  1   0     1
19  1   0     1

Require Outout
RSI LOW HIGH  LOW+HIGH Signal 
79  0   0     0        0 
80  0   0     0        0   
80  0   0     0        0   
81  0   -1    -1       SELL  
60  0   0     0        0
19  1   0     1        BUY
19  1   0     1        0
30  0   0     0        0
  1. 计算数据的RSI值

  2. 根据RSI值创建两列布尔值:一列用于RSI小于20时,另一列用于RSI大于80时。例如:


df['low'] = np.where(df['rsi'] < 20, 1, 0)
df['high'] = np.where(df['rsi'] > 80, -1, 0)
  1. 将低列和高列相加得到信号列。值为1表示"购买";信号,-1表示"卖出";信号,0表示无信号。例如:

df['signal'] = df['low'] + df['high']
  1. 使用diff()方法计算信号列中连续值的差值。这将告诉你信号随时间的变化。例如:

df['signal_diff'] = df['signal'].diff()
  1. 新建列final_signal,去掉重叠的信号。当信号列大于0且signal_diff列大于等于0时,将值设为1(buy);当信号列小于0且signal_diff列小于等于0时,将值设为-1(sell)。否则,该值设为0(无信号)。例如:

df['final_signal'] = np.where((df['signal'] > 0) & (df['signal_diff'] >= 0), 1,
np.where((df['signal'] < 0) & (df['signal_diff'] <= 0), -1, 0))

完整的示例

import pandas as pd
import numpy as np
# Step 1: Calculate RSI values for the data
df = pd.DataFrame({'close': [100, 110, 90, 120, 130, 140, 110, 90, 80, 100, 120]})
n = 3
delta = df['close'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(n).mean()
avg_loss = loss.rolling(n).mean()
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))
df['rsi'] = rsi
# Step 2: Create boolean columns for low and high RSI values
df['low'] = np.where(df['rsi'] < 20, 1, 0)
df['high'] = np.where(df['rsi'] > 80, -1, 0)
# Step 3: Sum low and high columns to get signal column
df['signal'] = df['low'] + df['high']
# Step 4: Calculate difference between consecutive signal values
df['signal_diff'] = df['signal'].diff()
# Step 5: Remove overlapping signals
df['final_signal'] = np.where((df['signal'] > 0) & (df['signal_diff'] >= 0), 1,
np.where((df['signal'] < 0) & (df['signal_diff'] <= 0), -1, 0))
print(df)
close        rsi  low  high  signal  signal_diff  final_signal
0     100        NaN    0     0       0          NaN             0
1     110        NaN    0     0       0          0.0             0
2      90  17.391304    1     0       1          1.0             1
3     120  75.000000    0    -1      -1         -2.0             0
4     130  80.000000    0    -1      -1          0.0             0
5     140  85.714286    0    -1      -1          0.0             0
6     110  63.636364    0     0       0          1.0             0
7      90  34.782609    0     0       0          0.0             0
8      80  25.000000    1     0       1          1.0             1
9     100  54.545455    0     0       0         -1.0             0
10    120  84.210526    0    -1      -1         -1.0             0