Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stoch RSI is broken #203

Closed
MaticConradi opened this issue Apr 27, 2018 · 72 comments
Closed

Stoch RSI is broken #203

MaticConradi opened this issue Apr 27, 2018 · 72 comments

Comments

@MaticConradi
Copy link

MaticConradi commented Apr 27, 2018

For some reason I'm getting completely wrong numbers.

fastk, fastd = talib.STOCHRSI(candles.close.values, timeperiod=14, fastk_period=3, fastd_period=3)

Any ideas why it might not work?

@mrjbq7
Copy link
Collaborator

mrjbq7 commented Apr 27, 2018 via email

@MaticConradi
Copy link
Author

Everything else works. RSI is correct. I feed in BTC/USD data from CCXT library. They are way off from what's actually going on.

@MaticConradi
Copy link
Author

MaticConradi commented Apr 27, 2018

Here's an example (BTC/USD [XBTUSD] from BitMEX):

5min close value candle data (last 20 candles):
[9205, 9222.5, 9226.5, 9235, 9227.5, 9228.5, 9226, 9234.5, 9241, 9237, 9255, 9249, 9241.5, 9230.5, 9256.5, 9255.5, 9254.5, 9268, 9248, 9258]

D:
[37.57962284, 70.91295617, 92.11272073, 100, 82.41736032, 57.1553351, 23.82200176, 41.40464144, 66.66666667, 85.20923078, 85.20923078, 76.03295412, 57.49039001, 24.15705667, 33.33333333, 65.5339434, 65.5339434, 65.5339434, 33.33333333, 50.08188329]

K:
[76.33816218, 100, 100, 100, 47.25208097, 24.21392432, 0, 100, 100, 55.62769234, 100, 72.47117002, 0, 0, 100, 96.60183021, 0, 100, 0, 50.24564987]

The fastK is way off, same for fastD

@MaticConradi
Copy link
Author

Any updates? Do you need aditional info/data?

@MaticConradi
Copy link
Author

I've been trying to get it working but came to the conclusion that Stochastic (talib.STOCH(...)) doesn't work either. RSI is 100% correct, so is the price I get from the exchange.

@mrjbq7
Copy link
Collaborator

mrjbq7 commented May 5, 2018

Why not try and get a pure python version working with expected output and then we can figure out what you're looking for. Seems like it's more likely you are defining it differently than TA-Lib.

https://sourceforge.net/p/ta-lib/code/HEAD/tree/trunk/ta-lib/c/src/ta_func/ta_STOCHRSI.c

This might be a little different than you expect, and I didn't really debug or test it, but posting here for discussion.

import numpy as np
import pandas as pd


def STOCH(h, l, c, fastk_period, slowk_period, slowd_period):
    hh = pd.rolling_max(h, fastk_period, min_periods=fastk_period)
    ll = pd.rolling_min(l, fastk_period, min_periods=fastk_period)
    fast_k = 100 * (c - ll) / (hh - ll)
    slow_k = pd.ewma(fast_k, span=slowk_period, min_periods=slowk_period)
    slow_d = pd.ewma(slow_k, span=slowd_period, min_periods=slowd_period)
    return slow_k, slow_d

def RS(c, n):
    diffs = pd.rolling_apply(c, 2, lambda x: x[-1] - x[0], min_periods=1)
    ups = pd.rolling_apply(diffs, n, lambda x: np.sum(x[x > 0]), min_periods=n)
    downs = pd.rolling_apply(diffs, n, lambda x: -np.sum(x[x < 0]), min_periods=n)
    rs = ups / downs
    rs[downs == 0] = 0
    return rs

def RSI(c, n):
    rs = RS(c, n)
    rsi = 100 - (100 / (1 + rs))
    return rsi

def STOCHRSI(c, timeperiod, fastk_period, fastd_period):
    rsi = RSI(c, timeperiod)
    return STOCH(rsi, rsi, rsi, timeperiod, fastk_period, fastd_period)

I should also note, you can try the TulipIndicators and see if that gives you results you expect.

@MaticConradi
Copy link
Author

I got it working by using Tulip indicators and calling fastk, fastd = ti.stoch(rsi, rsi, rsi, 14, 3, 3), still can't get it to work with TA-Lib though.

@Sungod3000
Copy link

I have a similar issue with the normal RSI. I can recognize the ups and downs but the magnitudes are quite different. Do you mind sharing your RSI implementation?

@mrjbq7
Copy link
Collaborator

mrjbq7 commented Oct 4, 2018

You can browse the underlying TA-Lib C library if you want:

https://github.com/TA-Lib/ta-lib/blob/master/src/ta_func/ta_RSI.c

If anyone wants to provide a test case for what they expect and what they get, I could look into it. I suspect a definitional difference, either smoothing related or similar.

@Sungod3000
Copy link

I looked into the definition but that goes over my head. I only recently started programming.
I also looked into smoothing and but from the RSI settings on the exchanges I can see no smoothing function.

The code here is supposed to fetch the last 900 hours of data for BTC-EUR pairing on coinbase (no api-keys required) and plot it.
I also tested the "stockstats" lib with the same result and I use tradingview.com for compare my RSI values.

TALIB-RSI.zip

`import pandas as pd
import stockstats
import json
import coinbase
import matplotlib.pyplot as plt
import requests as req
import numpy as np
import mpl_finance
import datetime as dt
import talib as ta
import time

#initialize the dates and variables
list_a = []
start_time = dt.datetime.strptime("2018-10-04",'%Y-%m-%d')
end_time = dt.datetime.strptime("2000-01-01",'%Y-%m-%d')
minus_300 = -288 #the coinbase api allows max 300 values per call
i = 0
result_array = np.empty([0, 6])

while True:
print(i)
end_time = start_time
start_time = start_time + dt.timedelta(hours=minus_300)

start_time = start_time.strftime('%Y-%m-%d') #converts timestamp to normal time for the link to work as a string
end_time = end_time.strftime('%Y-%m-%d')

#these variables build the url for the api call
coinbase_url_1 = "https://api.pro.coinbase.com/products/BTC-EUR/candles?granularity="
granularity = "3600"
coinbase_url_2 = "&start="
coinbase_url_3 = "&end="
print(coinbase_url_1+granularity+coinbase_url_2+start_time+coinbase_url_3+end_time)

url_full = coinbase_url_1+granularity+coinbase_url_2+start_time+coinbase_url_3+end_time
api_call = req.get(url_full)
data = json.loads(api_call.content.decode('utf-8')) #json object to python list
candles = np.array(data) #python list to numpy array
print(candles.shape)

result_array = np.append(result_array, candles, axis=0) #appends each new datablock to the existing array
#print(result_array)
print("result_shape: ", result_array.shape)
print("length: ",len(result_array))

#print(type(candles))
#print("length: ",len(candles))

start_time = dt.datetime.strptime(start_time,'%Y-%m-%d') #converts timeformat back to work with timedelta
end_time = dt.datetime.strptime(end_time,'%Y-%m-%d')

i = i+1
time.sleep(0.35) #3 api calls per sec
if i == 3:
    break

normal_time = np.vectorize(dt.datetime.fromtimestamp)(result_array[:,0])
#normal_time = dt.datetime.strptime(result_array[:,0],'%Y-%m-%d')
#print(normal_time)
#open_data = candles[:,3]
#high_data = candles[:,2]
#low_data = candles[:,1]
close_data = result_array[:,4]
#print("close_data: ",close_data)
print("length: ",len(close_data))

rsi_graph = ta.RSI(close_data, timeperiod=14)
#print (rsi_graph)

print(min(normal_time), max(normal_time))

plt.plot(normal_time, rsi_graph)
plt.xticks(rotation=45)
plt.ylim(0, 100)
plt.xlabel('time (days)')
plt.ylabel('RSI')
plt.hlines(y=70, xmin=min(normal_time), xmax=max(normal_time), linestyles='dashed')
plt.hlines(y=30, xmin=min(normal_time), xmax=max(normal_time), linestyles='dashed')
plt.show()

`

@alextousss
Copy link

Hello,

I'm having the same problem over here ! Is there any progress on the issue ?

Alex

@Sungod3000
Copy link

yes, turned out that the way i created the array for calculating the rsi was in reverse order.
after i reversed it the rsi looked excatly like i was supposed to

@alextousss
Copy link

I'm using the abstract API, the numbers are nonsensical while normal RSI is giving the good results so I guess I'm not doing anything wrong.
Is there something I can contribute to to help?

@Sungod3000
Copy link

the rsi numbers are nonsensical or the base data?

@pcawthron
Copy link

The code by Sungod3000 above is not showing correctly. This works in Spyder if you have the correct packages installed:

import pandas as pd
import stockstats
import json
import coinbase
import matplotlib.pyplot as plt
import requests as req
import numpy as np
import mpl_finance
import datetime as dt
import talib as ta
import time

#initialize the dates and variables
list_a = []
start_time = dt.datetime.strptime("2018-10-04",'%Y-%m-%d')
end_time = dt.datetime.strptime("2000-01-01",'%Y-%m-%d')
minus_300 = -288 #the coinbase api allows max 300 values per call
i = 0
result_array = np.empty([0, 6])

while True:
    print i
    end_time = start_time
    start_time = start_time + dt.timedelta(hours=minus_300)
    start_time = start_time.strftime('%Y-%m-%d') #converts timestamp to normal time for the link to work as a string
    end_time = end_time.strftime('%Y-%m-%d')
    
    #these variables build the url for the api call
    coinbase_url_1 = "https://api.pro.coinbase.com/products/BTC-EUR/candles?granularity="
    granularity = "3600"
    coinbase_url_2 = "&start="
    coinbase_url_3 = "&end="
    print(coinbase_url_1+granularity+coinbase_url_2+start_time+coinbase_url_3+end_time)
    
    url_full = coinbase_url_1+granularity+coinbase_url_2+start_time+coinbase_url_3+end_time
    api_call = req.get(url_full)
    data = json.loads(api_call.content.decode('utf-8')) #json object to python list
    candles = np.array(data) #python list to numpy array
    print(candles.shape)
    
    result_array = np.append(result_array, candles, axis=0) #appends each new datablock to the existing array
    #print(result_array)
    print("result_shape: ", result_array.shape)
    print("length: ",len(result_array))
    
    #print(type(candles))
    #print("length: ",len(candles))
    
    start_time = dt.datetime.strptime(start_time,'%Y-%m-%d') #converts timeformat back to work with timedelta
    end_time = dt.datetime.strptime(end_time,'%Y-%m-%d')
    
    i = i+1
    time.sleep(0.35) #3 api calls per sec
    if i == 3:
        break
normal_time = np.vectorize(dt.datetime.fromtimestamp)(result_array[:,0])
#normal_time = dt.datetime.strptime(result_array[:,0],'%Y-%m-%d')
#print(normal_time)
#open_data = candles[:,3]
#high_data = candles[:,2]
#low_data = candles[:,1]
close_data = result_array[:,4]
#print("close_data: ",close_data)
print("length: ",len(close_data))

rsi_graph = ta.RSI(close_data, timeperiod=14)
#print (rsi_graph)

print(min(normal_time), max(normal_time))

plt.plot(normal_time, rsi_graph)
plt.xticks(rotation=45)
plt.ylim(0, 100)
plt.xlabel('time (days)')
plt.ylabel('RSI')
plt.hlines(y=70, xmin=min(normal_time), xmax=max(normal_time), linestyles='dashed')
plt.hlines(y=30, xmin=min(normal_time), xmax=max(normal_time), linestyles='dashed')
plt.show()

i.e.

