Standardized MACD Heikin-Ashi Transformed for ThinkOrSwim

samer800

Moderator - Expert
VIP
Lifetime
nStoYKb.png


Author Message:

The Standardized MACD Heikin-Ashi Transformed (St. MACD) is an advanced indicator designed to overcome the limitations of the traditional MACD. It offers a more robust and standardized measure of momentum, making it comparable across different timeframes and securities. By incorporating the Heikin-Ashi transformation, the St. MACD provides a smoother visualization of trends and potential reversals, enhancing its utility for traders seeking a clearer view of the underlying market direction.

More Details : https://www.tradingview.com/v/g5qN1YDp/

Update:
I update the script to include dynamic levels. Can plot better signals I guess. Try it out!

More details on "MACD Fake Filter [RH]" indicator can found here:
https://www.tradingview.com/v/X1YMOQGm/

CODE:

CSS:
# https://www.tradingview.com/v/g5qN1YDp/
#//@QuantiLuxe
#indicator("Standardized MACD Heikin-Ashi Transformed"
# Converted by Sam4Cok@Samer800    - 07/2023
# upDate - Added Dynamic Levels    - 08/2023
# Dynamic level from "MACD Fake Filter [RH]" indicator by © HasanRifat
# https://www.tradingview.com/v/X1YMOQGm/
declare lower;

input useDynamicLevels = {Default "Yes", "No"};
input Source = close;            # "Source"
input MovAvgType = AverageType.EXPONENTIAL;
input CalcMethod = {Default "High/Low", "Open/Close"};
input fastLength = 12;           # "Fast Length"
input slowLength = 26;           # "Slow Length"
input signalLength = 9;          # "Signal Length"
input HeikinAshiSmoothing = {Default "No", "Yes"};
input ShowMacdSignalLine = yes;
input DisplayMode = {default "Hybrid", "MACD", "Histogram"};    # "Display Mode"
input signalThreshold = {"Don't Show Signals", "75", Default "100", "150"};  # "Reversion Threshold"
input BarColoringMode = {default "None","MidLine","Candles","Signal Cross","Extremities","Reversions"};
input HollowCandles = no;        # "Hollow Candles"
input HeikinAshiFactor = 1.0;      # "Heikin Ashi factor"
input UseModifiedCalc = no;        # "Use modified calculation?"
input smoothedHeikinAshi = no;     # "Do HA 2nd time?"
input UseModifiedCalcForSmoothedHa = no;    # "Use modified calculation (2nd time)?"

def na = Double.NaN;
def last = IsNaN(close);
def pos = Double.POSITIVE_INFINITY;
def neg = Double.NEGATIVE_INFINITY;
def ModHA2 = UseModifiedCalcForSmoothedHa;
def histo = DisplayMode == DisplayMode."Histogram";
def mac   = DisplayMode == DisplayMode."MACD";

def revt;
Switch (signalThreshold) {
Case "Don't Show Signals" : revt = na;
Case "75" : revt = 75;
Case "100" : revt = 100;
Case "150" : revt = 150;
}
def hiLo = high - low;
def OpCl = AbsValue(open - close);
def SrcDif;
Switch (CalcMethod) {
Case "High/Low"   : SrcDif = hiLo;
Case "Open/Close" : SrcDif = OpCl;
}
#-- Color--
DefineGlobalColor("up", CreateColor(0, 188, 212));
DefineGlobalColor("dn", CreateColor(252, 31, 31));
DefineGlobalColor("lvlup1", CreateColor(182, 2, 2));
DefineGlobalColor("lvlup2", CreateColor(85, 1, 1));
DefineGlobalColor("lvldn1", CreateColor(0, 170, 192));
DefineGlobalColor("lvldn2", CreateColor(0, 101, 114));

#// functions
#mkHA0(o_, h_, l_, c_, useModif) =>
script mkHA0 {
    input o_ = open;
    input h_ = high;
    input l_ = low;
    input c_ = close;
    input HAfact = 1;
    input useModif = no;
    def mintick = TickSize();
    def ohlc = (o_ + h_ + l_ + c_) / 4;
    def cl = Round(ohlc / mintick, 0) * mintick;# // needs to be before /op/
    def op;# = float(na)
    if useModif {
        op = if isNaN(o_[1]) then (o_ + HAfact*c_)/(1+HAfact) else
             (op[1] + HAfact * cl[1]) / (1 + HAfact);
    } else {
        op = if isNaN(o_[1]) then (o_ + HAfact*c_)/(1+HAfact) else
             (o_[1] + HAfact * c_[1]) / (1 + HAfact);
    }
    def op_ = Round(op / mintick, 0) * mintick;
    def max = Max(h_, Max(op, cl));
    def min = Min(l_, Min(op, cl));
    def hi  = Round(Max / mintick, 0) * mintick;
    def lo  = Round(Min / mintick, 0) * mintick;
    plot haop = op;
    plot haHi = hi;
    plot haLo = lo;
    plot haCl = cl;
}
#mkHA(o_, h_, l_, c_, useModif_, twice, useModif2) =>
script mkHA {
    input o_ = open;
    input h_ = high;
    input l_ = low;
    input c_ = close;
    input HAfact = 1;
    input useModif_ = no;
    input twice = no;
    input useModif2 = no;
    def op1 = mkHA0(o_, h_, l_, c_, HAfact, useModif_).haop;
    def hi1 = mkHA0(o_, h_, l_, c_, HAfact, useModif_).haHi;
    def lo1 = mkHA0(o_, h_, l_, c_, HAfact, useModif_).haLo;
    def cl1 = mkHA0(o_, h_, l_, c_, HAfact, useModif_).haCl;
    def op2 = mkHA0(op1, hi1, lo1, cl1, HAfact, useModif2).haop;
    def hi2 = mkHA0(op1, hi1, lo1, cl1, HAfact, useModif2).haHi;
    def lo2 = mkHA0(op1, hi1, lo1, cl1, HAfact, useModif2).haLo;
    def cl2 = mkHA0(op1, hi1, lo1, cl1, HAfact, useModif2).haCl;
    def op;
    def hi;
    def lo;
    def cl;
    if twice {
        op = op2;
        hi = hi2;
        lo = lo2;
        cl = cl2;
    } else {
        op = op1;
        hi = hi1;
        lo = lo1;
        cl = cl1;
    }
    plot haop = op;
    plot haHi = hi;
    plot haLo = lo;
    plot haCl = cl;
}

#f_macd(src, fast, slow) =>
script f_macd {
    input type = close;
    input src = close;
    input fast = 12;
    input slow = 26;
    input MovAvgType = AverageType.EXPONENTIAL;
    def diff = type;
    def fasMov = MovingAverage(MovAvgType, src, fast);
    def slowMov = MovingAverage(MovAvgType, src, slow);
    def value = fasMov - slowMov;
    def sign = MovingAverage(MovAvgType, diff, slow);
    def macd = (value / sign) * 100;
    plot out = macd;
}
#-- functions
def macd = f_macd(SrcDif, Source, fastLength, slowLength, MovAvgType);
def sig = MovingAverage(MovAvgType, macd, signalLength);
def hist = macd - sig;

def o_macd = macd[1];
def h_macd = Max(macd, macd[1]);
def l_macd = Min(macd, macd[1]);
def c_macd = macd;

def haO = mkHA(o_macd, h_macd, l_macd, c_macd, HeikinAshiFactor, UseModifiedCalc, smoothedHeikinAshi, ModHA2).haop;
def haH = mkHA(o_macd, h_macd, l_macd, c_macd, HeikinAshiFactor, UseModifiedCalc, smoothedHeikinAshi, ModHA2).haHi;
def haL = mkHA(o_macd, h_macd, l_macd, c_macd, HeikinAshiFactor, UseModifiedCalc, smoothedHeikinAshi, ModHA2).haLo;
def haC = mkHA(o_macd, h_macd, l_macd, c_macd, HeikinAshiFactor, UseModifiedCalc, smoothedHeikinAshi, ModHA2).haCl;

def haClose = haC;
def haOpen = haO;
def haHigh = haH;
def haLow  = haL;

def haSrcdiff;
def haHiLo = haHigh - haLow;
def haOpCl = AbsValue(haOpen - haClose);
Switch (CalcMethod) {
Case "High/Low"   : haSrcdiff = haHiLo;
Case "Open/Close" : haSrcdiff = haOpCl;
}
def hamacd = f_macd(haSrcdiff, haClose, fastLength, slowLength, MovAvgType);
def hasig = MovingAverage(MovAvgType, hamacd, signalLength);
def hahist = hamacd - hasig;

