Market Euphoria Index v2 - MEI - Predict Market Tops & BottomsThe Market Euphoria Index v2 (MEI) is a 0–100 macro composite designed for the MONTHLY chart of SPX or the Nasdaq Composite (weekly also supported). It measures the cumulative buildup of the conditions that have historically surrounded major cycle tops and bottoms — not price alone, but the collision of euphoria (extension, sustained complacency) with late-cycle stress (profit stagnation, claims turning, curve dynamics, tight policy).
HOW TO READ IT
Above 80 — Extreme euphoria: the historical top zone
Above 65 — Euphoria warning: late-cycle, tighten risk
35–65 — Neutral
Below 35 — Fear: opportunity zone
Below 20 — Extreme fear: the historical bottom zone
Confirmation markers add a timing layer on top of the regime reading: a red triangle prints when MEI is in the euphoria zone AND monthly RSI shows a bearish divergence (higher price, lower momentum). A green triangle prints when MEI is in the fear zone AND either monthly RSI is washed out or initial jobless claims roll over from cycle highs — historically one of the tightest bottom signals available (claims peaked within weeks of the March 2009 and March 2020 lows).
THE 8 COMPONENTS (weights adjustable)
Price extension vs 5-year MA (22%) — blended with a 15-year percentile rank so each era is judged against its own norms
Yield curve un-inversion clock (18%) — tops historically cluster 0–12 months after un-inversion; includes a resolve gate so the clock disarms once the cycle has clearly broken (heavy Fed cuts, price under its 5-year MA, or claims spiking)
Corporate profits, ECONOMICS:USCPR (15%) — profits stagnated or declined ahead of the recession-driven bears (1997→2000, 2006→2007); deep decline with an improving second derivative scores as bottom conditions
Jobless claims cycle, ECONOMICS:USIJC (15%) — trough-and-turn off cycle lows = pre-top; spike-and-rollover = bottom
VIX 12-month average (10%) — sustained complacency, not spot readings
Inflation re-acceleration (8%)
Real rate stress (6%) — deflation-guarded so 2009-style CPI collapses read as fear, not stress
Fed cycle position (6%)
All rolling windows are computed at native monthly/quarterly/weekly resolution, so the math is correct on any chart timeframe. Missing history (VIX pre-1990, claims pre-1967, curve pre-1976 falls back to 10Y minus Fed Funds) is handled by dynamic weight renormalization — the composite extends back decades using whatever components exist, and the table shows how much weight is live at any point.
LIMITATIONS — READ BEFORE USING
Economic data publishes with a lag and gets revised, so real-time signals arrive later than a historical replay suggests. This framework targets recession-driven cycles: it structurally cannot anticipate exogenous shocks (2020) and only partially captures rate-shock bears (2022). The 2022–24 curve inversion that resolved without a recession is a live example of a component false positive — which is why no single component, including the curve, should be read in isolation. This is a regime gauge, not a precision timer, and nothing here is financial advice. Always combine with your own risk management.
Alerts are included for all threshold crossings and both confirmation signals. Feedback welcome — especially observations from earlier cycles. Indicator

TGIF Weekly Retracement+ (M1D)TGIF "Thank God It's Friday"-
Is a weekly retracement model taught by ICT. It is day-specific: it appears once a week, on Friday. Once the week has expanded and delivered into a higher-timeframe objective, Friday's job is not more expansion but a retracement back inside the weekly range — roughly 20-30% of that range given back before the weekly close. Structurally it is the distribution phase of the weekly Power 3.
This script measures the range and maps the draw. It takes no directional opinion of its own.
THE RANGE-
The weekly range is the lowest low of the week up to its highest high. Both anchors are weekly extremes, so the percentages are cut from the weekly range itself.
Direction comes from the sequence of those two extremes. Whichever printed later is the terminus the retracement runs back from; the opposite extreme is the origin. A week making higher highs into Friday is measured low to high; a week that topped midweek and sold off into Friday is measured high to low. The read refreshes on every confirmed bar, so a week that re-expands and takes its other side flips the measurement with it.
THE PRECONDITION-
The model expects price to have already delivered into a higher-timeframe premium array in a bullish week, or a discount array in a bearish week. Without that the week can keep expanding and close on its extreme with no retracement at all. It is the condition that separates the two, so it is checked rather than assumed, and enforced by default.
Monthly, Weekly and 3D are scanned. Each keeps at most one discount and one premium array, the most recent to pass validation. Two kinds of void qualify: a three-candle displacement gap, where an order block registers only if its displacement left a gap and the gap only registers if it clears a height floor with a real body behind it; and the void across a candle boundary, from one higher-timeframe candle's close to the next one's open, which nothing traded through at all — on the weekly, the weekend.
A week qualifies when its terminus extreme has traded a set depth into one of those arrays, 25% by default, measured from the edge price approached. The array checked is the one opposite the week's direction: a bullish week rallies into premium, a bearish week drops into discount. Because the test runs against that week's own extreme it reads correctly on every week in history, and the dashboard names what qualified it.
One array per side is drawn by default, highest timeframe winning where two overlap in price. Raising the count draws the next one down that sits elsewhere. That is display only — the check reads every array found, so tidying the chart cannot change which weeks qualify. An array stays drawn until price has traded fully through it.
A SPENT DRAW IS NOT A SETUP-
Friday is meant to deliver the give-back. A week that already paid it out on Wednesday has nothing left, however cleanly the rest reads. The deepest pullback from the terminus is tracked, and if it reached the retracement band before Friday the week is marked as worked rather than shown as live. That measurement restarts whenever the terminus moves, since a new extreme begins a new leg with its own untouched draw.
A stricter reading is available, off by default: require the terminus to have formed on Thursday or Friday.
(Visual shows the setting ON)
CONFIRMATION-
Friday's swing sets no level. It is the gate on conviction: a swing on the terminus side, confirmed on the 15M or 30M and held on a closing basis. The zones are a draw on liquidity, drawn in anticipation rather than waited on, which is how the model is used. Confirmation fires the alert and locks the measurement, so the levels stop moving. If the swing is later broken the lock releases and it re-arms on the next one.
Before that lock the levels do move, because the weekly range is not final until the extreme stops extending. That is the model rather than a repaint: nothing is read from an unclosed bar, no decision taken on a closed bar is ever revised, and the confirmation timeframe is requested one bar back so no forming higher-timeframe bar can contribute a pivot that later disappears.
WHAT IT DRAWS-
- The weekly range as an outline: a dotted level on each extreme, each beginning at the candle that formed it, closed by a riser at each end. It draws from early in the week.
- TGIF 20-30%, the retracement zone measured from the terminus back inside the range, with a midline through it — the 25% marker at default settings. The zones begin at the candle that formed the terminus, since a retracement cannot start before the extreme it runs back from exists.
- A reversal band beyond the draw. Not a target: past roughly 40% the move stops describing a Friday retracement and starts describing a larger reversal, and by 50% most of a TGIF position would already be off.
- The higher-timeframe arrays, captioned BISI, SIBI, OB+, OB- or VI alongside the timeframe that owns them.
- A dashboard carrying the chart timeframe, a countdown to the Friday close, model status, the array that qualified the week, the weekly range in points, and the distance from price to each zone.
Callouts sit at the right edge of the drawing, spaced by ATR-derived clearance so they do not stack on one another.
SETTINGS-
- Timezone, IANA format, defaulting to America/New_York. All day-of-week resolution uses it.
- Whether delivery into a higher-timeframe array is required, which of the three timeframes are scanned, the depth that counts as delivery, and how many arrays are drawn per side.
- Whether the terminus must have formed on Thursday or Friday, and how many completed weeks stay on the chart.
- The Friday hour past which the extreme is treated as set, 13:30 by default. Reported in the dashboard; it does not stop the anchors tracking a genuine new extreme.
- Swing confirmation timeframe, 15M or 30M, with adjustable pivot bars.
- Both bands are adjustable. 20/30 and 40/50 are defaults, not fixed values.
- Colours, label visibility and offset, dashboard position, and the Friday close time the countdown counts to.
NOTES-
- Non-repainting. All structure is read on closed bars.
- Completed weeks stay on the chart behind the current one, two by default and up to eight, frozen as they finished and with their callouts dropped so old text does not sit over live price. Set the count to zero for the current week only.
- Three alert conditions: Friday swing confirmed, price tapping the retracement zone, and price entering the reversal band.
- This is a mapping tool. It draws the model's levels and reports where price sits relative to them; it produces no entries, targets or stops. ICT is explicit that TGIF supplies the draw and the day, and that the entry is whichever of his models you prefer.
Disclaimer-
This is not financial advice. Levels drawn by a model are context, not a recommendation to trade, and the past behaviour of a weekly range says nothing certain about the next one. Indicator

Deep Market Structure & Liquidity Matrix [Pro]================================================================================
Deep Market Structure & Liquidity Matrix
================================================================================
Welcome to the Deep Market Structure & Liquidity Matrix . This all-in-one technical indicator is designed for Smart Money Concepts (SMC) traders, price action analysts, and institutional structure followers. It cleans up market noise and delivers precise structure mapping directly on your chart.
Whether you trade Forex, Crypto, Indices, or Commodities, this tool provides clear, real-time insights into macro trends, key structural breaks, major liquidity levels, and dynamic trend channels.
--------------------------------------------------------------------------------
KEY FEATURES & DETAILED BREAKDOWN
--------------------------------------------------------------------------------
1. Smooth Glowing Trend Line (Length: 70)
Unlike standard moving averages that lag or cause frequent false flips during choppy sessions, this script incorporates a high-period smoothed trend tracking algorithm (Hull-based).
- Green Line: Confirms a sustained macro Bullish Trend.
- Red Line: Confirms a sustained macro Bearish Trend.
It filters out minor price noise and keeps your focus aligned with the dominant higher-timeframe trend direction.
2. Major ITH & ITL Badges (Intermediate Term Highs/Lows)
Identifying major structural pivots is essential for liquidity mapping.
- Red "ITH" Badge: Highlights major macro swing highs (Intermediate Term Highs) where buy-side liquidity resides.
- Green "ITL" Badge: Highlights major macro swing lows (Intermediate Term Lows) where sell-side liquidity resides.
These badges only trigger on major swing points, keeping your charts clutter-free.
3. SMC Structure Mapping (BOS & CHoCH with Offset Labels)
To eliminate visual clutter, all structure markers are placed precisely with clean vertical offsets:
- BOS (Break of Structure): Highlights structural trend continuations.
- CHoCH (Change of Character): Signals potential early trend reversals.
Labels are placed above bullish break lines and below bearish break lines to prevent candles or lines from obscuring the text.
4. Dynamic Trend Channel Engine
Automated swing-point connections generate real-time trend channels to highlight dynamic support and resistance zones. This helps traders visually identify key channel boundaries and structural slope without manual drawing clutter.
5. Live Market Structure Dashboard
Located at the top right of the chart, this live dashboard summarizes key market metrics at a glance:
- Market Trend: Live macro direction (Bullish / Bearish).
- Market Phase: Automatically detects Consolidation (Low Volatility) vs. Expansion (High Volatility) using ATR parameters.
- Volatility (ATR): Displays real-time 14-period Average True Range metrics.
--------------------------------------------------------------------------------
HOW TO USE THIS INDICATOR
--------------------------------------------------------------------------------
1. Trend Identification: Use the Glowing Trend Line to bias your trades (Long when Green, Short when Red).
2. Liquidity Zones: Monitor the Major ITH and ITL levels as key targets or reversal zones.
3. Confirmation: Look for CHoCH for trend shift signals and BOS for continuation entries aligned with the main trend.
--------------------------------------------------------------------------------
DISCLAIMER & HOUSE RULES COMPLIANCE
--------------------------------------------------------------------------------
This script is strictly created for educational and analytical purposes only. It does not provide buy/sell signals or financial advice. Trading involves substantial risk, and past structural setups do not guarantee future price action. Always apply sound risk management strategies.
Indicator

8020 System Indicator=============================================================================
8020 SYSTEM INDICATOR FOR TRADINGVIEW — USER GUIDE
=============================================================================
Strategy by Okala. This indicator is a chart companion for the 80/20 trading strategy, Okala's
framework for trading NQ (Nasdaq) futures around price levels ending in 80
and 20. All trading concepts described below are Okala's; the indicator
simply automates spotting and tracking them on the chart.
Nothing in this guide or the indicator is financial advice. It marks
patterns; the trading decisions remain yours.
-----------------------------------------------------------------------------
1. WHAT THE INDICATOR DOES
-----------------------------------------------------------------------------
The indicator draws the core 8020 read on a single chart:
80/20 LEVELS
Horizontal lines at every price ending in 20 or 80 (for example 23,480
and 23,520). In the 8020 framework these act as liquidity magnets:
prices where both institutional and retail orders cluster, producing
reversals, breakouts and stop runs. The indicator draws the nearest
levels above and below the current price and moves them with the market.
40-POINT ZONE BANDS
A translucent band from each 80-ending level up to the next 20-ending
level, straddling every round hundred (for example 23,480 to 23,520).
This is the zone the levels frame, shown as one shaded region.
REPAIRS ("R")
A repair is a candle with no wick on one side of its body. In Okala's
teaching this signals imbalance: aggressive one-sided orders left
unfinished business, and the market tends to return later to "repair"
the move by filling that missing liquidity.
- A bullish candle with no lower wick creates a bullish repair at its
low (a magnet below).
- A bearish candle with no upper wick creates a bearish repair at its
high (a magnet above).
The indicator draws a line from each repair, extending right until
price returns and taps it. Repairs are used both as confluence for
entries and as profit targets. Okala's guidance: recent, aggressive
repairs have the strongest pull; stale ones fade in relevance — the AGE
column in the stats table (see section 4) helps you judge this.
FORK ("F")
A reversal pattern after a sharp capitulation move: three consecutive
candles print wicks at similar prices, with the centre wick extending
furthest and small bodies on the outer two candles.
- A bullish fork: 1st candle closes bearish, the 2nd (centre) candle's
low dives deepest, the 3rd closes bullish to confirm the reversal.
- A bearish fork is the mirror image using the highs.
The indicator draws a line at the centre candle's wick extreme — the
key level of the pattern — extending right until price returns and
taps it. Detection fires when the 3rd candle confirms, and the line is
anchored back at the centre candle where the level actually formed.
CROSS SECTIONS ("XS")
A continuation pattern built from two strong candles in the same
direction where the close of the first meets the open of the second at
the same price — no gap and no overlap between the bodies. That
junction forms a precise level. The playbook: mark the level, wait for
price to pull back to it, and enter in the original trend direction.
The indicator draws a line at the junction, extending right until the
retest happens.
GAPS
Two consecutive candles whose bodies do not overlap, leaving a void
between them (up or down). A translucent box marks the gap and extends
right until price trades back into it — another form of unfinished
liquidity that price is drawn to fill.
A+ WINDOWS
Shaded background over the two sessions the strategy is traded in:
09:30-11:00 ET (morning) and 15:00-16:00 ET (afternoon). The period in
between (11:00-15:00 ET) is the dead zone and is deliberately left
unshaded. Daylight-saving changes are handled automatically.
CONFLUENCE ("+")
Any repair, fork or cross section that forms within a set distance of
an 80/20 level is recoloured (magenta by default) and its label gains a
"+" (for example "R+" or "F+"). Level-plus-pattern confluence is the
heart of the strategy, so these markers deserve the most attention.
STATS TABLE
An on-chart panel with a legend and a live list of every level that
has not yet been tapped. Covered fully in section 4.
Note: of the three core setups, the h Pattern is not yet detected by
this version of the indicator; the sub-levels taught in the full course
(33, 46, 66, 93) are also not drawn.
-----------------------------------------------------------------------------
2. GETTING STARTED
-----------------------------------------------------------------------------
CHART TIMEFRAMES
The system uses a 200-second chart for entries and a 10-minute chart for
bias. PulseWire only offers second-based intervals on Premium plans and
above; per Okala's own guidance, if your platform does not support
200-second candles, use 3-minute candles instead — the setups work the
same way. The 10-minute chart is read separately for direction; this
indicator draws the entry-timeframe picture.
The detection logic runs on any symbol and timeframe, but the level
spacing (80/20 within each hundred) and the default thresholds are tuned
for NQ and MNQ. Tick size is detected automatically (0.25 on NQ/MNQ) and
can be overridden in settings.
NO REPAINTING
All patterns are detected on confirmed (closed) candles only. A marker
will never appear mid-candle and then vanish; what you see in a replay is
what you would have seen live.
-----------------------------------------------------------------------------
3. SETTINGS, GROUP BY GROUP
-----------------------------------------------------------------------------
A note on transparency: PulseWire uses transparency rather than opacity,
so 0 means solid and 100 means invisible.
80/20 LEVELS
Show levels ............... master toggle for the horizontal lines
Dashed lines .............. dashed (on) or solid (off) level lines
Price labels .............. print the price next to each level
40-pt zone bands .......... toggle the shaded bands around each hundred
Levels each side .......... how many levels to draw above and below the
current price (default 10 each side)
Line width / transparency . visual styling for the level lines
Zone band transparency .... how faint the bands are (default 90, subtle)
Line / zone band colour ... colours for lines and bands
REPAIRS
Show repairs .............. toggle repair detection
"R" labels ................ toggle the R text label (line still draws)
Max wick (ticks) .......... how large a wick may be and still count as
"no wick". Default 0 = strictly wickless;
set to 1-2 to allow a tick or two of wick.
CROSS SECTIONS
Show cross sections ....... toggle detection
"XS" labels ............... toggle the XS text label
Body / range ratio ........ how much of each candle must be body for it
to count as a strong directional candle
(default 0.6 = 60 percent)
Junction tolerance (ticks). how closely close-1 must meet open-2
(default 2 ticks)
Min body (ticks) .......... minimum size of each momentum candle
(default 40 ticks = 10 NQ points)
FORK
Show fork ................. toggle fork detection
"F" labels ................ toggle the F text label (line still draws)
Outer-wick similarity ..... how close the 1st and 3rd candles' wicks
must sit to count as "similar prices"
(default 3 ticks)
Min center-wick depth ..... how far the center candle's wick must
extend beyond BOTH outer wicks for the
pattern to count (default 4 ticks = 1 pt)
Max outer body / range .... how small-bodied the outer candles must be:
the body may take up at most this fraction
of the candle's range (default 0.5). Lower
values demand more indecision-like outers.
MARKER STYLE (REPAIRS + CROSS SECTIONS + FORK)
Line width ................ thickness of the marker lines
Lookback (bars) ........... markers older than this are removed
(default 1000 bars; 0 disables the limit)
Bullish / bearish colour .. cyan and pink by default. These also colour
the labels and the stats-table rows. If you
use a light chart background, darken these.
CONFLUENCE
Highlight confluence ...... toggle the recolour-and-"+" behaviour
Distance to level (ticks) . how near an 80/20 level a marker must be to
count as confluent (default 8 ticks = 2 pts)
Colour .................... confluence colour (magenta by default)
GAPS
Show gaps ................. toggle gap boxes
Min gap size (ticks) ...... smallest body gap that registers
(default 4 ticks = 1 point)
Box transparency / colour . styling for the gap boxes
A+ WINDOWS
Shade A+ windows .......... toggle the session shading
Transparency / colour ..... styling for the shading
STATS TABLE
Show table ................ toggle the panel
Position .................. which corner or edge of the chart it sits in
Text size ................. Tiny, Small, Normal or Large
Max untapped rows ......... how many untapped levels to list (1-30).
The header always shows the true total even
when the list is capped.
GENERAL
Tick size (0 = auto) ...... leave at 0 to use the symbol's own tick
size; override only if needed.
-----------------------------------------------------------------------------
4. THE STATS TABLE
-----------------------------------------------------------------------------
The table has a white body with black text; section headers are inverted
(black with white text). Everything is set in a monospaced font. It
updates live on the last bar.
LEGEND (top section)
R repair (no-wick candle)
F fork (three-candle reversal)
XS cross section (junction of two momentum candles)
# coloured square: body gap
+ confluence with an 80/20 level
UP / DOWN arrows: bullish (cyan) and bearish (pink) marker direction
UNTAPPED (bottom section)
This is a live watch-list of every level the market has not yet returned
to — the levels that still have pull. The count in the header is the
total number outstanding. Rows are listed newest first, in three columns:
TYPE ... what the level is (R, F, XS or GAP), with a "+" if it sits in
confluence with an 80/20 level, and an arrow for direction.
An up arrow means price would come DOWN to tap it (a magnet
below); a down arrow means price would come UP to tap it.
PRICE .. the exact level, or for gaps the full price range of the void.
AGE .... how many bars have passed since the level was created. Recency
matters in this system — fresh repairs pull hardest — so a
young age is generally more interesting than an old one. For
forks, age is counted from the centre candle, where the level
actually formed.
The moment price taps a level, its line stops extending on the chart and
its row leaves the table, so the table always reflects what is still open.
-----------------------------------------------------------------------------
5. READING THE CHART: THE INTENDED WORKFLOW
-----------------------------------------------------------------------------
The indicator is built to support a daily routine, rather than
replace it:
1. Pre-market, note where the 80/20 levels and fresh repairs sit; the
untapped table gives you this list at a glance.
2. Set bias from the 10-minute chart (a separate chart or layout).
3. Trade only inside the shaded A+ windows and avoid the dead zone.
4. Wait for a setup at a marked location — a fork reversal at
exhaustion, a cross section pullback or a reaction at a repair —
with the highest priority on "+" (confluent) markers near 80/20
levels.
5. Manage risk per the playbook: a 10-15 point stop at structure (size
down if wider), a 15-point standard target (1.0-1.5R), and a strict
cap of one to three trades per day. Repairs above or below often
serve as the natural targets.
The indicator marks locations and keeps score of what remains untapped;
the discipline — windows, bias, risk and trade count — is on you.
-----------------------------------------------------------------------------
6. ALERTS
-----------------------------------------------------------------------------
There is an "Alerts" group in the settings with seven toggles: new repair, new fork, new cross section, new gap (off by default — they can be noisy), level tapped / gap filled, "+"-only mode (restricts new-marker alerts to confluent ones, which pairs nicely with the strategy's A+-setups-only discipline), and A+ window opens (off by default). Messages are compact and self-describing
-----------------------------------------------------------------------------
7. TECHNICAL NOTES AND LIMITS
-----------------------------------------------------------------------------
- PulseWire caps every indicator at 500 lines, 500 boxes and 500
labels. The script reserves headroom for the level lines and bands,
caps markers at 400 and gaps at 450, and when a cap is reached evicts
the oldest FILLED marker first, so open (untapped) levels are never
dropped in favour of dead ones.
- The Lookback setting removes markers older than the given number of
bars regardless of fill state, keeping the chart focused on recent
structure.
- Levels and zone bands are redrawn around the latest price on every
update, so they follow the market automatically.
- Fill checks use the candle's full range: a wick touching a level
counts as a tap.
- Detection is on-close only, which means a pattern is marked one candle
after it completes forming — the trade-off for signals that never
repaint. For the fork this means the marker appears when the 3rd
(confirming) candle closes, two candles after the centre candle that
set the level; the line is drawn back to that centre candle.
Credit once more to Okala for the strategy and all of the concepts this indicator visualises. Indicator

Indicator

General Daily-Weekly BUY and TAKE PROFIT SystemGeneral Daily-Weekly BUY and TAKE PROFIT System v3.2
Overview
The General Daily-Weekly BUY and TAKE PROFIT System is a completed-candle PulseWire indicator designed to identify potential oversold reversals on daily and weekly charts.
The indicator does not select companies, evaluate financial strength, or determine whether a stock belongs on your watchlist. It is intended to provide technical timing signals for securities that you have already decided are acceptable to monitor or own.
The system uses RSI, a fast 3-period EMA, a slow 13-period EMA, ATR-based measurements, and optional trend filters to manage a structured signal sequence:
RSI reaches an oversold condition and creates an ARM signal.
The indicator waits for evidence that price and momentum are reversing.
A completed candle meeting the selected trigger requirements produces a BUY signal.
After a BUY, a completed RSI crossover above the take-profit level may produce one TAKE PROFIT signal.
The script supports exact 1-day and 1-week PulseWire charts. It does not operate on intraday, monthly, or other chart intervals.
Primary Signal Sequence
The basic sequence is:
ARM
BUY
TAKE PROFIT
An ARM is not a BUY recommendation. It means that the ticker has entered an oversold condition and the script has begun watching for a qualified reversal.
A BUY occurs only after the ARM is active and the selected reversal conditions are satisfied.
A TAKE PROFIT occurs only after the script has previously issued a BUY on that chart timeframe. This prevents isolated TAKE PROFIT labels from appearing on stocks that never generated a corresponding BUY.
Completed-Candle Operation
All signals are evaluated only after the current candle closes.
On a daily chart, the indicator waits for the daily candle to complete.
On a weekly chart, the indicator waits for the weekly candle to complete.
Signals do not appear intrabar and should not disappear after the candle has closed. This reduces the risk of acting on temporary RSI or EMA conditions that do not survive through the end of the period.
Daily and Weekly Modules
The Daily Module and Weekly Module can be enabled or disabled independently.
The Daily Module operates only when the chart is set to 1D.
The Weekly Module operates only when the chart is set to 1W.
Enabling both modules does not combine daily and weekly information into one signal. Each module operates independently on its corresponding chart timeframe.
Shared Calculations
The default shared calculations are:
Source: Close
RSI Length: 14
Fast EMA Length: 3
Slow EMA Length: 13
ATR Length: 14
The 3 EMA is used to measure short-term price direction.
The 13 EMA represents the slower trend structure.
ATR is used to normalize certain price and EMA measurements so the same settings can be applied across stocks with different prices and volatility levels.
Daily ARM Logic
The default daily oversold level is RSI 30.
The default ARM method is Cross Below. This means RSI must move from above 30 to below 30 on a completed daily candle.
The daily ARM also requires the completed candle to close below the 13 EMA.
Daily ATR Displacement is enabled by default. The completed daily close must be at least 0.50 ATR below the 13 EMA.
This additional displacement requirement prevents a minor RSI dip near the slower EMA from creating an ARM. The stock must demonstrate a more meaningful oversold move.
The lower Bollinger Band requirement is disabled by default.
The daily long-term trend filter is disabled by default.
Weekly ARM Logic
The default weekly oversold level is RSI 32.
The default ARM method is Cross Below. Weekly RSI must move from above 32 to below 32 on a completed weekly candle.
The completed week must also close below the 13 EMA.
Weekly ATR Displacement is disabled by default. The displayed 0.25 ATR value has no effect unless Weekly ATR Displacement is enabled.
The weekly lower Bollinger Band requirement is disabled by default.
The weekly long-term trend filter is disabled by default.
ARM Expiration
An ARM does not remain active forever.
The daily ARM expires after 45 completed daily candles.
The weekly ARM expires after 26 completed weekly candles.
Expiration prevents an extremely old oversold reading from producing a BUY during a much later and potentially unrelated market cycle.
For example, a stock may become oversold, continue declining for more than a year, and eventually recover. Without expiration, that eventual recovery could be treated as the reversal of the original oversold event even though the market conditions may have changed completely.
When an ARM expires, the indicator displays a gray BUY ARM EXPIRED marker.
Daily Reset After Expiration or BUY
After a daily BUY or an expired daily ARM, daily RSI must recover to the Daily RSI Reset Level before another daily cycle can ARM.
The default daily reset level is 50.
The reset candle cannot create a new ARM on the same candle. RSI must first complete the reset, and a later completed candle must create a new qualifying oversold event.
Weekly Reset After BUY
After a weekly BUY, weekly RSI must recover to the Weekly RSI Reset Level After BUY.
The default is 50.
This helps prevent repeated weekly BUY signals from being generated during the same unresolved oversold cycle.
Weekly Reset After ARM Expiration
Weekly ARM expiration uses a separate reset requirement.
The default Weekly RSI Reset Level After ARM Expiration is 32.
After an ARM expires, weekly RSI only needs to recover to 32 before the script becomes eligible to recognize a later fresh cross below 32.
With the default Cross Below method, the sequence is:
The original ARM expires.
RSI recovers to 32 or higher.
The reset lock is cleared.
A later week crosses from above 32 to below 32.
A new weekly ARM is created.
This lighter post-expiration reset allows prolonged weak stocks to begin a genuinely new oversold cycle without requiring RSI to recover all the way to 50 first.
Trigger Modes
The script provides four trigger modes:
Strong Confirmation
EMA Turn Only
Bullish Cross Only
EMA Turn or Bullish Cross
Strong Confirmation is the default for both daily and weekly charts.
Strong Confirmation
Strong Confirmation begins watching when the 3 EMA crosses above the 13 EMA after a valid ARM.
The script then requires the bullish structure to meet the full confirmation criteria.
The default requirements are:
The 3 EMA is above the 13 EMA.
The 3/13 EMA separation is at least 0.10 ATR.
The 3 EMA is rising.
The bullish distance between the 3 EMA and 13 EMA is widening.
The completed candle closes above the 13 EMA.
RSI is at least 50.
RSI is rising.
Any enabled prior-close or prior-high requirement is satisfied.
The Daily Strong Confirmation watch can remain active for up to 10 completed daily candles after the bullish crossover.
The Weekly Strong Confirmation watch can remain active for up to 8 completed weekly candles after the bullish crossover.
If the confirmation watch expires, the crossover attempt is canceled. By default, the original ARM is preserved and may be used for another bullish crossover attempt, provided the ARM itself has not expired.
Daily Crossover-Candle BUY
Allow Strong BUY on Daily Crossover Candle is enabled by default.
This allows the completed daily 3/13 crossover candle to issue the BUY immediately when every Strong Confirmation requirement is already satisfied.
Enabling this setting does not force a BUY on every crossover candle. The crossover candle must still satisfy minimum RSI, EMA separation, rising EMA, widening spread, close-above-slow-EMA, and all other enabled confirmation requirements.
If the crossover candle is not strong enough, the daily confirmation watch remains active for later completed days.
Weekly Crossover-Candle BUY
Allow Strong BUY on Weekly Crossover Candle is disabled by default in version 3.2.
The completed weekly bullish crossover starts the Strong Confirmation watch, but the crossover week cannot issue the BUY.
A later completed week must satisfy all Strong Confirmation requirements.
This creates a more conservative weekly signal and provides additional evidence that the bullish crossover is holding.
The setting can be enabled manually, but enabling it only makes the crossover candle eligible for evaluation. It does not bypass any other confirmation requirement.
Preserving the ARM After a Failed Crossover
Preserve ARM After Failed Daily Crossover and Preserve ARM After Failed Weekly Crossover are enabled by default.
If the 3 EMA crosses above the 13 EMA but then falls back below it before producing a BUY, the failed crossover watch is canceled.
The original oversold ARM remains active.
The indicator may then watch for another bullish crossover during the remaining ARM period.
If this setting is disabled, a failed crossover ends the entire ARM cycle and requires the appropriate RSI reset before another cycle can begin.
EMA Turn Trigger
EMA Turn Only is an earlier reversal mode.
Instead of waiting for the 3 EMA to cross above the 13 EMA, it looks for the 3 EMA to stop falling and begin turning upward.
By default, the fast EMA must still be below the slow EMA when the turn occurs.
ATR Turn Sharpness is enabled by default.
The minimum daily EMA turn sharpness is 0.15 ATR.
The minimum weekly EMA turn sharpness is 0.05 ATR.
These settings help distinguish a meaningful upward turn from a very small flattening of the fast EMA.
The EMA Turn settings are primarily relevant when EMA Turn Only or EMA Turn or Bullish Cross is selected. They are not the primary confirmation mechanism in Strong Confirmation mode.
Bullish Cross Trigger
Bullish Cross Only produces a trigger based on the 3 EMA crossing above the 13 EMA.
The Trigger Confirmation Candles setting can require either one or two completed candles.
With one candle selected, the completed crossover candle can act as the trigger.
With two candles selected, the script requires the crossover to remain intact and strengthen on the following completed candle.
Strong Confirmation uses its own crossover watch and confirmation requirements. The Trigger Confirmation Candles setting is mainly relevant to the non-Strong-Confirmation trigger modes.
RSI Rising Requirement
Require Daily RSI Rising and Require Weekly RSI Rising are enabled by default.
RSI must be higher than it was on the previous completed candle.
The RSI Rising Candles setting can be changed from one to two.
When two candles are selected, RSI must rise for two consecutive completed candles.
This requirement applies to the selected reversal trigger and to Strong Confirmation.
Prior Close and Prior High Requirements
Require Close Above Prior Close is disabled by default.
Require Close Above Prior High is disabled by default.
These optional filters can make the trigger more restrictive.
Requiring a close above the prior close demands basic price improvement.
Requiring a close above the prior high demands a stronger breakout-style confirmation.
These settings should be enabled carefully because they may significantly delay or eliminate signals.
TAKE PROFIT Logic
The default daily and weekly take-profit RSI level is 70.
A TAKE PROFIT signal occurs when RSI crosses from below 70 to above 70 on a completed candle.
The signal is not produced merely because RSI remains above 70. A completed crossover must occur.
A TAKE PROFIT is allowed only when the script has previously generated a BUY on that chart timeframe.
When the BUY occurs, the script activates an internal signal-position state.
When the first qualifying TAKE PROFIT occurs, that signal-position state is closed.
Additional RSI crosses above 70 will not generate another TAKE PROFIT until a later BUY activates a new signal position.
This eliminates TAKE PROFIT labels on securities that never produced a BUY.
The TAKE PROFIT signal is based on RSI, not the actual gain or loss from the BUY price. It does not calculate percentage profit, entry cost, position size, or tax consequences.
Position-State Limitation
The internal position state only records whether at least one script-generated BUY is active.
It does not track share quantity, average entry price, partial exits, multiple accounts, or separately sized entries.
The script contains no ADD or scale-in logic.
The script also contains no stop-loss, risk-off, or full SELL signal.
TAKE PROFIT closes the internal signal state, but it does not place or manage an order.
Ticker Overrides
The script allows ticker-specific overrides for two values:
RSI
TP_RSI
RSI changes the oversold ARM threshold.
TP_RSI changes the TAKE PROFIT RSI threshold.
Overrides are entered one ticker per line.
Example:
TSM|RSI=35|TP_RSI=75
This means TSM will use an oversold threshold of 35 and a take-profit threshold of 75.
You may override only one value:
TSM|RSI=35
All unspecified values continue using the normal daily or weekly defaults.
The parser uses the ticker symbol without the exchange prefix. Use TSM rather than NASDAQ:TSM.
The default weekly overrides are:
TQQQ|RSI=32
TSM|RSI=35
The Daily Ticker Overrides field is blank by default.
Daily and weekly overrides are maintained separately.
Chart Markers
The indicator uses the following markers:
Orange ARM marker: The completed candle satisfied the oversold ARM requirements.
Aqua BUY marker: The armed cycle produced a qualified reversal BUY.
Red TAKE PROFIT marker: RSI crossed above the take-profit level after a prior BUY.
Gray BUY ARM EXPIRED marker: The ARM remained unresolved beyond its expiration period.
Each marker can be independently shown or hidden in the Display settings.
Hiding a marker does not disable the underlying signal or alert condition.
EMA Plots
Plot Fast and Slow EMAs is enabled by default.
The 3 EMA is plotted in yellow.
The 13 EMA is plotted in purple.
Optional long-term trend EMAs may also be displayed.
The fast trend EMA is plotted in blue.
The long trend EMA is plotted in red.
The trend EMA plots are disabled by default.
The trend EMA values are still calculated when needed by an enabled long-term trend filter.
Long-Term Trend Filters
The daily and weekly long-term trend filters are disabled by default.
Available choices are:
Off
Price Above Long EMA
Fast Trend EMA Above Long EMA
Price Above Long EMA requires the current close to remain above the configured long trend EMA during the ARM event.
Fast Trend EMA Above Long EMA requires the configured fast trend EMA to remain above the long trend EMA.
The default daily trend lengths are 50 and 200.
The default weekly trend lengths are 10 and 40.
These filters apply to the ARM condition, not the later BUY trigger.
Bollinger Band Filter
The optional lower Bollinger Band filter is disabled by default.
When enabled, the ARM candle must close below the calculated lower Bollinger Band.
The default Bollinger Band length is 20.
The default standard-deviation multiplier is 2.0.
This can produce fewer and more deeply oversold ARM events.
Recommended Workflow
Begin with a watchlist of companies, ETFs, or other securities that meet your own quality, liquidity, and risk requirements.
Use the daily chart for more frequent opportunities and shorter technical cycles.
Use the weekly chart for slower, more conservative reversal signals.
When an orange ARM appears, do not treat it as an entry. The ticker has only entered the watch phase.
Wait for the aqua BUY marker.
Review the chart structure, company quality, liquidity, earnings schedule, and any other relevant risks before acting.
If the script later produces a red TAKE PROFIT marker, evaluate whether to reduce or close the position according to your own trade plan.
Do not assume the indicator manages an open trade after the alert is delivered.
Creating PulseWire Alerts
Add the indicator to the exact chart timeframe you intend to monitor.
Use a 1D chart for Daily BUY and Daily TAKE PROFIT alerts.
Use a 1W chart for Weekly BUY and Weekly TAKE PROFIT alerts.
Available alert conditions are:
Daily BUY
Weekly BUY
Daily TAKE PROFIT
Weekly TAKE PROFIT
Because signals use confirmed candles, select Once Per Bar Close when creating the PulseWire alert.
The alert messages include the action, signal type, ticker, interval, close price, and timestamp in JSON format.
After changing the script code or changing important inputs, delete and recreate the PulseWire alerts. Existing PulseWire alerts retain a snapshot of the script and settings that existed when the alert was created.
How to Interpret Missing Signals
A stock can ARM without ever producing a BUY.
Common reasons include:
The ARM expired before the reversal completed.
The 3 EMA never crossed above the 13 EMA.
The bullish crossover failed and the EMAs crossed back down.
RSI remained below the Strong Confirmation minimum.
The EMA separation remained below the minimum ATR requirement.
The fast EMA was not rising.
The bullish EMA spread was not widening.
Price did not close above the slow EMA.
The confirmation watch expired.
An enabled prior-close or prior-high condition was not satisfied.
Allowing a BUY on the crossover candle does not bypass these requirements. It only allows that candle to be evaluated.
Intended Use
This indicator is best understood as a timing tool for an existing watchlist.
It is not intended to turn every oversold stock into an investment candidate.
A deeply fallen speculative stock may ARM, expire, re-arm, or eventually recover without producing a BUY. That is not automatically a defect. The confirmation requirements are intended to avoid treating every temporary bounce as a durable reversal.
The quality of the underlying company and the suitability of the security should be evaluated separately from the indicator’s technical signals. Indicator

ZeyneptenBiriCrSinyalZeyneptenBiriCrSinyal combines EMA trend filtering, Fair Value Gaps (FVG), Order Blocks (OB), Breaker Blocks (BB), and BOS/CHoCH structure into a multi-factor scoring system to generate LONG/SHORT signals.
How it works:
Trend direction is determined using EMA 50/200
FVG, Order Block, and Breaker Block zones are auto-detected and plotted
BOS/CHoCH labels mark structure shifts
RSI and volume act as confirmation filters
All factors combine into a score; when the score passes your threshold and Risk/Reward falls within your set range, a signal fires with Entry, Stop, Target, and RR shown on the chart
Features:
Toggle each component (EMA, FVG, OB, BB, BOS/CHoCH) independently
Live score panel showing LONG/SHORT scores, RSI, and ATR
Optional repaint protection (calculates only on confirmed bars)
Built-in alerts for new LONG/SHORT signals
For educational purposes only — not financial advice. Backtest before live use. Indicator

Indicator

Indicator

Penny stocks Pro Execution (15m & 1H HTF)🚀 Penny Stock Pro Execution (15m & 1H HTF Confluence)
📌 Overview
Penny stocks and low-float momentum plays rarely follow classic macro trends. Instead, they operate on violent spikes followed by rapid decay. Traditional trend-following strategies fail on these assets because by the time a higher timeframe trend is "confirmed," the move is already over and smart money is dumping into late buyers.
Penny Stock Pro Execution is purpose-built for intraday momentum execution (ideal on 5m to 15m charts while pulling non-repainting multi-timeframe data from 15m and 1H). It pinpoints precision entries at the exact micro-inflection point right as volume pours in, then equips you with automatic ATR risk structures to lock in profits before the spike dies.
⚡ The Penny Stock Dilemma: "Spike & Die" Dynamics
Unlike large-cap stocks that trend smoothly, penny stocks are driven by short squeezes, news catalysts, and liquidity grabs. They follow a distinct lifecycle:
* Accumulation / Compression: Low-volume consolidation near dynamic support.
* The Liquidity Spike: A sudden burst of volume causing an explosive move across 1–3 candles.
* The Distribution Decay: High-volume rejection, micro-structure break, and rapid dump back to baseline.
This script solves two crucial problems when trading these patterns:
* Prevents Chasing Top-of-Spike Moves: Uses strict HTF Extension Filters to block long signals when price is already stretched too far above the baseline.
* Captures Early Inflections: Combines Volume-Backed Pinbar Rejections and Micro Market Structure Shifts (MSS/CHoCH) on the lower timeframe to fire entries before the main move unfolds.
🔑 Key Features & Logic Breakdown
1. Non-Repainting Multi-Timeframe HUD (15m & 1H)
* Tracks higher timeframe EMA alignment, RSI momentum, ADX strength, and the last 6 candles using barmerge.gaps_on and lookahead_off to guarantee zero repainting.
2. Multi-Factor Confluence Scoring (1–6 Scale)
Signals are evaluated through a 6-point checklist. A setup must achieve a minimum confluence score of 4/6 to trigger an entry:
* HTF Trend Stack Alignment (1H alignment)
* HTF Mean-Reversion / Pullback Check (Ensures you aren't buying the absolute peak)
* 15m Trend Support
* 1H RSI Safety Gate (Filters out exhausted setups)
* Relative Volume Spike (\eg 1.2\times average volume)
* 5m RSI In-Zone Check
3. Dynamic Micro-Structure Trigger Logic
The script looks for one of two localized entry triggers:
* Volume-Backed Pinbar Rejections: Identifies high-wick candle rejections (\ge 40\% total range and 2\times body size) occurring at recent 8-candle extremes.
* Micro Market Structure Shifts (MSS): Confirms structural break of recent swing highs/lows on close basis.
4. Automated Risk Management Projection
Upon signal execution, the indicator dynamically projects horizontal level markers directly on the chart:
* Entry Line (White)
* Stop Loss (SL): ATR-based dynamic risk placement (Default: 1.5\times \text{ATR})
* Take Profit 1 & 2 (TP1 / TP2): 1.0\times and 2.0\times \text{ATR} targets to secure gains before the inevitable decay.
🛠️ How to Trade This Script
│
▼
───► 🚀 ENTRY SIGNAL FIRED (Score >= 4)
│
├──────► Take Profit 1 (1.0x ATR) ──► Scale out 50% & set SL to Entry
│
└──────► Take Profit 2 (2.0x ATR) ──► Fully exit before "Die" phase
* Chart Setup: Apply script to a 5-minute chart (or 3-minute for fast momentum plays).
* Wait for Signal: Look for a green LONG or red SHORT triangle supported by a score label on the TP2 line.
* Execution Rules:
* TP1 (1.0\times \text{ATR}): Sell 50% of position immediately. Move Stop Loss to breakeven.
* TP2 (2.0\times \text{ATR}): Clear out the remaining position. Do not hold penny stocks hoping for a overnight hold unless HTF is breaking out with unprecedented volume.
⚙️ Recommended Inputs
* Medium Timeframe: 15
* Higher Timeframe: 60 (1H)
* HTF Extension Threshold: 1.5% (Adjust higher for extreme low-float runners)
* Relative Vol Multiplier: 1.2x - 1.5x
Disclaimer: Penny stocks carry high volatility and slippage risk. This script is designed for momentum scalping and active intraday risk management. Always trade with strict stop losses. Indicator

Indicator

Indicator

Combined Breaker Blocks with Imbalance Filter//@version=6
indicator("Combined Breaker Blocks with Imbalance Filter", shorttitle = "Combined Breakers + Imbalance", overlay = true, behind_chart = false, max_boxes_count = 500, max_lines_count = 500, max_labels_count = 500, max_bars_back = 5000)
import PulseWire/ta/12
// ============================================================================
// BỘ LỌC IMBALANCE (FVG)
// ============================================================================
grp_imb = "Bộ Lọc Imbalance (FVG)"
useImbalanceFilter = input.bool(true, title = "Chỉ giữ OB có Imbalance (FVG)", group = grp_imb, tooltip = "Lọc bỏ những vùng OB/Breaker không có khoảng trống giá Imbalance xung quanh.")
// Hàm kiểm tra Imbalance
f_has_imbalance_bull() =>
// Bullish Imbalance (FVG Tăng): Giá cao nhất cây 2 thanh trước thấp hơn giá thấp nhất cây hiện tại
(high < low) or (high < low ) or (high < low)
f_has_imbalance_bear() =>
// Bearish Imbalance (FVG Giảm): Giá thấp nhất cây 2 thanh trước cao hơn giá cao nhất cây hiện tại
(low > high) or (low > high ) or (low > high)
// ============================================================================
// SECTION 1: ALGOALPHA BREAKER BLOCKS
// ============================================================================
// --- Inputs (AlgoAlpha) ---
preventOverlap = input.bool(true, title = "Prevent Overlap", group = "AlgoAlpha - Calculation", tooltip = "When enabled, new orderblocks will not be created if their price range overlaps any existing active orderblock.")
zLen = input.int(100, title = "Z-Score Window (bars)", minval = 1, group = "AlgoAlpha - Calculation", tooltip = "Lookback window used to normalize the impulse distance into a z-score.")
maxAge = input.int(500, title = "Max Box Age (bars)", minval = 1, group = "AlgoAlpha - Calculation", tooltip = "Maximum lifetime (in bars) of an orderblock that has not been mitigated.")
bullCol = input.color(#00ffbb, title = "Bullish Colour", group = "AlgoAlpha - Appearance", tooltip = "Color used for bullish breaker zones and bullish signals.")
bearCol = input.color(#ff1100, title = "Bearish Colour", group = "AlgoAlpha - Appearance", tooltip = "Color used for bearish breaker zones and bearish signals.")
// --- Calculations (AlgoAlpha) ---
var updist = 0.0
var downdist = 0.0
updist := close > open ? nz(updist ) + (close - open) : 0.0
downdist := close < open ? nz(downdist ) + (open - close) : 0.0
upMean = ta.sma(updist, zLen)
upStdev = ta.stdev(updist, zLen)
dnMean = ta.sma(downdist, zLen)
dnStdev = ta.stdev(downdist, zLen)
zUp = (updist - upMean) / (upStdev == 0.0 ? na : upStdev)
zDn = (downdist - dnMean) / (dnStdev == 0.0 ? na : dnStdev)
// Bổ sung lọc Imbalance cho tín hiệu AlgoAlpha
bullish = ta.crossover(zUp, 4) and nz(zUp ) != 0 and (not useImbalanceFilter or f_has_imbalance_bull())
bearish = ta.crossunder(-zDn, -4) and nz((-zDn) ) != 0 and (not useImbalanceFilter or f_has_imbalance_bear())
var box bullBoxes = array.new()
var box bearBoxes = array.new()
var int bullStarts = array.new_int()
var int bearStarts = array.new_int()
var line bullMidLines = array.new()
var line bearMidLines = array.new()
var box breakerBullBoxes = array.new()
var box breakerBearBoxes = array.new()
var int breakerBullStarts = array.new_int()
var int breakerBearStarts = array.new_int()
var line breakerBullMidLines = array.new()
var line breakerBearMidLines = array.new()
breakerBullPlot = float(na)
breakerBearPlot = float(na)
rejectBullPlot = float(na)
rejectBearPlot = float(na)
f_can_create(float tNew, float bNew) =>
bool ok = true
if bullBoxes.size() > 0
for j = 0 to array.size(bullBoxes) - 1
exB = array.get(bullBoxes, j)
float exTop = box.get_top(exB)
float exBot = box.get_bottom(exB)
if (tNew > exBot) and (bNew < exTop)
ok := false
break
if ok and bearBoxes.size() > 0
for j = 0 to array.size(bearBoxes) - 1
exS = array.get(bearBoxes, j)
float exTop2 = box.get_top(exS)
float exBot2 = box.get_bottom(exS)
if (tNew > exBot2) and (bNew < exTop2)
ok := false
break
if ok and breakerBullBoxes.size() > 0
for j = 0 to array.size(breakerBullBoxes) - 1
exB = array.get(breakerBullBoxes, j)
float exTop = box.get_top(exB)
float exBot = box.get_bottom(exB)
if (tNew > exBot) and (bNew < exTop)
ok := false
break
if ok and breakerBearBoxes.size() > 0
for j = 0 to array.size(breakerBearBoxes) - 1
exS = array.get(breakerBearBoxes, j)
float exTop2 = box.get_top(exS)
float exBot2 = box.get_bottom(exS)
if (tNew > exBot2) and (bNew < exTop2)
ok := false
break
ok
f_can_create_breaker(float tNew, float bNew) =>
f_can_create(tNew, bNew)
lastDownIdx = ta.valuewhen(close < open, bar_index, 0)
lastDownHigh = ta.valuewhen(close < open, high, 0)
lastDownLow = ta.valuewhen(close < open, low, 0)
breakerBullPlot := na
breakerBearPlot := na
rejectBullPlot := na
rejectBearPlot := na
if bullish and not na(lastDownIdx) and not na(lastDownHigh) and not na(lastDownLow)
if not preventOverlap or f_can_create(lastDownHigh, lastDownLow)
float midYB = (lastDownHigh + lastDownLow) / 2.0
bx = box.new(lastDownIdx, lastDownHigh, lastDownIdx + 1, lastDownLow, border_color = color.new(color.gray, 40), bgcolor = color.new(color.gray, 85))
ln = line.new(x1 = lastDownIdx, y1 = midYB, x2 = lastDownIdx + 1, y2 = midYB, xloc = xloc.bar_index, extend = extend.none, color = color.new(color.gray, 40), style = line.style_dashed, width = 1)
array.unshift(bullBoxes, bx)
array.unshift(bullStarts, lastDownIdx)
array.unshift(bullMidLines, ln)
lastUpIdx = ta.valuewhen(close > open, bar_index, 0)
lastUpHigh = ta.valuewhen(close > open, high, 0)
lastUpLow = ta.valuewhen(close > open, low, 0)
if bearish and not na(lastUpIdx) and not na(lastUpHigh) and not na(lastUpLow)
if not preventOverlap or f_can_create(lastUpHigh, lastUpLow)
float midYS = (lastUpHigh + lastUpLow) / 2.0
bx2 = box.new(lastUpIdx, lastUpHigh, lastUpIdx + 1, lastUpLow, border_color = color.new(color.gray, 40), bgcolor = color.new(color.gray, 85))
ln2 = line.new(x1 = lastUpIdx, y1 = midYS, x2 = lastUpIdx + 1, y2 = midYS, xloc = xloc.bar_index, extend = extend.none, color = color.new(color.gray, 40), style = line.style_dashed, width = 1)
array.unshift(bearBoxes, bx2)
array.unshift(bearStarts, lastUpIdx)
array.unshift(bearMidLines, ln2)
if bullBoxes.size() > 0
for i = array.size(bullBoxes) - 1 to 0
if array.size(bullBoxes) <= i or array.size(bullStarts) <= i
continue
b = array.get(bullBoxes, i)
box.set_right(b, bar_index)
if array.size(bullMidLines) > i
ln = array.get(bullMidLines, i)
float topB = box.get_top(b)
float botB = box.get_bottom(b)
float midY = (topB + botB) / 2.0
int leftX = box.get_left(b)
line.set_x1(ln, leftX)
line.set_x2(ln, bar_index)
line.set_y1(ln, midY)
line.set_y2(ln, midY)
float topB = box.get_top(b)
float botB = box.get_bottom(b)
bool mitigatedB = close < botB and close < botB
int startB = array.get(bullStarts, i)
bool expiredB = (bar_index - startB) >= maxAge
if mitigatedB or expiredB
bool makeBreaker = mitigatedB
array.remove(bullBoxes, i)
array.remove(bullStarts, i)
if array.size(bullMidLines) > i
array.remove(bullMidLines, i)
if makeBreaker and (not preventOverlap or f_can_create_breaker(topB, botB))
float midYB = (topB + botB) / 2.0
int leftX = bar_index
bxBr = box.new(leftX, topB, leftX + 1, botB, border_color = color.new(bearCol, 40), bgcolor = color.new(bearCol, 85))
lnBr = line.new(x1 = leftX, y1 = midYB, x2 = leftX + 1, y2 = midYB, xloc = xloc.bar_index, extend = extend.none, color = color.new(bearCol, 40), style = line.style_dashed, width = 1)
array.unshift(breakerBearBoxes, bxBr)
array.unshift(breakerBearStarts, leftX)
array.unshift(breakerBearMidLines, lnBr)
breakerBearPlot := topB
if bearBoxes.size() > 0
for i = array.size(bearBoxes) - 1 to 0
if array.size(bearBoxes) <= i or array.size(bearStarts) <= i
continue
b = array.get(bearBoxes, i)
box.set_right(b, bar_index)
if array.size(bearMidLines) > i
ln = array.get(bearMidLines, i)
float topS = box.get_top(b)
float botS = box.get_bottom(b)
float midY = (topS + botS) / 2.0
int leftX = box.get_left(b)
line.set_x1(ln, leftX)
line.set_x2(ln, bar_index)
line.set_y1(ln, midY)
line.set_y2(ln, midY)
float topS = box.get_top(b)
float botS = box.get_bottom(b)
bool mitigatedS = close > topS and close > topS
int startS = array.get(bearStarts, i)
bool expiredS = (bar_index - startS) >= maxAge
if mitigatedS or expiredS
bool makeBreaker = mitigatedS
array.remove(bearBoxes, i)
array.remove(bearStarts, i)
if array.size(bearMidLines) > i
array.remove(bearMidLines, i)
if makeBreaker and (not preventOverlap or f_can_create_breaker(topS, botS))
float midYS = (topS + botS) / 2.0
int leftX = bar_index
bxBr = box.new(leftX, topS, leftX + 1, botS, border_color = color.new(bullCol, 40), bgcolor = color.new(bullCol, 85))
lnBr = line.new(x1 = leftX, y1 = midYS, x2 = leftX + 1, y2 = midYS, xloc = xloc.bar_index, extend = extend.none, color = color.new(bullCol, 40), style = line.style_dashed, width = 1)
array.unshift(breakerBullBoxes, bxBr)
array.unshift(breakerBullStarts, leftX)
array.unshift(breakerBullMidLines, lnBr)
breakerBullPlot := botS
if breakerBullBoxes.size() > 0
for i = array.size(breakerBullBoxes) - 1 to 0
if array.size(breakerBullBoxes) <= i or array.size(breakerBullStarts) <= i
continue
b = array.get(breakerBullBoxes, i)
box.set_right(b, bar_index)
if array.size(breakerBullMidLines) > i
ln = array.get(breakerBullMidLines, i)
float topB = box.get_top(b)
float botB = box.get_bottom(b)
float midY = (topB + botB) / 2.0
int leftX = box.get_left(b)
line.set_x1(ln, leftX)
line.set_x2(ln, bar_index)
line.set_y1(ln, midY)
line.set_y2(ln, midY)
float topB = box.get_top(b)
float botB = box.get_bottom(b)
bool mitigatedB = close < botB and close < botB
int startB = array.get(breakerBullStarts, i)
bool expiredB = (bar_index - startB) >= maxAge
if not mitigatedB and not expiredB and high > botB and low < topB and close > topB
float pad = math.max(math.abs(topB - botB) * 0.1, syminfo.mintick * 2)
rejectBullPlot := botB - pad
if mitigatedB or expiredB
array.remove(breakerBullBoxes, i)
array.remove(breakerBullStarts, i)
if array.size(breakerBullMidLines) > i
array.remove(breakerBullMidLines, i)
if breakerBearBoxes.size() > 0
for i = array.size(breakerBearBoxes) - 1 to 0
if array.size(breakerBearBoxes) <= i or array.size(breakerBearStarts) <= i
continue
b = array.get(breakerBearBoxes, i)
box.set_right(b, bar_index)
if array.size(breakerBearMidLines) > i
ln = array.get(breakerBearMidLines, i)
float topS = box.get_top(b)
float botS = box.get_bottom(b)
float midY = (topS + botS) / 2.0
int leftX = box.get_left(b)
line.set_x1(ln, leftX)
line.set_x2(ln, bar_index)
line.set_y1(ln, midY)
line.set_y2(ln, midY)
float topS = box.get_top(b)
float botS = box.get_bottom(b)
bool mitigatedS = close > topS and close > topS
int startS = array.get(breakerBearStarts, i)
bool expiredS = (bar_index - startS) >= maxAge
if not mitigatedS and not expiredS and high > botS and low < topS and close < botS
float pad = math.max(math.abs(topS - botS) * 0.1, syminfo.mintick * 2)
rejectBearPlot := topS + pad
if mitigatedS or expiredS
array.remove(breakerBearBoxes, i)
array.remove(breakerBearStarts, i)
if array.size(breakerBearMidLines) > i
array.remove(breakerBearMidLines, i)
// --- Plots (AlgoAlpha) ---
breakerBullFormed = not na(breakerBullPlot)
breakerBearFormed = not na(breakerBearPlot)
rejectBull = not na(rejectBullPlot)
rejectBear = not na(rejectBearPlot)
plotshape(breakerBullPlot, "Bullish Breaker ", shape.labelup, location.absolute, bullCol, size = size.tiny, text = "▲", textcolor = chart.fg_color)
plotshape(breakerBearPlot, "Bearish Breaker ", shape.labeldown, location.absolute, bearCol, size = size.tiny, text = "▼", textcolor = chart.fg_color)
plotchar(rejectBullPlot, title = "Bullish Rejection ", char = "▲", location = location.absolute, color = bullCol, size = size.tiny)
plotchar(rejectBearPlot, title = "Bearish Rejection ", char = "▼", location = location.absolute, color = bearCol, size = size.tiny)
// ============================================================================
// SECTION 2: VOLUMIZED BREAKER BLOCKS
// ============================================================================
const bool DEBUG = false
const int maxBoxesCount = 500
const float overlapThresholdPercentage = 0
const int maxDistanceToLastBar = 1750
const int maxOrderBlocks = 60
var bool initRun = true
// --- Inputs (Flux Charts) ---
showInvalidated = input.bool(true, "Show Historic Zones", group = "Flux Charts - Configuration", display = display.none)
OBsEnabled = true
breakBlockVolumetricInfo = input.bool(false, "Volumetric Info", group = "Flux Charts - Configuration", inline="EV", display = display.none)
obEndMethod = input.string("Close", "Order Block Invalidation", options = , group = "Flux Charts - Configuration", display = display.none)
bbEndMethod = input.string("Close", "Breaker Block Invalidation", options = , group = "Flux Charts - Configuration", display = display.none)
combineOBs = DEBUG ? input.bool(true, "Combine Zones", group = "Flux Charts - Configuration", display = display.none) : true
maxATRMult = DEBUG ? input.float(3.5,"Max Atr Multiplier", group = "Flux Charts - Configuration") : 3.5
swingLength = input.int(10, 'Swing Length', minval = 3, tooltip="Swing length is used when finding breaker block formations.", group = "Flux Charts - Configuration", display = display.none)
zoneCount = input.string("Low", 'Zone Count', options = , tooltip = "Number of Breaker Block Zones to be rendered.", group = "Flux Charts - Configuration", display = display.none)
bullishBreakerBlockColor = input(color.new(#2962ff, 75), "Bullish Breaker", inline = 'breakerColor', group = 'Flux Charts - Configuration', display = display.none)
bearishBreakerBlockColor = input(color.new(#ffeb3b, 75), "Bearish Breaker", inline = 'breakerColor', group = 'Flux Charts - Configuration', display = display.none)
bullishBreakerBlocks = zoneCount == "Low" ? 3 : zoneCount == "Medium" ? 5 : 10
bearishBreakerBlocks = zoneCount == "Low" ? 3 : zoneCount == "Medium" ? 5 : 10
bullishOrderBlocks = zoneCount == "Low" ? 15 : zoneCount == "Medium" ? 30 : 60
bearishOrderBlocks = zoneCount == "Low" ? 15 : zoneCount == "Medium" ? 30 : 60
BBsEnabled = true
timeframe1Enabled = true
timeframe1 = ""
breakersFull = DEBUG ? input.bool(true, "Breakers Full", group = "Flux Charts - Style", display = display.none) : true
textColor = input.color(#ffffff80, "Text Color", group = "Flux Charts - Style")
combinedText = DEBUG ? input.bool(false, "Combined Text", group = "Flux Charts - Style", inline = "CombinedColor") : false
atr = ta.atr(10)
// --- Types (Flux Charts) ---
type orderBlockInfo
float top
float bottom
float obVolume
string obType
int startTime
float bbVolume
float obLowVolume
float obHighVolume
bool breaker
int breakTime
string timeframeStr
bool disabled = false
string combinedTimeframesStr = na
bool combined = false
type orderBlock
orderBlockInfo info
bool isRendered = false
box orderBox = na
box breakerBox = na
line orderBoxLineTop = na
line orderBoxLineBottom = na
line breakerBoxLineTop = na
line breakerBoxLineBottom = na
box orderBoxText = na
box orderBoxPositive = na
box orderBoxNegative = na
line orderSeperator = na
line orderTextSeperator = na
createOrderBlock(orderBlockInfo orderBlockInfoF) =>
orderBlock newOrderBlock = orderBlock.new(orderBlockInfoF)
newOrderBlock
safeDeleteOrderBlock(orderBlock orderBlockF) =>
orderBlockF.isRendered := false
box.delete(orderBlockF.orderBox)
box.delete(orderBlockF.breakerBox)
box.delete(orderBlockF.orderBoxText)
box.delete(orderBlockF.orderBoxPositive)
box.delete(orderBlockF.orderBoxNegative)
line.delete(orderBlockF.orderBoxLineTop)
line.delete(orderBlockF.orderBoxLineBottom)
line.delete(orderBlockF.breakerBoxLineTop)
line.delete(orderBlockF.breakerBoxLineBottom)
line.delete(orderBlockF.orderSeperator)
line.delete(orderBlockF.orderTextSeperator)
type timeframeInfo
int index = na
string timeframeStr = na
bool isEnabled = false
orderBlockInfo bullishOrderBlocksList = na
orderBlockInfo bearishOrderBlocksList = na
newTimeframeInfo(index, timeframeStr, isEnabled) =>
newTFInfo = timeframeInfo.new()
newTFInfo.index := index
newTFInfo.isEnabled := isEnabled
newTFInfo.timeframeStr := timeframeStr
newTFInfo
type obSwing
int x = na
float y = na
float swingVolume = na
bool crossed = false
var timeframeInfo timeframeInfos = array.from(newTimeframeInfo(1, timeframe1, timeframe1Enabled))
var bullishOrderBlocksList = array.new(0)
var bearishOrderBlocksList = array.new(0)
var allOrderBlocksList = array.new(0)
// --- Helper Functions (Flux Charts) ---
renderOrderBlock(orderBlock ob) =>
orderBlockInfo info = ob.info
ob.isRendered := true
breakerBlockColor = ob.info.obType == "Bull" ? bearishBreakerBlockColor : bullishBreakerBlockColor
if info.breaker and BBsEnabled
startTime = (OBsEnabled and not breakersFull) ? info.breakTime : info.startTime
ob.breakerBox := box.new(startTime, info.top, time + 1, info.bottom, na, bgcolor = breakerBlockColor, extend = extend.none, xloc = xloc.bar_time, text_color = textColor, text_size = size.normal)
BBText = (na(ob.info.combinedTimeframesStr) ? (ob.info.timeframeStr == "" ? timeframe.period : ob.info.timeframeStr) : ob.info.combinedTimeframesStr) + " BB"
box.set_text(ob.breakerBox, (breakBlockVolumetricInfo ? str.tostring(ob.info.bbVolume, format.volume) + " " : "") + (combinedText and ob.info.combined ? " " : "") + BBText)
ob.breakerBoxLineTop := line.new(startTime, info.top, time + 1, info.top, xloc.bar_time, extend.none, color.new(breakerBlockColor, 0), line.style_dashed)
ob.breakerBoxLineBottom := line.new(startTime, info.bottom, time + 1, info.bottom, xloc.bar_time, extend.none, color.new(breakerBlockColor, 0), line.style_dashed)
findOBSwings(len) =>
var swingType = 0
var obSwing top = obSwing.new(na, na)
var obSwing bottom = obSwing.new(na, na)
upper = ta.highest(len)
lower = ta.lowest(len)
swingType := high > upper ? 0 : low < lower ? 1 : swingType
if swingType == 0 and swingType != 0
top := obSwing.new(bar_index , high , volume )
if swingType == 1 and swingType != 1
bottom := obSwing.new(bar_index , low , volume )
findOrderBlocks() =>
if bar_index > last_bar_index - maxDistanceToLastBar
= findOBSwings(swingLength)
useBody = false
max = useBody ? math.max(close, open) : high
min = useBody ? math.min(close, open) : low
// Bullish Order Block (có bổ sung kiểm tra Imbalance)
if bullishOrderBlocksList.size() > 0
for i = bullishOrderBlocksList.size() - 1 to 0
currentOB = bullishOrderBlocksList.get(i)
if not currentOB.breaker
if ((obEndMethod == "Wick" ? low : close) < currentOB.bottom)
currentOB.breaker := true
currentOB.breakTime := time
currentOB.bbVolume := volume
else
if (bbEndMethod == "Wick" ? high : close) > currentOB.top
bullishOrderBlocksList.remove(i)
if close > top.y and not top.crossed and (not useImbalanceFilter or f_has_imbalance_bull())
top.crossed := true
boxBtm = max
boxTop = min
boxLoc = time
for i = 1 to (bar_index - top.x) - 1
boxBtm := math.min(min , boxBtm)
boxTop := boxBtm == min ? max : boxTop
boxLoc := boxBtm == min ? time : boxLoc
newOrderBlockInfo = orderBlockInfo.new(boxTop, boxBtm, volume + volume + volume , "Bull", boxLoc)
newOrderBlockInfo.obLowVolume := volume
newOrderBlockInfo.obHighVolume := volume + volume
obSize = math.abs(newOrderBlockInfo.top - newOrderBlockInfo.bottom)
if obSize <= atr * maxATRMult
bullishOrderBlocksList.unshift(newOrderBlockInfo)
if bullishOrderBlocksList.size() > maxOrderBlocks
bullishOrderBlocksList.pop()
// Bearish Order Block (có bổ sung kiểm tra Imbalance)
if bearishOrderBlocksList.size() > 0
for i = bearishOrderBlocksList.size() - 1 to 0
currentOB = bearishOrderBlocksList.get(i)
if not currentOB.breaker
if (obEndMethod == "Wick" ? high : close) > currentOB.top
currentOB.breaker := true
currentOB.breakTime := time
currentOB.bbVolume := volume
else
if (bbEndMethod == "Wick" ? low : close) < currentOB.bottom
bearishOrderBlocksList.remove(i)
if close < btm.y and not btm.crossed and (not useImbalanceFilter or f_has_imbalance_bear())
btm.crossed := true
boxBtm = min
boxTop = max
boxLoc = time
for i = 1 to (bar_index - btm.x) - 1
boxTop := math.max(max , boxTop)
boxBtm := boxTop == max ? min : boxBtm
boxLoc := boxTop == max ? time : boxLoc
newOrderBlockInfo = orderBlockInfo.new(boxTop, boxBtm, volume + volume + volume , "Bear", boxLoc)
newOrderBlockInfo.obLowVolume := volume + volume
newOrderBlockInfo.obHighVolume := volume
obSize = math.abs(newOrderBlockInfo.top - newOrderBlockInfo.bottom)
if obSize <= atr * maxATRMult
bearishOrderBlocksList.unshift(newOrderBlockInfo)
if bearishOrderBlocksList.size() > maxOrderBlocks
bearishOrderBlocksList.pop()
true
areaOfOB(orderBlockInfo OBInfoF) =>
float XA1 = OBInfoF.startTime
float XA2 = na(OBInfoF.breakTime) ? time + 1 : OBInfoF.breakTime
float YA1 = OBInfoF.top
float YA2 = OBInfoF.bottom
float edge1 = math.sqrt((XA2 - XA1) * (XA2 - XA1) + (YA2 - YA2) * (YA2 - YA2))
float edge2 = math.sqrt((XA2 - XA2) * (XA2 - XA2) + (YA2 - YA1) * (YA2 - YA1))
edge1 * edge2
doOBsTouch(orderBlockInfo OBInfo1, orderBlockInfo OBInfo2) =>
float XA1 = OBInfo1.startTime
float XA2 = na(OBInfo1.breakTime) ? time + 1 : OBInfo1.breakTime
float YA1 = OBInfo1.top
float YA2 = OBInfo1.bottom
float XB1 = OBInfo2.startTime
float XB2 = na(OBInfo2.breakTime) ? time + 1 : OBInfo2.breakTime
float YB1 = OBInfo2.top
float YB2 = OBInfo2.bottom
float intersectionArea = math.max(0, math.min(XA2, XB2) - math.max(XA1, XB1)) * math.max(0, math.min(YA1, YB1) - math.max(YA2, YB2))
float unionArea = areaOfOB(OBInfo1) + areaOfOB(OBInfo2) - intersectionArea
float overlapPercentage = (intersectionArea / unionArea) * 100.0
overlapPercentage > overlapThresholdPercentage
isOBValid(orderBlockInfo OBInfo) =>
not OBInfo.disabled
combineOBsFunc() =>
if allOrderBlocksList.size() > 0
lastCombinations = 999
while lastCombinations > 0
lastCombinations := 0
for i = 0 to allOrderBlocksList.size() - 1
curOB1 = allOrderBlocksList.get(i)
for j = 0 to allOrderBlocksList.size() - 1
curOB2 = allOrderBlocksList.get(j)
if i == j or not isOBValid(curOB1.info) or not isOBValid(curOB2.info) or curOB1.info.obType != curOB2.info.obType
continue
if doOBsTouch(curOB1.info, curOB2.info)
curOB1.info.disabled := true
curOB2.info.disabled := true
orderBlock newOB = createOrderBlock(orderBlockInfo.new(math.max(curOB1.info.top, curOB2.info.top), math.min(curOB1.info.bottom, curOB2.info.bottom), curOB1.info.obVolume + curOB2.info.obVolume, curOB1.info.obType))
newOB.info.startTime := math.min(curOB1.info.startTime, curOB2.info.startTime)
newOB.info.breakTime := math.max(nz(curOB1.info.breakTime), nz(curOB2.info.breakTime))
newOB.info.breakTime := newOB.info.breakTime == 0 ? na : newOB.info.breakTime
newOB.info.timeframeStr := curOB1.info.timeframeStr
newOB.info.obVolume := curOB1.info.obVolume + curOB2.info.obVolume
newOB.info.obLowVolume := curOB1.info.obLowVolume + curOB2.info.obLowVolume
newOB.info.obHighVolume := curOB1.info.obHighVolume + curOB2.info.obHighVolume
newOB.info.bbVolume := nz(curOB1.info.bbVolume, 0) + nz(curOB2.info.bbVolume, 0)
newOB.info.breaker := curOB1.info.breaker or curOB2.info.breaker
newOB.info.combined := true
allOrderBlocksList.unshift(newOB)
lastCombinations += 1
reqSeq(timeframeStr) =>
request.security(syminfo.tickerid, timeframeStr, )
getTFData(timeframeInfo timeframeInfoF, timeframeStr) =>
if timeframeInfoF.isEnabled
reqSeq(timeframeStr)
else
handleTimeframeInfo(timeframeInfo timeframeInfoF, bullishOrderBlocksListF, bearishOrderBlocksListF) =>
if timeframeInfoF.isEnabled
timeframeInfoF.bullishOrderBlocksList := bullishOrderBlocksListF
timeframeInfoF.bearishOrderBlocksList := bearishOrderBlocksListF
arrHasOB(orderBlock arr, orderBlock obF) =>
hasOB = false
if arr.size() > 0
for i = 0 to arr.size() - 1
orderBlock ob1 = arr.get(i)
if isOBValid(ob1.info) and isOBValid(obF.info) and (ob1.info.breaker == obF.info.breaker) and doOBsTouch(ob1.info, obF.info)
hasOB := true
break
hasOB
bool newBullishBBTick = false
bool newBearishBBTick = false
handleOrderBlocksFinal() =>
newBullishOBAlert = false
newBearishOBAlert = false
newBullishBBAlert = false
newBearishBBAlert = false
alertTimeOB = ""
alertTimeBB = ""
orderBlock orderBlocksToAdd = array.new(0)
for i = 0 to timeframeInfos.size() - 1
curTimeframe = timeframeInfos.get(i)
if not curTimeframe.isEnabled
continue
if not na(curTimeframe.bullishOrderBlocksList)
if curTimeframe.bullishOrderBlocksList.size() > 0
for j = 0 to math.min(curTimeframe.bullishOrderBlocksList.size() - 1, bullishOrderBlocks - 1)
orderBlockInfoF = curTimeframe.bullishOrderBlocksList.get(j)
orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr
orderBlocksToAdd.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))
if not na(curTimeframe.bearishOrderBlocksList)
if curTimeframe.bearishOrderBlocksList.size() > 0
for j = 0 to math.min(curTimeframe.bearishOrderBlocksList.size() - 1, bearishOrderBlocks - 1)
orderBlockInfoF = curTimeframe.bearishOrderBlocksList.get(j)
orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr
orderBlocksToAdd.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))
if orderBlocksToAdd.size() > 0
for i = 0 to orderBlocksToAdd.size() - 1
obToTest = orderBlocksToAdd.get(i)
if obToTest.info.breaker == false
if not arrHasOB(allOrderBlocksList, obToTest)
alertTimeOB := obToTest.info.timeframeStr
if obToTest.info.obType == "Bull"
newBullishOBAlert := true
else
newBearishOBAlert := true
else
if not arrHasOB(allOrderBlocksList, obToTest)
alertTimeBB := obToTest.info.timeframeStr
if obToTest.info.obType == "Bull"
newBearishBBAlert := true
else
newBullishBBAlert := true
if allOrderBlocksList.size() > 0
for i = 0 to allOrderBlocksList.size() - 1
safeDeleteOrderBlock(allOrderBlocksList.get(i))
allOrderBlocksList.clear()
if orderBlocksToAdd.size() > 0
for i = 0 to orderBlocksToAdd.size() - 1
allOrderBlocksList.unshift(orderBlocksToAdd.get(i))
if combineOBs
combineOBsFunc()
if allOrderBlocksList.size() > 0
for i = 0 to allOrderBlocksList.size() - 1
curOB = allOrderBlocksList.get(i)
if isOBValid(curOB.info)
renderOrderBlock(curOB)
findOrderBlocks()
= getTFData(timeframeInfos.get(0), timeframe1)
if barstate.isconfirmed and (bar_index > last_bar_index - maxDistanceToLastBar)
handleTimeframeInfo(timeframeInfos.get(0), bullishOrderBlocksListTimeframe1, bearishOrderBlocksListTimeframe1)
= handleOrderBlocksFinal()
if newBullishBBAlert
newBullishBBTick := true
if newBearishBBAlert
newBearishBBTick := true
// --- Alerts (Flux Charts) ---
alertcondition((newBullishBBTick or newBearishBBTick) and not initRun, "Breaker Block Formation ", "A new Breaker Block has formed.")
alertcondition(newBullishBBTick and not initRun, "Bullish Breaker Block Formation ", "A new Bullish Breaker Block has formed.")
alertcondition(newBearishBBTick and not initRun, "Bearish Breaker Block Formation ", "A new Bearish Breaker Block has formed.")
if barstate.isconfirmed
initRun := false Indicator

Indicator

Liquidity Gravity SMC Engine [Jayadev Rana]LIQUIDITY GRAVITY SMC ENGINE
WHAT IT IS
An experimental Smart Money Concepts toolkit that does not treat every order block and fair value gap as equal. Each unmitigated zone is modeled as a gravitational mass acting on price: heavy zones (born from strong displacement on high relative volume) matter more, old zones fade away, and the combined pull of all active zones is compressed into a single bounded bias reading. On top of that field sit a composite trend engine, a quality-scored buy/sell signal engine, and a pyramid re-add engine that only accepts fresh continuation zones.
THE GRAVITY MODEL (CORE ORIGINAL IDEA)
Every zone is minted with a mass at birth:
mass = displacement impulse (in ATR units) x (0.5 + volume percentile / 100)
The mass decays exponentially with a configurable half-life, so a zone that sits unmitigated for a long time gradually loses influence:
effective mass = mass x 0.5 ^ (age in bars / half-life)
Each bar, the script sums the pull of every active bullish zone and every active bearish zone on the current close using a softened inverse-square law (the softening epsilon prevents the value from exploding when price trades inside a zone):
pull = effective mass / (distance in ATR ^ 2 + epsilon ^ 2)
The two fields collapse into a bounded oscillator:
gravity bias = 100 x (bull field - bear field) / (bull field + bear field)
A reading near +100 means the active demand field dominates; near -100 means overhead supply dominates. The raw bull/bear field values, zone counts, and the bias are all exposed in the data window and on the dashboard.
ZONE DETECTION
- Order blocks: a break of a confirmed swing pivot with a displacement candle (body larger than a configurable ATR multiple) anoints the most recent opposite-color candle as the origin. Body-only or full-range zones are selectable.
- Fair value gaps: classic three-candle imbalance, filtered by a minimum gap height in ATR units and an optional minimum displacement body on the middle candle.
- Lifecycle: zones are marked on first touch, removed on a decisive close through the far side, expired after a maximum age, and capped per side (oldest dropped first).
TREND ENGINE
A composite score in -100..+100 blends three independent measurements with user weights:
1. Market structure regime from a BOS / CHoCH state machine on confirmed swing pivots.
2. Signed Kaufman efficiency ratio (how directional the recent path is versus noise).
3. ATR-normalized Hull MA slope, clamped to -1..+1.
The score passes through a hysteresis gate with separate entry and exit thresholds, so the published trend state (LONG / SHORT / NEUTRAL) does not flicker around zero.
SIGNALS AND THE RE-ADD ENGINE
A primary BUY prints when price trades into an active bullish zone and closes back above its top (a sweep and reject), while the trend state and, optionally, the gravity bias agree. Every candidate is scored with a 0-100 confluence quality:
quality = 100 x (0.35 x trend alignment + 0.25 x gravity alignment + 0.20 x zone mass rank + 0.20 x rejection strength)
Only candidates above the quality threshold print. After a primary entry, the re-add engine arms: an ADD signal requires a FRESH zone (born after the previous entry bar), the same trend direction, and a reduced quality threshold, with a hard cap on adds per leg. Legs terminate on an opposing trend flip or an opposing CHoCH, which prints an EXIT marker. SELL logic mirrors the buy side.
INPUT GROUPS
1. Market Structure - pivot length, BOS/CHoCH lines, swing labels.
2. Order Blocks - lookback, body-only toggle, displacement filter.
3. Fair Value Gaps - minimum gap size, middle-candle displacement filter.
4. Gravity Model - mass half-life, softening epsilon, volume percentile lookback, zone expiry, zone cap.
5. Trend Engine - efficiency ratio length, Hull MA length and slope lookback, component weights, entry/exit thresholds.
6. Signals and Re-Add - primary and re-add quality thresholds, max adds per leg, cooldown, gravity alignment toggle, bar-close confirmation.
7. Visuals - zone boxes, signal labels, trend ribbon, gravity gradient bar coloring, colors.
8. Dashboard - position and text size.
ALERTS
Ten alert conditions: primary BUY, primary SELL, re-add long, re-add short, trend flip long, trend flip short, bullish zone created, bearish zone created, bullish zone touched, bearish zone touched.
INTENDED MARKETS AND TIMEFRAMES
Any symbol with volume data (crypto, futures, liquid stocks, major forex pairs). The volume percentile term falls back gracefully where volume is absent, but zone masses become less differentiated. Designed for intraday through daily timeframes; defaults were chosen on 5-minute to 1-hour charts.
NON-REPAINTING BEHAVIOR
Swing pivots confirm after the pivot length (standard pivot lag). BOS/CHoCH events are evaluated on closes against already-confirmed pivots. With "confirm on bar close" enabled (default), signals and alerts fire only on confirmed bars. No security() calls and no lookahead are used.
LIMITATIONS
- The gravity model is a heuristic, not a physical law; the inverse-square form and the half-life are modeling choices you can tune.
- Zone quality depends on the displacement and volume filters; thin or gappy instruments produce fewer, noisier zones.
- Signals are informational markers, not orders; the leg/adds bookkeeping is a visual state machine, not broker position tracking.
This is an educational tool, not financial advice. Test any settings on your own market and timeframe before relying on them. Indicator

Fair Value Gaps Standalone [Rivasjr]English
Fair Value Gaps Standalone is a Pine Script® v6 indicator designed to identify and display bullish and bearish Fair Value Gaps directly on the chart.
A Fair Value Gap is a three-candle price imbalance that appears when part of the price range between the first and third candles is not traded. These areas can help traders visualize zones where price moved with displacement and where future interaction may occur.
Main features
Detects bullish and bearish Fair Value Gaps.
Displays each imbalance as a two-part shaded zone.
Supports the chart timeframe or a user-selected detection timeframe.
Includes an automatic threshold to filter less significant imbalances.
Allows users to control the horizontal extension of each FVG.
Can automatically remove fully mitigated Fair Value Gaps.
Provides independent colors for bullish and bearish zones.
How the indicator works
A bullish Fair Value Gap is identified when the low of the third candle remains above the high of the first candle and the displacement conditions are satisfied.
A bearish Fair Value Gap is identified when the high of the third candle remains below the low of the first candle and the displacement conditions are satisfied.
Each detected imbalance is divided at its midpoint and displayed using two boxes. Both boxes belong to the same Fair Value Gap and are removed together when full mitigation is enabled and price completely crosses the corresponding invalidation boundary.
Settings translation
Fair Value Gaps: Shows or hides detected Fair Value Gaps.
Auto Threshold: Automatically filters less significant gaps.
Intervalo de tiempo / Timeframe: Selects the timeframe used for FVG detection. Selecting “Chart” uses the current chart timeframe.
Bullish FVG: Sets the color of bullish Fair Value Gaps.
Bearish FVG: Sets the color of bearish Fair Value Gaps.
Extend FVG: Sets the number of additional bars used to extend each zone.
Eliminar FVG mitigados / Delete mitigated FVGs: Removes a zone after price completely crosses its mitigation boundary.
Important information
This indicator identifies price imbalances only. It does not generate entries, exits, profit targets, stop-loss levels, or trading recommendations. Fair Value Gaps should be evaluated together with market structure, liquidity, volume, trend, session context, and appropriate risk management.
Historical and real-time behavior can differ while a higher-timeframe candle is still developing. Users should understand the selected detection timeframe before using the indicator in their analysis.
Credits
Original Fair Value Gap concept and logic: © LuxAlgo.
Standalone Pine Script® v6 adaptation, structural organization, configurable visualization, mitigation management, timeframe selection, and user-interface implementation: © Rivasjr.
This work is distributed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
────────────────────────────────────
Español
Fair Value Gaps Standalone es un indicador desarrollado en Pine Script® v6 para identificar y mostrar Fair Value Gaps alcistas y bajistas directamente sobre el gráfico.
Un Fair Value Gap es un desequilibrio de precio formado por una estructura de tres velas, en la cual una parte del rango comprendido entre la primera y la tercera vela no fue negociada. Estas zonas permiten visualizar áreas donde el precio se desplazó con fuerza y donde podría producirse una interacción posterior.
Funciones principales
Detecta Fair Value Gaps alcistas y bajistas.
Representa cada desequilibrio mediante una zona dividida en dos secciones.
Permite utilizar el intervalo del gráfico o un intervalo de detección diferente.
Incluye un umbral automático para filtrar desequilibrios menos significativos.
Permite controlar la extensión horizontal de las zonas.
Puede eliminar automáticamente los FVG completamente mitigados.
Ofrece colores independientes para zonas alcistas y bajistas.
Funcionamiento
Un Fair Value Gap alcista se identifica cuando el mínimo de la tercera vela permanece por encima del máximo de la primera vela y se cumplen las condiciones de desplazamiento.
Un Fair Value Gap bajista se identifica cuando el máximo de la tercera vela permanece por debajo del mínimo de la primera vela y se cumplen las condiciones de desplazamiento.
Cada desequilibrio se divide en su punto medio y se representa mediante dos cajas. Ambas cajas forman parte del mismo Fair Value Gap y se eliminan conjuntamente cuando está activada la eliminación de zonas mitigadas y el precio atraviesa completamente su límite correspondiente.
Información importante
Este indicador identifica desequilibrios de precio. No proporciona entradas, salidas, objetivos, niveles de stop-loss ni recomendaciones de inversión. Los Fair Value Gaps deben analizarse junto con la estructura del mercado, liquidez, volumen, tendencia, contexto de sesión y una gestión de riesgo adecuada.
El comportamiento histórico y en tiempo real puede variar mientras una vela de temporalidad superior continúa en formación.
Indicator

Wonra Alchemist SNR EngineWonra Alchemist SNR Engine
An implementation of Malaysian SNR (MSNR) and the Quasimodo reversal pattern, built as one engine because in that method the pieces are not independent indicators. A level means nothing without knowing which way the story is running, and the story is told by levels. This publishes the whole reading rather than one part of it.
Everything below is visible in the source. This is published open-source so the code is the final word on any of it.
How levels are found
Malaysian SNR ignores wicks. A level is marked by joining one candle's close to the next candle's open, and the space between those two prices is the level itself. Where the two meet you get a hairline; where they do not, the space between them never traded, and that untraded space is what the method calls a GAP. The engine treats both as one construct: a level is a band, and a gap is a band you can see.
That has consequences the code follows through on:
A touch registers at either edge of the band.
A break requires a close through the far edge. Closing inside the band has broken nothing, because nothing in there ever traded.
Levels are seeded from confirmed swings (an ATR-threshold zigzag, so minor noise does not create a level of its own) and from close-to-open gaps above a size floor.
How a level earns weight
Two things strengthen a level, and the second is the one most tools ignore.
Touches. Price left the level, came back and was refused. Leaving is required: price hovering at a price does not add a touch every bar.
Misses. Price swung toward the level and turned before reaching it. In MSNR a miss validates a level rather than doing nothing, and the reasoning is that the resting liquidity was never taken, so all of it is still there. A level with three misses is not the same as one with three taps, and the label shows them separately.
Role flip (SBR / RBS)
A level closed through does not disappear, it changes sides. Broken support becomes resistance and broken resistance becomes support, keeping its history. This is the SBR/RBS part of the method and it is why the chart does not empty out over a session.
Quasimodo (QM / QML)
The engine looks for the QM shape: a shoulder, a head beyond it, and a return. For a bullish QM the head must be a lower low than the left shoulder; the level drawn is the left shoulder, not the head, which is where the pattern is traded from. Each candidate must also produce a structure break before it is accepted, and combinations are scanned across several swings so a pattern is still found when a minor swing sits inside it.
Supply zones extend up from the QM level and demand zones extend down from it, on one side only, so price is not counted as having reached a zone while it is still short of the level.
Storyline (direction)
MSNR determines direction from higher-timeframe levels, and the engine follows the four rules the method states:
Direction comes from higher-timeframe levels, read from bodies, not from wick extremes.
A storyline begins with a rejection: a close back below resistance, or back above support.
It is confirmed by a breakout on a lower timeframe. The engine distinguishes the two kinds the method names — an internal breakout of a level formed after the rejection, and an external breakout of one that already existed — and reports which occurred.
Levels against the established direction are roadblocks: the places pullbacks are expected to stop on the way. They are marked rather than hidden, because they are the one thing the method tells you to expect.
Engulfing zones (EG / EF)
An engulfing candle above a size floor creates a zone. The rule that makes it worth having is what happens when it fails: a bullish zone that price closes through becomes a failed zone read the other way, at the same prices, because that is where the other side proved itself. Broken twice and it is discarded, having now been wrong in both directions.
Imbalances
Three-candle gaps, drawn as neutral background. Zones spanning a market closure are discarded — a weekend is not unfinished business between buyers and sellers, it is a closed market, and it happens to leave the largest and most eye-catching gap on the chart.
Scoring
Confirmed patterns are scored 0-100 from what the engine already knows about them: the size of the structure, the quality of the break, whether liquidity was swept and how cleanly, whether an imbalance sits inside the zone, and how proven the levels involved are. The score sets how loudly a pattern is drawn. Nothing is deleted for scoring low.
Why this is one script and not several
Because in this method the parts are not separable. The storyline decides which levels are tradeable and which are roadblocks. The QM level is only a setup when it agrees with the storyline. A level's weight comes from its own touch and miss history. Splitting these into separate indicators would produce three scripts that each need the other two to say anything, which is the situation this replaces.
How to use it
The panel gives the current reading: storyline direction and which breakout confirmed it, how many fresh zones are live on each side, the nearest zone in ATR, and whether a confluence is being watched.
Fresh zones are the tradeable ones. A zone that has been used is faded, not removed, so the history stays readable.
Zone reactions are marked where they happen. A diamond marks a reaction from a level that had already proven itself.
Levels against the storyline are marked RB. Expect a pause there, not a reversal.
Higher timeframes for direction, lower for entry timing. The storyline timeframe is automatic and can be set manually.
Credits
The concepts are not mine. Malaysian SNR, the storyline structure, roadblocks, fresh and unfresh levels, the MISS, SBR/RBS and the Quasimodo entry come from Malaysian SNR and Alchemist educational material that circulates publicly. This is an implementation of that method, not a new one.
The Strong FVG section is taken from "Customizable Strong FVGs" by Fleezzuss, published open-source under the Mozilla Public License 2.0. The three-candle detection, the sensitivity modes and the zone lifecycle are their work. This script is published open-source under the same licence because of it.
Added on top: a gap is not drawn when it would sit on one already on the chart, so consecutive impulse candles stop stacking zones at the same price; gaps spanning a market closure are discarded, because a weekend is a closed market rather than an imbalance; and the palette is neutral so imbalances sit behind the levels instead of competing with them.
Not financial advice. This is an analysis tool. It does not predict outcomes and does not tell you to buy or sell. Every level can fail.
Indicator

Ultimate Scalping Signal Indicator//@version=6
indicator("Ultimate Scalping Signal Indicator", overlay=true)
// --- Inputs ---
emaLength = input.int(50, title="EMA Trend Length", minval=1)
stochLength = input.int(14, title="Stochastic Length", minval=1)
rsiLength = input.int(14, title="RSI Length", minval=1)
kSmooth = input.int(3, title="Smooth %K", minval=1)
dSmooth = input.int(3, title="Smooth %D", minval=1)
// --- Calculations ---
// 1. Trend Filter (EMA)
emaVal = ta.ema(close, emaLength)
plot(emaVal, color=color.blue, title="50 EMA", linewidth=2)
// 2. Momentum Filter (Stochastic RSI)
rsiVal = ta.rsi(close, rsiLength)
stochRsi = ta.stoch(rsiVal, rsiVal, rsiVal, stochLength)
k = ta.sma(stochRsi, kSmooth)
d = ta.sma(k, dSmooth)
// --- Signal Conditions ---
// Long Condition: Price is above EMA, and Stoch RSI %K crosses above %D below the oversold line (20)
longCondition = (close > emaVal) and ta.crossover(k, d) and (k < 20)
// Short Condition: Price is below EMA, and Stoch RSI %K crosses below %D above the overbought line (80)
shortCondition = (close < emaVal) and ta.crossunder(k, d) and (k > 80)
// --- Visual Alerts on Chart ---
plotshape(series=longCondition, title="Buy Signal", style=shape.triangleup,
location=location.belowbar, color=color.green, size=size.small, text="BUY")
plotshape(series=shortCondition, title="Sell Signal", style=shape.triangledown,
location=location.abovebar, color=color.red, size=size.small, text="SELL")
// --- Technical Alerts for PulseWire ---
alertcondition(longCondition, title="Scalp Buy Alert", message="Scalp Buy Signal Triggered!")
alertcondition(shortCondition, title="Scalp Sell Alert", message="Scalp Sell Signal Triggered!") Indicator

Indicator

Indicator

Eliot's Suite StrategyEliot's Suite Strategy — how it works
This strategy turns the "Eliot's Suite" indicator into a full trading system. It follows exactly the workflow the indicator's author described in the manual: define bias → wait for a structure trigger → enter → trail the stop behind fractals.
1. Bias filter. First the strategy decides which direction it's allowed to trade. With the default EMA Trend (50/200) filter, EMA50 above EMA200 means a macro uptrend, so only longs are allowed; the reverse allows only shorts. You can switch this to Session VWAP (looser) or turn it off entirely.
2. Structure trigger. By default the entry signal is ChoCh (Reversal) — the same trigger the author recommends. After a pullback, market structure breaks in your direction, and you enter on the resumption. You can switch this to BOS (Continuation) or Both.
3. Level check (optional, off by default). This is the author's "wait for the setup" rule. When enabled, the entry only fires if price is currently near a key level — VWAP, Daily Open, or yesterday's VWAP close.
4. Entry. A position only opens when all active conditions line up at once: bias confirms the direction and the trigger fires and (if enabled) price is near a level. The trigger alone does nothing without the bias filter agreeing — this is what filters out counter-trend entries, which is where this kind of structural logic usually bleeds money.
Once you're in a position, the second diagram takes over.
Stop loss sits at the last opposite fractal (below price for longs, above for shorts). If no valid fractal exists at entry, it falls back to an ATR-based stop.
Take profit is set as an R-multiple of that stop distance — default 2R, meaning the target is twice as far as the risk.
Trailing uses a ratchet rule: the stop only ever moves in your favour and never loosens. For a long, the stop becomes max(old stop, newest fractal below price); for a short, min(old stop, newest fractal above price). That's the "trail your stop behind the newly formed fractal boundary lines" idea from the manual, made mechanical.
Exit happens when price hits the stop, hits the take profit, or (optionally) when an opposite structure signal prints.
A couple of honest notes on backtesting: the strategy runs "clean" — no repainting, orders fill on the next bar's open, fractals confirm with the natural rightLen-bar delay. That delay means entries lag slightly behind the actual extreme, which is normal for fractals but eats into moves on low timeframes, so watch net profit against commission carefully — especially on 10m gold like your screenshot.
The two PNGs above are downloadable and copy-pasteable. Want me to also export the same two as a single combined image, or add a short-side mirror toggle like we did on "Money Printer"? Strategy

Indicator

ICT Sessions//@version=6
indicator("ICT交易时段", overlay=true)
// ==================== 设置 ====================
tz = input.string("America/New_York", "时区", options= )
showAsia = input.bool(true, "显示亚洲盘")
showLondon = input.bool(true, "显示伦敦盘")
showNY = input.bool(true, "显示纽约盘")
showOverlap = input.bool(true, "显示重合时段")
// 重点:加上 :23456 (只周一到周五)
asiaS = input.session("1900-0400:23456", "亚洲盘时间")
londonS = input.session("0200-1200:23456", "伦敦盘时间")
nyS = input.session("0800-1700:23456", "纽约盘时间")
asiaColor = input.color(color.new(#F5E6C8, 78), "亚洲颜色")
londonColor = input.color(color.new(#C8E6C9, 78), "伦敦颜色")
nyColor = input.color(color.new(#E1BEE7, 78), "纽约颜色")
overlapColor = input.color(color.new(#9C27B0, 65), "伦敦-纽约重合颜色")
asiaLonColor = input.color(color.new(#80CBC4, 70), "亚洲-伦敦重合颜色")
// ==================== 核心逻辑 ====================
isAsia = not na(time(timeframe.period, asiaS, tz))
isLondon = not na(time(timeframe.period, londonS, tz))
isNY = not na(time(timeframe.period, nyS, tz))
isLondonNY = isLondon and isNY
isAsiaLon = isAsia and isLondon
// ==================== 背景绘制 ====================
bgcolor(showOverlap and isLondonNY ? overlapColor : na)
bgcolor(showOverlap and isAsiaLon ? asiaLonColor : na)
bgcolor(showAsia and isAsia and not isAsiaLon and not isLondonNY ? asiaColor : na)
bgcolor(showLondon and isLondon and not isAsiaLon and not isLondonNY ? londonColor : na)
bgcolor(showNY and isNY and not isLondonNY ? nyColor : na) Indicator
