Bar Charts, Tradeview and Sierra Charts use a double smoothing of HeikinAshi candles. While I am not convinced of their value, I have been trying to explore in detail. To that end, I have been trying to write thinkscript to explore in TOS. There are several thinkscripts available, most from here, for single smoothing with one calculation of moving average, but not two. I generate one using a moving average, then a moving average of those results as the values to generate HeikinAshi candle bodies. While similar, they did not match the same dates in Barcharts results. I discussed this with support at Barchart and they finally came up with this comment of their actual calculations:
https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=314
It looks like they are doing a moving average of OHLC, then generating the HeikinAshi candle values and repeating the moving average on the candle values to generate the final values. I have tried to code it out but the numbers are not working out the same as what Barchart gets. My coding skills are pretty nonexistant so easily could be me, so looking for any help I can get in trying to refine this. Also, to be honest, it's more of an exercise in learning for me, not an indicator that is necessarily of critical value. Although, could be if I can get it right!
My attemopt:
Thanks in advance for any insight, thoughts and corrections.
Snowthunder
https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=314
It looks like they are doing a moving average of OHLC, then generating the HeikinAshi candle values and repeating the moving average on the candle values to generate the final values. I have tried to code it out but the numbers are not working out the same as what Barchart gets. My coding skills are pretty nonexistant so easily could be me, so looking for any help I can get in trying to refine this. Also, to be honest, it's more of an exercise in learning for me, not an indicator that is necessarily of critical value. Although, could be if I can get it right!
My attemopt:
Code:
# Second Working Draft Twice Smoothed Heikin Ashi
# Snowthunder 03132023
#Core start TS_HeikinAshiSmoothed
# http://www.thinkscripter.com, Last Update 30 June 2013
#Initial inputs are for the first average calculation period and the period for the second calculation
input period = 10;
input hideCandles = YES;
input period2 = 10;
DefineGlobalColor("RisingMA", Color.DARK_GREEN);
DefineGlobalColor("FallingMA", Color.RED);
input movingAverageType = {default TEMA, Exponential, Weighted, Hull, Variable, SIMPLE};
####################################################################################################
####################################################################################################
# Initial moving average calculation to generate the first moving average of the price points, designated
# as openMA, closeMA, highMA and lowMA
def openMA;
def closeMA;
def highMA;
def lowMA;
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);
}
#####################################################################################
#####################################################################################
# Initial averages used to generate initial Heikin Ashi candle Values
# Values designated haOpen, haHigh, haLow and haClose
def haOpen;
def haHigh;
def haLow;
def haClose;
haOpen = ((haOpen[1] + haClose[1]) / 2.0);
haClose = ((openMA + highMA + lowMA + closeMA) / 4.0) ;
haLow = Min(lowMA, haOpen);
haHigh = Max(highMA, haOpen);
#####################################################################################################
#####################################################################################################
# Calculating the Moving Average of the initial moving average price point calculation
# Using haOpen, haClose, haHigh and haLow to generate openHAMA, closeHAMA, highHAM and lowHAMA
input movingAverageType2 = {default TEMA, Exponential, Weighted, Hull, Variable, SIMPLE};
def openHAMA;
def closeHAMA;
def highHAMA;
def lowHAMA;
switch (movingAverageType2) {
case SIMPLE:
openHAMA = CompoundValue(1, Average(haOpen, period2), haOpen);
closeHAMA = CompoundValue(1, Average(haClose, period2), haClose);
highHAMA = CompoundValue(1, Average(haHigh, period2), haHigh);
lowHAMA = CompoundValue(1, Average(haLow, period2), haLow);
case Exponential:
openHAMA = CompoundValue(1, ExpAverage (haOpen, period2), haOpen);
closeHAMA = CompoundValue(1, ExpAverage (haClose, period2), haClose);
highHAMA = CompoundValue(1, ExpAverage (haHigh, period2), haHigh);
lowHAMA = CompoundValue(1, ExpAverage (haLow, period2), haLow);
case Weighted:
openHAMA = CompoundValue(1, WMA (haOpen, period2), haOpen);
closeHAMA = CompoundValue(1, WMA (haClose, period2), haClose);
highHAMA = CompoundValue(1, WMA (haHigh, period2), haHigh);
lowHAMA = CompoundValue(1, WMA (haLow, period2), haLow);
case Hull:
openHAMA = CompoundValue(1, HullMovingAvg (haOpen, period2), haOpen);
closeHAMA = CompoundValue(1, HullMovingAvg (haClose, period2), haClose);
highHAMA = CompoundValue(1, HullMovingAvg (haHigh, period2), haHigh);
lowHAMA = CompoundValue(1, HullMovingAvg (haLow, period2), haLow);
case Variable:
openHAMA = CompoundValue(1, VariableMA (haOpen, period2), haOpen);
closeHAMA = CompoundValue(1, VariableMA (haClose, period2), haClose);
highHAMA = CompoundValue(1, VariableMA (haHigh, period2), haHigh);
lowHAMA = CompoundValue(1, VariableMA (haLow, period2), haLow);
case TEMA:
openHAMA = CompoundValue(1, TEMA (haOpen, period2), haOpen);
closeHAMA = CompoundValue(1, TEMA (haClose, period2), haClose);
highHAMA = CompoundValue(1, TEMA (haHigh, period2), haHigh);
lowHAMA = CompoundValue(1, TEMA (haLow, period2), haLow);
}
#############################################################################################
#############################################################################################
# Generating the secondary plotting points using Heikin-Ashi calculations
# plot points designated hamaOpen, hamaClose, hamaHigh and hamaLow
# Chart price plotting is hidden in default mode
#
HidePricePlot(hideCandles);
#def hamaOpen;
#def hamaClose;
#
#hamaOpen = ((hamaOpen[1] + hamaClose[1]) / 2.0);
#hamaClose = ((hamaOpen + hamaHigh + hamaLow + hamaClose) / 4.0) ;
plot o = openHAMA;
o.Hide();
#def hamaLow = Min(hamaLow, hamaOpen);
#def hamaHigh = Max(hamaHigh, hamaOpen);
AddChart(high = highHAMA, low = lowHAMA, open = o, close = closeHAMA, type = ChartType.CANDLE, growColor = GlobalColor("RisingMA"), fallColor = GlobalColor("FallingMA"));
#Red Candlesticks -----------------------------------------------------------------|
input charttype = ChartType.CANDLE;
def hamaOpen_fall = if openHAMA > closeHAMA
then openHAMA
else Double.NaN;
def hamaHigh_fall = if openHAMA >= closeHAMA
then highHAMA
else Double.NaN;
def hamaLow_fall = if openHAMA >= closeHAMA
then lowHAMA
else Double.NaN;
def hamaClose_fall = if openHAMA >= closeHAMA
then closeHAMA
else Double.NaN;
AddChart(growColor = Color.RED, fallColor = Color.DARK_GREEN, neutralColor = Color.CURRENT, high = hamaHigh_fall, low = hamaLow_fall, open = hamaOpen_fall, close = hamaClose_fall , type = ChartType.CANDLE);
#Green Candlesticks -----------------------------------------------------------------|
def hamaOpen_rise = if openHAMA < closeHAMA
then closeHAMA
else Double.NaN;
def hamaHigh_rise = if openHAMA <= closeHAMA
then highHAMA
else Double.NaN;
def hamaLow_rise = if openHAMA <= closeHAMA
then lowHAMA
else Double.NaN;
def hamaClose_rise = if openHAMA <= closeHAMA
then openHAMA
else Double.NaN;
AddChart(growColor = Color.DARK_GREEN, fallColor = Color.RED, neutralColor = Color.CURRENT, high = hamaHigh_rise, low = hamaLow_rise, open = hamaOpen_rise, close = hamaClose_rise, type = ChartType.CANDLE);
# End Study
#############################################################
Thanks in advance for any insight, thoughts and corrections.
Snowthunder