Heikin-Ashi Candles Lower Chart For ThinkorSwim (assorted versions)

The same lower study with additional price levels.
Ruby:
#Heiken_Ashi based on Sylvan Verboort's Trading with HA Candlestick Oscillator
#Bon Bon
#Mono Bollinger Bands Created by Peter Luis

declare lower;
input period = 1;
input hideCandles = no;
input candleSmoothing = {default Valcu, Vervoort};
input show_bubble_labels = yes;
input bubbles = yes;
input arrows = yes;
input price_a = FundamentalType.CLOSE;
input aggregationPeriod = AggregationPeriod.DAY;
input averageType_a = AverageType.exponential;
input averageType1 = AverageType.SIMPLE;
input movingAverageType = {default  TEMA, Exponential, Hull };
input timeFrame = {DAY, default WEEK, MONTH};
input showOnlyToday = no;

def H = high(period = timeFrame)[1];
def L = low(period = timeFrame)[1];
def C_1 = close(period = timeFrame)[1];

def calc_PP = (H + L + C_1) / 3;
def calc_R1 =  (2 * calc_PP) - L;
def calc_R2 = calc_PP + H - L;
def calc_R3 = H + 2 * (calc_PP - L);

def calc_S1 = (2 * calc_PP) - H;
def calc_S2 = calc_PP - H + L;
def calc_S3 = L - 2 * (H - calc_PP);
def openMA;
def closeMA;
def highMA;
def lowMA;

switch (movingAverageType) {
case Exponential:
    openMA = CompoundValue(1, ExpAverage(open, period), open);
    closeMA = CompoundValue(1, ExpAverage(close, period), close);
    highMA = CompoundValue(1, ExpAverage(high, period), high);
    lowMA = CompoundValue(1, ExpAverage(low, period), low);
case Hull:
    openMA = CompoundValue(1, HullMovingAvg(open, period), open);
    closeMA = CompoundValue(1,  HullMovingAvg(close, period), close);
    highMA = CompoundValue(1,  HullMovingAvg(high, period), high);
    lowMA = CompoundValue(1,  HullMovingAvg(low, period), low);
case TEMA:
    openMA = CompoundValue(1, TEMA(open, period), open);
    closeMA = CompoundValue(1, TEMA(close, period), close);
    highMA = CompoundValue(1, TEMA(high, period), high);
    lowMA = CompoundValue(1, TEMA(low, period), low);

}


HidePricePlot(hideCandles);

def haOpen;
def haClose;

switch (candleSmoothing){
case Valcu:
    haOpen = CompoundValue(1, ( (haOpen[1] + (openMA[1] + highMA[1] + lowMA[1] + closeMA[1]) / 4.0) / 2.0), open);
    haClose = ((((openMA + highMA + lowMA + closeMA) / 4.0) + haOpen + Max(highMA, haOpen) + Min(lowMA, haOpen)) / 4.0);
case Vervoort:
    haOpen = CompoundValue(1, ( (haOpen[1] + (openMA[1] + highMA[1] + lowMA[1] + closeMA[1]) / 4.0 ) / 2.0), open);
    haClose = ((((openMA + highMA + lowMA + closeMA) / 4.0) + haOpen + Max(highMA, haOpen) + Min(lowMA, haOpen)) / 4.0);

}

plot o = haOpen;
o.AssignValueColor(if o > o[1] then Color.cyan else if o < o[1] then Color.magenta else color.gray);
o.SetLineWeight (5);
o.Hide();

def haLow =  Min(lowMA, haOpen);
def haHigh = Max(highMA, haOpen);

def avg = 34;
def TMA1 = reference TEMA(haClose, avg); # triple exponential moving average (TEMA) of 34 bars
def TMA2 =  reference TEMA(TMA1, avg);
def Diff = TMA1 - TMA2;
def ZlHa = TMA1 + Diff; #Zero-lagging TEMA average on closing prices - medium term uptrend;


