OPEN-SOURCE SCRIPT
Unmitigated Gaps by Midniteblade

4H Unmitigated Gaps — Build Summary
A Pine Script indicator that finds and draws unmitigated Fair Value Gaps (FVGs) on the 4H timeframe, from any chart timeframe you're viewing.
What it does
An FVG is a three-candle imbalance — a move so fast that price left a gap no two-way auction filled. The script looks for two kinds:
Bullish FVG — candle 3's low is above candle 1's high (l3 > h1). Price skipped up; the gap sits below.
Bearish FVG — candle 3's high is below candle 1's low (h3 < l1). Price skipped down; the gap sits above.
Each gap is drawn as a box and stays on the chart until price trades back through it ("mitigated"). The info table reports live counts, the nearest gap above/below price, and the stored 4H period data.
The three bugs we hit — and why each mattered
1. max_bars_back rejected built-in series. The script needed deep history for dynamic indexing. Pine refused max_bars_back(volume, 5000) because volume, close, open, hlc3 are built-ins — the parameter needs a user-declared series. Fix: assign each to a variable first, then declare.
2. The history buffer was keyed to the wrong variable. This is the subtle one. We declared history on the new variables — but the loop still indexed volume[...], close[...] directly. Pine sizes its buffer for the exact series you reference, so the declarations did nothing and the runtime error came back. Fix: swap every dynamic index in the loop to the declared variables.
Lesson: declaring max_bars_back on a variable only helps if that variable is what you actually index. The declaration follows the reference, not the value.
3. The live test compared a bar against itself. The ongoing check read candle 3 from the n-1 slot while also treating the live bar as a separate candle — but those were the same bar. It could never detect a new gap. Fix: compare the newest stored period against the two before it, so all three candles are genuinely distinct.
Lesson: when a test returns zero forever, check whether its inputs are actually independent before assuming the market is quiet. A debug row showing the raw stored values is what exposed this.
Debug technique worth stealing
We added a table row printing the last three stored htfH/htfL pairs — [n-3 | n-2 | n-1]. That single row let us verify the array was storing sane values and cross-check them against the table's own "Cur/Prev period" rows. When the numbers matched, the storage was proven correct; when the live test still failed, the bug had to be in the comparison logic.
Print your raw inputs, not just your outputs. An output of 0 tells you nothing. The inputs tell you why.
Takeaway
Three separate bugs, each hidden behind the last. The first fix looked like it worked until the second surfaced; the second looked complete until the third appeared. Debugging in sequence — fix, re-run, read the new error — is what got there. Skipping verification after a fix would have left all three in place.
A Pine Script indicator that finds and draws unmitigated Fair Value Gaps (FVGs) on the 4H timeframe, from any chart timeframe you're viewing.
What it does
An FVG is a three-candle imbalance — a move so fast that price left a gap no two-way auction filled. The script looks for two kinds:
Bullish FVG — candle 3's low is above candle 1's high (l3 > h1). Price skipped up; the gap sits below.
Bearish FVG — candle 3's high is below candle 1's low (h3 < l1). Price skipped down; the gap sits above.
Each gap is drawn as a box and stays on the chart until price trades back through it ("mitigated"). The info table reports live counts, the nearest gap above/below price, and the stored 4H period data.
The three bugs we hit — and why each mattered
1. max_bars_back rejected built-in series. The script needed deep history for dynamic indexing. Pine refused max_bars_back(volume, 5000) because volume, close, open, hlc3 are built-ins — the parameter needs a user-declared series. Fix: assign each to a variable first, then declare.
2. The history buffer was keyed to the wrong variable. This is the subtle one. We declared history on the new variables — but the loop still indexed volume[...], close[...] directly. Pine sizes its buffer for the exact series you reference, so the declarations did nothing and the runtime error came back. Fix: swap every dynamic index in the loop to the declared variables.
Lesson: declaring max_bars_back on a variable only helps if that variable is what you actually index. The declaration follows the reference, not the value.
3. The live test compared a bar against itself. The ongoing check read candle 3 from the n-1 slot while also treating the live bar as a separate candle — but those were the same bar. It could never detect a new gap. Fix: compare the newest stored period against the two before it, so all three candles are genuinely distinct.
Lesson: when a test returns zero forever, check whether its inputs are actually independent before assuming the market is quiet. A debug row showing the raw stored values is what exposed this.
Debug technique worth stealing
We added a table row printing the last three stored htfH/htfL pairs — [n-3 | n-2 | n-1]. That single row let us verify the array was storing sane values and cross-check them against the table's own "Cur/Prev period" rows. When the numbers matched, the storage was proven correct; when the live test still failed, the bug had to be in the comparison logic.
Print your raw inputs, not just your outputs. An output of 0 tells you nothing. The inputs tell you why.
Takeaway
Three separate bugs, each hidden behind the last. The first fix looked like it worked until the second surfaced; the second looked complete until the third appeared. Debugging in sequence — fix, re-run, read the new error — is what got there. Skipping verification after a fix would have left all three in place.
Script open-source
Dans l'esprit TradingView, le créateur de ce script l'a rendu open source afin que les traders puissent examiner et vérifier ses fonctionnalités. Bravo à l'auteur! Bien que vous puissiez l'utiliser gratuitement, n'oubliez pas que la republication du code est soumise à nos Règles.
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.
Script open-source
Dans l'esprit TradingView, le créateur de ce script l'a rendu open source afin que les traders puissent examiner et vérifier ses fonctionnalités. Bravo à l'auteur! Bien que vous puissiez l'utiliser gratuitement, n'oubliez pas que la republication du code est soumise à nos Règles.
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.