It uses Heiken Ashi candles to detect recent swing high and low. It can be used as a stop-loss or support/resistance indicator.
I added Multi timeframe support, smoothed HA, Bar color option and show/hide wicks
CODE:
CSS:
#// © wallneradam
#indicator("Heiken Ashi Swing High/Low with Smoothed HA"
# Created and mod by Sam4@Samer800 based on @wallneradam code - 11/2022
input ColorBars = no;
input useChartTime = yes;
input Aggregation = AggregationPeriod.FIFTEEN_MIN;
input ShowBand = yes;
input SmoothedHeikenAshi = yes;
input type = {Default "High/Low", "HA Open/Close"};#"Which levels to use for upper and lower?")
input wick = yes;
input PaintHeikenAshiBars = no;
input ha_smooth_ma_type = {default EMA, SMA, WMA, McGinley, HMA};
input ha_smooth_length = 10; # "Smooth Length"
input ha_after_smooth_ma_type = {default EMA, SMA, WMA, VWMA, McGinley, HMA};
input ha_after_smooth_length = 10;#
def na = Double.NaN;
def chartTime = GetAggregationPeriod();
def mtfc = if(useChartTime,close,close(Period=Aggregation));
def mtfh = if(useChartTime,high,high(Period=Aggregation));
def mtfl = if(useChartTime,low,low(Period=Aggregation));
#// ] -------------- FUNCTIONS : Moving Avg ------------------ [
# mcginley(float src, simple int len)=>
script mcginley {
input src = close;
input len = 14;
def mg;
def t = ExpAverage(src, len);
mg = if IsNaN(mg[1]) then t else
CompoundValue(1 , mg[1] + (src - mg[1]) / (len * Power(src / mg[1], 4)), src);
plot return = mg;
}
#export multiMa(float source, simple int length, string type) =>
script anyma {
input source = close;
input length = 14;
input type = "SMA";
def multiMa =
if type == "SMA" then SimpleMovingAvg(source, length) else
if type == "EMA" then ExpAverage(source, length) else
if type == "SMMA" then WildersAverage(source, length) else
if type == "WMA" then WMA(source, length) else
if type == "McGinley" then mcginley(source, length) else
if type == "HMA" then HullMovingAvg(source, length ) else Double.NaN;
plot return = multiMa;
}
#heiken_ashi(simple int smooth_length = 1, simple string smooth_ma_type = "EMA",
script heiken_ashi {
input smooth_length = 1;
input smooth_ma_type = 1;
input after_smooth_length = 1;
input after_smooth_ma_type = 1;
input wick = yes;
input agg = AggregationPeriod.FIFTEEN_MIN;
def src_open = open(period=agg);
def src_high = high(period=agg);
def src_low = low(period=agg);
def src_close = close(period=agg);
def haopen;
def haclose;
def hahigh;
def halow;
def o = anyma(src_open, smooth_length, smooth_ma_type);
def h = anyma(src_high, smooth_length, smooth_ma_type);
def l = anyma(src_low, smooth_length, smooth_ma_type);
def c = anyma(src_close, smooth_length, smooth_ma_type);
haclose = (o + h + l + c) / 4.0;
haopen = CompoundValue(1, (haOpen[1] + haClose[1]) / 2, haClose);
hahigh = Max(h,Max(haopen, haclose));
halow = Min(l,Min(haopen, haclose));
def SmoothO = anyma(haopen, after_smooth_length, smooth_ma_type);
def SmoothH = anyma(if(wick,hahigh,haclose), after_smooth_length,smooth_ma_type);
def SmoothL = anyma(if(wick,halow,haclose), after_smooth_length, smooth_ma_type);
def SmoothC = anyma(haclose, after_smooth_length, smooth_ma_type);
def dir = SmoothO>SmoothC;
plot OpenHA = SmoothO;
plot HighHA = if(!dir,SmoothH,if(wick,SmoothH,SmoothO));
plot LowHA = if(dir,SmoothL,if(wick,SmoothL,SmoothO));
plot CloseHA = SmoothC;
}
def o = heiken_ashi(1,ha_smooth_ma_type,1,ha_smooth_ma_type,wick,if(useChartTime,chartTime,Aggregation)).OpenHA;
def h = heiken_ashi(1,ha_smooth_ma_type,1,ha_smooth_ma_type,wick,if(useChartTime,chartTime,Aggregation)).HighHA;
def l = heiken_ashi(1,ha_smooth_ma_type,1,ha_smooth_ma_type,wick,if(useChartTime,chartTime,Aggregation)).LowHA;
def c = heiken_ashi(1,ha_smooth_ma_type,1,ha_smooth_ma_type,wick,if(useChartTime,chartTime,Aggregation)).CloseHA;
def upper;
def lower;
if c[1] > o[1] and c < o {
upper = if(type==type."High/Low", mtfh[1], c[1]);
lower = lower[1];
} else {
if c[1] < o[1] and c > o {
upper = upper[1];
lower = if(type==type."High/Low", mtfl[1], o[1]);
} else {
upper = upper[1];
lower = lower[1];
}}
plot UpBand = if !ShowBand or isNaN(mtfc) then na else upper; # "Upper"
plot LoBand = if !ShowBand or isNaN(mtfc) then na else lower; # "Lower"
UpBand.SetDefaultColor(Color.CYAN);
LoBand.SetDefaultColor(Color.MAGENTA);
#--- Smoothed
# Plot the new Chart
def HAo = heiken_ashi(ha_smooth_length,ha_smooth_ma_type,ha_after_smooth_length,ha_after_smooth_ma_type,wick,if(useChartTime,chartTime,Aggregation)).OpenHA;
def HAh = heiken_ashi(ha_smooth_length,ha_smooth_ma_type,ha_after_smooth_length,ha_after_smooth_ma_type,wick,if(useChartTime,chartTime,Aggregation)).HighHA;
def HAl = heiken_ashi(ha_smooth_length,ha_smooth_ma_type,ha_after_smooth_length,ha_after_smooth_ma_type,wick,if(useChartTime,chartTime,Aggregation)).LowHA;
def HAc = heiken_ashi(ha_smooth_length,ha_smooth_ma_type,ha_after_smooth_length,ha_after_smooth_ma_type,wick,if(useChartTime,chartTime,Aggregation)).CloseHA;
def dir = HAo>HAc;
AddChart(high = if SmoothedHeikenAshi and !dir then HAh else na , low = HAl ,
open = if(PaintHeikenAshiBars,HAc,HAo), close = if(PaintHeikenAshiBars,HAo,HAc),
type = ChartType.CANDLE, growcolor = CreateColor(4,127,145));
AddChart(high = if SmoothedHeikenAshi and dir then HAh else na , low = HAl ,
open = if(PaintHeikenAshiBars,HAo,HAc), close = if(PaintHeikenAshiBars,HAc,HAo),
type = ChartType.CANDLE, growcolor = CreateColor(123,3,143));
#---- Bar Color---
AssignPriceColor(if !ColorBars then Color.CURRENT else
if mtfc>HAh and !dir then color.GREEN else
if mtfc>HAh and dir then color.DARK_GREEN else
if mtfc<HAl and dir then Color.RED else
if mtfc<HAl and !dir then Color.DARK_RED else Color.GRAY);
#---END CODE
Update: some code improvements and added different candle calc options and HA style options (Candle and parapolice)
CSS:
#// © wallneradam
#indicator("Heiken Ashi Swing High/Low with Smoothed HA"
# Created and mod by Sam4@Samer800 based on @wallneradam code - 11/2022
# Updated - Added differnt candleType and style - Sam4@Samer800 11/2022
input showPricePlot = yes;
input ColorBars = no;
input useChartTime = yes;
input Aggregation = AggregationPeriod.FIFTEEN_MIN;
input ShowBand = yes;
input HeikenAshiStyle = {Default "Don't Show", "Candle", "Parabolic"};
input ParabolicPercent = 0.2; # Parabolic Squeeze Percent
input candleCalcType = {Default "Default", "Valcu", "Vervoort"};
input SourceCalcMethod = {Default "High/Low", "Candle Close"};
input ShowWick = yes;
input PaintHaCandle = no;
input smoothMaType = {default EMA, SMA, WMA, TEMA, LSMA, VWMA, HMA, ALMA};
input MaSmoothLength = 1;
input smoothLength = 10; # "Smooth Length"
input afterSmoothMaType = {default EMA, SMA, WMA, TEMA, LSMA, VWMA, HMA, ALMA};
input afterSmoothLength = 10;#
hidePricePlot(!showPricePlot);
def na = Double.NaN;
def HeikStyle = if HeikenAshiStyle==HeikenAshiStyle."Candle" then 2 else
if HeikenAshiStyle==HeikenAshiStyle."Parabolic" then 1 else 0;
#def chartTime = GetAggregationPeriod();
def mtfc = if(useChartTime,close,close(Period=Aggregation));
def mtfh = if(useChartTime,high,high(Period=Aggregation));
def mtfl = if(useChartTime,low,low(Period=Aggregation));
def mtfo = if(useChartTime,open,open(Period=Aggregation));
#// ] -------------- FUNCTIONS : Moving Avg ------------------ [
#export tema(float src, simple int len)=>
script tema {
input src = close;
input len = 14;
def ema1 = ExpAverage(src, len);
def ema2 = ExpAverage(ema1, len);
def ema3 = ExpAverage(ema2, len);
def tema = 3 * (ema1 - ema2) + ema3;
plot return = tema;
}
#vwma(source, length)
script VWMA {
input x = close;
input y = 15;
def VWMA = SimpleMovingAvg(x * volume, y) / SimpleMovingAvg(volume, y);
Plot result = VWMA;
}
script ALMA {
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;
def m = (Offset * (Window - 1));
def s = Window/Sigma;
def SumVectorData = fold y = 0 to Window with WS do
WS + Exp(-(sqr(y-m))/(2*sqr(s))) * getvalue(Data, (Window-1)-y);
def SumVector = fold z = 0 to Window with CW do
CW + Exp(-(sqr(z-m))/(2*sqr(s)));
plot ALMA = SumVectorData / SumVector;
}
#export multiMa(float source, simple int length, string type) =>
script anyma {
input source = close;
input length = 14;
input type = "SMA";
def multiMa =
if type == "SMA" then SimpleMovingAvg(source, length) else
if type == "EMA" then ExpAverage(source, length) else
if type == "SMMA" then WildersAverage(source, length) else
if type == "WMA" then WMA(source, length) else
if type == "TEMA" then TEMA(source, length) else
if type == "LSMA" then Inertia(source, length) else
if type == "ALMA" then ALMA(source, length) else
if type == "VWMA" then VWMA(source, length) else
if type == "HMA" then HullMovingAvg(source, length ) else Double.NaN;
plot return = multiMa;
}
#heiken_ashi(simple int smooth_length = 1, simple string smooth_ma_type = "EMA",
script heiken_ashi {
input src_open = open;
input src_close = close;
input src_high = high;
input src_low = low;
input after_smooth_length = 10;
input after_smooth_ma_type = yes;
input wick = yes;
def haopen = src_open;
def haclose= src_close;
def hahigh = src_high;
def halow = src_low;
def hiWick = if(wick,hahigh,haclose);
def loWick = if(wick,halow,haopen);
def SmoothO = anyma(haopen, after_smooth_length, after_smooth_ma_type);
def SmoothH = anyma(hiWick, after_smooth_length, after_smooth_ma_type);
def SmoothL = anyma(loWick, after_smooth_length, after_smooth_ma_type);
def SmoothC = anyma(haclose,after_smooth_length, after_smooth_ma_type);
def dir = SmoothO>SmoothC;
plot OpenHA = SmoothO;
plot HighHA = if(!dir,SmoothH,if(wick,SmoothH,SmoothO));
plot LowHA = if(dir,SmoothL,if(wick,SmoothL,SmoothO));
plot CloseHA = SmoothC;
}
def haopen; def haclose; def hahigh; def halow;
def mao = anyma(mtfo, MaSmoothLength, smoothMaType);
def mah = anyma(mtfh, MaSmoothLength, smoothMaType);
def mal = anyma(mtfl, MaSmoothLength, smoothMaType);
def mac = anyma(mtfc, MaSmoothLength, smoothMaType);
switch(candleCalcType) {
case "Default":
haclose = (mao + mah + mal + mac) / 4.0;
haopen = CompoundValue(1, (haOpen[1] + haClose[1]) / 2, haClose);
hahigh = Max(mah,Max(haopen, haclose));
halow = Min(mal,Min(haopen, haclose));
case "Valcu":
haOpen = CompoundValue(1, ((haOpen[1] + (mao + mah + mal + mac)/4.0)/2.0), mao);
haClose = (mao + mah + mal + mac)/4.0;
hahigh = Max(mah,Max(haopen, haclose));
halow = Min(mal,Min(haopen, haclose));
case "Vervoort":
haOpen = CompoundValue(1, ((haOpen[1] + (mao + mah + mal + mac)/4.0)/2.0), mao);
haClose = ((mao + mah + mal + mac)/4.0 + haOpen + Max(mah, haOpen) + Min(mal, haOpen))/4.0;
hahigh = Max(mah,Max(haopen, haclose));
halow = Min(mal,Min(haopen, haclose));
}
def o = haOpen;
def h = hahigh;
def l = halow;
def c = haClose;
def upper;
def lower;
if c[1] > o[1] and c < o {
upper = if(SourceCalcMethod==SourceCalcMethod."High/Low", mtfh[1], c[1]);
lower = lower[1];
} else {
if c[1] < o[1] and c > o {
upper = upper[1];
lower = if(SourceCalcMethod==SourceCalcMethod."High/Low", mtfl[1], o[1]);
} else {
upper = upper[1];
lower = lower[1];
}}
plot UpBand = if !ShowBand or isNaN(mtfc) then na else upper; # "Upper"
plot LoBand = if !ShowBand or isNaN(mtfc) then na else lower; # "Lower"
UpBand.SetDefaultColor(Color.CYAN);
LoBand.SetDefaultColor(Color.MAGENTA);
#--- Smoothed
# Plot the new Chart
def smO = anyma(o, smoothLength, smoothMaType);;
def smH = anyma(h, smoothLength, smoothMaType);;
def smL = anyma(l, smoothLength, smoothMaType);;
def smC = anyma(c, smoothLength, smoothMaType);;
def HAo = heiken_ashi(smO,smC,smH,smL,afterSmoothLength,afterSmoothMaType,ShowWick).OpenHA;
def HAh = heiken_ashi(smO,smC,smH,smL,afterSmoothLength,afterSmoothMaType,ShowWick).HighHA;
def HAl = heiken_ashi(smO,smC,smH,smL,afterSmoothLength,afterSmoothMaType,ShowWick).LowHA;
def HAc = heiken_ashi(smO,smC,smH,smL,afterSmoothLength,afterSmoothMaType,ShowWick).CloseHA;
def dir = HAo>HAc;
AddChart(high = if HeikStyle==2 and !dir then HAh else na , low = HAl ,
open = if(PaintHaCandle,HAc,HAo), close = if(PaintHaCandle,HAo,HAc),
type = ChartType.CANDLE, growcolor = CreateColor(4,127,145));
AddChart(high = if HeikStyle==2 and dir then HAh else na , low = HAl ,
open = if(PaintHaCandle,HAo,HAc), close = if(PaintHaCandle,HAc,HAo),
type = ChartType.CANDLE, growcolor = CreateColor(123,3,143));
#--- Par Calc
def percentHL = ((HAo - HAc) / ((HAo + HAc)/2)) * 100;
def high_squeeze= AbsValue(percentHL) < ParabolicPercent and percentHL>0;
def low_squeeze = AbsValue(percentHL) < ParabolicPercent and percentHL<0;
def crossPlot;
if dir {
crossPlot = HAh;
} else {
crossPlot = HAl; }
def o2_cross_under_long = crosses(HAo,HAc, CrossingDirection.BELOW);
def c2_cross_over_short = crosses(HAo,HAc, CrossingDirection.ABOVE);
def plotColor = if high_squeeze then -1 else
if low_squeeze then 1 else
if !dir then 2 else -2;
plot haLine = if(HeikStyle!=1, na, crossPlot);#, color = plotColor, style = plot.style_cross, linewidth = 2)
haLine.SetStyle(Curve.POINTS);
haLine.AssignValueColor(if plotColor==-1 then Color.DARK_RED else
if plotColor==1 then Color.DARK_GREEN else
if plotColor==2 then Color.GREEN else Color.RED);
#---- Bar Color---
AssignPriceColor(if !ColorBars or HeikStyle==1 then Color.CURRENT else
if mtfc>HAh and !dir then color.GREEN else
if mtfc>HAh and dir then color.DARK_GREEN else
if mtfc<HAl and dir then Color.RED else
if mtfc<HAl and !dir then Color.DARK_RED else Color.GRAY);
AssignPriceColor(if !ColorBars or HeikStyle!=1 then Color.CURRENT else
if plotColor==2 then Color.GREEN else
if plotColor==1 then Color.Dark_GREEN else
if plotColor==-1 then Color.DARK_RED else Color.RED);
#---END CODE
Last edited: