Wave Projection Bands for ThinkOrSwim

chewie76

Well-known member
VIP
VIP Enthusiast
1784848108989.png


The Wave Projection Bands indicator transforms the traditional WaveTrend oscillator into a dynamic price overlay, projecting momentum and overbought/oversold zones directly onto the price chart.

Rather than forcing traders to constantly compare price action with a lower-panel oscillator, the indicator converts oscillator values into adaptive price bands surrounding a projected trend centerline. This creates a visual map showing where WaveTrend considers price to be statistically stretched or compressed in real time.

At its core is a smoothed adaptive centerline that represents the market's current equilibrium. Around this equilibrium, multiple dynamic bands expand and contract with changing market volatility using WaveTrend's channel calculations. As volatility increases, the bands naturally widen. During quieter conditions they contract, providing proportional price targets regardless of market regime.

The indicator divides price into progressive momentum zones ranging from mild extension to extreme overbought and oversold conditions. These zones help traders identify:
  • Areas where pullbacks become increasingly probable
  • Potential trend continuation zones
  • High-probability reversal regions
  • Relative momentum strength
  • Risk versus reward before entering trades
Unlike fixed ATR bands or Bollinger Bands, these levels are derived from WaveTrend momentum calculations, allowing them to reflect both volatility and underlying market momentum simultaneously.

Additional features include:
  • Adaptive projected centerline
  • Multi-level dynamic overbought/oversold bands
  • Volatility-sensitive zone shading
  • Automatic bar coloring by momentum zone
  • Forward projection of all bands for anticipating future support and resistance
The result is a clean upper-chart visualization that eliminates the need to monitor a separate oscillator while preserving the analytical power of WaveTrend. Traders can evaluate trend direction, momentum exhaustion, mean reversion opportunities, and breakout potential from a single integrated price display.

Code:
# Wave_Projection_Bands
# Inspired by the Wavetrend Oscillator
# Created by Chewie 7/23/26

declare upper;

input colorBars = yes;
input showBands = yes;
input showZoneShading = yes;
input showCenterLine = yes;
input period    = 14;          # "Period"
input ExtendBands = 10;        # "Extend Bands"
input bandChannelLen = 25;     # Separate, slower baseline used ONLY for band width
input bandWidthMultiplier = 3.0;  # Manual width dial - raise/lower to match your eye

input obLevel0 = 15; 
input obLevel1 = 30; 
input obLevel2 = 50; 
input obLevel3 = 60; 
input osLevel0 = -15;
input osLevel1 = -30;
input osLevel2 = -50;
input osLevel3 = -60;

def wtMASource = hlc3;
def price = close;
def na = Double.NaN;
def extBand = Max(ExtendBands, 5);

Script smma {
input src = close;
input length = 100;
    def sma = Average(src, length);
    def smma_value = CompoundValue(1, (smma_value[1] * (length - 1) + src) / length, sma);
    plot out = smma_value;
}

def smma = smma(price, period);

Script extendLine {
input src = close;
input extend = 30;
    def slop_i = Round(extend/10, 0);
    def slope  = (src - src[slop_i]) / slop_i;
    def ext; def y1; def slp;
    if !isNaN(close) {
        ext = 0;
        y1 = src;
        slp = slope;
    } else {
        ext = if ext[1] >= extend then Double.NaN else ext[1] + 1;
        y1 = y1[1];
        slp = slp[1];
    }
    plot line = y1 +(ext * slp);}

def l_m  = extendLine(smma, extBand);
def tfsrc = wtMASource;
def esaBand = ExpAverage(tfsrc, bandChannelLen);
def deBand = ExpAverage(AbsValue(tfsrc - esaBand), bandChannelLen);
def bandScale = 0.015 * deBand * bandWidthMultiplier;


