Breadth Thrust Indicator for ThinkorSwim

Art

Member
Hi community, does anyone have/familiar with Whaley Breadth Thrust indicator for ThinkorSwim?

I found Zweig's market breadth indicator but I'm not sure whether that would be the same thing.

Code:
#Developed by Dr. Martin Zweig, the Breadth Thrust Indicator measures market momentum. The Breadth Thrust is calculated by dividing a 10-day exponential moving average of the number of advancing issues, by the number of advancing plus declining issues.

#A "Breadth Thrust" occurs when, during a 10-day period, the Breadth Thrust indicator rises from below 40% to above 61.5%. A "Thrust" indicates that the stock market has rapidly changed from an oversold condition to one of strength, but has not yet become overbought. According to Dr. Zweig, there have only been fourteen Breadth Thrusts since 1945. The average gain following these fourteen Thrusts was 24.6% in an average time-frame of eleven months. Dr. Zweig also points out that most bull markets begin with a Breadth Thrust. A weekly chart is best for this indicator.

declare lower;

plot zw = ExpAverage(data = close("$advn"), length = 10 ) /( ExpAverage(data=close("$advn"), length=10) + ExpAverage(data=close("$decn"), length = 10));
plot forty = 0.40;
forty.SetDefaultColor(Color.RED);
plot sixfifteen = 0.615;
sixfifteen.SetDefaultColor(Color.Yellow);
 
I recently became interested in breadth thrusts deemer, desmond, whaley, & now zweig. I found this link on twitter.

Breakaway Momentum (Breadth Thrust) [Upper Study]

Code:
# Breakaway Momentum (Breadth Thrust)
# defined: 10d sma advances > 1.97 x 10d sma declines.
# article: https://www.walterdeemer.com/bam.htm
#
# Desmond Reversals
# defined: 1 or more 90% downvolume day(s) [panic selling] followed by 90% upvolume day or 2 80+% upvolume days [panic buying]
# article: https://data.bloomberglp.com/assets/sites/2/2014/01/Desmond-report.pdf
#
# Whaley Thrusts
# defined:
#    - breath thursts (ADT): 5day cumulative advance/total issues crossing above 75 [whaley1] or crossing below 25 [whaley2]
#    - volume thrusts (UDT): 5day cumulative upvolume/total volume crossing above 77.8 [whaley3] or crossing below 16.4 [whaley4]
#    - sprice thrusts (SPT): 5day cumulative SP500 price % change of +10.05% [whaley5] or -13.85% [whaley6]
# article: http://docs.mta.org/pdfs/dowaward-2010.pdf
#
# Zweig Thrust
# defined: 10d ema advances crosses above 4.0 and 6.1 within 10 trading days
# article: https://www.seeitmarket.com/did-zweig-breadth-thrust-indicator-flash-buy-signal-for-stock-market/
# sourcecode: @ClarenceCarr
#


declare upper;

input thrustType = {default "Breakaway", "Desmond", "Whaley|ADT", "Whaley|UDT", "Whaley|SPT", "Zweig"};
input exchange = {default NYSE, NASDAQ, SnP500, Nasdaq100, Russell2000, Dow30, AMEX};
input signalType = {"Off", default "Bubble", "VerticalLine"};
input signalLabel = {"Date", "Type", default "Type|Date"};
input showLabels = no;
input showClouds = yes;
input tradeDays = 60;
input showExtLine = yes;


def advanceI;
def declineI;
def advanceV;
def declineV;
switch (exchange) {
case NYSE:
    advanceI = close("$ADVN");
    declineI = close("$DECN");
    advanceV = close("$UVOL");
    declineV = close("$DVOL");
case NASDAQ:
    advanceI = close("$ADVN/Q");
    declineI = close("$DECN/Q");
    advanceV = close("$UVOL/Q");
    declineV = close("$DVOL/Q");
case SnP500:
    advanceI = close("$ADVSP");
    declineI = close("$DECLSP");
    advanceV = close("$UVOLSP");
    declineV = close("$DVOLSP");
case Nasdaq100:
    advanceI = close("$ADVND");
    declineI = close("$DECLND");
    advanceV = close("$UVOLND");
    declineV = close("$DVOLND");
case Russell2000:
    advanceI = close("$ADVRL");
    declineI = close("$DECLRL");
    advanceV = close("$UVOLRL");
    declineV = close("$DVOLRL");
case Dow30:
    advanceI = close("$ADVI");
    declineI = close("$DECLI");
    advanceV = close("$UVOLI");
    declineV = close("$DVOLI");
case AMEX:
    advanceI = close("$ADVA");
    declineI = close("$DECA");
    advanceV = close("$UVOLUS");
    declineV = close("$DVOLUS");
}

def aCount = if isnan(advanceI) then aCount[1] + 1 else 0;
def dCount = if isnan(declineI) then dCount[1] + 1 else 0;
def addI = if isnan(advanceI) then GetValue(advanceI, aCount) else advanceI;
def decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
def totI = addI+decI;
def addIR = addI/totI;
def decIR = decI/totI;

def aVCount = if isnan(advanceV) then aVCount[1] + 1 else 0;
def dVCount = if isnan(declineV) then dVCount[1] + 1 else 0;
def addV = if isnan(advanceV) then GetValue(advanceV, aVCount) else advanceV;
def decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def addVR = addV/totV;
def decVR = decV/totV;

def SPChg = 100 * (close("SPX") / close("SPX")[1] - 1);


def advnDecl;
def mean;
def weak;
def thrust;
switch (thrustType){
case "Breakaway":
    advnDecl = round(average(addIR,10) - 1.97*average(decIR,10),2);
    mean = 0;
    weak = Double.NaN;
    thrust = Double.NaN;
case "Desmond":
    advnDecl = if addVR > decVR then round(addVR*100,2) else round(-decVR*100,2);
    mean = 0;
    weak = -80;
    thrust = 80;
case "Whaley|ADT":
    advnDecl = round(sum(addI,5)/sum(totI,5),3)*100;
    mean = 50;
    weak = 25;
    thrust = 75;
case "Whaley|UDT":
    advnDecl = round(sum(addV,5)/sum(totV,5),3)*100;
    mean = 50;
    weak = 16.4;
    thrust = 77.8;
case "Whaley|SPT":
    advnDecl = round(sum(SPChg,5),2);
    mean = 0;
    weak = -13.85;
    thrust = 10.05;
case "Zweig":
    advnDecl = round(ExpAverage(addIR,10),3);
    mean = 0.5;
    weak = 0.4;
    thrust = 0.61;
}

# -- plots
def ADExpAvg = if IsNaN(close) then double.nan else if IsNaN(advnDecl) then mean else advnDecl;


# -- signals
# breakaway signal
def breakaway = average(addIR,10) crosses above 1.97*average(decIR,10);
def breakaway2 = average(addIR,20) crosses above 1.72*average(decIR,20); # jan 2019 addendum
# desmond
def desmond1 = advnDecl[1]<=-90 and advnDecl>=90;
def desmond2 = advnDecl[2]<=-90 and advnDecl[1]>=80 and advnDecl>=80;
# whaley signal
def whaley1 = advnDecl crosses above thrust; #whaley1,3,&5
def whaley2 = advnDecl crosses below weak; #whaley2,4,&6
# zweig signal
def maxDays = 10;
def zCount = if advnDecl >= Weak then zCount[1] + 1 else 0;
def zweig = advnDecl crosses above Thrust and zCount <= maxDays;

def signal =
if thrustType == thrustType."breakaway" then (breakaway or breakaway2) else
if thrustType == thrustType."desmond" then (desmond1 or desmond2) else
if thrustType == thrustType."whaley|ADT" then (whaley1 or whaley2) else
if thrustType == thrustType."whaley|UDT" then (whaley1 or whaley2) else
if thrustType == thrustType."whaley|SPT" then (whaley1 or whaley2) else
if thrustType == thrustType."Zweig" then Zweig else
double.nan;

