Author Message:
This indicator is intended to reduce market noise by averaging "Heikin-ashi" a few more times.
You can set the number of averages and how the closing price is calculated.
The Modes:
There are several presets.
The "Mode 1" is more conservative and flips fewer times, but with less noise.
(Averaged by 5 times, Close calculated by oc2)
The "Mode 2" is more aggressive, with more flips and faster timing.
(Averaged by 10 times, Close calculated by ohlc4)
Triggers:
Triggers the inversion of the bar. It can be visualized and alerts can be set.
CODE:
CSS:
#// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
#// © boitoki
#indicator("Cloak & Dagger Heikin-ashi", "Heikinashi", overlay=true, max_labels_count=500, max_lines_count=500)
# Converted by Sam4Cok@Samer800 - 02/2023
#// Inputs //
input ShowChart = yes;
input show_triggers = yes; # "Flip"
input show_trigger_count = yes; # "counts "
input PlotChart_type = {default "Heikin-Ashi", "Candles", "Barcolor", "None"};
input Set_mode = {default "Mode 1", "Mode 2", "Mode 3", "Custom"};
input averaged_times = 1; # 'Averaged by (times)'
input Source_type = {Default "ohlc4", "hlc3", "oc2", "hl2", "close"};
input ma1_type = {ALMA, AMA, DEMA, default EMA, HMA, KAMA, LSMA, MAV, RMA, SMA, SWMA, TEMA, TMA, VWMA, WMA, ZLEMA};
input Show_ma1 = no;
input ma1_period = 30;
input ma2_type = {ALMA, AMA, DEMA, default EMA, HMA, KAMA, LSMA, MAV, RMA, SMA, SWMA, TEMA, TMA, VWMA, WMA, ZLEMA};
input Show_ma2 = no;
input ma2_period = 200;
def na = Double.NaN;
HidePricePlot(!ShowChart);
def i_show_candle = PlotChart_type == PlotChart_type."Candles";
def i_show_heikinashi = PlotChart_type == PlotChart_type."Heikin-Ashi";
def i_show_barcolor = PlotChart_type == PlotChart_type."Barcolor";
#--- scripts
script nz {
input data = close;
input repl = 0;
def ret_val = if !IsNaN(data) then data else repl;
plot return = ret_val;
}
#vwma(source, length)
script VWMA {
input src = close;
input len = 15;
def v = volume;
def VWMA = SimpleMovingAvg(src * nz(v, 1), len) / SimpleMovingAvg(nz(v, 1), len);
plot result = VWMA;
}
#pine_alma(series, windowsize, offset, sigma) =>
script ALMA {
input series = close;
input windowsize = 9;
input Offset = 0.85;
input Sigma = 6;
def m = Offset * (windowsize - 1);
def s = windowsize / Sigma;
def norm = fold z = 0 to windowsize with CW do
CW + Exp(-(Sqr(z - m)) / (2 * Sqr(s)));
def sum = fold y = 0 to windowsize with WS do
WS + Exp(-(Sqr(y - m)) / (2 * Sqr(s))) * GetValue(series, windowsize - 1 - y);
plot ALMA = sum / norm ;
}
#pine_swma(source) =>
script swma {
input source = close;
def swma = source[3] * 1 / 6 + source[2] * 2 / 6 + source[1] * 2 / 6 + source[0] * 1 / 6;
plot retun = swma;
}
#kama(xPrice, Length)=>
script kama {
input xPrice = close;
input Length = 14;
def xvnoise = AbsValue(xPrice - xPrice[1]);
def nfastend = 0.666;
def nslowend = 0.0645;
def nsignal = AbsValue(xPrice - xPrice[Length]);
def nnoise = Sum(xvnoise, Length);
def nefratio = if nnoise != 0 then nsignal / nnoise else 0;
def nsmooth = Power(nefratio * (nfastend - nslowend) + nslowend, 2);
def nAMA;
nAMA = CompoundValue(1, nAMA[1] + nsmooth * (xPrice - nAMA[1]), xPrice);
plot returen = nAMA;
}
#mav (source, length) =>
script mav {
input source = close;
input length = 14;
def mav = ((SimpleMovingAvg(source, length)[1] * (length - 1)) + source) / length;
plot return = mav;
}
#zlema (src, length) =>
script zlema {
input src = close;
input length = 14;
def zxLag = if length / 2 == Round(length / 2, 0) then length / 2 else (length - 1) / 2;
def zxEMAData = (src + (src - src[zxLag]));
def ZLEMA = ExpAverage(zxEMAData, length);
plot return = ZLEMA;
}
#ama (source, length, fast, slow) =>
script ama {
input source = close;
input length = 14;
input fast = 2;
input slow = 30;
def fastAlpha = 2 / (fast + 1);
def slowAlpha = 2 / (slow + 1);
def hh = Highest(high, length + 1);
def ll = Lowest(low, length + 1);
def mltp = if (hh - ll) != 0 then AbsValue(2 * source - ll - hh) / (hh - ll) else 0;
def ssc = mltp * (fastAlpha - slowAlpha) + slowAlpha;
def ama;
ama = CompoundValue(1, ama[1] + Power(ssc, 2) * (source - ama[1]), source);
plot return = ama;
}
#export multiMa(float source, simple int length, string type) =>
script CalcMa {
input source = close;
input length = 14;
input type = "EMA";
def TMA = SimpleMovingAvg(SimpleMovingAvg(source, Ceil(length / 2)), Floor(length / 2) + 1);
def multiMa =
if type == "SMA" then SimpleMovingAvg(source, length) else
if type == "EMA" then ExpAverage(source, length) else
if type == "RMA" then WildersAverage(source, length) else
if type == "WMA" then WMA(source, length) else
if type == "KAMA" then KAMA(source, length) else
if type == "MAV" then MAV(source, length) else
if type == "AMA" then AMA(source, length) else
if type == "VWMA" then vwma(source, length) else
if type == "DEMA" then DEMA(source, length) else
if type == "TEMA" then TEMA(source, length) else
if type == "SWMA" then SWMA(source) else
if type == "ZLSMA" then ZLEMA(source, length) else
if type == "TMA" then TMA else
if type == "LSMA" then Inertia(source, length) else
if type == "ALMA" then ALMA(source, length) else
if type == "HMA" then HullMovingAvg(source, length ) else source;
plot return = multiMa;
}
#f_get_trigger_count
script f_get_trigger_count {
input _break = yes;
input _buy = no;
input _sell = no;
def count;
if _break {
count = 0;
} else
if _buy or _sell {
count = count[1] + 1;
} else {
count = count[1];
}
plot retun = count;
}
#f_get_bartype (_o, _h, _l, _c, _is_insidebar, _is_tinybar) =>
script f_get_bartype {
input _o = open;
input _h = high;
input _l = low;
input _c = close;
input _is_insidebar = no;
input _is_tinybar = no;
def is_positive_bar = _c >= _o;
def bt1 = if is_positive_bar then 1 else -1;
def bt2;
def bt;
if (_is_insidebar or _is_tinybar) {
bt2 = bt2[1];
} else {
bt2 = if is_positive_bar then 1 else -1;
}
if bt2 == 1 and bt2[1] == -1 and _c < ((_o[1] + _o[2]) / 2) {
bt = -1;
} else
if bt2 == -1 and bt2[1] == 1 and _c > ((_o[1] + _o[2]) / 2) {
bt = 1;
} else
if bt2 == -1 and bt2[1] == 1 and close > ((_h + _l) / 2) {
bt = 1;
} else
if bt2 == 1 and bt2[1] == -1 and close < ((_h + _l) / 2) {
bt = -1;
} else {
bt = bt2;
}
plot return = bt;
}
#close_calc (_type, _o, _h, _l, _c) =>
script close_calc {
input _type = 4;
input _o = open;
input _h = high;
input _l = low;
input _c = close;
def close_calc =
if _type == 4 then (_o + _h + _l + _c) /4 else
if _type == 3 then (_h + _l + _c) /3 else
if _type == 2 then (_o + _c) / 2 else
if _type == 1 then (_h + _l) / 2 else
if _type == 0 then _c else (_o + _h + _l + _c) /4;
plot return = close_calc;
}
#heikinashi (float _o, float _h, float _l, float _c, string _close_type = 'ohlc4') =>
script heikinashi {
input _o = open;
input _h = high;
input _l = low;
input _c = close;
# input _close_type = close;
def haclose = _c;
def temp_hopen = (_o[1] + _h[1] + _l[1] + _c[1]) / 4;
def haopen = if !isNaN(haopen[1]) then (haopen[1] + haclose[1]) / 2 else temp_hopen;
# plot close_ = haclose;
plot open_ = haopen;
}
def htf = GetAggregationPeriod();
def auto_htf = if htf <= AggregationPeriod.HOUR then GetDay() else
if htf <= AggregationPeriod.FOUR_HOURS then GetWeek() else
if htf <= AggregationPeriod.DAY then GetMonth() else GetYear();
def i_show_trigger_count_br = auto_htf;
def Src_Type = if Source_type==Source_type."hlc3" then 3 else
if Source_type==Source_type."oc2" then 2 else
if Source_type==Source_type."hl2" then 1 else
if Source_type==Source_type."close" then 0 else 4;
def i_averaged_times;
def i_close_type;
#// Setting param by mode
if Set_mode == Set_mode."Mode 1" {
i_averaged_times = 3;
i_close_type = 2;
} else
if Set_mode == Set_mode."Mode 2" {
i_averaged_times = 10;
i_close_type = 4;
} else
if Set_mode == Set_mode."Mode 3" {
i_averaged_times = 10;
i_close_type = 2;
} else {
i_averaged_times = averaged_times;
i_close_type = Src_Type;
}
def i_signal_times = Max(Floor(i_averaged_times / 2), 1);
def htf_changed = i_show_trigger_count_br - i_show_trigger_count_br[1];
#--- HA Calcualtion
def hclose0 = close_calc(i_close_type,open, high, low, close);
def hopen0 = heikinashi(open, high, low, hclose0);
def hclose2 = close_calc(i_close_type,hopen0, high, low, hclose0);
def hopen2 = heikinashi(hopen0, high, low, hclose2);
def hclose3 = close_calc(i_close_type,hopen2, high, low, hclose2);
def hopen3 = heikinashi(hopen2, high, low, hclose3);
def hclose4 = close_calc(i_close_type,hopen3, high, low, hclose3);
def hopen4 = heikinashi(hopen3, high, low, hclose4);
def hclose5 = close_calc(i_close_type,hopen4, high, low, hclose4);
def hopen5 = heikinashi(hopen4, high, low, hclose5);
def hclose6 = close_calc(i_close_type,hopen5, high, low, hclose5);
def hopen6 = heikinashi(hopen5, high, low, hclose6);
def hclose7 = close_calc(i_close_type,hopen6, high, low, hclose6);
def hopen7 = heikinashi(hopen6, high, low, hclose7);
def hclose8 = close_calc(i_close_type,hopen7, high, low, hclose7);
def hopen8 = heikinashi(hopen7, high, low, hclose8);
def hclose9 = close_calc(i_close_type,hopen8, high, low, hclose8);
def hopen9 = heikinashi(hopen8, high, low, hclose9);
def hclose10 = close_calc(i_close_type,hopen9, high, low, hclose9);
def hopen10 = heikinashi(hopen9, high, low, hclose10);
def times = min(max(i_averaged_times, 1), 10);
def hclose;
def hopen;
if times == 2 {
hclose = hclose2;
hopen = hopen2;
} else
if times == 3 {
hclose = hclose3;
hopen = hopen3;
} else
if times == 4 {
hclose = hclose4;
hopen = hopen4;
} else
if times == 5 {
hclose = hclose5;
hopen = hopen5;
} else
if times == 6 {
hclose = hclose6;
hopen = hopen6;
} else
if times == 7 {
hclose = hclose7;
hopen = hopen7;
} else
if times == 8 {
hclose = hclose8;
hopen = hopen8;
} else
if times == 9 {
hclose = hclose9;
hopen = hopen9;
} else
if times == 10 {
hclose = hclose10;
hopen = hopen10;
} else {
hclose = hclose0;
hopen = hopen0;
}
def srcAvg = (hclose + hopen) / 2;
def ma1 = CalcMa(srcAvg, ma1_period, ma1_type);
def ma2 = CalcMa(srcAvg, ma2_period, ma2_type);
def hl_pips = AbsValue(high - low) / (TickSize() * 10);
def oc_pips = AbsValue(hopen - hclose) / (TickSize() * 10);
#/ Conditions
def is_insidebar = high < high[1] and low > low[1];
def is_tinybar = oc_pips < Round(StDev(oc_pips, 100) / 3, 0);
def is_largebar = hl_pips > Round(StDev(hl_pips, 100) * 3, 0);
def bar_type = f_get_bartype(hopen, high, low, hclose, is_insidebar, is_tinybar);
#/ Triggers
def cond_buy = (bar_type - bar_type[1]) > 0 and (!is_tinybar);# //and (not is_largebar)
def cond_sell = (bar_type - bar_type[1]) < 0 and (!is_tinybar);# //and (not is_largebar)
#// Plot //
def candle_open;
def candle_close;
if i_show_heikinashi {
candle_open = hopen;
candle_close = hclose;
} else
if i_show_candle {
candle_open = open;
candle_close = close;
} else {
candle_open = na;
candle_close = na;
}
# Plot the new Chart
def upCandle = bar_type == 1;
AddChart(high = if upCandle then high else na , low = low , open = candle_close, close = candle_open,
type = ChartType.CANDLE, growcolor = CreateColor(34,171,148));
AddChart(high = if upCandle then na else high , low = low , open = candle_open, close = candle_close,
type = ChartType.CANDLE, growcolor = CreateColor(242,54,69));
#---- Mov Avg
plot MovAvg1 = if Show_ma1 then ma1 else na;
MovAvg1.SetDefaultColor(CreateColor(41,98,255));
plot MovAvg2 = if Show_ma2 then ma2 else na;
MovAvg2.SetDefaultColor(CreateColor(255,152,0));
MovAvg2.SetStyle(Curve.MEDIUM_DASH);
#// Triggers //
def margin_top = round(stdev(oc_pips, 500) / 2, 0);
def margin_top2 = round(stdev(oc_pips, 500) / 4, 0);
def p_top = max(max(hopen, hclose), high) + (margin_top * TickSize() * 10);
def p_btm = min(min(hopen, hclose), low) - (margin_top * TickSize() * 10);
plot buy = if show_triggers and cond_buy then p_btm else na;
buy.SetLineWeight(2);
buy.SetDefaultColor(Color.GREEN);
buy.SetPaintingStrategy(PaintingStrategy.POINTS);
plot sell = if show_triggers and cond_sell then p_top else na;
sell.SetLineWeight(2);
sell.SetDefaultColor(Color.RED);
sell.SetPaintingStrategy(PaintingStrategy.POINTS);
#--- count Bubbles
def trigger_count = f_get_trigger_count(htf_changed, cond_buy, cond_sell);
AddChartBubble(show_trigger_count and cond_buy, p_btm - (margin_top2 * TickSize() * 10), trigger_count, Color.GREEN, no);
AddChartBubble(show_trigger_count and cond_sell,p_top + (margin_top2 * TickSize() * 10), trigger_count, Color.RED, yes);
#-- Bar Color--
AssignPriceColor(if !i_show_barcolor then Color.CURRENT else
if upCandle then CreateColor(34,171,148) else CreateColor(242,54,69));
#--- END Code