Next Gen Volume Momentum Oscillator For ThinkOrSwim

justAnotherTrader

Active member
VIP
VIP Enthusiast
This is the second indicator in my next gen series.
(first one: https://usethinkscript.com/threads/eliteperformers-for-thinkorswim.20982/)
It does what we always want our indicators to do, it takes volume into consideration, adapts to market changes and gives labels for quick action.

šŸ“Š VWMO Momentum + Compression Zones Indicator – Explained for Traders
This indicator tracks where volume is flowing — into up days or down days — and combines that with volatility compression to identify high-probability setups before they move.

šŸ”¹ What It Measures:
  • VWMO stands for Volume-Weighted Momentum Oscillator. It looks at recent volume and checks if more of it is coming in on up days vs down days.
  • The line moves from 0 to 100:
    • Above 50 = volume favoring up moves (bullish bias)
    • Below 50 = volume favoring down moves (bearish bias)

šŸ”¹ What Makes It Unique:
  • It doesn’t just look at price — it tracks where the smart money is pushing volume.
  • It adapts based on volatility:
    • During a tight Bollinger Band squeeze, the indicator pulls the overbought/oversold zones closer to center, helping you catch early reversals before they run.

šŸ”¹ How to Use It:
  • VWMO > upper red dashed band = possibly overbought, but if the trend is up, it could mean strength continuation.
  • VWMO < lower green dashed band = possibly oversold, but if price is holding, could be absorption or reversal brewing.
  • Watch for "Squeeze Bias" labels – when price is compressed and volume starts leaning one way, the spring is coiling.
  • The dynamic labelsgive real-time context:
    • ā€œMomentum Upā€ = trending and strong.
    • ā€œOverbought Exhaustionā€ or ā€œCapitulation Riskā€ = fading moves.
    • ā€œAbsorption Zoneā€ = price holding while volume recovers (bullish potential).
    • ā€œEarly Bull Reversalā€ = first uptick from deep oversold with rising slope.
    • ā€œBear Divergenceā€ = volume rising but price stalling — risk of pullback.


This tool may help determine the direction bollinger band squeezes. When bands are compressed watch for volume to be on the top half of the oscillator for a potential breakout. I am not familiar with any tools that currently do a good job predicting squeeze directions

In the following picture I actually took this trade when the dashed lines converged and the volume line stayed steady above it. Note it is the first time ive traded with it
JSKzY0Q.png


Code:
declare lower;

input length = 14;
input percentileLookback = 63;       # VWMO percentile window
input volatilityLookback = 63;        # BBW percentile window
input bbLength = 20;
input bbNumDev = 2.0;

# --- VWMO Core Calculation ---
def upVol = if close > close[1] then volume else 0;
def downVol = if close < close[1] then volume else 0;
def upVolSum = Sum(upVol, length);
def downVolSum = Sum(downVol, length);
def totalVol = upVolSum + downVolSum;
def VWMO = if totalVol != 0 then 100 * upVolSum / totalVol else 50;

plot VWMO_Line = VWMO;
VWMO_Line.SetDefaultColor(Color.CYAN);

# --- Percentile Approximation for VWMO ---
def maxVWMO = Highest(VWMO, percentileLookback);
def minVWMO = Lowest(VWMO, percentileLookback);
def rangeVWMO = maxVWMO - minVWMO;

def OB_raw = minVWMO + rangeVWMO * 0.75;
def OS_raw = minVWMO + rangeVWMO * 0.25;

# --- Bollinger Band Width for Volatility ---
def bbBasis = Average(close, bbLength);
def bbDev = StDev(close, bbLength);
def bbUpper = bbBasis + bbNumDev * bbDev;
def bbLower = bbBasis - bbNumDev * bbDev;
def BBW = (bbUpper - bbLower) / bbBasis;

def maxBBW = Highest(BBW, volatilityLookback);
def minBBW = Lowest(BBW, volatilityLookback);
def rangeBBW = maxBBW - minBBW;
def BBWPercentile = if rangeBBW != 0 then (BBW - minBBW) / rangeBBW else 0;

# --- Compression Logic ---
def compressionFactor = if BBWPercentile < 0.25 then (0.25 - BBWPercentile) / 0.25 else 0;

def OB_dynamic = OB_raw - (OB_raw - 50) * compressionFactor;
def OS_dynamic = OS_raw + (50 - OS_raw) * compressionFactor;

plot OB_Band = OB_dynamic;
OB_Band.SetDefaultColor(Color.RED);
OB_Band.SetStyle(Curve.SHORT_DASH);

plot OS_Band = OS_dynamic;
OS_Band.SetDefaultColor(Color.GREEN);
OS_Band.SetStyle(Curve.SHORT_DASH);

# --- Label Logic with Smart Absorption and Trend Filters ---
def overbought = maxVWMO;
def oversold = minVWMO;
def priceSlope = LinearRegressionSlope(close, 5);
def absorptionCondition = VWMO < oversold and (close > close[1] or priceSlope > 0);

AddLabel(yes,
    if VWMO > overbought and priceSlope > 0 then
        "VWMO: " + Round(VWMO, 1) + " | Momentum Up"
    else if VWMO > overbought and priceSlope <= 0 then
        "VWMO: " + Round(VWMO, 1) + " | Overbought Exhaustion"
    else if VWMO < oversold and priceSlope < 0 then
        "VWMO: " + Round(VWMO, 1) + " | Capitulation Risk"
    else if absorptionCondition then
        "VWMO: " + Round(VWMO, 1) + " | Absorption Zone"
    else if VWMO > VWMO[1] and VWMO[1] < oversold and priceSlope >= 0 then
        "VWMO: " + Round(VWMO, 1) + " | Early Bull Reversal"
    else if VWMO < VWMO[1] and priceSlope > 0 then
        "VWMO: " + Round(VWMO, 1) + " | Bear Divergence"
    else if VWMO >= 45 and VWMO <= 55 then
        "VWMO: " + Round(VWMO, 1) + " | Neutral Volume"
    else
        "VWMO: " + Round(VWMO, 1),
    if VWMO > overbought and priceSlope > 0 then Color.GREEN
    else if VWMO > overbought and priceSlope <= 0 then Color.RED
    else if VWMO < oversold and priceSlope < 0 then Color.DARK_RED
    else if absorptionCondition then Color.LIGHT_GREEN
    else if VWMO > VWMO[1] and VWMO[1] < oversold and priceSlope >= 0 then Color.CYAN
    else if VWMO < VWMO[1] and priceSlope > 0 then Color.ORANGE
    else if VWMO >= 45 and VWMO <= 55 then Color.GRAY
    else Color.WHITE
);

def isSqueezing = compressionFactor > 0;
AddLabel(isSqueezing and VWMO > 55, "Squeeze Bias: Bullish", Color.GREEN);
AddLabel(isSqueezing and VWMO < 45, "Squeeze Bias: Bearish", Color.RED);
mod note:
classified with Buy Sell Volume Pressure Indicators
 
Last edited by a moderator:

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