def TMA1_ = reference TEMA((high + low) / 2, avg);
def Diff2 = TMA1_ - TMA2;
def ZlCl = TMA1_ + Diff2; #Zero-lagging TEMA average on closing prices - medium term doenwardtrend;

def ZlDif = ZlCl - ZlHa; # Zero-Lag close - Zero-Lag HA(green candle) Uptrend when ZlDif is equal to or greater than zero

def keep1 = if (haClose >= haOpen and haClose[1] >= haOpen[1]) then 1 else 0;
def keep2 = if ZlDif >= 0 then 1 else 0;
def keep3 = if (AbsValue(close - open) < ((high - low) * 0.35)) and high >= low[1] then 1 else 0;
def keeping = if (keep1 or keep2) then 1 else 0;
def keepall = if keeping or (keeping[1]) and close >= open or close >= (close[1]) then 1 else 0;

def utr = if keepall or (keepall[1]) and keep3 then 1 else 0;


def keep1_ = if (haClose < haOpen and haClose[1] < haOpen[1]) then 1 else 0;
def keep2_ = if ZlDif < 0 then 1 else 0;
def keep3_ = if (AbsValue(close - open) < ((high - low) * 0.35)) and low <= high[1] then 1 else 0;
def keeping_ = if (keep1_ or keep2_) then 1 else 0;
def dkeepall_ = if keeping_ or (keeping_[1]) and close < open or close < (close[1]) then 1 else 0;

def dtr = if dkeepall_ or (dkeepall_[1] - 1) and keep3_ == 1 then 1 else 0;  #downtrend
def upw = if dtr and (dtr[1]) and utr then 1 else 0;
def dnw = if !utr and (utr[1] ) and dtr then 1 else 0;

def results = if upw then 1 else if dnw then 0 else results[1];


input charttype = ChartType.CANDLE;

def haopen_ = if haClose <= haOpen
              then haOpen + 0
             else Double.NaN;

def HAhi   = if haClose <= haOpen
              then haHigh
              else Double.NaN;

def HAlo =   if haClose <= haOpen
              then haLow
              else Double.NaN;


AddChart(growColor = Color.red, neutralColor = Color.CURRENT, high = HAhi, low = HAlo, open = haopen_, close = haClose, type = ChartType.CANDLE);

def HAclose1 = ohlc4;
def HAopen1  = if haClose >= haOpen
               then CompoundValue(1, (haOpen[1] + haClose[1]) / 2, (open[1] + close[1]) / 2)
               else Double.NaN;

def haopen_1 = if haOpen <= haClose
               then HAopen1 + 0  else Double.NaN;

def HAhigh1  = haHigh;
def HAlow1   = haLow;


AddChart(growColor = Color.green, neutralColor = Color.CURRENT,  high = HAhigh1, low = HAlow1, open = haopen_1, close = haClose, type = ChartType.CANDLE);


input price = close;

input displace = 0;

input length = 10;

input Num_Dev_Dn = -1.0;

input Num_Dev_up = 1.0;

def nan  =  Double.NaN;

input averageType = AverageType.SIMPLE;

input fill = yes;

def sDev = StDev(data = price[-displace], length = length);

def MidLine = MovingAverage(averageType, data = price[-displace], length = length);

plot LowerBand = MidLine + Num_Dev_Dn * sDev;

plot UpperBand = MidLine + Num_Dev_up * sDev;

UpperBand.AssignValueColor(if UpperBand > UpperBand[1] then Color.UPTICK else Color.RED);

LowerBand.AssignValueColor(if LowerBand > LowerBand[1] then Color.UPTICK else Color.RED);

AddCloud(UpperBand, LowerBand, Color.GREEN, Color.RED);

def a = (UpperBand > UpperBand[1] and Midline > Midline[1]);
def b = (UpperBand < UpperBand[1] and LowerBand < LowerBand[1]);
def c = (UpperBand > UpperBand[1] and Midline > Midline[1]);
def d = (UpperBand < UpperBand[1] and midline < midline[1]);
def e = average(close)>midline;
def f = midline<average(close);

def Chg      =   If(a, 1, If(b, -1, 0));
def Hold     =   CompoundValue(1, If(Hold[1] == Chg or Chg == 0, Hold[1], If(Chg == 1, 1, -1)), 0);
def Chg_a      =   If((c or e), 1, If((d or f), -1, 0));
def Hold_a     =   CompoundValue(1, If(Hold[1] == Chg or Chg == 0, Hold[1], If(Chg == 1, 1, -1)), 0);
def LBUp     =   if fill and Hold[0] == 1 then lowerBand else nan;
def UBUp     =   if fill and Hold[0] == 1 then upperband else nan;
def LBDn     =   if fill and Hold[0] == -1 then lowerband else nan;
def UBDn     =   if fill and Hold[0] == -1 then upperband else nan;
def MBUP     =   if fill and Hold[0] == 1 then midline else nan;
def MBDn     =   if fill and Hold[0] == -1 then Midline else nan;

DefineGlobalColor("Cloud Up", Color.red);
DefineGlobalColor("Cloud_Up", Color.downtick);
DefineGlobalColor("Cloud_Dn", Color.light_green);
DefineGlobalColor("Cloud Dn", Color.light_green);
AddCloud(LBUp, UBUp, GlobalColor("Cloud Up"), GlobalColor("Cloud Dn"));
AddCloud(LBDn, UBDn, GlobalColor("Cloud Dn"), GlobalColor("Cloud Up"));
AddCloud(MBUp, UBUp, GlobalColor("Cloud_Up"), GlobalColor("Cloud_Dn"));
AddCloud(MBDn, UBDn, GlobalColor("Cloud_Dn"), GlobalColor("Cloud_Up"));

plot Ema5 = MovingAverage(averageType_a, Fundamental(price_a, period = aggregationPeriod), 5);
plot Ema10 = MovingAverage(averageType_a, Fundamental(price_a, period = aggregationPeriod), 10);
plot Ema20 = MovingAverage(averageType_a, Fundamental(price_a, period = aggregationPeriod), 20);
plot Ema50 = MovingAverage(averageType_a, Fundamental(price_a, period = aggregationPeriod), 50);
plot Ema100 = MovingAverage(averageType_a, Fundamental(price_a, period = aggregationPeriod),100);
plot sma200 = MovingAverage(averageType1, Fundamental(price_a, period = aggregationPeriod),200);
ema5.AssignValueColor(if ema5 > ema5[1] then Color.cyan else Color.RED);
ema10.AssignValueColor(if ema10 > ema10[1] then Color.green else Color.light_red);
ema20.AssignValueColor(if ema20 > ema20[1] then Color.white else Color.pink);
ema50.AssignValueColor(if ema50 > ema50[1] then Color.light_green else Color.plum);
ema100.AssignValueColor(if ema100 >ema100[1] then Color.UPTICK else Color.magenta);
sma200.AssignValueColor(if sma200 > sma200[1] then Color.lime else Color.dark_red);
ema5.setLineWeight(2);
ema10.setLineWeight(2);
ema20.setLineWeight(2);
ema50.setLineWeight(3);
ema100.setLineWeight(3);
sma200.setLineWeight(4);



plot R3;
plot R2;
plot R1;
plot PP;
plot S1;
plot S2;
plot S3;

if (showOnlyToday and !IsNaN(close(period = timeFrame)[-1])) or
(getAggregationPeriod() > if timeframe == timeframe.DAY
                          then AggregationPeriod.DAY
                          else if timeframe == timeframe.WEEK
                               then AggregationPeriod.WEEK
                               else AggregationPeriod.MONTH)

then {

    R1 = Double.NaN;
    
    R2 = Double.NaN;
    
    R3 = Double.NaN;
    
    PP = Double.NaN;
    
    S1 = Double.NaN;
    
    S2 = Double.NaN;
    
    S3 = Double.NaN;
  
}
else {
    
  
 R1 = calc_R1;
    
    R2 = calc_R2;
    
    R3 = calc_R3;
    
    PP = calc_PP;
    
    S1 = calc_S1;
    
    S2 = calc_S2;
    
    S3 = calc_S3;

}

R1.SetDefaultColor(color.red);
R2.SetDefaultColor(color.red);
R3.SetDefaultColor(color.red);
S1.SetDefaultColor(color.green);
S2.SetDefaultColor(color.green);
S3.SetDefaultColor(color.green);

R1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
R2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
R3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
S1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
S2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
S3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);;

PP.DefineColor("Color", CreateColor(0, 102, 204));
PP.AssignValueColor(PP.color("Color"));
PP.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
 
I combined regular candles with smoothed Heiken Ashi in a lower study. You can use smoothed the HeiKen Ashi as a moving average to see uptrends or downtrends.
Ruby:
# addchart_peter_redgreen
#Smoothed Heiken Ashi and ATR studies
# https://usethinkscript.com/threads/could-i-have-heikin-ashi-candles-in-lower-section-in-thinkorswim.10428/#post-92406

declare lower;
def o = open;
def h = high;
def l = low;
def c = close;
input period = 10;
input hideCandles = no;
input candleSmoothing = {default Valcu, Vervoort};

input movingAverageType = {Simple, default Exponential, Weighted, Hull, Variable, TEMA};

def openMA;
def closeMA;
def highMA;
def lowMA;

# solid or hollow bars  ( swap open and close)
input solid = yes;

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

} 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;
    DnO = if solid then o else c;
    DnH = h;
    DnL = l;
#    DnC = c;
    DnC = if solid then c else o;
} else {
    DnO = Double.NaN;
    DnH = Double.NaN;
    DnL = Double.NaN;
    DnC = Double.NaN;
}

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);

switch (movingAverageType) {
case Simple:
    openMA = CompoundValue(1, Average(open, period), open);
    closeMA = CompoundValue(1, Average(close, period), close);
    highMA = CompoundValue(1, Average(high, period), high);
    lowMA = CompoundValue(1, Average(low, period), low);
case Exponential:
    openMA = CompoundValue(1, ExpAverage(open, period), open);
    closeMA = CompoundValue(1, ExpAverage(close, period), close);
    highMA = CompoundValue(1, ExpAverage(high, period), high);
    lowMA = CompoundValue(1, ExpAverage(low, period), low);
case Weighted:
    openMA = CompoundValue(1, WMA(open, period), open);
    closeMA = CompoundValue(1, WMA(close, period), close);
    highMA = CompoundValue(1, WMA(high, period), high);
    lowMA = CompoundValue(1, WMA(low, period), low);
case Hull:
    openMA = CompoundValue(1, HullMovingAvg(open, period), open);
    closeMA = CompoundValue(1, HullMovingAvg(close, period), close);
    highMA = CompoundValue(1, HullMovingAvg(high, period), high);
    lowMA = CompoundValue(1, HullMovingAvg(low, period), low);
case Variable:
    openMA = CompoundValue(1, VariableMA(open, period), open);
    closeMA = CompoundValue(1, VariableMA(close, period), close);
    highMA = CompoundValue(1, VariableMA(high, period), high);
    lowMA = CompoundValue(1, VariableMA(low, period), low);
case TEMA:
    openMA = CompoundValue(1, TEMA(open, period), open);
    closeMA = CompoundValue(1, TEMA(close, period), close);
    highMA = CompoundValue(1, TEMA(high, period), high);
    lowMA = CompoundValue(1, TEMA(low, period), low);
}

HidePricePlot(hideCandles);

def haOpen;
def haClose;

switch (candleSmoothing) {
case Valcu:
    haOpen = CompoundValue(1, ( (haOpen[1] + (openMA[1] + highMA[1] + lowMA[1] + closeMA[1]) / 4.0) / 2.0), open);
    haClose = ((openMA + highMA + lowMA + closeMA) / 4.0) ;
case Vervoort:
    haOpen = CompoundValue(1, ( (haOpen[1] + (openMA[1] + highMA[1] + lowMA[1] + closeMA[1]) / 4.0) / 2.0), open);
    haClose = ((((openMA + highMA + lowMA + closeMA) / 4.0) + haOpen + Max(highMA, haOpen) + Min(lowMA, haOpen)) / 4.0);
}

