Indicator

Swing Trader's Buy Signal
A Buy or Strong Buy signal triggers when multiple independent technical factors align simultaneously. Instead of relying on a single indicator (which often produces false signals), this dashboard evaluates confluent technical layers: Macro Trend, Short-Term Momentum, Institutional Volume, and Relative Strength.
Breakdown of Dashboard Elements
Trend (Overall Structure)
What it checks: Confirms whether Price > SMA20 > SMA50 > SMA200.
Why it triggers a Buy: Institutional traders trade in the direction of the macro trend. A bullish trend hierarchy ensures you are not buying into a falling knife or fighting a broader downtrend.
RSI (Relative Strength Index)
What it checks: Measures price momentum speed (RSI > 50 gives +1 pt, RSI > 60 gives +1 pt).
Why it triggers a Buy: An RSI above 50 indicates buyers are in control of momentum. Crossing above 60 signifies accelerating momentum without entering extreme overbought exhaustion.
Stoch RSI (Stochastic RSI Crossover)
What it checks: Evaluates if the Fast line %K is above %D (k > d) and recovering from oversold territory (k > 20).
Why it triggers a Buy: RSI provides the macro momentum, but Stoch RSI provides precise swing timing. A bullish %K > %D crossover pinpoints the exact moment a brief pullback ends and the upward swing resumes.
RS vs SPY (Relative Strength vs. Benchmark)
What it checks: Compares the asset's performance directly against the market index (AMEX:SPY).
Why it triggers a Buy: Outperforming stocks lead market rallies. Positive RS momentum (+1 to +2 pts) confirms that institutions are actively accumulating this specific asset faster than the broader market.
Price > SMA20 (Short-Term Trend Filter)
What it checks: Verifies if current price is trading above its 20-period Simple Moving Average.
Why it triggers a Buy: The 20 SMA represents the short-term swing baseline. Trading above it confirms immediate buyer control and validates short-term breakout momentum.
Price > SMA50 (Medium-Term Trend Filter)
What it checks: Verifies if current price is trading above its 50-period Simple Moving Average.
Why it triggers a Buy: The 50 SMA is the primary benchmark for institutional support. Staying above this level proves medium-term pullbacks are being bought rather than sold.
Volume (Institutional Participation)
What it checks: Compares current bar volume against its 20-period average (HIGH = >120%, VERY HIGH = >150%).
Why it triggers a Buy: Price moves without high volume lack conviction. Above-average volume confirms "smart money" accumulation, providing the fuel required for a sustained breakout.
Score (Confluence Aggregator)What it checks: Sums up the binary conditions across all indicators (Maximum score = 11).
Why it triggers a Buy: A BUY requires a score $\ge 7$ alongside an early bull trend, while a STRONG BUY requires a score $\ge 9$ with fully aligned trends, relative strength, and RSI momentum. This eliminates guesswork by requiring a strict mathematical majority of positive technical factors before triggering an entry.
Indicator

Indicator

SMC Swing Structure + Order Blocks + CHoCH VolumeOrderBlock Radar — SMC Swing & Volume CHoCH
A Smart Money Concepts (SMC) toolkit that maps market structure and order blocks the way institutional order flow is typically read — without drowning your chart in noise from minor pivots.
What it does:
📊 Swing Structure (BOS / CHoCH) — Tracks the market's real trend using major swing highs and lows, not every small wiggle. A break with the trend is marked BOS (Break of Structure); a break against the trend is marked CHoCH (Change of Character) — the earliest, most reliable signal that momentum may be shifting.
📦 Order Blocks — Automatically plots the last opposing candle before each structural break — the classic "footprint" of where smart money likely entered before the move. Boxes extend forward and auto-delete once price mitigates them, so your chart only shows blocks that are still relevant.
🔊 Volume-Confirmed CHoCH — Not all character changes are equal. This indicator checks volume against its recent average at the moment of a CHoCH — when a break comes with a volume spike, it's tagged separately ("CHoCH ⚡Vol") and fires its own dedicated alert, helping you filter high-conviction reversals from low-volume fakeouts.
🔔 Built-in Alerts — Six alert conditions ready to go: bullish/bearish CHoCH, bullish/bearish CHoCH with volume confirmation, and bullish/bearish BOS. Set them once and get pinged the moment structure shifts.
Customizable settings:
Swing pivot sensitivity (how "major" a swing needs to be to count)
Optional internal (minor) structure overlay for extra context
Order block count limits, lookback range, and mitigation method (wick vs. close)
Volume average length and spike threshold
Full color and label control
How to use it: Best used as a structural context tool — combine CHoCH signals with your own entry confirmation (order block retest, FVG fill, liquidity sweep, etc.) rather than trading the label in isolation. Works on any timeframe and asset class; higher timeframes and liquid instruments tend to give the cleanest structure.
This is a technical analysis tool, not financial advice — always manage risk and confirm signals with your own strategy. Indicator

