Volume Confirmed Trend Dashboard For ThinkOrSwim

antwerks

Well-known member
VIP
VIP Enthusiast
Just a rewrite of a transcribed script from TV that in my opinion correctly attributes volume confirmation to the price chart- emphasizing whether the action is backed by the volume and participation.
Code:
########################################################
# Volume Confirmed Trend Dashboard
# Based on TASC 2024.08:
# Trend Thrust Indicator + Volume Price Confirmation
#
# Rewritten for ThinkorSwim as a lower confirmation panel
# Role:
# - Confirms whether trend has volume participation
# - Does NOT act as a standalone buy/sell system
# REWRITE AS A VALIDATOR NOT INDICATOR
# ANTWERKS
########################################################

declare lower;

#========================
# INPUTS
#========================
input adxThreshold = 20.0;
input adxStrongThreshold = 30.0;

input adxLength = 14;
input adxSmoothingLength = 14;

input ttiFastLength = 13;
input ttiSlowLength = 26;
input ttiSignalLength = 9;

input vpciFastLength = 5;
input vpciSlowLength = 25;
input vpciScale = 10.0;

input showLabels = yes;
input showClouds = yes;
input showVerticalEvents = yes;
input showHistogram = yes;
input showLines = yes;

#========================
# HELPERS
#========================
script SafeVWMA {
    input src = close;
    input len = 14;
    input vol = volume;

    def numerator = Average(src * vol, len);
    def denominator = Average(vol, len);

    plot result =
        if denominator != 0 then numerator / denominator
        else Average(src, len);
}

script TTI_Calc {
    input price = close;
    input fast = 13;
    input slow = 26;

    def fastMA = SafeVWMA(price, fast);
    def slowMA = SafeVWMA(price, slow);

    def ratio =
        if slowMA != 0 then fastMA / slowMA
        else 1;

    def vMult = Power(ratio, 2);
    def VEFA = fastMA * vMult;
    def VESA =
        if vMult != 0 then slowMA / vMult
        else slowMA;

    plot out = VEFA - VESA;
}

script VPCI_Calc {
    input longLen = 25;
    input shortLen = 5;

    def longVWMA = SafeVWMA(close, longLen);
    def longSMA = Average(close, longLen);

    def shortVWMA = SafeVWMA(close, shortLen);
    def shortSMA = Average(close, shortLen);

    def shortVolAvg = Average(volume, shortLen);
    def longVolAvg = Average(volume, longLen);

    def VPC = longVWMA - longSMA;

    def VPR =
        if shortSMA != 0 then shortVWMA / shortSMA
        else 1;

    def VM =
        if longVolAvg != 0 then shortVolAvg / longVolAvg
        else 1;

    plot out = VPC * VPR * VM;
}

#========================
# CORE CALCULATIONS
#========================
def diPlus = DMI(length = adxLength)."DI+";
def diMinus = DMI(length = adxLength)."DI-";

def dx =
    if diPlus + diMinus > 0 then
        100 * AbsValue(diPlus - diMinus) / (diPlus + diMinus)
    else 0;

def adx = WildersAverage(dx, adxSmoothingLength);

def tti = TTI_Calc(close, ttiFastLength, ttiSlowLength);
def ttiSignal = Average(tti, ttiSignalLength);
def ttiHist = tti - ttiSignal;

def vpci = VPCI_Calc(vpciSlowLength, vpciFastLength);
def vpciPlotValue = vpci * vpciScale;

#========================
# STATES
#========================
def trendBuilding =
    adx >= 15 and adx < adxThreshold;

def trendUsable =
    adx >= adxThreshold and adx < adxStrongThreshold;

def trendStrong =
    adx >= adxStrongThreshold;

def trendWeak =
    adx < 15;

def adxRising =
    adx > adx[1];

def adxFalling =
    adx < adx[1];

def ttiBull =
    tti > ttiSignal;

def ttiBear =
    tti < ttiSignal;

def ttiImproving =
    ttiHist > ttiHist[1];

def ttiFading =
    ttiHist < ttiHist[1];

def vpciBull =
    vpci > 0;

def vpciBear =
    vpci < 0;

def vpciImproving =
    vpci > vpci[1];

def vpciFading =
    vpci < vpci[1];

def bullVolumeConfirm =
    adx >= adxThreshold and
    ttiBull and
    vpciBull;