plot o1 = haOpen + 0;
o1.Hide();

def haLow = Min(lowMA, haOpen);
def haHigh = Max(highMA, haOpen);

def haOpen_fall = if haOpen > haClose
              then haOpen
              else Double.NaN;
def haHigh_fall   = if haOpen >= haClose
              then haHigh
              else Double.NaN;
def haLow_fall    = if haOpen >= haClose
              then haLow
              else Double.NaN;
def haClose_fall    = if haOpen >= haClose
              then haClose
              else Double.NaN;

AddChart(growColor = Color.PLUM, fallColor = Color.BLUE, neutralColor = Color.CURRENT, high = haHigh_fall, low = haLow_fall, open = haOpen_fall, close = haClose_fall , type = ChartType.CANDLE);

def haOpen_rise = if haOpen < haClose
                then haClose
                else Double.NaN;
def haHigh_rise  = if haOpen <= haClose
              then haHigh
              else Double.NaN;
def haLow_rise   = if haOpen <= haClose
              then haLow
              else Double.NaN;
def haClose_rise   = if haOpen <= haClose
              then haOpen
              else Double.NaN;

AddChart(growColor = Color.BLUE, fallColor = Color.PLUM, neutralColor = Color.CURRENT, high = haHigh_rise, low = haLow_rise, open = haOpen_rise, close = haClose_rise, type = ChartType.CANDLE);

input TradeInFlatRange = Yes;
input BarsForFlatRange = 4;
input BarsReqToStayInRange = 8;

def HH = Highest(high[1], BarsForFlatRange);
def LL = Lowest(low[1], BarsForFlatRange);
def maxH = Highest(HH, BarsReqToStayInRange);
def maxL = Lowest(LL, BarsReqToStayInRange);
def HHn = if maxH == maxH[1] or maxL == maxL then maxH else HHn[1];
def LLn = if maxH == maxH[1] or maxL == maxL then maxL else LLn[1];
def Bh = if high <= HHn and HHn == HHn[1] then HHn else Double.NaN;
def Bl = if low >= LLn and LLn == LLn[1] then LLn else Double.NaN;
def CountH = if IsNaN(Bh) or IsNaN(Bl) then 2 else CountH[1] + 1;
def CountL = if IsNaN(Bh) or IsNaN(Bl) then 2 else CountL[1] + 1;
def ExpH = if BarNumber() == 1 then Double.NaN else
            if CountH[-BarsReqToStayInRange] >= BarsReqToStayInRange then HHn[-BarsReqToStayInRange] else
            if high <= ExpH[1] then ExpH[1] else Double.NaN;
def ExpL = if BarNumber() == 1 then Double.NaN else
            if CountL[-BarsReqToStayInRange] >= BarsReqToStayInRange then LLn[-BarsReqToStayInRange] else
            if low >= ExpL[1] then ExpL[1] else Double.NaN;

def BoxHigh = if !IsNaN(ExpL) and !IsNaN(ExpH) then ExpH else Double.NaN;
def BoxLow = if !IsNaN(ExpL) and !IsNaN(ExpH) then ExpL else Double.NaN;

AddCloud( BoxHigh, BoxLow, Color.GRAY, Color.GRAY);

def Flat = if (!IsNaN(BoxHigh[1]) and !IsNaN(BoxLow[1])) and !TradeInFlatRange then 1 else 0;

input trailType = {default modified, unmodified};
input ATRPeriod = 7;
input ATRFactor = 2.5;
input firstTrade = {default long, short};
input averageType = AverageType.WILDERS;

Assert(ATRFactor > 0, "'atr factor' must be positive: " + ATRFactor);

def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);

def trueRange;
switch (trailType) {
case modified:
    trueRange = Max(HiLo, Max(HRef, LRef));
case unmodified:
    trueRange = TrueRange(high, close, low);
}
def loss = ATRFactor * MovingAverage(averageType, trueRange, ATRPeriod);

def state = {default init, long, short};
def trail;
switch (state[1]) {
case init:
    if (!IsNaN(loss)) {
        switch (firstTrade) {
        case long:
            state = state.long;
            trail =  close - loss;
        case short:
            state = state.short;
            trail = close + loss;
    }
    } else {
        state = state.init;
        trail = Double.NaN;
    }
case long:
    if (close > trail[1]) {
        state = state.long;
        trail = Max(trail[1], close - loss);
    } else {
        state = state.short;
        trail = close + loss;
    }
case short:
    if (close < trail[1]) {
        state = state.short;
        trail = Min(trail[1], close + loss);
    } else {
        state = state.long;
        trail =  close - loss;
    }
}

#
What does the gray box that appears at times indicate?

I have been testing this version of SHA and like it
 
I figure it out to show normal candles in a lower study. I would like to know how to add borders to down and up candles.

Ruby:
declare lower;
def o = open;
def h = high;
def l = low;
def c = close;
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;
}
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);
If o = c I end up with a blank space on the chart. How do I fix this?
 
Last edited:
I'm trying to create Heiken Ashi bars in a lower window. I created the following code, but I keep getting an error message referring to the HAOpen, "recs are not used inside FunctionClass{scriptMethodName='addchart'} call at 9:45." Does anyone know what I'm doing wrong?
Thanks,
Cliff

Code:
declare lower;

def haClose = ohlc4;
def haOpen = (haOpen[1] + haClose[1]) / 2;
def haHigh = Max(high, Max(haClose, haOpen));
def haLow = Min(low, Min(haClose, haOpen));

AddChart(high = HAhigh, low = HAlow, open = HAOpen, close = HAClose, growColor = Color.LIGHT_GREEN, fallColor = Color.RED, neutralColor = Color.GRAY, type = ChartType.CANDLE);

# End
 
keep on experimenting and trying things, that's how i learned.
search the site for addchart( and look at examples.

don't know what you mean by, borders?
if you mean hollow candles, then you swap the open and close numbers

Code:
# addchart_peter_redgreen

# https://usethinkscript.com/threads/could-i-have-heikin-ashi-candles-in-lower-section-in-thinkorswim.10428/#post-92406

declare lower;
def o = open;
def h = high;
def l = low;
def c = close;

# solid or hollow bars  ( swap open and close)
input solid = yes;



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

} 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;
    DnO = if solid then o else c;
    DnH = h;
    DnL = l;
#    DnC = c;
    DnC = if solid then c else o;
} else {
    DnO = Double.NaN;
    DnH = Double.NaN;
    DnL = Double.NaN;
    DnC = Double.NaN;
}


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);
#
I don't believe I've made a mistake on this. Pasting this code gives me regular candles in the lower study, not heikin-ashi. Did I do something wrong, and if not, would you know how I can make them heikin-ashi? Thanks!
 
I don't believe I've made a mistake on this. Pasting this code gives me regular candles in the lower study, not heikin-ashi. Did I do something wrong, and if not, would you know how I can make them heikin-ashi? Thanks!
After a lot experimentation, I came up with this. It seems to work.

Code:
declare lower;

def c = ohlc4;
def o = CompoundValue(1, (o[1] + c[1]) / 2, c[0]);
def h = Max(high, Max(close, open));
def l = Min(low, Min(close, open));

# 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;
}

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);
# end
 
I combined regular candles with smoothed Heiken Ashi in a lower study. You can use smoothed the HeiKen Ashi as a moving average to see uptrends or downtrends.
Ruby:
# addchart_peter_redgreen
#Smoothed Heiken Ashi and ATR studies
# https://usethinkscript.com/threads/could-i-have-heikin-ashi-candles-in-lower-section-in-thinkorswim.10428/#post-92406