image

@Sungod3000
Copy link

yes in order to make that work you need to reverse -> "close_data [::-1]"

@alextousss
Copy link

the rsi numbers are nonsensical or the base data?

They're nonsensical on my data (BTC prices from Binance) using Stoch RSI, while they are totally valid with RSI.

Is there any way to help the maintainers figure it out ?

@mrjbq7
Copy link
Collaborator

mrjbq7 commented Nov 28, 2018 via email

@alextousss
Copy link

Hello,

The code where I'm using it is quite huge, I've used the quickfix provided here :

I got it working by using Tulip indicators and calling fastk, fastd = ti.stoch(rsi, rsi, rsi, 14, 3, 3), still can't get it to work with TA-Lib though.

I'll give you a "working" example of the bug as soon as I can, thanks for the help !

Alex

@asimsan
Copy link

asimsan commented Dec 21, 2018

I got it working by using Tulip indicators and calling fastk, fastd = ti.stoch(rsi, rsi, rsi, 14, 3, 3), still can't get it to work with TA-Lib though.

are the values exactly same as in the trading view ? For me it did not work , I want to get the values exactly same as trading view but none of the libraries work,

@h0wXD
Copy link

h0wXD commented Feb 10, 2019

I believe the tradingview one is a different implementation, see tulip issue : TulipCharts/tulipindicators#23
So in order to get your expected output you should follow order of operations found in following pine script: https://www.tradingview.com/script/UueLosr9-Stochastic-RSI/ (which is identical to the tradingview built in one)

smoothK = 3
smoothD = 3
lengthRSI = 14
lengthStoch = 14

rsi1 = rsi(close, lengthRSI)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

@alextousss
Copy link

I believe the tradingview one is a different implementation, see tulip issue : TulipCharts/tulipindicators#23
So in order to get your expected output you should follow order of operations found in following pine script: https://www.tradingview.com/script/UueLosr9-Stochastic-RSI/ (which is identical to the tradingview built in one)

smoothK = 3
smoothD = 3
lengthRSI = 14
lengthStoch = 14

rsi1 = rsi(close, lengthRSI)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

Okay, I understand more. In order to add Stoch RSI to ta-lib, you should add the function to TA-Lib, which you could do following this : https://ta-lib.org/d_misc/how-to_function.html
If I've understood well enough the source code of this wrapper, you'll be able to use your newly created C function in Python using the abstract API.
If you do so, don't hesitate to share your newly created TA-Lib function ;-)
Alex

@alextousss
Copy link

I believe the tradingview one is a different implementation, see tulip issue : TulipCharts/tulipindicators#23
So in order to get your expected output you should follow order of operations found in following pine script: https://www.tradingview.com/script/UueLosr9-Stochastic-RSI/ (which is identical to the tradingview built in one)

smoothK = 3
smoothD = 3
lengthRSI = 14
lengthStoch = 14

rsi1 = rsi(close, lengthRSI)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

I've started to try to implement the function with TA-Lib
Nevertheless, while looking at TA-Lib's Stoch RSI implementation, it seems to be doing exactly what you're telling:

   /* Insert TA function code here. */

   /* Default return values */
   VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
   VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);

   /* Adjust startIdx to account for the lookback period. */
   lookbackSTOCHF  = LOOKBACK_CALL(STOCHF)( optInFastK_Period, optInFastD_Period, optInFastD_MAType );
   lookbackTotal   = LOOKBACK_CALL(RSI)( optInRSI_Period ) + lookbackSTOCHF;

   if( startIdx < lookbackTotal )
      startIdx = lookbackTotal;

   /* Make sure there is still something to evaluate. */
   if( startIdx > endIdx )
   {
      VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
      VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
      return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
   }

   VALUE_HANDLE_DEREF(outBegIdx) = startIdx;

   tempArraySize = (endIdx - startIdx) + 1 + lookbackSTOCHF;

   ARRAY_ALLOC( tempRSIBuffer, tempArraySize );

   retCode = FUNCTION_CALL(RSI)(startIdx-lookbackSTOCHF, 
                                endIdx, 
                                inReal, 
                                optInRSI_Period, 
                                VALUE_HANDLE_OUT(outBegIdx1),
                                VALUE_HANDLE_OUT(outNbElement1), 
                                tempRSIBuffer);

   if( retCode != ENUM_VALUE(RetCode,TA_SUCCESS,Success) || VALUE_HANDLE_GET(outNbElement1) == 0 )
   {
      ARRAY_FREE( tempRSIBuffer );
      VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
      VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
      return retCode;
   }
   
   retCode = FUNCTION_CALL_DOUBLE(STOCHF)(0,
                                          tempArraySize-1,
                                          tempRSIBuffer,
                                          tempRSIBuffer,
                                          tempRSIBuffer,
                                          optInFastK_Period,
                                          optInFastD_Period,
                                          optInFastD_MAType,
                                          VALUE_HANDLE_OUT(outBegIdx2),
                                          outNBElement,
                                          outFastK,
                                          outFastD);
 
   ARRAY_FREE( tempRSIBuffer );

   if( retCode != ENUM_VALUE(RetCode,TA_SUCCESS,Success) || ((int)VALUE_HANDLE_DEREF(outNBElement)) == 0 )
   {
      VALUE_HANDLE_DEREF_TO_ZERO(outBegIdx);
      VALUE_HANDLE_DEREF_TO_ZERO(outNBElement);
      return retCode;
   }

   return ENUM_VALUE(RetCode,TA_SUCCESS,Success);
}

Am I missing something? Would be pleased to make this work, I'll publish my TA-Lib fork when done.
Alex

@sinand99
Copy link

As you can see in the ta-lib source code, it uses fast stoch function after RSI. Just replace it with normal stoch and it works correctly. (I mean same values with Tradingview)

