RSI-Heiken Ashi For ThinkOrSwim

this is my mod script for TV - Heikin Ashi RSI Oscillator.

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

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 by a moderator:
Last edited:

cos251

Well-known member
RSI-Heiken Ashi For ThinkOrSwim
Not sure how accurate I have this. Trying to play with the isBull and isExp variables to make sure colors match. Had to add 4x AddChart()

Updated Image
hUqZ7kF.jpg


Version 1.1 of RSI_Div_Candles per @High_Velocity request.
(Thx @germanburrito for AddChart() logic)
Fixed/Added the following:
  1. Fixed hollow UP Candles - fix provided by @SleepyZ
  2. Adjusted OB/OS option to turn on/off
  3. Added Visual Divergence Lines - credit @SuryaKiranC

Ruby:
## RSI_DIV_CANDLES
##
##
## CREDITS
## Requested by @High_Velocity from orignal source https://www.tradingview.com/v/4VKd87zy/
##
##
## Removing the header Credit credits and description is not permitted, any modification needs to be shared.
##
## V 1.1 :    @cos251 - @SleepyZ provided fix for hollow UP candles.  @SuryaKiranC provided Divergence line identifier
##                      Added option to turn on/off OB/OS lines.
##
## V 1.0 :    @cos251 - Initial release per request from usethinkscript forum.  Logic appears to match, Candle wicks may need additional
##       :    tweaking; thanks to @germanburrito for sharing AddChart() logic

declare lower;

input useHL          = no;
input price          = close;
input fastLength     = 8;
input slowLength     = 55;
input smooth         = 10;
input overBought     = 70;
input overSold       = 30;
input showOBOS       = no;
input showDivergence = yes;

def fastRSI = reference RSI(length = fastLength, price = price);
def slowRSI = reference RSI(length = slowLength, price = price);

def smoothFastRSI = MovingAverage(AverageType.WILDERS,fastRSI,smooth);
def smoothSlowRSI = MovingAverage(AverageType.WILDERS,slowRSI,smooth);

def rsiHigh = if useHL then Max(RSI(length = fastLength, price = high),RSI(length=slowLength,price = high)) else MAX(fastRSI,slowRSI);
def rsiLow = if useHL then MIN(RSI(length=fastLength,price=low),RSI(length=slowLength,price=low)) else MIN(fastRSI,slowRSI);

def isBull = smoothFastRSI >= smoothSlowRSI;
def isExp = AbsValue(smoothFastRSI-smoothSlowRSI) >= AbsValue(smoothFastRSI[1]-smoothSlowRSI[1]);

def o = smoothSlowRSI;
def h = rsiHigh;
def l = rsiLow;
def c = smoothFastRSI;

# Plot UP candle with isBull only
def UpO1;
def UpH1;
def UpL1;
def UpC1;
if o < c and isBull
then {
    UpO1 = o;
    UpH1 = h;
    UpL1 = l;
    UpC1 = c;
} else {
    UpO1 = Double.NaN;
    UpH1 = Double.NaN;
    UpL1 = Double.NaN;
    UpC1 = Double.NaN;
}

# Plot UP candle with isBull and isExp
def UpO;
def UpH;
def UpL;
def UpC;
if o < c and isBull and isExp
then {
    UpO = o;
    UpH = h;
    UpL = l;
    UpC = c;
} else {
    UpO = Double.NaN;
    UpH = Double.NaN;
    UpL = Double.NaN;
    UpC = Double.NaN;
}

# Plot DOWN candle
def DnO;
def DnH;
def DnL;
def DnC;
if o > c
then {
    DnO = o;
    DnH = h;
    DnL = l;
    DnC = c;
} else {
    DnO = Double.NaN;
    DnH = Double.NaN;
    DnL = Double.NaN;
    DnC = Double.NaN;
}


# Plot DOWN candle with !isBull and !isExp
def DnO1;
def DnH1;
def DnL1;
def DnC1;
if o > c and !isBull and !isExp
then {
    DnO1 = o;
    DnH1 = h;
    DnL1 = l;
    DnC1 = c;
} else {
    DnO1 = Double.NaN;
    DnH1 = Double.NaN;
    DnL1 = Double.NaN;
    DnC1 = Double.NaN;
}

