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
# 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 showExtLine = yes;

def declineI;
def declineV;
switch (exchange) {
case NYSE:
declineI = close("\$DECN");
declineV = close("\$DVOL");
case NASDAQ:
declineI = close("\$DECN/Q");
declineV = close("\$DVOL/Q");
case SnP500:
declineI = close("\$DECLSP");
declineV = close("\$DVOLSP");
case Nasdaq100:
declineI = close("\$DECLND");
declineV = close("\$DVOLND");
case Russell2000:
declineI = close("\$DECLRL");
declineV = close("\$DVOLRL");
case Dow30:
declineI = close("\$DECLI");
declineV = close("\$DVOLI");
case AMEX:
declineI = close("\$DECA");
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 decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
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 decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def decVR = decV/totV;

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

def mean;
def weak;
def thrust;
switch (thrustType){
case "Breakaway":
mean = 0;
weak = Double.NaN;
thrust = Double.NaN;
case "Desmond":
mean = 0;
weak = -80;
thrust = 80;
mean = 50;
weak = 25;
thrust = 75;
case "Whaley|UDT":
mean = 50;
weak = 16.4;
thrust = 77.8;
case "Whaley|SPT":
mean = 0;
weak = -13.85;
thrust = 10.05;
case "Zweig":
mean = 0.5;
weak = 0.4;
thrust = 0.61;
}

# -- plots

# -- signals
# breakaway signal
def breakaway = average(addIR,10) crosses above 1.97*average(decIR,10);
# desmond
# 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;

(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;
# 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);

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;

# -- thrust 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
if addI == 0 then 0 else
if decI == 0 then 0 else
if addV == 0 then 0 else
if decV == 0 then 0 else

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
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

# -- 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:
``````#
# 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
# 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 declineI;
def declineV;
switch (exchange) {
case NYSE:
declineI = close("\$DECN");
declineV = close("\$DVOL");
case NASDAQ:
declineI = close("\$DECN/Q");
declineV = close("\$DVOL/Q");
case SnP500:
declineI = close("\$DECLSP");
declineV = close("\$DVOLSP");
case Nasdaq100:
declineI = close("\$DECLND");
declineV = close("\$DVOLND");
case Russell2000:
declineI = close("\$DECLRL");
declineV = close("\$DVOLRL");
case Dow30:
declineI = close("\$DECLI");
declineV = close("\$DVOLI");
case AMEX:
declineI = close("\$DECA");
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 decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
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 decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def decVR = decV/totV;

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

def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
mean = 0;
weak = Double.NaN;
thrust = Double.NaN;
spaceU = 1;
spaceD = -1;
case "Desmond":
mean = 0;
weak = -80;
thrust = 80;
spaceU = 100;
spaceD = -100;
mean = 50;
weak = 25;
thrust = 75;
spaceU = 100;
spaceD = 0;
case "Whaley|UDT":
mean = 50;
weak = 16.4;
thrust = 77.8;
spaceU = 100;
spaceD = 0;
case "Whaley|SPT":
mean = 0;
weak = -13.85;
thrust = 10.05;
spaceU = 30;
spaceD = -30;
case "Zweig":
mean = 0.5;
weak = 0.4;
thrust = 0.61;
spaceU = 0.8;
spaceD = 0.2;
}

# -- plots

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);
# desmond
# 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;

(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);
(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;
# 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 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
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
if addI == 0 then 0 else
if decI == 0 then 0 else
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
if addV == 0 then 0 else
if decV == 0 then 0 else
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

# zweig labels
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

# -- 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:
``````#
# 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
# 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 declineI;
def declineV;
switch (exchange) {
case NYSE:
declineI = close("\$DECN");
declineV = close("\$DVOL");
case NASDAQ:
declineI = close("\$DECN/Q");
declineV = close("\$DVOL/Q");
case SnP500:
declineI = close("\$DECLSP");
declineV = close("\$DVOLSP");
case Nasdaq100:
declineI = close("\$DECLND");
declineV = close("\$DVOLND");
case Russell2000:
declineI = close("\$DECLRL");
declineV = close("\$DVOLRL");
case Dow30:
declineI = close("\$DECLI");
declineV = close("\$DVOLI");
case AMEX:
declineI = close("\$DECA");
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 decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
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 decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def decVR = decV/totV;

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

def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
mean = 0;
weak = Double.NaN;
thrust = Double.NaN;
spaceU = 1;
spaceD = -1;
case "Desmond":
mean = 0;
weak = -80;
thrust = 80;
spaceU = 100;
spaceD = -100;
mean = 50;
weak = 25;
thrust = 75;
spaceU = 100;
spaceD = 0;
case "Whaley|UDT":
mean = 50;
weak = 16.4;
thrust = 77.8;
spaceU = 100;
spaceD = 0;
case "Whaley|SPT":
mean = 0;
weak = -13.85;
thrust = 10.05;
spaceU = 30;
spaceD = -30;
case "Zweig":
mean = 0.5;
weak = 0.4;
thrust = 0.61;
spaceU = 0.8;
spaceD = 0.2;
}

# -- plots

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);
# desmond
# 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;

(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);
(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;
# 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 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
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
if addI == 0 then 0 else
if decI == 0 then 0 else
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
if addV == 0 then 0 else
if decV == 0 then 0 else
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

# zweig labels
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

# -- 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:
``````#
# 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
# 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 declineI;
def declineV;
switch (exchange) {
case NYSE:
declineI = close("\$DECN");
declineV = close("\$DVOL");
case NASDAQ:
declineI = close("\$DECN/Q");
declineV = close("\$DVOL/Q");
case SnP500:
declineI = close("\$DECLSP");
declineV = close("\$DVOLSP");
case Nasdaq100:
declineI = close("\$DECLND");
declineV = close("\$DVOLND");
case Russell2000:
declineI = close("\$DECLRL");
declineV = close("\$DVOLRL");
case Dow30:
declineI = close("\$DECLI");
declineV = close("\$DVOLI");
case AMEX:
declineI = close("\$DECA");
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 decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
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 decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def decVR = decV/totV;

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

def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
mean = 0;
weak = Double.NaN;
thrust = Double.NaN;
spaceU = 1;
spaceD = -1;
case "Desmond":
mean = 0;
weak = -80;
thrust = 80;
spaceU = 100;
spaceD = -100;
mean = 50;
weak = 25;
thrust = 75;
spaceU = 100;
spaceD = 0;
case "Whaley|UDT":
mean = 50;
weak = 16.4;
thrust = 77.8;
spaceU = 100;
spaceD = 0;
case "Whaley|SPT":
mean = 0;
weak = -13.85;
thrust = 10.05;
spaceU = 30;
spaceD = -30;
case "Zweig":
mean = 0.5;
weak = 0.4;
thrust = 0.61;
spaceU = 0.8;
spaceD = 0.2;
}

# -- plots

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);
# desmond
# 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;

(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);
(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;
# 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 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
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
if addI == 0 then 0 else
if decI == 0 then 0 else
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
if addV == 0 then 0 else
if decV == 0 then 0 else
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

# zweig labels
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

# -- 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

@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.

Try this Zweig Breadth Thrust indicator. Here is a TOS sharing link for an SPX chart with the indicator already on it: http://tos.mx/IhZpd9

would you please explain how you use it?​

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
# 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 showExtLine = yes;

def declineI;
def declineV;
switch (exchange) {
case NYSE:
declineI = close("\$DECN");
declineV = close("\$DVOL");
case NASDAQ:
declineI = close("\$DECN/Q");
declineV = close("\$DVOL/Q");
case SnP500:
declineI = close("\$DECLSP");
declineV = close("\$DVOLSP");
case Nasdaq100:
declineI = close("\$DECLND");
declineV = close("\$DVOLND");
case Russell2000:
declineI = close("\$DECLRL");
declineV = close("\$DVOLRL");
case Dow30:
declineI = close("\$DECLI");
declineV = close("\$DVOLI");
case AMEX:
declineI = close("\$DECA");
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 decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
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 decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def decVR = decV/totV;

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

def mean;
def weak;
def thrust;
switch (thrustType){
case "Breakaway":
mean = 0;
weak = Double.NaN;
thrust = Double.NaN;
case "Desmond":
mean = 0;
weak = -80;
thrust = 80;
mean = 50;
weak = 25;
thrust = 75;
case "Whaley|UDT":
mean = 50;
weak = 16.4;
thrust = 77.8;
case "Whaley|SPT":
mean = 0;
weak = -13.85;
thrust = 10.05;
case "Zweig":
mean = 0.5;
weak = 0.4;
thrust = 0.61;
}

# -- plots

# -- signals
# breakaway signal
def breakaway = average(addIR,10) crosses above 1.97*average(decIR,10);
# desmond
# 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;

(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;
# 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);

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;

# -- thrust 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
if addI == 0 then 0 else
if decI == 0 then 0 else
if addV == 0 then 0 else
if decV == 0 then 0 else

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
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

# -- 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:
``````#
# 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
# 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 declineI;
def declineV;
switch (exchange) {
case NYSE:
declineI = close("\$DECN");
declineV = close("\$DVOL");
case NASDAQ:
declineI = close("\$DECN/Q");
declineV = close("\$DVOL/Q");
case SnP500:
declineI = close("\$DECLSP");
declineV = close("\$DVOLSP");
case Nasdaq100:
declineI = close("\$DECLND");
declineV = close("\$DVOLND");
case Russell2000:
declineI = close("\$DECLRL");
declineV = close("\$DVOLRL");
case Dow30:
declineI = close("\$DECLI");
declineV = close("\$DVOLI");
case AMEX:
declineI = close("\$DECA");
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 decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
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 decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def decVR = decV/totV;

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

def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
mean = 0;
weak = Double.NaN;
thrust = Double.NaN;
spaceU = 1;
spaceD = -1;
case "Desmond":
mean = 0;
weak = -80;
thrust = 80;
spaceU = 100;
spaceD = -100;
mean = 50;
weak = 25;
thrust = 75;
spaceU = 100;
spaceD = 0;
case "Whaley|UDT":
mean = 50;
weak = 16.4;
thrust = 77.8;
spaceU = 100;
spaceD = 0;
case "Whaley|SPT":
mean = 0;
weak = -13.85;
thrust = 10.05;
spaceU = 30;
spaceD = -30;
case "Zweig":
mean = 0.5;
weak = 0.4;
thrust = 0.61;
spaceU = 0.8;
spaceD = 0.2;
}

# -- plots

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);
# desmond
# 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;

(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);
(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;
# 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 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
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
if addI == 0 then 0 else
if decI == 0 then 0 else
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
if addV == 0 then 0 else
if decV == 0 then 0 else
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

# zweig labels
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

# -- 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:
``````#
# 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
# 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 declineI;
def declineV;
switch (exchange) {
case NYSE:
declineI = close("\$DECN");
declineV = close("\$DVOL");
case NASDAQ:
declineI = close("\$DECN/Q");
declineV = close("\$DVOL/Q");
case SnP500:
declineI = close("\$DECLSP");
declineV = close("\$DVOLSP");
case Nasdaq100:
declineI = close("\$DECLND");
declineV = close("\$DVOLND");
case Russell2000:
declineI = close("\$DECLRL");
declineV = close("\$DVOLRL");
case Dow30:
declineI = close("\$DECLI");
declineV = close("\$DVOLI");
case AMEX:
declineI = close("\$DECA");
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 decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
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 decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def decVR = decV/totV;

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

def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
mean = 0;
weak = Double.NaN;
thrust = Double.NaN;
spaceU = 1;
spaceD = -1;
case "Desmond":
mean = 0;
weak = -80;
thrust = 80;
spaceU = 100;
spaceD = -100;
mean = 50;
weak = 25;
thrust = 75;
spaceU = 100;
spaceD = 0;
case "Whaley|UDT":
mean = 50;
weak = 16.4;
thrust = 77.8;
spaceU = 100;
spaceD = 0;
case "Whaley|SPT":
mean = 0;
weak = -13.85;
thrust = 10.05;
spaceU = 30;
spaceD = -30;
case "Zweig":
mean = 0.5;
weak = 0.4;
thrust = 0.61;
spaceU = 0.8;
spaceD = 0.2;
}

# -- plots

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);
# desmond
# 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;

(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);
(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;
# 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 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
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
if addI == 0 then 0 else
if decI == 0 then 0 else
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
if addV == 0 then 0 else
if decV == 0 then 0 else
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

# zweig labels
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

# -- 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:
``````#
# 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
# 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 declineI;
def declineV;
switch (exchange) {
case NYSE:
declineI = close("\$DECN");
declineV = close("\$DVOL");
case NASDAQ:
declineI = close("\$DECN/Q");
declineV = close("\$DVOL/Q");
case SnP500:
declineI = close("\$DECLSP");
declineV = close("\$DVOLSP");
case Nasdaq100:
declineI = close("\$DECLND");
declineV = close("\$DVOLND");
case Russell2000:
declineI = close("\$DECLRL");
declineV = close("\$DVOLRL");
case Dow30:
declineI = close("\$DECLI");
declineV = close("\$DVOLI");
case AMEX:
declineI = close("\$DECA");
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 decI = if isnan(declineI) then GetValue(declineI, dCount) else declineI;
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 decV = if isnan(declineV) then GetValue(declineV, dVCount) else declineV;
def totV = addV + decV;
def decVR = decV/totV;

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

def mean;
def weak;
def thrust;
def spaceU;
def spaceD;
switch (thrustType){
case "Breakaway":
mean = 0;
weak = Double.NaN;
thrust = Double.NaN;
spaceU = 1;
spaceD = -1;
case "Desmond":
mean = 0;
weak = -80;
thrust = 80;
spaceU = 100;
spaceD = -100;
mean = 50;
weak = 25;
thrust = 75;
spaceU = 100;
spaceD = 0;
case "Whaley|UDT":
mean = 50;
weak = 16.4;
thrust = 77.8;
spaceU = 100;
spaceD = 0;
case "Whaley|SPT":
mean = 0;
weak = -13.85;
thrust = 10.05;
spaceU = 30;
spaceD = -30;
case "Zweig":
mean = 0.5;
weak = 0.4;
thrust = 0.61;
spaceU = 0.8;
spaceD = 0.2;
}

# -- plots

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);
# desmond
# 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;

(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);
(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;
# 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 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
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
if addI == 0 then 0 else
if decI == 0 then 0 else
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
if addV == 0 then 0 else
if decV == 0 then 0 else
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

# zweig labels
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

# -- 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
Thank you so much for this. Greatly appreciated!!! I hope to get up to speed with ThinkScript so I can contribute to this great forum!!!
I just saw a video of someone using the Fear and Greed indicator to find major turning points. It's very interesting and he shows how he created Python code to accomplish this.

Last edited by a moderator:
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.

Not the exact question you're looking for?

87k+ Posts
357 Online

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
• Exclusive indicators
• Proven strategies & setups
• Private Discord community
• Exclusive members-only content
• 1 full year of unlimited support

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?