LOOKBACK_CALL(STOCHF) should be LOOKBACK_CALL(STOCH)
and
FUNCTION_CALL_DOUBLE(STOCHF) should be FUNCTION_CALL_DOUBLE(STOCH)

@2803media
Copy link

Any update on this problem. I use

fastk, fastd = talib.STOCHRSI(close, timeperiod=slowperiod, fastk_period=3, fastd_period=3, fastd_matype=0)

But can't get the right numbers...

Thanks for your help

@Bablofil
Copy link

Bablofil commented Jun 1, 2019 via email

@2803media
Copy link

2803media commented Jun 1, 2019

Thanks for your input so I just need to change the fastd_matype=0 to fastd_matype=talib.MA_Type.EMA is that right?

@2803media
Copy link

@sinand99 how do you change those settings? Thanks for your help

@goga1978
Copy link

goga1978 commented Jun 5, 2019

hi)
`rsi = talib.RSI(close, 14)

stochrsi_wk_1, stochrsi_wd_1 = talib.STOCH(rsi, rsi, rsi, fastk_period=14,slowk_period=3,slowk_matype=0,slowd_period=3, slowd_matype=0)`
more or less accurately)

@2803media
Copy link

Finally I use Tulip and it's working very well:

import tulipy as ti

rsi = talib.RSI(close, timeperiod=14)
rsinp = rsi.values
rsinp = rsinp[np.logical_not(np.isnan(rsinp))]
fastk, fastd = ti.stoch(rsinp, rsinp, rsinp, 14, 3, 3)

@Meehir5
Copy link

Meehir5 commented Dec 13, 2020

@bluetyphoon77 you need to congratulate @spyke555 as it was his answer- i tried what he has posted but somehow still now able to get the required values that match tradingview STOCHRSI i commented to check if he could help me by providing a code snippet on how he achieved manual calculation.

@Meehir5
Copy link

Meehir5 commented Dec 13, 2020

For the record, STOCHRSI is not broken, it uses STOCHF instead of STOCH.

On Sun, Dec 13, 2020 at 6:41 AM bluetyphoon77 @.***> wrote: Thanks for your answer Meehir ! Crazyyyyyyyyyyyyyyyy LOL It's like having the wrong tools and needing to build a cathedral LOL I really wonder what is the use of this function then LOL, we should better use tools that work rather than having to wrap it in this, then wrap it in this, then wrap it in this, then wrap it in this ... to have the result we shuld have from the beginning ;) But well done !!! And thanks for sharing ! I'll try it ! But I almost forgot to use this LIB ! Too stupid to not be able to have right values from the start, pretty stupid. But IMPRESSIVE you found your way like ths ! Thanks again — You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub <#203 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAF5AYWSBEKRG424E6HEZ3SUTHCNANCNFSM4E5JBKHQ .

Thank you for the incredible library John - is there a way to force STOCHRSI to consider STOCK instead of STOCHF ?

@mrjbq7
Copy link
Collaborator

mrjbq7 commented Dec 13, 2020

Here is an example:

>>> import talib

>>> import numpy

>>> c = numpy.random.randn(100)

You can print the STOCHRSI for these values:

>>> talib.STOCHRSI(c)
(array([         nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
          3.76717443,   2.70876831,   0.        , 100.        ,
          0.        ,  96.33241266,  15.36227639, 100.        ,
         62.72093168,  83.19304414,  16.60408449,  43.38698102,
          0.        ,  18.1147527 ,  91.93501715, 100.        ,
         56.94277117,  36.26825354,   0.        ,   0.        ,
        100.        , 100.        ,   0.        ,   0.        ,
         32.0912658 , 100.        ,  57.83580898,  77.27810854,
         49.69824729,   0.        ,  64.55140934,  85.87311054,
         50.35189501, 100.        ,  66.84277367, 100.        ,
          9.24285073,  36.64048166,   0.        ,  37.914832  ,
         93.66947806,  82.36521899,  53.82289748,  18.41583569,
        100.        , 100.        ,  54.81596066,  40.60882574,
          0.        ,  29.43748114,  45.14367517,   0.        ,
         25.47226423,  19.67612782,  52.23303698, 100.        ,
        100.        ,  51.38846693, 100.        ,  40.9050621 ,
         29.55785047, 100.        ,   8.19064563,   0.        ,
          0.        ,  23.73882862,  34.87160964, 100.        ,
         47.03004845,  58.79845783,   0.        ,  22.90742908,
         54.39644817,  42.27017627,  45.27672676, 100.        ,
         54.50636285,  32.08944274,  49.35204405,  26.04980239]),
 array([        nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
        37.40425209, 12.95513924,  2.15864758, 34.2362561 , 33.33333333,
        65.44413755, 37.23156302, 70.56489635, 59.36106935, 81.97132527,
        54.17268677, 47.72803655, 19.99702184, 20.50057791, 36.68325661,
        70.01658995, 82.95926277, 64.40367491, 31.07034157, 12.08941785,
        33.33333333, 66.66666667, 66.66666667, 33.33333333, 10.6970886 ,
        44.03042193, 63.30902493, 78.37130584, 61.60405494, 42.32545195,
        38.08321888, 50.14150663, 66.92547163, 78.74166852, 72.39822289,
        88.94759122, 58.69520813, 48.62777746, 15.29444413, 24.85177122,
        43.86143669, 71.31650969, 76.61919818, 51.53465072, 57.41291105,
        72.80527856, 84.93865355, 65.14159547, 31.80826213, 23.34876896,
        24.86038544, 24.86038544, 23.53864647, 15.04946402, 32.46047634,
        57.30305493, 84.07767899, 83.79615564, 83.79615564, 64.09784301,
        56.82097086, 56.82097086, 45.91616537, 36.06354854,  2.73021521,
         7.91294287, 19.53681276, 52.87014609, 60.63388603, 68.60950209,
        35.27616876, 27.23529564, 25.76795908, 39.85801784, 47.3144504 ,
        62.51563434, 66.5943632 , 62.19860186, 45.31594988, 35.83042973]))

But, notice how this is just RSI passed into STOCHF:

>>> rsi = talib.RSI(c)

>>> talib.STOCHF(rsi, rsi, rsi)
(array([         nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
          3.76717443,   2.70876831,   0.        , 100.        ,
          0.        ,  96.33241266,  15.36227639, 100.        ,
         62.72093168,  83.19304414,  16.60408449,  43.38698102,
          0.        ,  18.1147527 ,  91.93501715, 100.        ,
         56.94277117,  36.26825354,   0.        ,   0.        ,
        100.        , 100.        ,   0.        ,   0.        ,
         32.0912658 , 100.        ,  57.83580898,  77.27810854,
         49.69824729,   0.        ,  64.55140934,  85.87311054,
         50.35189501, 100.        ,  66.84277367, 100.        ,
          9.24285073,  36.64048166,   0.        ,  37.914832  ,
         93.66947806,  82.36521899,  53.82289748,  18.41583569,
        100.        , 100.        ,  54.81596066,  40.60882574,
          0.        ,  29.43748114,  45.14367517,   0.        ,
         25.47226423,  19.67612782,  52.23303698, 100.        ,
        100.        ,  51.38846693, 100.        ,  40.9050621 ,
         29.55785047, 100.        ,   8.19064563,   0.        ,
          0.        ,  23.73882862,  34.87160964, 100.        ,
         47.03004845,  58.79845783,   0.        ,  22.90742908,
         54.39644817,  42.27017627,  45.27672676, 100.        ,
         54.50636285,  32.08944274,  49.35204405,  26.04980239]),
 array([        nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
        37.40425209, 12.95513924,  2.15864758, 34.2362561 , 33.33333333,
        65.44413755, 37.23156302, 70.56489635, 59.36106935, 81.97132527,
        54.17268677, 47.72803655, 19.99702184, 20.50057791, 36.68325661,
        70.01658995, 82.95926277, 64.40367491, 31.07034157, 12.08941785,
        33.33333333, 66.66666667, 66.66666667, 33.33333333, 10.6970886 ,
        44.03042193, 63.30902493, 78.37130584, 61.60405494, 42.32545195,
        38.08321888, 50.14150663, 66.92547163, 78.74166852, 72.39822289,
        88.94759122, 58.69520813, 48.62777746, 15.29444413, 24.85177122,
        43.86143669, 71.31650969, 76.61919818, 51.53465072, 57.41291105,
        72.80527856, 84.93865355, 65.14159547, 31.80826213, 23.34876896,
        24.86038544, 24.86038544, 23.53864647, 15.04946402, 32.46047634,
        57.30305493, 84.07767899, 83.79615564, 83.79615564, 64.09784301,
        56.82097086, 56.82097086, 45.91616537, 36.06354854,  2.73021521,
         7.91294287, 19.53681276, 52.87014609, 60.63388603, 68.60950209,
        35.27616876, 27.23529564, 25.76795908, 39.85801784, 47.3144504 ,
        62.51563434, 66.5943632 , 62.19860186, 45.31594988, 35.83042973]))

So... if you want the alternative definition of STOCHRSI that everyone is asking for above then you can do the same, but call STOCH instead of STOCHF:

>>> rsi = talib.RSI(c)

>>> talib.STOCH(rsi, rsi, rsi)

Really, the upstream library should have called it STOCHFRSI and saved us all a bit of headache, but I believe it's only two lines to have the behavior you want instead...

@mrjbq7
Copy link
Collaborator

mrjbq7 commented Dec 13, 2020

I added this example code as a note in the README:

3f872e3

@Meehir5
Copy link

Meehir5 commented Dec 13, 2020

Here is an example:

>>> import talib

>>> import numpy

>>> c = numpy.random.randn(100)

You can print the STOCHRSI for these values:

>>> talib.STOCHRSI(c)
(array([         nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
          3.76717443,   2.70876831,   0.        , 100.        ,
          0.        ,  96.33241266,  15.36227639, 100.        ,
         62.72093168,  83.19304414,  16.60408449,  43.38698102,
          0.        ,  18.1147527 ,  91.93501715, 100.        ,
         56.94277117,  36.26825354,   0.        ,   0.        ,
        100.        , 100.        ,   0.        ,   0.        ,
         32.0912658 , 100.        ,  57.83580898,  77.27810854,
         49.69824729,   0.        ,  64.55140934,  85.87311054,
         50.35189501, 100.        ,  66.84277367, 100.        ,
          9.24285073,  36.64048166,   0.        ,  37.914832  ,
         93.66947806,  82.36521899,  53.82289748,  18.41583569,
        100.        , 100.        ,  54.81596066,  40.60882574,
          0.        ,  29.43748114,  45.14367517,   0.        ,
         25.47226423,  19.67612782,  52.23303698, 100.        ,
        100.        ,  51.38846693, 100.        ,  40.9050621 ,
         29.55785047, 100.        ,   8.19064563,   0.        ,
          0.        ,  23.73882862,  34.87160964, 100.        ,
         47.03004845,  58.79845783,   0.        ,  22.90742908,
         54.39644817,  42.27017627,  45.27672676, 100.        ,
         54.50636285,  32.08944274,  49.35204405,  26.04980239]),
 array([        nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
        37.40425209, 12.95513924,  2.15864758, 34.2362561 , 33.33333333,
        65.44413755, 37.23156302, 70.56489635, 59.36106935, 81.97132527,
        54.17268677, 47.72803655, 19.99702184, 20.50057791, 36.68325661,
        70.01658995, 82.95926277, 64.40367491, 31.07034157, 12.08941785,
        33.33333333, 66.66666667, 66.66666667, 33.33333333, 10.6970886 ,
        44.03042193, 63.30902493, 78.37130584, 61.60405494, 42.32545195,
        38.08321888, 50.14150663, 66.92547163, 78.74166852, 72.39822289,
        88.94759122, 58.69520813, 48.62777746, 15.29444413, 24.85177122,
        43.86143669, 71.31650969, 76.61919818, 51.53465072, 57.41291105,
        72.80527856, 84.93865355, 65.14159547, 31.80826213, 23.34876896,
        24.86038544, 24.86038544, 23.53864647, 15.04946402, 32.46047634,
        57.30305493, 84.07767899, 83.79615564, 83.79615564, 64.09784301,
        56.82097086, 56.82097086, 45.91616537, 36.06354854,  2.73021521,
         7.91294287, 19.53681276, 52.87014609, 60.63388603, 68.60950209,
        35.27616876, 27.23529564, 25.76795908, 39.85801784, 47.3144504 ,
        62.51563434, 66.5943632 , 62.19860186, 45.31594988, 35.83042973]))

