Calculate RSI indicator from pandas DataFrame?

前端 未结 3 1784
甜味超标
甜味超标 2021-01-02 06:36

My problem

I tried many libraries on Github but all of them did not produce matching results for TradingView so I followed the fo

3条回答
  •  醉话见心
    2021-01-02 06:58

    Here is an option.

    I will be touching only on your second bullet

    # libraries required
    import pandas as pd
    import numpy as np
    
    # create dataframe
    df = pd.DataFrame({'close':[4724.89, 4378.51,6463.00,9838.96,13716.36,10285.10,
                              10326.76,6923.91,9246.01,7485.01,6390.07,7730.93,
                              7011.21,6626.57,6371.93,4041.32,3702.90,3434.10,
                              3813.69,4103.95,5320.81,8555.00,10854.10]})
    
    df['change'] = df['close'].diff(1) # Calculate change
    
    # calculate gain / loss from every change
    df['gain'] = np.select([df['change']>0, df['change'].isna()], 
                           [df['change'], np.nan], 
                           default=0) 
    df['loss'] = np.select([df['change']<0, df['change'].isna()], 
                           [-df['change'], np.nan], 
                           default=0)
    
    # create avg_gain /  avg_loss columns with all nan
    df['avg_gain'] = np.nan 
    df['avg_loss'] = np.nan
    
    n = 14 # what is the window
    
    # keep first occurrence of rolling mean
    df['avg_gain'][n] = df['gain'].rolling(window=n).mean().dropna().iloc[0] 
    df['avg_loss'][n] = df['loss'].rolling(window=n).mean().dropna().iloc[0]
    # Alternatively
    df['avg_gain'][n] = df.loc[:n, 'gain'].mean()
    df['avg_loss'][n] = df.loc[:n, 'loss'].mean()
    
    # This is not a pandas way, looping through the pandas series, but it does what you need
    for i in range(n+1, df.shape[0]):
        df['avg_gain'].iloc[i] = (df['avg_gain'].iloc[i-1] * (n - 1) + df['gain'].iloc[i]) / n
        df['avg_loss'].iloc[i] = (df['avg_loss'].iloc[i-1] * (n - 1) + df['loss'].iloc[i]) / n
    
    # calculate rs and rsi
    df['rs'] = df['avg_gain'] / df['avg_loss']
    df['rsi'] = 100 - (100 / (1 + df['rs'] ))
    

提交回复
热议问题