1. Indicator Description – Ranked FVG Imbalance Zones (Zeiierman)
Detects, ranks, and displays the highest-quality Fair Value Gap zones on the chart using a dynamic scoring system
1.1 Indicator Concept
A Fair Value Gap (FVG) — also called a price imbalance — is a concept rooted in Smart Money Concept (SMC) theory. The core idea: when price moves too fast and too aggressively in one direction, it leaves a gap on the chart (a void between two candles) where no actual trading took place. The market tends to return and fill that gap later, as if correcting the supply/demand imbalance it created.
This indicator goes further: instead of plotting every FVG that appears (which floods the chart with colored boxes), it scores the quality of each FVG zone based on four factors — gap size, trading volume, trend alignment, and candle strength — then only displays the highest-scoring zones. That is why the word "Ranked" appears in the indicator's name.
The core belief: Not all FVGs are equal — a gap formed during high volume, a clear trend, and a strong breakout candle is far more reliable than one formed under ordinary conditions.
1.2 Indicator Features
- FVG Zone Boxes: Each FVG is drawn as a rectangle — teal/green for bullish zones and pink/red for bearish zones — extending to the right so they remain visible over time.
- Bull/Bear Strength Bars inside each box: Every FVG box is split vertically — the upper half shows a bear strength bar, the lower half shows a bull strength bar — each displaying its percentage (e.g. 73% bull / 27% bear).
- Smart Text Label: Each box displays a plain-language assessment such as "Strong Bullish Imbalance", "Bearish Bias", or "Weak Bullish (Bear Pressure)" for a quick read of zone quality.
- Ranking & Filtering: Only the top maxZones zones (default 10) by score are visible at any time. Lower-ranked zones are hidden (not deleted) until their score improves.
- Alerts (6 types): Triggered when a new FVG forms, when an FVG reaches the top rank, when price touches a zone, and when a zone is fully mitigated.
1.3 How to Use the Indicator
- Identify potential support and resistance zones: Teal FVG boxes below current price are potential support areas (price may return to fill them). Pink/red boxes above price are potential resistance areas.
- Prioritize high-ranked zones: Since only the top maxZones zones are shown, any visible box has already passed the quality filter. Zones that remain displayed across many bars without being mitigated — and keep their top-N ranking — are the most significant.
- Read the text label for directional bias: "Strong Bullish Imbalance" → strong buy zone, expect a bounce when price revisits. "Weak Bullish (Bear Pressure)" → even though it is a bullish FVG, selling pressure dominates — be cautious going long.
- Watch the bull/bear percentage bars for internal strength: If a bullish FVG box shows a bear bar above 60%, the zone is weakening — the long signal is less reliable.
- Use the "Bullish/Bearish FVG Touch" alert to catch entries when price pulls back to test an FVG zone, combined with price action confirmation or another indicator.
- Use the "FVG Fully Mitigated" alert to know when a zone has been completely filled and removed — time to update your support/resistance map.
1.4 How the Indicator Works
Inputs & Their Roles- maxZones (Integer, default 10, range 1–20): How many top-ranked FVG zones are displayed on the chart. The indicator stores more internally but only colors and labels the top N. Reducing to 3 shows only the 3 strongest; increasing to 20 includes weaker zones as well.
- maxStored (Integer, default 50, range 10–200): Maximum number of FVGs kept in memory at once. When exceeded, the lowest-ranked zone is permanently deleted. Higher values allow tracking older historical zones at the cost of more resources.
- volLength (Integer, default 20): The lookback period for the Volume SMA used as a baseline. If the candle forming the FVG has volume twice the 20-bar average, volScore = 2.0, adding significant points. Lowering to 5 makes the baseline shorter and easier to beat.
- trendLength (Integer, default 50): The EMA period used for trend alignment. If price closes above EMA-50 when a bullish FVG forms → trend is aligned → trendScore = 1.0 → +20 points. A shorter value (e.g. 20) reacts more to short-term trend direction.
- showBars (Checkbox, default on): Toggles the bull/bear strength bars inside each FVG box. Turning off keeps the chart cleaner.
- showBlockText (Checkbox, default on): Toggles the smart text label ("Strong Bullish Imbalance", etc.) inside each FVG box.
- strengthTextSize / blockTextSize (Options: auto/tiny/small/normal/large/huge): Controls the font size of the percentage labels and the block text label respectively.
- bullColor / bearColor (Color): Fill color for bullish and bearish FVG boxes and strength bars. Default is teal for bull and pink/red for bear.
- alertNewBull / alertNewBear / alertTopRank / alertBullTouch / alertBearTouch / alertFullyMitigated (Checkboxes): Enable or disable each of the 6 alert types independently.
🔷 Flow 1 – FVG Detection (3-candle pattern)
On every new bar, the indicator checks for a 3-candle imbalance pattern:
- Bullish FVG: low[0] > high[2] — The current candle's low is above the high of the candle 2 bars ago. The gap between those two candles is a bullish FVG. Example: candle[2] has high = 100, current candle has low = 102 → the zone from 100 to 102 is a bullish FVG.
- Bearish FVG: high[0] < low[2] — The current candle's high is below the low of the candle 2 bars ago. Example: candle[2] has low = 100, current candle has high = 98 → the zone from 98 to 100 is a bearish FVG.
The middle candle (bar[1]) is the strong breakout candle. Candle[2] and candle[0] define the upper and lower boundaries of the FVG zone.
🔷 Flow 2 – Quality Score Calculation
When a new FVG is detected, its initial quality score is calculated immediately:
qualityScore = fvgSize × 100 + volScore × 10 + trendScore × 20 − mitigation × 50
mitigation = 0.0 when freshly created. The score also decays by
age × 0.1 on every subsequent bar.
| Component | Calculation | Meaning |
|---|---|---|
| fvgSize × 100 | Gap width in price units × 100 | Wider gap = stronger breakout = higher score |
| volScore × 10 | volume / volumeMA. If volume is 2× the average → volScore = 2.0 → +20 pts | High volume confirms the validity of the imbalance |
| trendScore × 20 | = 1.0 if FVG aligns with EMA trend direction, = 0.0 if against | Trend-aligned FVGs are more reliable than counter-trend ones |
| − mitigation × 50 | Fraction of zone already filled (0.0 to 1.0) | Partially filled zones lose score — their reliability decreases |
| − age × 0.1 | Number of bars elapsed since the FVG was created | Older untested zones gradually decay in score over time |
🔷 Flow 3 – Bull/Bear Strength Score
Alongside the quality score, a composite strength score (0–100) is calculated to split the bull/bear bars:
| Component | Max Points | Calculation |
|---|---|---|
| Gap Strength | 40 pts | fvgSize relative to ATR(14), capped at 2× ATR for full score |
| Volume Strength | 30 pts | volScore capped at 2.0 — volume twice the average earns max points |
| Trend Strength | 20 pts | trendScore × 20 — binary: 0 or 20 depending on EMA alignment |
| Candle Strength | 10 pts | Body-to-range ratio × 10 — a full marubozu candle earns ~10 pts |
The total (0–100) is mainStrength. It is then split:
- For a bullish FVG: bullStrength = mainStrength, bearStrength = 100 − mainStrength
- For a bearish FVG: bearStrength = mainStrength, bullStrength = 100 − mainStrength
Example: a bullish FVG with mainStrength = 73 → bullStrength = 73%, bearStrength = 27%.
🔷 Flow 4 – Mitigation Tracking
On every bar, the indicator loops through all stored FVGs and checks if price has entered the zone:
- Bullish FVG is touched when: low <= fvg.top (current bar's low enters the zone from above)
- Bearish FVG is touched when: high >= fvg.bottom (current bar's high enters the zone from below)
When touched, the fill ratio is calculated. Example: bullish FVG from 100 to 105 (width = 5 pts). Price low reaches 102 → fillDistance = 105 − 102 = 3 → mitigation = 3/5 = 0.6 (60%). When mitigation reaches 1.0 (100%), the zone is permanently deleted from the chart and memory.
🔷 Flow 5 – Sorting, Filtering & Display
After all updates, the full FVG list is sorted descending by qualityScore. Then:
- If stored count exceeds maxStored: the lowest-ranked zone is popped from memory permanently
- Each zone is rendered by rank: index < maxZones → shown fully colored; index ≥ maxZones → rendered fully transparent (hidden, not deleted)
🔷 Flow 6 – Smart Text Label Logic
For each visible FVG, the text label is chosen according to the following rules:
| FVG Type | Condition | Label Displayed |
|---|---|---|
| Bearish FVG | bearStrength ≥ 70 | Strong Bearish Imbalance |
| bearStrength ≥ 55 | Bearish Bias | |
| bullStrength > bearStrength | Weak Bearish (Bull Pressure) | |
| Otherwise | Neutral Bearish | |
| Bullish FVG | bullStrength ≥ 70 | Strong Bullish Imbalance |
| bullStrength ≥ 55 | Bullish Bias | |
| bearStrength > bullStrength | Weak Bullish (Bear Pressure) | |
| Otherwise | Neutral Bullish |
- FVG Zone Boxes: Colored rectangles extending 25 bars to the right. Teal = bullish (potential support), Pink/Red = bearish (potential resistance).
- Bull/Bear Strength Bars: Two horizontal bars inside each box showing percentage for each side. Bull bar in the lower half, bear bar in the upper half. Bar width scales with the percentage.
- Smart Text Label: A plain-text string in the right corner of the FVG box — Strong / Bias / Weak / Neutral — for instant readability without needing to look at the percentages.
- 6 Alert Types: New Bullish FVG, New Bearish FVG, New Top-Ranked FVG, Bullish FVG Touch, Bearish FVG Touch, FVG Fully Mitigated — each toggled independently.
// This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
// https://creativecommons.org/licenses/by-nc-sa/4.0/
// © Zeiierman {
//@version=6
indicator("Ranked FVG Imbalance Zones (Zeiierman)", overlay = true, max_boxes_count = 300)
//}
// ~~ Tooltips {
t1 = "Controls how many of the highest-ranked FVG zones are visible on the chart. The script can store more zones internally, but only the strongest ranked zones are displayed."
t2 = "Maximum number of FVG zones stored internally before the oldest/lowest-ranked zones are removed. Higher values allow more historical zones to be tracked."
t3 = "Length used to calculate the average volume baseline. The FVG volume score compares current volume against this average."
t4 = "EMA length used to define trend alignment. Bullish FVGs above the EMA and bearish FVGs below the EMA receive stronger trend scores."
t5 = "Shows or hides the internal bullish and bearish strength bars inside each FVG block."
t6 = "Shows or hides the smart text label inside each FVG block, such as Strong Bullish Imbalance, Bearish Bias, or Weak Bearish."
t7 = "Color used for bullish FVG bodies and bullish strength bars."
t8 = "Color used for bearish FVG bodies and bearish strength bars."
t9 = "Trigger an alert when a new bullish FVG is detected."
t10 = "Trigger an alert when a new bearish FVG is detected."
t11 = "Trigger an alert when a new FVG becomes the highest-ranked visible zone."
t12 = "Trigger an alert when price touches or begins mitigating an active bullish FVG."
t13 = "Trigger an alert when price touches or begins mitigating an active bearish FVG."
t14 = "Trigger an alert when an FVG becomes fully mitigated and is removed from the chart."
t15 = "Controls the text size used for the bullish and bearish strength percentage labels inside each FVG."
t16 = "Controls the text size used for the smart FVG block text, such as Strong Bullish Imbalance or Bearish Bias."
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Inputs {
gRanking = "Ranking"
gStrength = "Strength Engine"
gDisplay = "Display"
gColors = "Colors"
gAlerts = "Alerts"
maxZones = input.int(10, "Show Top Zones", minval = 1, maxval = 20, tooltip = t1, group = gRanking)
maxStored = input.int(50, "Max Stored FVGs", minval = 10, maxval = 200, tooltip = t2, group = gRanking)
volLength = input.int(20, "Volume MA Length", tooltip = t3, group = gStrength)
trendLength = input.int(50, "Trend EMA Length", tooltip = t4, group = gStrength)
showBars = input.bool(true, "Show Strength Bars", tooltip = t5, group = gDisplay)
showBlockText = input.bool(true, "Show FVG Block Text", tooltip = t6, group = gDisplay)
strengthTextSize = input.string("auto", "Strength Text Size", options = ["auto", "tiny", "small", "normal", "large", "huge"], tooltip = t15, group = gDisplay)
blockTextSize = input.string("auto", "Block Text Size", options = ["auto", "tiny", "small", "normal", "large", "huge"], tooltip = t16, group = gDisplay)
bullColor = input.color(color.rgb(26, 216, 194, 50), "Bullish", inline = "colors", tooltip = t7, group = gColors)
bearColor = input.color(color.rgb(216, 26, 102, 50), "Bearish", inline = "colors", tooltip = t8, group = gColors)
alertNewBull = input.bool(true, "New Bullish FVG", tooltip = t9, group = gAlerts)
alertNewBear = input.bool(true, "New Bearish FVG", tooltip = t10, group = gAlerts)
alertTopRank = input.bool(true, "New Top-Ranked FVG", tooltip = t11, group = gAlerts)
alertBullTouch = input.bool(true, "Bullish FVG Touch", tooltip = t12, group = gAlerts)
alertBearTouch = input.bool(true, "Bearish FVG Touch", tooltip = t13, group = gAlerts)
alertFullyMitigated = input.bool(true, "FVG Fully Mitigated", tooltip = t14, group = gAlerts)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ UDT for each imbalance zone {
type FVG
float qualityScore
float top
float bottom
int direction
int bornBar
int leftTime
float size
float mitigation
float volumeScore
float trendScore
int bullStrength
int bearStrength
box body
box bullBar
box bearBar
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Helpers {
volumeMA = ta.sma(volume, volLength)
trendEMA = ta.ema(close, trendLength)
barMs = timeframe.in_seconds(timeframe.period) * 1000
bullFVG = low > high[2]
bearFVG = high < low[2]
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Create new FVG object {
var array fvgs = array.new()
var string topFvgKey = ""
newBullFvgAlert = false
newBearFvgAlert = false
newTopRankAlert = false
bullTouchAlert = false
bearTouchAlert = false
fullyMitigatedAlert = false
if bullFVG or bearFVG
float top = bullFVG ? low : low[2]
float bottom = bullFVG ? high[2] : high
int direction = bullFVG ? 1 : -1
newBullFvgAlert := direction == 1
newBearFvgAlert := direction == -1
float fvgSize = math.abs(top - bottom)
float volScore = volumeMA != 0 ? volume / volumeMA : 1.0
float trendScore = direction == 1 and close > trendEMA ? 1.0 : direction == -1 and close < trendEMA ? 1.0 : 0.0
float mitigation = 0.0
float qualityScore = fvgSize * 100 + volScore * 10 + trendScore * 20 - mitigation * 50
float gapStrength = math.min(fvgSize / ta.atr(14), 2.0) / 2.0 * 40
float volStrength = math.min(volScore, 2.0) / 2.0 * 30
float trendStrength = trendScore * 20
float candleStrength = math.abs(close - open) / math.max(high - low, syminfo.mintick) * 10
float totalStrength = gapStrength + volStrength + trendStrength + candleStrength
int mainStrength = int(math.max(math.min(totalStrength, 100), 0))
int bullStrength = direction == 1 ? mainStrength : 100 - mainStrength
int bearStrength = direction == -1 ? mainStrength : 100 - mainStrength
color bodyColor = direction == 1 ? bullColor : bearColor
int leftTime = time[2]
int rightTime = time + barMs * 5
box body = box.new(
left = leftTime,
right = rightTime,
top = top,
bottom = bottom,
xloc = xloc.bar_time,
bgcolor = color.new(bodyColor, 70),
border_color = na
)
float mid = math.avg(top, bottom)
box bearBar = box.new(
left = leftTime,
right = leftTime,
top = top,
bottom = mid,
xloc = xloc.bar_time,
bgcolor = bearColor,
border_color = chart.bg_color
)
box bullBar = box.new(
left = leftTime,
right = leftTime,
top = mid,
bottom = bottom,
xloc = xloc.bar_time,
bgcolor = bullColor,
border_color = chart.bg_color
)
fvgs.push(FVG.new(
qualityScore,
top,
bottom,
direction,
bar_index,
leftTime,
fvgSize,
mitigation,
volScore,
trendScore,
bullStrength,
bearStrength,
body,
bullBar,
bearBar
))
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Update existing FVGs {
if fvgs.size() > 0
for i = fvgs.size() - 1 to 0
FVG fvg = fvgs.get(i)
int age = bar_index - fvg.bornBar
bool touched = fvg.direction == 1 ? low <= fvg.top : high >= fvg.bottom
bullTouchAlert := bullTouchAlert or (touched and fvg.direction == 1)
bearTouchAlert := bearTouchAlert or (touched and fvg.direction == -1)
if touched
float fillDistance = fvg.direction == 1 ? fvg.top - low : high - fvg.bottom
float zoneSize = math.max(fvg.top - fvg.bottom, syminfo.mintick)
fvg.mitigation := math.min(math.max(fillDistance / zoneSize, 0), 1)
fvg.qualityScore := fvg.size * 100 + fvg.volumeScore * 10 + fvg.trendScore * 20 - fvg.mitigation * 50 - age * 0.1
box.set_right(fvg.body, time + barMs * 25)
if fvg.mitigation >= 1
fullyMitigatedAlert := true
box.delete(fvg.body)
box.delete(fvg.bullBar)
box.delete(fvg.bearBar)
fvgs.remove(i)
else
fvgs.set(i, fvg)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Sort FVGs by quality score {
fvgs.sort(order.descending, sort_field = "qualityScore")
if fvgs.size() > 0
FVG topFvg = fvgs.get(0)
string currentTopKey = str.tostring(topFvg.leftTime) + "_" + str.tostring(topFvg.direction)
newTopRankAlert := currentTopKey != topFvgKey
topFvgKey := currentTopKey
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Limit stored zones {
while fvgs.size() > maxStored
FVG removed = fvgs.pop()
box.delete(removed.body)
box.delete(removed.bullBar)
box.delete(removed.bearBar)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Show only top zones {
if fvgs.size() > 0
for i = 0 to fvgs.size() - 1
FVG fvg = fvgs.get(i)
bool showZone = i < maxZones
color bodyColor = fvg.direction == 1 ? bullColor : bearColor
int left = fvg.leftTime
int right = time + barMs * 25
int width = right - left
int sizeUnit = math.max(int(width / 200), 1)
float top = box.get_top(fvg.body)
float bot = box.get_bottom(fvg.body)
float mid = math.avg(top, bot)
box.set_bgcolor(fvg.body, showZone ? color.new(bodyColor, 70) : color.new(color.gray, 100))
box.set_border_color(fvg.body, na)
box.set_right(fvg.body, right)
if showZone and showBars
box.set_left(fvg.bearBar, left)
box.set_right(fvg.bearBar, left + sizeUnit * fvg.bearStrength)
box.set_top(fvg.bearBar, top)
box.set_bottom(fvg.bearBar, mid)
box.set_bgcolor(fvg.bearBar, bearColor)
box.set_border_color(fvg.bearBar, chart.bg_color)
box.set_text(fvg.bearBar, str.tostring(fvg.bearStrength, format.percent))
box.set_text_color(fvg.bearBar, chart.fg_color)
box.set_text_halign(fvg.bearBar, text.align_right)
box.set_text_size(fvg.bearBar, strengthTextSize)
box.set_left(fvg.bullBar, left)
box.set_right(fvg.bullBar, left + sizeUnit * fvg.bullStrength)
box.set_top(fvg.bullBar, mid)
box.set_bottom(fvg.bullBar, bot)
box.set_bgcolor(fvg.bullBar, bullColor)
box.set_border_color(fvg.bullBar, chart.bg_color)
box.set_text(fvg.bullBar, str.tostring(fvg.bullStrength, format.percent))
box.set_text_color(fvg.bullBar, chart.fg_color)
box.set_text_halign(fvg.bullBar, text.align_right)
box.set_text_size(fvg.bullBar, strengthTextSize)
string labelText = ""
if fvg.direction == -1 // Bearish FVG
if fvg.bearStrength >= 70
labelText := "Strong Bearish Imbalance"
else if fvg.bearStrength >= 55
labelText := "Bearish Bias"
else if fvg.bullStrength > fvg.bearStrength
labelText := "Weak Bearish (Bull Pressure)"
else
labelText := "Neutral Bearish"
else // Bullish FVG
if fvg.bullStrength >= 70
labelText := "Strong Bullish Imbalance"
else if fvg.bullStrength >= 55
labelText := "Bullish Bias"
else if fvg.bearStrength > fvg.bullStrength
labelText := "Weak Bullish (Bear Pressure)"
else
labelText := "Neutral Bullish"
box.set_text(fvg.body, showBlockText ? labelText : "")
box.set_text_halign(fvg.body, text.align_right)
box.set_text_color(fvg.body, chart.bg_color)
box.set_text_size(fvg.body, blockTextSize)
else
box.set_bgcolor(fvg.bullBar, color.new(color.gray, 100))
box.set_bgcolor(fvg.bearBar, color.new(color.gray, 100))
box.set_border_color(fvg.bullBar, color.new(color.gray, 100))
box.set_border_color(fvg.bearBar, color.new(color.gray, 100))
box.set_text(fvg.bullBar, "")
box.set_text(fvg.bearBar, "")
box.set_text(fvg.body, "")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Alerts {
alertcondition(alertNewBull and newBullFvgAlert, "New Bullish FVG", "A new bullish FVG has formed.")
alertcondition(alertNewBear and newBearFvgAlert, "New Bearish FVG", "A new bearish FVG has formed.")
alertcondition(alertTopRank and newTopRankAlert, "New Top-Ranked FVG", "A new FVG has become the highest-ranked zone.")
alertcondition(alertBullTouch and bullTouchAlert, "Bullish FVG Touch", "Price has touched or started mitigating a bullish FVG.")
alertcondition(alertBearTouch and bearTouchAlert, "Bearish FVG Touch", "Price has touched or started mitigating a bearish FVG.")
alertcondition(alertFullyMitigated and fullyMitigatedAlert, "FVG Fully Mitigated", "An FVG has been fully mitigated and removed.")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
Indicator Insider

04/02/026 Cup & Handle
Isolated Scroll Container 1. Cup & Handle Indicator Description (Zeiierman) An indicator that automatically detects the Cup & Handle pattern – one of the most classic chart patterns in technical analysis 1.1 Indicator Concept The Cup & Handle indicator is based on the theory of market psychology patterns discovered by

27/01/026 Spring & Upthrust Trap
Backtest analysis of Spring & Upthrust Trap strategy: 34.9% win rate, +4.95% profit, 2.021 profit factor. Complete guide to optimal settings and risk management.

Smart Money Concepts Pro – OB, FVG, Liquidity + Trade Setups
The indicator follows Smart Money Concepts (SMC): price moves because of supply–demand imbalances and the hunt for liquidity. From there, we focus on four key pillars:
Order Block (OB): institutional order zones; price often retests them before continuing.
Fair Value Gap (FVG): a 3-candle void showing imbalance; price tends


