Today we are going to work on two separated short exercises
- building a SuperTrend that uses Rational Quadratic / Gaussian Kernels to forecast trend and build a script to compare it against the standard SuperTrend implementation
- We will work on a version of RSI that uses Inverse Fisher Transform to produce smoother values. We will add as well some Kernel functions to produce an interesting trend following oscillator.
Kernel Supertrend code and chart
//@version=5
indicator("K Supertrend", overlay=true, timeframe="", timeframe_gaps=true)
import jdehorty/KernelFunctions/2 as kernels
atrPeriod = input(10, "ATR Length")
factor = input.float(3.0, "Factor", step = 0.01)
lb = input.int(10)
rw = input.int(5)
sb = input.int(100)
mode = input.string("rationalQ","Mode", options=["rma","rationalQ", "gaussian"])
pine_atr(length) =>
trueRange = na(high[1])? high-low : math.max(math.max(high - low, math.abs(high - close[1])), math.abs(low - close[1]))
//true range can be also calculated with ta.tr(true)
if mode == "rationalQ"
kernels.rationalQuadratic(trueRange,length,rw,sb)
else if mode == "gaussian"
kernels.gaussian(trueRange,length, sb)
else if mode == "rma"
ta.rma(trueRange, length)
else
0.0
pine_supertrend(factor, atrPeriod) =>
src = hl2
atr = pine_atr(atrPeriod)
upperBand = src + factor * atr
lowerBand = src - factor * atr
prevLowerBand = nz(lowerBand[1])
prevUpperBand = nz(upperBand[1])
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
int direction = na
float superTrend = na
prevSuperTrend = superTrend[1]
if na(atr[1])
direction := 1
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
[supertrend, direction] = pine_supertrend(factor, atrPeriod)
var int swaps = 0
if na(swaps)
swaps := 0
if (direction < 0 and direction[1] > 0) or (direction > 0 and direction[1] < 0)
swaps := swaps[1] + 1
plot(swaps,"swaps", color=na)
var float diff = 0
if na(diff[1])
diff := 0
else
diff := diff + math.abs(close - supertrend)
plot(diff, "diff", color = na)
bodyMiddle = plot((open + close) / 2, display=display.none)
upTrend = plot(direction < 0 ? supertrend : na, "Up Trend", color = color.green, style=plot.style_linebr)
downTrend = plot(direction < 0? na : supertrend, "Down Trend", color = color.red, style=plot.style_linebr)
fill(bodyMiddle, upTrend, color.new(color.green, 90), fillgaps=false)
fill(bodyMiddle, downTrend, color.new(color.red, 90), fillgaps=false)
Kernel IFTRSI code and chart
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// ยฉ TheTradingParrot
//@version=5
indicator("TTP IFTRSI + Kernel", overlay = false)
import jdehorty/KernelFunctions/2 as kernels
rsilength=input(5, "RSI Length",group="IFTRSI settings")
wmalength=input(9, title="Smoothing length",group="IFTRSI settings")
v1=0.1*(ta.rsi(close, rsilength)-50)
v2=ta.wma(v1,wmalength)
INV=(math.exp(2*v2)-1)/(math.exp(2*v2)+1)
rsi = INV
lb = input.int(10)
lb2 = input.int(20)
rw = input.int(5)
sb = input.int(100)
k = kernels.rationalQuadratic(rsi,lb, rw, sb)
k2 = kernels.rationalQuadratic(rsi,lb2, rw, sb)
hline(0.95)
hline(0)
hline(-0.95)
buy = k > k2+0.0
buy2 = rsi > k + 2 or rsi > k2
c = buy ? color.green : color.red
plot(rsi, color = color.new(color.white, 60))
a = plot(k, color = c)
b = plot(k2, color = c)
fill(a,b, color= color.new(c,40))
sell = not buy
buycondition = buy and not buy[1]
sellcondition = sell and not sell[1]
plot(buycondition ? 1 : sellcondition ? -1 : 0, "backtest stream", color= na)
alertcondition(buycondition, "buy")
alertcondition(sellcondition, "sell")