# Plot the new Chart
#AddChart(high = UpH1, low = UpL1, open = UpO1, close = UpC1, type = ChartType.CANDLE, growcolor = Color.PINK);
#AddChart(high = UpH, low = UpL, open = UpO, close = UpC, type = ChartType.CANDLE, growcolor = Color.GREEN);
AddChart(high = UpH1, low = UpL1, open = Upc1, close = Upo1, type = ChartType.CANDLE, growcolor = Color.PINK);
AddChart(high = UpH, low = UpL, open = Upc, close = Upo, type = ChartType.CANDLE, growcolor = Color.GREEN);
AddChart(high = DnH, low = DnL, open = DnO, close = DnC, type = ChartType.CANDLE, growcolor = Color.RED);
AddChart(high = DnH1, low = DnL1, open = DnO1, close = DnC1, type = ChartType.CANDLE, growcolor = Color.CYAN);

plot ob = if showOBOS then overBought else Double.NaN;
ob.SetDefaultColor(COLOR.RED);
plot os = if showOBOS then overSold else Double.NaN;
os.SetDefaultColor(COLOR.GREEN);

def BN = barnumber();

#Divergence Code

def RSI_H = if fastRSI > overBought then fold Ri = 1 to Floor(fastLength / 2) with Rp = 1 while Rp do fastRSI > GetValue(fastRSI, -Ri) else 0;
def RSI_PivotH = if (BN > fastLength and fastRSI == Highest(fastRSI, Floor(fastLength / 2)) and RSI_H) then fastRSI else Double.NaN;
def RSI_L = if fastRSI < overSold then fold Rj = 1 to Floor(fastLength / 2) with Rq = 1 while Rq do fastRSI < GetValue(fastRSI, -Rj) else 0;
def RSI_PivotL = if (BN > fastLength and fastRSI == Lowest(fastRSI, Floor(fastLength / 2)) and RSI_L) then fastRSI else Double.NaN;
def RSI_PHBar = if !IsNaN(RSI_PivotH) then BN else RSI_PHBar[1];
def RSI_PLBar = if !IsNaN(RSI_PivotL) then BN else RSI_PLBar[1];
def RSI_PHPoint = if !IsNaN(RSI_PivotH) then RSI_PivotH else RSI_PHPoint[1];
def RSI_LastPHBar = if RSI_PHPoint != RSI_PHPoint[1] then RSI_PHBar[1] else RSI_LastPHBar[1];
def RSI_PLPoint = if !IsNaN(RSI_PivotL) then RSI_PivotL else RSI_PLPoint[1];
def RSI_LastPLBar = if RSI_PLPoint != RSI_PLPoint[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 RSI_PivotH else Double.NaN;

plot RSI_plotHline = if showDivergence then RSI_pivotHigh else Double.NaN;
RSI_plotHline.EnableApproximation();
RSI_plotHline.SetDefaultColor(Color.LIME);
RSI_plotHline.SetStyle(Curve.SHORT_DASH);

plot RSI_pivotLow = if showDivergence and RSI_LowPivots then RSI_PivotL else Double.NaN;
RSI_pivotLow.EnableApproximation();
RSI_pivotLow.SetDefaultColor(Color.LIME);
RSI_pivotLow.SetStyle(Curve.SHORT_DASH);

plot RSI_pivotDot = if !IsNaN(RSI_pivotHigh) then RSI_pivo[ATTACH=full]11413[/ATTACH]tHigh else if !IsNaN(RSI_pivotLow) then RSI_pivotLow else Double.NaN;
RSI_pivotDot.SetDefaultColor(Color.LIME);
RSI_pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
RSI_pivotDot.SetLineWeight(3);

AddLabel(yes,"RSI:",Color.YELLOW);

UPPER STUDY VERSION 1.0 (per request from @TradeUp)
This is the upper version as requested (pretty lean on code too).
For now only includes the candle coloring, will have to work on plotting the Divergence Lines.
BGDMrrq.jpg


Code:
## RSI_DIV_CANDLES_Upper
##
##
## CREDITS
## Requested by @High_Velocity from orignal source https://www.tradingview.com/v/4VKd87zy/
## Upper Study requested by @TradeUp
##
##
##
## V 1.0 :    @cos251 - Initial release of UPPER version per request from usethinkscript forum. Logic adopted from lower study
##       :    tweaking; thanks to @germanburrito for sharing AddChart() logic

declare upper;

input useHL          = no;
input price          = close;
input fastLength     = 14;
input slowLength     = 55;
input smooth         = 10;
#input showDivergence = yes;
input paintBars      = yes;


def fastRSI = reference RSI(length = fastLength, price = price);
def slowRSI = reference RSI(length = slowLength, price = price);

def smoothFastRSI = MovingAverage(AverageType.WILDERS,fastRSI,smooth);
def smoothSlowRSI = MovingAverage(AverageType.WILDERS,slowRSI,smooth);

def rsiHigh = if useHL then Max(RSI(length = fastLength, price = high),RSI(length=slowLength,price = high)) else MAX(fastRSI,slowRSI);
def rsiLow = if useHL then MIN(RSI(length=fastLength,price=low),RSI(length=slowLength,price=low)) else MIN(fastRSI,slowRSI);

def isBull = smoothFastRSI >= smoothSlowRSI;
def isExp = AbsValue(smoothFastRSI-smoothSlowRSI) >= AbsValue(smoothFastRSI[1]-smoothSlowRSI[1]);

def o = smoothSlowRSI;
def h = rsiHigh;
def l = rsiLow;
def c = smoothFastRSI;

AssignPriceColor(if paintBars and o < c and isBull and isExp then Color.GREEN else if paintBars and o > c and !isBull and !isExp then Color.CYAN else if paintBars and o > c and !isBull then Color.RED else if paintBars then Color.PINK else Color.CURRENT);
 
Last edited by a moderator:
@cos251
@germanburrito
@SleepyZ

The indicator now works as expected. Thanks for your help. The next challenge is writing a scanner on 15 minutes. With the following
DOWN candle with Bull and not isExp
(this is signal is for short trades when the candle is bull and weak “pink color” with wick pointing down; print red dot or Red circle).
OR
UP candle with not Bull and isExp
(this signal is for long trades when the candle is bear and weak “pink color” with wick pointing up; print Green dot or Green circle).
 
Last edited:
OK, I like this indicator now that I've looked at it more.
It pairs nice with vol RoC

Updated colors to be more uniform


Code:
## RSI_DIV_CANDLES
##
##
## CREDITS
## Requested by @High_Velocity from orignal source https://www.tradingview.com/v/4VKd87zy/
##
##
## Removing the header Credit credits and description is not permitted, any modification needs to be shared.
##
## V 1.1 :    @cos252 - @SleepyZ provided fix for hollow UP candles.  @SuryaKiranC provided Divergence line identifier
##                      Added option to turn on/off OB/OS lines.
##
## V 1.0 :    @cos251 - Initial release per request from usethinkscript forum.  Logic appears to match, Candle wicks may need additional
##       :    tweaking; thanks to @germanburrito for sharing AddChart() logic

declare lower;

input useHL          = no;
input price          = close;
input fastLength     = 8;
input slowLength     = 55;
input smooth         = 10;
input overBought     = 70;
input overSold       = 30;
input showOBOS       = no;
input showDivergence = yes;

def fastRSI = reference RSI(length = fastLength, price = price);
def slowRSI = reference RSI(length = slowLength, price = price);

def smoothFastRSI = MovingAverage(AverageType.WILDERS,fastRSI,smooth);
def smoothSlowRSI = MovingAverage(AverageType.WILDERS,slowRSI,smooth);

def rsiHigh = if useHL then Max(RSI(length = fastLength, price = high),RSI(length=slowLength,price = high)) else MAX(fastRSI,slowRSI);
def rsiLow = if useHL then MIN(RSI(length=fastLength,price=low),RSI(length=slowLength,price=low)) else MIN(fastRSI,slowRSI);

def isBull = smoothFastRSI >= smoothSlowRSI;
def isExp = AbsValue(smoothFastRSI-smoothSlowRSI) >= AbsValue(smoothFastRSI[1]-smoothSlowRSI[1]);

def o = smoothSlowRSI;
def h = rsiHigh;
def l = rsiLow;
def c = smoothFastRSI;

# Plot UP candle with isBull only
def UpO1;
def UpH1;
def UpL1;
def UpC1;
if o < c and isBull
then {
    UpO1 = o;
    UpH1 = h;
    UpL1 = l;
    UpC1 = c;
} else {
    UpO1 = Double.NaN;
    UpH1 = Double.NaN;
    UpL1 = Double.NaN;
    UpC1 = Double.NaN;
}

# Plot UP candle with isBull and isExp
def UpO;
def UpH;
def UpL;
def UpC;
if o < c and isBull and isExp
then {
    UpO = o;
    UpH = h;
    UpL = l;
    UpC = c;
} else {
    UpO = Double.NaN;
    UpH = Double.NaN;
    UpL = Double.NaN;
    UpC = Double.NaN;
}

# Plot DOWN candle
def DnO;
def DnH;
def DnL;
def DnC;
if o > c
then {
    DnO = o;
    DnH = h;
    DnL = l;
    DnC = c;
} else {
    DnO = Double.NaN;
    DnH = Double.NaN;
    DnL = Double.NaN;
    DnC = Double.NaN;
}


# Plot DOWN candle with !isBull and !isExp
def DnO1;
def DnH1;
def DnL1;
def DnC1;
if o > c and !isBull and !isExp
then {
    DnO1 = o;
    DnH1 = h;
    DnL1 = l;
    DnC1 = c;
} else {
    DnO1 = Double.NaN;
    DnH1 = Double.NaN;
    DnL1 = Double.NaN;
    DnC1 = Double.NaN;
}

# Plot the new Chart
#AddChart(high = UpH1, low = UpL1, open = UpO1, close = UpC1, type = ChartType.CANDLE, growcolor = Color.PINK);
#AddChart(high = UpH, low = UpL, open = UpO, close = UpC, type = ChartType.CANDLE, growcolor = Color.GREEN);
AddChart(high = UpH1, low = UpL1, open = Upc1, close = Upo1, type = ChartType.CANDLE, growcolor = CreateColor(0,166,50));
AddChart(high = UpH, low = UpL, open = Upc, close = Upo, type = ChartType.CANDLE, growcolor = CreateColor(0,110,33));
AddChart(high = DnH, low = DnL, open = DnO, close = DnC, type = ChartType.CANDLE, growcolor = CreateColor(117,0,14));
AddChart(high = DnH1, low = DnL1, open = DnO1, close = DnC1, type = ChartType.CANDLE, growcolor = CreateColor(173,0,20));

plot ob = if showOBOS then overBought else Double.NaN;
ob.SetDefaultColor(COLOR.RED);
plot os = if showOBOS then overSold else Double.NaN;
os.SetDefaultColor(COLOR.GREEN);

def BN = barnumber();

#Divergence Code

def RSI_H = if fastRSI > overBought then fold Ri = 1 to Floor(fastLength / 2) with Rp = 1 while Rp do fastRSI > GetValue(fastRSI, -Ri) else 0;
def RSI_PivotH = if (BN > fastLength and fastRSI == Highest(fastRSI, Floor(fastLength / 2)) and RSI_H) then fastRSI else Double.NaN;
def RSI_L = if fastRSI < overSold then fold Rj = 1 to Floor(fastLength / 2) with Rq = 1 while Rq do fastRSI < GetValue(fastRSI, -Rj) else 0;
def RSI_PivotL = if (BN > fastLength and fastRSI == Lowest(fastRSI, Floor(fastLength / 2)) and RSI_L) then fastRSI else Double.NaN;
def RSI_PHBar = if !IsNaN(RSI_PivotH) then BN else RSI_PHBar[1];
def RSI_PLBar = if !IsNaN(RSI_PivotL) then BN else RSI_PLBar[1];
def RSI_PHPoint = if !IsNaN(RSI_PivotH) then RSI_PivotH else RSI_PHPoint[1];
def RSI_LastPHBar = if RSI_PHPoint != RSI_PHPoint[1] then RSI_PHBar[1] else RSI_LastPHBar[1];
def RSI_PLPoint = if !IsNaN(RSI_PivotL) then RSI_PivotL else RSI_PLPoint[1];
def RSI_LastPLBar = if RSI_PLPoint != RSI_PLPoint[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 RSI_PivotH else Double.NaN;

plot RSI_plotHline = if showDivergence then RSI_pivotHigh else Double.NaN;
RSI_plotHline.EnableApproximation();
RSI_plotHline.SetDefaultColor(Color.DARK_GRAY);
RSI_plotHline.SetStyle(Curve.SHORT_DASH);

plot RSI_pivotLow = if showDivergence and RSI_LowPivots then RSI_PivotL else Double.NaN;
RSI_pivotLow.EnableApproximation();
RSI_pivotLow.SetDefaultColor(Color.DARK_GRAY);
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 Double.NaN;
RSI_pivotDot.SetDefaultColor(Color.LIME);
RSI_pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
RSI_pivotDot.SetLineWeight(3);

AddLabel(yes,"RSI:",Color.LIGHT_GRAY);
i8W3TB8.png
 
Last edited:
Thank you for your comment - this doesn't seem to do what the TV HARSI does - IMO - as the TV Harsi has zones to easily see when to go Long or Short - that is too simplistic of course - but it is Backtesting pretty well on TV
Try this. I wanted to test doing AddChart again so I took a stab at this one as well. I did not include the RSI histogram or the Stochastic plot. Both were unnecessary. Feel free to add if you like.

QUICK UPDATE - Added divergence code provided by @SuryaKiranC

Mm65IQU.jpg



Ruby:
## HARSI_Oscillator
##
##
## CREDITS
## Requested by @MatthewTherrien from orignal source https://www.tradingview.com/script/1o4oWbEx-Heikin-Ashi-RSI-Oscillator/
##
##
## Removing the header Credit credits and description is not permitted, any modification needs to be shared.
##
## V 1.1 :    @cos251 - Added divergence code provided by @SuryaKiranC
##
## V 1.0 :    @cos251 - Initial release per request from usethinkscript forum. 
##       :    Did not include stochasitc plots

declare lower;

input i_upper        = 20;
input i_upperx       = 30;
input i_lenRSI       = 7;
input i_lenHARSI     = 14;
input i_smoothing    = 1;
input showDivergence = yes;
input showOBOS       = yes;
input i_RSISmooth    = yes;
input cType          = ChartType.CANDLE;


# --- RSI Line Plot (Orange)
def _zrsi = reference RSI(price = ohlc4, length = i_lenRSI) - 50;
def _smooth = if IsNaN(_smooth[1]) then _zrsi else (_smooth[1] + _zrsi) / 2;
def rsivar = if i_RSISmooth then _smooth else _zrsi;
plot RSI = rsivar;
RSI.SetDefaultColor(Color.ORANGE);
# --- End RSI Line Plot


# --- Heikin Ashi RSI O,H,L,C Calculations
def closeRSI = reference RSI(price = close, length = i_lenHARSI) - 50;
def openRSI = if IsNaN(closeRSI[1]) then closeRSI else closeRSI[1];
def highRSI_raw = reference RSI(price = high, length = i_lenHARSI) - 50;
def lowRSI_raw = reference RSI(price = low, length = i_lenHARSI) - 50;
def highRSI = Max(highRSI_raw, lowRSI_raw);
def lowRSI = Min(highRSI_raw, lowRSI_raw);
def _close = (openRSI + highRSI + lowRSI + closeRSI) / 4;
def _open = if IsNaN(_open[i_smoothing]) then (openRSI + closeRSI) / 2 else ((_open[1] * i_smoothing) + _close[1]) / (i_smoothing + 1);
def _high = Max( highRSI, Max( _open, _close ) );
def _low = Min( lowRSI,  Min( _open, _close ) );

def o = _open;
def h = _high;
def l = _low;
def c = _close;

# --- End Heikin Ashi O,H,L,C


# OHLC UP candle
def UpO;
def UpH;
def UpL;
def UpC;
if o < c
then {
    UpO = o;
    UpH = h;
    UpL = l;
    UpC = c;
} else {
    UpO = Double.NaN;
    UpH = Double.NaN;
    UpL = Double.NaN;
    UpC = Double.NaN;
}

# OHLC DOWN candle
def DnO;
def DnH;
def DnL;
def DnC;
if o > c
then {
    DnO = o;
    DnH = h;
    DnL = l;
    DnC = c;
} else {
    DnO = Double.NaN;
    DnH = Double.NaN;
    DnL = Double.NaN;
    DnC = Double.NaN;
}

# --- Plot OB/OS areas
plot ob = if showOBOS then i_upper else Double.NaN;
plot obextreme = if showOBOS then i_upperx else Double.NaN;
ob.SetDefaultColor(Color.RED);
obextreme.SetDefaultColor(Color.RED);
plot os = if showOBOS then -i_upper else Double.NaN;
plot osextreme = if showOBOS then -i_upperx else Double.NaN;
os.SetDefaultColor(Color.GREEN);
osextreme.SetDefaultColor(Color.GREEN);
AddCloud(if showOBOS then ob else Double.NaN, if showOBOS then Double.POSITIVE_INFINITY else Double.NaN, Color.RED);
AddCloud(if showOBOS then os else Double.NaN, if showOBOS then Double.NEGATIVE_INFINITY else Double.NaN, Color.GREEN);
plot z = 0;
z.SetDefaultColor(Color.GRAY);


# Plot the new Chart
AddChart(high = UpH, low = UpL, open = UpC, close = UpO, type = cType, growcolor = Color.GREEN);
AddChart(high = DnH, low = DnL, open = DnO, close = DnC, type = cTYpe, growcolor = Color.RED);


def BN = barnumber();

#Divergence Code

def RSI_H = if RSI > ob then fold Ri = 1 to Floor(i_lenRSI / 2) with Rp = 1 while Rp do RSI > GetValue(RSI, -Ri) else 0;
def RSI_PivotH = if (BN > i_lenRSI and RSI == Highest(RSI, Floor(i_lenRSI / 2)) and RSI_H) then RSI else Double.NaN;
def RSI_L = if RSI < os then fold Rj = 1 to Floor(i_lenRSI / 2) with Rq = 1 while Rq do RSI < GetValue(RSI, -Rj) else 0;
def RSI_PivotL = if (BN > i_lenRSI and RSI == Lowest(RSI, Floor(i_lenRSI / 2)) and RSI_L) then RSI else Double.NaN;
def RSI_PHBar = if !IsNaN(RSI_PivotH) then BN else RSI_PHBar[1];
def RSI_PLBar = if !IsNaN(RSI_PivotL) then BN else RSI_PLBar[1];
def RSI_PHPoint = if !IsNaN(RSI_PivotH) then RSI_PivotH else RSI_PHPoint[1];
def RSI_LastPHBar = if RSI_PHPoint != RSI_PHPoint[1] then RSI_PHBar[1] else RSI_LastPHBar[1];
def RSI_PLPoint = if !IsNaN(RSI_PivotL) then RSI_PivotL else RSI_PLPoint[1];
def RSI_LastPLBar = if RSI_PLPoint != RSI_PLPoint[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 RSI_PivotH else Double.NaN;

plot RSI_plotHline = if showDivergence then RSI_pivotHigh else Double.NaN;
RSI_plotHline.EnableApproximation();
RSI_plotHline.SetDefaultColor(Color.LIME);
RSI_plotHline.SetStyle(Curve.SHORT_DASH);

plot RSI_pivotLow = if showDivergence and RSI_LowPivots then RSI_PivotL else Double.NaN;
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 Double.NaN;
RSI_pivotDot.SetDefaultColor(Color.LIME);
RSI_pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
RSI_pivotDot.SetLineWeight(3);
 
Last edited:
Magenta color with wick pointing down for short trade -------> Add to watch list and plot red circle.
Cyan color with wick pointing up for long trade -------> Add to watch list and plot a green circle.
 
Folks - my humble suggestion is to use the HA RSI for trend following trades rather than for reversals.
Try to keep the candles without the smoothening setting. Look to go long when the candles cross the zero line from below and the opposite for shorts...you may add a macd histogram (with an 8/13/21 setting) or another indicator for a double confirmation..

Trying to finding the bottom and trade reversals using this indicator or any other for that matter is a trade that
looks tempting and simple, but is not worth it!!
 
Here's a scalping system using the RSI and the Heiken Ashi. It appears to have combined the code of both, but doesn't have buy/sell signals. Has anyone seen something like this in this forum? Take a look at this YouTube video.

HARSHI Chart Video
 
@Picard I have not seen this in thinkscript. It is available on Tradingview pinescript. Thanks for the link, I think it has merit, I'm going to strategize it on Tradingview, its too much to convert to TOS. I have realized you don't have to think in terms of one platform anymore when you can work with several and even interlink strategies and trading platforms. Actually I have found some studies just do better in certain platforms.
 
Here's a scalping system using the RSI and the Heiken Ashi. It appears to have combined the code of both, but doesn't have buy/sell signals. Has anyone seen something like this in this forum? Take a look at this YouTube video.

HARSHI Chart Video
I moved your post to this thread. You will find a few variations of the RSI, Heiken.
Start here: https://usethinkscript.com/threads/rsi-heiken-ashi-for-thinkorswim.7250/#post-70605 and read your way through.
@irishgold
 
Last edited:
OK, I like this indicator now that I've looked at it more.
It pairs nice with vol RoC

Updated colors to be more uniform


Code:
## RSI_DIV_CANDLES
##
##
## CREDITS
## Requested by @High_Velocity from orignal source https://www.tradingview.com/v/4VKd87zy/
##
##
## Removing the header Credit credits and description is not permitted, any modification needs to be shared.
##
## V 1.1 :    @cos252 - @SleepyZ provided fix for hollow UP candles.  @SuryaKiranC provided Divergence line identifier
##                      Added option to turn on/off OB/OS lines.
##
## V 1.0 :    @cos251 - Initial release per request from usethinkscript forum.  Logic appears to match, Candle wicks may need additional
##       :    tweaking; thanks to @germanburrito for sharing AddChart() logic

declare lower;

input useHL          = no;
input price          = close;
input fastLength     = 8;
input slowLength     = 55;
input smooth         = 10;
input overBought     = 70;
input overSold       = 30;
input showOBOS       = no;
input showDivergence = yes;

def fastRSI = reference RSI(length = fastLength, price = price);
def slowRSI = reference RSI(length = slowLength, price = price);

def smoothFastRSI = MovingAverage(AverageType.WILDERS,fastRSI,smooth);
def smoothSlowRSI = MovingAverage(AverageType.WILDERS,slowRSI,smooth);

def rsiHigh = if useHL then Max(RSI(length = fastLength, price = high),RSI(length=slowLength,price = high)) else MAX(fastRSI,slowRSI);
def rsiLow = if useHL then MIN(RSI(length=fastLength,price=low),RSI(length=slowLength,price=low)) else MIN(fastRSI,slowRSI);

def isBull = smoothFastRSI >= smoothSlowRSI;
def isExp = AbsValue(smoothFastRSI-smoothSlowRSI) >= AbsValue(smoothFastRSI[1]-smoothSlowRSI[1]);

def o = smoothSlowRSI;
def h = rsiHigh;
def l = rsiLow;
def c = smoothFastRSI;

# Plot UP candle with isBull only
def UpO1;
def UpH1;
def UpL1;
def UpC1;
if o < c and isBull
then {
    UpO1 = o;
    UpH1 = h;
    UpL1 = l;
    UpC1 = c;
} else {
    UpO1 = Double.NaN;
    UpH1 = Double.NaN;
    UpL1 = Double.NaN;
    UpC1 = Double.NaN;
}

# Plot UP candle with isBull and isExp
def UpO;
def UpH;
def UpL;
def UpC;
if o < c and isBull and isExp
then {
    UpO = o;
    UpH = h;
    UpL = l;
    UpC = c;
} else {
    UpO = Double.NaN;
    UpH = Double.NaN;
    UpL = Double.NaN;
    UpC = Double.NaN;
}

# Plot DOWN candle
def DnO;
def DnH;
def DnL;
def DnC;
if o > c
then {
    DnO = o;
    DnH = h;
    DnL = l;
    DnC = c;
} else {
    DnO = Double.NaN;
    DnH = Double.NaN;
    DnL = Double.NaN;
    DnC = Double.NaN;
}


# Plot DOWN candle with !isBull and !isExp
def DnO1;
def DnH1;
def DnL1;
def DnC1;
if o > c and !isBull and !isExp
then {
    DnO1 = o;
    DnH1 = h;
    DnL1 = l;
    DnC1 = c;
} else {
    DnO1 = Double.NaN;
    DnH1 = Double.NaN;
    DnL1 = Double.NaN;
    DnC1 = Double.NaN;
}

# Plot the new Chart
#AddChart(high = UpH1, low = UpL1, open = UpO1, close = UpC1, type = ChartType.CANDLE, growcolor = Color.PINK);
#AddChart(high = UpH, low = UpL, open = UpO, close = UpC, type = ChartType.CANDLE, growcolor = Color.GREEN);
AddChart(high = UpH1, low = UpL1, open = Upc1, close = Upo1, type = ChartType.CANDLE, growcolor = CreateColor(0,166,50));
AddChart(high = UpH, low = UpL, open = Upc, close = Upo, type = ChartType.CANDLE, growcolor = CreateColor(0,110,33));
AddChart(high = DnH, low = DnL, open = DnO, close = DnC, type = ChartType.CANDLE, growcolor = CreateColor(117,0,14));
AddChart(high = DnH1, low = DnL1, open = DnO1, close = DnC1, type = ChartType.CANDLE, growcolor = CreateColor(173,0,20));

plot ob = if showOBOS then overBought else Double.NaN;
ob.SetDefaultColor(COLOR.RED);
plot os = if showOBOS then overSold else Double.NaN;
os.SetDefaultColor(COLOR.GREEN);

def BN = barnumber();

#Divergence Code

def RSI_H = if fastRSI > overBought then fold Ri = 1 to Floor(fastLength / 2) with Rp = 1 while Rp do fastRSI > GetValue(fastRSI, -Ri) else 0;
def RSI_PivotH = if (BN > fastLength and fastRSI == Highest(fastRSI, Floor(fastLength / 2)) and RSI_H) then fastRSI else Double.NaN;
def RSI_L = if fastRSI < overSold then fold Rj = 1 to Floor(fastLength / 2) with Rq = 1 while Rq do fastRSI < GetValue(fastRSI, -Rj) else 0;
def RSI_PivotL = if (BN > fastLength and fastRSI == Lowest(fastRSI, Floor(fastLength / 2)) and RSI_L) then fastRSI else Double.NaN;
def RSI_PHBar = if !IsNaN(RSI_PivotH) then BN else RSI_PHBar[1];
def RSI_PLBar = if !IsNaN(RSI_PivotL) then BN else RSI_PLBar[1];
def RSI_PHPoint = if !IsNaN(RSI_PivotH) then RSI_PivotH else RSI_PHPoint[1];
def RSI_LastPHBar = if RSI_PHPoint != RSI_PHPoint[1] then RSI_PHBar[1] else RSI_LastPHBar[1];
def RSI_PLPoint = if !IsNaN(RSI_PivotL) then RSI_PivotL else RSI_PLPoint[1];
def RSI_LastPLBar = if RSI_PLPoint != RSI_PLPoint[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 RSI_PivotH else Double.NaN;

plot RSI_plotHline = if showDivergence then RSI_pivotHigh else Double.NaN;
RSI_plotHline.EnableApproximation();
RSI_plotHline.SetDefaultColor(Color.DARK_GRAY);
RSI_plotHline.SetStyle(Curve.SHORT_DASH);

plot RSI_pivotLow = if showDivergence and RSI_LowPivots then RSI_PivotL else Double.NaN;
RSI_pivotLow.EnableApproximation();
RSI_pivotLow.SetDefaultColor(Color.DARK_GRAY);
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 Double.NaN;
RSI_pivotDot.SetDefaultColor(Color.LIME);
RSI_pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
RSI_pivotDot.SetLineWeight(3);

AddLabel(yes,"RSI:",Color.LIGHT_GRAY);
i8W3TB8.png
Would it be possible to Add option to turn on/off the Candles to just have the #Divergence? or just have the Divergence in upper on Price?
 
Would it be possible to Add option to turn on/off the Candles to just have the #Divergence? or just have the Divergence in upper on Price?
If you turn off the candles that means you just want the RSI?
You can plot RSI on the upper chart with the ToS built-in indicator: ReverseEngineeringRSI
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
317 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top