Calculating RSI in Python

2024/11/15 6:10:24

I am trying to calculate RSI on a dataframe

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     20RSI_length = 7

Now, I am stuck in calculating "Avg Gain". The logic for average gain here is for first average gain at index 6 will be mean of "Gain" for RSI_length periods. For consecutive "Avg Gain" it should be

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

I tried the following but does not work as expected

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))

The output of this code is:

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

Desired output is:

    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

Answer

(edited)

Here's an implementation of your formula.

RSI_LENGTH = 7rolling_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

The result is:

    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
https://en.xdnf.cn/q/119687.html

Related Q&A

Pandas groupwise percentage

How can I calculate a group-wise percentage in pandas?similar to Pandas: .groupby().size() and percentages or Pandas Very Simple Percent of total size from Group by I want to calculate the percentage…

How to deal with large json files (flattening it to tsv) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.Want to improve this question? Add details and clarify the problem by editing this post.Closed 3 years ago.Improve…

How can I find max number among numbers in this code?

class student(object):def student(self):self.name=input("enter name:")self.stno=int(input("enter stno:"))self.score=int(input("enter score:"))def dis(self):print("nam…

Assert data type of the values of a dict when they are in a list

How can I assert the values of my dict when they are in a list My_dict = {chr7: [127479365, 127480532], chr8: [127474697, 127475864], chr9: [127480532, 127481699]}The code to assert this assert all(isi…

Loading tiff images in fiftyone using ipynp

I am trying to load tiff images using fiftyone and python in ipynb notebook, but it just doesnt work. Anyone knows how to do it?

Regular expression to match the word but not the word inside other strings

I have a rich text like Sample text for testing:<a href="http://www.baidu.com" title="leoshi">leoshi</a>leoshi for details balala... Welcome to RegExr v2.1 by gskinner.c…

Make one image out of avatar and frame in Python with Pillow

If I haveandneed to getdef create_avatar(username):avatar, frame, avatar_id = get_avatar(username)if avatar is not None and frame is not None:try:image = Image.new("RGBA", size)image.putalpha…

Could not broadcast input array from shape (1285) into shape (1285, 5334)

Im trying to follow some example code provided in the documentation for np.linalg.svd in order to compare term and document similarities following an SVD on a TDM matrix. Heres what Ive got:results_t =…

Python URL Stepping Returns Only First Page Results

Any help with the below code would be appreciated. I have checked the results of h and g using print to verify that they are incrementing the url properly, but the program seems to be only repeating th…

Text processing to find co-occurences of strings

I need to process a series of space separated strings i.e. text sentences. ‘Co-occurrence’ is when two tags (or words) appear on the same sentence. I need to list all the co-occurring words when they…