Completed Heikin_Ashi Indicator

BonBon

Member
VIP
Thanks to everyone for their work as I would not have gotten this far without your contribution. I have referenced members of the community as you have either commented or contributed to the HA forums/discussions.

After conducting research on indicators/studies that would aid in my entry and exits as well as keeping me in the trend longer than usual, I came upon Sylvan Vervoort and his work. ( I have previously used the TrendPainter, Supertrend etc.) After reading “Trading with the Heikin-Ashi Candlestick Oscillator" and “Trading Medium-Term Divergences” I began searching the site for script that emulates his work.

@BenTen, @zkm, @mc01439, @HighBredCloud, @JBTrades, @markos, @tomsk @horserider @YungTraderFromMontana @diazlaz @J007RMC

Key components
TEMA, Reversal bubbles and/or arrows, MTF indicator, Addchart script used to create the HA , does not repaint.

Strategy – long and/or short. Enter and/or exit based on reversals (however, I utilize other indicators and signals such as the RSI, MTF, increased volume, stocks with strong catalyst, RV above 2.0 and Fib retracement.

Scan
The scan comprises of the MTF script along with the script for liquidity, relative volume and/or stocks that are near (2-5%) to their 52wk high and short interest. I scan for stocks that are low float.

Watchlist
The watchlist is based on the buy and sell signals.

Feedback from members

I would like feedback from members regarding changing those candles that are “in the trend” but have a different color. (see chart). This would eliminate the number of signals that appear. (especially where there is only one red or green candle in the middle of the current trend. I have tried using strategies such as increasing the lookback period, using the previous candle(s) script but with no success. Please see notes within the chart.

Also, can someone please provide the information for making the Fib lines shorter. Please see notes within the chart.

It is a work in progress. I have made profitable trades and this indicator has allowed me to find setups before major breakouts etc. (this is in combination with the Buy-the Dip).

This is a chart without the regular candles. This shows the HA with the buy and sell signals and the Multi Time Frames. This is the main trading chart. The chart with the candlesticks is used for reference during trading. (I use two monitors when trading)
i7GJm5H.jpg


This is the above chart with the regular candles.
O3grdOi.jpg


This chart shows the Fib Lines and notes on the feedback needed.
ZrGyZKw.jpg


This chart shows the HA candles without the new HA_smoothing chart
3pBHtFX.jpg


This chart shows the scan criteria
DllROT7.jpg


Code
Code:
#Heiken_Ashi based on Sylvan Verboort's Trading with HA Candlestick Oscillator
#Bon Bon _last update Jan 17th 2021
#Influenced by script from HoboTheClown / blt,http://www.thinkscripter.com, TD Hacolt etc.
#MTF based on HannTech's MTF_MACD script
#update 1/2/21 - changed the default moving average to TEMA.  Changed the period to 35.
#update changed reversal arrows to reversal bubbles with price

### YOU MUST HAVE THE STYLE SETTING FIT STUDIES ENABLED ###
#hint: The style setting Fit Studies must be enabled to use these bars.


input period = 50;
input hideCandles = yes;
input candleSmoothing = {default Valcu, Vervoort};
input show_bubble_labels = yes;
input bubbles = yes;
input arrows = yes;


#input smoothingLength = 3;

input movingAverageType = {default  TEMA, Exponential, Hull };

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.Hide();

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

#Zero Lag System - MetaStock Crossover Formula
#zero-lagging principle
#Zero-lagging TEMA average on closing prices

#Medium-term price reversals - upward trend

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;

#Medium-term price reversals - downward trend
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

#uptrend {green candle}
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;

#downtrend red candle

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

#Change the color of HA and Japanese Candles - turn off to show only HA on chart
AssignPriceColor(if haClose >= haOpen
                 then Color.GREEN else
                 if  haClose < haOpen
                 then Color.RED else Color.WHITE);


#Heiken_A script

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

#####################################################################################################
#Buy and sell signals
def trend =  haClose >= haOpen; 
def trendup = trend and !trend[1];
def trendd =  haClose < haOpen;
def trendDown = trendd and !trendd[1];

AddChartBubble(bubbles and trendup and trendup, HAlow1, ("Reversal:"    + round(HAlow1, 2)), Color.GREEN, no);

AddChartBubble(bubbles and trendDown and trendDown, HAhigh1, ("Reversal:"  + round(HAhigh1,2)), Color.LIGHT_RED, yes);

#Arrows instead of bubbles
#def trend = haClose >= haOpen ;
#plot trendup = trend and !trend[1];
#trendup.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#trendup.SetDefaultColor(Color.CYAN);


#def trendd = haClose <= haOpen ;
#plot trendDown = trendd and !trendd[1];
#trendDown.SetDefaultColor(Color.MAGENTA);
#trendDown.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);

I am looking forward to your feedback. Thanks.
 
Last edited:

Ilya

New member
VIP
Looks really nice, thank you. I will be looking at this closely. How did you get the regular candles to overlie the HA candles?

Also, I am sure this is well known, but in a trend the bodies of the HA candles are large compared to wicks, as the trend tapers the body gets smaller, the wicks get larger. I would really like to flag that as potential reversal but have no idea how to code that in.
 

BonBon

Member
VIP
@Ilya the HA candles were created using the HA script that is shown above. This adds the HA smoothing chart/candles on the regular chart as well. These will help in understanding the rationale behind the script. The candle factor is coded in the above code. https://docplayer.net/24587491-Trading-with-the-heikin-ashi-candlestick-oscillator.html

The TD HACOLT thinkscript contains code that also references the short and long candle. Maybe that can help you with your code.
 

Ilya

New member
VIP
Ty. I don't think I expressed it clearly. When I start out with a bar chart and add your study it shows HA candles only. In one of your images above you have both the bars and HA candles together on the same chart. I can't seem to figure out how to do that, its one or the other.
 

BonBon

Member
VIP
@Ilya Ok...Now I understand.

You have to change the below script. The above code includes the hashtags which prevented them from being visible. I do this when I want to view the HA only. Remove the hashtags and it will show the candles as well. In the chart settings you can change the candles to japanese or heiken. Sometimes I would use the line chart as well.

Code:
#Change the color of HA and Japanese Candles - turn off to show only HA on chart
AssignPriceColor(if haClose >= haOpen
                 then Color.GREEN else
                 if  haClose < haOpen
                 then Color.RED else Color.WHITE);
 

BonBon

Member
VIP
@BonBon where do you have the lower MTF indicator scripts?
Here it is. I incorporated a MTF_MACD study script into the scripts. I turned off the "longtermperiod" and for each script I changed the default based on the main timeframe I use for trading (5 min). The daily timeframe is mainly used for a general reference.

Code:
# Modified using Hahn_Tech LTD MTF_MACDStudyand TD's HACOLT
# Bon Bon - Jan 2021

declare lower;

input midTermPeriod = {"1 min", "3 min", "5 min", "30 min", "60 min", "120 min", "240 min", "Daily", "Monthly" Weekly", default "15 mins" };
#input longTermPeriod = {"3 min", "5 min", "15 min", "30 min", "60 min", "120 min", "Daily", "Weekly", default "Monthly"};


def middleAggregation;

switch (midTermPeriod) {
    case "1 min":
        middleAggregation = AggregationPeriod.MIN;
    case "3 min":
        middleAggregation = AggregationPeriod.THREE_MIN;
    case "5 min":
        middleAggregation = AggregationPeriod.FIVE_MIN;
    case "15 min":
        middleAggregation = AggregationPeriod.FIFTEEN_MIN;
    case "30 min":
        middleAggregation = AggregationPeriod.THIRTY_MIN;
    case "60 min":
        middleAggregation = AggregationPeriod.HOUR;
    case "120 min":
        middleAggregation = AggregationPeriod.TWO_HOURS;
    case "240 min":
        middleAggregation = AggregationPeriod.four_hours;
       case "Daily":
        middleAggregation = AggregationPeriod.DAY;
    case "Weekly":
        middleAggregation = AggregationPeriod.WEEK;
    case "Monthly":
        middleAggregation = AggregationPeriod.MONTH;
}

def timeFrame = getAggregationPeriod();
def testTimeFrames = if timeFrame < middleAggregation  #middleAggregation < highestAggregation
then yes else no;

AddLabel(yes, if testTimeFrames  then "Time Frames Are Correct" else "Time Frames Are Wrong", if testTimeFrames  then color.GREEN else color.RED);

input period = 50 ;
input hideCandles = no;
input candleSmoothing = {default Valcu, Vervoort};

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

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 = middleaggregation)), 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 = middleaggregation)), 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 = middleaggregation)), 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 = middleaggregation)), 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 = middleaggregation)), close);
    highMA = CompoundValue(1, TEMA(high, period), high);
    lowMA = CompoundValue(1, TEMA(low, period), low);
