【问题标题】:Calculating RSI in Python在 Python 中计算 RSI
【发布时间】:2023-03-13 20:29:02
【问题描述】:

我正在尝试在数据帧上计算 RSI

df = pd.DataFrame({"Close": [100,101,102,103,104,105,106,105,103,102,103,104,103,105,106,107,108,106,105,107,109]})

df["Change"] = df["Close"].diff()

df["Gain"] = np.where(df["Change"]>0,df["Change"],0)

df["Loss"] = np.where(df["Change"]<0,abs(df["Change"]),0 )
df["Index"] = [x for x in range(len(df))]

print(df)

      Close  Change  Gain  Loss  Index
0     100     NaN   0.0   0.0      0
1     101     1.0   1.0   0.0      1
2     102     1.0   1.0   0.0      2
3     103     1.0   1.0   0.0      3
4     104     1.0   1.0   0.0      4
5     105     1.0   1.0   0.0      5
6     106     1.0   1.0   0.0      6
7     105    -1.0   0.0   1.0      7
8     103    -2.0   0.0   2.0      8
9     102    -1.0   0.0   1.0      9
10    103     1.0   1.0   0.0     10
11    104     1.0   1.0   0.0     11
12    103    -1.0   0.0   1.0     12
13    105     2.0   2.0   0.0     13
14    106     1.0   1.0   0.0     14
15    107     1.0   1.0   0.0     15
16    108     1.0   1.0   0.0     16
17    106    -2.0   0.0   2.0     17
18    105    -1.0   0.0   1.0     18
19    107     2.0   2.0   0.0     19
20    109     2.0   2.0   0.0     20


RSI_length = 7

现在,我一直在计算“平均增益”。此处平均增益的逻辑是索引 6 处的第一个平均增益将是 RSI_length 周期的“增益”的平均值。对于连续的“平均增益”,它应该是

(Previous Avg Gain * (RSI_length - 1) + "Gain") / RSI_length 

我尝试了以下方法,但没有按预期工作

df["Avg Gain"] = np.nan
df["Avg Gain"] = np.where(df["Index"]==(RSI_length-1),df["Gain"].rolling(window=RSI_length).mean(),\
                          np.where(df["Index"]>(RSI_length-1),(df["Avg Gain"].iloc[df["Index"]-1]*(RSI_length-1)+df["Gain"]) / RSI_length,np.nan))

这段代码的输出是:

print(df)

     Close  Change  Gain  Loss  Index  Avg Gain
0     100     NaN   0.0   0.0      0       NaN
1     101     1.0   1.0   0.0      1       NaN
2     102     1.0   1.0   0.0      2       NaN
3     103     1.0   1.0   0.0      3       NaN
4     104     1.0   1.0   0.0      4       NaN
5     105     1.0   1.0   0.0      5       NaN
6     106     1.0   1.0   0.0      6  0.857143
7     105    -1.0   0.0   1.0      7       NaN
8     103    -2.0   0.0   2.0      8       NaN
9     102    -1.0   0.0   1.0      9       NaN
10    103     1.0   1.0   0.0     10       NaN
11    104     1.0   1.0   0.0     11       NaN
12    103    -1.0   0.0   1.0     12       NaN
13    105     2.0   2.0   0.0     13       NaN
14    106     1.0   1.0   0.0     14       NaN
15    107     1.0   1.0   0.0     15       NaN
16    108     1.0   1.0   0.0     16       NaN
17    106    -2.0   0.0   2.0     17       NaN
18    105    -1.0   0.0   1.0     18       NaN
19    107     2.0   2.0   0.0     19       NaN
20    109     2.0   2.0   0.0     20       NaN

期望的输出是:

    Close  Change   Gain  Loss  Index  Avg Gain