AddVerticalLine(signalType == signalType."VerticalLine" and signal,
(if signalLabel != signalLabel."Date" then
    " " + thrustType + ", " else ", ")
+
 (if GetMonth()==1 then " Jan " else
 if GetMonth()==2 then " Feb " else
 if GetMonth()==3 then " Mar " else
 if GetMonth()==4 then " Apr " else
 if GetMonth()==5 then " May " else
 if GetMonth()==6 then " Jun " else
 if GetMonth()==7 then " Jul " else
 if GetMonth()==8 then " Aug " else
 if GetMonth()==9 then " Sep " else
 if GetMonth()==10 then " Oct " else
 if GetMonth()==11 then " Nov " else
 " Dec ")
+ getdayofmonth(getyyyymmdd()) + ", " + asprice(getyear())
+ (if thrustType == thrustType."Zweig" then " (" + zCount + " days)" else " ")
, globalcolor("signal"), 1);

Addchartbubble(signalType == signalType."Bubble" and signalLabel != signalLabel."Date" and signal, low, thrustType + (if breakaway2 then "2" else ""), globalcolor("signal"), 0);
Addchartbubble(signalType == signalType."Bubble" and signalLabel != signalLabel."Type" and signal, low,
 (if GetMonth()==1 then "Jan " else
 if GetMonth()==2 then "Feb " else
 if GetMonth()==3 then "Mar " else
 if GetMonth()==4 then "Apr " else
 if GetMonth()==5 then "May " else
 if GetMonth()==6 then "Jun " else
 if GetMonth()==7 then "Jul " else
 if GetMonth()==8 then "Aug " else
 if GetMonth()==9 then "Sep " else
 if GetMonth()==10 then "Oct " else
 if GetMonth()==11 then "Nov " else
 "Dec ")
+ getdayofmonth(getyyyymmdd()) + ", " + asprice(getyear())
, color.light_gray, 0);


# -- clouds
def cond1 = if isnan(close) then double.nan else if signal or signal[1] then double.positive_INFINITY else Double.NaN;
def cond2 = if !showClouds then double.nan else double.negative_infinity;
AddCloud(cond1, cond2, globalcolor("signal"));
# zweig signal window
def ccross = advnDecl crosses above weak;
def ccloud = Sum(ccross, maxdays);
def value3 = if ccloud then double.positive_INFINITY else Double.NaN;
#AddCloud(if thrustType != thrustType."Zweig" then double.nan else value3, value2, color.light_gray);

# -- trade window
# sourcecode: @Pipsinger, bacontrading.com
Rec SignalBar = if barnumber() == 1 then double.nan else CompoundValue(1,if Signal then 0 else SignalBar[1] + 1,0);
def cond3 = if SignalBar <= tradeDays then double.positive_INFINITY else double.nan;
AddCloud(cond3, cond2, color.light_gray);


# -- thrust candles
# sourcecode: https://funwiththinkscript.com/adding-space-between-candles/
def o = open;
def h = high;
def l = low;
def c = close;

# up candles
def UpO;
def UpH;
def UpL;
def UpC;
if o <= c and signal
then {
    UpO = o;
    UpH = h;
    UpL = l;
    UpC = c;
} else {
    UpO = Double.NaN;
    UpH = Double.NaN;
    UpL = Double.NaN;
    UpC = Double.NaN;
}
AddChart(high = UpH, low = UpL, open = UpC, close = UpO, type = ChartType.CANDLE, growcolor = globalcolor("signal"));
AddChart(high = UpH, low = UpL, open = UpO, close = UpC, type = ChartType.CANDLE, growcolor = globalcolor("candlebody"));

# down candles
def DnO;
def DnH;
def DnL;
def DnC;
if o > c and signal
then {
    DnO = o;
    DnH = h;
    DnL = l;
    DnC = c;
} else {
    DnO = Double.NaN;
    DnH = Double.NaN;
    DnL = Double.NaN;
    DnC = Double.NaN;
}
AddChart(high = DnH, low = DnL, open = DnO, close = DnC, type = ChartType.CANDLE, growcolor = globalcolor("signal"));
AddChart(high = DnH, low = DnL, open = DnC, close = DnO, type = ChartType.CANDLE, growcolor = globalcolor("candlebody"));


# -- colors
defineglobalcolor("average", CreateColor(8,65,93)); #darker blue
#defineglobalcolor("average", CreateColor(0,102,153)); #blue
defineglobalcolor("candlebody", createcolor(25,25,25));
defineglobalcolor("signal", color.dark_orange);
defineglobalcolor("extLine", color.light_gray);


# -- labels
AddLabel(showLabels, " " + thrustType + " ", globalcolor("average"));
AddLabel(showLabels, " " + (if thrustType == thrustType."whaley|SPT" then "SnP500" else exchange) + " ", globalcolor("average"));

# breakaway labels
def ADRI =
if addI == 0 then 0 else
if decI == 0 then 0 else
if addI > decI then round(addI/decI,1) else round(-decI/addI, 1);
def ADRV =
if addV == 0 then 0 else
if decV == 0 then 0 else
if addV > decV then round(addV/decV,1) else round(-decV/addV, 1);

AddLabel(showLabels and thrustType == thrustType."breakaway",
if ADRI == 0 then " Iss: TILT " else
" Iss: " + ADRI + ":1 ", if addIR > decIR then color.uptick else if addIR < decIR then color.downtick else color.gray);
AddLabel(showLabels and thrustType == thrustType."breakaway", " " + round(addIR,2)*100 + "% ", if addIR > decIR then color.uptick else color.gray);
AddLabel(showLabels and thrustType == thrustType."breakaway", " " + round(decIR,2)*100 + "% ", if addIR > decIR then color.gray else color.downtick);

# desmond labels
AddLabel(showLabels and thrustType == thrustType."desmond",
if ADRV == 0 then " Vol: TILT " else
" Vol: " + ADRV + ":1 ", if addVR > decVR then color.uptick else if addVR < decVR then color.downtick else color.gray);
AddLabel(showLabels and thrustType == thrustType."desmond", " " + round(addVR,2)*100 + "% ", if addVR > decVR then color.uptick else color.gray);
AddLabel(showLabels and thrustType == thrustType."desmond", " " + round(decVR,2)*100 + "% ", if addVR > decVR then color.gray else color.downtick);

# whaley labels
AddLabel(showLabels and thrustType == thrustType."whaley|ADT", " " + ADExpAvg + "% ", if signal then globalcolor("signal") else globalcolor("average"));
AddLabel(showLabels and thrustType == thrustType."whaley|UDT", " " + ADExpAvg + "% ", if signal then globalcolor("signal") else globalcolor("average"));
AddLabel(showLabels and thrustType == thrustType."whaley|SPT", " " + ADExpAvg + "% Chg ", if signal then globalcolor("signal") else globalcolor("average"));

# zweig labels
AddLabel(showLabels and thrustType == thrustType."Zweig", " " + ADExpAvg * 100 + "% stocks ", if signal then globalcolor("signal") else if adexpavg crosses above Weak then color.magenta else globalcolor("average"));
AddLabel(showLabels and thrustType == thrustType."Zweig" and zCount <= maxDays, " AD >= Weak: " + zcount + " days ", color.light_gray);
#AddLabel(showLabels and thrustType == thrustType."Zweig" and zCount <= maxDays, " Signal Window: " + (10-zCount) + (if (10-zCount)<=1 then " day left" else " days "), if (10-zCount)<=2 then color.downtick else color.light_gray);
AddLabel(showLabels and thrustType == thrustType."Zweig" and zweig, " Thrust ", globalcolor("signal"));

# signal label
AddLabel(signal, " Alert ", globalcolor("signal"));


# -- extLine
def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(close), 0, barNumber));
def colorAvg = if isnan(close) then colorAvg[1] else if signal then 1 else 0;

def extend = if barNumber == 1 then Double.NaN else if barNumber == barCount then close
else if barNumber == barCount then Double.NaN else extend[1];
plot extLine = extend;
extLine.SetStyle(Curve.SHORT_DASH);
extLine.AssignValueColor(if colorAvg == 1 then globalcolor("signal") else globalcolor("extLine"));
#extLine.HideBubble();
extLine.HideTitle();
extLine.SetHiding(!showExtLine);

[Lower Study]

Code:
#
# Breakaway Momentum (Breadth Thrust)
# defined: 10d sma advances > 1.97 x 10d sma declines.
# article: https://www.walterdeemer.com/bam.htm
#
# Desmond Reversals
# defined: 1 or more 90% downvolume day(s) [panic selling] followed by 90% upvolume day or 2 80+% upvolume days [panic buying]
# article: https://data.bloomberglp.com/assets/sites/2/2014/01/Desmond-report.pdf
#
# Whaley Thrusts
# defined:
#    - breath thursts (ADT): 5day cumulative advance/total issues crossing above 75 [whaley1] or crossing below 25 [whaley2]
#    - volume thrusts (UDT): 5day cumulative upvolume/total volume crossing above 77.8 [whaley3] or crossing below 16.4 [whaley4]
#    - sprice thrusts (SPT): 5day cumulative SP500 price % change of +10.05% [whaley5] or -13.85% [whaley6]
# article: http://docs.mta.org/pdfs/dowaward-2010.pdf
#
# Zweig Thrust
# defined: 10d ema advances crosses above 4.0 and 6.1 within 10 trading days
# article: https://www.seeitmarket.com/did-zweig-breadth-thrust-indicator-flash-buy-signal-for-stock-market/
# sourcecode: @ClarenceCarr
#


declare lower;

input thrustType = {default "Breakaway", "Desmond", "Whaley|ADT", "Whaley|UDT", "Whaley|SPT", "Zweig"};
input exchange = {default NYSE, NASDAQ, SnP500, Nasdaq100, Russell2000, Dow30, AMEX};
input signalType = {"Off", default "Bubble", "VerticalLine"};
input signalLabel = {default "Date", "Type", "Type|Date"};


def advanceI;
def declineI;
def advanceV;
def declineV;
switch (exchange) {
case NYSE:
    advanceI = close("$ADVN");
    declineI = close("$DECN");
    advanceV = close("$UVOL");
    declineV = close("$DVOL");
case NASDAQ:
    advanceI = close("$ADVN/Q");
    declineI = close("$DECN/Q");
    advanceV = close("$UVOL/Q");
    declineV = close("$DVOL/Q");
case SnP500:
    advanceI = close("$ADVSP");
    declineI = close("$DECLSP");
    advanceV = close("$UVOLSP");
    declineV = close("$DVOLSP");
case Nasdaq100:
    advanceI = close("$ADVND");
    declineI = close("$DECLND");
    advanceV = close("$UVOLND");
    declineV = close("$DVOLND");
case Russell2000:
    advanceI = close("$ADVRL");
    declineI = close("$DECLRL");
    advanceV = close("$UVOLRL");
    declineV = close("$DVOLRL");
case Dow30:
    advanceI = close("$ADVI");
    declineI = close("$DECLI");
    advanceV = close("$UVOLI");
    declineV = close("$DVOLI");
case AMEX:
    advanceI = close("$ADVA");
    declineI = close("$DECA");
    advanceV = close("$UVOLUS");
    declineV = close("$DVOLUS");
}

def aCount = if isnan(advanceI) then aCount[1] + 1 else 0;
def dCount = if isnan(declineI) then dCount[1] + 1 else 0;
def addI = if isnan(advanceI) then GetValue(advanceI, aCount) else advanceI;
def decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
def totI = addI+decI;
def addIR = addI/totI;
def decIR = decI/totI;

def aVCount = if isnan(advanceV) then aVCount[1] + 1 else 0;
def dVCount = if isnan(declineV) then dVCount[1] + 1 else 0;
def addV = if isnan(advanceV) then GetValue(advanceV, aVCount) else advanceV;
def decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def addVR = addV/totV;
def decVR = decV/totV;

def SPChg = 100 * (close("SPX") / close("SPX")[1] - 1);


def advnDecl;
def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
    advnDecl = round(average(addIR,10) - 1.97*average(decIR,10),2);
    mean = 0;
    weak = Double.NaN;
    thrust = Double.NaN;
    spaceU = 1;
    spaceD = -1;
case "Desmond":
    advnDecl = if addVR > decVR then round(addVR*100,2) else round(-decVR*100,2);
    mean = 0;
    weak = -80;
    thrust = 80;
    spaceU = 100;
    spaceD = -100;
case "Whaley|ADT":
    advnDecl = round(sum(addI,5)/sum(totI,5),3)*100;
    mean = 50;
    weak = 25;
    thrust = 75;
    spaceU = 100;
    spaceD = 0;
case "Whaley|UDT":
    advnDecl = round(sum(addV,5)/sum(totV,5),3)*100;
    mean = 50;
    weak = 16.4;
    thrust = 77.8;
    spaceU = 100;
    spaceD = 0;
case "Whaley|SPT":
    advnDecl = round(sum(SPChg,5),2);
    mean = 0;
    weak = -13.85;
    thrust = 10.05;
    spaceU = 30;
    spaceD = -30;
case "Zweig":
    advnDecl = round(ExpAverage(addIR,10),3);
    mean = 0.5;
    weak = 0.4;
    thrust = 0.61;
    spaceU = 0.8;
    spaceD = 0.2;
}

# -- plots
plot ADAvg = if IsNaN(close) then double.nan else if IsNaN(advnDecl) then mean else advnDecl;
ADAvg.HideBubble();
ADAvg.HideTitle();
plot ADAvgDots = ADAvg;
ADAvgDots.SetPaintingStrategy(paintingStrategy.POINTS);
ADAvgDots.SetLineweight(2);
ADAvgDots.HideBubble();

plot ThrustLine = thrust;
ThrustLine.AssignValueColor(if thrustType == thrustType."desmond" then color.light_gray else Color.UPTICK);
ThrustLine.HideBubble();
ThrustLine.HideTitle();
plot MeanLine = Mean;
MeanLine.SetStyle(Curve.Short_Dash);
MeanLine.SetDefaultColor(color.gray);
MeanLine.HideBubble();
MeanLine.HideTitle();
plot WeakLine = weak;
WeakLine.AssignValueColor(if thrustType == thrustType."desmond" then color.light_gray else Color.DOWNTICK);
WeakLine.HideBubble();
WeakLine.HideTitle();


# -- signals
# breakaway signal
def breakaway = average(addIR,10) crosses above 1.97*average(decIR,10);
def breakaway2 = average(addIR,20) crosses above 1.72*average(decIR,20); # jan 2019 addendum
# desmond
def desmond1 = advnDecl[1] <= -90 and advnDecl >= 90;
def desmond2 = advnDecl[2] <= -90 and advnDecl[1] >= 80 and advnDecl >= 80;
# whaley signal
def whaley1 = advnDecl crosses above thrust; #whaley1,3,&5
def whaley2 = advnDecl crosses below weak; #whaley2,4,&6
# zweig signal
def maxDays = 10;
def zCount = if advnDecl >= weak then zCount[1] + 1 else 0;
def zweig = advnDecl crosses above Thrust and zCount <= maxDays;

def signal =
if thrustType == thrustType."breakaway" then (breakaway or breakaway2) else
if thrustType == thrustType."desmond" then (desmond1 or desmond2) else
if thrustType == thrustType."whaley|ADT" then (whaley1 or whaley2) else
if thrustType == thrustType."whaley|UDT" then (whaley1 or whaley2) else
if thrustType == thrustType."whaley|SPT" then (whaley1 or whaley2) else
if thrustType == thrustType."Zweig" then Zweig else
double.nan;

AddVerticalLine(signalType == signalType."VerticalLine" and signal,
(if signalLabel != signalLabel."Date" then
    " " + thrustType + ", " else " ")
+
(if signalLabel != signalLabel."Type" then
 (if GetMonth()==1 then " Jan " else
 if GetMonth()==2 then " Feb " else
 if GetMonth()==3 then " Mar " else
 if GetMonth()==4 then " Apr " else
 if GetMonth()==5 then " May " else
 if GetMonth()==6 then " Jun " else
 if GetMonth()==7 then " Jul " else
 if GetMonth()==8 then " Aug " else
 if GetMonth()==9 then " Sep " else
 if GetMonth()==10 then " Oct " else
 if GetMonth()==11 then " Nov " else
 " Dec ")
+ getdayofmonth(getyyyymmdd()) + ", " + asprice(getyear())
else " ")
+
(if signalLabel != signalLabel."Date" and thrustType == thrustType."Zweig" then " (" + zCount + " days)" else " ")
, globalcolor("signal"), 1);

Addchartbubble(signalType == signalType."Bubble" and signalLabel != signalLabel."Date" and signal, adavg, thrustType + if breakaway2 then "2" else "" + (if thrustType == thrustType."Zweig" then " (" + zCount + " days)" else ""), globalcolor("signal"), if (breakaway or breakaway2)then 1 else if whaley2 then 0 else 1);
Addchartbubble(signalType == signalType."Bubble" and signalLabel != signalLabel."Type" and signal, adavg,
 (if GetMonth()==1 then "Jan " else
 if GetMonth()==2 then "Feb " else
 if GetMonth()==3 then "Mar " else
 if GetMonth()==4 then "Apr " else
 if GetMonth()==5 then "May " else
 if GetMonth()==6 then "Jun " else
 if GetMonth()==7 then "Jul " else
 if GetMonth()==8 then "Aug " else
 if GetMonth()==9 then "Sep " else
 if GetMonth()==10 then "Oct " else
 if GetMonth()==11 then "Nov " else
 "Dec ")
+ getdayofmonth(getyyyymmdd()) + ", " + asprice(getyear())
, color.light_gray, if (breakaway or breakaway2) then 1 else if whaley2 then 0 else 1);


# -- clouds
def value1 = if isnan(close) then double.nan else if signal or signal[1] then double.positive_INFINITY else Double.NaN;
def value2 = double.negative_infinity;
AddCloud(value1, value2, globalcolor("signal"));
# zweig window
def ccross = advnDecl crosses above weak;
def ccloud = Sum(ccross, maxdays);
def value3 = if ccloud then double.positive_INFINITY else Double.NaN;
AddCloud(if thrustType != thrustType."Zweig" then double.nan else value3, value2, color.light_gray);


# -- colors
defineglobalcolor("average", CreateColor(8,65,93)); #darker blue
#defineglobalcolor("average", CreateColor(0,102,153)); #blue
defineglobalcolor("signal", color.dark_orange);
DefineGlobalColor("vline", CreateColor(102,102,102));

def colorAvg = if isnan(close) then colorAvg[1] else #if IsNaN(ADExpAvg) then 0 else
if barnumber() == 1 then 0 else
if thrustType == thrustType."breakaway" then if signal then 2 else 0 else
if thrustType == thrustType."desmond" then
    (if between(advnDecl,weak,thrust) then 0 else
    if signal then 2 else
    if advnDecl <= weak then -1 else
    if advnDecl >= thrust then 1 else 0)
else
if thrustType == thrustType."whaley|ADT" then if signal then 2 else 0 else
if thrustType == thrustType."whaley|UDT" then if signal then 2 else 0 else
if thrustType == thrustType."whaley|SPT" then if signal then 2 else 0 else
if thrustType == thrustType."Zweig" then
    (if signal then 2 else
    if ADAvg crosses above weak then 3 else 0)
else 0;

# plots
ADAvg.AssignValueColor(globalcolor("average"));
ADAvgDots.AssignValueColor(
if colorAvg == 3 then color.magenta else
if colorAvg == 2 then globalcolor("signal") else
if colorAvg == 1 then color.uptick else
if colorAvg == -1 then createcolor(204,51,0) else
globalcolor("average"));

# extension line
def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(close), 0, barNumber));
def extend = if barNumber == 1 then Double.NaN else if barNumber == barCount then ADAvg else if barNumber == barCount then Double.NaN else extend[1];
plot extLine = extend;
extLine.SetStyle(Curve.SHORT_DASH);
extLine.AssignValueColor(
if colorAvg == 3 then color.magenta else
if colorAvg == 2 then globalcolor("signal") else
if colorAvg == 1 then color.uptick else
if colorAvg == -1 then createcolor(204,51,0) else
globalcolor("average"));
#extLine.hidebubble();
extLine.hidetitle();


# -- labels
AddLabel(1, " " + thrustType + " ", globalcolor("average"));
AddLabel(1, " " + (if thrustType == thrustType."whaley|SPT" then "SnP500" else exchange) + " ", globalcolor("average"));

# breakaway labels, issues
def ADRI =
if addI == 0 then 0 else
if decI == 0 then 0 else
if addI > decI then round(addI/decI,1) else round(-decI/addI, 1);
AddLabel(thrustType == thrustType."breakaway",
if ADRI == 0 then " Iss: TILT " else
" Iss: " + ADRI + ":1 ", if addIR > decIR then color.uptick else if addIR < decIR then color.downtick else color.gray);
AddLabel(thrustType == thrustType."breakaway", " " + round(addIR,2)*100 + "% ", if addIR > decIR then color.uptick else color.gray);
AddLabel(thrustType == thrustType."breakaway", " " + round(decIR,2)*100 + "% ", if addIR > decIR then color.gray else color.downtick);

# desmond labels, volume
def ADRV =
if addV == 0 then 0 else
if decV == 0 then 0 else
if addV > decV then round(addV/decV,1) else round(-decV/addV, 1);
AddLabel(thrustType == thrustType."desmond",
if ADRV == 0 then " Vol: TILT " else
" Vol: " + ADRV + ":1 ", if addVR > decVR then color.uptick else if addVR < decVR then color.downtick else color.gray);
AddLabel(thrustType == thrustType."desmond", " " + round(addVR,2)*100 + "% ", if addVR > decVR then color.uptick else color.gray);
AddLabel(thrustType == thrustType."desmond", " " + round(decVR,2)*100 + "% ", if addVR > decVR then color.gray else color.downtick);

# whaley labels
AddLabel(thrustType == thrustType."whaley|ADT", " " + ADAvg + "% ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."whaley|UDT", " " + ADAvg + "% ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."whaley|SPT", " " + ADAvg + "% Chg ", ADAvg.TakeValueColor());