case SIMPLE:
    openMA = CompoundValue(1, Average(open, period), open);
    closeMA = CompoundValue(1, Average(close(period = middleaggregation)), close);
    highMA = CompoundValue(1, Average(high, period), high);
    lowMA = CompoundValue(1, Average(low, period), low);
}

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.Hide();


def haOpen2 = CompoundValue(1, (haOpen[1] + ohlc4[1]) / 2, ohlc4) / 4;
def haClose2 = (haOpen + Max(high, haOpen) + Min(low, haOpen) + ohlc4) / 4;

HidePricePlot(hideCandles);
#####################################################################################

#def highestAggregation;
#switch (longTermPeriod) {
   # case "3 min":
       # highestAggregation = AggregationPeriod.THREE_MIN;
   # case "5 min":
       # highestAggregation = AggregationPeriod.FIVE_MIN;
   # case "15 min":
       # highestAggregation = AggregationPeriod.FIFTEEN_MIN;
   # case "30 min":
       # highestAggregation = AggregationPeriod.THIRTY_MIN;
   # case "60 min":
       # highestAggregation = AggregationPeriod.HOUR;
   # case "120 min":
       # highestAggregation = AggregationPeriod.TWO_HOURS;
   # case "Daily":
       # highestAggregation = AggregationPeriod.DAY;
   # case "Weekly":
       # highestAggregation = AggregationPeriod.WEEK;
   # case "Monthly":
       # highestAggregation = AggregationPeriod.MONTH;
#}

#DefineGlobalColor("UpTrend", color.GREEN);
#DefineGlobalColor("DownTrend", color.RED);
#DefineGlobalColor("NoTrend", color.LIGHT_GRAY);

#############################################################################
#Zero Lag System - MetaStock Crossover Formula
#zero-lagging principle
#Zero-lagging TEMA average on closing prices

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

#Medium-term price reversals - upward trend

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;

#Medium-term price reversals - downward trend
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

#############################################################################

#uptrend {green candle}
def keep1 = if (haClose >= haOpen and haClose[1] >= haOpen[1]) then 1 else 0;
def keep2 = if ZlDif >= 0 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 keep3 = if (AbsValue(close - open) < ((high - low) * 0.35)) and high >= low[1] then 1 else 0;
def utr = if keepall or (keepall[1]) and keep3 then 1 else 0;

#downtrend red candle

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;

#HA_Points Script

plot HA_Up = if haClose >= haOpen then 1 else 0;
HA_Up.SetPaintingStrategy(PaintingStrategy.squared_HISTOGRAM);
HA_Up.AssignValueColor(Color.GREEN);
HA_Up.SetLineWeight(5);

plot HA_Down = if haClose < haOpen then 1 else 0;
HA_Down.SetPaintingStrategy(PaintingStrategy.squared_HISTOGRAM);
HA_Down.AssignValueColor(Color.RED);
HA_Down.SetLineWeight(5);
 
Last edited:

BonBon

Member
VIP
Worked perfectly. Thank you.
@Ilya if you want the arrows and/or reversal bubbles to trail the candles and not the HA smoothing chart swap the above script with the below which replaces the "hahigh" and "halow" with the regular "high" and "low".

AddChartBubble(bubbles and trendup and trendup, low, ("Reversal:" + round(low, 2)), Color.GREEN, no);

AddChartBubble(bubbles and trendDown and trendDown, high, ("Reversal:" + round(high,2)), Color.LIGHT_RED, yes);
 

Similar threads

Top