OPEN-SOURCE SCRIPT

Fair Value Gap Signals [Kodexius]

493
Fair Value Gap Signals is an advanced market structure tool that automatically detects and tracks Fair Value Gaps (FVGs), evaluates the quality of each gap, and highlights high value reaction zones with visual metrics and signal markers.

The script is designed for traders who focus on liquidity concepts, order flow and mean reversion. It goes beyond basic FVG plotting by continuously monitoring how price interacts with each gap and by quantifying three key aspects of each zone:

-Entry velocity inside the gap
-Volume absorption during tests
-Structural integrity and depth of penetration


The result is a dynamic, information rich visualization of which gaps are being respected, which are being absorbed, and where potential reversals or continuations are most likely to occur.

All visual elements are configurable, including the maximum number of visible gaps per direction, mitigation method (close or wick) and an ATR based filter to ignore insignificant gaps in low volatility environments.

snapshot

🔹 Features

🔸 Automated Fair Value Gap Detection

The script detects both bullish and bearish FVGs based on classic three candle logic:

Bullish FVG: current low is strictly above the high from two bars ago

Bearish FVG: current high is strictly below the low from two bars ago

🔸 ATR Based Gap Filter

To avoid clutter and low quality signals, the script can ignore very small gaps using an ATR based filter.

🔸Per Gap State Machine and Lifecycle

Each gap is tracked with an internal status:

Fresh: gap has just formed and has not been tested

Testing: price is currently trading inside the gap

Tested: gap was tested and left, waiting for a potential new test

Rejected: price entered the gap and then rejected away from it

Filled: gap is considered fully mitigated and no longer active

This state machine allows the script to distinguish between simple touches, multiple tests and meaningful reversals, and to trigger different alerts accordingly.

🔸 Visual Ranking of Gaps by Metrics

For each active gap, three additional horizontal rank bars are drawn on top of the gap area:

Rank 1 (Vel): maximum entry velocity inside the gap

Rank 2 (Vol): relative test volume compared to average volume

Rank 3 (Dpt): remaining safety of the gap based on maximum penetration depth

These rank bars extend horizontally from the creation bar, and their length is a visual score between 0 and 1, scaled to the age of the gap. Longer bars represent stronger or more favorable conditions.

snapshot

🔸Signals and Rejection Markers

When a gap shows signs of rejection (price enters the gap and then closes away from it with sufficient activity), the script can print a signal label at the reaction point. These markers summarize the internal metrics of the gap using a tooltip:

-Velocity percentage
-Volume percentage
-Safety score
-Number of tests


snapshot

snapshot

🔸 Flexible Mitigation Logic (Close or Wick)

You can choose how mitigation is defined via the Mitigation Method input:

Close: the gap is considered filled only when the closing price crosses the gap boundary

Wick: a full fill is detected as soon as any wick crosses the gap boundary

🔸 Alert Conditions

-New FVG formed
-Price entering a gap (testing)
-Gap fully filled and invalidated
-Rejection signal generated


🔹Calculations

This section summarizes the main calculations used under the hood. Only the core logic is covered.

1. ATR Filter and Gap Size

The script uses a configurable ATR length to filter out small gaps. First the ATR is computed:

Pine Script®
float atrVal = ta.atr(atrLength)


Gap size for both directions is then measured:

Pine Script®
float gapSizeBull = low - high[2] float gapSizeBear = low[2] - high


If useAtrFilter is enabled, gaps smaller than atrVal are ignored. This ties the minimum gap size to the current volatility regime.

2. Fair Value Gap Detection

The basic FVG conditions use a three bar structure:

Pine Script®
bool fvgBull = low > high[2] bool fvgBear = high < low[2]


For bullish gaps the script stores:

-top as low of the current bar
-bottom as high[2]

For bearish gaps:

-top as high of the current bar
-bottom as low[2]

This defines the price range that is considered the imbalance area.

3. Depth and Safety Score

Depth measures how far price has penetrated into the gap since its creation. For each bar, the script computes a currentDepth and updates the maximum depth:

Pine Script®
float currentDepth = 0.0 if g.isBullish if l < g.top currentDepth := g.top - l else if h > g.bottom currentDepth := h - g.bottom if currentDepth > g.maxDepth g.maxDepth := currentDepth


The safety score expresses how much of the gap remains intact:

Pine Script®
float depthRatio = g.maxDepth / gapSize float safetyScore = math.max(0.0, 1.0 - depthRatio)


safetyScore near 1: gap is mostly untouched

safetyScore near 0: gap is mostly or fully filled

4. Velocity Metric

Velocity captures how aggressively price moves inside the gap. It is based on the body to range ratio of each bar that trades within the gap and rewards bars that move in the same direction as the gap:

Pine Script®
float barRange = h - l float bodyRatio = math.abs(close - open) / barRange float directionBonus = 0.0 if g.isBullish and close > open directionBonus := 0.2 else if not g.isBullish and close < open directionBonus := 0.2 float currentVelocity = math.min(bodyRatio + directionBonus, 1.0)


The gap keeps track of the strongest observed value:

Pine Script®
if currentVelocity > g.maxVelocity g.maxVelocity := currentVelocity


This maximum is later used as velScore when building the velocity rank bar.

5. Volume Accumulation and Volume Score

While price is trading inside a gap, the script accumulates the traded volume:

Pine Script®
if isInside g.testVolume += volume


It also keeps track of the number of tests and the volume at the start of the first test:

Pine Script®
if g.status == "Fresh" g.status := "Testing" g.testCount := 1 g.testStartVolume := volume


An average volume is computed using a 20 period SMA:

Pine Script®
float volAvg = ta.sma(volume, 20)


The expected volume is approximated as:

Pine Script®
float expectedVol = volAvg * math.max(1, (bar_index - g.index) / 2)


The volume score is then:

Pine Script®
float volScore = math.min(g.testVolume / expectedVol, 1.0)


This produces a normalized 0 to 1 metric that shows whether the gap has attracted more or less volume than expected over its lifetime.

6. Rank Bar Scaling

All three scores are projected visually along the time axis as horizontal bars. The script uses the age of the gap in bars as the maximum width:

Pine Script®
float maxWidth = math.max(bar_index - g.index, 1)


Then each metric is mapped to a bar length:

Pine Script®
int len1 = int(math.max(1, maxWidth * velScore)) g.rankBox1.set_right(g.index + len1) int len2 = int(math.max(1, maxWidth * volScore)) g.rankBox2.set_right(g.index + len2) int len3 = int(math.max(1, maxWidth * safetyScore)) g.rankBox3.set_right(g.index + len3)


This creates an intuitive visual representation where stronger metrics produce longer rank bars, making it easy to quickly compare the relative quality of multiple FVGs on the chart.

Clause de non-responsabilité

Les informations et publications ne sont pas destinées à être, et ne constituent pas, des conseils ou recommandations financiers, d'investissement, de trading ou autres fournis ou approuvés par TradingView. Pour en savoir plus, consultez les Conditions d'utilisation.