Inducement [UAlgo]Inducement is a market structure tool designed to detect pullback liquidity levels that form during directional expansion and remain relevant until price comes back to sweep them. The script tracks directional legs, monitors the deepest retracement points that appear against the active move, and promotes those retracement extremes into active IDM levels once the trend resumes in the original direction.
The core idea is simple. During a bullish move, price often creates a temporary downside pullback before continuing upward. That pullback low can later act as an inducement point where liquidity rests below the market. In a bearish move, the opposite process happens, where an upside pullback forms before price continues lower. That pullback high can later become a bearish inducement point. This script automates that process and keeps those levels visible on the chart until they are eventually swept.
What makes the script useful is that it does not plot every fluctuation. It first filters out inside bars, tracks the active directional leg, records the most meaningful retracement extreme inside that leg, and only creates a new IDM when price resumes the main move by printing a fresh expansion. That makes the final levels cleaner and more structurally relevant.
Once an IDM is created, it is drawn as a horizontal reference with a label. If price later trades through that level, the script marks it as swept, updates the label, and changes the line style to reflect that the liquidity has been taken. This creates a very practical chart view for traders who want to monitor inducement behavior, liquidity sweeps, and the relationship between pullbacks and later price delivery.
🔹 Features
🔸 Directional Leg Tracking
The script maintains an internal bullish or bearish trend state and updates the active structural leg as price continues to expand. This gives the indicator a directional framework instead of treating each new bar independently.
🔸 Inside Bar Filtering
Inside bars are ignored for structural progression. This helps the script focus on meaningful range expansion rather than reacting to small compressive candles that do not add new directional information.
🔸 Pullback Extreme Detection
During a bullish leg, the script tracks the lowest downside pullback that forms before the next bullish expansion. During a bearish leg, it tracks the highest upside pullback before the next bearish expansion. These stored extremes are the raw candidates for inducement levels.
🔸 Automatic IDM Creation
A stored pullback extreme becomes an active IDM only when the market resumes the active leg and creates a fresh structural push. This means the indicator does not mark every retracement immediately. It waits for continuation confirmation.
🔸 Bullish and Bearish IDM Mapping
Bullish IDM levels are created from pullback lows inside bullish continuation.
Bearish IDM levels are created from pullback highs inside bearish continuation.
This gives the user a clean map of likely liquidity resting points below or above price.
🔸 Sweep Recognition
Once an IDM is active, the script checks every new bar to see whether price has swept it. Bullish IDM is considered swept when current low trades at or below the level. Bearish IDM is considered swept when current high trades at or above the level.
🔸 Live Visual State Changes
Active IDM levels are drawn with dashed lines and labeled as unswept. Once swept, the line style changes, the color becomes softer, and the label updates to show that the liquidity event has already occurred.
🔸 Lightweight Structure Display
The script keeps an internal array of active IDM levels and limits the array size to avoid uncontrolled growth. This keeps the display practical and suitable for live chart use.
🔹 Calculations
1) Defining the IDM Object
type InducementLevel
float price
int bIndex
int dir
line idmLine
label idmLabel
bool isSwept
This is the core data container used by the script.
Each inducement level stores:
its price,
the bar index where it originated,
its direction,
its line object,
its label object,
and whether it has already been swept.
The dir field controls the level type:
1 means bullish IDM
-1 means bearish IDM
So before any logic runs, the script already has a dedicated structure for tracking the full lifecycle of each inducement level from creation to sweep.
2) Drawing Active and Swept Levels
method draw(InducementLevel this, color c_bull, color c_bear) =>
color c = this.dir == 1 ? c_bull : c_bear
string txt = this.isSwept ? "IDM ✓" : "IDM ✗"
if na(this.idmLine)
this.idmLine := line.new(this.bIndex, this.price, bar_index, this.price, color=c, style=line.style_dashed)
else if not this.isSwept
this.idmLine.set_x2(bar_index)
if na(this.idmLabel)
this.idmLabel := label.new(bar_index, this.price, txt, style=label.style_none, textcolor=c, size=size.small, textalign=text.align_left)
else if not this.isSwept
this.idmLabel.set_x(bar_index)
this
This method is responsible for visualizing each inducement level.
First, it selects the correct color according to direction. Bullish levels use the bullish color input, and bearish levels use the bearish color input. Then it builds a text state:
"IDM ✗" means the level is still active and not yet swept.
"IDM ✓" means the level has already been swept.
If the line does not exist yet, the script creates a dashed horizontal line starting from the level’s origin bar to the current bar. If the line already exists and the level is still unswept, the line is extended to the latest bar.
The label follows the same logic. If no label exists, it is created. If the label already exists and the level is still active, its position is moved to the latest bar.
So visually, each active IDM behaves like a live horizontal liquidity reference that extends forward until price takes it.
3) Detecting Liquidity Sweeps
method checkSweep(InducementLevel this, float currLow, float currHigh, color c_bull, color c_bear) =>
if not this.isSwept
swept = false
if this.dir == 1 and currLow <= this.price
swept := true
else if this.dir == -1 and currHigh >= this.price
swept := true
This method determines whether an existing inducement level has been taken.
The logic is direction specific.
For bullish IDM:
if the current low trades at or below the level price, the level is considered swept.
For bearish IDM:
if the current high trades at or above the level price, the level is considered swept.
This matches the structural idea behind inducement. A bullish pullback low represents liquidity resting below price, and that liquidity is considered taken once price trades through it. A bearish pullback high represents liquidity resting above price, and that liquidity is considered taken once price pushes through it.
So this method is the event detector that turns an active liquidity level into a completed liquidity event.
4) Updating the Visual State After a Sweep
if swept
this.isSwept := true
color c = this.dir == 1 ? color.new(c_bull, 50) : color.new(c_bear, 50)
this.idmLine.set_color(c)
this.idmLine.set_style(line.style_dotted)
this.idmLine.set_x2(bar_index)
this.idmLabel.set_text("IDM ✓")
this.idmLabel.set_textcolor(c)
this.idmLabel.set_x(bar_index)
Once a sweep happens, the script changes both the internal state and the visual appearance.
The level is marked as swept with this.isSwept := true .
Then the line color becomes softer by applying transparency.
The line style changes from dashed to dotted.
The label text changes from IDM ✗ to IDM ✓ .
This is useful because it preserves the historical location of the inducement while also showing that the level is no longer pending. In other words, the chart keeps the context but changes the state.
5) Filtering Out Inside Bars
var float mHigh = high
var float mLow = low
bool isInside = high <= mHigh and low >= mLow
This small block is more important than it looks.
The script stores a reference range using mHigh and mLow . A bar is considered inside if its high is less than or equal to the stored high and its low is greater than or equal to the stored low.
In simple terms, an inside bar is a bar that remains contained within the prior meaningful structure range. The script ignores those bars for the purpose of leg progression.
This helps reduce noise because inside bars usually reflect compression rather than new structural information. By ignoring them, the indicator focuses on actual range expansion and meaningful pullback development.
6) Tracking Trend State and Leg Extremes
var int trend = 1
var float legHigh = high
var float legLow = low
var float pullbackLow = na
var int pullbackLowBar = na
var float pullbackHigh = na
var int pullbackHighBar = na
This block defines the internal market structure memory.
trend stores whether the script currently sees the market as bullish or bearish.
legHigh and legLow track the active structural extreme of the current leg.
pullbackLow and pullbackHigh store the most important retracement extreme that forms against the current trend.
So the script is always tracking two things at once:
the direction of the main move,
and the deepest retracement against that move.
That retracement extreme later becomes the candidate IDM if price resumes the original direction.
7) Bullish Leg Logic and Bullish IDM Creation
if trend == 1
if high > legHigh
if not na(pullbackLow)
activeIDMs.push(InducementLevel.new(pullbackLow, pullbackLowBar, 1, na, na, false))
pullbackLow := na
legHigh := high
else if brokeLow
if na(pullbackLow) or low < pullbackLow
pullbackLow := low
pullbackLowBar := bar_index
This is the heart of bullish inducement detection.
When the script is in bullish mode, it watches for two types of events.
First, if price makes a new leg high:
high > legHigh
That means bullish continuation has occurred. If a downside pullback low had been stored before this continuation, the script converts that pullback low into a new bullish IDM by pushing it into the active array.
That is the crucial idea:
the pullback low becomes inducement only after price proves continuation by printing a fresh high.
Second, if the current bar breaks below the stored micro range low:
brokeLow
Then the script updates pullbackLow if this new low is deeper than the previously stored pullback. This allows the script to keep tracking the deepest retracement inside the bullish leg until continuation happens.
So bullish IDM is created from the most meaningful downside retracement that occurs before the next bullish expansion.
8) Bearish Leg Logic and Bearish IDM Creation
else if trend == -1
if low < legLow
if not na(pullbackHigh)
activeIDMs.push(InducementLevel.new(pullbackHigh, pullbackHighBar, -1, na, na, false))
pullbackHigh := na
legLow := low
else if brokeHigh
if na(pullbackHigh) or high > pullbackHigh
pullbackHigh := high
pullbackHighBar := bar_index
This is the mirror image of the bullish logic.
When the script is in bearish mode, it waits for a new leg low:
low < legLow
If that happens and a prior upside pullback high was stored, the script converts that pullback high into a bearish IDM. This marks the retracement high as a future liquidity point above price.
If price does not yet continue lower but instead breaks upward inside the local structure:
brokeHigh
Then the script updates pullbackHigh if the new high is greater than the previously stored retracement high.
So bearish IDM is created from the strongest upside retracement that forms before the next bearish continuation.
9) Detecting Trend Reversal and Resetting the Pullback Memory
if low < legLow
trend := -1
legLow := low
pullbackLow := na
pullbackHigh := na
if high > legHigh
trend := 1
legHigh := high
pullbackHigh := na
pullbackLow := na
These blocks handle directional flips.
Inside bullish mode, if price breaks below the active leg low, the script changes its internal state to bearish.
Inside bearish mode, if price breaks above the active leg high, the script changes its internal state to bullish.
Whenever the trend flips, the stored pullback variables are cleared. That is important because retracement data from the old trend should not be reused after the market has structurally changed direction.
So the script always keeps its inducement logic aligned with the current structural leg rather than mixing information from opposite phases.
10) Updating the Reference Range After a Non Inside Bar
if not isInside
bool brokeLow = low < mLow
bool brokeHigh = high > mHigh
mHigh := high
mLow := low
This block updates the structure reference only when the current bar is not an inside bar.
Before resetting the reference range, the script checks whether the current bar expanded below the stored low or above the stored high. Those two booleans are then used in the bullish and bearish logic to decide whether the move represents pullback development or continuation.
After those checks are done, the reference high and low are updated to the current bar’s high and low.
So mHigh and mLow act like a rolling structural filter that helps the script ignore internal compression and focus on meaningful range expansion.
11) Managing All Active IDM Levels on Every Bar
if activeIDMs.size() > 0
for i = 0 to activeIDMs.size() - 1
idm = activeIDMs.get(i)
idm.checkSweep(low, high, colorBullIDM, colorBearIDM)
idm.draw(colorBullIDM, colorBearIDM)
This is the execution loop for all stored inducement levels.
On every bar, the script goes through each active IDM and does two things:
it checks whether the level has now been swept,
and it redraws or updates the level on the chart.
This means every stored level remains live and state aware. Unswept levels keep extending forward, while swept levels lock their appearance into a completed state.
So the script is always balancing two layers:
new IDM creation from ongoing structure,
and lifecycle management of previously created levels.
12) Limiting the Number of Stored Levels
if activeIDMs.size() > 50
activeIDMs.shift()
This last block keeps the internal IDM array from growing indefinitely.
If more than fifty inducement levels are stored, the oldest one is removed from the array. This helps keep memory usage under control and makes the indicator more practical for ongoing chart use.
The purpose here is not analytical. It is purely operational. The script limits historical storage so the active structure set remains manageable.
Indicador Pine Script®