def bearVolumeConfirm =
    adx >= adxThreshold and
    ttiBear and
    vpciBear;

def bullEarlyConfirm =
    adx >= 15 and
    adx < adxThreshold and
    adxRising and
    ttiBull and
    vpciBull;

def bearEarlyConfirm =
    adx >= 15 and
    adx < adxThreshold and
    adxRising and
    ttiBear and
    vpciBear;

def bullDivergence =
    ttiBull and
    !vpciBull;

def bearDivergence =
    ttiBear and
    !vpciBear;

def bullWarning =
    ttiBull and
    vpciBull and
    (ttiFading or vpciFading or adxFalling);

def bearWarning =
    ttiBear and
    vpciBear and
    (ttiImproving or vpciImproving or adxFalling);

def neutral =
    !bullVolumeConfirm and
    !bearVolumeConfirm and
    !bullEarlyConfirm and
    !bearEarlyConfirm;

#========================
# CONFIRMATION STATE MACHINE
#========================
def startBullConfirm =
    bullVolumeConfirm and !bullVolumeConfirm[1];

def startBearConfirm =
    bearVolumeConfirm and !bearVolumeConfirm[1];

def bullFail =
    vpciBear or ttiBear;

def bearFail =
    vpciBull or ttiBull;

def inBullConfirm =
    CompoundValue(
        1,
        if startBullConfirm then 1
        else if bullFail then 0
        else inBullConfirm[1],
        0
    );

def inBearConfirm =
    CompoundValue(
        1,
        if startBearConfirm then 1
        else if bearFail then 0
        else inBearConfirm[1],
        0
    );

def bullConfirmEvent =
    startBullConfirm;

def bearConfirmEvent =
    startBearConfirm;

def bullFailEvent =
    inBullConfirm[1] and bullFail;

def bearFailEvent =
    inBearConfirm[1] and bearFail;

#========================
# PLOTS
#========================
plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.LIGHT_GRAY);
ZeroLine.SetStyle(Curve.SHORT_DASH);

plot ADXLine = if showLines then adx else Double.NaN;
ADXLine.SetDefaultColor(Color.MAGENTA);
ADXLine.SetLineWeight(2);

plot ADXThresholdLine = if showLines then adxThreshold else Double.NaN;
ADXThresholdLine.SetDefaultColor(Color.PLUM);
ADXThresholdLine.SetStyle(Curve.SHORT_DASH);

plot TTIHistPlot = if showHistogram then ttiHist else Double.NaN;
TTIHistPlot.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
TTIHistPlot.SetLineWeight(3);
TTIHistPlot.AssignValueColor(
    if ttiBull and ttiImproving then Color.GREEN
    else if ttiBull and ttiFading then Color.YELLOW
    else if ttiBear and ttiFading then Color.RED
    else if ttiBear and ttiImproving then Color.MAGENTA
    else Color.GRAY
);

plot TTIPlot = if showLines then tti else Double.NaN;
TTIPlot.SetDefaultColor(Color.ORANGE);
TTIPlot.SetLineWeight(2);

plot TTISignalPlot = if showLines then ttiSignal else Double.NaN;
TTISignalPlot.SetDefaultColor(Color.VIOLET);
TTISignalPlot.SetLineWeight(1);

plot VPCIPlot = if showLines then vpciPlotValue else Double.NaN;
VPCIPlot.SetPaintingStrategy(PaintingStrategy.LINE);
VPCIPlot.SetLineWeight(2);
VPCIPlot.AssignValueColor(
    if vpciBull and vpciImproving then Color.GREEN
    else if vpciBull and vpciFading then Color.YELLOW
    else if vpciBear and vpciFading then Color.RED
    else if vpciBear and vpciImproving then Color.MAGENTA
    else Color.GRAY
);

# Optional clouds
AddCloud(
    if showClouds then TTIPlot else Double.NaN,
    if showClouds then TTISignalPlot else Double.NaN,
    Color.DARK_GREEN,
    Color.DARK_RED
);

AddCloud(
    if showClouds then VPCIPlot else Double.NaN,
    if showClouds then ZeroLine else Double.NaN,
    Color.GREEN,
    Color.RED
);

#========================
# VERTICAL EVENT LINES
#========================
AddVerticalLine(
    showVerticalEvents and bullConfirmEvent,
    "VOL CONFIRM",
    Color.GREEN
);

