Execution Context Engine For ThinkOrSwim

antwerks

Well-known member
VIP
VIP Enthusiast
This indicator combines price plot, 9 EMA plot, 21 EMA plot and volume plot. The reason that the interaction of these particular individual indicators is relevant and important is because their interaction captures the relationship between price structure, trend persistence, and volume participation, allowing us to distinguish between continuation, exhaustion, and reversal conditions. Individually they show signals, but together they tell you whether a move is worth trading.

0iC10yO.png

Here is how to translate the visual into actionable:

Who is in control + how aggressive they are
HIGH-VALUE SCENARIOS

1. LOW VOL PULLBACK (BULLISH CONTINUATION)
Condition:
  • Price ↓ (pulling back)
  • EMA 9 ↑
  • EMA 21 ↑
  • Volume ↓
Interpretation:
👉 Sellers are weak
👉 No urgency to exit
👉 Trend still intact
Meaning: Pullback → likely bounce
Trade Logic:
  • Buy dips into 9 / 21
  • Best version = shallow pullback
2. LOW VOL CONSOLIDATION AT HIGHS (STRONG BULLISH)
Condition:
  • Price flat / slight ↓ near highs
  • EMA 9 ↑
  • EMA 21 ↑
  • Volume ↓
Interpretation:
👉 Market is pausing, not selling
👉 No distribution
Meaning: Continuation setup (A+)

3. ABSORPTION (HIDDEN BUYING)
Condition:
  • Price ↓ or flat
  • Volume ↑
  • BUT price holds structure (no breakdown)
Interpretation:
👉 Sellers hitting bids
👉 Buyers absorbing
Meaning: Fuel for next move up

4. HEALTHY TREND (CONTROLLED MOVE)
Condition:
  • Price ↑
  • EMA 9 ↑
  • EMA 21 ↑
  • Volume steady (not spiking)
Interpretation:
👉 Balanced buying
👉 No exhaustion
Meaning: Trend continuation

5. EXHAUSTION (TOP RISK)
Condition:
  • Price ↑ fast
  • Volume ↑↑ (spike)
  • Price stalls or wicks
Interpretation:
👉 Buyers getting trapped
👉 Late entries
Meaning: Pullback likely

6. HIGH VOL SELLING (BEARISH)
Condition:
  • Price ↓
  • Volume ↑
  • Breaks prior low
Interpretation:
👉 Real selling pressure
👉 No absorption
Meaning: Avoid longs / short bias

7. WEAK PULLBACK (TREND AT RISK)
Condition:
  • Price ↓
  • EMA 9 ↓
  • EMA 21 still ↑ (lagging)
  • Volume neutral / rising
Interpretation:
👉 Short-term trend breaking
Meaning: Transition phase

8. TREND BREAKDOWN
Condition:
  • Price ↓ below 21 EMA
  • EMA 9 ↓
  • EMA 21 flattening or ↓
  • Volume ↑
Interpretation: Trend shift

Meaning: Bull trend likely over

9. NO EDGE / CHOP
Condition:
  • Price crossing 9 & 21 constantly
  • EMA 9 flat
  • EMA 21 flat
  • Volume low
Interpretation:
👉 No control
Meaning: Stay out

AN EXAMPLE
“If price drops and 9 and 21 drop and volume drops…”
That actually becomes: ⚠️ WEAKNESS, NOT BULLISH
  • Price ↓
  • EMA 9 ↓
  • EMA 21 ↓
  • Volume ↓
👉 This = lack of buyers AND sellers
Meaning: Drift / downtrend — not a bounce setup

SIMPLE DECISION FRAMEWORK
Ask 3 questions:
1. WHERE IS PRICE?
  • Above 9 = strong
  • Between 9 & 21 = pullback
  • Below 21 = danger
2. WHAT ARE EMAs DOING?
  • Both up = trend
  • 9 down, 21 up = pullback
  • Both down = bearish
3. WHAT IS VOLUME DOING?
  • Falling = weak move
  • Rising = strong move
  • Spike = exhaustion or break
COMBINED QUICK READ
SetupMeaning
Price ↓ + Vol ↓ + EMAs ↑BUY DIP
Price ↓ + Vol ↑SELL PRESSURE
Price flat + Vol ↓CONSOLIDATION
Price ↑ + Vol ↑ spikeEXHAUSTION
Price ↓ + EMAs ↓TREND DOWN

KEY INSIGHT (MOST IMPORTANT)
👉 Volume tells you conviction
👉 EMA tells you structure
👉 Price tells you timing

Code:
# =========================
# EXECUTION CONTECT ENGINE
# NORMALIZED EMA + VOLUME PANEL
# antwerks 04/09/2026
# =========================

declare lower;

input normLength = 50;

# =========================
# PRICE + EMA
# =========================
def price = close;
def ema9 = ExpAverage(close, 9);
def ema21 = ExpAverage(close, 21);

# =========================
# NORMALIZATION RANGE
# =========================
def highestP = Highest(price, normLength);
def lowestP = Lowest(price, normLength);
def range = highestP - lowestP;

def normPrice = (price - lowestP) / range;
def normEMA9 = (ema9 - lowestP) / range;
def normEMA21 = (ema21 - lowestP) / range;

# =========================
# PLOTS (NOW VISIBLE)
# =========================
plot PriceNorm = normPrice;
PriceNorm.SetDefaultColor(Color.MAGENTA);
PriceNorm.SetLineWeight(2);

plot EMA9Norm = normEMA9;
EMA9Norm.SetDefaultColor(Color.CYAN);
EMA9Norm.SetLineWeight(2);

plot EMA21Norm = normEMA21;
EMA21Norm.SetDefaultColor(Color.YELLOW);
EMA21Norm.SetLineWeight(2);

# =========================
# VOLUME NORMALIZATION
# =========================
def vol = volume;
def volHigh = Highest(volume, normLength);

def normVol = vol / volHigh;

plot VolumeNorm = normVol;
VolumeNorm.SetDefaultColor(Color.GRAY);
VolumeNorm.SetLineWeight(1);

# =========================
# CONDITIONS
# =========================
def lowVol = normVol < Average(normVol, 20);
def pullback = normPrice < normEMA9;
def volAvg = Average(volume, 20);

def lowVolumePullback =
    close < close[1] and
    volume < Average(volume, 20) and
    close > ExpAverage(close, 21);  # <-- trend filter

def highVolumeSell =
    close < close[1] and
    volume > Average(volume, 20) and
    close < low[1];   # <-- KEY ADDITION

def trueSellPressure =
    highVolumeSell and
    (high - low) > Average(TrueRange(high, close, low), 14);

def nearHigh =
    close >= Highest(close, 20) * 0.98;

def momentumRising =
    ExpAverage(close, 5) > ExpAverage(close, 5)[1];

def deeperPullback =
    close < ExpAverage(close, 9) and
    close < ExpAverage(close, 21);

# =========================
# SMART FLOW LABEL (FINAL)
# =========================

def avgVol = Average(volume, 20);

def absorption =
    close < close[1] and
    volume > avgVol and
    close >= low[1];

AddLabel(yes,

    # 🔵 HIGHEST PRIORITY: ABSORPTION
    if absorption and nearHigh then "A+ ABSORPTION (BULLISH)"
    else if absorption then "ABSORPTION (BUYERS ACTIVE)"

    # 🟢 CONTINUATION
    else if lowVolumePullback and deeperPullback then "WEAK PULLBACK (WATCH)"
else if lowVolumePullback then "B+ PULLBACK: DIGESTION"

    # 🔴 TRUE SELLING
    else if trueSellPressure then "STRONG SELLING (SHORT)"
else if highVolumeSell then "WEAK SELLING"

    # ⚪ DEFAULT
    else "NO EDGE",

    # COLORS
    if absorption then Color.CYAN
    else if lowVolumePullback then Color.GREEN
    else if highVolumeSell then Color.RED
    else Color.GRAY
);

# =========================
# KEY LINE LABELS (COLOR MATCHED)
# =========================

AddLabel(yes,
    "PRICE: " + Round(close, 2),
    Color.MAGENTA
);

AddLabel(yes,
    "EMA 9: " + Round(ExpAverage(close, 9), 2),
    Color.CYAN
);

AddLabel(yes,
    "EMA 21: " + Round(ExpAverage(close, 21), 2),
    Color.GREEN
);

AddLabel(yes,
    "VOL: " + Round(volume, 0),
    Color.GRAY
);

 
Last edited by a moderator:
this is a mod on your first post.

looking at a bunch of lines, doesn't mean anything to me.
i like to see some kind of signal.
i added clouds to show up for absorption , lowVolumePullback , highVolumesell .

feel free to tweak it to include more of your rules.

Code:
#EXECUTION_CONTECT_ENGINE

#https://usethinkscript.com/threads/execution-context-engine.22333/
#Indicators Custom 
#Execution Context Engine
#antwerks  4/9

#This indicator combines price plot, 9 EMA plot, 21 EMA plot and volume plot. The reason that the interaction of these particular individual indicators is relevant and important is because their interaction captures the relationship between price structure, trend persistence, and volume participation, allowing us to distinguish between continuation, exhaustion, and reversal conditions. Individually they show signals, but together they tell you whether a move is worth trading.

#Here is how to translate the visual into actionable:

#Who is in control + how aggressive they are
#HIGH-VALUE SCENARIOS

#1. LOW VOL PULLBACK (BULLISH CONTINUATION)

#Condition:
#Price ↓ (pulling back)
#EMA 9 ↑
#EMA 21 ↑
#Volume ↓
#Interpretation:

#👉 Sellers are weak
#👉 No urgency to exit
#👉 Trend still intact

#Meaning: Pullback → likely bounce

#Trade Logic:
#Buy dips into 9 / 21
#Best version = shallow pullback


#2. LOW VOL CONSOLIDATION AT HIGHS (STRONG BULLISH)
#Condition:
#Price flat / slight ↓ near highs
#EMA 9 ↑
#EMA 21 ↑
#Volume ↓
#Interpretation:

#👉 Market is pausing, not selling
#👉 No distribution

#Meaning: Continuation setup (A+)


#3. ABSORPTION (HIDDEN BUYING)
#Condition:
#Price ↓ or flat
#Volume ↑
#BUT price holds structure (no breakdown)
#Interpretation:

#👉 Sellers hitting bids
#👉 Buyers absorbing

#Meaning: Fuel for next move up


#4. HEALTHY TREND (CONTROLLED MOVE)
#Condition:
#Price ↑
#EMA 9 ↑
#EMA 21 ↑
#Volume steady (not spiking)
#Interpretation:

#👉 Balanced buying
#👉 No exhaustion

#Meaning: Trend continuation


#5. EXHAUSTION (TOP RISK)
#Condition:
#Price ↑ fast
#Volume ↑↑ (spike)
#Price stalls or wicks
#Interpretation:

#👉 Buyers getting trapped
#👉 Late entries

#Meaning: Pullback likely


#6. HIGH VOL SELLING (BEARISH)
#Condition:
#Price ↓
#Volume ↑
#Breaks prior low
#Interpretation:

#👉 Real selling pressure
#👉 No absorption

#Meaning: Avoid longs / short bias


#7. WEAK PULLBACK (TREND AT RISK)
#Condition:
#Price ↓
#EMA 9 ↓
#EMA 21 still ↑ (lagging)
#Volume neutral / rising
#Interpretation:

#👉 Short-term trend breaking

#Meaning: Transition phase


#8. TREND BREAKDOWN
#Condition:
#Price ↓ below 21 EMA
#EMA 9 ↓
#EMA 21 flattening or ↓
#Volume ↑
#Interpretation: Trend shift

#Meaning: Bull trend likely over


#9. NO EDGE / CHOP
#Condition:
#Price crossing 9 & 21 constantly
#EMA 9 flat
#EMA 21 flat
#Volume low
#Interpretation:

#👉 No control

#Meaning: Stay out

#AN EXAMPLE

#“If price drops and 9 and 21 drop and volume drops…”

#That actually becomes: ⚠️ WEAKNESS, NOT BULLISH
#Price ↓
#EMA 9 ↓
#EMA 21 ↓
#Volume ↓
#👉 This = lack of buyers AND sellers

#Meaning: Drift / downtrend — not a bounce setup


#SIMPLE DECISION FRAMEWORK

#Ask 3 questions:

#1. WHERE IS PRICE?
#Above 9 = strong
#Between 9 & 21 = pullback
#Below 21 = danger
#2. WHAT ARE EMAs DOING?
#Both up = trend
#9 down, 21 up = pullback
#Both down = bearish
#3. WHAT IS VOLUME DOING?
#Falling = weak move
#Rising = strong move
#Spike = exhaustion or break
#COMBINED QUICK READ

#Setup    Meaning
#Price ↓ + Vol ↓ + EMAs ↑    BUY DIP
#Price ↓ + Vol ↑    SELL PRESSURE
#Price flat + Vol ↓    CONSOLIDATION
#Price ↑ + Vol ↑ spike    EXHAUSTION
#Price ↓ + EMAs ↓    TREND DOWN

#KEY INSIGHT (MOST IMPORTANT)

#👉 Volume tells you conviction
#👉 EMA tells you structure
#👉 Price tells you timing



# =========================
# EXECUTION CONTECT ENGINE
# NORMALIZED EMA + VOLUME PANEL
# antwerks 04/09/2026
# =========================

declare lower;

input normLength = 50;

# =========================
# PRICE + EMA
# =========================
def price = close;
input avg1_type = AverageType.exponential;
input avg1_length = 9;
def avg1 = MovingAverage(avg1_type, price, avg1_length );

input avg2_type = AverageType.exponential;
input avg2_length = 21;
def avg2 = MovingAverage(avg2_type, price, avg2_length );



# =========================
# NORMALIZATION RANGE
# =========================
def highestP = Highest(price, normLength);
def lowestP = Lowest(price, normLength);
def range = highestP - lowestP;

def normPrice = (price - lowestP) / range;
def normEMA9 = (avg1 - lowestP) / range;
def normEMA21 = (avg2 - lowestP) / range;

# =========================
# PLOTS (NOW VISIBLE)
# =========================
plot PriceNorm = normPrice;
PriceNorm.SetDefaultColor(Color.MAGENTA);
PriceNorm.SetLineWeight(2);

