Gravity Trend Levels [BOSWaves] for ThinkorSwim

chewie76

Well-known member
VIP
VIP Enthusiast
Gravity Trend Levels [BOSWaves]
Acceleration-Derived Gravity Modeling with Adaptive Cloud Trail and Fail Level Projection

Original code: https://www.tradingview.com/script/nCUyWa7D-Gravity-Trend-Levels-BOSWaves/

Overview

Gravity Trend Levels [BOSWaves] is a momentum acceleration-based trend system that models directional gravity through the normalized rate of change of an EMA-derived velocity measurement, where cloud thickness, trail distance, and trend state are continuously adapted based on whether gravitational pull is building, sustained, or decaying rather than through fixed volatility multipliers or static band thresholds.

1780454280457.png



Code:
# ============================================================
# Gravity Trend Levels [BOSWaves]
# Original Pine Script: https://www.tradingview.com/script/nCUyWa7D-Gravity-Trend-Levels-BOSWaves/
# Converted by Chewie 6/2/2026
# ============================================================

declare upper;

# ─────────────────────────────────────────────────────────────
# INPUTS
# ─────────────────────────────────────────────────────────────
input alert        = yes;
input len          = 14;    # Trend Length — higher = smoother, fewer flips
input gravLen      = 19;    # Gravity Lookback — lower = more reactive
input decayRate    = 0.96;  # Gravity Decay — higher = gravity lingers longer
input madLen       = 24;    # MAD Length — higher = smoother trail
input trailMin     = 1.0;   # Trail Min (Strong Pull)
input trailMax     = 1.0;   # Trail Max (Weak Pull)
input showCloud    = yes;   # Show Gravity Cloud
input paintBars    = yes;   # Color Bars
input showSignals  = yes;   # Show Buy/Sell Signals
input showLevels   = yes;   # Show Gravity Fail Levels
input levelLen     = 50;    # Level Projection Length (bars forward)
input showDots     = yes;   # Retest Diamonds
input dotCooldown  = 12;    # Retest Cooldown (min bars between diamonds)
input signalBuffer = 10;    # Signal Buffer Period (bars after flip before diamonds)

# ─────────────────────────────────────────────────────────────
# COLORS
# ─────────────────────────────────────────────────────────────
DefineGlobalColor("Bull",      Color.GREEN);
DefineGlobalColor("Bear",      Color.RED);

# ─────────────────────────────────────────────────────────────
# CORE — Basis & Volatility (MAD)
# ─────────────────────────────────────────────────────────────
def basis = ExpAverage(close, len);
def meanC  = Average(close, madLen);
def mad    = Average(AbsValue(close - meanC), madLen);

# ─────────────────────────────────────────────────────────────
# GRAVITY DETECTION
# ─────────────────────────────────────────────────────────────
def velocity  = basis - basis[gravLen];
def accelRaw  = velocity - velocity[1];
def normAccel = if mad > 0 then AbsValue(accelRaw) / mad else 0.0;

def gravity;
if normAccel > 0.01 {
    gravity = Min(normAccel * 8.0, 2.0);
} else {
    gravity = gravity[1] * decayRate;
}

def pull = Min(gravity / 1.5, 1.0);

# ─────────────────────────────────────────────────────────────
# ADAPTIVE TRAIL BANDS
# ─────────────────────────────────────────────────────────────
def trailMult = trailMax - (trailMax - trailMin) * pull;
def upper_band = basis + mad * trailMult;
def lower_band = basis - mad * trailMult;

# ─────────────────────────────────────────────────────────────
# SIGNAL / TREND LOGIC
# ─────────────────────────────────────────────────────────────
def longCond  = close crosses above upper_band;
def shortCond = close crosses below lower_band;

def lastSignal;
if longCond {
    lastSignal = 1;
} else if shortCond {
    lastSignal = -1;
} else {
    lastSignal = lastSignal[1];
}

def switchUp   = lastSignal == 1  and lastSignal[1] == -1;
def switchDown = lastSignal == -1 and lastSignal[1] == 1;

def lastSignalBar;
if switchUp or switchDown {
    lastSignalBar = BarNumber();
} else {
    lastSignalBar = lastSignalBar[1];
}

# ─────────────────────────────────────────────────────────────
# GRAVITY CLOUD
# ─────────────────────────────────────────────────────────────
def cloudThick = mad * (0.3 + 0.5 * pull);
def cloudOuter = if lastSignal == 1 then lower_band else upper_band;
def cloudInner = if lastSignal == 1 then lower_band + cloudThick else upper_band - cloudThick;

def cloudOuterVis = ExpAverage(cloudOuter, 5);
def cloudInnerVis = ExpAverage(cloudInner, 5);

plot CloudOuterPlot = if showCloud then cloudOuterVis else Double.NaN;
CloudOuterPlot.SetLineWeight(2);
CloudOuterPlot.AssignValueColor(if lastSignal == 1 then GlobalColor("Bull") else GlobalColor("Bear"));
CloudOuterPlot.SetPaintingStrategy(PaintingStrategy.LINE);

plot CloudInnerPlot = if showCloud then cloudInnerVis else Double.NaN;
CloudInnerPlot.SetLineWeight(1);
CloudInnerPlot.AssignValueColor(if lastSignal == 1
    then CreateColor(0, 200, 0)
    else CreateColor(200, 0, 0));
CloudInnerPlot.SetPaintingStrategy(PaintingStrategy.LINE);

# Cloud fill — AddCloud draws between two named plots
AddCloud(CloudOuterPlot, CloudInnerPlot,
    CreateColor(100, 0, 0),
    CreateColor(0, 100, 0));

# ─────────────────────────────────────────────────────────────
# BAR COLORING
# ─────────────────────────────────────────────────────────────
AssignPriceColor(
    if !paintBars then Color.CURRENT
    else if lastSignal == 1 then GlobalColor("Bull")
    else GlobalColor("Bear")
);

# ─────────────────────────────────────────────────────────────
# BUY / SELL SIGNALS
# ─────────────────────────────────────────────────────────────
plot BuySignal = if showSignals and switchUp then low - mad * 1.5 else Double.NaN;
BuySignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BuySignal.SetDefaultColor(GlobalColor("Bull"));
BuySignal.SetLineWeight(3);
BuySignal.Hide();   # we use AddChartBubble below for labeling

AddChartBubble(showSignals and switchUp,
    low - mad * 1.5,
    "B",
    GlobalColor("Bull"),
    no);

AddChartBubble(showSignals and switchDown,
    high + mad * 1.5,
    "S",
    GlobalColor("Bear"),
    yes);

# ─────────────────────────────────────────────────────────────
# GRAVITY FAIL LEVELS 
# ─────────────────────────────────────────────────────────────
# Bull flip level — project from the low of the switchUp bar
def flipBullPrice  = if switchUp   then low  else Double.NaN;
def flipBearPrice  = if switchDown then high else Double.NaN;

# Carry the level forward for levelLen bars
def barsAfterBullFlip;
if switchUp {
    barsAfterBullFlip = 0;
} else if barsAfterBullFlip[1] < levelLen {
    barsAfterBullFlip = barsAfterBullFlip[1] + 1;
} else {
    barsAfterBullFlip = levelLen + 1;
}

def carriedBullLevel;
if switchUp {
    carriedBullLevel = low;
} else if barsAfterBullFlip <= levelLen {
    carriedBullLevel = carriedBullLevel[1];
} else {
    carriedBullLevel = Double.NaN;
}

def barsAfterBearFlip;
if switchDown {
    barsAfterBearFlip = 0;
} else if barsAfterBearFlip[1] < levelLen {
    barsAfterBearFlip = barsAfterBearFlip[1] + 1;
} else {
    barsAfterBearFlip = levelLen + 1;
}

def carriedBearLevel;
if switchDown {
    carriedBearLevel = high;
} else if barsAfterBearFlip <= levelLen {
    carriedBearLevel = carriedBearLevel[1];
} else {
    carriedBearLevel = Double.NaN;
}

plot BullLevel = if showLevels then carriedBullLevel else Double.NaN;
BullLevel.SetDefaultColor(CreateColor(0, 200, 0));
BullLevel.SetPaintingStrategy(PaintingStrategy.DASHES);
BullLevel.SetLineWeight(2);
BullLevel.HideBubble();

plot BearLevel = if showLevels then carriedBearLevel else Double.NaN;
BearLevel.SetDefaultColor(CreateColor(200, 0, 0));
BearLevel.SetPaintingStrategy(PaintingStrategy.DASHES);
BearLevel.SetLineWeight(2);
BearLevel.HideBubble();

# ─────────────────────────────────────────────────────────────
# RETEST DIAMONDS
# ─────────────────────────────────────────────────────────────
def farEnough = (BarNumber() - lastSignalBar) >= signalBuffer;

def bullRetest = showDots and lastSignal == 1  and low  < cloudInnerVis and farEnough;
def bearRetest = showDots and lastSignal == -1 and high > cloudInnerVis and farEnough;

# Cooldown tracking
def lastBullDotBar;
if bullRetest and (IsNaN(lastBullDotBar[1]) or (BarNumber() - lastBullDotBar[1]) >= dotCooldown) {
    lastBullDotBar = BarNumber();
} else {
    lastBullDotBar = lastBullDotBar[1];
}

def lastBearDotBar;
if bearRetest and (IsNaN(lastBearDotBar[1]) or (BarNumber() - lastBearDotBar[1]) >= dotCooldown) {
    lastBearDotBar = BarNumber();
} else {
    lastBearDotBar = lastBearDotBar[1];
}

def bullDotOk = bullRetest and lastBullDotBar == BarNumber();
def bearDotOk = bearRetest and lastBearDotBar == BarNumber();

plot BullDot = if bullDotOk then low  else Double.NaN;
BullDot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
BullDot.SetDefaultColor(GlobalColor("Bull"));
BullDot.SetLineWeight(3);

plot BearDot = if bearDotOk then high else Double.NaN;
BearDot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
BearDot.SetDefaultColor(GlobalColor("Bear"));
BearDot.SetLineWeight(3);

# ─────────────────────────────────────────────────────────────
# ALERTS
# ─────────────────────────────────────────────────────────────
Alert(alert and switchUp,   "Gravity Long — " + GetSymbol(),  Alert.BAR, Sound.Ring);
Alert(alert and switchDown, "Gravity Short — " + GetSymbol(), Alert.BAR, Sound.Ring);
Alert(alert and bullDotOk or bearDotOk, "Gravity Retest — " + GetSymbol(), Alert.BAR, Sound.Ding);
 

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