But, notice how this is just RSI passed into STOCHF:

>>> rsi = talib.RSI(c)

>>> talib.STOCHF(rsi, rsi, rsi)
(array([         nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
                 nan,          nan,          nan,          nan,
          3.76717443,   2.70876831,   0.        , 100.        ,
          0.        ,  96.33241266,  15.36227639, 100.        ,
         62.72093168,  83.19304414,  16.60408449,  43.38698102,
          0.        ,  18.1147527 ,  91.93501715, 100.        ,
         56.94277117,  36.26825354,   0.        ,   0.        ,
        100.        , 100.        ,   0.        ,   0.        ,
         32.0912658 , 100.        ,  57.83580898,  77.27810854,
         49.69824729,   0.        ,  64.55140934,  85.87311054,
         50.35189501, 100.        ,  66.84277367, 100.        ,
          9.24285073,  36.64048166,   0.        ,  37.914832  ,
         93.66947806,  82.36521899,  53.82289748,  18.41583569,
        100.        , 100.        ,  54.81596066,  40.60882574,
          0.        ,  29.43748114,  45.14367517,   0.        ,
         25.47226423,  19.67612782,  52.23303698, 100.        ,
        100.        ,  51.38846693, 100.        ,  40.9050621 ,
         29.55785047, 100.        ,   8.19064563,   0.        ,
          0.        ,  23.73882862,  34.87160964, 100.        ,
         47.03004845,  58.79845783,   0.        ,  22.90742908,
         54.39644817,  42.27017627,  45.27672676, 100.        ,
         54.50636285,  32.08944274,  49.35204405,  26.04980239]),
 array([        nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
                nan,         nan,         nan,         nan,         nan,
        37.40425209, 12.95513924,  2.15864758, 34.2362561 , 33.33333333,
        65.44413755, 37.23156302, 70.56489635, 59.36106935, 81.97132527,
        54.17268677, 47.72803655, 19.99702184, 20.50057791, 36.68325661,
        70.01658995, 82.95926277, 64.40367491, 31.07034157, 12.08941785,
        33.33333333, 66.66666667, 66.66666667, 33.33333333, 10.6970886 ,
        44.03042193, 63.30902493, 78.37130584, 61.60405494, 42.32545195,
        38.08321888, 50.14150663, 66.92547163, 78.74166852, 72.39822289,
        88.94759122, 58.69520813, 48.62777746, 15.29444413, 24.85177122,
        43.86143669, 71.31650969, 76.61919818, 51.53465072, 57.41291105,
        72.80527856, 84.93865355, 65.14159547, 31.80826213, 23.34876896,
        24.86038544, 24.86038544, 23.53864647, 15.04946402, 32.46047634,
        57.30305493, 84.07767899, 83.79615564, 83.79615564, 64.09784301,
        56.82097086, 56.82097086, 45.91616537, 36.06354854,  2.73021521,
         7.91294287, 19.53681276, 52.87014609, 60.63388603, 68.60950209,
        35.27616876, 27.23529564, 25.76795908, 39.85801784, 47.3144504 ,
        62.51563434, 66.5943632 , 62.19860186, 45.31594988, 35.83042973]))

So... if you want the alternative definition of STOCHRSI that everyone is asking for above then you can do the same, but call STOCH instead of STOCHF:

>>> rsi = talib.RSI(c)

>>> talib.STOCH(rsi, rsi, rsi)

Really, the upstream library should have called it STOCHFRSI and saved us all a bit of headache, but I believe it's only two lines to have the behavior you want instead...

WOW - this worked too well :) thanks a lot for adding this to README, much needed.

@bluetyphoon77
Copy link

Thanks a lot guyz ! For sharing !

@bluetyphoon77
Copy link

Anyone using Crypto Signals ? Do you know if there is a way to get the right values with their script ?
Because I'm not a dev, and cannot write myself a bot :(

@mahesh-solanke
Copy link

if still having a problem with talib stochrsi,
use pandas-ta stochrsi, its giving me accurate data.

you have to install dataclasses before installing pandas-ta
https://pypi.org/project/pandas-ta/
https://github.com/twopirllc/pandas-ta

Thanks,
Mahesh

@mrjbq7
Copy link
Collaborator

mrjbq7 commented Feb 24, 2021

Did the technique I added to the README not work for you?

@mahesh-solanke
Copy link

thanks for your reply, the technique is not works for me, because of that i have found alternatives

if still having a problem with talib stochrsi,
use pandas-ta stochrsi, its giving me accurate data.

you have to install dataclasses before installing pandas-ta
https://pypi.org/project/pandas-ta/
https://github.com/twopirllc/pandas-ta

Thanks,
Mahesh

@chappcc
Copy link

chappcc commented Mar 22, 2021

Why not try and get a pure python version working with expected output and then we can figure out what you're looking for. Seems like it's more likely you are defining it differently than TA-Lib.