plot EMA9Norm = normEMA9;
EMA9Norm.SetDefaultColor(Color.CYAN);
EMA9Norm.SetLineWeight(2);

plot EMA21Norm = normEMA21;
EMA21Norm.SetDefaultColor(Color.YELLOW);
EMA21Norm.SetLineWeight(2);


# =========================
# VOLUME NORMALIZATION
# =========================
def vol = volume;
def volHigh = Highest(volume, normLength);

def normVol = vol / volHigh;

plot VolumeNorm = normVol;
VolumeNorm.SetDefaultColor(Color.light_GRAY);
VolumeNorm.SetLineWeight(1);

# =========================
# CONDITIONS
# =========================
def lowVol = normVol < Average(normVol, 20);
def pullback = normPrice < normEMA9;
def volAvg = Average(volume, 20);

def lowVolumePullback =
    close < close[1] and
    volume < Average(volume, 20) and
    close > avg2;  # <-- trend filter

def highVolumeSell =
    close < close[1] and
    volume > Average(volume, 20) and
    close < low[1];   # <-- KEY ADDITION

def trueSellPressure = highVolumeSell and (high - low) > Average(TrueRange(high, close, low), 14);

def nearHigh = close >= (Highest(close, 20) * 0.98);

def momentumRising = ExpAverage(close, 5) > ExpAverage(close, 5)[1];

def deeperPullback = (close < avg1 and close < avg2);


# =========================
# SMART FLOW LABEL (FINAL)
# =========================

def avgVol = Average(volume, 20);

def absorption =
    close < close[1] and
    volume > avgVol and
    close >= low[1];

AddLabel(yes,
# 🔵 HIGHEST PRIORITY: ABSORPTION
  (if absorption and nearHigh then "A+ ABSORPTION (BULLISH)"
  else if absorption then "ABSORPTION (BUYERS ACTIVE)"

# 🟢 CONTINUATION
  else if lowVolumePullback and deeperPullback then "WEAK PULLBACK (WATCH)"
  else if lowVolumePullback then "B+ PULLBACK: DIGESTION"

# 🔴 TRUE SELLING
  else if trueSellPressure then "STRONG SELLING (SHORT)"
  else if highVolumeSell then "WEAK SELLING"

# ⚪ DEFAULT
  else "NO EDGE"),

# COLORS
  (if absorption then Color.CYAN
   else if lowVolumePullback then Color.GREEN
   else if highVolumeSell then Color.RED
   else Color.GRAY));


# =========================
# KEY LINE LABELS (COLOR MATCHED)
# =========================



addlabel(1, " ", color.black);
addlabel(1, "PriceNorm", EMA9Norm.TakeValueColor() );

addlabel(1,
(if avg2_type == AverageType.Simple then "SMA"
 else if avg2_type == AverageType.exponential then "EMA"
 else if avg2_type == AverageType.hull then "HULL"
 else if avg2_type == AverageType.weighted then "WT"
 else if avg2_type == AverageType.wilders then "WILD"
 else "---") + avg2_length
, EMA21Norm.TakeValueColor() );
#, color.cyan);


addlabel(1,
(if avg2_type == AverageType.Simple then "SMA"
 else if avg2_type == AverageType.exponential then "EMA"
 else if avg2_type == AverageType.hull then "HULL"
 else if avg2_type == AverageType.weighted then "WT"
 else if avg2_type == AverageType.wilders then "WILD"
 else "---") + avg2_length
, PriceNorm.TakeValueColor() );

addlabel(1, " ", color.black);




AddLabel(0,
    "PRICE: " + Round(close, 2),
    Color.MAGENTA);

AddLabel(yes,
#    "EMA 9: " + Round(ExpAverage(close, 9), 2),
    "EMA 9: " + Round(avg1, 2),
    Color.CYAN );

AddLabel(yes,
#    "EMA 21: " + Round(ExpAverage(close, 21), 2),
    "EMA 21: " + Round(avg2, 2),
    Color.GREEN );

AddLabel(yes,
    "VOL: " + Round(volume, 0),
    Color.light_GRAY);


def pos = Double.POSITIVE_INFINITY;
def neg = Double.NEGATIVE_INFINITY;
def na = double.nan;


def ab = if absorption then pos else na;
addcloud(ab, neg, color.cyan);

def lowv = if lowVolumePullback then pos else na;
addcloud(lowv, neg, color.green);

def hiv = if highVolumesell then pos else na;
addcloud(hiv, neg, color.red);


#def zz = if (!absorption and !lowVolumePullback and !highVolumeSell) then pos else na;
#addcloud(zz, neg, color.gray);

#
 
this is a mod on your first post.

looking at a bunch of lines, doesn't mean anything to me.
i like to see some kind of signal.
i added clouds to show up for absorption , lowVolumePullback , highVolumesell .

feel free to tweak it to include more of your rules.

Code:
#EXECUTION_CONTECT_ENGINE

#https://usethinkscript.com/threads/execution-context-engine.22333/
#Indicators Custom
#Execution Context Engine
#antwerks  4/9

#This indicator combines price plot, 9 EMA plot, 21 EMA plot and volume plot. The reason that the interaction of these particular individual indicators is relevant and important is because their interaction captures the relationship between price structure, trend persistence, and volume participation, allowing us to distinguish between continuation, exhaustion, and reversal conditions. Individually they show signals, but together they tell you whether a move is worth trading.

#Here is how to translate the visual into actionable:

#Who is in control + how aggressive they are
#HIGH-VALUE SCENARIOS

#1. LOW VOL PULLBACK (BULLISH CONTINUATION)

#Condition:
#Price ↓ (pulling back)
#EMA 9 ↑
#EMA 21 ↑
#Volume ↓
#Interpretation:

#👉 Sellers are weak
#👉 No urgency to exit
#👉 Trend still intact

#Meaning: Pullback → likely bounce

#Trade Logic:
#Buy dips into 9 / 21
#Best version = shallow pullback


#2. LOW VOL CONSOLIDATION AT HIGHS (STRONG BULLISH)
#Condition:
#Price flat / slight ↓ near highs
#EMA 9 ↑
#EMA 21 ↑
#Volume ↓
#Interpretation:

#👉 Market is pausing, not selling
#👉 No distribution

#Meaning: Continuation setup (A+)


#3. ABSORPTION (HIDDEN BUYING)
#Condition:
#Price ↓ or flat
#Volume ↑
#BUT price holds structure (no breakdown)
#Interpretation:

#👉 Sellers hitting bids
#👉 Buyers absorbing

#Meaning: Fuel for next move up


#4. HEALTHY TREND (CONTROLLED MOVE)
#Condition:
#Price ↑
#EMA 9 ↑
#EMA 21 ↑
#Volume steady (not spiking)
#Interpretation:

#👉 Balanced buying
#👉 No exhaustion

#Meaning: Trend continuation


#5. EXHAUSTION (TOP RISK)
#Condition:
#Price ↑ fast
#Volume ↑↑ (spike)
#Price stalls or wicks
#Interpretation:

#👉 Buyers getting trapped
#👉 Late entries

#Meaning: Pullback likely


#6. HIGH VOL SELLING (BEARISH)
#Condition:
#Price ↓
#Volume ↑
#Breaks prior low
#Interpretation:

#👉 Real selling pressure
#👉 No absorption

#Meaning: Avoid longs / short bias


#7. WEAK PULLBACK (TREND AT RISK)
#Condition:
#Price ↓
#EMA 9 ↓
#EMA 21 still ↑ (lagging)
#Volume neutral / rising
#Interpretation:

#👉 Short-term trend breaking

#Meaning: Transition phase


#8. TREND BREAKDOWN
#Condition:
#Price ↓ below 21 EMA
#EMA 9 ↓
#EMA 21 flattening or ↓
#Volume ↑
#Interpretation: Trend shift

#Meaning: Bull trend likely over


#9. NO EDGE / CHOP
#Condition:
#Price crossing 9 & 21 constantly
#EMA 9 flat
#EMA 21 flat
#Volume low
#Interpretation:

#👉 No control

#Meaning: Stay out

#AN EXAMPLE

#“If price drops and 9 and 21 drop and volume drops…”

#That actually becomes: ⚠️ WEAKNESS, NOT BULLISH
#Price ↓
#EMA 9 ↓
#EMA 21 ↓
#Volume ↓
#👉 This = lack of buyers AND sellers

#Meaning: Drift / downtrend — not a bounce setup


#SIMPLE DECISION FRAMEWORK

#Ask 3 questions:

#1. WHERE IS PRICE?
#Above 9 = strong
#Between 9 & 21 = pullback
#Below 21 = danger
#2. WHAT ARE EMAs DOING?
#Both up = trend
#9 down, 21 up = pullback
#Both down = bearish
#3. WHAT IS VOLUME DOING?
#Falling = weak move
#Rising = strong move
#Spike = exhaustion or break
#COMBINED QUICK READ

#Setup    Meaning
#Price ↓ + Vol ↓ + EMAs ↑    BUY DIP
#Price ↓ + Vol ↑    SELL PRESSURE
#Price flat + Vol ↓    CONSOLIDATION
#Price ↑ + Vol ↑ spike    EXHAUSTION
#Price ↓ + EMAs ↓    TREND DOWN

#KEY INSIGHT (MOST IMPORTANT)

#👉 Volume tells you conviction
#👉 EMA tells you structure
#👉 Price tells you timing