# zweig labels
AddLabel(thrustType == thrustType."Zweig", " " + ADAvg * 100 + "% stocks ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."Zweig" and zCount <= maxDays, " AD >= Weak: " + zcount + " days ", color.light_gray);
AddLabel(thrustType == thrustType."Zweig" and zweig, " Thrust ", globalcolor("signal"));

# signal label
AddLabel(signal, " Alert ", globalcolor("signal"));


# -- spacers
plot spaceUp = if barnumber() == 1 then spaceU else double.nan;
spaceUp.AssignValueCOlor(color.white);
spaceUp.HideBubble();
spaceUp.HideTitle();
plot spaceDn = if barnumber() == 1 then spaceD else double.nan;
spaceDn.AssignValueCOlor(color.white);
spaceDn.HideBubble();
spaceDn.HideTitle();


# -- yearly line
AddVerticalLine(GetYear() != GetYear()[1] and GetAggregationPeriod() >= AggregationPeriod.Day, " ", GlobalColor("vline"));

Desmond

Code:
#
# Breakaway Momentum (Breadth Thrust)
# defined: 10d sma advances > 1.97 x 10d sma declines.
# article: https://www.walterdeemer.com/bam.htm
#
# Desmond Reversals
# defined: 1 or more 90% downvolume day(s) [panic selling] followed by 90% upvolume day or 2 80+% upvolume days [panic buying]
# article: https://data.bloomberglp.com/assets/sites/2/2014/01/Desmond-report.pdf
#
# Whaley Thrusts
# defined:
#    - breath thursts (ADT): 5day cumulative advance/total issues crossing above 75 [whaley1] or crossing below 25 [whaley2]
#    - volume thrusts (UDT): 5day cumulative upvolume/total volume crossing above 77.8 [whaley3] or crossing below 16.4 [whaley4]
#    - sprice thrusts (SPT): 5day cumulative SP500 price % change of +10.05% [whaley5] or -13.85% [whaley6]
# article: http://docs.mta.org/pdfs/dowaward-2010.pdf
#
# Zweig Thrust
# defined: 10d ema advances crosses above 4.0 and 6.1 within 10 trading days
# article: https://www.seeitmarket.com/did-zweig-breadth-thrust-indicator-flash-buy-signal-for-stock-market/
# sourcecode: @ClarenceCarr
#


declare lower;

input thrustType = {default "Breakaway", "Desmond", "Whaley|ADT", "Whaley|UDT", "Whaley|SPT", "Zweig"};
input exchange = {default NYSE, NASDAQ, SnP500, Nasdaq100, Russell2000, Dow30, AMEX};
input signalType = {"Off", default "Bubble", "VerticalLine"};
input signalLabel = {default "Date", "Type", "Type|Date"};


def advanceI;
def declineI;
def advanceV;
def declineV;
switch (exchange) {
case NYSE:
    advanceI = close("$ADVN");
    declineI = close("$DECN");
    advanceV = close("$UVOL");
    declineV = close("$DVOL");
case NASDAQ:
    advanceI = close("$ADVN/Q");
    declineI = close("$DECN/Q");
    advanceV = close("$UVOL/Q");
    declineV = close("$DVOL/Q");
case SnP500:
    advanceI = close("$ADVSP");
    declineI = close("$DECLSP");
    advanceV = close("$UVOLSP");
    declineV = close("$DVOLSP");
case Nasdaq100:
    advanceI = close("$ADVND");
    declineI = close("$DECLND");
    advanceV = close("$UVOLND");
    declineV = close("$DVOLND");
case Russell2000:
    advanceI = close("$ADVRL");
    declineI = close("$DECLRL");
    advanceV = close("$UVOLRL");
    declineV = close("$DVOLRL");
case Dow30:
    advanceI = close("$ADVI");
    declineI = close("$DECLI");
    advanceV = close("$UVOLI");
    declineV = close("$DVOLI");
case AMEX:
    advanceI = close("$ADVA");
    declineI = close("$DECA");
    advanceV = close("$UVOLUS");
    declineV = close("$DVOLUS");
}

def aCount = if isnan(advanceI) then aCount[1] + 1 else 0;
def dCount = if isnan(declineI) then dCount[1] + 1 else 0;
def addI = if isnan(advanceI) then GetValue(advanceI, aCount) else advanceI;
def decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
def totI = addI+decI;
def addIR = addI/totI;
def decIR = decI/totI;

def aVCount = if isnan(advanceV) then aVCount[1] + 1 else 0;
def dVCount = if isnan(declineV) then dVCount[1] + 1 else 0;
def addV = if isnan(advanceV) then GetValue(advanceV, aVCount) else advanceV;
def decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def addVR = addV/totV;
def decVR = decV/totV;

def SPChg = 100 * (close("SPX") / close("SPX")[1] - 1);


def advnDecl;
def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
    advnDecl = round(average(addIR,10) - 1.97*average(decIR,10),2);
    mean = 0;
    weak = Double.NaN;
    thrust = Double.NaN;
    spaceU = 1;
    spaceD = -1;
case "Desmond":
    advnDecl = if addVR > decVR then round(addVR*100,2) else round(-decVR*100,2);
    mean = 0;
    weak = -80;
    thrust = 80;
    spaceU = 100;
    spaceD = -100;
case "Whaley|ADT":
    advnDecl = round(sum(addI,5)/sum(totI,5),3)*100;
    mean = 50;
    weak = 25;
    thrust = 75;
    spaceU = 100;
    spaceD = 0;
case "Whaley|UDT":
    advnDecl = round(sum(addV,5)/sum(totV,5),3)*100;
    mean = 50;
    weak = 16.4;
    thrust = 77.8;
    spaceU = 100;
    spaceD = 0;
case "Whaley|SPT":
    advnDecl = round(sum(SPChg,5),2);
    mean = 0;
    weak = -13.85;
    thrust = 10.05;
    spaceU = 30;
    spaceD = -30;
case "Zweig":
    advnDecl = round(ExpAverage(addIR,10),3);
    mean = 0.5;
    weak = 0.4;
    thrust = 0.61;
    spaceU = 0.8;
    spaceD = 0.2;
}

# -- plots
plot ADAvg = if IsNaN(close) then double.nan else if IsNaN(advnDecl) then mean else advnDecl;
ADAvg.HideBubble();
ADAvg.HideTitle();
plot ADAvgDots = ADAvg;
ADAvgDots.SetPaintingStrategy(paintingStrategy.POINTS);
ADAvgDots.SetLineweight(2);
ADAvgDots.HideBubble();

plot ThrustLine = thrust;
ThrustLine.AssignValueColor(if thrustType == thrustType."desmond" then color.light_gray else Color.UPTICK);
ThrustLine.HideBubble();
ThrustLine.HideTitle();
plot MeanLine = Mean;
MeanLine.SetStyle(Curve.Short_Dash);
MeanLine.SetDefaultColor(color.gray);
MeanLine.HideBubble();
MeanLine.HideTitle();
plot WeakLine = weak;
WeakLine.AssignValueColor(if thrustType == thrustType."desmond" then color.light_gray else Color.DOWNTICK);
WeakLine.HideBubble();
WeakLine.HideTitle();


# -- signals
# breakaway signal
def breakaway = average(addIR,10) crosses above 1.97*average(decIR,10);
def breakaway2 = average(addIR,20) crosses above 1.72*average(decIR,20); # jan 2019 addendum
# desmond
def desmond1 = advnDecl[1] <= -90 and advnDecl >= 90;
def desmond2 = advnDecl[2] <= -90 and advnDecl[1] >= 80 and advnDecl >= 80;
# whaley signal
def whaley1 = advnDecl crosses above thrust; #whaley1,3,&5
def whaley2 = advnDecl crosses below weak; #whaley2,4,&6
# zweig signal
def maxDays = 10;
def zCount = if advnDecl >= weak then zCount[1] + 1 else 0;
def zweig = advnDecl crosses above Thrust and zCount <= maxDays;

def signal =
if thrustType == thrustType."breakaway" then (breakaway or breakaway2) else
if thrustType == thrustType."desmond" then (desmond1 or desmond2) else
if thrustType == thrustType."whaley|ADT" then (whaley1 or whaley2) else
if thrustType == thrustType."whaley|UDT" then (whaley1 or whaley2) else
if thrustType == thrustType."whaley|SPT" then (whaley1 or whaley2) else
if thrustType == thrustType."Zweig" then Zweig else
double.nan;

AddVerticalLine(signalType == signalType."VerticalLine" and signal,
(if signalLabel != signalLabel."Date" then
    " " + thrustType + ", " else " ")
+
(if signalLabel != signalLabel."Type" then
 (if GetMonth()==1 then " Jan " else
 if GetMonth()==2 then " Feb " else
 if GetMonth()==3 then " Mar " else
 if GetMonth()==4 then " Apr " else
 if GetMonth()==5 then " May " else
 if GetMonth()==6 then " Jun " else
 if GetMonth()==7 then " Jul " else
 if GetMonth()==8 then " Aug " else
 if GetMonth()==9 then " Sep " else
 if GetMonth()==10 then " Oct " else
 if GetMonth()==11 then " Nov " else
 " Dec ")
+ getdayofmonth(getyyyymmdd()) + ", " + asprice(getyear())
else " ")
+
(if signalLabel != signalLabel."Date" and thrustType == thrustType."Zweig" then " (" + zCount + " days)" else " ")
, globalcolor("signal"), 1);

