#// 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, added stock and alerts.
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 showDivergence = yes;
def ob = overbought;
def os = oversold;
def BN = barnumber();
#Divergence Code
def lenRSI = floor(rsiLength / 2);
def rsi = nRSI;
def RSI_H = if RSI > ob then
fold Ri = 1 to lenRSI with Rp = 1 while Rp do
RSI > GetValue(RSI, -Ri) else 0;
def RSI_L = if RSI < os then
fold Rj = 1 to lenRSI with Rq = 1 while Rq do
RSI < GetValue(RSI, -Rj) else 0;
def pvtH = if (BN > rsiLength and RSI == Highest(RSI, lenRSI) and RSI_H) then RSI else na;
def pvtL = if (BN > rsiLength and RSI == Lowest(RSI, lenRSI) and RSI_L) then RSI else na;
def RSI_PHBar = if !IsNaN(pvtH) then BN else RSI_PHBar[1];
def RSI_PLBar = if !IsNaN(pvtL) then BN else RSI_PLBar[1];
def RSI_PHPoint = if !IsNaN(pvtH) then pvtH else RSI_PHPoint[1];
def RSI_PLPoint = if !IsNaN(pvtL) then pvtL else RSI_PLPoint[1];
def RSI_LastPHBar = if RSI_PHBar != RSI_PHBar[1] then RSI_PHBar[1] else RSI_LastPHBar[1];
def RSI_LastPLBar = if RSI_PLBar != RSI_PLBar[1] then RSI_PLBar[1] else RSI_LastPLBar[1];
def RSI_HighPivots = BN >= HighestAll(RSI_LastPHBar);
def RSI_LowPivots = BN >= HighestAll(RSI_LastPLBar);
def RSI_pivotHigh = if RSI_HighPivots then pvtH else na;
plot RSI_plotHline = if showDivergence then RSI_pivotHigh else na;
RSI_plotHline.EnableApproximation();
RSI_plotHline.SetDefaultColor(Color.LIME);
RSI_plotHline.SetStyle(Curve.SHORT_DASH);
plot RSI_pivotLow = if showDivergence and RSI_LowPivots then pvtL else na;
RSI_pivotLow.EnableApproximation();
RSI_pivotLow.SetDefaultColor(Color.LIME);
RSI_pivotLow.SetStyle(Curve.SHORT_DASH);
plot RSI_pivotDot = if !IsNaN(RSI_pivotHigh) then RSI_pivotHigh else
if !IsNaN(RSI_pivotLow) then RSI_pivotLow else na;
RSI_pivotDot.SetDefaultColor(Color.LIME);
RSI_pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
RSI_pivotDot.SetLineWeight(3);
#---- Alerts
Alert(enableAlerts and RSI_pivotLow, "Bullish Div", alertType, alertSound);
Alert(enableAlerts and RSI_pivotHigh, "Bearish Div", alertType, alertSound);
#-- END of CODE