0     100      NaN     0     0      0       NaN
1     101      1.0     1     0      1       NaN
2     102      1.0     1     0      2       NaN
3     103      1.0     1     0      3       NaN
4     104      1.0     1     0      4       NaN
5     105      1.0     1     0      5       NaN
6     106      1.0     1     0      6  0.857143
7     105     -1.0     0     1      7  0.734694
8     103     -2.0     0     2      8  0.629738
9     102     -1.0     0     1      9  0.539775
10    103      1.0     1     0     10  0.605522
11    104      1.0     1     0     11  0.661876
12    103     -1.0     0     1     12  0.567322
13    105      2.0     2     0     13  0.771990
14    106      1.0     1     0     14  0.804563
15    107      1.0     1     0     15  0.832483
16    108      1.0     1     0     16  0.856414
17    106     -2.0     0     2     17  0.734069
18    105     -1.0     0     1     18  0.629202
19    107      2.0     2     0     19  0.825030
20    109      2.0     2     0     20  0.992883

【问题讨论】:

  • 您确定公式“(Previous Avg Gain * (RSI_length - 1) + "Gain") / RSI_length" 对 RSI 是正确的吗?它似乎没有考虑“损失”。
  • @Roy2012 这不是最终的 rsi 值,此公式用于计算平均增益而不是 RSI
  • 我相信您的实现不起作用,因为在每个单元格中,它都会尝试查看前一个单元格的值(索引 -1) - 在计算前一个单元格的值之前。跨度>
  • 它仍然应该适用于索引 7
  • 嗯。我相信罪魁祸首是表达式 df["Avg Gain"].iloc[df["Index"]-1]。即使它将所有内容都移动了 1,但索引保持不变。也就是说,您得到的不是索引为 0-20 的序列和索引为 6 的值,而是索引为 20-0-19 的序列,索引值为 6。

标签: python numpy dataframe trading


【解决方案1】:

(已编辑)

这是您的公式的实现。

RSI_LENGTH = 7

rolling_gain = df["Gain"].rolling(RSI_LENGTH).mean()
df.loc[RSI_LENGTH-1, "RSI"] = rolling_gain[RSI_LENGTH-1]

for inx in range(RSI_LENGTH, len(df)):
    df.loc[inx, "RSI"] = (df.loc[inx-1, "RSI"] * (RSI_LENGTH -1) + df.loc[inx, "Gain"]) / RSI_LENGTH

结果是:

    Close  Change  Gain  Loss  Index       RSI
0     100     NaN   0.0   0.0      0       NaN
1     101     1.0   1.0   0.0      1       NaN
2     102     1.0   1.0   0.0      2       NaN
3     103     1.0   1.0   0.0      3       NaN
4     104     1.0   1.0   0.0      4       NaN
5     105     1.0   1.0   0.0      5       NaN
6     106     1.0   1.0   0.0      6  0.857143
7     105    -1.0   0.0   1.0      7  0.734694
8     103    -2.0   0.0   2.0      8  0.629738
9     102    -1.0   0.0   1.0      9  0.539775
10    103     1.0   1.0   0.0     10  0.605522
11    104     1.0   1.0   0.0     11  0.661876
12    103    -1.0   0.0   1.0     12  0.567322
13    105     2.0   2.0   0.0     13  0.771990
14    106     1.0   1.0   0.0     14  0.804563
15    107     1.0   1.0   0.0     15  0.832483
16    108     1.0   1.0   0.0     16  0.856414
17    106    -2.0   0.0   2.0     17  0.734069
18    105    -1.0   0.0   1.0     18  0.629202
19    107     2.0   2.0   0.0     19  0.825030
20    109     2.0   2.0   0.0     20  0.992883

【讨论】:

  • 嗨,我已经编辑了我的输出,因为我在之前的输出中将 RSI_length 设为 14 而不是 7。现在更新了。
  • 您显示的是 RSI,还是部分公式的结果?正如你上面提到的,它们是不一样的。
  • 您的实现仅适用于索引 7 处的值,但不适用于后面的部分。对于索引 8,我想要 (0.734694 * 6 + 0)/7 = 0.629738 并且您的解决方案采用相同的输出。当每一行都被填满时,它应该更新之前的增益
  • 这里提到的公式是针对 RSI 的平均增益部分,而不是最终的 RSI
  • @jerzrael 如果你能帮我解决这个问题
猜你喜欢
  • 2016-11-23
  • 2017-11-26
  • 1970-01-01
  • 2018-10-16
  • 2020-07-23
  • 2019-11-22
  • 2021-07-22
  • 1970-01-01
  • 2022-11-22
相关资源
最近更新 更多