20191002: The community is currently in readonly mode
Stochastic RSI indicator.

Hi colleagues.
I've finished stoch RSI indicator and i would like to share it. It has the same K & D values as the Tradingview stoch RSI.
https://www.tradingview.com/wiki/Stochastic_RSI_(STOCH_RSI)My applauds to the Backtrader developers team  excellent platform. Any comments are welcome.
from backtrader.indicators import Indicator, MovAv, RelativeStrengthIndex, Highest, Lowest class StochasticRSI(Indicator): """ K  The time period to be used in calculating the %K. 3 is the default. D  The time period to be used in calculating the %D. 3 is the default. RSI Length  The time period to be used in calculating the RSI Stochastic Length  The time period to be used in calculating the Stochastic Formula: %K = SMA(100 * (RSI(n)  RSI Lowest Low(n)) / (RSI HighestHigh(n)  RSI LowestLow(n)), smoothK) %D = SMA(%K, periodD) """ lines = ('fastk', 'fastd',) params = ( ('k_period', 3), ('d_period', 3), ('rsi_period', 14), ('stoch_period', 14), ('movav', MovAv.Simple), ('rsi', RelativeStrengthIndex), ('upperband', 80.0), ('lowerband', 20.0), ) plotlines = dict(percD=dict(_name='%D', ls=''), percK=dict(_name='%K')) def _plotlabel(self): plabels = [self.p.k_period, self.p.d_period, self.p.rsi_period, self.p.stoch_period] plabels += [self.p.movav] * self.p.notdefault('movav') return plabels def _plotinit(self): self.plotinfo.plotyhlines = [self.p.upperband, self.p.lowerband] def __init__(self): rsi_hh = Highest(self.p.rsi(period=self.p.rsi_period), period=self.p.stoch_period) rsi_ll = Lowest(self.p.rsi(period=self.p.rsi_period), period=self.p.stoch_period) knum = self.p.rsi(period=self.p.rsi_period)  rsi_ll kden = rsi_hh  rsi_ll self.k = self.p.movav(100.0 * (knum / kden), period=self.p.k_period) self.d = self.p.movav(self.k, period=self.p.d_period) self.lines.fastk = self.k self.lines.fastd = self.d

Thank you!
What is the difference between your implementation and
bt
builtin implementation?

@ab_trader
I did not find StochRSI inbt
. As i see, it has only Stochastic and RSI as a separate indicators. TAlib StochRSI has K & D values other than Tradingview.
Tradingview (TV) is a rapidly growing JS framwork. The goal was to receive exact the same values as TV.

StochRSI
is a well known indicator, not something which has been invented by Tradingview.You probably want to rewrite this
@nikolai said in Stochastic RSI indicator.:
def __init__(self): rsi_hh = Highest(self.p.rsi(period=self.p.rsi_period), period=self.p.stoch_period) rsi_ll = Lowest(self.p.rsi(period=self.p.rsi_period), period=self.p.stoch_period) knum = self.p.rsi(period=self.p.rsi_period)  rsi_ll kden = rsi_hh  rsi_ll self.k = self.p.movav(100.0 * (knum / kden), period=self.p.k_period) self.d = self.p.movav(self.k, period=self.p.d_period) self.lines.fastk = self.k self.lines.fastd = self.d
to look like this (and avoid unnecessary instantiation of multiple indicators and unneeded member attributes)
def __init__(self): rsi = bt.ind.RSI(period=self.p.rsi_period) rsi_ll = bt.ind.Lowest(rsi, period=self.p.rsi_period) rsi_hh = bt.ind.Highest(rsi, period=self.p.rsi_period) stochrsi = (rsi  rsi_ll) / (rsi_hh  rsi_ll) self.l.fastk = k = self.p.movav(100.0 * stochrsi, period=self.p.k_period) self.l.fastd = self.p.movav(k, period=self.p.d_period)

@backtrader, thanks for help with the code. Tradingview didn't invent StochRSI of course. Their docs are a bit messy for this indicator. So, the goal was to get the same implementation.

@nikolai Does this give output in pandas dataframe (dateseries format output).
What is the input used here ohlc data of each day ,hour ?
I am keen to try this out as i am trying to build the one that exactly gives tv matching output.Please reply back what shall be the changes here to be done to get the output as pandas data frame.
my email mbmarx gmail if you wish to share the code snippet please help.

@marxbabu said in Stochastic RSI indicator.:
Does this give output in pandas dataframe (dateseries format output)
No. For the simple reason that backtrader isn't
pandas
. You may execute backtrader on a step by step basis (needed for live trading of course), in which case it doesn't make any sense to get a dataframe as the output of anything, given the inflexibility of a dataframe to dynamically grow.@marxbabu said in Stochastic RSI indicator.:
Please reply back what shall be the changes here to be done to get the output as pandas data frame.
There are no changes to be done. All you can do is run the complete backtest and then transform the data to be imported into a dataframe if you wish.

@marxbabu This is all code you need. But it works only as
backtrader
indicator. Feel free to use it, but you will need to understand howbacktrader
framework works.

Im new to backtrader and still trying to get the hang of it. How would I go about calling the fastk and fastd lines in my strategy? Doing StochasticRSI.lines.fastk throws me an attribute error (AttributeError: 'NoneType' object has no attribute 'lines').

@Tomas
Hi. I wrote an example strategy for you. You can access the indicator lines through the name in__init__
method.class CryptoStochRSI(bt.Strategy): params = ( ('stoch_k_period', 3), ('stoch_d_period', 3), ('stoch_rsi_period', 14), ('stoch_period', 14), ('stoch_upperband', 80.0), ('stoch_lowerband', 20.0), ('take_profit', 0.04), ('stop_loss', 0.01), ('size', 20), ('debug', False), ) def __init__(self): self.stoch = StochasticRSI(k_period=self.p.stoch_k_period, d_period=self.p.stoch_d_period, rsi_period=self.p.stoch_rsi_period, stoch_period=self.p.stoch_period, upperband=self.p.stoch_upperband, lowerband=self.p.stoch_lowerband) def next(self): if not self.position: close = self.data.close[0] price1 = close price2 = price1  self.p.stop_loss * close price3 = price1 + self.p.take_profit * close if self.stoch.l.fastk[0] < 20: self.buy_bracket(price=price1, stopprice=price2, limitprice=price3, exectype=bt.Order.Limit) if self.stoch.l.fastk[0] > 80: self.sell_bracket(price=price1, stopprice=price3, limitprice=price2, exectype=bt.Order.Limit)