# =========================
# EXECUTION CONTECT ENGINE
# NORMALIZED EMA + VOLUME PANEL
# antwerks 04/09/2026
# =========================

declare lower;

input normLength = 50;

# =========================
# PRICE + EMA
# =========================
def price = close;
input avg1_type = AverageType.exponential;
input avg1_length = 9;
def avg1 = MovingAverage(avg1_type, price, avg1_length );

input avg2_type = AverageType.exponential;
input avg2_length = 21;
def avg2 = MovingAverage(avg2_type, price, avg2_length );



# =========================
# NORMALIZATION RANGE
# =========================
def highestP = Highest(price, normLength);
def lowestP = Lowest(price, normLength);
def range = highestP - lowestP;

def normPrice = (price - lowestP) / range;
def normEMA9 = (avg1 - lowestP) / range;
def normEMA21 = (avg2 - lowestP) / range;

# =========================
# PLOTS (NOW VISIBLE)
# =========================
plot PriceNorm = normPrice;
PriceNorm.SetDefaultColor(Color.MAGENTA);
PriceNorm.SetLineWeight(2);

plot EMA9Norm = normEMA9;
EMA9Norm.SetDefaultColor(Color.CYAN);
EMA9Norm.SetLineWeight(2);

plot EMA21Norm = normEMA21;
EMA21Norm.SetDefaultColor(Color.YELLOW);
EMA21Norm.SetLineWeight(2);


# =========================
# VOLUME NORMALIZATION
# =========================
def vol = volume;
def volHigh = Highest(volume, normLength);

def normVol = vol / volHigh;

plot VolumeNorm = normVol;
VolumeNorm.SetDefaultColor(Color.light_GRAY);
VolumeNorm.SetLineWeight(1);

# =========================
# CONDITIONS
# =========================
def lowVol = normVol < Average(normVol, 20);
def pullback = normPrice < normEMA9;
def volAvg = Average(volume, 20);

def lowVolumePullback =
    close < close[1] and
    volume < Average(volume, 20) and
    close > avg2;  # <-- trend filter

def highVolumeSell =
    close < close[1] and
    volume > Average(volume, 20) and
    close < low[1];   # <-- KEY ADDITION

def trueSellPressure = highVolumeSell and (high - low) > Average(TrueRange(high, close, low), 14);

def nearHigh = close >= (Highest(close, 20) * 0.98);

def momentumRising = ExpAverage(close, 5) > ExpAverage(close, 5)[1];

def deeperPullback = (close < avg1 and close < avg2);


# =========================
# SMART FLOW LABEL (FINAL)
# =========================

def avgVol = Average(volume, 20);

def absorption =
    close < close[1] and
    volume > avgVol and
    close >= low[1];

AddLabel(yes,
# 🔵 HIGHEST PRIORITY: ABSORPTION
  (if absorption and nearHigh then "A+ ABSORPTION (BULLISH)"
  else if absorption then "ABSORPTION (BUYERS ACTIVE)"

# 🟢 CONTINUATION
  else if lowVolumePullback and deeperPullback then "WEAK PULLBACK (WATCH)"
  else if lowVolumePullback then "B+ PULLBACK: DIGESTION"

# 🔴 TRUE SELLING
  else if trueSellPressure then "STRONG SELLING (SHORT)"
  else if highVolumeSell then "WEAK SELLING"

# ⚪ DEFAULT
  else "NO EDGE"),

# COLORS
  (if absorption then Color.CYAN
   else if lowVolumePullback then Color.GREEN
   else if highVolumeSell then Color.RED
   else Color.GRAY));


# =========================
# KEY LINE LABELS (COLOR MATCHED)
# =========================



addlabel(1, " ", color.black);
addlabel(1, "PriceNorm", EMA9Norm.TakeValueColor() );

addlabel(1,
(if avg2_type == AverageType.Simple then "SMA"
 else if avg2_type == AverageType.exponential then "EMA"
 else if avg2_type == AverageType.hull then "HULL"
 else if avg2_type == AverageType.weighted then "WT"
 else if avg2_type == AverageType.wilders then "WILD"
 else "---") + avg2_length
, EMA21Norm.TakeValueColor() );
#, color.cyan);


addlabel(1,
(if avg2_type == AverageType.Simple then "SMA"
 else if avg2_type == AverageType.exponential then "EMA"
 else if avg2_type == AverageType.hull then "HULL"
 else if avg2_type == AverageType.weighted then "WT"
 else if avg2_type == AverageType.wilders then "WILD"
 else "---") + avg2_length
, PriceNorm.TakeValueColor() );

addlabel(1, " ", color.black);




AddLabel(0,
    "PRICE: " + Round(close, 2),
    Color.MAGENTA);

AddLabel(yes,
#    "EMA 9: " + Round(ExpAverage(close, 9), 2),
    "EMA 9: " + Round(avg1, 2),
    Color.CYAN );