https://sourceforge.net/p/ta-lib/code/HEAD/tree/trunk/ta-lib/c/src/ta_func/ta_STOCHRSI.c

This might be a little different than you expect, and I didn't really debug or test it, but posting here for discussion.

import numpy as np
import pandas as pd


def STOCH(h, l, c, fastk_period, slowk_period, slowd_period):
    hh = pd.rolling_max(h, fastk_period, min_periods=fastk_period)
    ll = pd.rolling_min(l, fastk_period, min_periods=fastk_period)
    fast_k = 100 * (c - ll) / (hh - ll)
    slow_k = pd.ewma(fast_k, span=slowk_period, min_periods=slowk_period)
    slow_d = pd.ewma(slow_k, span=slowd_period, min_periods=slowd_period)
    return slow_k, slow_d

def RS(c, n):
    diffs = pd.rolling_apply(c, 2, lambda x: x[-1] - x[0], min_periods=1)
    ups = pd.rolling_apply(diffs, n, lambda x: np.sum(x[x > 0]), min_periods=n)
    downs = pd.rolling_apply(diffs, n, lambda x: -np.sum(x[x < 0]), min_periods=n)
    rs = ups / downs
    rs[downs == 0] = 0
    return rs

def RSI(c, n):
    rs = RS(c, n)
    rsi = 100 - (100 / (1 + rs))
    return rsi

def STOCHRSI(c, timeperiod, fastk_period, fastd_period):
    rsi = RSI(c, timeperiod)
    return STOCH(rsi, rsi, rsi, timeperiod, fastk_period, fastd_period)

I should also note, you can try the TulipIndicators and see if that gives you results you expect.

In def STOCH() above, fast_k and slow_k are also referred to as %K and %D. %D is the SlowStochastic on Tradingview.
ref: https://www.investopedia.com/terms/s/stochasticoscillator.asp

@mrjbq7
Copy link
Collaborator

mrjbq7 commented Mar 22, 2021

I'm pretty sure this is the main source of confusion:

If you wonder why STOCHRSI gives you different results than you expect, probably you want STOCH applied to RSI, which is a little different than the STOCHRSI which is STOCHF applied to RSI:

>>> import talib
>>> import numpy
>>> c = numpy.random.randn(100)

# this is the library function
>>> k, d = talib.STOCHRSI(c)

# this produces the same result, calling STOCHF
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCHF(rsi, rsi, rsi)

# you might want this instead, calling STOCH
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCH(rsi, rsi, rsi)

@laukikk
Copy link

laukikk commented May 23, 2021

It's almost 3 years and I still across this issue and I gave it a few tried but I wasn't able to implement it in Ta-Lib.
But I was able to implement it using the Technical Analysis Library.
My Pandas DataFrame has a column named 'Close' which has the data of the previous closing prices. and 'sRSI_k' and 'sRSI_d' are empty columns

stochInd = StochRSIIndicator(df.Close)
df.sRSI_d = stochInd.stochrsi_d()*100
df.sRSI_k = stochInd.stochrsi_k()*100

It worked flawlessly and the results are the same as seen in Trading View

@LukePenkava
Copy link

@Zignake

Can you please let me know what settings you used for your calculation and TradingView settings? I have tried to tweak the settings, but i cant get the same results. Here are my settings and code:

stoch = ta.momentum.StochRSIIndicator(df["close"], window=14, smooth1=3, smooth2=3)
df["stoch_k"] = stoch.stochrsi_k()
df["stock_d"] = stoch.stochrsi_d()

TradingView settings:
K = 3, D = 3, RSI Length = 14, Sotchastic Lenght = 14, RSI Source = close

Getting very different values.

@mrjbq7
Copy link
Collaborator

mrjbq7 commented Jul 22, 2021

This didn't work for you?

#203 (comment)

@LukePenkava
Copy link

LukePenkava commented Jul 22, 2021

@mrjbq7

Thanks for quick reply. Unfortunately not, i think i tried every suggested solution here with no luck. I am probably doing something wrong, not sure what tho. Here are some data.

Data i am testing it on ( example )

NURO - My Results
Date: 20210720 16: 27:10
Price: 4.07 (CORRECT)
ema5:  4.0406790425932115 (CORRECT)
wma10: 4.036945454545423 (CORRECT)
wma20: 4.05735857142856 (CORRECT)
sma50: 4.060712000000001 (CORRECT)
sma150: 4.039709333333329 (CORRECT)
stoch_k:  100.0 (WRONG)
stoch_d: 90.5110338048806 (WRONG)
stoch2_k:  78.91134366943875 (WRONG)
stoch2_d: 49.507357683678265 (WRONG)
macd_green:  -0.006643942996008789 (WRONG)
macd_red: -0.001442128098838441 (WRONG)

Code

df["ema5"] = talib.EMA(df["close"], timeperiod=5)
df["wma10"] = talib.WMA(df["close"], timeperiod=10)
df["wma20"] = talib.WMA(df["close"], timeperiod=20)
df["sma50"] = talib.MA(df["close"], timeperiod=50)
df["sma150"] = talib.MA(df["close"], timeperiod=150)
df["stoch_k"], df["stoch_d"] = talib.STOCHRSI(df["close"], timeperiod=14, fastk_period=3, fastd_period=3,  std_matype=0)
df["macd_green"], df["macd_red"], df["macd_hist"] = talib.MACD(df["close"], fastperiod=12, slowperiod=26, signalperiod=9)

rsi = talib.RSI(df["close"])
df["stoch2_k"], df["stoch2_d"] = talib.STOCH(rsi, rsi, rsi)
TradingView values
NURO - 20210720 16: 27:10
price: 4.07
ema5:  4.04
wma10: 4.04
wma20: 4.06
sma50: 4.06
sma150: 4.04
stoch_k:  24.09
stoch_d: 12.56
macd_green:  0.00
macd_red: 0.02