AddVerticalLine(
    showVerticalEvents and bearConfirmEvent,
    "BEAR VOL CONFIRM",
    Color.RED
);

AddVerticalLine(
    showVerticalEvents and bullFailEvent,
    "VOL FAIL",
    Color.ORANGE
);

AddVerticalLine(
    showVerticalEvents and bearFailEvent,
    "BEAR FAIL",
    Color.ORANGE
);

#========================
# LABELS
#========================
AddLabel(
    showLabels,
    "ADX: " + Round(adx, 1) + " - " +
    if trendStrong then "STRONG"
    else if trendUsable then "USABLE"
    else if trendBuilding then "BUILDING"
    else "WEAK",
    if trendStrong then Color.GREEN
    else if trendUsable then Color.CYAN
    else if trendBuilding then Color.YELLOW
    else Color.GRAY
);

AddLabel(
    showLabels,
    "TTI: " +
    if ttiBull and ttiImproving then "BULL THRUST"
    else if ttiBull and ttiFading then "BULL FADING"
    else if ttiBear and ttiFading then "BEAR THRUST"
    else if ttiBear and ttiImproving then "BEAR FADING"
    else "NEUTRAL",
    if ttiBull and ttiImproving then Color.GREEN
    else if ttiBull and ttiFading then Color.YELLOW
    else if ttiBear and ttiFading then Color.RED
    else if ttiBear and ttiImproving then Color.MAGENTA
    else Color.GRAY
);

AddLabel(
    showLabels,
    "VPCI: " +
    if vpciBull and vpciImproving then "BULL CONFIRM"
    else if vpciBull and vpciFading then "BULL FADING"
    else if vpciBear and vpciFading then "BEAR CONFIRM"
    else if vpciBear and vpciImproving then "BEAR FADING"
    else "NEUTRAL",
    if vpciBull and vpciImproving then Color.GREEN
    else if vpciBull and vpciFading then Color.YELLOW
    else if vpciBear and vpciFading then Color.RED
    else if vpciBear and vpciImproving then Color.MAGENTA
    else Color.GRAY
);

AddLabel(
    showLabels,
    "VOL TREND: " +
    if bullVolumeConfirm then "BULL CONFIRMED"
    else if bearVolumeConfirm then "BEAR CONFIRMED"
    else if bullEarlyConfirm then "EARLY BULL CONFIRM"
    else if bearEarlyConfirm then "EARLY BEAR CONFIRM"
    else if bullDivergence then "BULL PRICE / NO VOLUME"
    else if bearDivergence then "BEAR PRICE / NO VOLUME"
    else "NEUTRAL / WAIT",
    if bullVolumeConfirm then Color.GREEN
    else if bearVolumeConfirm then Color.RED
    else if bullEarlyConfirm then Color.CYAN
    else if bearEarlyConfirm then Color.PINK
    else if bullDivergence or bearDivergence then Color.ORANGE
    else Color.GRAY
);

AddLabel(
    showLabels,
    "ACTION: " +
    if bullVolumeConfirm and !bullWarning then "CONFIRM LONG SETUPS"
    else if bullVolumeConfirm and bullWarning then "LONG CONFIRMED / FADING"
    else if bullEarlyConfirm then "EARLY LONG WATCH"
    else if bullDivergence then "WAIT - PRICE AHEAD OF VOLUME"
    else if bearVolumeConfirm and !bearWarning then "CONFIRM SHORT SETUPS"
    else if bearVolumeConfirm and bearWarning then "SHORT CONFIRMED / FADING"
    else if bearEarlyConfirm then "EARLY SHORT WATCH"
    else if bearDivergence then "WAIT - BEAR MOVE UNCONFIRMED"
    else "NO VOLUME EDGE",
    if bullVolumeConfirm and !bullWarning then Color.GREEN
    else if bullVolumeConfirm and bullWarning then Color.YELLOW
    else if bullEarlyConfirm then Color.CYAN
    else if bullDivergence then Color.ORANGE
    else if bearVolumeConfirm and !bearWarning then Color.RED
    else if bearVolumeConfirm and bearWarning then Color.MAGENTA
    else if bearEarlyConfirm then Color.PINK
    else if bearDivergence then Color.ORANGE
    else Color.GRAY
);
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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