Addchartbubble(signalType == signalType."Bubble" and signalLabel != signalLabel."Date" and signal, adavg, thrustType + if breakaway2 then "2" else "" + (if thrustType == thrustType."Zweig" then " (" + zCount + " days)" else ""), globalcolor("signal"), if (breakaway or breakaway2)then 1 else if whaley2 then 0 else 1);
Addchartbubble(signalType == signalType."Bubble" and signalLabel != signalLabel."Type" and signal, adavg,
 (if GetMonth()==1 then "Jan " else
 if GetMonth()==2 then "Feb " else
 if GetMonth()==3 then "Mar " else
 if GetMonth()==4 then "Apr " else
 if GetMonth()==5 then "May " else
 if GetMonth()==6 then "Jun " else
 if GetMonth()==7 then "Jul " else
 if GetMonth()==8 then "Aug " else
 if GetMonth()==9 then "Sep " else
 if GetMonth()==10 then "Oct " else
 if GetMonth()==11 then "Nov " else
 "Dec ")
+ getdayofmonth(getyyyymmdd()) + ", " + asprice(getyear())
, color.light_gray, if (breakaway or breakaway2) then 1 else if whaley2 then 0 else 1);


# -- clouds
def value1 = if isnan(close) then double.nan else if signal or signal[1] then double.positive_INFINITY else Double.NaN;
def value2 = double.negative_infinity;
AddCloud(value1, value2, globalcolor("signal"));
# zweig window
def ccross = advnDecl crosses above weak;
def ccloud = Sum(ccross, maxdays);
def value3 = if ccloud then double.positive_INFINITY else Double.NaN;
AddCloud(if thrustType != thrustType."Zweig" then double.nan else value3, value2, color.light_gray);


# -- colors
defineglobalcolor("average", CreateColor(8,65,93)); #darker blue
#defineglobalcolor("average", CreateColor(0,102,153)); #blue
defineglobalcolor("signal", color.dark_orange);
DefineGlobalColor("vline", CreateColor(102,102,102));

def colorAvg = if isnan(close) then colorAvg[1] else #if IsNaN(ADExpAvg) then 0 else
if barnumber() == 1 then 0 else
if thrustType == thrustType."breakaway" then if signal then 2 else 0 else
if thrustType == thrustType."desmond" then
    (if between(advnDecl,weak,thrust) then 0 else
    if signal then 2 else
    if advnDecl <= weak then -1 else
    if advnDecl >= thrust then 1 else 0)
else
if thrustType == thrustType."whaley|ADT" then if signal then 2 else 0 else
if thrustType == thrustType."whaley|UDT" then if signal then 2 else 0 else
if thrustType == thrustType."whaley|SPT" then if signal then 2 else 0 else
if thrustType == thrustType."Zweig" then
    (if signal then 2 else
    if ADAvg crosses above weak then 3 else 0)
else 0;

# plots
ADAvg.AssignValueColor(globalcolor("average"));
ADAvgDots.AssignValueColor(
if colorAvg == 3 then color.magenta else
if colorAvg == 2 then globalcolor("signal") else
if colorAvg == 1 then color.uptick else
if colorAvg == -1 then createcolor(204,51,0) else
globalcolor("average"));

# extension line
def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(close), 0, barNumber));
def extend = if barNumber == 1 then Double.NaN else if barNumber == barCount then ADAvg else if barNumber == barCount then Double.NaN else extend[1];
plot extLine = extend;
extLine.SetStyle(Curve.SHORT_DASH);
extLine.AssignValueColor(
if colorAvg == 3 then color.magenta else
if colorAvg == 2 then globalcolor("signal") else
if colorAvg == 1 then color.uptick else
if colorAvg == -1 then createcolor(204,51,0) else
globalcolor("average"));
#extLine.hidebubble();
extLine.hidetitle();


# -- labels
AddLabel(1, " " + thrustType + " ", globalcolor("average"));
AddLabel(1, " " + (if thrustType == thrustType."whaley|SPT" then "SnP500" else exchange) + " ", globalcolor("average"));

# breakaway labels, issues
def ADRI =
if addI == 0 then 0 else
if decI == 0 then 0 else
if addI > decI then round(addI/decI,1) else round(-decI/addI, 1);
AddLabel(thrustType == thrustType."breakaway",
if ADRI == 0 then " Iss: TILT " else
" Iss: " + ADRI + ":1 ", if addIR > decIR then color.uptick else if addIR < decIR then color.downtick else color.gray);
AddLabel(thrustType == thrustType."breakaway", " " + round(addIR,2)*100 + "% ", if addIR > decIR then color.uptick else color.gray);
AddLabel(thrustType == thrustType."breakaway", " " + round(decIR,2)*100 + "% ", if addIR > decIR then color.gray else color.downtick);

# desmond labels, volume
def ADRV =
if addV == 0 then 0 else
if decV == 0 then 0 else
if addV > decV then round(addV/decV,1) else round(-decV/addV, 1);
AddLabel(thrustType == thrustType."desmond",
if ADRV == 0 then " Vol: TILT " else
" Vol: " + ADRV + ":1 ", if addVR > decVR then color.uptick else if addVR < decVR then color.downtick else color.gray);
AddLabel(thrustType == thrustType."desmond", " " + round(addVR,2)*100 + "% ", if addVR > decVR then color.uptick else color.gray);
AddLabel(thrustType == thrustType."desmond", " " + round(decVR,2)*100 + "% ", if addVR > decVR then color.gray else color.downtick);

# whaley labels
AddLabel(thrustType == thrustType."whaley|ADT", " " + ADAvg + "% ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."whaley|UDT", " " + ADAvg + "% ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."whaley|SPT", " " + ADAvg + "% Chg ", ADAvg.TakeValueColor());

