我想创建信号列
其中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
-
计算数据的RSI值
-
根据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表示"卖出";信号,0表示无信号。例如:
df['signal'] = df['low'] + df['high']
- 使用
diff()
方法计算信号列中连续值的差值。这将告诉你信号随时间的变化。例如:
df['signal_diff'] = df['signal'].diff()
- 新建列
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