declare lower;
def o = open;
def h = high;
def l = low;
def c = close;
input period = 10;
input hideCandles = no;
input candleSmoothing = {default Valcu, Vervoort};

input movingAverageType = {Simple, default Exponential, Weighted, Hull, Variable, TEMA};

def openMA;
def closeMA;
def highMA;
def lowMA;

# solid or hollow bars  ( swap open and close)
input solid = yes;

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

} 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;
    DnO = if solid then o else c;
    DnH = h;
    DnL = l;
#    DnC = c;
    DnC = if solid then c else o;
} else {
    DnO = Double.NaN;
    DnH = Double.NaN;
    DnL = Double.NaN;
    DnC = Double.NaN;
}

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);

switch (movingAverageType) {
case Simple:
    openMA = CompoundValue(1, Average(open, period), open);
    closeMA = CompoundValue(1, Average(close, period), close);
    highMA = CompoundValue(1, Average(high, period), high);
    lowMA = CompoundValue(1, Average(low, period), low);
case Exponential:
    openMA = CompoundValue(1, ExpAverage(open, period), open);
    closeMA = CompoundValue(1, ExpAverage(close, period), close);
    highMA = CompoundValue(1, ExpAverage(high, period), high);
    lowMA = CompoundValue(1, ExpAverage(low, period), low);
case Weighted:
    openMA = CompoundValue(1, WMA(open, period), open);
    closeMA = CompoundValue(1, WMA(close, period), close);
    highMA = CompoundValue(1, WMA(high, period), high);
    lowMA = CompoundValue(1, WMA(low, period), low);
case Hull:
    openMA = CompoundValue(1, HullMovingAvg(open, period), open);
    closeMA = CompoundValue(1, HullMovingAvg(close, period), close);
    highMA = CompoundValue(1, HullMovingAvg(high, period), high);
    lowMA = CompoundValue(1, HullMovingAvg(low, period), low);
case Variable:
    openMA = CompoundValue(1, VariableMA(open, period), open);
    closeMA = CompoundValue(1, VariableMA(close, period), close);
    highMA = CompoundValue(1, VariableMA(high, period), high);
    lowMA = CompoundValue(1, VariableMA(low, period), low);
case TEMA:
    openMA = CompoundValue(1, TEMA(open, period), open);
    closeMA = CompoundValue(1, TEMA(close, period), close);
    highMA = CompoundValue(1, TEMA(high, period), high);
    lowMA = CompoundValue(1, TEMA(low, period), low);
}

HidePricePlot(hideCandles);

def haOpen;
def haClose;

switch (candleSmoothing) {
case Valcu:
    haOpen = CompoundValue(1, ( (haOpen[1] + (openMA[1] + highMA[1] + lowMA[1] + closeMA[1]) / 4.0) / 2.0), open);
    haClose = ((openMA + highMA + lowMA + closeMA) / 4.0) ;
case Vervoort:
    haOpen = CompoundValue(1, ( (haOpen[1] + (openMA[1] + highMA[1] + lowMA[1] + closeMA[1]) / 4.0) / 2.0), open);
    haClose = ((((openMA + highMA + lowMA + closeMA) / 4.0) + haOpen + Max(highMA, haOpen) + Min(lowMA, haOpen)) / 4.0);
}

plot o1 = haOpen + 0;
o1.Hide();

def haLow = Min(lowMA, haOpen);
def haHigh = Max(highMA, haOpen);

def haOpen_fall = if haOpen > haClose
              then haOpen
              else Double.NaN;
def haHigh_fall   = if haOpen >= haClose
              then haHigh
              else Double.NaN;
def haLow_fall    = if haOpen >= haClose
              then haLow
              else Double.NaN;
def haClose_fall    = if haOpen >= haClose
              then haClose
              else Double.NaN;

AddChart(growColor = Color.PLUM, fallColor = Color.BLUE, neutralColor = Color.CURRENT, high = haHigh_fall, low = haLow_fall, open = haOpen_fall, close = haClose_fall , type = ChartType.CANDLE);