# zweig labels
AddLabel(thrustType == thrustType."Zweig", " " + ADAvg * 100 + "% stocks ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."Zweig" and zCount <= maxDays, " AD >= Weak: " + zcount + " days ", color.light_gray);
AddLabel(thrustType == thrustType."Zweig" and zweig, " Thrust ", globalcolor("signal"));

# signal label
AddLabel(signal, " Alert ", globalcolor("signal"));


# -- spacers
plot spaceUp = if barnumber() == 1 then spaceU else double.nan;
spaceUp.AssignValueCOlor(color.white);
spaceUp.HideBubble();
spaceUp.HideTitle();
plot spaceDn = if barnumber() == 1 then spaceD else double.nan;
spaceDn.AssignValueCOlor(color.white);
spaceDn.HideBubble();
spaceDn.HideTitle();


# -- yearly line
AddVerticalLine(GetYear() != GetYear()[1] and GetAggregationPeriod() >= AggregationPeriod.Day, " ", GlobalColor("vline"));

Zweig

Code:
#
# Breakaway Momentum (Breadth Thrust)
# defined: 10d sma advances > 1.97 x 10d sma declines.
# article: https://www.walterdeemer.com/bam.htm
#
# Desmond Reversals
# defined: 1 or more 90% downvolume day(s) [panic selling] followed by 90% upvolume day or 2 80+% upvolume days [panic buying]
# article: https://data.bloomberglp.com/assets/sites/2/2014/01/Desmond-report.pdf
#
# Whaley Thrusts
# defined:
#    - breath thursts (ADT): 5day cumulative advance/total issues crossing above 75 [whaley1] or crossing below 25 [whaley2]
#    - volume thrusts (UDT): 5day cumulative upvolume/total volume crossing above 77.8 [whaley3] or crossing below 16.4 [whaley4]
#    - sprice thrusts (SPT): 5day cumulative SP500 price % change of +10.05% [whaley5] or -13.85% [whaley6]
# article: http://docs.mta.org/pdfs/dowaward-2010.pdf
#
# Zweig Thrust
# defined: 10d ema advances crosses above 4.0 and 6.1 within 10 trading days
# article: https://www.seeitmarket.com/did-zweig-breadth-thrust-indicator-flash-buy-signal-for-stock-market/
# sourcecode: @ClarenceCarr
#


declare lower;

input thrustType = {default "Breakaway", "Desmond", "Whaley|ADT", "Whaley|UDT", "Whaley|SPT", "Zweig"};
input exchange = {default NYSE, NASDAQ, SnP500, Nasdaq100, Russell2000, Dow30, AMEX};
input signalType = {"Off", default "Bubble", "VerticalLine"};
input signalLabel = {default "Date", "Type", "Type|Date"};


def advanceI;
def declineI;
def advanceV;
def declineV;
switch (exchange) {
case NYSE:
    advanceI = close("$ADVN");
    declineI = close("$DECN");
    advanceV = close("$UVOL");
    declineV = close("$DVOL");
case NASDAQ:
    advanceI = close("$ADVN/Q");
    declineI = close("$DECN/Q");
    advanceV = close("$UVOL/Q");
    declineV = close("$DVOL/Q");
case SnP500:
    advanceI = close("$ADVSP");
    declineI = close("$DECLSP");
    advanceV = close("$UVOLSP");
    declineV = close("$DVOLSP");
case Nasdaq100:
    advanceI = close("$ADVND");
    declineI = close("$DECLND");
    advanceV = close("$UVOLND");
    declineV = close("$DVOLND");
case Russell2000:
    advanceI = close("$ADVRL");
    declineI = close("$DECLRL");
    advanceV = close("$UVOLRL");
    declineV = close("$DVOLRL");
case Dow30:
    advanceI = close("$ADVI");
    declineI = close("$DECLI");
    advanceV = close("$UVOLI");
    declineV = close("$DVOLI");
case AMEX:
    advanceI = close("$ADVA");
    declineI = close("$DECA");
    advanceV = close("$UVOLUS");
    declineV = close("$DVOLUS");
}

def aCount = if isnan(advanceI) then aCount[1] + 1 else 0;
def dCount = if isnan(declineI) then dCount[1] + 1 else 0;
def addI = if isnan(advanceI) then GetValue(advanceI, aCount) else advanceI;
def decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
def totI = addI+decI;
def addIR = addI/totI;
def decIR = decI/totI;

def aVCount = if isnan(advanceV) then aVCount[1] + 1 else 0;
def dVCount = if isnan(declineV) then dVCount[1] + 1 else 0;
def addV = if isnan(advanceV) then GetValue(advanceV, aVCount) else advanceV;
def decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def addVR = addV/totV;
def decVR = decV/totV;

def SPChg = 100 * (close("SPX") / close("SPX")[1] - 1);


def advnDecl;
def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
    advnDecl = round(average(addIR,10) - 1.97*average(decIR,10),2);
    mean = 0;
    weak = Double.NaN;
    thrust = Double.NaN;
    spaceU = 1;
    spaceD = -1;
case "Desmond":
    advnDecl = if addVR > decVR then round(addVR*100,2) else round(-decVR*100,2);
    mean = 0;
    weak = -80;
    thrust = 80;
    spaceU = 100;
    spaceD = -100;
case "Whaley|ADT":
    advnDecl = round(sum(addI,5)/sum(totI,5),3)*100;
    mean = 50;
    weak = 25;
    thrust = 75;
    spaceU = 100;
    spaceD = 0;
case "Whaley|UDT":
    advnDecl = round(sum(addV,5)/sum(totV,5),3)*100;
    mean = 50;
    weak = 16.4;
    thrust = 77.8;
    spaceU = 100;
    spaceD = 0;
case "Whaley|SPT":
    advnDecl = round(sum(SPChg,5),2);
    mean = 0;
    weak = -13.85;
    thrust = 10.05;
    spaceU = 30;
    spaceD = -30;
case "Zweig":
    advnDecl = round(ExpAverage(addIR,10),3);
    mean = 0.5;
    weak = 0.4;
    thrust = 0.61;
    spaceU = 0.8;
    spaceD = 0.2;
}

# -- plots
plot ADAvg = if IsNaN(close) then double.nan else if IsNaN(advnDecl) then mean else advnDecl;
ADAvg.HideBubble();
ADAvg.HideTitle();
plot ADAvgDots = ADAvg;
ADAvgDots.SetPaintingStrategy(paintingStrategy.POINTS);
ADAvgDots.SetLineweight(2);
ADAvgDots.HideBubble();

plot ThrustLine = thrust;
ThrustLine.AssignValueColor(if thrustType == thrustType."desmond" then color.light_gray else Color.UPTICK);
ThrustLine.HideBubble();
ThrustLine.HideTitle();
plot MeanLine = Mean;
MeanLine.SetStyle(Curve.Short_Dash);
MeanLine.SetDefaultColor(color.gray);
MeanLine.HideBubble();
MeanLine.HideTitle();
plot WeakLine = weak;
WeakLine.AssignValueColor(if thrustType == thrustType."desmond" then color.light_gray else Color.DOWNTICK);
WeakLine.HideBubble();
WeakLine.HideTitle();


# -- signals
# breakaway signal
def breakaway = average(addIR,10) crosses above 1.97*average(decIR,10);
def breakaway2 = average(addIR,20) crosses above 1.72*average(decIR,20); # jan 2019 addendum
# desmond
def desmond1 = advnDecl[1] <= -90 and advnDecl >= 90;
def desmond2 = advnDecl[2] <= -90 and advnDecl[1] >= 80 and advnDecl >= 80;
# whaley signal
def whaley1 = advnDecl crosses above thrust; #whaley1,3,&5
def whaley2 = advnDecl crosses below weak; #whaley2,4,&6
# zweig signal
def maxDays = 10;
def zCount = if advnDecl >= weak then zCount[1] + 1 else 0;
def zweig = advnDecl crosses above Thrust and zCount <= maxDays;

def signal =
if thrustType == thrustType."breakaway" then (breakaway or breakaway2) else
if thrustType == thrustType."desmond" then (desmond1 or desmond2) else
if thrustType == thrustType."whaley|ADT" then (whaley1 or whaley2) else
if thrustType == thrustType."whaley|UDT" then (whaley1 or whaley2) else
if thrustType == thrustType."whaley|SPT" then (whaley1 or whaley2) else
if thrustType == thrustType."Zweig" then Zweig else
double.nan;

AddVerticalLine(signalType == signalType."VerticalLine" and signal,
(if signalLabel != signalLabel."Date" then
    " " + thrustType + ", " else " ")
+
(if signalLabel != signalLabel."Type" then
 (if GetMonth()==1 then " Jan " else
 if GetMonth()==2 then " Feb " else
 if GetMonth()==3 then " Mar " else
 if GetMonth()==4 then " Apr " else
 if GetMonth()==5 then " May " else
 if GetMonth()==6 then " Jun " else
 if GetMonth()==7 then " Jul " else
 if GetMonth()==8 then " Aug " else
 if GetMonth()==9 then " Sep " else
 if GetMonth()==10 then " Oct " else
 if GetMonth()==11 then " Nov " else
 " Dec ")
+ getdayofmonth(getyyyymmdd()) + ", " + asprice(getyear())
else " ")
+
(if signalLabel != signalLabel."Date" and thrustType == thrustType."Zweig" then " (" + zCount + " days)" else " ")
, globalcolor("signal"), 1);