Key Levels Zone v1.5KEY LEVEL ZONE SUITE v1.5
The Key Level Zone Suite is a multi-timeframe market-structure indicator designed to organize important price levels into customizable zones instead of single horizontal lines.
The indicator combines session levels, daily reference levels, supply and demand, repeated-touch support and resistance, and confirmed swing points in one clean system. Every category can be independently enabled, customized, limited, and managed after price breaks through it.
Its purpose is to help traders identify areas where price may react, reject, consolidate, break, or reverse—while reducing chart clutter on lower timeframes.
FEATURES
SESSION OPEN ZONES
The indicator can display the exact opening prices of:
• Asia
• London
• New York
Each opening price is expanded into an adjustable zone. Opening prices are calculated using internal 1-minute data, helping maintain accurate session opens when the indicator is viewed on higher-timeframe charts.
Each session-open zone includes independent controls for:
• Visibility
• Session time
• Zone thickness in ticks
• Horizontal projection length
• Fill and border colors
• Maximum number of zones
• Text visibility
• Broken-zone behavior
Session-open zones are disabled by default but can be enabled individually.
SESSION HIGH AND LOW ZONES
The indicator can display completed high and low zones from the:
• Asia session
• London session
• New York session
For each session, traders can choose:
• Today
• Yesterday
• Both
Today’s high and low are added only after the selected session finishes. This prevents a developing session range from being mistaken for a finalized level.
Older session ranges are automatically cleared, preventing multiple days of session highs and lows from accumulating across the chart.
DAILY AND WEEKLY KEY LEVELS
The indicator includes:
• Daily Open
• Previous-Day High
• Previous-Day Low
• Previous Monday High
• Previous Monday Low
The Daily Open is calculated from the customizable trading-day session. By default, it uses the futures-style trading day beginning at 6:00 PM New York time.
Only the two newest Daily Open zones are retained, representing the current trading day and the previous trading day.
Previous-Day High and Low zones can be enabled when needed, with an adjustable number of previous-day sets.
The Monday levels represent the completed high and low from the latest Monday. Only the newest Monday pair is retained, so older Monday zones do not fill the chart.
SUPPLY AND DEMAND ZONES
Supply and demand zones are created from confirmed pivot points that produce a required move away from the area.
A supply zone requires:
• A confirmed pivot high
• A bearish move away from the pivot
• A move meeting the selected ATR-strength requirement
A demand zone requires:
• A confirmed pivot low
• A bullish move away from the pivot
• A move meeting the selected ATR-strength requirement
Supply and demand have their own calculation timeframe. This allows a trader to display zones from one selected timeframe while changing the chart timeframe.
For example, supply and demand can remain calculated from the 2-hour chart while the trader moves down to a 5-minute, 2-minute, or 1-minute execution chart.
Adjustable settings include:
• Calculation timeframe
• Pivot strength
• ATR length
• Required ATR move away
• Zone thickness
• Projection length
• Supply and demand colors
• Maximum supply zones
• Maximum demand zones
• Broken-zone behavior
• Text visibility
The default profile displays a maximum of four supply zones and four demand zones.
SUPPORT AND RESISTANCE ZONES
Support and resistance zones are created from repeated confirmed pivots near the same price.
A zone is displayed only after the required number of touches occurs within the selected tick tolerance.
Resistance is formed from matching pivot highs, while support is formed from matching pivot lows.
Adjustable settings include:
• Independent calculation timeframe
• Pivot bars to the left and right
• Minimum number of touches
• Matching tolerance in ticks
• Zone thickness
• Projection length
• Maximum support and resistance zones
• Colors and transparency
• Broken-zone behavior
• Text visibility
Because support and resistance use an independent source timeframe, their zones remain consistent when changing chart timeframes.
SWING-HIGH AND SWING-LOW ZONES
Confirmed swing highs and swing lows can also be displayed as zones.
These levels use adjustable pivot confirmation and an independent calculation timeframe.
Swing zones are disabled by default to keep the starting chart clean. They can be enabled when a trader wants additional market-structure levels.
MULTI-TIMEFRAME ZONES
Supply and demand, support and resistance, and swing zones each have independent calculation timeframes.
The selected source timeframe controls where the zone is created—not the current chart timeframe.
For example:
• Set supply and demand to 120 minutes
• Set support and resistance to 2 minutes
• View the chart on 1, 2, 5, or 15 minutes
The supply and demand zones will continue to represent the 2-hour structure, while support and resistance will continue to represent the 2-minute structure.
For multi-timeframe structural zones, projection length is measured using bars from the selected calculation timeframe.
ZONE-BREAK CONFIRMATION
A zone can be considered broken using either:
• Close
• Wick
Close mode waits for a candle to close beyond the zone and break buffer. This is the more conservative setting and helps prevent a temporary wick from invalidating a zone.
Wick mode considers the zone broken when the candle’s high or low crosses completely through the zone and buffer.
An adjustable break buffer, measured in ticks, can help prevent small overshoots or liquidity sweeps from immediately invalidating a level.
BROKEN-ZONE OPTIONS
Every category includes independent behavior for zones that are broken:
DELETE
The zone is completely removed from the chart.
FREEZE
The zone stops extending at the candle that broke it and remains visible for review.
SHORTEN
The zone stops actively extending and keeps only the selected number of bars after the break.
For example, an active zone projecting 20 bars ahead can be shortened to 10 bars after it breaks.
KEEP
The zone stops actively updating but retains its existing endpoint.
Broken zones can also use a separate fill color so traders can distinguish invalidated levels from active zones.
ZONE RETENTION AND CHART CLEANUP
The indicator contains several controls designed to keep lower-timeframe charts organized:
• Adjustable calendar-day history
• Global maximum number of zones
• Independent limits for each structural category
• Only two Daily Opens retained
• Only the latest Monday High and Low retained
• Today, Yesterday, or Both session-range selection
• Independent text switches
• Automatic removal of older zones
The default history is seven calendar days.
When a structural category exceeds its selected maximum, the indicator removes broken zones first. If no broken zones remain, it removes the oldest active zone.
This helps preserve the newest and most relevant active areas.
ZONE TEXT CONTROLS
Zone labels can be controlled using:
• A master text switch
• Session-open text
• Session high/low text
• Daily and weekly level text
• Supply and demand text
• Support and resistance text
• Swing-zone text
Turning off the text does not remove the zones. It only hides their labels, allowing for a cleaner visual layout.
ALERTS
The indicator can generate an alert whenever an active zone is broken.
To use this feature:
1. Enable “Alert when a zone breaks” in the indicator settings.
2. Open PulseWire’s alert window.
3. Select the Key Level Zone Suite.
4. Choose “Any alert() function call.”
5. Select the desired alert frequency and notification method.
HOW TO USE THE INDICATOR
1. SET THE CORRECT TIMEZONE AND SESSIONS
Begin by confirming the session timezone. The default is America/New_York.
The default session times are designed around futures trading:
• Asia: 6:00 PM–3:00 AM
• London: 3:00 AM–9:30 AM
• New York: 9:30 AM–4:59 PM
• Trading day: 6:00 PM–5:00 PM
Session behavior can vary by market, exchange, daylight-saving changes, and personal trading plan. Adjust these values when trading instruments that use different session schedules.
2. CHOOSE THE LEVELS YOU NEED
Avoid enabling every available zone at once.
A clean intraday setup can include:
• Asia High and Low
• London High and Low
• Yesterday’s New York High and Low
• Current and previous Daily Open
• Previous Monday High and Low
• Higher-timeframe supply and demand
• Lower-timeframe support and resistance
Swing zones and session opens can be added when the trading plan specifically uses them.
3. USE HIGHER-TIMEFRAME SUPPLY AND DEMAND FOR CONTEXT
The default supply and demand timeframe is 2 hours.
These zones can be used to identify broader areas where a significant reaction may occur. Traders can then move to a lower timeframe and look for entry confirmation inside or near the higher-timeframe zone.
Supply can act as a potential resistance area. Demand can act as a potential support area.
These areas should not automatically be treated as entry signals.
4. USE SESSION LEVELS FOR INTRADAY LIQUIDITY
Session highs and lows often represent important intraday liquidity areas.
Watch how price behaves when it approaches:
• Asia High or Low
• London High or Low
• Previous New York High or Low
• Daily Open
• Previous Monday High or Low
Price may reject the level, sweep beyond it and return, consolidate inside it, or break through it with momentum.
5. LOOK FOR CONFLUENCE
A zone becomes more meaningful when multiple independent factors appear near the same price.
Examples include:
• London Low overlapping a demand zone
• Asia High overlapping resistance
• Daily Open inside a support zone
• Previous Monday High near supply
• A session liquidity sweep followed by a market-structure shift
Overlapping zones do not guarantee a trade, but they can help identify areas that deserve closer attention.
6. WAIT FOR PRICE CONFIRMATION
The indicator identifies areas of interest; it does not produce automatic buy or sell signals.
Possible confirmation can include:
• Strong rejection candle
• Hammer or shooting-star formation
• Engulfing candle
• Liquidity sweep and close back inside the zone
• Break of structure
• Change of character
• Increase in volume
• Delta shift
• Retest after a confirmed breakout
Entering only because price touches a zone can expose the trader to levels that are being broken rather than respected.
7. PLACE RISK OUTSIDE THE ZONE
When using a zone for an entry, the invalidation point is commonly placed beyond the opposite side of the zone with an additional tick buffer.
The exact stop distance should account for:
• Instrument volatility
• Zone thickness
• Current ATR
• Session conditions
• The trader’s maximum allowed risk
A wider zone requires different risk management than a narrow zone.
8. USE THE NEXT OPPOSING ZONE AS A REFERENCE
Potential targets can be based on the next opposing area.
For a long setup, possible references include:
• Resistance
• Supply
• Session High
• Previous-Day High
• Previous Monday High
For a short setup, possible references include:
• Support
• Demand
• Session Low
• Previous-Day Low
• Previous Monday Low
Always confirm that the available distance supports the minimum risk-to-reward ratio required by the trading plan.
DEFAULT SETUP
The included default profile is designed to provide useful structure without displaying every possible level.
The main defaults include:
• Seven calendar days of history
• Maximum of 50 total zones
• Close-based break confirmation
• One-tick break buffer
• Session opening zones disabled
• Asia High and Low set to Today
• London High and Low set to Today
• New York High and Low set to Yesterday
• Daily Open enabled
• Previous-Day High and Low disabled
• Previous Monday High and Low enabled
• Supply and demand enabled on the 2-hour timeframe
• Maximum of four supply and four demand zones
• Support and resistance enabled on the 2-minute timeframe
• Maximum of two support and two resistance zones
• Swing zones disabled
• Supply, demand, support, resistance, and swing text hidden
IMPORTANT NOTES
Confirmed pivot-based zones require bars to the right of the pivot. This means supply, demand, support, resistance, and swing zones appear only after their pivot conditions have been confirmed.
Session highs and lows appear after their session finishes because the final high and low cannot be known while the session is still active.
The indicator is best used as a mapping and confluence tool alongside price action, market structure, volume, and disciplined risk management.
No zone guarantees a reversal. Strong momentum can break through any level, and a broken zone does not automatically confirm that price will continue in the same direction.
This indicator is intended for educational and analytical purposes only. It does not provide financial advice or guarantee future trading performance.
Indicator

Indicator

Auto Pattern Detector Targets [MarkitTick] Thinh 9/8/26Pivot Lookback Right: 10, 23
● Các mô hình được phát hiện
Đỉnh đôi: Mô hình đảo chiều giảm giá bao gồm hai đỉnh liên tiếp ở gần cùng mức giá, báo hiệu sự cạn kiệt xu hướng tiềm năng.
Đáy đôi: Mô hình đảo chiều tăng giá với hai đáy liên tiếp ở các mức tương tự, cho thấy sự chuyển dịch tiềm năng từ áp lực bán sang áp lực mua.
Đỉnh ba: Mô hình đảo chiều giảm giá được đánh dấu bằng ba đỉnh riêng biệt ở mức kháng cự tương tự, phản ánh sự thất bại liên tục trong việc phá vỡ mức cao hơn.
Đáy ba: Mô hình đảo chiều tăng giá được đặc trưng bởi ba đáy liên tiếp ở mức hỗ trợ tương tự, cho thấy sự tích lũy mạnh mẽ.
Đầu và Vai: Mô hình đảo chiều giảm giá cổ điển với một đỉnh trung tâm cao hơn được bao quanh bởi hai đỉnh thấp hơn, thể hiện sự mất đà tăng.
Đầu và Vai ngược: Mô hình đảo chiều tăng giá bao gồm một đáy trung tâm thấp hơn được bao quanh bởi hai đáy cao hơn, cho thấy sự chuyển dịch sang xu hướng tăng.
Cờ tăng giá: Mô hình tiếp diễn ngắn hạn được hình thành bởi sự tăng giá mạnh mẽ tiếp theo là sự tích lũy hẹp, dốc xuống.
Cờ giảm giá (Bearish Flag): Mô hình tiếp diễn xảy ra trong xu hướng giảm, trong đó sự giảm mạnh được theo sau bởi một giai đoạn tích lũy hẹp, dốc lên.
Cờ hiệu tăng giá (Bullish Pennant): Mô hình tiếp diễn được xác định bởi sự tăng mạnh, tiếp theo là giai đoạn tích lũy hình tam giác hội tụ đối xứng. Cờ hiệu
giảm giá (Bearish Pennant): Mô hình tiếp diễn có đặc điểm là sự giảm mạnh, tiếp theo là sự hình thành hình tam giác hội tụ trước khi tiếp tục giảm.
Nêm tăng (Rising Wedge): Mô hình đảo chiều hoặc tiếp diễn, trong đó giá tích lũy giữa các đường xu hướng hội tụ dốc lên, thường báo hiệu sự suy yếu tiềm tàng.
Nêm giảm (Falling Wedge): Mô hình được hình thành bởi các đường xu hướng hội tụ dốc xuống, thường là tiền thân của một sự đột phá tăng giá.
Tam giác (Triangle): Giai đoạn tích lũy, trong đó giá thu hẹp giữa các đường xu hướng hội tụ, cho thấy sự đột phá sắp xảy ra (Tăng dần, Giảm dần hoặc Đối xứng).
Hình chữ nhật (Rectangle): Phạm vi giao dịch, trong đó giá di chuyển theo chiều ngang giữa các mức hỗ trợ và kháng cự song song, cho thấy sự lưỡng lự trước khi đột phá.
Cốc và tay cầm (Cup and Handle): Mô hình tiếp diễn tăng giá giống như một chiếc cốc, tiếp theo là sự giảm giá nhẹ, cho thấy tiềm năng cho một đợt tăng giá mới.
Mô hình Cốc và Tay cầm ngược: Một mô hình tiếp diễn giảm giá được hình thành bởi một chiếc cốc và tay cầm ngược, báo hiệu áp lực giảm giá.
## Chiến lược Mục tiêu Mô hình Tự động — bởi Code2trade
Chiến lược **Auto Pattern Detector Targets** tự động quét thị trường để tìm **16 mô hình biểu đồ kinh điển**, bao gồm Đỉnh & Đáy đôi, Đỉnh & Đáy ba, Vai & Đầu, Vai & Đầu ngược, Cờ, Cờ hiệu, Nêm, Tam giác, Hình chữ nhật, Cốc & Tay cầm, và nhiều hơn nữa.
Khi một tín hiệu phá vỡ hợp lệ được xác nhận bằng cách sử dụng các bộ lọc tích hợp của chiến lược, một thiết lập giao dịch hoàn chỉnh sẽ được tạo ra với các mức **Vào lệnh**, **Cắt lỗ** và **Chốt lời** được xác định trước dựa trên mức độ di chuyển được đo lường của mô hình được phát hiện.
### Cách thức hoạt động
* Liên tục phát hiện các mô hình biểu đồ có xác suất cao bằng cách sử dụng các điểm xoay.
* Chờ tín hiệu phá vỡ được xác nhận trước khi tạo tín hiệu.
* Tự động tính toán Điểm vào lệnh, Cắt lỗ và Mục tiêu.
* Mở vị thế Mua cho các tín hiệu phá vỡ tăng giá và vị thế Bán cho các tín hiệu phá vỡ giảm giá.
* Sử dụng mức Cắt lỗ dựa trên mô hình ban đầu và Mục tiêu được đo lường từ chỉ báo.
* Tùy chọn thoát khỏi vị thế hiện có khi xuất hiện tín hiệu ngược chiều.
### Logic giao dịch mặc định
* **Vào lệnh:** Lệnh thị trường sau khi tín hiệu phá vỡ được xác nhận.
* **Cắt lỗ:** Mức vô hiệu hóa mô hình.
* **Chốt lời:** Mục tiêu di chuyển được tính toán từ mô hình đã phát hiện.
* **Quy mô vị thế:** Số lượng cố định (mặc định là 1 hợp đồng).
* **Gia tăng vị thế:** Đã tắt.
### Các tính năng chính
* Nhận diện mô hình hoàn toàn tự động.
* Thực hiện giao dịch khách quan, dựa trên quy tắc.
* Loại bỏ việc vẽ mô hình chủ quan.
* Hỗ trợ cả giao dịch Mua và Bán.
* Được xây dựng trực tiếp từ logic chỉ báo gốc mà không thay đổi quy trình tạo tín hiệu.
### Tuyên bố miễn trừ trách nhiệm rủi ro
Chiến lược này chỉ dành cho mục đích giáo dục và nghiên cứu. Kết quả kiểm thử ngược trong quá khứ không đảm bảo hiệu suất trong tương lai. Luôn luôn tự mình kiểm thử và áp dụng quản lý rủi ro thích hợp trước khi sử dụng chiến lược trên thị trường thực tế. Strategy

Indicator

Indicator

Indicator

Target Trend ProEnhanced trend-following tool with automated entry signals, stop loss, three profit targets, filters, and live dashboard.
🎯 Target Trend Pro
An enhanced and expanded version of the original Target Trend concept by BigBeluga.
This indicator helps traders identify trend direction and manage trades visually with clear entry signals, stop loss, and three customizable take-profit levels — all displayed directly on the chart.
══════════════════════════════════════
🔵 KEY FEATURES
══════════════════════════════════════
• Adaptive SMA ± ATR bands for trend detection
• Automatic Long / Short entry triangles
• Three fixed Take Profit levels (ATR-based)
• Dynamic or fixed Stop Loss (with optional trailing)
• Live Dashboard showing:
- Entry, SL, TP1/TP2/TP3 with distance %
- Risk:Reward ratio
- ADX status
- Bars in trade
- Current trade status
• Filters:
- ADX Filter
- Higher Timeframe confirmation
- Volume Filter
• Clean visual management (lines, labels, fills)
• Full alert support (Entry + TP hits + SL hit)
══════════════════════════════════════
🔵 HOW IT WORKS
══════════════════════════════════════
1. Trend is detected when price crosses the adaptive SMA bands.
2. On a confirmed trend change, the indicator plots:
- Entry level
- Stop Loss
- Three Take Profit targets
3. Targets are calculated using ATR at the moment of the signal (fixed).
4. The dashboard updates in real time with trade progress.
5. Optional filters help reduce low-quality signals.
══════════════════════════════════════
🔵 SETTINGS OVERVIEW
══════════════════════════════════════
• Trend Length & ATR settings → Control sensitivity
• TP1 / TP2 / TP3 Multipliers → Customize target distances
• Trailing Stop → Optional dynamic stop loss
• ADX / HTF / Volume filters → Improve signal quality
• Display options → Dashboard position, line extension, etc.
══════════════════════════════════════
🔵 CREDITS
══════════════════════════════════════
Original concept: Target Trend by BigBeluga
This version is a heavily enhanced and expanded modification released for free under the same Creative Commons Attribution-NonCommercial-ShareAlike 4.0 license.
Please keep credits if you share or modify this script.
══════════════════════════════════════
⚠️ DISCLAIMER
══════════════════════════════════════
This indicator is for educational and informational purposes only.
It does not constitute financial advice. Always do your own research and manage risk properly. Indicator

Indicator

Fair Value Gap Strategy with Break of Structure ConfirmationDescription:
Fair Value Gaps are one of the most discussed concepts in modern price action trading, and one of the most misunderstood. Most traders who learn about FVGs start marking every three-candle imbalance they can find and entering every time price returns to one. The results are typically poor — not because the concept is wrong, but because the context around the FVG determines almost everything about whether it will hold or fail.
This strategy is built around one specific idea: a Fair Value Gap is only worth trading when it forms in the direction of a confirmed Break of Structure. Without that structural context, an FVG is just a gap in price — interesting, but not tradable on its own.
What a Fair Value Gap actually is
A Fair Value Gap forms when three consecutive candles create a price zone that the middle candle's body does not overlap. Specifically: the high of the first candle is below the low of the third candle (bullish FVG), or the low of the first candle is above the high of the third candle (bearish FVG). The gap represents a price range where no two-way trading occurred — price moved through it so quickly, driven by aggressive one-directional orders, that the normal auction process was bypassed. When price returns to that zone, the institutional logic is that unfilled orders from the original move are still resting there, creating a reaction point.
The reason most traders misuse FVGs is that they treat them as generic support and resistance. They are not. An FVG formed during a weak, low-conviction move in a choppy market has almost no institutional significance. An FVG formed during an aggressive displacement move that also breaks market structure, that is a different animal entirely.
What a Break of Structure is
Break of Structure (BOS) is the confirmation that the current swing direction has been validated by price taking out the most recent swing high (in an uptrend) or swing low (in a downtrend). In a series of higher highs and higher lows, each break above the prior swing high is a BOS confirming the uptrend. A BOS tells you the market is making a committed directional statement, not oscillating within a range.
The reason BOS matters for FVG trading is displacement. An aggressive candle that creates a BOS almost always leaves a Fair Value Gap behind it, the candle moves so fast that a price imbalance forms in its wake. That FVG is structurally significant because it was created by the same momentum that just confirmed the trend direction. When price returns to fill that gap, it is returning to the exact zone where institutional momentum entered the market and structural commitment was made.
How the strategy works
The strategy identifies bullish FVGs formed during upward BOS moves and bearish FVGs formed during downward BOS moves. A bullish FVG entry fires when price retraces into the gap after a confirmed bullish BOS, the high of candle one is plotted as the upper boundary, and price closing back inside that zone triggers the long entry. The stop is placed below the low of the FVG zone. The target is set at a 2x ATR multiple from the entry, scaled to current volatility rather than a fixed distance.
The BOS confirmation uses swing high and swing low detection with a defined lookback period. Only FVGs that form within a specified number of bars after a BOS are considered valid, older gaps that formed long before the most recent structural move are not traded, since the institutional orders that created them have likely already been filled or cancelled.
Why FVGs fail and how this addresses it
The most common failure mode for FVG strategies is trading imbalances in ranging, low-conviction markets where no structural context exists. The BOS filter directly addresses this by requiring that a swing high or low has been broken with enough conviction to register a structural shift before any FVG is considered valid. The second most common failure is holding positions through the entire FVG zone hoping for a reversal, this strategy enters at the gap boundary and exits at a defined ATR target rather than waiting for a full reversal, which keeps the average trade duration shorter and reduces exposure to the next structural shift invalidating the position.
What to examine in backtesting
FVG strategies are particularly sensitive to the lookback period used for swing detection and the maximum bar age allowed for a gap to remain valid. Shorter lookbacks detect more swing points and more FVGs but include lower-quality setups. Longer lookbacks produce fewer, higher-conviction structural shifts but generate fewer trades, which makes backtesting more difficult due to small sample sizes. Run the strategy across at least 200 completed trades before drawing any performance conclusions, and test separately across trending and ranging market environments. FVGs in ranging markets without genuine displacement will produce consistently poor results regardless of parameter tuning, this is expected behavior, not a failure of the strategy.
Shared for educational purposes and community discussion. This is not investment advice. Always backtest on your own instruments and timeframes with realistic commission assumptions before evaluating performance. Strategy

Indicator

Indicator

V6 ORB Retest NY Session// ORB Retest — NY Session (MNQ)
// Live companion to the walk-forward-validated strategy in orb_retest.py.
//
// Draws and alerts only. It never places an order.
//
// DESIGNED FOR A 5-MINUTE CHART. The strategy was validated on 5-minute bars;
// on any other timeframe the breakout/retest granularity differs from what was
// tested, so the panel shows a warning.
//
// Session times are pinned to America/New_York, so the 9:30 ET open is located
// correctly no matter what timezone your chart displays, and DST is handled
// automatically. No chart timezone change needed.
//
// Install: PulseWire -> Pine Editor -> paste -> Save -> Add to chart.
//@version=6
indicator("ORB Retest — NY Session", "ORB Retest", overlay = true,
max_boxes_count = 500, max_lines_count = 500, max_labels_count = 500)
// ───────────────────────── Inputs ─────────────────────────
grpS = "Session (always New York time)"
orSessionInput = input.session("0930-0945", "Opening range window", group = grpS, display = display.none)
tradeSessionInput = input.session("0930-1555", "Trading session (flat at end)", group = grpS, display = display.none)
cutoffInput = input.session("0930-1200", "Breakout must occur before", group = grpS, display = display.none)
grpR = "Trade rules"
targetR = input.float(2.5, "Target (multiple of risk)", minval = 0.5, step = 0.5, group = grpR,
tooltip = "2.5R tested best across both 2019-2026 and 2023-onward: target is hit on 48% of trades vs 38% at 3R, win rate 58% vs 52%, slightly more total profit and a smaller drawdown.",
display = display.none)
stopBufTicks = input.int(4, "Stop buffer beyond retest extreme (ticks)", minval = 0, group = grpR, display = display.none)
touchTolTicks = input.int(2, "Retest touch tolerance (ticks)", minval = 0, group = grpR, display = display.none)
invalTicks = input.int(4, "Invalidation buffer past level (ticks)", minval = 0, group = grpR, display = display.none)
retestDeadlineM = input.int(60, "Cancel if no retest within (minutes)", minval = 5, group = grpR, display = display.none)
maxRiskPts = input.float(0, "Skip if risk exceeds (points, 0 = no limit)", minval = 0, group = grpR,
tooltip = "Off by default. On a 5-minute chart a 40-point cap improved results (+0.72R to +0.80R, drawdown roughly halved). On a 15-minute chart stops are naturally wider and the same cap removes too many good trades, so leave it at 0 there.",
display = display.none)
grpF = "Day filter"
useRangeFilter = input.bool(true, "Skip days with unusual opening-range width", group = grpF, display = display.none)
rangeLookback = input.int(20, "Lookback (days)", minval = 5, group = grpF, display = display.none)
rangeMinMult = input.float(0.5, "Minimum multiple of average", step = 0.1, group = grpF, display = display.none)
rangeMaxMult = input.float(2.0, "Maximum multiple of average", step = 0.1, group = grpF, display = display.none)
grpV = "Display"
drawSessionInput = input.session("0930-1230", "Extend drawings during (NY time)", group = grpV,
tooltip = "Boxes and lines grow only inside this window, then freeze. Default = first 3 hours of the NY session, so old days stay compact.",
display = display.none)
keepDays = input.int(120, "Keep drawings for last N days", minval = 1, maxval = 250, group = grpV,
tooltip = "PulseWire caps an indicator at 500 drawings per type; at 4 lines per traded day that is roughly 125 days of full markup. Beyond the cap the oldest drawings drop off automatically.",
display = display.none)
pointValue = input.float(2.0, "Contract $ per point (MNQ = 2)", minval = 0.01, group = grpV, display = display.none)
showPanel = input.bool(true, "Show status panel", group = grpV, display = display.none)
showBox = input.bool(true, "Opening range box", group = grpV, display = display.none)
showLevels = input.bool(true, "Entry / stop / target lines", group = grpV, display = display.none)
showMarkers = input.bool(true, "Signal markers", group = grpV, display = display.none)
showLabels = input.bool(true, "Outcome labels", group = grpV, display = display.none)
showLegend = input.bool(true, "Show symbol legend (bottom-left)", group = grpV, display = display.none)
TZ = "America/New_York"
// ───────────────────── Session detection ─────────────────────
inOR = not na(time(timeframe.period, orSessionInput, TZ))
inTrade = not na(time(timeframe.period, tradeSessionInput, TZ))
beforeCut = not na(time(timeframe.period, cutoffInput, TZ))
inDraw = not na(time(timeframe.period, drawSessionInput, TZ))
orStart = inOR and not inOR
orEnd = not inOR and inOR
tradeEnd = not inTrade and inTrade
tick = syminfo.mintick
isFiveMin = timeframe.isminutes and timeframe.multiplier == 5
// Live-chart safety: every decision waits for the bar to CLOSE, exactly like
// the backtest. On the streaming realtime bar nothing updates until it
// confirms, so signals never appear and then vanish mid-bar (no repainting).
confirmed = barstate.isconfirmed
// ───────────────────────── State ─────────────────────────
// 0 = waiting for breakout, 1 = waiting for retest, 2 = in trade, 3 = done today
var int state = 0
var int armedDir = 0
var int armTime = na
var float orH = na
var float orL = na
var float orRange = na
var bool orReady = false
var bool dayEligible = false
var float retestExtreme = na
var float entryPrice = na
var float stopPrice = na
var float targetPrice = na
var float riskPts = na
var string outcome = "—"
var array orHistory = array.new_float()
// Drawing handles for the current day
var box orBox = na
var line levelLine = na
var line entryLine = na
var line stopLine = na
var line targetLine = na
// Rolling registry so old days' drawings get cleaned up instead of piling up.
var array boxReg = array.new()
var array lineReg = array.new()
var array labelReg = array.new()
// Signal flags at global scope so plotshape / alertcondition can read them.
bool sigBreakout = false
bool sigEntry = false
bool sigInvalidated = false
bool sigExpired = false
bool sigTargetHit = false
bool sigStopHit = false
// ───────────── Build the opening range, reset for a new day ─────────────
if orStart and confirmed
orH := high
orL := low
orReady := false
state := 0
armedDir := 0
dayEligible := false
retestExtreme := na
entryPrice := na
stopPrice := na
targetPrice := na
riskPts := na
outcome := "—"
levelLine := na
entryLine := na
stopLine := na
targetLine := na
else if inOR and confirmed
orH := math.max(orH, high)
orL := math.min(orL, low)
if orEnd and confirmed
orRange := orH - orL
orReady := true
// Compare today's range against the trailing average BEFORE adding it.
// Starts judging after 5 days of history (averaging what it has, up to the
// full lookback) — demanding all 20 up front left short-history charts,
// like 5-minute ones, permanently stuck in "filtered out".
int warmup = math.min(rangeLookback, 5)
float avgRange = array.size(orHistory) >= warmup ? array.avg(orHistory) : na
dayEligible := not useRangeFilter or (not na(avgRange)
and orRange >= avgRange * rangeMinMult
and orRange <= avgRange * rangeMaxMult)
array.push(orHistory, orRange)
if array.size(orHistory) > rangeLookback
array.shift(orHistory)
if not dayEligible
outcome := na(avgRange) and useRangeFilter ? "warming up — collecting history" : "day filtered out"
if showBox
orBox := box.new(bar_index - 1, orH, bar_index, orL,
border_color = dayEligible ? color.new(color.orange, 20) : color.new(color.gray, 65),
border_style = line.style_dashed, border_width = 1,
bgcolor = dayEligible ? color.new(color.orange, 90) : color.new(color.gray, 96))
array.push(boxReg, orBox)
if array.size(boxReg) > keepDays
box.delete(array.shift(boxReg))
// Stretch the box only inside the drawing window, then freeze it.
if showBox and inDraw and orReady and not na(orBox)
box.set_right(orBox, bar_index)
// ───────────────────── State machine ─────────────────────
if orReady and inTrade and dayEligible and confirmed
// ---- Waiting for a breakout CLOSE (wicks do not count) ----
if state == 0 and beforeCut
if close > orH
armedDir := 1
state := 1
armTime := time
retestExtreme := low
sigBreakout := true
outcome := "armed long — waiting for retest"
else if close < orL
armedDir := -1
state := 1
armTime := time
retestExtreme := high
sigBreakout := true
outcome := "armed short — waiting for retest"
if sigBreakout and showLevels
float lvl = armedDir == 1 ? orH : orL
levelLine := line.new(bar_index, lvl, bar_index, lvl,
color = color.orange, width = 2)
array.push(lineReg, levelLine)
// ---- Armed: waiting for price to come back and retest the level ----
else if state == 1
bool isLong = armedDir == 1
float lvl = isLong ? orH : orL
float invalLevel = isLong ? lvl - invalTicks * tick : lvl + invalTicks * tick
bool invalidated = isLong ? close < invalLevel : close > invalLevel
bool expired = (time - armTime) / 60000 > retestDeadlineM or not beforeCut
if invalidated
state := 3
sigInvalidated := true
outcome := "invalidated — closed back inside"
if not na(levelLine)
line.set_color(levelLine, color.new(color.gray, 40))
else if expired
state := 3
sigExpired := true
outcome := "no retest — expired"
if not na(levelLine)
line.set_color(levelLine, color.new(color.gray, 40))
else
// Track how far the pullback has run — this defines the stop.
retestExtreme := isLong ? math.min(retestExtreme, low) : math.max(retestExtreme, high)
float tol = touchTolTicks * tick
bool touched = isLong ? low <= lvl + tol : high >= lvl - tol
bool pierced = isLong ? low <= lvl - tick : high >= lvl + tick
if touched and pierced
float eP = lvl
float sP = isLong ? retestExtreme - stopBufTicks * tick
: retestExtreme + stopBufTicks * tick
float rk = isLong ? eP - sP : sP - eP
if rk > 0 and (maxRiskPts == 0 or rk <= maxRiskPts)
entryPrice := eP
stopPrice := sP
riskPts := rk
targetPrice := isLong ? eP + targetR * rk : eP - targetR * rk
state := 2
sigEntry := true
outcome := (isLong ? "LONG live" : "SHORT live")
if showLevels
entryLine := line.new(bar_index, entryPrice, bar_index, entryPrice,
color = color.blue, width = 2)
stopLine := line.new(bar_index, stopPrice, bar_index, stopPrice,
color = color.red, width = 1, style = line.style_dashed)
targetLine := line.new(bar_index, targetPrice, bar_index, targetPrice,
color = color.green, width = 1, style = line.style_dashed)
array.push(lineReg, entryLine)
array.push(lineReg, stopLine)
array.push(lineReg, targetLine)
if showLabels
label lb = label.new(bar_index, isLong ? low : high,
(isLong ? "LONG " : "SHORT ")
+ str.tostring(rk, format.mintick) + " pts ($"
+ str.tostring(rk * pointValue, "#.##") + ")",
yloc = isLong ? yloc.belowbar : yloc.abovebar,
style = isLong ? label.style_label_up : label.style_label_down,
size = size.small,
color = isLong ? color.new(color.green, 20) : color.new(color.red, 20),
textcolor = color.white)
array.push(labelReg, lb)
else
state := 3
outcome := rk <= 0 ? "skipped — no risk defined" : "skipped — risk too wide"
// ---- In the trade: stop or target first? ----
else if state == 2
bool isLong = armedDir == 1
bool hitStop = isLong ? low <= stopPrice : high >= stopPrice
bool hitTarget = isLong ? high >= targetPrice : low <= targetPrice
// If one bar spans both, assume the stop filled first (matches the backtest).
if hitStop
state := 3
sigStopHit := true
outcome := "stopped out (−1R)"
else if hitTarget
state := 3
sigTargetHit := true
outcome := "target hit (+" + str.tostring(targetR, "#.#") + "R)"
// Grow active lines only inside the drawing window (no infinite extend,
// and old days stay frozen at their 3-hour width).
if inDraw
if state == 1 and not na(levelLine)
line.set_x2(levelLine, bar_index)
if state == 2
if not na(entryLine)
line.set_x2(entryLine, bar_index)
if not na(stopLine)
line.set_x2(stopLine, bar_index)
if not na(targetLine)
line.set_x2(targetLine, bar_index)
// ---- Session over: anything still open is flattened ----
if tradeEnd and state == 2 and confirmed
state := 3
outcome := "flat — session end"
if showLabels
label lb2 = label.new(bar_index, close, "flat — session end", yloc = yloc.abovebar,
style = label.style_label_down, size = size.tiny,
color = color.new(color.gray, 35), textcolor = color.white)
array.push(labelReg, lb2)
// ---- Prune old drawings so the chart doesn't fill up ----
if array.size(lineReg) > keepDays * 4
line.delete(array.shift(lineReg))
if array.size(labelReg) > keepDays * 2
label.delete(array.shift(labelReg))
// ───────────────────────── Plots ─────────────────────────
plotshape(showMarkers and sigBreakout, "Breakout close", shape.triangleup,
location.belowbar, color.new(color.orange, 0), size = size.tiny, display = display.pane)
plotshape(showMarkers and sigEntry and armedDir == 1, "Long entry", shape.labelup,
location.belowbar, color.new(color.green, 0), text = "E", textcolor = color.white,
size = size.small, display = display.pane)
plotshape(showMarkers and sigEntry and armedDir == -1, "Short entry", shape.labeldown,
location.abovebar, color.new(color.red, 0), text = "E", textcolor = color.white,
size = size.small, display = display.pane)
plotshape(showMarkers and sigTargetHit, "Target hit", shape.xcross,
location.abovebar, color.new(color.green, 0), size = size.tiny, display = display.pane)
plotshape(showMarkers and sigStopHit, "Stop hit", shape.xcross,
location.belowbar, color.new(color.red, 0), size = size.tiny, display = display.pane)
plotshape(showMarkers and sigInvalidated, "Setup invalidated", shape.circle,
location.abovebar, color.new(color.gray, 25), size = size.tiny, display = display.pane)
plotshape(showMarkers and sigExpired, "No retest — expired", shape.square,
location.abovebar, color.new(color.gray, 25), size = size.tiny, display = display.pane)
// ───────────────────────── Status panel ─────────────────────────
var table panel = table.new(position.top_right, 2, 7,
border_width = 1, border_color = color.new(color.gray, 60),
frame_width = 1, frame_color = color.new(color.gray, 60))
if showPanel and barstate.islast
color hdrBg = color.new(color.gray, 85)
color cellBg = color.new(color.gray, 92)
table.cell(panel, 0, 0, "ORB Retest", text_size = size.small, text_color = color.gray,
bgcolor = hdrBg, text_halign = text.align_left)
table.cell(panel, 1, 0, isFiveMin ? "5m ✓" : "⚠ tested on 5m",
text_size = size.small, bgcolor = hdrBg,
text_color = isFiveMin ? color.green : color.orange, text_halign = text.align_right)
table.cell(panel, 0, 1, "Status", text_size = size.small, text_color = color.gray,
bgcolor = cellBg, text_halign = text.align_left)
table.cell(panel, 1, 1, outcome, text_size = size.small, bgcolor = cellBg,
text_color = state == 2 ? color.blue : color.gray, text_halign = text.align_right)
table.cell(panel, 0, 2, "Range high", text_size = size.small, text_color = color.gray,
bgcolor = cellBg, text_halign = text.align_left)
table.cell(panel, 1, 2, na(orH) ? "—" : str.tostring(orH, format.mintick),
text_size = size.small, bgcolor = cellBg, text_color = color.orange,
text_halign = text.align_right)
table.cell(panel, 0, 3, "Range low", text_size = size.small, text_color = color.gray,
bgcolor = cellBg, text_halign = text.align_left)
table.cell(panel, 1, 3, na(orL) ? "—" : str.tostring(orL, format.mintick),
text_size = size.small, bgcolor = cellBg, text_color = color.orange,
text_halign = text.align_right)
table.cell(panel, 0, 4, "Range width", text_size = size.small, text_color = color.gray,
bgcolor = cellBg, text_halign = text.align_left)
table.cell(panel, 1, 4, na(orRange) ? "—" : str.tostring(orRange, "#.##") + " pts",
text_size = size.small, bgcolor = cellBg, text_color = color.gray,
text_halign = text.align_right)
table.cell(panel, 0, 5, "Entry / Stop", text_size = size.small, text_color = color.gray,
bgcolor = cellBg, text_halign = text.align_left)
table.cell(panel, 1, 5, na(entryPrice) ? "—"
: str.tostring(entryPrice, format.mintick) + " / " + str.tostring(stopPrice, format.mintick),
text_size = size.small, bgcolor = cellBg, text_color = color.gray,
text_halign = text.align_right)
table.cell(panel, 0, 6, "Risk", text_size = size.small, text_color = color.gray,
bgcolor = cellBg, text_halign = text.align_left)
table.cell(panel, 1, 6, na(riskPts) ? "—"
: str.tostring(riskPts, "#.##") + " pts $" + str.tostring(riskPts * pointValue, "#.##"),
text_size = size.small, bgcolor = cellBg, text_color = color.red,
text_halign = text.align_right)
// ───────────────────────── Symbol legend ─────────────────────────
var table legend = table.new(position.bottom_left, 4, 7,
border_width = 1, border_color = color.new(color.gray, 70),
frame_width = 1, frame_color = color.new(color.gray, 70))
if showLegend and barstate.islast
color lgBg = color.new(color.gray, 94)
color lgTxt = color.new(color.gray, 15)
table.cell(legend, 0, 0, "SYMBOL GUIDE", text_size = size.tiny, text_color = color.gray,
bgcolor = color.new(color.gray, 88), text_halign = text.align_left)
table.merge_cells(legend, 0, 0, 3, 0)
// column 0-1: setup phase column 2-3: trade phase
table.cell(legend, 0, 1, "▭", text_size = size.small, text_color = color.orange, bgcolor = lgBg)
table.cell(legend, 1, 1, "opening range 9:30–9:45", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 2, 1, "▬", text_size = size.small, text_color = color.blue, bgcolor = lgBg)
table.cell(legend, 3, 1, "entry price", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 0, 2, "▭", text_size = size.small, text_color = color.gray, bgcolor = lgBg)
table.cell(legend, 1, 2, "day skipped (range filter)", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 2, 2, "╌", text_size = size.small, text_color = color.red, bgcolor = lgBg)
table.cell(legend, 3, 2, "stop loss", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 0, 3, "▲", text_size = size.small, text_color = color.orange, bgcolor = lgBg)
table.cell(legend, 1, 3, "breakout close — wait for retest", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 2, 3, "╌", text_size = size.small, text_color = color.green, bgcolor = lgBg)
table.cell(legend, 3, 3, "take profit (3R)", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 0, 4, "▬", text_size = size.small, text_color = color.orange, bgcolor = lgBg)
table.cell(legend, 1, 4, "retest level = your entry", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 2, 4, "✕", text_size = size.small, text_color = color.green, bgcolor = lgBg)
table.cell(legend, 3, 4, "target hit (win)", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 0, 5, "E", text_size = size.small, text_color = color.green, bgcolor = lgBg)
table.cell(legend, 1, 5, "long entry filled", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 2, 5, "✕", text_size = size.small, text_color = color.red, bgcolor = lgBg)
table.cell(legend, 3, 5, "stop hit (−1R)", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 0, 6, "E", text_size = size.small, text_color = color.red, bgcolor = lgBg)
table.cell(legend, 1, 6, "short entry filled", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
table.cell(legend, 2, 6, "● ■", text_size = size.small, text_color = color.gray, bgcolor = lgBg)
table.cell(legend, 3, 6, "invalidated / no retest — no trade", text_size = size.tiny, text_color = lgTxt, bgcolor = lgBg, text_halign = text.align_left)
// ───────────────────────── Alerts ─────────────────────────
alertcondition(sigBreakout, "ORB: breakout close", "Opening range broken on the close — watch for a retest")
alertcondition(sigEntry, "ORB: retest entry", "Retest reached — entry level touched")
alertcondition(sigTargetHit, "ORB: target hit", "Target reached")
alertcondition(sigStopHit, "ORB: stop hit", "Stop hit")
alertcondition(sigInvalidated, "ORB: setup invalid", "Price closed back inside the range — setup dead")
alertcondition(sigExpired, "ORB: no retest", "Retest window expired — no trade today") Indicator

Indicator

Indicator

Entry Checklist Panel## The 13 checklist points, explained
**1. Trend breaks swing / bias** — Is the market actually trending right now? The script looks at recent swing highs and lows and checks if price has been making higher highs and higher lows (uptrend) or lower highs and lower lows (downtrend) two times in a row. If yes, there's a real trend to trade with.
**2. Pullback small + low volume** — When price pulls back against the trend, is that pullback small and quiet, not a big aggressive move? A weak, low-volume pullback suggests the trend is just resting, not reversing.
**3. Volume match move** — Was the volume during the actual trending move bigger than the volume during the pullback? If the trend candles had more participation (volume) than the pullback candles, that's a sign the trend is the "real" move and the pullback is just noise.
**4. 9EMA/VWAP close** — Are the 9-period moving average and VWAP sitting near each other (within 1%)? If they're far apart, price is stretched too far in one direction and may need to cool off before continuing.
**5. Entry near 9EMA/VWAP** — Is your actual entry price close to one of those two reference lines? Entering too far away from either means you're chasing price rather than getting a fair, supported entry.
**6. Breaking ORB high/low** — Has price broken above or below the opening range (the high/low set in the first several minutes of the session)? This is often the sign that a real directional move for the day is starting.
**7. Key level out of way (manual)** — Is there a support/resistance line you've drawn nearby that price hasn't cleared yet? You check this yourself — if a key level is sitting right in the way, it's not a clean entry.
**8. 200/400 SMA not in the way** — Are the longer-term moving averages either trending clearly, or is price already clear of both? If they're flat and price is tangled up in them, that's resistance/support you'd be fighting.
**9. FTFC aligned (manual)** — Does your "timeframe continuity" indicator agree with the direction you want to trade? You check this yourself since it depends on a separate tool.
**10. SL makes sense (manual)** — Is your stop-loss placed sensibly — not too wide, with room to reach your target, and beyond the levels that would prove you wrong? A judgment call only you can make.
**11. Not consolidating at entry** — Is the current candle showing real movement, or is price just chopping sideways in a tight range? Trading during dead chop is a losing habit; this row checks for actual expansion.
**12. Bid/ask held 5s (manual)** — For quick order-book-based (BW) entries: did the price actually hold at your entry level for a few seconds instead of just flickering through it? You confirm this yourself in the moment.
**13. Pullback engulfed (manual)** — Did the move back in your favor "engulf" (fully cover) the pullback candle before you? Not required, but it's a stronger signal when it happens — you judge this by eye. Indicator

Indicator

Indicator

Indicator

Indicator