def hist1;def macd1; def sig1;def macdL;
Switch (HeikinAshiSmoothing) {
Case "yes"   :
    macd1 = hamacd;
    sig1  = hasig;
    hist1 = hahist;
    macdL = hamacd;
Case "No" :
    macd1 = macd;
    sig1  = sig;
    hist1 = hist;
    macdL = na;
}

def h_col = if hist1 > 0 then
           (if hist1 > hist1[1] then 2 else 1) else
           (if hist1 > hist1[1] then -1 else -2);

#--Heikin-Ashi
def candleUp = haClose > haOpen;
def haopenUp = if Histo then na else if candleUp then if HollowCandles then haOpen else haClose else na;
def hacloseUp = if Histo then na else if candleUp then if HollowCandles then haClose else haOpen else na;
def hahigh_   = if Histo then na else haHigh;
def halow_    = if Histo then na else haLow;
def haopenDn  = if Histo or candleUp then na else haOpen;
def hacloseDn = if Histo or candleUp then na else haClose;

AddChart(high = haHigh_, low = haLow_, open = haopenUp,  close = hacloseUp,
         type = ChartType.CANDLE, growcolor =  Color.CYAN);

AddChart(high = haHigh_ , low = haLow_ , open = haopenDn,  close = hacloseDn,
         type = ChartType.CANDLE, growcolor =  Color.MAGENTA);

#-- midLine
plot MidLine = if last then na else 0;
MidLine.SetStyle(Curve.SHORT_DASH);
MidLine.SetDefaultColor(Color.GRAY);
# macd Line
plot macdLine = if ShowMacdSignalLine then macdL else na;
macdLine.SetDefaultColor(Color.LIGHT_ORANGE);
#-- Signal Line
plot macdSig = if ShowMacdSignalLine then sig1 else na;    # "Signal"
macdSig.SetDefaultColor(Color.WHITE);

#-- Histogram
plot macdHist = if !mac then hist1 else na;    # "Histogram"
macdHist.SetLineWeight(3);
macdHist.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
macdHist.AssignValueColor(if h_col == 2  then Color.LIGHT_GREEN else
                          if h_col == 1  then Color.DARK_GRAY else#
                          if h_col == -2 then Color.PINK else Color.DARK_GRAY);
#-- Dynamic Levels

def macdZeroCrossOver  = !isNaN(macd1[1]) and macd1 > 0 and macd1[1] <= 0;
def macdZeroCrossUnder = !isNaN(macd1[1]) and macd1 < 0 and macd1[1] >= 0;

def activeWave;
if macdZeroCrossOver {
    activeWave = 1;
} else
if macdZeroCrossUnder {
    activeWave = -1;
} else {
    activeWave = activeWave[1];
}
def dirUp = activeWave == 1;
def dirDn = activeWave == -1;

def positiveTop;def negatieTop;
def AvgHi; def AvgLo; def countUp; def countDn;
if dirUp {
    positiveTop = max(positiveTop[1], macd1);
    negatieTop  = 0;
    AvgHi       = AvgHi[1];
    AvgLo       = if !dirUp[1] then AvgLo[1] + negatieTop[1] else AvgLo[1];
    countUp     = countUp[1];
    countDn     = if !dirUp[1] then countDn[1] + 1 else countDn[1];
    } else
if dirDn {
    negatieTop  = min(negatieTop[1], macd1);
    positiveTop = 0;
    AvgHi       = if !dirDn[1] then AvgHi[1] + positiveTop[1] else AvgHi[1];
    AvgLo       = AvgLo[1];
    countUp     = if !dirDn[1] then countUp[1] + 1 else countUp[1];
    countDn     = countDn[1];
} else {
    negatieTop  = 0;
    positiveTop = 0;
    AvgHi       = AvgHi[1];
    AvgLo       = AvgLo[1];
    countUp     = countUp[1];
    countDn     = countDn[1];
}
def posAvgHi = AvgHi;
def cntUp    = countUp;
def positiveAverageHeight = posAvgHi / cntUp;

def negAvgHi = AvgLo;
def cntDn    = countDn;
def negativeAverageHeight = negAvgHi / cntDn;

def bearishCrossunder = (macd1 < sig1) and (macd1[1] >= sig1[1]);
def bullishCrossover  = (macd1 > sig1) and (macd1[1] <= sig1[1]);
def crossunderAboveAvg = bearishCrossunder and macd1 > positiveAverageHeight;
def crossaboveBelowAvg = bullishCrossover and macd1 < negativeAverageHeight;

#-- OB/OS highlight
def max; def hh;def lh;def min;def ll;def hl;
Switch (useDynamicLevels) {
Case "Yes":
    max = if last then na else pos;
    hh = if last then na else if !histo then
         if positiveAverageHeight > 150 then positiveAverageHeight else 150 else
         if positiveAverageHeight > 75 then positiveAverageHeight else 75;
    lh = if last then na else positiveAverageHeight;
    min = if last then na else neg;
    ll = if last then na else if !histo then
         if negativeAverageHeight < -150 then negativeAverageHeight else -150 else
         if negativeAverageHeight < -75 then negativeAverageHeight else -75;
    hl = if last then na else negativeAverageHeight;
Case "No":
    max = if last then na else pos;
    hh = if last then na else if !histo then 150 else 75;
    lh = if last then na else if !histo then 100 else 50;
    min = if last then na else neg;
    ll = if last then na else if !histo then -150 else -75;
    hl = if last then na else if !histo then -100 else -50;
}

AddCloud(hh, lh, GlobalColor("lvlup2"), GlobalColor("lvlup2"));
AddCloud(max, hh, GlobalColor("lvlup1"), GlobalColor("lvlup1"));

AddCloud(hl, ll, GlobalColor("lvldn2"), GlobalColor("lvldn2"));
AddCloud(ll, min, GlobalColor("lvldn1"), GlobalColor("lvldn1"));

#-- Signal
def SigDn;def SigUp;
Switch (useDynamicLevels) {
Case "Yes":
    SigDn = if Histo then na else
            if crossunderAboveAvg then haHigh + 30 else na;
    SigUp = if Histo then na else 
            if crossaboveBelowAvg then haLow - 30 else na;
Case "No":
    SigDn = if Histo then na else
            if haHigh > revt and haClose < haOpen and !(haClose[1] < haOpen[1]) then
             haHigh + 30 else na;
    SigUp = if Histo then na else 
            if haLow < -revt and haClose > haOpen and !(haClose[1] > haOpen[1]) then
             haLow - 30 else na;
}

plot OB = SigDn;
plot OS = SigUp;
OB.SetPaintingStrategy(PaintingStrategy.SQUARES);
OS.SetPaintingStrategy(PaintingStrategy.SQUARES);
OB.SetDefaultColor(Color.RED);
OS.SetDefaultColor(Color.GREEN);

#-- Bar Color
def col;
switch (BarColoringMode) {
Case "None": col = na;
Case "MidLine" : col = if macd1 > 0 then 1 else -1;
Case "Extremities": col = if macd1 > revt then -1 else if macd1 < -revt then 1 else 0;
Case "Reversions" : col = if macd1 > revt and macd1 < macd1[1] and !(macd1[1] < macd1[2]) then -1 else
                          if macd1 < -revt and macd1 > macd1[1] and !(macd1[1] > macd1[2]) then 1 else 0;
Case "Candles"      : col = if haClose > haOpen then 1 else -1;
Case "Signal Cross" : col = if sig1 > haClose then -1 else 1;
}

AssignPriceColor(if isNaN(col) then Color.CURRENT else
                 if col >0 then GlobalColor("up") else
                 if col <0 then GlobalColor("dn") else Color.GRAY);

#--- END of Code
 
Last edited:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

mod note:
Please do not ask for a scan for this indicator.
It cannot be used in the Scan Hacker.
It cannot be used in watchlists or conditional orders, or any other widgets that utilize the condition wizard.
It is limited to creating plots on a chart.

TDA limits the complexity of scripts allowed in all other widgets, to prevent excess demand on TDA resources.
This script, in every way, exceeds TDA limits.
And No, after playing with the code, it could not be parred down to be less complex enough to run.

@pipes7693 @rkwchu @pete1123
 
Last edited:
Do you know whether this indicator will repaint?
Repainter Threads have a prefix of Repaints. I don't see anything in the code which would cause you to question repainting.

It is common for the current bar of most indicators on the forum to "repaint"
But that is not considered "repainting".
Obviously, the current bar is still forming, there is no way of knowing what the close, high, low, is going to be,until it closes. In the interim, it updates on every tick.

Continue to check it in live trading. Come back and relay your experience.
 
Last edited:
samer800, Thanks for sharing! This indicator sure is intriguing. If there is not too much to ask, can you add the codes for up/down arrows as histogram crosses above and below zero line?

nStoYKb.png


Author Message:

The Standardized MACD Heikin-Ashi Transformed (St. MACD) is an advanced indicator designed to overcome the limitations of the traditional MACD. It offers a more robust and standardized measure of momentum, making it comparable across different timeframes and securities. By incorporating the Heikin-Ashi transformation, the St. MACD provides a smoother visualization of trends and potential reversals, enhancing its utility for traders seeking a clearer view of the underlying market direction.

More Details : https://www.tradingview.com/v/g5qN1YDp/

CODE:

CSS:
# https://www.tradingview.com/v/g5qN1YDp/
#//@QuantiLuxe
#indicator("Standardized MACD Heikin-Ashi Transformed"
# Converted by Sam4Cok@Samer800    - 07/2023
declare lower;

input Source = close;            # "Source"
input MovAvgType = AverageType.EXPONENTIAL;
input CalcMethod = {Default "High/Low", "Open/Close"};
input fastLength = 12;           # "Fast Length"
input slowLength = 26;           # "Slow Length"
input signalLength = 9;          # "Signal Length"
input HeikinAshiSmoothing = {Default "No", "Yes"};
input ShowSignalLine = yes;
input DisplayMode = {default "Hybrid", "MACD", "Histogram"};    # "Display Mode"
input signalThreshold = {"Don't Show Signals", "75", Default "100", "150"};  # "Reversion Threshold"
input BarColoringMode = {default "None","MidLine","Candles","Signal Cross","Extremities","Reversions"};
input HollowCandles = no;        # "Hollow Candles"
input HeikinAshiFactor = 1.0;      # "Heikin Ashi factor"
input UseModifiedCalc = no;        # "Use modified calculation?"
input smoothedHeikinAshi = no;     # "Do HA 2nd time?"
input UseModifiedCalcForSmoothedHa = no;    # "Use modified calculation (2nd time)?"

def na = Double.NaN;
def last = IsNaN(close);
def ModHA2 = UseModifiedCalcForSmoothedHa;
def histo = DisplayMode == DisplayMode."Histogram";
def mac   = DisplayMode == DisplayMode."MACD";

def revt;
Switch (signalThreshold) {
Case "Don't Show Signals" : revt = na;
Case "75" : revt = 75;
Case "100" : revt = 100;
Case "150" : revt = 150;
}
def diff;
Switch (CalcMethod) {
Case "High/Low"   : diff = high - low;
Case "Open/Close" : diff = AbsValue(open - close);
}
#-- Color--
DefineGlobalColor("up", CreateColor(0, 188, 212));
DefineGlobalColor("dn", CreateColor(252, 31, 31));
DefineGlobalColor("lvlup1", CreateColor(182, 2, 2));
DefineGlobalColor("lvlup2", CreateColor(85, 1, 1));
DefineGlobalColor("lvldn1", CreateColor(0, 170, 192));
DefineGlobalColor("lvldn2", CreateColor(0, 101, 114));

#// functions
#mkHA0(o_, h_, l_, c_, useModif) =>
script mkHA0 {
    input o_ = open;
    input h_ = high;
    input l_ = low;
    input c_ = close;
    input HAfact = 1;
    input useModif = no;
    def mintick = TickSize();
    def ohlc = (o_ + h_ + l_ + c_) / 4;
    def cl = Round(ohlc / mintick, 0) * mintick;# // needs to be before /op/
    def op;# = float(na)
    if useModif {
        op = if isNaN(o_[1]) then (o_ + HAfact*c_)/(1+HAfact) else
             CompoundValue(1, (op[1] + HAfact * cl[1]) / (1 + HAfact), (o_ + HAfact * c_ ) / (1 + HAfact));
    } else {
        op = if isNaN(o_[1]) then (o_ + HAfact*c_)/(1+HAfact) else
             CompoundValue(1, (o_[1] + HAfact * c_[1]) / (1 + HAfact), (o_ + HAfact * c_ ) / (1 + HAfact));
    }
    def op_ = Round(op / mintick, 0) * mintick;
    def max = Max(h_, Max(op, cl));
    def min = Min(l_, Min(op, cl));
    def hi  = Round(Max / mintick, 0) * mintick;
    def lo  = Round(Min / mintick, 0) * mintick;
    plot haop = op;
    plot haHi = hi;
    plot haLo = lo;
    plot haCl = cl;
}
#mkHA(o_, h_, l_, c_, useModif_, twice, useModif2) =>
script mkHA {
    input o_ = open;
    input h_ = high;
    input l_ = low;
    input c_ = close;
    input HAfact = 1;
    input useModif_ = no;
    input twice = no;
    input useModif2 = no;
    def op1 = mkHA0(o_, h_, l_, c_, HAfact, useModif_).haop;
    def hi1 = mkHA0(o_, h_, l_, c_, HAfact, useModif_).haHi;
    def lo1 = mkHA0(o_, h_, l_, c_, HAfact, useModif_).haLo;
    def cl1 = mkHA0(o_, h_, l_, c_, HAfact, useModif_).haCl;
    def op2 = mkHA0(op1, hi1, lo1, cl1, HAfact, useModif2).haop;
    def hi2 = mkHA0(op1, hi1, lo1, cl1, HAfact, useModif2).haHi;
    def lo2 = mkHA0(op1, hi1, lo1, cl1, HAfact, useModif2).haLo;
    def cl2 = mkHA0(op1, hi1, lo1, cl1, HAfact, useModif2).haCl;
    def op;
    def hi;
    def lo;
    def cl;
    if twice {
        op = op2;
        hi = hi2;
        lo = lo2;
        cl = cl2;
    } else {
        op = op1;
        hi = hi1;
        lo = lo1;
        cl = cl1;
    }
    plot haop = op;
    plot haHi = hi;
    plot haLo = lo;
    plot haCl = cl;
}

#f_macd(src, fast, slow) =>
script f_macd {
    input type = close;
    input src = close;
    input fast = 12;
    input slow = 26;
    input MovAvgType = AverageType.EXPONENTIAL;
    def diff = type;
    def value = MovingAverage(MovAvgType, src, fast) - MovingAverage(MovAvgType, src, slow);
    def sign = MovingAverage(MovAvgType, diff, slow);
    def macd = (value / sign) * 100;
    plot out = macd;
}
#-- functions
def macd = f_macd(diff, Source, fastLength, slowLength, MovAvgType);
def sig = MovingAverage(MovAvgType, macd, signalLength);
def hist = macd - sig;

def o_macd = macd[1];
def h_macd = Max(macd, macd[1]);
def l_macd = Min(macd, macd[1]);
def c_macd = macd;

def haO = mkHA(o_macd, h_macd, l_macd, c_macd, HeikinAshiFactor, UseModifiedCalc, smoothedHeikinAshi, ModHA2).haop;
def haH = mkHA(o_macd, h_macd, l_macd, c_macd, HeikinAshiFactor, UseModifiedCalc, smoothedHeikinAshi, ModHA2).haHi;
def haL = mkHA(o_macd, h_macd, l_macd, c_macd, HeikinAshiFactor, UseModifiedCalc, smoothedHeikinAshi, ModHA2).haLo;
def haC = mkHA(o_macd, h_macd, l_macd, c_macd, HeikinAshiFactor, UseModifiedCalc, smoothedHeikinAshi, ModHA2).haCl;

def haClose = haC;
def haOpen = haO;
def haHigh = haH;
def haLow  = haL;

def hadiff;
Switch (CalcMethod) {
Case "High/Low"   : hadiff = haHigh - haLow;
Case "Open/Close" : hadiff = AbsValue(haOpen - haClose);
}
def hamacd = f_macd(hadiff, haClose, fastLength, slowLength, MovAvgType);
def hasig = MovingAverage(MovAvgType, hamacd, signalLength);
def hahist = hamacd - hasig;

def hist1;def macd1; def sig1;
Switch (HeikinAshiSmoothing) {
Case "yes"   :
    macd1 = hamacd;
    sig1  = hasig;
    hist1 = hahist;
Case "No" :
    macd1 = macd;
    sig1  = sig;
    hist1 = hist;
}

def h_col = if hist1 > 0 then
           (if hist1 > hist1[1] then 2 else 1) else
           (if hist1 > hist1[1] then -1 else -2);

#--Heikin-Ashi
def candleUp = haClose > haOpen;
def haopenUp = if Histo then na else if candleUp then if HollowCandles then haOpen else haClose else na;
def hacloseUp = if Histo then na else if candleUp then if HollowCandles then haClose else haOpen else na;
def hahigh_   = if Histo then na else haHigh;
def halow_    = if Histo then na else haLow;
def haopenDn  = if Histo or candleUp then na else haOpen;
def hacloseDn = if Histo or candleUp then na else haClose;

AddChart(high = haHigh_, low = haLow_, open = haopenUp,  close = hacloseUp,
         type = ChartType.CANDLE, growcolor =  Color.CYAN);

AddChart(high = haHigh_ , low = haLow_ , open = haopenDn,  close = hacloseDn,
         type = ChartType.CANDLE, growcolor =  Color.MAGENTA);

#-- midLine
plot MidLine = if last then na else 0;
MidLine.SetDefaultColor(Color.GRAY);

#-- Signal Line
plot macdSig = if ShowSignalLine then sig1 else na;    # "Signal"
macdSig.SetDefaultColor(Color.WHITE);

#-- Histogram
plot macdHist = if !mac then hist1 else na;    # "Histogram"
macdHist.SetLineWeight(3);
macdHist.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
macdHist.AssignValueColor(if h_col == 2  then Color.LIGHT_GREEN else#GlobalColor("lvldn1") else
                          if h_col == 1  then Color.DARK_GRAY else#GlobalColor("lvldn2") else
                          if h_col == -2 then Color.PINK else Color.DARK_GRAY);#GlobalColor("lvlup2") else GlobalColor("lvlup1"));

#-- OB/OS highlight
def max = if last then na else if !histo then 200 else 100;
def hh = if last then na else if !histo then 150 else 75;
def lh = if last then na else if !histo then 100 else 50;

AddCloud(hh, lh, GlobalColor("lvlup2"));
AddCloud(max, hh, GlobalColor("lvlup1"));

def min = if last then na else if !histo then -200 else -100;
def ll = if last then na else if !histo then -150 else -75;
def hl = if last then na else if !histo then -100 else -50;

AddCloud(hl, ll, GlobalColor("lvldn2"));
AddCloud(ll, min, GlobalColor("lvldn1"));

#-- Signal
def SigDn = if Histo then na else
            if haHigh > revt and haClose < haOpen and !(haClose[1] < haOpen[1]) then
             haHigh + 40 else na;
def SifUp = if Histo then na else
            if haLow < -revt and haClose > haOpen and !(haClose[1] > haOpen[1]) then
             haLow - 40 else na;

plot OB = SigDn;
plot OS = SifUp;
OB.SetPaintingStrategy(PaintingStrategy.SQUARES);
OS.SetPaintingStrategy(PaintingStrategy.SQUARES);
OB.SetDefaultColor(Color.RED);
OS.SetDefaultColor(Color.GREEN);

#-- Bar Color
def col;
switch (BarColoringMode) {
Case "None": col = na;
Case "MidLine" : col = if macd1 > 0 then 1 else -1;
Case "Extremities": col = if macd1 > revt then -1 else if macd1 < -revt then 1 else 0;
Case "Reversions" : col = if macd1 > revt and macd1 < macd1[1] and !(macd1[1] < macd1[2]) then -1 else
                          if macd1 < -revt and macd1 > macd1[1] and !(macd1[1] > macd1[2]) then 1 else 0;
Case "Candles"      : col = if haClose > haOpen then 1 else -1;
Case "Signal Cross" : col = if sig1 > haClose then -1 else 1;
}

AssignPriceColor(if isNaN(col) then Color.CURRENT else
                 if col >0 then GlobalColor("up") else
                 if col <0 then GlobalColor("dn") else Color.GRAY);


#--- END of Code[/COT
[/QUOTE]
 
Last edited by a moderator:
samer800, Thanks for sharing! This indicator sure is intriguing. If there is not too much to ask, can you add the codes for up/down arrows as histogram crosses above and below zero line?
add the below at the end of the code:

CSS:
def histUp = hist1>0;
def histDn = hist1<0;

plot arrowUp = if histUp and !histUp[1] then 0 else na;
plot arrowDn = if histDn and !histDn[1] then 0 else na;

arrowUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
arrowDn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);

arrowUp.SetDefaultColor(Color.GREEN);
arrowDn.SetDefaultColor(Color.RED);
 
add the below at the end of the code:

CSS:
def histUp = hist1>0;
def histDn = hist1<0;

plot arrowUp = if histUp and !histUp[1] then 0 else na;
plot arrowDn = if histDn and !histDn[1] then 0 else na;

arrowUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
arrowDn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);

arrowUp.SetDefaultColor(Color.GREEN);
arrowDn.SetDefaultColor(Color.RED);
Thank you so much! 🙌
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
403 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