For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

# 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.

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` built-in implementation?

I did not find StochRSI in `bt`. As i see, it has only Stochastic and RSI as a separate indicators. TA-lib 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

``````      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.