this is my mod script for TV - Heikin Ashi RSI Oscillator.
below review on YouTube
Updated - Added Stochastic, divergence, alert, minor code fix.
Old Script
Introducing HARSI - the RSI based Heikin Ashi candle oscillator.
...that's right, you read it correctly. This is Heikin Ashi candles in an oscillator
format derived from RSI calculations, aimed at smoothing out some of the
inherent noise seen with standard RSI indicators.
below review on YouTube
Updated - Added Stochastic, divergence, alert, minor code fix.
CSS:
#// This source code is free to use, copy, and alter in any way you choose.
#// ...but credit is always nice :)
#//@version=4
#//@author=JayRogers
#https://www.tradingview.com/script/1o4oWbEx-Heikin-Ashi-RSI-Oscillator/
#study( "Heikin Ashi RSI Oscillator", "HARSI •", false, format.price, 2 )
# Converted by SAM4COK@ 06/2022 - Not exact code
# updated by Sam4Cok@Samer800 - 06/2024
declare lower;
#//====== INPUTS ======//
#// -- Candle config
input enableAlerts = yes;
input alertType = Alert.BAR;
input alertSound = Sound.NoSound;
input harsiLength = 14; #"Length RSI calculations"
input harsiSmoothingLength = 1; #"Open Smoothing"
#// -- RSI plot config
input source = ohlc4; # "Source"
input rsiLength = 7; # "Length"
input SmoothedRsi = yes; # "Smoothed Mode RSI?"
input showRsiLine = yes; # "Show RSI Plot?"
input showRsiHistogram = yes; # "Show RSI Histogram?"
#// -- Stochastic RSI plots config
input showStochastic = no; # "Show Stochastic? "
input ribbon = yes; # "Ribbon?"
input smoothingK = 3; # "Smoothing K"
input smoothingD = 3; # "Smoothing D"
input StochasticLength = 14; # "Stochastic Length"
input StochasticScaling = 80; # "Stoch Scaling %"
#// -- Channel OB/OS config
input overbought = 20; # "OB"
input overboughtExtreme = 30; # "OB Extreme"
input oversold = -20; # "OS"
input oversoldExtreme = -30; # "OS Extreme"
def na = Double.NaN;
def last = IsNaN(close);
########## Colors ########
DefineGlobalColor("UPTICK" , CreateColor(0, 173, 173));
DefineGlobalColor("UP" , CreateColor(0, 100, 100));
DefineGlobalColor("DOWNTICK" , CreateColor(183, 0, 20));
DefineGlobalColor("DOWN" , CreateColor(117, 0, 14));
DefineGlobalColor("RSI" , CreateColor(250, 200, 50));
DefineGlobalColor("K" , CreateColor(0,148,255));
DefineGlobalColor("D" , CreateColor(255,106,0));
#//====== FUNCTIONS ======//
#// zero median stoch helper function, subtracts 50 and includes % scaling
script f_zstoch {
input _source = ohlc4;
input _length = 14;
input _smooth = 3;
input _scale = 80;
def hh = Highest(_source, _length);
def ll = Lowest(_source, _length);
def c1 = _source - ll;
def c2 = hh - ll;
def stoch = if c2 != 0 then c1 / c2 * 100 else 0;
def _zstoch = stoch - 50;
def _smoothed = Average(_zstoch, _smooth );
def _scaled = (_smoothed / 100) * _scale;
plot out = _scaled;
}
script f_rsi {
input _source = ohlc4;
input _length = 0;
input _mode = yes;
def _zrsi = RSI(PRICE = _source, LENGTH = _length) - 50;
def _smoothed = CompoundValue(1, (_smoothed[1] + _zrsi) / 2, _zrsi);
def f_rsi = if _mode then _smoothed else _zrsi;
plot return = f_rsi;
}
#// RSI Heikin-Ashi generation function
script f_rsiHeikinAshi {
input _length = 10;
input i_smoothing = 5;
def _closeRSI = RSI(PRICE = close, LENGTH = _length) - 50;
def _highRSI_raw = RSI(PRICE = high, LENGTH = _length ) - 50;
def _lowRSI_raw = RSI(PRICE = low, LENGTH = _length ) - 50;
def _openRSI = CompoundValue(1, _closeRSI[1], _closeRSI);
def _highRSI = Max( _highRSI_raw, _lowRSI_raw );
def _lowRSI = Min( _highRSI_raw, _lowRSI_raw );
def _close = (_openRSI + _highRSI + _lowRSI + _closeRSI) / 4;
def _open = CompoundValue(1, if IsNaN(_open[i_smoothing]) then (_openRSI + _closeRSI) / 2 else
((_open[1] * i_smoothing) + _close[1]) / (i_smoothing + 1), (_openRSI + _closeRSI) / 2);
def OpOP = if !isNaN(_open) then _open else (_openRSI + _closeRSI) / 2;
def _high = Max(_highRSI, Max(OpOP, _close));
def _low = Min(_lowRSI, Min(OpOP, _close));
plot hi = _high;
plot lo = _low;
plot cl = _close;
plot op = OpOP; #_open;
}
#// ====== SERIES, LINES and LABELS ====== //
#// standard, or ha smoothed rsi for the line plot and/or histogram
def nRSI = f_rsi(source, rsiLength, SmoothedRsi);
#// stoch stuff
def StochK = f_zstoch(nRSI, StochasticLength, smoothingK, StochasticScaling);
def StochD = Average(StochK, smoothingD );
#// get OHLC values to use in the plotcandle()
def op = f_rsiHeikinAshi(harsiLength, harsiSmoothingLength).op;
def hi = f_rsiHeikinAshi(harsiLength, harsiSmoothingLength).hi;
def lo = f_rsiHeikinAshi(harsiLength, harsiSmoothingLength).lo;
def cl = f_rsiHeikinAshi(harsiLength, harsiSmoothingLength).cl;
def isExp = AbsValue(cl - op) > AbsValue(cl[1] - op[1]);
def green = cl > op;
def up = if green then if isExp then 1 else 0 else na;
def dn = if !green then if isExp then 1 else 0 else na;
# Plot ----
def lower = if last then na else oversold;
def upperx = if last then na else overboughtExtreme;
def upper = if last then na else overbought;
def lowerx = if last then na else oversoldExtreme;
#// RSI overlay plot
plot RSI_OL = if showRsiLine then nRSI else na;
def rsi_Hist = if showRsiHistogram then nRSI else na;
RSI_OL.SetDefaultColor(GlobalColor("RSI"));
#// Stochastic RSI plots and fill
def plot_stochK = if showStochastic and ribbon then StochK else na; # "Stoch K"
def plot_stochD = if showStochastic and ribbon then StochD else na; # "Stoch D"
plot StocKLine = if showStochastic and !ribbon then StochK else na; # "Stoch K Shadow"
plot StocDLine = if showStochastic and !ribbon then StochD else na; # "Stoch D Shadow"
StocKLine.SetDefaultColor(GlobalColor("K"));
StocDLine.SetDefaultColor(GlobalColor("D"));
AddCloud(plot_stochK, plot_stochD, GlobalColor("K"), GlobalColor("D"));
#-- Med Line
plot median = if !last and !showRsiHistogram then 0 else na;
median.SetDefaultColor(Color.DARK_GRAY);
median.SetStyle(Curve.MEDIUM_DASH);
# Plot the new Chart
AddCloud (upperx, upper, Color.DARK_RED, Color.DARK_RED, no);
AddCloud (lower, lowerx, Color.DARK_GREEN, Color.DARK_GREEN, no);
AddChart(open = 0, high = rsi_Hist , low = 0 , close = 0,
type = ChartType.CANDLE, growcolor = Color.DARK_GRAY);
AddChart(open = if up then cl else na, high = hi , low = lo , close = op,
type = ChartType.CANDLE, growcolor = GlobalColor("UPTICK"));
AddChart(open = if !up then cl else na, high = hi , low = lo , close = op,
type = ChartType.CANDLE, growcolor = GlobalColor("UP"));
AddChart(open = if dn then op else na, high = hi , low = lo , close = cl,
type = ChartType.CANDLE, growcolor = GlobalColor("DOWNTICK"));
AddChart(open = if !dn then op else na, high = hi , low = lo , close = cl,
type = ChartType.CANDLE, growcolor = GlobalColor("DOWN"));
#----Div-----------
input showRegularBullish = yes; # "Plot Bullish"
input showRegularBearish = yes; # "Plot Bearish"
input MaxLookbackRange = 60; # "Max of Lookback Range"
input MinLookbackRange = 5; # "Min of Lookback Range"
def lookback = floor(rsiLength/2);
def ohlc = (op + hi + lo + cl)/4;
def divSrc = nRSI; #if ohlc > 0 then hi else lo;
def h = high;
def l = low;
script FindPivots {
input dat = close; # default data or study being evaluated
input HL = 0; # default high or low pivot designation, -1 low, +1 high
input lbL = 5; # default Pivot Lookback Left
input lbR = 1; # default Pivot Lookback Right
##############
def _nan; # used for non-number returns
def _BN; # the current barnumber
def _VStop; # confirms that the lookforward period continues the pivot trend
def _V; # the Value at the actual pivot point
##############
_BN = BarNumber();
_nan = Double.NaN;
_VStop = if !isNaN(dat) and lbr > 0 and lbl > 0 then
fold a = 1 to lbR + 1 with b=1 while b do
if HL > 0 then dat > GetValue(dat,-a) else dat < GetValue(dat,-a) else _nan;
if (HL > 0) {
_V = if _BN > lbL + 1 and dat == Highest(dat, lbL + 1) and _VStop
then dat else _nan;
} else {
_V = if _BN > lbL + 1 and dat == Lowest(dat, lbL + 1) and _VStop
then dat else _nan;
}
plot result = if !IsNaN(_V) and _VStop then _V else _nan;
}
#_inRange(cond) =>
script _inRange {
input cond = yes;
input rangeUpper = 60;
input rangeLower = 5;
def bars = if cond then 0 else bars[1] + 1;
def inrange = (rangeLower <= bars) and (bars <= rangeUpper);
plot retrun = inRange;
}
def pl_ = findpivots(divSrc,-1, lookback, lookback);
def ph_ = findpivots(divSrc, 1, lookback, lookback);
def pl = !isNaN(pl_);
def ph = !isNaN(ph_);
def pll = lowest(divSrc,lookback +1);
def phh = highest(divSrc,lookback+1);
def sll = lowest(l, lookback +1);
def shh = highest(h, lookback+1);
#-- Pvt Low
def plStart = if pl then yes else plStart[1];
def plFound = if (plStart and pl) then 1 else 0;
def vlFound1 = if plFound then divSrc else vlFound1[1];
def vlFound_ = if vlFound1!=vlFound1[1] then vlFound1[1] else vlFound_[1];
def vlFound = if !vlFound_ then pll else vlFound_;
def plPrice1 = if plFound then l else plPrice1[1];
def plPrice_ = if plPrice1!=plPrice1[1] then plPrice1[1] else plPrice_[1];
def plPrice = if !plPrice_ then sll else plPrice_;
#-- Pvt High
def phStart = if ph then yes else phStart[1];
def phFound = if (phStart and ph) then 1 else 0;
def vhFound1 = if phFound then divSrc else vhFound1[1];
def vhFound_ = if vhFound1!=vhFound1[1] then vhFound1[1] else vhFound_[1];
def vhFound = if !vhFound_ then phh else vhFound_;
def phPrice1 = if phFound then h else phPrice1[1];
def phPrice_ = if phPrice1!=phPrice1[1] then phPrice1[1] else phPrice_[1];
def phPrice = if !phPrice_ then shh else phPrice_;
#// Regular Bullish
def inRangePl = _inRange(plFound[1],MaxLookbackRange, MinLookbackRange);
def oscHL = divSrc > vlFound and inRangePl;
def priceLL = l < plPrice and divSrc <= oversold; #40;
def bullCond = plFound and oscHL and priceLL;
#// Regular Bearish
def inRangePh = _inRange(phFound[1],MaxLookbackRange, MinLookbackRange);
def oscLH = divSrc < vhFound and inRangePh;
def priceHH = h > phPrice and divSrc >= overbought; #60;;
def bearCond = phFound and oscLH and priceHH;
#------ Bubbles
def bullBub = showRegularBullish and bullCond;
def bearBub = showRegularBearish and bearCond;
addchartbubble(bullBub, divSrc, "R", color.GREEN, no);
addchartbubble(bearBub, divSrc, "R", Color.MAGENTA, yes);
##### Lines
def bar = BarNumber();
#-- Bear Line
def lastPhBar = if ph then bar else lastPhBar[1];
def prePhBar = if lastPhBar!=lastPhBar[1] then lastPhBar[1] else prePhBar[1];
def priorPHBar = if bearCond then prePhBar else priorPHBar[1];
#-- Bull Line
def lastPlBar = if pl then bar else lastPlBar[1];
def prePlBar = if lastPlBar!=lastPlBar[1] then lastPlBar[1] else prePlBar[1];
def priorPLBar = if bullCond then prePlBar else priorPLBar[1];
def lastBullBar = if bullCond then bar else lastBullBar[1];
def lastBearBar = if bearCond then bar else lastBearBar[1];
def HighPivots = ph and bar >= HighestAll(priorPHBar) and bar <= HighestAll(lastBearBar);
def LowPivots = pl and bar >= HighestAll(priorPLBar) and bar <= HighestAll(lastBullBar);
def pivotHigh = if HighPivots then divSrc else na;
def pivotLow = if LowPivots then divSrc else na;
plot PlotHline = if showRegularBearish then pivotHigh else na;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(Color.MAGENTA);
plot PlotLline = if showRegularBullish then pivotLow else na;
PlotLline.EnableApproximation();
PlotLline.SetDefaultColor(Color.GREEN);
#---- Alerts
Alert(enableAlerts and bullBub, "Bullish Div", alertType, alertSound);
Alert(enableAlerts and bearBub, "Bearish Div", alertType, alertSound);
#-- END of CODE
Old Script
Ruby:
#// This source code is free to use, copy, and alter in any way you choose.
#// ...but credit is always nice :)
#//@version=4
#//@author=JayRogers
#https://www.tradingview.com/script/1o4oWbEx-Heikin-Ashi-RSI-Oscillator/
#study( "Heikin Ashi RSI Oscillator", "HARSI •", false, format.price, 2 )
# Converted by SAM4COK@ 06/2022 - Not exact code
declare lower;
def na = Double.NaN;
########## Colors ########
DefineGlobalColor("UPTICK" , CreateColor( 0,120,120));
DefineGlobalColor("UP" , CreateColor( 0,80 , 80));
DefineGlobalColor("DOWNTICK" , CreateColor(173, 0, 20));
DefineGlobalColor("DOWN" , CreateColor(117, 0, 14));
DefineGlobalColor("RSI" , CreateColor(250, 200, 50));
#DefineGlobalColor("UPTICK" , CreateColor( 0,166, 50));
#DefineGlobalColor("UP" , CreateColor( 0,110, 33));
#////////////////////////////////////////////////////////////////////////////////
#// //
#// ====== INPUTS ====== //
#// //
#////////////////////////////////////////////////////////////////////////////////
#// -- Candle config
input i_lenHARSI = 14; #"Length RSI calculations"
input i_smoothing = 1; #"Open Smoothing"
#// -- RSI plot config
input i_source = ohlc4; # "Source",
input i_lenRSI = 7; # "Length",
input i_mode = yes; # "Smoothed Mode RSI?"
input i_showPlot = yes; # "Show RSI Plot?"
input i_showHist = yes; # "Show RSI Histogram?"
#// -- Channel OB/OS config
input i_upper = 20; # "OB"
input i_upperx = 30; # "OB Extreme"
input i_lower = -20; # "OS"
input i_lowerx = -30; # "OS Extreme"
#////////////////////////////////////////////////////////////////////////////////
#// ====== FUNCTIONS ====== //
#////////////////////////////////////////////////////////////////////////////////
#// zero median rsi helper function, just subtracts 50.
script f_zrsi {
input _source = ohlc4;
input _length = 0;
def RSI = RSI(PRICE = _source, LENGTH = _length ) - 50;
plot return = RSI;
}
script f_rsi { #f_rsi( i_source, i_lenRSI, i_mode )
input _source = ohlc4;
input _length = 0;
input _mode = yes;
def _zrsi = f_zrsi( _source, _length );
def _smoothed = if IsNaN( _smoothed[1] ) then _zrsi else ( _smoothed[1] + _zrsi ) / 2;
def f_rsi = if _mode then _smoothed else _zrsi;
plot return = f_rsi;
}
#// RSI Heikin-Ashi generation function
script nz {
input data = 0;
input replacement = 0;
def ret_val = if IsNaN(data) then replacement else data;
plot return = ret_val;
}
script f_Close { #f_Close(i_lenHARSI)
input _length = 0;
def _closeRSI = f_zrsi( close, _length);
def _openRSI = nz( _closeRSI[1], _closeRSI );
def _highRSI_raw = f_zrsi( high, _length );
def _lowRSI_raw = f_zrsi( low, _length );
def _highRSI = Max( _highRSI_raw, _lowRSI_raw );
def _lowRSI = Min( _highRSI_raw, _lowRSI_raw );
def _close = ( _openRSI + _highRSI + _lowRSI + _closeRSI ) / 4;
plot return = _close;
}
script f_Open { #f_Open(i_lenHARSI, i_smoothing)
input _length = 0;
input _smoothing = 1;
def _closeRSI = f_zrsi( close, _length);
def _openRSI = nz( _closeRSI[1], _closeRSI );
def _open = if IsNaN ( _open[_smoothing]) then ( _openRSI + _closeRSI ) / 2 else
(( _open[1] * _smoothing ) + f_Close(_length)[1]) / (_smoothing + 1 );
plot return = _open;
}
script f_High { #f_High(i_lenHARSI , i_smoothing)
input _length = 0;
input _smoothing = 1;
def _highRSI_raw = f_zrsi( high, _length );
def _lowRSI_raw = f_zrsi( low, _length );
def _highRSI = Max( _highRSI_raw, _lowRSI_raw );
def _high = Max( _highRSI, Max(f_Open(_length, _smoothing), f_Close(_length)));
plot return = _high;
}
script f_Low { #f_Low(i_lenHARSI , i_smoothing)
input _length = 0;
input _smoothing = 1;
def _highRSI_raw = f_zrsi( high, _length );
def _lowRSI_raw = f_zrsi( low, _length );
def _lowRSI = Min( _highRSI_raw, _lowRSI_raw );
def _low = Min( _lowRSI, Min(f_Open(_length, _smoothing), f_Close(_length)));
plot return = _low ;
}
#////////////////////////////////////////////////////////////////////////////////
#// ====== SERIES, LINES and LABELS ====== //
#////////////////////////////////////////////////////////////////////////////////
#// standard, or ha smoothed rsi for the line plot and/or histogram
def RSI = f_rsi( i_source, i_lenRSI, i_mode );
plot RSI_OL = if i_showPlot then RSI else na;
RSI_OL.setDefaultColor(GlobalColor("RSI"));
def o = f_Open(i_lenHARSI, i_smoothing);
def h = f_High(i_lenHARSI , i_smoothing);
def l = f_Low(i_lenHARSI , i_smoothing);
def c = f_Close(i_lenHARSI);
def isExp = AbsValue( c - o ) >= AbsValue( c[1] - o[1]);
# Plot UP candle with isBull only
def UpO1; def UpH1; def UpL1; def UpC1;
if o < c then {UpO1 = o ; UpH1 = h ; UpL1 = l ; UpC1 = c; } else
{UpO1 = na; UpH1 = na; UpL1 = na; UpC1 = na;}
# Plot UP candle with isBull and isExp
def UpO; def UpH; def UpL; def UpC;
if o < c and isExp then {UpO = o ; UpH = h ; UpL = l ; UpC = c; } else
{UpO = na; UpH = na; UpL = na; UpC = na;}
# Plot DOWN candle
def DnO; def DnH; def DnL; def DnC;
if o > c and !isExp then {DnO = o ; DnH = h ; DnL = l ; DnC = c; } else
{DnO = na; DnH = na; DnL = na; DnC = na;}
# Plot DOWN candle with !isBull and !isExp
def DnO1; def DnH1; def DnL1; def DnC1;
if o > c then {DnO1 = o ; DnH1 = h ; DnL1 = l ; DnC1 = c; } else
{DnO1 = na; DnH1 = na; DnL1 = na; DnC1 = na;}
# Plot the new Chart
AddChart(high = UpH1, low = UpL1, open = UpC1, close = UpO1,
type = ChartType.CANDLE, growcolor = GlobalColor("UPTICK"));
AddChart(high = UpH , low = UpL , open = UpC, close = UpO,
type = ChartType.CANDLE, growcolor = GlobalColor("UP"));
AddChart(high = DnH1, low = DnL1, open = DnO1, close = DnC1,
type = ChartType.CANDLE, growcolor = GlobalColor("DOWNTICK"));
AddChart(high = DnH , low = DnL , open = DnO, close = DnC,
type = ChartType.CANDLE, growcolor = GlobalColor("DOWN"));
#####
def upperx = i_upperx;
#upperx.SetDefaultColor(Color.DARK_RED);
#upperx.SetStyle(Curve.FIRM);
def upper = i_upper;
#upper.SetDefaultColor(Color.DARK_RED);
#upper.SetStyle(Curve.SHORT_DASH);
plot median = 0;
#median.SetDefaultColor(Color.DARK_GRAY);
#median.SetStyle(Curve.LONG_DASH);
def lower = i_lower;
#lower.SetDefaultColor(Color.DARK_GREEN);
#lower.SetStyle(Curve.SHORT_DASH);
def lowerx = i_lowerx;
#lowerx.SetDefaultColor(Color.DARK_GREEN);
#lowerx.SetStyle(Curve.FIRM);
addcloud (upperx, upper, color.dark_red,color.dark_red,no);
addcloud (lower, lowerx, color.dark_green,color.dark_green,no);
Last edited: