Индикатор

SOXL Breakout# SOXL Breakout — Intraday Breakout Levels & Position Sizing
## What It Does
SOXL Breakout is a day-trading overlay indicator designed for leveraged ETFs (SOXL, TQQQ, etc.) on the **5-minute timeframe**. It automatically plots key price levels each morning and tracks position sizing and P&L across two independent accounts.
## How It Works
Every trading day at **09:25 EST**, the indicator captures the open of that candle and draws three levels:
- **OPEN** — the 09:25 candle's open price (white solid line)
- **TRIGGER** — a configurable percentage above the open (green dashed line, default +1.41%). This is your **buy signal**. When price touches this level during RTH, the indicator enters a simulated long position.
- **STOP LOSS** — a configurable percentage below the trigger (red dashed line, default -8%). If price drops to this level while in a position, the trade is closed at a loss.
### Trade Lifecycle
1. **09:25 EST** — Levels are drawn for the day.
2. **During RTH (09:30–16:00)** — If price hits the TRIGGER, a position is entered at the trigger price. Shares are calculated based on your account size and deploy percentage, rounded down to the nearest 100 shares.
3. **Stop Loss** — If price hits the stop-loss level at any time while in a position (including pre-market the next day), the position is closed.
4. **09:20 EST (next day)** — If still in a position, it is auto-sold at the open price. This is the default exit.
### SOXS (Inverse) Entry
An optional feature for hedging or inverse plays. When enabled, if the TRIGGER was **never hit** during RTH on Monday, Thursday, or Friday, a **SOXS ENTRY** line is drawn at the 15:55 closing price. This signals a potential inverse (bearish) entry.
## The Position Sizing Table
A live overlay table displays:
| Row | Description |
|---|---|
| **Account** | Current account balance (seed + cumulative P&L). Shows before/after transition on trade close. |
| **Running P&L** | Live dollar P&L while in a position, or locked P&L after exit. |
| **Status** | Current state: Waiting, Acct updated, In position, Sold - gain, Sold - loss, Stopped out. |
| **Shares** | Number of shares to trade based on account size, deploy %, and trigger price. |
| **Risk** | Dollar risk and percentage risk per account if stopped out. |
The table supports **two independent accounts** — useful for tracking separate portfolios or different position sizes side by side.
## Settings
### Open Candle Time
- **Open Candle Hour/Minute (EST)** — When to capture the reference candle (default: 09:25)
- **Trigger % above Open** — Percentage above open for the buy trigger (default: 1.41%)
- **Stop Loss % below Trigger** — Percentage below trigger for the stop loss (default: 8.0%)
### Line Colours
- Customize colors for the OPEN, TRIGGER, and STOP LOSS lines.
### SOXS Entry
- **Enable SOXS Entry** — Toggle the inverse entry line feature.
- **SOXS ENTRY colour** — Color for the SOXS entry line.
### Account 1 / Account 2
- **Account Name** — Label shown in the table header.
- **Starting Account ($)** — Your account seed capital. Changing this resets cumulative P&L.
- **Deploy %** — Percentage of account to deploy per trade (default: 80%).
### Display
- **Table Position** — Where to place the position sizing table on the chart.
## Important Notes
- This indicator is designed for the **5-minute timeframe only**. A warning label will appear if applied to any other timeframe.
- Cumulative P&L only updates on **realtime bars** to avoid inflated backtest results.
- Changing the starting account value resets the cumulative P&L counter.
- Shares are always rounded down to the nearest 100.
- The indicator does **not** place actual trades — it is a visual and analytical tool only.
## Disclaimer
This indicator is for **educational and informational purposes only**. It does not constitute financial advice. Leveraged ETFs carry significant risk, including the potential for substantial losses. Always do your own research and consult a qualified financial advisor before trading. Past performance does not guarantee future results.
Индикатор

Индикатор

Стратегия

Doji Volume Map (Zeiierman)█ Overview
Doji Volume Map (Zeiierman) is a volume reaction scanner that detects doji-like candles appearing with relatively high and rising volume, then converts those events into projected price levels. When a valid signal forms, the script places a bubble on the candle, extends a horizontal reaction level forward, and optionally merges nearby levels into a highlighted zone box. The result is a clean map of potential reaction areas built from high-interest doji events rather than generic swing highs or lows.
⚪ What It Detects
The script searches for candles that combine 3 conditions at the same time:
Relative high volume: Current volume must exceed the average volume by a user-defined multiplier.
Rising volume: Current volume must be greater than the previous bar’s volume.
Loose doji structure: The candle body must remain small relative to the total range, while the full range must still be meaningful enough relative to ATR.
When those conditions align, the candle is treated as a significant reaction point and plotted as a bubble. From there, the script projects the price level forward and can combine overlapping levels into broader zones.
█ How It Works
For each bar inside the Lookback Length, the script checks whether the candle qualifies as a valid signal.
It measures:
Average volume over the selected Volume Average Length
Relative volume strength using the Relative Volume Multiplier
Whether volume is increasing vs the previous bar
Whether the candle body is small enough to be considered doji-like
Whether the total range is large enough relative to ATR
█ How to Use
When a doji-like candle forms with high and rising volume, it signals strong participation but no clear directional control.
This means:
Heavy trading occurred.
Both sides were active.
Price failed to move decisively.
These areas often become key reaction zones, as the market tends to revisit and respond to where significant transactions took place.
⚪ In Trend
In uptrends , signals on pullbacks can act as support/continuation zones
In downtrends, signals on bounces can act as resistance/rejection zones
Focus on using levels in the direction of the trend, where the dominant side is likely to defend.
⚪ In Ranges
Signals near range lows → potential buy/support zones
Signals near range highs → potential sell/resistance zones
Merged zones are especially useful for identifying rotation areas within the range.
⚪ Key Idea
High volume + indecision = high-interest price area
These zones often lead to:
Reactions
Rejections
Or continuation after confirmation
Use retests and price behavior at these levels to guide entries.
█ Settings
Lookback Length — how many bars back the script scans for qualifying signals.
Volume Average Length — baseline used to measure relative volume.
Relative Volume Multiplier — minimum volume expansion required vs average.
Max Body % of Range — defines how small the candle body must be to count as doji-like.
Min Candle Range as ATR Fraction — filters out candles that are too small to matter.
Key effect:
Higher Relative Volume Multiplier = fewer but stronger signals
Lower Max Body % of Range = stricter doji selection
Higher Min Candle Range as ATR Fraction = fewer weak micro-signals
Merge Close Levels Into Box — combines nearby projected levels into a single zone.
Merge Distance (ATR) — controls how close levels must be to merge.
-----------------
Disclaimer
The content provided in my scripts, indicators, ideas, algorithms, and systems is for educational and informational purposes only. It does not constitute financial advice, investment recommendations, or a solicitation to buy or sell any financial instruments. I will not accept liability for any loss or damage, including without limitation any loss of profit, which may arise directly or indirectly from the use of or reliance on such information.
All investments involve risk, and the past performance of a security, industry, sector, market, financial product, trading strategy, backtest, or individual's trading does not guarantee future results or returns. Investors are fully responsible for any investment decisions they make. Such decisions should be based solely on an evaluation of their financial circumstances, investment objectives, risk tolerance, and liquidity needs.
Индикатор

Индикатор

Strong Pinbar Reversals MTF | ProjectSyndicateStrong Pinbar Reversals MTF automatically identifies and power-ranks high-probability reversal opportunities by analyzing clusters of institutional pinbar rejections. It filters for quality, calculates a 0-10 strength score for every reversal cluster based on wick purity, cluster density, and candle momentum, and presents all data on the chart and in a comprehensive multi-timeframe dashboard to eliminate noise and focus on reversals that matter.
• 🎯 Power-Ranking System (0-10) — every pinbar cluster is given a strength score based on a strict 5-dimensional algorithm that assesses cluster size, average wick purity, minimum wick purity, candle range versus ATR, and time density, providing an instant quality assessment.
• 🎨 Strength-Based Color Scheme — reversal zones are colored by their power rank; stronger clusters get darker, more prominent colors for immediate visual hierarchy.
• 🧠 Smart Context Detection — automatically ensures that bullish pinbar clusters only fire at local price lows (support) and bearish clusters only fire at local price highs (resistance), completely filtering out fake signals in mid-range consolidation.
• 📊 On-Chart Statistics — each reversal zone displays its direction (Bullish/Bearish) and its calculated strength score directly inside the shaded zone.
• 🧭 Full MTF Dashboard Display — provides a complete market overview across 7 timeframes (M1, M5, M15, M30, H1, H4, D1), showing the latest reversal signal, its strength, entry/SL/TP levels, and how many bars ago it occurred on that timeframe. The dashboard uses persistent state memory, meaning it is perfectly stable and consistent regardless of the chart you are viewing.
• 🔔 Comprehensive Alerts — get notified the moment a new high-strength cluster occurs, with the alert message containing the full details: direction, strength, entry, SL, and TP levels.
• ✅ Quality Control Filters — a user-configurable minimum strength score (default 6.0) allows you to filter out weak, low-probability wicks and focus only on institutional-grade reversal clusters.
• 🔧 Fully Customizable — control everything from the minimum wick percentage and cluster lookback window to the ADR multipliers for universal zone height and SL/TP placement.
• 🎯 Why this algo is unique: Standard pinbar indicators look at single candles and generate massive amounts of false signals in consolidation. This algorithm looks for clusters of rejection (e.g., 3+ pinbars in a tight window) and uses a multi-factor scoring system to quantify the quality of the rejection. It doesn't just show you a wick; it tells you how strong the institutional absorption is. The MTF dashboard provides a complete, stable cross-timeframe perspective that is impossible to achieve with standard single-timeframe indicators.
• 🚀 Apply to Gold (XAUUSD), Forex, Crypto, and Indices on any timeframe. The wick percentage and cluster size settings allow it to adapt to anything from scalping (M1/M5) to swing trading (H4/D1).
• 🎯 How to use this? Focus on trading opportunities from high-strength reversal clusters rated 7/10 or higher, as these show the highest probability of a structural shift. Use the dashboard to quickly identify which timeframes have active rejection zones, and look for alignment between lower timeframe clusters and higher timeframe support/resistance.
• ⚠️ IMPORTANT NOTICE: This indicator is designed to identify high-probability reversal opportunities based on price action rejection. It should NOT be used as a standalone signal for entering trades. Always use it in conjunction with your own trading strategy, market structure analysis, and other technical indicators to confirm trade setups and manage risk. Индикатор

8:00-8:15 ORB Retest on 5m Time Frame v1.3 by Alf_AlgoORB Retest on 5m Time Frame
Breakout → Retest → Confirm → Enter
A structured session indicator designed to trade continuation after an opening range breakout using midpoint retests and confirmation.
Opening Range defines session structure
Breakout sets directional bias (with multiple detection modes)
Midpoint retest provides entry location
Momentum confirmation triggers signals
Triple ATR-based TP levels and structure-based SL manage risk
The system avoids chasing breakouts and instead waits for price acceptance and momentum confirmation.
━━━━━━━━━━━━━━━━━━━━━━━━
Timeframe
Pine Script®
Designed exclusively for the 5-minute chart.
The opening range is built using the first three 5-minute candles.
━━━━━━━━━━━━━━━━━━━━━━━━
Opening Range Levels
OR High — upper boundary (teal)
OR Low — lower boundary (red)
OR Midpoint — primary retest level (amber, dashed)
Shaded zone between High and Low for visual clarity
The midpoint acts as the primary retest level for entries.
━━━━━━━━━━━━━━━━━━━━━━━━
Breakout Direction Mode (New in v1.2)
Four modes to determine how directional bias is set after the opening range:
First Break — original behavior; whichever direction breaks out first locks the bias
Last Break — bias updates with each new breakout before the entry window opens, capturing the final sentiment
Strongest Break — the breakout with the largest candle body wins; more conviction = more significant
Directional Preference — manually select Bullish or Bearish; bias is set when the OR locks regardless of price action
For Last Break and Strongest Break modes, triangle markers appear on the chart each time the bias flips, so you can visually track the tug-of-war between bulls and bears before the entry window.
━━━━━━━━━━━━━━━━━━━━━━━━
Bias Logic
Close above OR High → Bullish Bias
Close below OR Low → Bearish Bias
Depending on the selected Breakout Direction Mode, the bias may lock on the first break, update with subsequent breaks, follow the strongest candle body, or be manually chosen.
━━━━━━━━━━━━━━━━━━━━━━━━
Entry Logic
Wait for midpoint retest
Require confirmation
Signal triggers within the active session window
Three confirmation modes are available:
Retest Close Reclaim
Break Retest Candle
Hybrid (default)
━━━━━━━━━━━━━━━━━━━━━━━━
Risk Management — Triple TP System (New in v1.2)
Three take-profit levels are automatically calculated using ATR, all shown on the chart from the moment a signal fires:
TP1 — 2× ATR (default) — solid line
TP2 — 3× ATR (default) — dashed line
TP3 — 5× ATR (default) — dotted line
SL — structure-based, remains fixed throughout the trade
Each TP and SL level gets a label when hit (TP1 ✓, TP2 ✓, TP3 ✓, SL ✗), so you can see exactly where targets were reached or where the stop was triggered. All ATR multipliers are fully adjustable in the settings.
Alert conditions are available for each individual TP hit and SL hit.
━━━━━━━━━━━━━━━━━━━━━━━━
Chart Elements
Opening Range High / Low / Mid with shaded zone
Breakout markers (triangles)
Retest markers (diamonds)
Buy / Sell signal labels
TP1 / TP2 / TP3 and SL levels with hit labels
On-chart dashboard with full state tracking
━━━━━━━━━━━━━━━━━━━━━━━━
Dashboard
The on-chart dashboard displays real-time state:
Session preset
Breakout Direction Mode
First break direction
Current bias
Retest status
Signal status
Confirmation mode
Individual TP1 / TP2 / TP3 and SL hit status
TP ATR multiplier values
━━━━━━━━━━━━━━━━━━━━━━━━
Typical Workflow
Apply on a 5-minute chart
Select your session and breakout direction mode
Allow opening range to form
Observe breakout(s) and bias assignment
Wait for midpoint retest
Enter after confirmation
Monitor TP1 → TP2 → TP3 progression
━━━━━━━━━━━━━━━━━━━━━━━━
v1.2 Release Notes
Added Breakout Direction Mode with four options: First Break, Last Break, Strongest Break, Directional Preference
Added triple take-profit system (TP1, TP2, TP3) with independent ATR multipliers
TP and SL hit labels appear on chart when each level is reached
Added alert conditions for each TP hit and SL hit
Styled OR lines with updated color palette (teal / red / amber)
Added shaded zone between OR High and Low
Updated dashboard with Breakout Direction Mode, individual TP status, and ATR multiplier display
v1.1 Release Notes
Added ORB session selection (New York, London, Asia)
Replaced breakout text labels with directional triangle icons
Replaced retest text labels with diamond icons
Added on-chart dashboard
Dashboard now shows directional state instead of checkmarks
Added Buy / Sell signal display in dashboard
Added color-coded dashboard values (green bullish, red bearish)
Updated Buy/Sell signal label colors
Added TP / SL outcome tracking in dashboard
━━━━━━━━━━━━━━━━━━━━━━━━
Feedback
This script is shared publicly to help traders study structured opening range continuation setups.
Feedback and suggestions are welcome
Ideas for improvements or additional features are appreciated
Индикатор

Индикатор

Индикатор

Индикатор

Индикатор

Range Zones AlertsRange Zones — Buy the Green, Sell the Red
Get alerted when price enters a buy zone or a sell zone.
This indicator detects the current trading range, splits it into three color-coded zones, and sends you an alert the moment price touches the zone you care about. No guessing where support and resistance are — the indicator finds them for you.
Green Zone = Buy Zone
The bottom third of the range is shaded green. This is where price has historically found support. When price drops into the green, buyers tend to step in. Set up the Bull alert and get notified the instant price touches this zone — that's your signal to start looking for a long entry.
Red Zone = Sell Zone
The top third of the range is shaded pink/red. This is where price has historically hit resistance. When price pushes into the red, sellers tend to step in. Set up the Bear alert and get notified the instant price touches this zone — that's your signal to start looking for a short entry or to take profits on longs.
Blue Zone = No Trade Zone
The middle third is shaded blue. Price is stuck between support and resistance with no clear edge in either direction. When price is in the blue, wait.
Alerts
Three options in TradingView's alert panel:
— Bull Alert: fires when price touches the green support zone.
— Bear Alert: fires when price touches the red resistance zone.
— Both: fires on either — one alert covers everything.
A built-in cooldown (default 20 bars) prevents spam. You get one alert per zone touch, then silence until the cooldown clears. Bull and bear cooldowns are independent — a green zone alert won't block a red zone alert.
How It Works
The indicator uses pivot-based swing detection to find the most recent significant high and low. The range between them is divided into three equal horizontal zones. The zones update automatically as new swing highs and lows form. A Max Range Age setting ensures stale, outdated ranges are dropped.
Settings
— Pivot Strength: how significant the swing points need to be. Default 20. Higher = wider ranges.
— Max Range Age: how old the range can be before it's dropped. Default 300 bars.
— Alert Cooldown: bars of silence after an alert fires. Default 20.
— Zone Colors: fully customizable.
Works on any ticker, any timeframe. Add it to your chart, set up your alerts, and let the zones tell you when it's time to trade. Индикатор

Candle DNA Strand█ CANDLE DNA STRAND
A unique lower-panel indicator that visualizes candle structure as a stylized double-helix pattern. One strand represents body dominance (open-close range) while the other represents wick proportion (shadow-to-body ratio). The strands twist around a center axis with color encoding for bullish/bearish bias, revealing candle character patterns over time in an intuitive DNA-inspired format.
█ CONCEPT
Traditional candlestick analysis focuses on individual candle patterns. The Candle DNA Strand takes a different approach by decomposing every candle into two core metrics and plotting them as intertwined waves:
• Body Strand — Measures how much of each candle is "body" (the filled portion between open and close). High body ratios indicate conviction and directional commitment.
• Wick Strand — Measures how much of each candle is "shadow" (upper and lower wicks combined). High wick ratios indicate rejection, indecision, or failed attempts at direction.
These two strands are phase-offset by 180° to create the classic double-helix DNA appearance. As you scroll through the chart, you can visually identify periods of conviction (body-dominant) versus indecision (wick-dominant), and how candle character evolves over time.
█ HOW IT WORKS
The indicator calculates two normalized ratios for each candle:
Body Ratio = |Close - Open| / (High - Low)
Wick Ratio = (Upper Wick + Lower Wick) / (High - Low)
These ratios are smoothed and then modulated onto sine waves that twist around a center axis at the 50 level. The amplitude of each strand reflects the strength of that metric — larger bodies push the body strand further from center, and larger wicks push the wick strand further out.
The strands are color-coded by the current candle's bias:
• Bullish candles (close ≥ open) → Neon green tones
• Bearish candles (close < open) → Neon red tones
█ TRADE ZONES
The indicator includes an optional Trade Zone detection system based on candle character analysis:
◉ LONG ZONE (Green Background)
Triggers when:
• Average body ratio exceeds the Body Dominance Threshold (default 65%)
• Bullish momentum score > 40% (more bulls than bears in lookback period)
• Average wick ratio below the Wick Rejection Threshold (default 55%)
This identifies periods where price is moving up with conviction — strong bullish bodies with minimal rejection wicks.
◉ SHORT ZONE (Red Background)
Triggers when:
• Average body ratio exceeds the Body Dominance Threshold
• Bearish momentum score > 40% (more bears than bulls in lookback period)
• Average wick ratio below the Wick Rejection Threshold
This identifies periods where price is moving down with conviction — strong bearish bodies with minimal rejection wicks.
◉ CHOP/INDECISION
When the average wick ratio exceeds 60%, the market is showing high rejection and indecision. The DNA strands will show wick dominance during these periods.
Triangle markers appear at zone entry points:
• ▲ Green triangle below the helix = Long zone entry
• ▼ Red triangle above the helix = Short zone entry
█ VISUAL ELEMENTS
DNA Strands
Two intertwined lines representing body and wick ratios, twisting around the center axis with a configurable wavelength.
Base Pair Connectors
Vertical lines connecting the two strands at regular intervals, mimicking the "rungs" of a DNA ladder. These help visualize the spread between body and wick metrics.
Nucleotide Nodes
Small circular markers along each strand showing individual data points.
Fill Zone
Subtle gradient fill between the strands for visual depth. The fill color matches whichever strand is currently on top.
Info Label
Displays current values at the right edge of the chart:
• Current bias (BULL/BEAR)
• Body and Wick percentages
• Active trade zone (if any)
█ PATTERN DETECTION
The indicator automatically detects significant candle patterns based on DNA metrics:
DOJI — Body ratio < 15%
Very small body relative to total range. Indicates indecision.
MARUBOZU — Body ratio > 85%
Almost no wicks. Strong conviction candle with price closing near the high (bullish) or low (bearish).
HAMMER — Wick ratio > 60% with lower wick > 2× upper wick
Long lower shadow showing rejection of lower prices.
SHOOTING STAR — Wick ratio > 60% with upper wick > 2× lower wick
Long upper shadow showing rejection of higher prices.
█ SETTINGS
DNA Helix Settings
• Helix Wavelength — Number of bars for one complete DNA twist cycle (default: 20)
• Helix Amplitude — Vertical spread of the strands from center (default: 35)
• Show Base Pair Connectors — Toggle the connecting rungs (default: On)
• Connector Frequency — Draw a connector every N bars (default: 2)
• Data Smoothing — SMA length for smoothing ratios (default: 3)
• Strand Thickness — Line width for the DNA strands (default: 2)
Trade Zone Settings
• Show Trade Zones — Toggle background highlighting and entry signals (default: On)
• Zone Lookback — Bars to analyze for zone detection (default: 5)
• Body Dominance Threshold — Minimum avg body ratio for zone trigger (default: 0.65)
• Wick Rejection Threshold — Maximum avg wick ratio for zone trigger (default: 0.55)
Fluorescent Colors
• Bullish colors — Neon green and electric green variants
• Bearish colors — Neon red and hot pink variants
• Axis, connector, and zone colors are all customizable
Visual Settings
• Show Nucleotide Nodes — Toggle the small circles on strands (default: On)
• Show Info Labels — Toggle the right-side information label (default: On)
• Show DNA Analysis Table — Toggle detailed analysis table (default: Off)
█ ALERTS
Four alert conditions are available:
1. Long Zone Entry
"Entered LONG zone - strong bullish momentum with conviction candles"
2. Short Zone Entry
"Entered SHORT zone - strong bearish momentum with conviction candles"
3. Doji Pattern
"Doji detected - indecision"
4. Marubozu Pattern
"Marubozu detected - strong conviction"
█ INTERPRETATION GUIDE
Reading the DNA:
When body strand dominates (further from center):
• Market is moving with conviction
• Candles have strong bodies, minimal wicks
• Trend is likely to continue
When wick strand dominates (further from center):
• Market is showing rejection/indecision
• Candles have long shadows relative to bodies
• Potential reversal or consolidation
Strand crossovers:
• When strands cross, character is shifting
• Body crossing above wick → increasing conviction
• Wick crossing above body → increasing indecision
Color consistency:
• Long stretches of green → sustained bullish pressure
• Long stretches of red → sustained bearish pressure
• Alternating colors → choppy, mixed market
█ BEST PRACTICES
1. Use with price context — The DNA strand shows candle character, not direction. Combine with price action on the main chart.
2. Adjust wavelength to timeframe — Shorter wavelengths (10-15) for scalping, longer wavelengths (25-40) for swing trading.
3. Trade zones are filters, not signals — Use zone entries as confirmation for your existing strategy, not as standalone signals.
4. Watch for character shifts — When the dominant strand changes, market behavior is changing. This often precedes reversals.
5. Multiple timeframe analysis — Check DNA character on higher timeframes to understand the broader context.
█ CREDITS
Developed by Hash Capital Research
Pine Script™ v6
This indicator is provided for educational and informational purposes. Always conduct your own analysis and manage risk appropriately. Индикатор

Индикатор

Индикатор

Statistical Candle Patterns [QuantRegime]## Overview
Most candle pattern indicators just label patterns on your chart. This one goes further — it **backtests every pattern against the actual chart history** and shows you the **real win rate** for each pattern on the specific instrument and timeframe you're trading.
A "Bullish Engulfing" might have a 68% win rate on BTC 4H but only 42% on EUR/USD 15m. This indicator tells you the difference. **Stop guessing which patterns work — measure them.**
## 12 Patterns Detected
| Pattern | Type | What It Signals |
|---------|------|----------------|
| **Bullish Engulfing** | Bullish | New candle fully engulfs previous bearish candle |
| **Bearish Engulfing** | Bearish | New candle fully engulfs previous bullish candle |
| **Hammer** | Bullish | Long lower wick, small body at top — rejection of lows |
| **Shooting Star** | Bearish | Long upper wick, small body at bottom — rejection of highs |
| **Doji** | Neutral | Tiny body — indecision, potential reversal |
| **Morning Star** | Bullish | 3-bar reversal: down → indecision → up |
| **Evening Star** | Bearish | 3-bar reversal: up → indecision → down |
| **Three White Soldiers** | Bullish | 3 consecutive strong green candles |
| **Three Black Crows** | Bearish | 3 consecutive strong red candles |
| **Inside Bar** | Neutral | Current bar fits inside previous bar — consolidation |
| **Bullish Marubozu** | Bullish | Strong green candle with almost no wicks |
| **Bearish Marubozu** | Bearish | Strong red candle with almost no wicks |
## How Win Rates Are Calculated
For each pattern occurrence in the lookback window:
1. Record the close price at the pattern
2. Look forward N bars (default: 5)
3. **Bullish patterns "win"** if the highest high in those N bars > pattern close
4. **Bearish patterns "win"** if the lowest low in those N bars < pattern close
5. Win Rate = wins / total occurrences × 100
This is a real backtest on the actual chart data — not some theoretical "textbook" win rate.
## The Statistics Dashboard
The bottom-right dashboard shows all 12 patterns with:
- **Win %** — Historical win rate on THIS symbol, THIS timeframe
- **Count** — How many times the pattern appeared
- **Type** — Bullish, Bearish, or Neutral
Win rates are color-coded:
- 🟢 60%+ = Strong edge
- 🟡 50-60% = Moderate
- 🔴 Below 50% = Pattern doesn't work here — skip it
## Smart Filtering
Labels only appear on the chart when:
- The pattern has appeared at least N times (configurable, default 3)
- The historical win rate exceeds your threshold (configurable, default 50%)
This means **you only see patterns that have actually worked** on this chart. Low-probability patterns are automatically hidden.
## Key Features
- **12 classic candle patterns** detected automatically
- **Real win rates** calculated from actual chart history — not theory
- **Smart filtering** hides unreliable patterns
- **Full statistics dashboard** with pattern-by-pattern breakdown
- **Customizable detection** — adjust body ratios, wick ratios, lookback windows
- **Toggle individual patterns** on/off
- **11 alert conditions** — one for each pattern type
- **Works on any market, any timeframe**
## Recommended Settings
| Style | Lookback | Outcome Bars | Min Win Rate |
|-------|----------|-------------|-------------|
| Scalping (1-5m) | 200-300 | 3 | 55% |
| Day Trading (15m-1H) | 500 | 5 | 50% |
| Swing (4H-Daily) | 500 | 5-10 | 50% |
| Position (Weekly) | 250 | 3-5 | 45% |
## Important Notes
- Win rates are calculated from historical data and **do not guarantee future results**
- Low occurrence counts (< 5) produce unreliable statistics — increase lookback or use a higher timeframe
- Some patterns (like Doji) are very common — consider raising the min body ratio to filter for higher-quality dojis
- The outcome window matters: 3 bars is aggressive, 10 bars gives more room
- Computing intensive on lower timeframes with high lookback — reduce lookback if the indicator loads slowly
## Disclaimer
This indicator is for educational and analytical purposes only. Past pattern win rates do not guarantee future performance. Always use proper risk management and never rely solely on candle patterns for trading decisions. Индикатор

SMT Divergence [UAlgo]SMT Divergence is a comparative market structure indicator designed to detect disagreement between a primary instrument and a second reference symbol. The script looks for situations where the main chart prints a stronger structural move, while the comparison symbol fails to confirm that move. This kind of disagreement is often referred to as SMT divergence and is commonly used to identify potential weakness in continuation or hidden strength into reversal conditions.
The script works by tracking confirmed swing highs and swing lows on both instruments. Once enough pivots are stored, it compares the latest structural movement in the primary chart against the latest comparable movement in the reference symbol. If the primary chart makes a lower low while the comparison symbol makes a higher low, the script identifies bullish SMT divergence. If the primary chart makes a higher high while the comparison symbol makes a lower high, the script identifies bearish SMT divergence.
What makes this script especially practical is its flexible comparison logic. It can work in a time matched mode, where the comparison swings must occur near the same bars as the primary swings, or in an independent mode, where the script simply uses the most recent valid swings from both instruments. It also supports inverse correlation logic, allowing the user to compare instruments that normally move in opposite directions.
The indicator can then display SMT labels directly on the main chart, draw structure lines between the relevant swing points, show a live information table, and optionally render the comparison symbol as candles inside the oscillator pane. This creates a complete workflow for divergence monitoring instead of only printing occasional labels.
In practical use, SMT Divergence can help traders identify moments when the primary symbol appears to be making an aggressive structural move without proper confirmation from a related market. These moments can provide useful context for potential exhaustion, liquidity events, or directional imbalance between correlated instruments.
🔹 Features
🔸 Dual Symbol Market Structure Comparison
The script compares the active chart against a second user selected symbol. Both instruments are processed using the same pivot logic, which creates a consistent framework for structural comparison.
🔸 Bullish SMT Detection
Bullish SMT is identified when the primary chart makes a lower low while the comparison symbol makes a higher low. This can suggest hidden relative strength in the comparison instrument or possible exhaustion in the primary one.
🔸 Bearish SMT Detection
Bearish SMT is identified when the primary chart makes a higher high while the comparison symbol makes a lower high. This can suggest weakening confirmation and possible vulnerability in the primary move.
🔸 Positive and Inverse Correlation Modes
The script supports both normal and inverse correlation logic. In normal mode, lows are compared with lows and highs are compared with highs. In inverse mode, lows are compared with highs and highs are compared with lows. This makes the tool flexible enough for both positively correlated and negatively correlated markets.
🔸 Time Matched and Independent Swing Modes
The user can choose whether swing comparison should require approximate time alignment or simply use the most recent valid swings from each symbol. This allows the script to be either stricter or more flexible depending on the relationship between the two markets.
🔸 Pivot Strength Control
Swing highs and lows are built from confirmed pivots using user defined left and right bar settings. This allows the user to control how sensitive or how selective the swing structure should be.
🔸 Minimum Price Difference Filter
A minimum price difference percentage can be required before a divergence is accepted. This helps avoid labeling very small and potentially insignificant swing differences.
🔸 Max Swing Memory Control
The script stores a limited number of recent swings for both the primary and comparison symbol. This keeps the logic focused on relevant structure and prevents unnecessary buildup of stale pivots.
🔸 On Chart Labels and Lines
Detected SMT events can be labeled directly on the main chart. The script can also draw structure lines across the primary and comparison swing legs used in the divergence.
🔸 Live Info Table
An information table can display the active comparison symbol, correlation mode, divergence count, and the latest signal direction. This makes the script easier to monitor in real time.
🔸 Optional Compare Candle Panel
The comparison symbol can be plotted as candles in the indicator pane. This allows the user to visually inspect whether the second instrument is confirming or rejecting the move seen in the primary chart.
🔸 Alert Support
The script includes separate alerts for bullish SMT, bearish SMT, and any SMT event.
🔹 Calculations
1) Defining Swing and Divergence Objects
type SwingPoint
int barIdx
int barTm
float price
bool isHigh
type SMTDivergence
int barIdx
int barTm
bool isBullish
float primaryPrice
float comparePrice
string primarySymbol
string compareSymbol
label lbl
line ln1
line ln2
type SymbolData
float h
float l
float c
This is the structural base of the whole script.
A SwingPoint stores one confirmed pivot with its bar index, time, price, and whether it is a high or a low.
An SMTDivergence object stores the final event once a divergence is confirmed. It keeps the primary and comparison prices, the involved symbols, the direction, and the visual references used for labels and lines.
A SymbolData object is used as a clean container for each symbol’s high, low, and close series.
So before any logic runs, the script already has a full structure for swing storage and divergence output.
2) Requesting the Comparison Symbol Data
= request.security(compareSymbolInput, timeframe.period, , lookahead = barmerge.lookahead_off)
SymbolData primaryData = SymbolData.new(high, low, close)
SymbolData compareData = SymbolData.new(compareHigh, compareLow, compareClose)
This block loads the second symbol on the same chart timeframe.
The primary chart uses the current symbol’s own high, low, and close. The comparison symbol is requested with request.security , and its values are placed into a matching data structure.
This means both symbols are analyzed on an equal timeframe basis, which is essential for consistent swing comparison.
3) Finding Pivot Highs and Pivot Lows on Both Symbols
float primaryPivotHigh = ta.pivothigh(primaryData.h, pivotLeftBars, pivotRightBars)
float primaryPivotLow = ta.pivotlow(primaryData.l, pivotLeftBars, pivotRightBars)
float comparePivotHigh = ta.pivothigh(compareData.h, pivotLeftBars, pivotRightBars)
float comparePivotLow = ta.pivotlow(compareData.l, pivotLeftBars, pivotRightBars)
This is the swing discovery engine.
The script uses the same pivot settings for both instruments. A pivot high or pivot low is only confirmed after the required number of bars has passed on each side.
This means the divergence engine is built from confirmed structure, not from temporary highs and lows that can disappear before confirmation.
4) Storing Swings in Memory
method addSwing(array swings, SwingPoint newSwing) =>
swings.push(newSwing)
if swings.size() > maxSwingsToStore
swings.shift()
swings
if not na(primaryPivotHigh)
primarySwings.addSwing(SwingPoint.new(bar_index - pivotOffset, time , primaryPivotHigh, true))
if not na(primaryPivotLow)
primarySwings.addSwing(SwingPoint.new(bar_index - pivotOffset, time , primaryPivotLow, false))
if not na(comparePivotHigh)
compareSwings.addSwing(SwingPoint.new(bar_index - pivotOffset, time , comparePivotHigh, true))
if not na(comparePivotLow)
compareSwings.addSwing(SwingPoint.new(bar_index - pivotOffset, time , comparePivotLow, false))
Once a pivot is confirmed, it is pushed into the appropriate swing array.
The true pivot bar is pivotRightBars bars in the past, so the script subtracts that offset from the current bar index and time. Each array only keeps the latest user defined number of swings.
So the script maintains a rolling structural memory for both markets without allowing the arrays to grow indefinitely.
5) Retrieving the Latest and Previous Swings
method getLastSwing(array swings, bool isHigh) =>
SwingPoint result = na
if swings.size() > 0
for i = swings.size() - 1 to 0
SwingPoint sw = swings.get(i)
if sw.isHigh == isHigh
result := sw
break
result
method getPreviousSwing(array swings, bool isHigh) =>
SwingPoint result = na
int count = 0
if swings.size() > 1
for i = swings.size() - 1 to 0
SwingPoint sw = swings.get(i)
if sw.isHigh == isHigh
count += 1
if count == 2
result := sw
break
result
These two helper methods are used to build the swing pairs required for divergence detection.
getLastSwing returns the most recent high or low swing of the requested type.
getPreviousSwing returns the swing before that.
This is important because SMT logic always compares two consecutive structure points on the primary side and two corresponding structure points on the comparison side.
6) Enforcing Maximum Distance Between Swing Points
method isWithinRange(SwingPoint sw1, SwingPoint sw2) =>
not na(sw1) and not na(sw2) and math.abs(sw1.barIdx - sw2.barIdx) <= maxBarsLookback
This method makes sure the two swings being compared are not too far apart in time.
If the latest and previous swing are separated by more than the allowed bar distance, the setup is ignored.
This helps keep the analysis focused on fresh and structurally related moves rather than comparing swings that are too old or too distant to be meaningful together.
7) Time Matched Swing Search
method findSwingNearBar(array swings, int targetBar, bool isHigh, int toleranceBars) =>
SwingPoint result = na
int minDiff = 999999
if swings.size() > 0
for i = swings.size() - 1 to 0
SwingPoint sw = swings.get(i)
if sw.isHigh == isHigh
int diff = math.abs(sw.barIdx - targetBar)
if diff <= toleranceBars and diff < minDiff
minDiff := diff
result := sw
result
This method is used only when the user selects time matched mode.
The idea is to find a comparison symbol swing that occurred near the same bar as the primary swing. The script searches for the nearest swing of the correct type inside the allowed tolerance window.
So time matched mode is stricter because it requires approximate timing alignment between the two instruments.
8) Minimum Price Difference Filter
method pctDiff(float price1, float price2) =>
math.abs(price1 - price2) / ((price1 + price2) / 2) * 100
This function measures the percentage difference between two prices.
The result is later used as an optional minimum swing magnitude filter. If the primary chart’s new swing differs only slightly from its previous one, the script can ignore that divergence candidate.
So the minimum difference filter helps reduce weaker signals that are based on very small structure changes.
9) Bullish SMT Detection Logic
if not na(primaryPivotLow) and not na(primaryLastLow) and not na(primaryPrevLow)
SwingPoint usedCompareLast = na
SwingPoint usedComparePrev = na
bool targetSwingHigh = inverseCorrelation ? true : false
if useTimeMatching
usedCompareLast := compareSwings.findSwingNearBar(primaryLastLow.barIdx, targetSwingHigh, timeToleranceBars)
usedComparePrev := compareSwings.findSwingNearBar(primaryPrevLow.barIdx, targetSwingHigh, timeToleranceBars)
else
usedCompareLast := compareSwings.getLastSwing(targetSwingHigh)
usedComparePrev := compareSwings.getPreviousSwing(targetSwingHigh)
This is the setup stage for bullish SMT.
The script only begins the test when a new primary pivot low has just been confirmed and both the latest and previous primary lows are available.
Then it decides what kind of comparison swings are needed.
In normal correlation mode, bullish SMT compares primary lows to comparison lows.
In inverse correlation mode, bullish SMT compares primary lows to comparison highs.
Then the script either uses time matched lookup or independent swing retrieval depending on the chosen mode.
So before the bullish condition itself is tested, the script first builds the proper comparison pair according to both timing mode and correlation mode.
10) Bullish SMT Confirmation Conditions
if not na(usedCompareLast) and not na(usedComparePrev)
if primaryLastLow.isWithinRange(primaryPrevLow)
bool primaryLL = primaryLastLow.price < primaryPrevLow.price
bool compareHL = inverseCorrelation ? (usedCompareLast.price < usedComparePrev.price) : (usedCompareLast.price > usedComparePrev.price)
bool meetsMinDiff = minPriceDiff == 0.0 or (primaryLastLow.price.pctDiff(primaryPrevLow.price) >= minPriceDiff)
Bullish SMT is confirmed when three things happen.
First, the primary chart must make a lower low:
primaryLastLow.price < primaryPrevLow.price
Second, the comparison symbol must fail to confirm that weakness. In normal correlation mode this means the comparison symbol makes a higher low. In inverse correlation mode the logic is adjusted accordingly because the relationship is reversed.
Third, if the minimum difference filter is enabled, the primary low must differ enough from the previous low.
So bullish SMT is essentially a lower low in the main chart that is not properly confirmed by the comparison market.
11) Creating the Bullish Divergence Event
if primaryLL and compareHL and meetsMinDiff and primaryLastLow.barIdx != lastBullPrimaryIdx
bullishSMT := true
lastBullPrimaryIdx := primaryLastLow.barIdx
SMTDivergence newDiv = SMTDivergence.new(primaryLastLow.barIdx, primaryLastLow.barTm, true, primaryLastLow.price, usedCompareLast.price, syminfo.tickerid, compareSymbolInput, na, na, na)
newDiv.drawVisuals(primaryPrevLow.barTm, primaryPrevLow.price, usedCompareLast.barTm, usedComparePrev.barTm, usedComparePrev.price)
divergences.push(newDiv)
Once the bullish conditions are met, the script creates a new SMT divergence object.
It stores the primary swing information, the comparison swing information, the involved symbols, and the bullish direction. Then it calls the visual drawing method and pushes the divergence into the history array.
The duplicate protection check against lastBullPrimaryIdx prevents the same primary swing from being labeled repeatedly.
12) Bearish SMT Detection Logic
if not na(primaryPivotHigh) and not na(primaryLastHigh) and not na(primaryPrevHigh)
SwingPoint usedCompareLastH = na
SwingPoint usedComparePrevH = na
bool targetSwingHigh = inverseCorrelation ? false : true
if useTimeMatching
usedCompareLastH := compareSwings.findSwingNearBar(primaryLastHigh.barIdx, targetSwingHigh, timeToleranceBars)
usedComparePrevH := compareSwings.findSwingNearBar(primaryPrevHigh.barIdx, targetSwingHigh, timeToleranceBars)
else
usedCompareLastH := compareSwings.getLastSwing(targetSwingHigh)
usedComparePrevH := compareSwings.getPreviousSwing(targetSwingHigh)
This is the mirror setup stage for bearish SMT.
It begins only when a new primary pivot high has been confirmed and the required primary highs exist. Then it selects the proper comparison swing type according to the chosen correlation mode.
In normal correlation mode, bearish SMT compares highs with highs.
In inverse correlation mode, bearish SMT compares highs with lows.
So this block prepares the correct structural pair for the bearish test.
13) Bearish SMT Confirmation Conditions
if not na(usedCompareLastH) and not na(usedComparePrevH)
if primaryLastHigh.isWithinRange(primaryPrevHigh)
bool primaryHH = primaryLastHigh.price > primaryPrevHigh.price
bool compareLH = inverseCorrelation ? (usedCompareLastH.price > usedComparePrevH.price) : (usedCompareLastH.price < usedComparePrevH.price)
bool meetsMinDiff = minPriceDiff == 0.0 or (primaryLastHigh.price.pctDiff(primaryPrevHigh.price) >= minPriceDiff)
Bearish SMT is confirmed when the primary chart makes a higher high while the comparison symbol fails to confirm that strength.
In normal correlation mode, the comparison symbol must make a lower high. In inverse correlation mode the logic is adjusted to preserve the intended structural disagreement.
The minimum difference filter is applied here as well.
So bearish SMT is the opposite structure of bullish SMT, focused on unconfirmed upside continuation.
14) Creating the Bearish Divergence Event
if primaryHH and compareLH and meetsMinDiff and primaryLastHigh.barIdx != lastBearPrimaryIdx
bearishSMT := true
lastBearPrimaryIdx := primaryLastHigh.barIdx
SMTDivergence newDiv = SMTDivergence.new(primaryLastHigh.barIdx, primaryLastHigh.barTm, false, primaryLastHigh.price, usedCompareLastH.price, syminfo.tickerid, compareSymbolInput, na, na, na)
newDiv.drawVisuals(primaryPrevHigh.barTm, primaryPrevHigh.price, usedCompareLastH.barTm, usedComparePrevH.barTm, usedComparePrevH.price)
divergences.push(newDiv)
Once the bearish rules are satisfied, the script creates a bearish SMT divergence object, draws its visuals, and stores it in the divergence history array.
The duplicate protection check against lastBearPrimaryIdx prevents repeated labeling of the same primary high.
15) Drawing Labels and Lines
method drawVisuals(SMTDivergence div, int prevTime, float prevPrice, int compareTime, int prevCompareTime, float prevComparePrice) =>
if showLabels
string labelText = div.isBullish ? "🔺 SMT" : "🔻 SMT"
string tooltipText = str.format("{0} SMT Divergence {1} vs {2} Price: {3}", div.isBullish ? "Bullish" : "Bearish", div.primarySymbol, div.compareSymbol, str.tostring(div.primaryPrice, format.mintick))
color labelColor = div.isBullish ? bullishColor : bearishColor
div.lbl := label.new(div.barIdx, div.primaryPrice, labelText, xloc = xloc.bar_index, yloc = div.isBullish ? yloc.belowbar : yloc.abovebar, color = labelColor, textcolor = color.white, style = div.isBullish ? label.style_label_up : label.style_label_down, tooltip = tooltipText, size = size.small, force_overlay = true)
if showLines and not na(prevTime) and not na(prevPrice)
color lineColor = div.isBullish ? bullishColor : bearishColor
div.ln1 := line.new(prevTime, prevPrice, div.barTm, div.primaryPrice, xloc = xloc.bar_time, color = lineColor, width = 2, style = line.style_solid, force_overlay = true)
if not na(prevComparePrice) and not na(prevCompareTime) and not na(compareTime)
div.ln2 := line.new(prevCompareTime, prevComparePrice, compareTime, div.comparePrice, xloc = xloc.bar_time, color = lineColor, width = 2, style = line.style_solid)
This method creates the chart visuals for each divergence.
The label is placed directly at the primary swing location, above price for bearish SMT and below price for bullish SMT.
If line drawing is enabled, the script also draws one line across the primary chart’s two relevant swing points and another line across the comparison symbol’s swing leg.
So the user can see both the signal marker and the underlying structural disagreement that produced it.
16) Limiting Divergence History
if divergences.size() > maxDivergencesToShow
SMTDivergence rmDiv = divergences.shift()
rmDiv.cleanup()
This block controls object history.
If the stored divergence count exceeds the chosen limit, the oldest divergence is removed from the array and all its visuals are deleted.
This keeps the chart clean and prevents unlimited buildup of old labels and lines.
17) Building the Information Table
var table infoTable = table.new(position.top_right, 2, 6, bgcolor = color.new(#2222b3, 10), border_width = 1, border_color = color.new(color.white, 80), frame_width = 2, frame_color = color.new(color.white, 70))
if showTable and barstate.islast
table.cell(infoTable, 0, 1, "Primary", text_color = color.gray, text_size = size.tiny)
table.cell(infoTable, 1, 1, syminfo.tickerid, text_color = color.white, text_size = size.tiny)
table.cell(infoTable, 0, 2, "Compare", text_color = color.gray, text_size = size.tiny)
table.cell(infoTable, 1, 2, compareSymbolInput, text_color = color.white, text_size = size.tiny)
table.cell(infoTable, 0, 3, "Correlation", text_color = color.gray, text_size = size.tiny)
table.cell(infoTable, 1, 3, inverseCorrelation ? "Inverse" : "Positive", text_color = inverseCorrelation ? color.orange : color.aqua, text_size = size.tiny)
table.cell(infoTable, 0, 4, "Divergences", text_color = color.gray, text_size = size.tiny)
table.cell(infoTable, 1, 4, str.tostring(divergences.size()), text_color = color.white, text_size = size.tiny)
This table provides a compact real time summary.
It shows:
the primary symbol,
the comparison symbol,
the current correlation mode,
the number of stored divergences,
and the most recent signal direction.
So the table functions as a monitoring dashboard rather than only a decorative element.
18) Determining the Last Signal for the Table
string lastSignal = "None"
color signalColor = color.gray
if divergences.size() > 0
SMTDivergence lastDiv = divergences.get(divergences.size() - 1)
lastSignal := lastDiv.isBullish ? "🔺 Bullish" : "🔻 Bearish"
signalColor := lastDiv.isBullish ? bullishColor : bearishColor
This block determines what the table should show as the latest signal.
If at least one divergence has been stored, the script reads the newest one and displays whether it was bullish or bearish, along with the corresponding color.
So the info table always reflects the current state of the divergence history.
19) Alert Conditions
alertcondition(bullishSMT, title = "Bullish SMT Divergence", message = "🔺 Bullish SMT Divergence detected on {{ticker}}! Primary made Lower Low while {{interval}} comparison made Higher Low.")
alertcondition(bearishSMT, title = "Bearish SMT Divergence", message = "🔻 Bearish SMT Divergence detected on {{ticker}}! Primary made Higher High while {{interval}} comparison made Lower High.")
alertcondition(bullishSMT or bearishSMT, title = "Any SMT Divergence", message = "SMT Divergence detected on {{ticker}}!")
The script provides three alert types.
One triggers only on bullish SMT.
One triggers only on bearish SMT.
One triggers on any SMT event.
This makes the indicator useful both for visual study and for live event monitoring.
20) Compare Candle Panel
color compareBodyColor = compareClose >= compareOpen ? color.new(#00E676, 0) : color.new(#FF5252, 0)
color compareWickColor = compareClose >= compareOpen ? color.new(#00E676, 30) : color.new(#FF5252, 30)
color compareBorderColor = compareClose >= compareOpen ? color.new(#00C853, 0) : color.new(#D50000, 0)
plotcandle(compareOpen, compareHigh, compareLow, compareClose, title = "Compare Symbol Candles", color = compareBodyColor, wickcolor = compareWickColor, bordercolor = compareBorderColor, display = showCandlePanel ? display.all : display.none)
This block renders the comparison symbol as candles inside the indicator pane.
The candle colors are determined by the comparison symbol’s own open and close direction. If the user enables the candle panel, this gives a quick visual reference for how the second instrument is behaving without needing to open a separate chart.
So the user can study SMT signals and the comparison structure in the same pane. Индикатор

Effort & Result [UAlgo]Effort & Result is a volume spread relationship oscillator inspired by the classic idea that market effort and market result do not always move in balance. The script compares how unusual current volume is versus how unusual current price range is, then measures the gap between those two conditions. The result is a compact oscillator that helps reveal whether the market is showing heavy participation with limited progress, or strong price expansion with relatively weak participation.
The core concept is simple. Volume represents effort, while true range represents result. When effort rises much faster than result, the market may be meeting opposing liquidity and progress can become inefficient. When result rises much faster than effort, price may be moving through thinner liquidity with relatively little resistance. This script transforms that relationship into standardized values so both dimensions can be compared on the same scale.
To make the comparison more useful, the script converts both volume and true range into rolling z scores. That means each bar is judged relative to its own recent context rather than by raw magnitude alone. A large volume bar may not mean much in a market that always trades large volume, while the same raw value could be highly unusual in another market. The same logic applies to price range. By standardizing both series, the indicator focuses on anomaly versus normal behavior rather than on absolute size.
The final oscillator is the difference between effort z score and result z score. Positive readings suggest effort is leading result, while negative readings suggest result is leading effort. The script also highlights two special regimes. Absorption appears when effort is strongly positive but result remains weak. Vacuum appears when result is strongly positive but effort remains weak. These conditions are then labeled directly on the oscillator.
In practical use, the indicator can help identify hidden resistance to price movement, low liquidity expansion, or moments where market participation and delivered movement are out of balance. It is best used as a context tool rather than a standalone entry engine.
🔹 Features
🔸 Effort Versus Result Framework
The script separates market behavior into two dimensions. Volume is treated as effort, and true range is treated as result. This creates a clean and intuitive model for comparing participation versus delivered movement.
🔸 Rolling Z Score Standardization
Both effort and result are transformed into rolling z scores over the selected lookback window. This makes the oscillator adaptive to the recent environment and allows direct comparison between volume and range.
🔸 Delta Oscillator
The final plotted value is the difference between effort z score and result z score. This gives the user a direct read on whether volume is leading range or range is leading volume.
🔸 Absorption Detection
When effort is strongly positive but result is weak or negative, the script flags absorption. This can indicate that strong participation is being met by opposing liquidity and price progress is being contained.
🔸 Vacuum Detection
When result is strongly positive but effort is weak or negative, the script flags a vacuum condition. This can indicate that price is moving through thin liquidity with little resistance.
🔸 Context Aware Histogram Coloring
The histogram changes color depending on whether the bar reflects absorption, vacuum, or neutral conditions. This makes regime identification faster and more visual.
🔸 Threshold Guides
The oscillator includes reference lines for equilibrium as well as absorption and vacuum alert thresholds, making it easier to interpret extremes.
🔸 Direct Chart Labels
Special conditions are labeled directly on the oscillator so absorption and vacuum events stand out immediately without requiring separate scanning.
🔹 Calculations
1) Defining the Flow Metrics Container
type FlowMetrics
float totalVol
float spread
float effortZ
float resultZ
This object stores the four main values used by the indicator.
totalVol stores the current bar volume.
spread stores the current bar range measure.
effortZ stores the standardized effort reading.
resultZ stores the standardized result reading.
So before any signal logic is built, the script already has a clean structure for the raw inputs and their normalized forms.
2) Measuring Effort and Result Inputs
float v = nz(volume, 1)
float tr = ta.tr(true)
This block defines the two core raw inputs of the indicator.
v is the current volume, with a fallback of 1 in case the symbol does not provide volume data.
tr is the true range of the bar, which is used as the result measure.
The reason true range is used instead of a simpler high minus low calculation is that true range also accounts for gaps relative to the prior close. This makes it a more complete measure of actual delivered price movement.
So the indicator begins with one participation variable and one movement variable.
3) Rolling Mean and Standard Deviation for Effort
float volMean = ta.sma(vol, len)
float volStd = ta.stdev(vol, len)
this.effortZ := volStd == 0 ? 0 : (vol - volMean) / volStd
This is the effort standardization step.
The script first computes the rolling average volume over the chosen window. Then it computes the rolling volume standard deviation over the same window. Finally, it converts the current volume into a z score:
effortZ = (current volume minus mean volume) divided by volume standard deviation
This means:
a positive effort z score implies current volume is above normal,
a negative effort z score implies current volume is below normal,
and zero means current volume is near its rolling average.
So effort is not judged by raw volume alone. It is judged by how unusual that volume is relative to recent history.
4) Safe Spread Handling for Result Calculation
float safeSpread = r == 0 ? syminfo.mintick : r
This line prevents division and standardization issues when the range is zero.
If the current true range is zero, the script substitutes the instrument’s minimum tick size instead. This ensures that the result side of the calculation always has a valid positive value and avoids unstable behavior in rare flat bars.
So the script remains numerically stable even when a bar has no measurable range.
5) Rolling Mean and Standard Deviation for Result
float spreadMean = ta.sma(safeSpread, len)
float spreadStd = ta.stdev(safeSpread, len)
this.resultZ := spreadStd == 0 ? 0 : (safeSpread - spreadMean) / spreadStd
This is the result standardization step.
Just like effort, the script calculates the rolling average and rolling standard deviation for the bar spread. It then converts the current spread into a z score:
resultZ = (current spread minus mean spread) divided by spread standard deviation
This means:
a positive result z score implies current movement is above normal,
a negative result z score implies current movement is below normal.
So result becomes directly comparable to effort on the same statistical scale.
6) Full Metric Calculation Method
method calcMetrics(FlowMetrics this, float vol, float r, int len) =>
this.totalVol := vol
this.spread := r
float volMean = ta.sma(vol, len)
float volStd = ta.stdev(vol, len)
this.effortZ := volStd == 0 ? 0 : (vol - volMean) / volStd
float safeSpread = r == 0 ? syminfo.mintick : r
float spreadMean = ta.sma(safeSpread, len)
float spreadStd = ta.stdev(safeSpread, len)
this.resultZ := spreadStd == 0 ? 0 : (safeSpread - spreadMean) / spreadStd
This method combines the full effort and result workflow into one place.
It first stores the raw bar volume and raw spread. Then it calculates the effort z score from rolling volume statistics and the result z score from rolling spread statistics.
So each bar receives:
a raw effort reading,
a raw result reading,
a normalized effort score,
and a normalized result score.
This normalized pair is what the rest of the oscillator uses.
7) Building the Main Oscillator Value
FlowMetrics flow = FlowMetrics.new()
flow.calcMetrics(v, tr, length)
float deltaZ = flow.effortZ - flow.resultZ
This is the main oscillator formula.
After the metrics object is updated, the script computes:
deltaZ = effortZ minus resultZ
This value answers the central question of the indicator:
is effort stronger than result, or is result stronger than effort?
If deltaZ is positive, effort is outrunning result.
If deltaZ is negative, result is outrunning effort.
If deltaZ is near zero, effort and result are more balanced.
So the oscillator is really a normalized imbalance measure between participation and delivered movement.
8) Absorption Condition
bool isAbsorption = flow.effortZ > 1.5 and flow.resultZ < 0.0
This is the first special regime filter.
Absorption is defined as:
effort significantly above normal,
while result remains weak.
The threshold 1.5 means effort must be at least 1.5 standard deviations above its rolling average. At the same time, result must still be below zero, meaning current movement is not even above its recent average.
This combination suggests that strong participation is entering the market but price is not expanding proportionally. That can imply opposing liquidity, passive absorption, or resistance to movement.
So absorption is the classic high effort, low result condition.
9) Vacuum Condition
bool isVacuum = flow.resultZ > 1.5 and flow.effortZ < 0.0
This is the second special regime filter.
Vacuum is defined as:
result significantly above normal,
while effort remains weak.
Here, price is delivering unusually large movement, but volume is not confirming that move with above average participation. This can imply thin liquidity, poor resistance, or fast movement through lightly traded space.
So vacuum is the classic low effort, high result condition.
10) Histogram Color Logic
color histColor = isAbsorption ? color.new(color.fuchsia, 30) :
isVacuum ? (close >= open ? color.new(color.aqua, 30) : color.new(color.orange, 30)) :
color.new(color.gray, 70)
This block determines how the histogram is colored.
If the current bar meets the absorption condition, the histogram is colored fuchsia.
If it meets the vacuum condition, the histogram is colored aqua when the candle is bullish and orange when the candle is bearish.
If neither special regime is active, the histogram is colored neutral gray.
So the visual layer helps the user distinguish ordinary imbalance readings from the two emphasized special states.
11) Plotting the Oscillator
plot(deltaZ, "Effort/Result Delta", style=plot.style_columns, color=histColor)
This line plots the main effort versus result delta as a column histogram.
The use of columns is helpful because it emphasizes relative magnitude and direction around the zero line. Positive columns show effort leading result. Negative columns show result leading effort.
So the visual output is both directional and strength sensitive.
12) Threshold and Equilibrium Lines
hline(1.5, "Vacuum Alert", color=color.new(color.aqua, 50), linestyle=hline.style_dashed)
hline(-1.5, "Absorption Alert", color=color.new(color.fuchsia, 50), linestyle=hline.style_dashed)
hline(0, "Equilibrium", color=color.new(color.gray, 50))
These reference lines give the oscillator context.
The zero line marks equilibrium, where effort and result are more balanced.
The positive 1.5 line acts as a visual vacuum threshold.
The negative 1.5 line acts as a visual absorption threshold.
These levels do not define the regime conditions directly by themselves, because the actual logic checks the separate effort and result z scores. But they still give the user a useful visual frame for interpreting the size of the delta reading.
13) Labeling Absorption Events
if isAbsorption
label.new(bar_index, deltaZ, text="Absorbed", color=color.new(color.fuchsia, 100), textcolor=color.fuchsia, style=label.style_none, size=size.small, yloc=yloc.price)
When an absorption condition is detected, the script prints an Absorbed label directly at the oscillator value for that bar.
This makes the event easier to spot when scanning history and also helps separate truly qualified absorption conditions from merely positive delta readings.
So the label is not attached to every strong positive bar, only to the bars that meet the specific high effort and weak result rule.
14) Labeling Vacuum Events
if isVacuum
label.new(bar_index, deltaZ, text="Vacuum", color=color.new(color.aqua, 100), textcolor=color.aqua, style=label.style_none, size=size.small, yloc=yloc.price)
This block does the same for vacuum events.
When a bar shows unusually strong range with weak volume participation, the script prints a Vacuum label at the oscillator level.
So the chart distinguishes not only statistical imbalance in general, but specifically the regime where result is outrunning effort. Индикатор

Индикатор

Outside Bar & 2-Bar Reversal Alerts + SystemOutside Bar & 2-Bar Reversal — Price Action Reversal Detection with Integrated Trade Management
Hello friends and traders!
🔹 Introduction
This indicator — Outside Bar & 2-Bar Reversal — automatically identifies two of the most structurally sound price action reversal patterns and overlays a complete trade management system directly on your chart.
The patterns this indicator detects are rooted in a simple but powerful idea: momentum exhaustion followed by full absorption. When price makes an aggressive directional push and is then completely engulfed by the opposing side, it often signals that the prevailing move has run out of willing participants.
The indicator also includes an optional suite of confluence filters — VWAP, swing sweeps, and time-of-day — so you can isolate the highest-quality setups rather than trading every signal blindly.
I'll cover the pattern logic, the trade management system, and all filters in detail throughout this description.
🔹 The Premise
🔸 Why Reversal Candles Work
Price moves because of imbalance. When more aggressive buyers than sellers are active, price rises. When more aggressive sellers than buyers are active, price falls.
Reversal candle patterns are useful because they attempt to identify the moment that imbalance flips — where one side that was previously dominant is fully overcome by the other.
The key word is fully. A simple bearish candle after a bullish candle tells you very little. What's meaningful is when the opposing candle completely engulfs the prior move — taking out its low, closing above its open, and reaching above its high. That's not just a pause. That's a statement.
This is the foundation of both patterns this indicator detects.
🔸 What Is an Outside Bar?
An outside bar is a candle that completely engulfs the prior candle — its range exceeds the prior candle's range on both sides.
But not all outside bars are created equal. A random outside bar on a quiet consolidation bar means very little. The patterns this indicator targets require context and directionality before the signal fires.
Bullish Outside Bar — Full Conditions:
Candle 1 must be bearish — it closes below its open
Candle 1 must close below the prior candle's close — a genuine continuation of selling
Candle 1's low must be below the prior candle's low — it must make a lower low, showing directional commitment
Candle 2 (signal candle) must have a lower low than Candle 1 — extending the flush
Candle 2 must close above Candle 1's open — full absorption of the bearish candle
Candle 2 must have a higher high than Candle 1 — completing the engulf
The result: a setup where price made a committed bearish push, and then a single candle came in, swept below it, and closed above the entire prior move. Buyers didn't just show up — they overwhelmed every seller from the prior candle.
Bearish Outside Bar — Full Conditions:
The exact mirror. A committed bullish candle that makes a higher high, followed by a signal candle that sweeps above it and closes below its entire range. Sellers overwhelmed every buyer.
🔸 What Is a 2-Bar Reversal?
The 2-Bar Reversal is a related but distinct pattern. Rather than requiring full range engulfment, it focuses on close-to-close extremity.
Bullish 2-Bar Reversal:
Candle 1 closes entirely below the low of the candle before it — an aggressive, committed flush
Candle 2 closes above the open of Candle 1 — a full reclaim of the prior candle's starting point
The logic: if price closes below a prior candle's entire range, sellers were aggressive. If the very next candle reclaims all of that, buyers responded even more aggressively. The speed of the reversal is what makes this significant.
Bearish 2-Bar Reversal:
Candle 1 closes above the prior candle's high. Candle 2 closes below Candle 1's open. Immediate and full rejection of the breakout.
🔹 Integrated Trade Management
Every signal automatically places three levels on your chart so you never have to manually calculate a trade again.
🔸 Entry
The open of the candle immediately following the signal candle. You're not chasing — you're entering at the next structured open after confirmation is complete.
🔸 Stop Loss
The open of the signal candle itself. The reasoning: if price returns to where the signal candle opened, the reversal thesis is structurally compromised.
🔸 Take Profit
Fully user-adjustable R multiple. Default is 2R — meaning for every dollar risked, you're targeting two dollars of reward. Adjustable from 0.1R to any value via the settings panel.
🔸 Line Behavior
All three lines extend to the right in real time and automatically terminate the moment price hits either the TP or SL level. No manual cleanup. No cluttered leftover lines. Every historical trade remains visible on the chart so you can review setups at a glance.
🔹 Live Performance Table
A built-in stats table tracks every closed trade automatically:
Total Trades — all resolved trades
Wins — trades that reached the TP level
Losses — trades that hit the SL level
Win Rate — displayed as a percentage, color coded green above 50% and red below
Load any chart, any timeframe, any market — the table populates in real time and gives you an instant read on how the patterns have performed under your current filter settings.
🔹 Confluence Filters
Each filter is independently toggleable. Use one, all, or none — the indicator works standalone without any filters active.
🔸 VWAP Filter
VWAP (Volume Weighted Average Price) is widely used by institutional participants as an intraday benchmark. Price trading above VWAP is generally considered a bullish market structure for the session; below VWAP is bearish.
When enabled, this filter requires:
Bullish signals: the signal candle must close above VWAP
Bearish signals: the signal candle must close below VWAP
This keeps you aligned with the intraday institutional bias rather than trading reversals against the dominant order flow of the session.
🔸 Swing Sweep Filter
One of the most reliable contexts for a reversal pattern is when it occurs after a liquidity sweep — price briefly trading through a prior swing point before reversing. This is often where stop orders from trapped traders trigger, adding fuel to the reversal.
When enabled:
Bullish signals only show if the signal candle's low swept below a recent pivot low
Bearish signals only show if the signal candle's high swept above a recent pivot high
Both the lookback window and the pivot strength (number of bars required on each side to qualify as a swing) are fully adjustable.
🔸 Time Window Filter
Not all hours of the trading day are equal. The highest-quality price action signals tend to occur during periods of genuine institutional participation — typically the first few hours of the New York session when volume, spread, and volatility are all at their daily peak.
When enabled, signals are restricted to a user-defined time window. Default is 8:00 AM – 11:00 AM EST, covering the New York open. The start and end times are individually adjustable by hour and minute. Uses the America/New_York timezone, so EST/EDT daylight saving transitions are handled automatically.
🔹 Settings Overview
SettingDescriptionShow Bullish / Bearish SignalsToggle each direction independentlyShow Outside BarsToggle OB pattern on/offShow 2-Bar ReversalsToggle 2BR pattern on/offTake Profit R MultipleAdjustable TP target (default 2R)Show Trade LinesToggle entry/SL/TP linesLine ColorsIndependently customizableTime Window FilterOn/off + start/end timeVWAP FilterOn/offSwing Sweep FilterOn/off + lookback + pivot strength
🔹 Works On Any Market & Timeframe
The patterns are purely price-action based — no volume dependency, no indicator inputs. They apply equally to equities, futures, forex, and crypto. Most effective on intraday timeframes (1m–15m) during high-liquidity sessions, but the logic holds on higher timeframes for swing traders as well.
🔹 Closing Remarks
The Outside Bar and 2-Bar Reversal are not new concepts. Traders have been observing these patterns for decades. What this indicator adds is precision in definition — ensuring every signal meets a strict structural checklist rather than firing on any loosely engulfing candle — combined with a fully automated trade management overlay and a real-time performance table.
The filters exist because context matters. The same pattern in the middle of a choppy afternoon session, below VWAP, with no liquidity sweep, is a different proposition to the same pattern at the New York open, above VWAP, after a clean sweep of a prior swing low.
Use the filters to build a ruleset that matches your edge, and use the performance table to validate it.
Drop a comment below with the market and timeframe you're testing this on — always interested to see how different traders apply price action tools. Индикатор

Volumetric Inverse Fair Value Gap (VIFVG) [UAlgo]Volumetric Inverse Fair Value Gap is an imbalance analysis tool that tracks the full lifecycle of a Fair Value Gap and then focuses on what happens after that gap fails. Instead of stopping at the initial gap detection, the script stores qualifying bullish and bearish FVGs, waits for price to invalidate them from the opposite side, and then converts those failed imbalances into active Inverse Fair Value Gaps.
The main idea is rooted in role reversal. A bullish Fair Value Gap may initially represent an area of inefficiency below price, but if price later trades through that gap in the opposite direction, the same zone can flip into a bearish inverse area. The same logic applies in reverse for bearish gaps that later fail to the upside. This script automates that transition and keeps the resulting IFVG visible on the chart as long as it remains active.
What makes this version more distinctive is the volumetric overlay inside the inverse zone. Once an IFVG is created, the script attaches three internal metrics to it. The first estimates bullish participation, the second estimates bearish participation, and the third measures relative volume strength using percentile rank. These values are then displayed inside the box as horizontal progress bars, turning the IFVG into both a structural level and a compact participation summary.
The indicator also supports a ghost box that preserves the original FVG location from the moment it was created until the moment it became inverse. This gives the user a clearer narrative of how the imbalance formed and where the role reversal occurred. Combined with the active box, the result is a visually informative workflow for traders who want to study failed imbalances, structure flips, and how strong the inversion candle was when the role change happened.
In practical use, the script can help identify zones where a former inefficiency has turned into a reaction area, while also showing whether the inversion event carried more bullish pressure, more bearish pressure, or unusually strong participation relative to recent volume history.
🔹 Features
🔸 Fair Value Gap Detection With ATR Filtering
The script first detects classic three candle FVG structures, then filters them using a minimum gap size expressed in ATR units. This helps reduce noise and removes smaller gaps that may be less meaningful.
🔸 Strict and Non Strict Detection Modes
Strict mode requires actual wick separation between the first and third candle. Non strict mode allows close based confirmation instead. This gives the user control over how precise the gap definition should be.
🔸 Pending FVG Lifecycle Tracking
Detected FVGs are not immediately turned into inverse zones. They are first stored as pending gaps and monitored until price later crosses them in the opposite direction.
🔸 Automatic FVG to IFVG Conversion
When price invalidates a pending gap from the opposite side, the script creates a new Inverse Fair Value Gap object and begins tracking it as an active zone.
🔸 Ghost Box Support
The original FVG can be preserved visually as a dashed ghost box from the creation time of the imbalance to the inversion time. This makes it easier to see the original gap and the later role reversal event together.
🔸 Volumetric Breakdown Inside the IFVG
Each active inverse gap includes three stacked internal bars:
estimated bullish participation,
estimated bearish participation,
and relative strength.
This gives the zone more context than a normal box alone.
🔸 Participation Estimation From Candle Anatomy
Bullish and bearish participation are estimated from the inversion candle’s structure and volume. This creates a practical volume split model that helps describe how the inversion occurred.
🔸 Strength Metric From Volume Percentile Rank
The script measures how strong the inversion candle’s volume is relative to the last one hundred bars. This is displayed as a separate strength bar inside the IFVG.
🔸 Live Box Expansion
As long as an IFVG remains active, its container extends forward in time. The internal volumetric bars and text labels are updated continuously so the zone remains clear and readable.
🔸 Automatic Invalidation
A bullish IFVG is removed if price closes below its bottom. A bearish IFVG is removed if price closes above its top. This keeps the display focused on still valid inverse zones.
🔸 Controlled History Size
The script limits how many active IFVGs remain on the chart. Older ones are removed once the display exceeds the selected history count.
🔹 Calculations
1) Defining the Pending Gap and Active IFVG Objects
type PendingFVG
float top
float btm
bool is_bull_gap
bool processed
int created_time
type IFVG
int start_time
int origin_time
float top
float btm
bool is_bull_ifvg
float pct_bull
float pct_bear
float pct_strength
box container
box ghost_box
box bg_bull
box bar_bull
box bg_bear
box bar_bear
box bg_str
box bar_str
label lbl_bull
label lbl_bear
label lbl_str
bool active
This is the structural foundation of the script.
A PendingFVG stores an imbalance that has been detected but has not yet inverted. It contains the gap boundaries, whether the original gap was bullish or bearish, whether it has already been processed into an inverse gap, and the time when it was created.
An IFVG stores the full active inverse gap state. In addition to the price boundaries and direction, it also stores the three internal metrics, the container box, the optional ghost box, the internal background and progress bars, the labels, and the active state.
So the script is not just drawing boxes. It is managing two linked object lifecycles:
pending FVGs,
and active inverse FVGs.
2) ATR Filter for Gap Significance
float atr_val = ta.atr(14)
The ATR value is used as the script’s minimum significance filter.
Instead of accepting every visible gap, the script compares gap size against a fraction of ATR. This is useful because a fixed price threshold would behave very differently across markets and timeframes, while ATR gives a volatility aware reference.
So ATR acts as the noise filter that decides whether a newly found gap deserves to be tracked.
3) Estimating Bullish and Bearish Participation
calc_metrics(float o, float h, float l, float c, float v) =>
float rng = h - l
float buy_v = 0.0
if rng == 0
buy_v := v * 0.5
else
if c >= o
buy_v := v * ((math.abs(c - o) + (math.min(o, c) - l)) / rng)
else
buy_v := v * ((h - math.max(o, c)) / rng)
float sell_v = v - buy_v
float total = buy_v + sell_v
float p_bull = total > 0 ? buy_v / total : 0
float p_bear = total > 0 ? sell_v / total : 0
float p_str = ta.percentrank(v, 100) / 100.0
This function is one of the most important parts of the whole script.
Its goal is to turn one candle into three interpretable metrics:
bullish share,
bearish share,
and strength.
First, the script measures the candle range. If the candle has zero range, volume is split evenly.
If the candle has a real range, the script estimates buying pressure differently depending on candle direction.
For bullish candles, buy volume is influenced by the candle body plus the lower section of the candle.
For bearish candles, buy volume is approximated from the remaining upper section.
The result is not true exchange level aggressor volume, but it is a practical candle anatomy based estimate of how much of the inversion bar behaved more like buying versus selling.
Then the script converts those raw buy and sell estimates into proportions:
p_bull
and
p_bear
Finally, it calculates p_str using the percentile rank of current volume over the last one hundred bars. That means the strength value is not just raw volume. It describes how relatively strong the inversion candle was compared with recent history.
4) Reading the Current Candle Metrics
= calc_metrics(open, high, low, close, volume)
This line applies the volumetric function to the current bar.
These three values are later attached to a new IFVG at the moment of inversion. So each active inverse gap inherits the participation and strength profile of the candle that caused the role reversal.
That is important conceptually. The internal bars inside the IFVG are not random decorations. They represent the inversion event itself.
5) Detecting Bullish and Bearish FVGs
bool bull_cond = strict_mode ? (low > high ) : (close > high )
bool bear_cond = strict_mode ? (high < low ) : (close < low )
This block defines the actual Fair Value Gap logic.
In strict mode:
a bullish gap exists only when the current low is above the high from two bars ago,
and a bearish gap exists only when the current high is below the low from two bars ago.
That means actual wick separation is required.
In non strict mode:
the script relaxes this and allows close based confirmation instead.
So the user can choose whether the script should only accept clean wick gaps or allow a softer close based definition.
6) Measuring the Gap Size
float gap_size = 0.0
if bull_cond and close > open
gap_size := low - high
if bear_cond and close < open
gap_size := low - high
bool is_significant = gap_size >= (atr_val * fvg_threshold_atr)
Once a candidate FVG is found, the script measures how large the gap actually is.
For bullish gaps, the size is the distance between the current low and the high from two bars ago.
For bearish gaps, the size is the distance between the low from two bars ago and the current high.
The script also adds a candle direction filter on the middle bar:
bullish gaps require the middle candle to be bullish,
and bearish gaps require the middle candle to be bearish.
Finally, the measured gap must be at least as large as:
ATR × threshold
This removes smaller gaps that may simply be noise.
7) Storing a Pending FVG
if is_significant
PendingFVG p = PendingFVG.new()
p.created_time := time
p.processed := false
if bull_cond
p.is_bull_gap := true
p.top := low
p.btm := high
else
p.is_bull_gap := false
p.top := low
p.btm := high
array.push(pending_fvgs, p)
If the gap is significant, the script stores it as a pending FVG.
The gap is not drawn yet as an inverse zone. Instead, it is placed into the pending list with:
its direction,
its boundaries,
its creation time,
and a flag showing it has not yet been processed.
This is important because an FVG only becomes an IFVG after it fails. The pending list is the waiting room for that future role reversal.
8) Detecting the Inversion Event
if array.size(pending_fvgs) > 0
for i = array.size(pending_fvgs) - 1 to 0
PendingFVG p = array.get(pending_fvgs, i)
if not p.processed
bool inverted = false
bool to_bull = false
if not p.is_bull_gap and close > p.top
inverted := true
to_bull := true
if p.is_bull_gap and close < p.btm
inverted := true
to_bull := false
This is the core IFVG transition logic.
A pending bearish FVG becomes a bullish IFVG if price closes above its top.
A pending bullish FVG becomes a bearish IFVG if price closes below its bottom.
That is the actual role reversal event. Price has invalidated the original imbalance from the opposite side, so the gap flips into an inverse form.
The to_bull flag determines the direction of the new inverse zone.
9) Creating the IFVG Object
if inverted
IFVG obj = IFVG.new()
obj.start_time := time
obj.origin_time := p.created_time
obj.top := p.top
obj.btm := p.btm
obj.is_bull_ifvg := to_bull
obj.pct_bull := curr_p_bull
obj.pct_bear := curr_p_bear
obj.pct_strength := curr_p_str
obj.active := true
obj.create_drawings()
array.push(active_ifvgs, obj)
p.processed := true
Once inversion is confirmed, the script creates the active IFVG.
The new object inherits:
the original FVG boundaries,
the original creation time,
the inversion start time,
and the new inverse direction.
It also stores:
the bullish participation percentage,
the bearish participation percentage,
and the strength percentage from the inversion candle.
So the IFVG is a structural object with a built in event profile. It tells the user not only where the failed gap is located, but also what the inversion bar looked like in participation terms.
10) Creating the Ghost Box and Main Container
if show_ghost
this.ghost_box := box.new(
left=this.origin_time,
top=this.top,
right=this.start_time,
bottom=this.btm,
border_color=color.new(c_border, 20),
border_width=1,
border_style=line.style_dashed,
bgcolor=c_ghost,
xloc=xloc.bar_time
)
this.container := box.new(
left=this.start_time,
top=this.top,
right=time,
bottom=this.btm,
border_color=c_border,
border_width=1,
bgcolor=color(na),
xloc=xloc.bar_time
)
This is the first part of the IFVG drawing engine.
If ghost mode is enabled, the script draws a dashed box from the original FVG creation time to the inversion time. This visually represents the original gap before it failed.
Then it creates the main IFVG container box starting from the inversion time and extending to the current bar.
So the chart can show both:
where the original gap existed,
and where the inverse zone now lives.
11) Building the Internal Volumetric Bar Areas
this.bg_bull := box.new(this.start_time, this.top, time, this.top, border_width=0, bgcolor=c_bg_dark, xloc=xloc.bar_time)
this.bar_bull := box.new(this.start_time, this.top, this.start_time, this.top, border_width=0, bgcolor=c_bull_bar, xloc=xloc.bar_time)
this.bg_bear := box.new(this.start_time, this.top, time, this.top, border_width=0, bgcolor=c_bg_dark, xloc=xloc.bar_time)
this.bar_bear := box.new(this.start_time, this.top, this.start_time, this.top, border_width=0, bgcolor=c_bear_bar, xloc=xloc.bar_time)
this.bg_str := box.new(this.start_time, this.top, time, this.top, border_width=0, bgcolor=c_bg_dark, xloc=xloc.bar_time)
this.bar_str := box.new(this.start_time, this.top, this.start_time, this.top, border_width=0, bgcolor=c_str_bar, xloc=xloc.bar_time)
Inside every IFVG, the script creates three horizontal rows.
Each row has:
a dark background box,
and a colored progress bar box.
The three rows represent:
bullish participation,
bearish participation,
and strength.
Initially these boxes are created with minimal size. Their real geometry is set later during updates.
So the IFVG is designed as a mini information panel embedded directly inside the zone.
12) Slicing the IFVG Into Three Metric Rows
float total_h = this.top - this.btm
float h_slice = total_h / 3
float y1 = this.top
float y2 = this.top - h_slice
float y3 = this.top - 2 * h_slice
float y4 = this.btm
This block divides the IFVG vertically into three equal sections.
The full height of the box is measured, then split into thirds:
the first slice for bullish participation,
the second slice for bearish participation,
the third slice for strength.
This makes the internal visualization clean and consistent regardless of zone height.
13) Converting Percentages Into Horizontal Width
int now = time
int dur = now - this.start_time
if dur <= 0
dur := timeframe.in_seconds() * 1000
int w_bull = math.round(dur * this.pct_bull)
int w_bear = math.round(dur * this.pct_bear)
int w_str = math.round(dur * this.pct_strength)
This is how the script turns percentages into visible progress bars.
The available horizontal width is the elapsed time from the IFVG start to the current bar. That duration becomes the maximum usable width.
Then each stored metric is multiplied by that duration:
bullish percentage controls the bullish bar width,
bearish percentage controls the bearish bar width,
strength percentage controls the strength bar width.
So the internal bars behave like proportion meters stretched across the live duration of the zone.
14) Updating the Bull, Bear, and Strength Bars
this.bg_bull.set_left(this.start_time)
this.bg_bull.set_right(now)
this.bg_bull.set_top(y1)
this.bg_bull.set_bottom(y2)
this.bar_bull.set_left(this.start_time)
this.bar_bull.set_right(this.start_time + w_bull)
this.bar_bull.set_top(y1)
this.bar_bull.set_bottom(y2)
this.bg_bear.set_left(this.start_time)
this.bg_bear.set_right(now)
this.bg_bear.set_top(y2)
this.bg_bear.set_bottom(y3)
this.bar_bear.set_left(this.start_time)
this.bar_bear.set_right(this.start_time + w_bear)
this.bar_bear.set_top(y2)
this.bar_bear.set_bottom(y3)
this.bg_str.set_left(this.start_time)
this.bg_str.set_right(now)
this.bg_str.set_top(y3)
this.bg_str.set_bottom(y4)
this.bar_str.set_left(this.start_time)
this.bar_str.set_right(this.start_time + w_str)
this.bar_str.set_top(y3)
this.bar_str.set_bottom(y4)
These blocks physically place the three metric layers inside the IFVG.
Each background row spans the full current width of the active zone.
Each colored bar spans only the proportional amount determined by the stored metric.
So if bullish participation is high, the bullish bar stretches farther across its row. If strength is low, the strength bar remains shorter.
This gives the zone an at a glance internal profile.
15) Updating the Text Labels
this.lbl_bull.set_xy(center_x, mid_bull)
this.lbl_bull.set_text(str.format("Bull: {0}%", math.round(this.pct_bull * 100)))
this.lbl_bear.set_xy(center_x, mid_bear)
this.lbl_bear.set_text(str.format("Bear: {0}%", math.round(this.pct_bear * 100)))
this.lbl_str.set_xy(center_x, mid_str)
this.lbl_str.set_text(str.format("Str: {0}%", math.round(this.pct_strength * 100)))
The script also prints the numerical values inside the three rows.
Each label is placed at the center of its row and updated with the rounded percentage value.
So the user sees both:
the visual bar length,
and the exact stored percentage.
This makes the IFVG readable even when box width is large or when color alone is not enough.
16) IFVG Invalidation Logic
bool broken = false
if this.is_bull_ifvg and close < this.btm
broken := true
if not this.is_bull_ifvg and close > this.top
broken := true
if broken
this.active := false
this.remove()
An active IFVG only remains valid while price stays on the correct side of its structure.
For bullish IFVG:
if close falls below the bottom, the zone is broken.
For bearish IFVG:
if close rises above the top, the zone is broken.
When that happens, the IFVG is marked inactive and all associated objects are deleted.
So the indicator is not just drawing inverse gaps indefinitely. It actively monitors whether they continue to behave as valid reaction zones.
17) Display Limit Management
while array.size(active_ifvgs) > show_last_n
IFVG d = array.shift(active_ifvgs)
d.remove()
This final block controls how many IFVGs remain visible.
If the number of active inverse gaps exceeds the selected display limit, the oldest one is removed from the front of the array and all of its drawings are deleted.
This keeps the chart focused on the most recent inverse gaps and prevents excessive visual clutter. Индикатор

Squeeze Impulse OscillatorSqueeze Impulse Oscillator (SIO)
Indicator Description
The Squeeze Impulse Oscillator is designed to detect moments when the market exits a consolidation phase (squeeze) and forms a strong impulsive move. The indicator analyzes candlestick patterns, the ratio of the body to the range, wick lengths, and price dynamics to assess the strength of the current trend and potential breakout from consolidation.
The core idea is to compare two components:
Impulse – shows how strong the price movement is, based on the body size relative to the range and the persistence of direction (consecutive bars in the same direction).
Squeeze – reflects the degree of market tightness, evaluated by wick length and range contraction. Longer wicks and narrower ranges indicate higher energy accumulation for a subsequent impulse.
The resulting SIO value = impulse − squeeze. Positive values indicate a dominance of the impulse component, negative values point to a squeeze phase. Additional threshold levels help identify confident impulse zones and extreme squeeze zones.
How It Works
Candle Evaluation
Relative body size (bodyEff) – ratio of the candle body to its full range. Larger body means stronger impulse.
Wick ratio (wickRatio) – total wick length relative to the range. Long wicks indicate indecision or accumulation.
Current range compared to its average (rangeRatio) – helps incorporate volatility.
Price Dynamics
Persistence factor (persist) equals 1 if the last two price changes are in the same direction, otherwise 0.
Component Calculation
impulseScore = bodyEff × rangeRatio × (0.5 + 0.5 × persist)
squeezeScore = wickRatio × (2.0 − rangeRatio) × (1.0 − persist × 0.5)
Oscillator
rawSIO = impulseScore − squeezeScore
Final sio value is smoothed with an exponential moving average (EMA) using the specified smoothing period.
Squeeze Counter
When sio drops below the squeeze threshold (i_sqzTh), a consecutive bar count begins. The counter resets when sio rises above zero.
Additional Line
Averaged wick bias (avgWickBias) is displayed, showing which side has longer wicks (positive → bullish bias, negative → bearish bias). Used for signal filtering.
Signals
The indicator generates three types of signals (enabled via Show Signals parameter):
Bull Impulse – green triangle at the bottom.
Conditions:
sio crosses above the impulse threshold (i_impTh);
preceded by at least the minimum number of squeeze bars (Min Squeeze Bars);
wick bias positive (avgWickBias > 0).
Interpretation: after a prolonged squeeze phase, price starts moving up, confirmed by bullish candle structure.
Bear Impulse – red triangle at the bottom.
Same conditions but wick bias ≤ 0.
Interpretation: expected downward move after a squeeze.
Squeeze Start – purple diamond at the top.
Occurs when sio crosses below the squeeze threshold. Warns of possible energy accumulation and an upcoming impulse.
Visual Elements
SIO Histogram – colored according to the state:
bright green/red (depending on candle direction) – above impulse threshold;
purple – below squeeze threshold;
gray – neutral zone.
Wick Bias Line (yellow) – scaled for better visibility.
Squeeze Counter – purple step line showing consecutive bars in squeeze.
Background Highlight – squeeze zones are marked with a semi‑transparent purple background.
Horizontal Levels: impulse threshold, zero line, squeeze threshold.
Input Parameters
Core
Period – period for average range calculation and wick bias moving average.
Smoothing – EMA smoothing of the final SIO value.
Impulse Threshold – level above which the value is considered impulsive.
Squeeze Threshold – level below which the value is considered a squeeze.
Signals
Show Signals – enable/disable signal plotting.
Min Squeeze Bars – minimum number of consecutive squeeze bars required for an impulse signal.
Highlight Squeeze Zones – enable/disable background highlighting.
Colors – custom colors for all visual elements.
Usage
The indicator helps identify entry points after consolidation phases. Buy/sell signals should be considered only with confirming factors: higher‑timeframe trend, volume, support/resistance levels. False signals may occur in low‑volatility markets or during news events. It is recommended to backtest and adapt thresholds for the specific instrument.
Disclaimer
This indicator is not financial advice. All calculations are based on historical data and do not guarantee future results. Use it as one of many analytical tools in combination with other methods. Индикатор