Addchartbubble(signalType == signalType."Bubble" and signalLabel != signalLabel."Date" and signal, adavg, thrustType + if breakaway2 then "2" else "" + (if thrustType == thrustType."Zweig" then " (" + zCount + " days)" else ""), globalcolor("signal"), if (breakaway or breakaway2)then 1 else if whaley2 then 0 else 1);
Addchartbubble(signalType == signalType."Bubble" and signalLabel != signalLabel."Type" and signal, adavg,
 (if GetMonth()==1 then "Jan " else
 if GetMonth()==2 then "Feb " else
 if GetMonth()==3 then "Mar " else
 if GetMonth()==4 then "Apr " else
 if GetMonth()==5 then "May " else
 if GetMonth()==6 then "Jun " else
 if GetMonth()==7 then "Jul " else
 if GetMonth()==8 then "Aug " else
 if GetMonth()==9 then "Sep " else
 if GetMonth()==10 then "Oct " else
 if GetMonth()==11 then "Nov " else
 "Dec ")
+ getdayofmonth(getyyyymmdd()) + ", " + asprice(getyear())
, color.light_gray, if (breakaway or breakaway2) then 1 else if whaley2 then 0 else 1);


# -- clouds
def value1 = if isnan(close) then double.nan else if signal or signal[1] then double.positive_INFINITY else Double.NaN;
def value2 = double.negative_infinity;
AddCloud(value1, value2, globalcolor("signal"));
# zweig window
def ccross = advnDecl crosses above weak;
def ccloud = Sum(ccross, maxdays);
def value3 = if ccloud then double.positive_INFINITY else Double.NaN;
AddCloud(if thrustType != thrustType."Zweig" then double.nan else value3, value2, color.light_gray);


# -- colors
defineglobalcolor("average", CreateColor(8,65,93)); #darker blue
#defineglobalcolor("average", CreateColor(0,102,153)); #blue
defineglobalcolor("signal", color.dark_orange);
DefineGlobalColor("vline", CreateColor(102,102,102));

def colorAvg = if isnan(close) then colorAvg[1] else #if IsNaN(ADExpAvg) then 0 else
if barnumber() == 1 then 0 else
if thrustType == thrustType."breakaway" then if signal then 2 else 0 else
if thrustType == thrustType."desmond" then
    (if between(advnDecl,weak,thrust) then 0 else
    if signal then 2 else
    if advnDecl <= weak then -1 else
    if advnDecl >= thrust then 1 else 0)
else
if thrustType == thrustType."whaley|ADT" then if signal then 2 else 0 else
if thrustType == thrustType."whaley|UDT" then if signal then 2 else 0 else
if thrustType == thrustType."whaley|SPT" then if signal then 2 else 0 else
if thrustType == thrustType."Zweig" then
    (if signal then 2 else
    if ADAvg crosses above weak then 3 else 0)
else 0;

# plots
ADAvg.AssignValueColor(globalcolor("average"));
ADAvgDots.AssignValueColor(
if colorAvg == 3 then color.magenta else
if colorAvg == 2 then globalcolor("signal") else
if colorAvg == 1 then color.uptick else
if colorAvg == -1 then createcolor(204,51,0) else
globalcolor("average"));

# extension line
def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(close), 0, barNumber));
def extend = if barNumber == 1 then Double.NaN else if barNumber == barCount then ADAvg else if barNumber == barCount then Double.NaN else extend[1];
plot extLine = extend;
extLine.SetStyle(Curve.SHORT_DASH);
extLine.AssignValueColor(
if colorAvg == 3 then color.magenta else
if colorAvg == 2 then globalcolor("signal") else
if colorAvg == 1 then color.uptick else
if colorAvg == -1 then createcolor(204,51,0) else
globalcolor("average"));
#extLine.hidebubble();
extLine.hidetitle();


# -- labels
AddLabel(1, " " + thrustType + " ", globalcolor("average"));
AddLabel(1, " " + (if thrustType == thrustType."whaley|SPT" then "SnP500" else exchange) + " ", globalcolor("average"));

# breakaway labels, issues
def ADRI =
if addI == 0 then 0 else
if decI == 0 then 0 else
if addI > decI then round(addI/decI,1) else round(-decI/addI, 1);
AddLabel(thrustType == thrustType."breakaway",
if ADRI == 0 then " Iss: TILT " else
" Iss: " + ADRI + ":1 ", if addIR > decIR then color.uptick else if addIR < decIR then color.downtick else color.gray);
AddLabel(thrustType == thrustType."breakaway", " " + round(addIR,2)*100 + "% ", if addIR > decIR then color.uptick else color.gray);
AddLabel(thrustType == thrustType."breakaway", " " + round(decIR,2)*100 + "% ", if addIR > decIR then color.gray else color.downtick);

# desmond labels, volume
def ADRV =
if addV == 0 then 0 else
if decV == 0 then 0 else
if addV > decV then round(addV/decV,1) else round(-decV/addV, 1);
AddLabel(thrustType == thrustType."desmond",
if ADRV == 0 then " Vol: TILT " else
" Vol: " + ADRV + ":1 ", if addVR > decVR then color.uptick else if addVR < decVR then color.downtick else color.gray);
AddLabel(thrustType == thrustType."desmond", " " + round(addVR,2)*100 + "% ", if addVR > decVR then color.uptick else color.gray);
AddLabel(thrustType == thrustType."desmond", " " + round(decVR,2)*100 + "% ", if addVR > decVR then color.gray else color.downtick);

# whaley labels
AddLabel(thrustType == thrustType."whaley|ADT", " " + ADAvg + "% ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."whaley|UDT", " " + ADAvg + "% ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."whaley|SPT", " " + ADAvg + "% Chg ", ADAvg.TakeValueColor());

# zweig labels
AddLabel(thrustType == thrustType."Zweig", " " + ADAvg * 100 + "% stocks ", ADAvg.TakeValueColor());
AddLabel(thrustType == thrustType."Zweig" and zCount <= maxDays, " AD >= Weak: " + zcount + " days ", color.light_gray);
AddLabel(thrustType == thrustType."Zweig" and zweig, " Thrust ", globalcolor("signal"));

# signal label
AddLabel(signal, " Alert ", globalcolor("signal"));


# -- spacers
plot spaceUp = if barnumber() == 1 then spaceU else double.nan;
spaceUp.AssignValueCOlor(color.white);
spaceUp.HideBubble();
spaceUp.HideTitle();
plot spaceDn = if barnumber() == 1 then spaceD else double.nan;
spaceDn.AssignValueCOlor(color.white);
spaceDn.HideBubble();
spaceDn.HideTitle();


# -- yearly line
AddVerticalLine(GetYear() != GetYear()[1] and GetAggregationPeriod() >= AggregationPeriod.Day, " ", GlobalColor("vline"));

My entire grid setup: https://tos.mx/VqsmiPC
 

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

@SilverSurferAI Duuuude! Thanks, I've been looking for an all in one for a long damn time. Don't know if anybody follows these (I'm still on the fence), but the breakaway thrust just triggered, which hasn't happened since early Jan 2019.
 
The Whaley SPT signals off of the March lows might have been expected for a bounce given the sharpness of the decline. But, the recent Breakaway (6/3 & 6/5) plus Whaley ADT on 6/8/20 coming this late in a rally are unusual indicators that the rally may have legs.
The lower indicators appear to be broken for Desmond and Whaley UDT when using NYSE (showing errors the last few weeks). I had to change those to NASDAQ composite.
 
I just use them as the upper indicators with the vertical lines. As much as I hate this rally, this thing has some strong momentum. The thing that worries me the most is the spy to qqq ratio. Lowest it's been since the dot-com boom. The only difference being the RSI is no way near as sunk as back then.
 
Certainly a tech heavy uptrend. Ongoing strength in NASDAQ (COMP & NDX) vs middling SPX vs weaker $DJI vs even weaker RUT.
The upper indicators (vertical lines) show thrust dates based on the lower indicators. NYSE and AMEX inputs have been broken for several weeks in Desmond and Whaley UDT. Weird that they still show good data for earlier in the year, though.
 
I use it as an extreme indicator. When TRIN nears previous extreme levels (hi or Low), I start looking for other reversal confirmation signals. For example, candle stick pattern, fibonacci levels, DeMark trigger, McClellan oscillator.
 
Last edited by a moderator:

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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