AddLabel(yes,
#    "EMA 21: " + Round(ExpAverage(close, 21), 2),
    "EMA 21: " + Round(avg2, 2),
    Color.GREEN );

AddLabel(yes,
    "VOL: " + Round(volume, 0),
    Color.light_GRAY);


def pos = Double.POSITIVE_INFINITY;
def neg = Double.NEGATIVE_INFINITY;
def na = double.nan;


def ab = if absorption then pos else na;
addcloud(ab, neg, color.cyan);

def lowv = if lowVolumePullback then pos else na;
addcloud(lowv, neg, color.green);

def hiv = if highVolumesell then pos else na;
addcloud(hiv, neg, color.red);


#def zz = if (!absorption and !lowVolumePullback and !highVolumeSell) then pos else na;
#addcloud(zz, neg, color.gray);

#
let me look - very cool visual, I might think about adding conditions like price above the 9 and 21 and volume up before going green and things like that - what do you think? At the right side of chart you see you get some false signals otherwise ---
 
Last edited:
This indicator combines price plot, 9 EMA plot, 21 EMA plot and volume plot. The reason that the interaction of these particular individual indicators is relevant and important is because their interaction captures the relationship between price structure, trend persistence, and volume participation, allowing us to distinguish between continuation, exhaustion, and reversal conditions. Individually they show signals, but together they tell you whether a move is worth trading.

0iC10yO.png

Here is how to translate the visual into actionable:

Who is in control + how aggressive they are
HIGH-VALUE SCENARIOS

1. LOW VOL PULLBACK (BULLISH CONTINUATION)
Condition:
  • Price ↓ (pulling back)
  • EMA 9 ↑
  • EMA 21 ↑
  • Volume ↓
Interpretation:
👉 Sellers are weak
👉 No urgency to exit
👉 Trend still intact
Meaning: Pullback → likely bounce
Trade Logic:
  • Buy dips into 9 / 21
  • Best version = shallow pullback
2. LOW VOL CONSOLIDATION AT HIGHS (STRONG BULLISH)
Condition:
  • Price flat / slight ↓ near highs
  • EMA 9 ↑
  • EMA 21 ↑
  • Volume ↓
Interpretation:
👉 Market is pausing, not selling
👉 No distribution
Meaning: Continuation setup (A+)

3. ABSORPTION (HIDDEN BUYING)
Condition:
  • Price ↓ or flat
  • Volume ↑
  • BUT price holds structure (no breakdown)
Interpretation:
👉 Sellers hitting bids
👉 Buyers absorbing
Meaning: Fuel for next move up

4. HEALTHY TREND (CONTROLLED MOVE)
Condition:
  • Price ↑
  • EMA 9 ↑
  • EMA 21 ↑
  • Volume steady (not spiking)
Interpretation:
👉 Balanced buying
👉 No exhaustion
Meaning: Trend continuation

5. EXHAUSTION (TOP RISK)
Condition:
  • Price ↑ fast
  • Volume ↑↑ (spike)
  • Price stalls or wicks
Interpretation:
👉 Buyers getting trapped
👉 Late entries
Meaning: Pullback likely

6. HIGH VOL SELLING (BEARISH)
Condition:
  • Price ↓
  • Volume ↑
  • Breaks prior low
Interpretation:
👉 Real selling pressure
👉 No absorption
Meaning: Avoid longs / short bias

7. WEAK PULLBACK (TREND AT RISK)
Condition:
  • Price ↓
  • EMA 9 ↓
  • EMA 21 still ↑ (lagging)
  • Volume neutral / rising
Interpretation:
👉 Short-term trend breaking
Meaning: Transition phase

8. TREND BREAKDOWN
Condition:
  • Price ↓ below 21 EMA
  • EMA 9 ↓
  • EMA 21 flattening or ↓
  • Volume ↑
Interpretation: Trend shift

Meaning: Bull trend likely over

9. NO EDGE / CHOP
Condition:
  • Price crossing 9 & 21 constantly
  • EMA 9 flat
  • EMA 21 flat
  • Volume low
Interpretation:
👉 No control
Meaning: Stay out

AN EXAMPLE
“If price drops and 9 and 21 drop and volume drops…”
That actually becomes: ⚠️ WEAKNESS, NOT BULLISH
  • Price ↓
  • EMA 9 ↓
  • EMA 21 ↓
  • Volume ↓
👉 This = lack of buyers AND sellers
Meaning: Drift / downtrend — not a bounce setup

SIMPLE DECISION FRAMEWORK
Ask 3 questions:
1. WHERE IS PRICE?
  • Above 9 = strong
  • Between 9 & 21 = pullback
  • Below 21 = danger
2. WHAT ARE EMAs DOING?
  • Both up = trend
  • 9 down, 21 up = pullback
  • Both down = bearish