def haOpen_rise = if haOpen < haClose
                then haClose
                else Double.NaN;
def haHigh_rise  = if haOpen <= haClose
              then haHigh
              else Double.NaN;
def haLow_rise   = if haOpen <= haClose
              then haLow
              else Double.NaN;
def haClose_rise   = if haOpen <= haClose
              then haOpen
              else Double.NaN;

AddChart(growColor = Color.BLUE, fallColor = Color.PLUM, neutralColor = Color.CURRENT, high = haHigh_rise, low = haLow_rise, open = haOpen_rise, close = haClose_rise, type = ChartType.CANDLE);

input TradeInFlatRange = Yes;
input BarsForFlatRange = 4;
input BarsReqToStayInRange = 8;

def HH = Highest(high[1], BarsForFlatRange);
def LL = Lowest(low[1], BarsForFlatRange);
def maxH = Highest(HH, BarsReqToStayInRange);
def maxL = Lowest(LL, BarsReqToStayInRange);
def HHn = if maxH == maxH[1] or maxL == maxL then maxH else HHn[1];
def LLn = if maxH == maxH[1] or maxL == maxL then maxL else LLn[1];
def Bh = if high <= HHn and HHn == HHn[1] then HHn else Double.NaN;
def Bl = if low >= LLn and LLn == LLn[1] then LLn else Double.NaN;
def CountH = if IsNaN(Bh) or IsNaN(Bl) then 2 else CountH[1] + 1;
def CountL = if IsNaN(Bh) or IsNaN(Bl) then 2 else CountL[1] + 1;
def ExpH = if BarNumber() == 1 then Double.NaN else
            if CountH[-BarsReqToStayInRange] >= BarsReqToStayInRange then HHn[-BarsReqToStayInRange] else
            if high <= ExpH[1] then ExpH[1] else Double.NaN;
def ExpL = if BarNumber() == 1 then Double.NaN else
            if CountL[-BarsReqToStayInRange] >= BarsReqToStayInRange then LLn[-BarsReqToStayInRange] else
            if low >= ExpL[1] then ExpL[1] else Double.NaN;

def BoxHigh = if !IsNaN(ExpL) and !IsNaN(ExpH) then ExpH else Double.NaN;
def BoxLow = if !IsNaN(ExpL) and !IsNaN(ExpH) then ExpL else Double.NaN;

AddCloud( BoxHigh, BoxLow, Color.GRAY, Color.GRAY);

def Flat = if (!IsNaN(BoxHigh[1]) and !IsNaN(BoxLow[1])) and !TradeInFlatRange then 1 else 0;

input trailType = {default modified, unmodified};
input ATRPeriod = 7;
input ATRFactor = 2.5;
input firstTrade = {default long, short};
input averageType = AverageType.WILDERS;

Assert(ATRFactor > 0, "'atr factor' must be positive: " + ATRFactor);

def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);

def trueRange;
switch (trailType) {
case modified:
    trueRange = Max(HiLo, Max(HRef, LRef));
case unmodified:
    trueRange = TrueRange(high, close, low);
}
def loss = ATRFactor * MovingAverage(averageType, trueRange, ATRPeriod);

def state = {default init, long, short};
def trail;
switch (state[1]) {
case init:
    if (!IsNaN(loss)) {
        switch (firstTrade) {
        case long:
            state = state.long;
            trail =  close - loss;
        case short:
            state = state.short;
            trail = close + loss;
    }
    } else {
        state = state.init;
        trail = Double.NaN;
    }
case long:
    if (close > trail[1]) {
        state = state.long;
        trail = Max(trail[1], close - loss);
    } else {
        state = state.short;
        trail = close + loss;
    }
case short:
    if (close < trail[1]) {
        state = state.short;
        trail = Min(trail[1], close + loss);
    } else {
        state = state.long;
        trail =  close - loss;
    }
}

#
Can u add to change color of the candle. i want normal candle darker than the smoothed Heiken Ashi candle. Thanks
 

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
273 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