#-- Project OB/OS levels into price
def bandOB0 = l_m + obLevel0 * bandScale;
def bandOB1 = l_m + obLevel1 * bandScale;
def bandOB2 = l_m + obLevel2 * bandScale;
def bandOB3 = l_m + obLevel3 * bandScale;
def bandOS0 = l_m + osLevel0 * bandScale;
def bandOS1 = l_m + osLevel1 * bandScale;
def bandOS2 = l_m + osLevel2 * bandScale;
def bandOS3 = l_m + osLevel3 * bandScale;

plot CenterLine = if showCenterLine then l_m else na;
CenterLine.assignValueColor(if Centerline > Centerline[1] then color.cyan else color.magenta);
Centerline.setlineWeight(4);
CenterLine.HideBubble();

def Volatility_Band1 = 20;

plot DYNAverage1 = Average(CenterLine, Volatility_Band1);
DYNAverage1.SetLineWeight(2);
DYNAverage1.SetDefaultColor(Color.cyan);
AddCloud(DYNAverage1, CenterLine, Color.RED, Color.GREEN);

def bandOB0a = extendLine(bandOB0, extBand);
def bandOB1a = extendLine(bandOB1, extBand);
def bandOB2a = extendLine(bandOB2, extBand);
def bandOB3a = extendLine(bandOB3, extBand);
def bandOS0a = extendLine(bandOS0, extBand);
def bandOS1a = extendLine(bandOS1, extBand);
def bandOS2a = extendLine(bandOS2, extBand);
def bandOS3a = extendLine(bandOS3, extBand);

plot OB0 = if showBands then bandOB0a else na;
plot OB1 = if showBands then bandOB1a else na;
plot OB2 = if showBands then bandOB2a else na;
plot OB3 = if showBands then bandOB3a else na;
plot OS0 = if showBands then bandOS0a else na;
plot OS1 = if showBands then bandOS1a else na;
plot OS2 = if showBands then bandOS2a else na;
plot OS3 = if showBands then bandOS3a else na;

OB0.SetDefaultColor(Color.RED);
OB1.SetDefaultColor(Color.RED);
OB2.SetDefaultColor(Color.MAGENTA);
OB3.SetDefaultColor(Color.MAGENTA);
OS0.SetDefaultColor(Color.GREEN);
OS1.SetDefaultColor(Color.GREEN);
OS2.SetDefaultColor(Color.CYAN);
OS3.SetDefaultColor(Color.CYAN);

OB0.HideTitle(); OB0.HideBubble();
OB1.HideTitle(); OB1.HideBubble();
OB2.HideTitle(); OB2.HideBubble();
OB3.HideTitle(); OB3.HideBubble();
OS0.HideTitle(); OS0.HideBubble();
OS1.HideTitle(); OS1.HideBubble();
OS2.HideTitle(); OS2.HideBubble();
OS3.HideTitle(); OS3.HideBubble();

AddCloud(if showZoneShading then OB0 else na, ob1, createcolor(120,0,0), createcolor(120,0,0));
AddCloud(if showZoneShading then OB1 else na, ob2, createcolor(200,0,0), createcolor(200,0,0));
AddCloud(if showZoneShading then OB2 else na, ob3, Color.MAGENTA, Color.MAGENTA);
AddCloud(os1, if showZoneShading then OS0 else na, createcolor(10,100,0), createcolor(10,100,0));
AddCloud(os2, if showZoneShading then OS1 else na, createcolor(50,150,0), createcolor(50,150,0));
AddCloud(os3, if showZoneShading then OS2 else na, Color.CYAN, Color.CYAN);


#-- Bar coloring by which projected zone price is currently sitting in
def barCol = if high > bandOB2 then 2 else
             if high > bandOB1 then 1 else
             if low < bandOS2 then -2 else
             if low < bandOS1 then -1 else 0;

AssignPriceColor(if !colorBars then Color.CURRENT else
                  if barCol == 2 then Color.MAGENTA else
                  if barCol == 1 then Color.RED else
                  if barCol == -1 then Color.GREEN else
                  if barCol == -2 then Color.CYAN else Color.light_GRAY);
                    
#-- END of CODE
 

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