3. WHAT IS VOLUME DOING?
  • Falling = weak move
  • Rising = strong move
  • Spike = exhaustion or break
COMBINED QUICK READ
SetupMeaning
Price ↓ + Vol ↓ + EMAs ↑BUY DIP
Price ↓ + Vol ↑SELL PRESSURE
Price flat + Vol ↓CONSOLIDATION
Price ↑ + Vol ↑ spikeEXHAUSTION
Price ↓ + EMAs ↓TREND DOWN

KEY INSIGHT (MOST IMPORTANT)
👉 Volume tells you conviction
👉 EMA tells you structure
👉 Price tells you timing

Code:
# =========================
# EXECUTION CONTECT ENGINE
# NORMALIZED EMA + VOLUME PANEL
# antwerks 04/09/2026
# =========================

declare lower;

input normLength = 50;

# =========================
# PRICE + EMA
# =========================
def price = close;
def ema9 = ExpAverage(close, 9);
def ema21 = ExpAverage(close, 21);

# =========================
# NORMALIZATION RANGE
# =========================
def highestP = Highest(price, normLength);
def lowestP = Lowest(price, normLength);
def range = highestP - lowestP;

def normPrice = (price - lowestP) / range;
def normEMA9 = (ema9 - lowestP) / range;
def normEMA21 = (ema21 - lowestP) / range;

# =========================
# PLOTS (NOW VISIBLE)
# =========================
plot PriceNorm = normPrice;
PriceNorm.SetDefaultColor(Color.MAGENTA);
PriceNorm.SetLineWeight(2);

plot EMA9Norm = normEMA9;
EMA9Norm.SetDefaultColor(Color.CYAN);
EMA9Norm.SetLineWeight(2);

plot EMA21Norm = normEMA21;
EMA21Norm.SetDefaultColor(Color.YELLOW);
EMA21Norm.SetLineWeight(2);

# =========================
# VOLUME NORMALIZATION
# =========================
def vol = volume;
def volHigh = Highest(volume, normLength);

def normVol = vol / volHigh;

plot VolumeNorm = normVol;
VolumeNorm.SetDefaultColor(Color.GRAY);
VolumeNorm.SetLineWeight(1);

# =========================
# CONDITIONS
# =========================
def lowVol = normVol < Average(normVol, 20);
def pullback = normPrice < normEMA9;
def volAvg = Average(volume, 20);

def lowVolumePullback =
    close < close[1] and
    volume < Average(volume, 20) and
    close > ExpAverage(close, 21);  # <-- trend filter

def highVolumeSell =
    close < close[1] and
    volume > Average(volume, 20) and
    close < low[1];   # <-- KEY ADDITION

def trueSellPressure =
    highVolumeSell and
    (high - low) > Average(TrueRange(high, close, low), 14);

def nearHigh =
    close >= Highest(close, 20) * 0.98;

def momentumRising =
    ExpAverage(close, 5) > ExpAverage(close, 5)[1];

def deeperPullback =
    close < ExpAverage(close, 9) and
    close < ExpAverage(close, 21);

# =========================
# SMART FLOW LABEL (FINAL)
# =========================

def avgVol = Average(volume, 20);

def absorption =
    close < close[1] and
    volume > avgVol and
    close >= low[1];

AddLabel(yes,

    # 🔵 HIGHEST PRIORITY: ABSORPTION
    if absorption and nearHigh then "A+ ABSORPTION (BULLISH)"
    else if absorption then "ABSORPTION (BUYERS ACTIVE)"

    # 🟢 CONTINUATION
    else if lowVolumePullback and deeperPullback then "WEAK PULLBACK (WATCH)"
else if lowVolumePullback then "B+ PULLBACK: DIGESTION"

    # 🔴 TRUE SELLING
    else if trueSellPressure then "STRONG SELLING (SHORT)"
else if highVolumeSell then "WEAK SELLING"

    # ⚪ DEFAULT
    else "NO EDGE",

    # COLORS
    if absorption then Color.CYAN
    else if lowVolumePullback then Color.GREEN
    else if highVolumeSell then Color.RED
    else Color.GRAY
);

# =========================
# KEY LINE LABELS (COLOR MATCHED)
# =========================

AddLabel(yes,
    "PRICE: " + Round(close, 2),
    Color.MAGENTA
);

AddLabel(yes,
    "EMA 9: " + Round(ExpAverage(close, 9), 2),
    Color.CYAN
);

AddLabel(yes,
    "EMA 21: " + Round(ExpAverage(close, 21), 2),
    Color.GREEN
);

AddLabel(yes,
    "VOL: " + Round(volume, 0),
    Color.GRAY
);

Nice! I changed the VolumeNorm line to HISTOGRAM.
 

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

Thread starter Similar threads Forum Replies Date
Ricky_005 Fibonacci MAs – 8-Slot Engine For ThinkOrSwim Custom 0

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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