As you can see both Stoch and MACD are wrong, i have tested it on a lot of data. Never getting any proper results for Stoch and MACD with any library :(

Edit: Btw my averages are quite often off as well

Edit2: I have put there the correct values, the result is much better, but still off. I hope its possible to get closer values

Code
rsi = talib.RSI(df["close"], 14)
df["stoch2_k"], df["stoch2_d"] = talib.STOCH(rsi, rsi, rsi, astk_period=14,slowk_period=3,slowk_matype=0,slowd_period=3, slowd_matype=0)

My Values
stoch2_k: 22.580624039177494 stoch2_d: 12.957650021073347
TradingView values
stoch_k: 24.09, stoch_d: 12.56

@chappcc
Copy link

chappcc commented Jul 23, 2021 via email

@ijusss
Copy link

ijusss commented Jan 28, 2022

I'm pretty sure this is the main source of confusion:

If you wonder why STOCHRSI gives you different results than you expect, probably you want STOCH applied to RSI, which is a little different than the STOCHRSI which is STOCHF applied to RSI:

>>> import talib
>>> import numpy
>>> c = numpy.random.randn(100)

# this is the library function
>>> k, d = talib.STOCHRSI(c)

# this produces the same result, calling STOCHF
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCHF(rsi, rsi, rsi)

# you might want this instead, calling STOCH
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCH(rsi, rsi, rsi)

I got it! I have a numbers like StochRSI on Tradingview!
But you need to complete your code with "14" period:

>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCH(rsi, rsi, rsi, 14)

Worked for me! Thanks!

@xiaogea01
Copy link

I'm pretty sure this is the main source of confusion:

If you wonder why STOCHRSI gives you different results than you expect, probably you want STOCH applied to RSI, which is a little different than the STOCHRSI which is STOCHF applied to RSI:

>>> import talib
>>> import numpy
>>> c = numpy.random.randn(100)

# this is the library function
>>> k, d = talib.STOCHRSI(c)

# this produces the same result, calling STOCHF
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCHF(rsi, rsi, rsi)

# you might want this instead, calling STOCH
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCH(rsi, rsi, rsi)

I got it! I have a numbers like StochRSI on Tradingview! But you need to complete your code with "14" period:

>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCH(rsi, rsi, rsi, 14)

Worked for me! Thanks!

It works for me !!

@bluetyphoon77
Copy link

Thanks a lot I'll try it !!Cheeeers
Ps: by the way is it possible to hire your services for some coding ? cheeers

@bluetyphoon77
Copy link

bluetyphoon77 commented Feb 19, 2022 via email

@laukikk
Copy link

laukikk commented Feb 19, 2022

@bluetyphoon77, not that I think that I can be of much help to you. What exactly is it that you're trying to develop?
I've tried to make a bot myself but the profit margin was so low in my case that the fees would always get me down to losses. I've been trying to find a solution ever since. Increasing the time frame and then again backtesting my strategies would always give varied hyperparameters every time I tried to train them. If you also have a solution for this, do please let me know.

@bluetyphoon77
Copy link

bluetyphoon77 commented Feb 19, 2022 via email

@laukikk
Copy link

laukikk commented Feb 20, 2022

@bluetyphoon77,
Actually, as I have multiple different strategies and there wasn't a single package that was sufficient, I have used 2/3 libraries and also had to code a few myself.
As you want notifications, then you would also be needing different packages depending on your strategies.
Yeah, building strategies and frameworks from scratch rather than using the existing ones has been really helpful. Though if you want you can still give a try to this Python package called BackTrader.
Regarding my rates., tbh, I personally haven't freelanced. But yet I'd like to get to know more about the project, and then we can maybe have a discussion.

@bluetyphoon77
Copy link

bluetyphoon77 commented Feb 20, 2022 via email

@laukikk
Copy link

laukikk commented Feb 20, 2022

Hey @bluetyphoon77, you can find my contact info on my profile. 😄

@xiaogea01
Copy link

@bluetyphoon77 you means you need some notification bot service? As I see you said you use telegram ,is it not satisfied your demand?

@ZaphodBeeblebrox12
Copy link

I'm pretty sure this is the main source of confusion:

If you wonder why STOCHRSI gives you different results than you expect, probably you want STOCH applied to RSI, which is a little different than the STOCHRSI which is STOCHF applied to RSI:

>>> import talib
>>> import numpy
>>> c = numpy.random.randn(100)

# this is the library function
>>> k, d = talib.STOCHRSI(c)

# this produces the same result, calling STOCHF
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCHF(rsi, rsi, rsi)

# you might want this instead, calling STOCH
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCH(rsi, rsi, rsi)

I'm pretty sure this is the main source of confusion:

If you wonder why STOCHRSI gives you different results than you expect, probably you want STOCH applied to RSI, which is a little different than the STOCHRSI which is STOCHF applied to RSI:

>>> import talib
>>> import numpy
>>> c = numpy.random.randn(100)

# this is the library function
>>> k, d = talib.STOCHRSI(c)

# this produces the same result, calling STOCHF
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCHF(rsi, rsi, rsi)

# you might want this instead, calling STOCH
>>> rsi = talib.RSI(c)
>>> k, d = talib.STOCH(rsi, rsi, rsi)

So this is the code I used as you advised:

import yfinance as yf
import pandas as pd
from dateutil.relativedelta import relativedelta
import talib
df = yf.download(tickers='fb', start=datetime.datetime.now()-relativedelta(days=200), end= datetime.datetime.now(), interval="1d", progress = False)
rsi = talib.RSI(df['Close'], timeperiod=20)
k, d = talib.STOCH(rsi, rsi, rsi)

The d value is 2022-04-04 48.946233
But on TradingView it is showing 92.4. Did I miss something? Any help you can provide would be much appreciated!

@Elyasnz
Copy link

Elyasnz commented May 24, 2023

if a Python implementation of STOCHRSI is needed this comment is useful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests