Indikator dan strategi
Volume Profile Skew [BackQuant]Volume Profile Skew
Overview
Volume Profile Skew is a market-structure indicator that answers a specific question most volume profiles do not:
“Is volume concentrating toward lower prices (accumulation) or higher prices (distribution) inside the current profile range?”
A standard volume profile shows where volume traded, but it does not quantify the shape of that distribution in a single number. This script builds a volume profile over a rolling lookback window, extracts the key profile levels (POC, VAH, VAL, and a volume-weighted mean), then computes the skewness of the volume distribution across price bins. That skewness becomes an oscillator, smoothed into a regime signal and paired with visual profile plotting, key level lines, and historical POC tracking.
This gives you two layers at once:
A full profile and its important levels (where volume is).
A skew metric (how volume is leaning within that range).
What this indicator is based on
The foundation comes from classical “volume at price” concepts used in Market Profile and Volume Profile analysis:
POC (Point of Control): the price level with the highest traded volume.
Value Area (VAH/VAL): the zone containing the bulk of activity, commonly 70% of total volume.
Volume-weighted mean (VWMP in this script): the average price weighted by volume, a “center of mass” for traded activity.
Where this indicator extends the idea is by treating the volume profile as a statistical distribution across price. Once you treat “volume by price bin” as a probability distribution (weights sum to 1), you can compute distribution moments:
Mean: where the mass is centered.
Standard deviation: how spread-out it is.
Skewness: whether the distribution has a heavier tail toward higher or lower prices.
This is not a gimmick. Skewness is a standard statistic in probability theory. Here it is applied to “volume concentration across price”, not to returns.
Core concept: what “skew” means in a volume profile
Imagine a profile range from Low to High, split into bins. Each bin has some volume. You can get these shapes:
Balanced profile: volume is fairly symmetric around the mean, skew near 0.
Bottom-heavy profile: more volume at lower prices, with a tail toward higher prices, skew tends to be positive.
Top-heavy profile: more volume at higher prices, with a tail toward lower prices, skew tends to be negative.
In this script:
Positive skew is labeled as ACCUMULATION.
Negative skew is labeled as DISTRIBUTION.
Near-zero skew is NEUTRAL.
Important: accumulation here does not mean “buying will immediately pump price.” It means the profile shape suggests more participation at lower prices inside the current lookback range. Distribution means participation is heavier at higher prices.
How the volume profile is built
1) Define the analysis window
The profile is computed on a rolling window:
Lookback Period: number of bars included (capped by available history).
Profile Resolution (bins): number of price bins used to discretize the high-low range.
The script finds the highest high and lowest low in the lookback window to define the price range:
rangeHigh = highest high in window
rangeLow = lowest low in window
binSize = (rangeHigh - rangeLow) / bins
2) Create bin midpoints
Each bin gets a midpoint “price” used for calculations:
price = rangeLow + binSize * (b + 0.5)
These midpoints are what the mean, variance, and skewness are computed on.
3) Distribute each candle’s volume into bins
This is a key implementation detail. Real volume profiles require tick-level data, but Pine does not provide that. So the script approximates volume-at-price using candle ranges:
For each bar in the lookback:
Determine which bins its low-to-high range touches.
Split that candle’s total volume evenly across the touched bins.
So if a candle spans 6 bins, each bin gets volume/6 from that bar. This is a practical, consistent approximation for “where trading could have occurred” inside the bar.
This approach has tradeoffs:
It does not know where within the candle the volume truly traded.
It assumes uniform distribution across the candle range.
It becomes more meaningful with larger samples (bigger lookback) and/or higher timeframes.
But it is still useful because the purpose here is the shape of the distribution across the whole window, not exact microstructure.
Key profile levels: POC, VAH, VAL, VWMP
POC (Point of Control)
POC is found by scanning bins and selecting the bin with maximum volume. The script stores:
pocIndex: which bin has max volume
poc price: midpoint price of that bin
Value Area (VAH/VAL) using 70% volume
The script builds the value area around the POC outward until it captures 70% of total volume:
Start with the POC bin.
Expand one bin at a time to the side with more volume.
Stop when accumulated volume >= 70% of total profile volume.
Then:
VAL = rangeLow + binSize * lowerIdx
VAH = rangeLow + binSize * (upperIdx + 1)
This produces a classic “where most business happened” zone.
VWMP (Volume-Weighted Mean Price)
This is essentially the center of mass of the profile:
VWMP = sum(price * volume ) / totalVolume
It is similar in spirit to VWAP, but it is computed over the profile bins, not from bar-by-bar typical price.
Skewness calculation: turning the profile into an oscillator
This is the main feature.
1) Treat volumes as weights
For each bin:
weight = volume / totalVolume
Now weights sum to 1.
2) Compute weighted mean
Mean price:
mean = sum(weight * price )
3) Compute weighted variance and std deviation
Variance:
variance = sum(weight * (price - mean)^2)
stdDev = sqrt(variance)
4) Compute weighted third central moment
Third moment:
m3 = sum(weight * (price - mean)^3)
5) Standardize to skewness
Skewness:
rawSkew = m3 / (stdDev^3)
This standardization matters. Without it, the value would explode or shrink based on profile scale. Standardized skewness is dimensionless and comparable.
Smoothing and regime rules
Raw skewness can be jumpy because:
profile bins change as rangeHigh/rangeLow shift,
one high-volume candle can reshape the distribution,
volume regimes change quickly in crypto.
So the indicator applies EMA smoothing:
smoothedSkew = EMA(rawSkew, smooth)
Then it classifies regime using fixed thresholds:
Bullish (ACCUMULATION): smoothedSkew > +0.25
Bearish (DISTRIBUTION): smoothedSkew < -0.25
Neutral: between those values
Signals are generated on threshold cross events:
Bull signal when smoothedSkew crosses above +0.25
Bear signal when smoothedSkew crosses below -0.25
This makes the skew act like a regime oscillator rather than a constantly flipping color.
Volume Profile plotting modes
The script draws the profile on the last bar, using boxes for each bin, anchored to the right with a configurable offset. The width of each profile bar is normalized by max bin volume:
volRatio = binVol / maxVol
barWidth = volRatio * width
Three style modes exist:
1) Gradient
Uses a “jet-like” gradient based on volRatio (blue → red). Higher-volume bins stand out naturally. Transparency increases as volume decreases, so low-volume bins fade.
2) Solid
Uses the current regime color (bull/bear/neutral) for all bins, with transparency. This makes the profile read as “structure + regime.”
3) Skew Highlight
Highlights bins that match the skew bias:
If skew bullish, emphasize lower portion of profile.
If skew bearish, emphasize higher portion of profile.
Else, keep most bins neutral.
This is a visual “where the skew is coming from” mode.
Historical POC tracking and Naked POCs
This script also treats POCs as meaningful levels over time, similar to how traders track old VA levels.
What is a “naked POC”?
A “naked POC” is a previously formed POC that has not been revisited (retested) by price since it was recorded. Many traders watch these as potential reaction zones because they represent prior “maximum traded interest” that the market has not re-engaged with.
How this script records POCs
It stores a new historical POC when:
At least updatebars have passed since the last stored POC, and
The POC has changed by at least pochangethres (%) from the last stored value.
New stored POCs are flagged as naked by default.
How naked becomes tested
On each update, the script checks whether price has entered a small zone around a naked POC:
zoneSize = POC * 0.002 (about 0.2%)
If bar range overlaps that zone, mark it as tested (not naked).
Display controls:
Highlight Naked POCs: draws and labels untested POCs.
Show Tested POCs: optionally draw tested ones in a muted color.
To avoid clutter, the script limits stored POCs to the most recent 20 and avoids drawing ones too close to the current POC.
On-chart key levels and what they mean
When enabled, the script draws the current lookback profile levels on the price chart:
POC (solid): the “most traded” price.
VAH/VAL (dashed): boundaries of the 70% value area.
VWMP (dotted): volume-weighted mean of the profile distribution.
Interpretation framework (practical, not mystical):
POC often behaves like a magnet in balanced conditions.
VAH/VAL define the “accepted” area, breaks can signal auction continuation.
VWMP is a fair-value reference, useful as a mean anchor when skew is neutralizing.
Oscillator panel and histogram
The skew oscillator is plotted in a separate pane:
Line: smoothedSkew, colored by regime.
Histogram: smoothedSkew as bars, colored by sign.
Fill: subtle shading above/below 0 to reinforce bias.
This makes it easy to read:
Direction of bias (positive vs negative).
Strength (distance from 0 and from thresholds).
Transitions (crosses of ±0.25).
Info table: what it summarizes
On the last bar, a table prints key diagnostics:
Current skew value (smoothed).
Regime label (ACCUMULATION / DISTRIBUTION / NEUTRAL).
Current POC, VAH, VAL, VWMP.
Count of naked POCs still active.
A simple “volume location” hint (lower/higher/balanced).
This is designed for quick scanning without reading the entire profile.
Alerts
The indicator includes alerts for:
Skew regime shifts (cross above +0.25, cross below -0.25).
Price crossing above/below current POC.
Approaching a naked POC (within 1% of any active naked POC).
The “approaching naked POC” alert is useful as a heads-up that price is entering a historically important volume magnet/reaction zone.
How to use it properly
1) Regime filter
Use skew regime to decide what type of trades you should prioritize:
ACCUMULATION (positive skew): market activity is heavier at lower prices, pullbacks into value or below VWMP often matter more.
DISTRIBUTION (negative skew): activity is heavier at higher prices, rallies into value or above VWMP often matter more.
NEUTRAL: mean-reversion and POC magnet behavior tends to dominate.
This is not “buy when green.” It is context for what the auction is doing.
2) Level-based execution
Combine skew with VA/POC levels:
In neutral regimes, expect rotations around POC and inside VA.
In strong skew regimes, watch for acceptance away from POC and reactions at VA edges.
3) Naked POCs as targets and reaction zones
Naked POCs can act like unfinished business. Common workflows:
As targets in rotations.
As areas to reduce risk when price is approaching.
As “if it breaks cleanly, trend continuation” markers when price returns with force.
Parameter tuning guidance
Lookback
Controls how “local” the profile is.
Shorter: reacts faster, more sensitive to recent moves.
Longer: more stable, better for swing context.
Bins
Controls resolution of the profile.
Higher bins: more detail, more computation, more sensitive profile shape.
Lower bins: smoother, less detail, more stable skew.
Smoothing
Controls how noisy the skew oscillator is.
Higher smoothing: fewer regime flips, slower response.
Lower smoothing: more responsive, more false transitions.
POC tracking settings
Update interval and threshold decide how many historical POCs you store and how different they must be. If you set them too loose, you will spam levels. If too strict, you will miss meaningful shifts.
Limitations and what not to assume
This indicator uses candle-range volume distribution because Pine cannot see tick-level volume-at-price. That means:
The profile is an approximation of where volume could have traded, not exact tape data.
Skew is best treated as a structural bias, not a precise signal generator.
Extreme single-bar events can distort the distribution briefly, smoothing helps but cannot remove reality.
Summary
Volume Profile Skew takes standard volume profile structure (POC, Value Area, volume-weighted mean) and adds a statistically grounded measure of profile shape using skewness. The result is a regime oscillator that quantifies whether volume concentration is leaning toward lower prices (accumulation) or higher prices (distribution), while also plotting the full profile, key levels, and historical naked POCs for actionable context.
Hedge Fund Session Ranges [GMT+2] - Multi-Timezone TrackingOverview
This professional-grade tool is designed for institutional-style trading, specifically focusing on the Liquidity Cycles of the global markets. It allows traders to visualize key trading windows (Asia, Europe, and US) with precision, using a fixed GMT+2 offset—ideal for traders aligned with Middle Eastern or Eastern European timezones.
Key Features
Triple Session Tracking: Includes pre-defined windows for Asia, London Morning, and NY Afternoon.
Dynamic Box Scaling: Automatically calculates and visualizes the High/Low range of each session in real-time.
GMT+2 Optimization: Built-in timezone handling to ensure your charts align perfectly with local bank hours.
Clean Visuals: Minimalist design to avoid chart clutter, allowing for clear price action analysis.
Why Trade Sessions?
Institutional volume isn't distributed evenly throughout the day. By identifying the Asian Range (01:00-06:00), the London Open (10:00-12:00), and the NY Reversal/Trend (16:30-18:30), traders can identify "Liquidity Grabs" and "Expansion Phases" more effectively.
LDEF SENS Loss Dependent Error Filter Dominance Regime SwitchCAPITALCOM:GOLD
LDEF SENS stands for Loss Dependent Error Filter. This indicator is a dominance regime filter with an adaptive switch boundary. It separates the market into two main states.
Directional tradeable tape (trend and impulse conditions)
Balanced noisy tape (higher fakeout probability)
It also provides a dominance direction bias (bull vs bear) and an adaptive boundary you can use as a market switch signal.
What you see in the indicator pane (bottom panel)
Main line (0 to 100): dominance sensitivity score
Line color meaning
Green: bullish dominance (L greater than R)
Red: bearish dominance (R greater than L)
Gray: low strength or mixed tape
Purple line: adaptive regime boundary (moving threshold)
Violet shading: regime ON (tradeable conditions)
Key idea: height equals strength, color equals direction, violet shading equals regime state.
How to read the three images
Image A - Regime ON in a trending environment
Where to look
Price panel: left to middle shows a clean up move
Indicator panel: directly below the same time window
Violet band is present for a sustained stretch
Main line stays high and mostly green
What it means
When the violet band stays ON, the tape is directional enough for trend following setups to have higher quality. This is not an entry signal. It is an environment filter.
Image B - Switch boundary and state changes
Where to look
Indicator panel: focus on the purple adaptive line and the main line crossing relative to it
Watch the moment the main line moves above the purple line. In the same region, violet shading turns ON.
What it means
The purple line is the adaptive regime boundary.
Cross above: regime switches toward directional tape (state change confirmation)
Cross below: regime fades and chop risk returns
Image C - Direction semantics inside a regime
Where to look
Indicator panel: inside violet shaded regions
Main line is green during bullish dominance (L greater than R)
Main line is red during bearish dominance (R greater than L)
What it means
Violet answers: is this a tradeable regime
Green or red answers: which side is dominating
Together, they provide a filter plus bias framework.
Practical usage
Regime filter
Prefer setups only when the violet band is ON
Reduce size or tighten criteria when the violet band is OFF
Direction bias
Prefer longs when the line is green
Prefer shorts when the line is red
Treat gray as no edge or mixed tape
Switch boundary analysis
Cross above purple: treat as regime shift confirmation
Cross below purple: treat as regime cooling off and higher chop risk
Limitations
This is a regime and dominance tool, not a standalone entry generator. Regime confirmation can be late by design, especially after shocks. Use it with structure, liquidity, and risk management.
Market Structure & Supply-Demand EngineMarket Structure & Supply-Demand Engine (MSD-Engine) is a professional, non-repainting market structure and supply-demand analysis tool built purely on price action and volatility logic.
This indicator is designed for discretionary traders who want a clean, institutional-style view of market structure without lagging indicators or strategy automation.
🔍 What This Indicator Does
MSD-Engine identifies major structural reversals, plots price-action based supply & demand zones, and provides multi-timeframe confluence in a single, unified framework.
It is visual and analytical only — no strategy orders, no backtesting, and no repainting.
🚀 Core Features
• Non-Repainting Market Structure
Event-based swing reversal detection
ATR-adaptive displacement filtering
Confirmed pivots only (no future leaks)
• Pure Supply & Demand Zones
Candle-structure based zone detection
Volume-weighted zone strength
Automatic invalidation on breach
Configurable zone limits to maintain chart clarity
• Multi-Timeframe Context (MTF)
Chart timeframe structure
Two independent higher-timeframe supply & demand layers
Higher-timeframe directional bias visualization
HTF zones plotted only on confirmed HTF closes
• Volatility-Adaptive Logic
ATR normalized across timeframes
Dynamic reversal thresholds
Stable behavior from scalping to swing charts
• Trendline Lifecycle Tracking
Automatic major trendline construction
Single-fire break detection
Break validation / failure logic
HTF-aligned vs counter-trend classification
🧠 Designed For
• Discretionary price-action traders
• Supply & demand traders
• Market structure & smart-money style analysis
• Multi-timeframe confluence trading
• Futures, indices, forex, crypto, and equities
⚠️ Important Notes
This is NOT a strategy or auto-trading system
No buy/sell signals or performance metrics
No repainting (uses barmerge.lookahead_off)
Educational & analytical use only
📜 Disclaimer
This script is provided for educational and analytical purposes only.
It does not constitute financial advice. Trading financial markets involves risk.
Jurik MA Trend Breakouts [BigBeluga]🔵 OVERVIEW
Jurik MA Trend Breakouts is a precision trend-breakout detector built on a custom Jurik-smoothed moving average.
It identifies trend direction with ultra-low lag and maps breakout levels using pivot-based swing highs/lows.
The indicator plots dynamic breakout lines and confirms trend continuation or reversal when price breaks them — providing clean, minimalistic yet extremely accurate trend signals.
🔵 CONCEPTS
Jurik Moving Average (JMA) — A highly smooth and low-lag moving average that reacts quickly to trend shifts without noise. This becomes the core trend baseline.
Trend Bias —
• JMA rising → bullish trend
• JMA falling → bearish trend
The JMA color updates instantly based on slope.
Swing Pivots — Recent pivot highs/lows are detected to define structural break levels while filtering out weak noise.
Trend Breakout Levels —
The indicator draws horizontal levels at the last valid pivot in the direction of the trend.
These levels act as “confirmation gates” for breakout entries.
ATR Validity Filter — Ensures only meaningful pivots within a threshold are used to prevent fake breakouts.
🔵 FEATURES
Ultra-Smooth Jurik Trend Line — A visually clean trend baseline changing color based on direction.
Automatic Swing High Breakout Setup (Bullish) —
• During an uptrend, the indicator tracks the most recent pivot high.
• A horizontal breakout line is extended across the chart.
• A ✔ marker appears at both pivot points when the breakout structure becomes valid.
Automatic Swing Low Breakout Setup (Bearish) —
• During a downtrend, pivot lows are tracked.
• A horizontal breakout line marks the breakdown level.
• ✔ markers confirm valid structure before the breakout triggers.
Breakout Detection —
• Price closing above the bullish breakout line → “↑” signal printed on the chart.
• Price closing below the bearish breakout line → “↓” signal printed on the chart.
Automatic Reset on Trend Change —
When the JMA trend flips, all breakout structures are cleared and the model starts tracking new pivot levels.
Trend-Colored Visualization —
Glow + main JMA line give instant clarity of market direction.
🔵 HOW IT WORKS
1. JurikMA defines the main trend — Slope determines bullish or bearish state.
2. The indicator continuously searches for pivots in the direction of the trend.
3. When a valid pivot forms and passes ATR proximity filter, a structural breakout level is drawn.
4. As long as price stays below that level (bullish case), the trend setup remains active.
5. When price finally breaks the level , the indicator prints a directional arrow (↑ or ↓).
6. Trend flip instantly resets all levels and begins tracking pivots on the opposite side.
🔵 HOW TO USE
Breakout Trading — Enter long on “↑” and short on “↓” signals when price breaks key pivot structure.
Trend Confirmation — Use the JurikMA color to stay aligned with the main trend direction.
Reversals — Trend flips often mark major turning points.
Structure Mapping — Use the horizontal breakout lines to understand how close price is to confirming a new trend leg.
🔵 CONCLUSION
Jurik MA Trend Breakouts combines the speed of a Jurik MA with structural breakout logic to deliver clean, reliable entry signals.
Its minimal design, pivot-based confirmation, and trend-aligned logic make it suitable for scalping, swing trading, and intraday trend continuation setups.
If you want fast yet filtered breakout recognition with almost zero noise, this tool gives you everything you need.
Iron Fly 0DTE StrategyOverview
This indicator identifies optimal entry and exit points for 0DTE (zero days to expiration) Iron Fly options strategies on SPX. It uses a combination of DMI (Directional Movement Index) regime classification and ATR (Average True Range) volatility measurement to determine when market conditions favor non-directional premium selling.
An Iron Fly is a neutral options strategy that profits when price stays near a central strike. This indicator automates the decision of WHEN to enter and at WHAT strikes, based on quantifiable market conditions rather than discretionary judgment.
How It Works
Market Regime Classification
The core logic uses DMI and ADX to classify market conditions into four regimes:
SAFE - ADX below 25 AND DI Spread below 20: Low directional momentum, ideal for Iron Flies
CAUTION - ADX below 35 AND DI Spread below 30: Moderate conditions, wider wings recommended
WARNING - ADX below 45 OR DI Spread below 45: Elevated risk, no new entries
NO ENTRY - ADX above 45 AND DI Spread above 45: Strong trend, avoid premium selling
The DI Spread is calculated as the absolute difference between DI+ and DI-. A low spread indicates balanced buying and selling pressure, which favors range-bound price action.
Dynamic Wing Width Calculation
Wing width (the distance between the short strikes and protective long strikes) is calculated dynamically using:
Wing Width = ATR(14) × Multiplier × Late Session Factor
The multiplier varies by Entry Aggressiveness setting (5x to 7x ATR). Wings are widened by 20% in CAUTION regime for additional protection. Late in the session (after 50% elapsed), wings narrow by up to 20% as less time remains for adverse moves.
Wing width is bounded between 15 and 50 points and rounded to the nearest 5-point strike.
Entry Logic
New positions open when:
Market regime is SAFE or CAUTION
Current open positions are below the maximum limit
Daily trade count is below the daily limit
Price has moved sufficiently from the last entry (trigger distance)
No existing position at the calculated strike
Exit Logic
Positions close when price exceeds a dynamic exit threshold:
Exit Threshold = Wing Width × (Base Exit Percent + Time Decay Bonus)
The Base Exit Percent varies by Exit Aggressiveness (50% to 80%). The Time Decay Bonus increases throughout the session (0% to 25%), allowing wider tolerance as theta decay works in your favor.
What Makes This Original
This indicator differs from simple moving average or RSI-based approaches by:
Using DMI spread (not just ADX) to measure directional balance, which better identifies consolidation
Dynamically sizing wings based on current ATR rather than fixed widths
Adjusting exit tolerance based on session progress to account for theta decay
Implementing regime-based position management that automatically steps aside during trending conditions
Providing complete strike calculations for the 4-leg Iron Fly structure
Settings Guide
Strategy Settings
Entry Aggressiveness - Controls how often new trades open. LOW: fewer trades, wider wings, more selective. MID: balanced. HIGH: more trades, tighter wings.
Exit Aggressiveness - Controls how long positions are held. LOW: exits early at 50% of wing. MID: exits at 65% plus time bonus. HIGH: holds longer, exits at 80%.
Max Concurrent Flies - Maximum simultaneous open positions (1-5). Start with 1-2.
Max Trades Per Day - Daily limit to prevent overtrading (3-30).
Session Settings
Session Start/End - Trading hours in Eastern Time. Default 10:00-16:00.
How to Use
Add indicator to SPX chart (1-5 minute timeframe recommended)
Create alert with condition "Any alert() function call"
When OPEN alert fires, execute the 4-leg Iron Fly in your broker at the specified strikes
When CLOSE alert fires, close the position
Always verify the premium collected justifies the risk before entering
Alert Messages
OPEN alerts provide: Strike price, wing width, and all four leg strikes (short call, short put, long call, long put).
CLOSE alerts provide: Strike price and exit reason (price exceeded threshold or session ended).
Status Panel
The on-chart panel displays:
Positions - Current open count vs maximum
Market - Current regime classification
Wings - Current calculated wing width
Exit @ - Current exit threshold distance
Trades - Daily trade count vs limit
Limitations
Designed specifically for SPX 0DTE options; may not suit other underlyings
Does not account for bid-ask spreads or execution slippage
Market regime classification may lag during rapid regime changes
Past performance of signals does not guarantee future results
Requires manual execution in your options broker
Best Conditions
This strategy performs best during:
Range-bound, choppy market conditions
Normal volatility days (avoid major news events)
Regular trading hours (10 AM - 4 PM ET)
Avoid using during:
Strong trending days
FOMC announcements, CPI releases, earnings
Pre-market or after-hours
Disclaimer
This indicator is for educational and informational purposes only. It does not constitute financial advice.
Options trading involves substantial risk of loss
Iron Flies can result in losses up to the wing width minus premium collected
Past indicator signals do not guarantee future performance
Always understand your maximum risk before entering any trade
Never risk more than you can afford to lose
Conduct your own research and consider consulting a financial advisor
Money managementnever forget your money management ! never.....................................................................................
Multi-Timeframe EMA LevelsThis indicator will plot 2 different EMA's from 4 different timeframes on your chart. It displays as horizontal dotted lines so does not clutter your chart with loads of MA's. The lines are labeled with timeframe, EMA length and the level value. Levels update in real time.
If you are trading key levels or ma's this plots everything for you on one single chart.
MIZAN: Fake Out / Inducement HunterDescription
STOP GETTING TRAPPED BY THE MARKET!
Are you tired of getting stopped out right before the market moves in your direction? This is called a Fake Out or Liquidity Sweep. The "MIZAN Fake Out Hunter" is designed to detect these manipulation patterns automatically using Smart Money Concepts (SMC).
💎 How It Works:
Identifies Key Levels: The script automatically detects major Swing Highs and Swing Lows (Key Fractals) where liquidity (Stop Loss orders) is resting.
Detects Inducement: It monitors price action approaching these levels. When price creates "Equal Highs" or "Equal Lows" near a key level without breaking it, it identifies this as Inducement (a trap for retail traders).
Signals the Sweep: The signal fires ONLY when price aggressively breaks the level (sweeping the liquidity) and immediately rejects (closes back inside the range).
🚀 Features:
Bullish Fake Out (Green Signal): Detects when sellers are trapped at support (Stop Hunt Low).
Bearish Fake Out (Red Signal): Detects when buyers are trapped at resistance (Stop Hunt High).
Alerts Included: Never miss a manipulation setup again.
🧠 How to Trade: Use this indicator to confirm entries at Major Support/Resistance or Supply/Demand zones. Wait for the "FAKE OUT" signal to confirm that the Smart Money has finished collecting liquidity before entering the trade.
Net Accumulation/Distribution ScreenerNet Accumulation or distribution days within the last 20 days. If volume is high and price is higher than 2%, is an accumulation day. If volume is high and price is below -2% is a distribution day
12H Fib MidpointsPrints the .5 fib retrace for final trading levels on the 1 minute chart.
Background process is exactly how its done in the video EverEvolving365 shared
Price Levels Wall//@version=6
indicator("Price Levels From File", overlay = true)
// === Public parameters ===
string fileContent = input.text_area("Contenu du fichier", "Collez le contenu de Niveaux.txt ici")
color minColor = input.color(color.new(color.green, 0), "Couleur Min", group = "Couleurs")
color maxColor = input.color(color.new(color.red, 0), "Couleur Max", group = "Couleurs")
color acheteursColor = input.color(color.new(color.lime, 0), "Couleur Acheteurs", group = "Couleurs")
color vendeursColor = input.color(color.new(color.orange, 0), "Couleur Vendeurs", group = "Couleurs")
color wallUpperColor = input.color(color.new(color.fuchsia, 0), "Couleur Wall Upper", group = "Couleurs")
color wallMidColor = input.color(color.new(color.gray, 0), "Couleur Wall Mid", group = "Couleurs")
color controlMidColor = input.color(color.new(color.green, 0), "Couleur Control Mid", group = "Couleurs")
color wallLowerColor = input.color(color.new(color.aqua, 0), "Couleur Wall Lower", group = "Couleurs")
color highlightColor = input.color(color.new(#FFFF00, 88), "Couleur Highlight", group = "Couleurs")
int lineWidth = input.int(2, "Épaisseur ligne", group = "Apparence")
bool enableMinMinEventHighlight = input.bool(true, "Highlight Min–Min Event", group = "Options")
bool enableMaxMaxEventHighlight = input.bool(true, "Highlight Max–Max Event", group = "Options")
// === Private fields ===
var array prices = array.new()
var array labels = array.new()
var array colors = array.new()
var float minOneDayLevel = na
var float maxOneDayLevel = na
var float minEventLevel = na
var float maxEventLevel = na
var bool initialized = false
// === Helper functions ===
tryParse(string s) =>
string s_replaced = str.replace_all(s, ",", ".")
float val = str.tonumber(s_replaced)
na(val) ? na : val
trim(string s) =>
string res = s
while str.length(res) > 0 and (str.substring(res, 0, 1) == " " or str.substring(res, 0, 1) == "\t")
res := str.substring(res, 1)
while str.length(res) > 0 and (str.substring(res, str.length(res) - 1) == " " or str.substring(res, str.length(res) - 1) == "\t")
res := str.substring(res, 0, str.length(res) - 1)
res
extractValue(string line) =>
int colonIdx = str.pos(line, ":")
if colonIdx == -1
na
else
string valueStr = str.substring(line, colonIdx + 1)
valueStr := trim(valueStr)
tryParse(valueStr)
// === Parsing ===
if not initialized and barstate.islast
initialized := true
array rawLines = str.split(fileContent, " ")
for i = 0 to array.size(rawLines) - 1
string raw = array.get(rawLines, i)
string line = trim(raw)
if line == ""
continue
string lower = str.lower(line)
// Extract levels based on keywords
if str.contains(lower, "max event")
maxEventLevel := extractValue(line)
else if str.contains(lower, "max 1d")
maxOneDayLevel := extractValue(line)
else if str.contains(lower, "wall upper")
float val = extractValue(line)
if not na(val)
array.push(prices, val)
array.push(labels, "Wall Upper")
array.push(colors, wallUpperColor)
else if str.contains(lower, "buyers ctrl")
float val = extractValue(line)
if not na(val)
array.push(prices, val)
array.push(labels, "Buyers Ctrl")
array.push(colors, acheteursColor)
else if str.contains(lower, "wall mid")
float val = extractValue(line)
if not na(val)
array.push(prices, val)
array.push(labels, "Wall Mid")
array.push(colors, wallMidColor)
else if str.contains(lower, "control mid")
float val = extractValue(line)
if not na(val)
array.push(prices, val)
array.push(labels, "Control Mid")
array.push(colors, controlMidColor)
else if str.contains(lower, "sellers ctrl")
float val = extractValue(line)
if not na(val)
array.push(prices, val)
array.push(labels, "Sellers Ctrl")
array.push(colors, vendeursColor)
else if str.contains(lower, "wall lower")
float val = extractValue(line)
if not na(val)
array.push(prices, val)
array.push(labels, "Wall Lower")
array.push(colors, wallLowerColor)
else if str.contains(lower, "min 1d")
minOneDayLevel := extractValue(line)
else if str.contains(lower, "min event")
minEventLevel := extractValue(line)
// Add special levels
if not na(maxOneDayLevel)
array.push(prices, maxOneDayLevel)
array.push(labels, "Max 1D")
array.push(colors, maxColor)
if not na(maxEventLevel)
array.push(prices, maxEventLevel)
array.push(labels, "Max Event")
array.push(colors, maxColor)
if not na(minOneDayLevel)
array.push(prices, minOneDayLevel)
array.push(labels, "Min 1D")
array.push(colors, minColor)
if not na(minEventLevel)
array.push(prices, minEventLevel)
array.push(labels, "Min Event")
array.push(colors, minColor)
// === Rendering ===
var box minBand = na
var box maxBand = na
if barstate.islast and initialized
if enableMinMinEventHighlight and not na(minOneDayLevel) and not na(minEventLevel) and na(minBand)
float top = math.max(minOneDayLevel, minEventLevel)
float bottom = math.min(minOneDayLevel, minEventLevel)
minBand := box.new(left = bar_index, top = top, right = bar_index + 1, bottom = bottom, xloc = xloc.bar_index, extend = extend.both, bgcolor = highlightColor, border_width = 0)
if enableMaxMaxEventHighlight and not na(maxOneDayLevel) and not na(maxEventLevel) and na(maxBand)
float top = math.max(maxOneDayLevel, maxEventLevel)
float bottom = math.min(maxOneDayLevel, maxEventLevel)
maxBand := box.new(left = bar_index, top = top, right = bar_index + 1, bottom = bottom, xloc = xloc.bar_index, extend = extend.both, bgcolor = highlightColor, border_width = 0)
var array hlines = array.new()
var array rightLabels = array.new()
if barstate.islast and initialized and array.size(hlines) == 0
for i = 0 to array.size(prices) - 1
float p = array.get(prices, i)
string lbl = array.get(labels, i)
color col = array.get(colors, i)
line hl = line.new(bar_index, p, bar_index + 1, p, xloc = xloc.bar_index, extend = extend.both, color = col, width = lineWidth)
array.push(hlines, hl)
string labelText = lbl + " " + str.tostring(p)
label rightLbl = label.new(bar_index + 1, p, labelText, xloc = xloc.bar_index, yloc = yloc.price, style = label.style_label_right, color = na, textcolor = col, size = size.small)
array.push(rightLabels, rightLbl)
if barstate.islast
for i = 0 to array.size(rightLabels) - 1
label.set_x(array.get(rightLabels, i), bar_index + 1)
Ker 2021 EMA/SMA這個腳本主要是EMA/SMA的基礎
加上可調動範圍
數字可以調動
但是因為我不是coding人員
所以有些欄位編排不正確
但是使用上沒有什麼問題
如果你有coding的能力
可以聯絡我 幫我補正 謝謝
This script is mainly based on EMA/SMA, with adjustable ranges and parameters.
The values can be modified freely.
Since I’m not a programmer, some of the field formatting may not be perfectly structured.
However, it works fine in actual use.
If you have coding experience and would like to help improve or clean up the code, feel free to contact me. Thank you.
Custom 4 EMA [TickDaddy]Custom 4 EMA
Hey everyone! I put together this EMA indicator because I wanted more flexibility than what's built into TradingView. Figured I'd share it in case anyone else finds it useful.
What it does:
Customizable EMA Periods
Change all 4 EMAs to whatever periods you want (I default them to 20/50/100/200 but you do you)
Not stuck with preset values - make it work for your strategy
Toggle EMAs On/Off
Each EMA has its own checkbox
Super handy when you want to hide one without losing your settings
Multi-Timeframe EMAs
This is the big one - you can view higher timeframe EMAs on your current chart
Like if you're day trading on a 15-min chart but want to see where the daily EMAs are
Works with any timeframe: Daily, Weekly, 4-Hour, whatever you need
Helps you respect the bigger picture while trading lower timeframes
Smooth Lines on Multi-Timeframe
Got rid of that annoying zigzag effect when using higher timeframes
You can adjust how smooth you want them (or turn it off)
Clean Setup
All the style stuff (colors, thickness, line style) is in the Style tab where it should be
Input settings are organized and not cluttered
Built this with Pine Script v6. Hope it helps with your trading!
DarkFutures Where/How/WhenTesting - for 15min Gold scalps
It identifies 4hr Where, 30m How and 5min When sareas of trade, then gives a signal to buy/sell based on that trend and momentum information using 8/21 EAM and Vwaps.
Sonic R 89 - NY buy LionLee 079 228 1999//@version=5
indicator("Sonic R 89 - NY SL Custom Fixed", overlay=true, max_lines_count=500)
// --- 0. TÙY CHỈNH THÔNG SỐ ---
group_session = "Cài đặt Phiên Giao Dịch (Giờ New York)"
use_session = input.bool(true, "Chỉ giao dịch theo khung giờ", group=group_session)
session_time = input.session("0800-1200", "Khung giờ NY 1", group=group_session)
session_time2 = input.session("1300-1700", "Khung giờ NY 2", group=group_session)
max_trades_per_session = input.int(1, "Số lệnh tối đa/mỗi khung giờ", minval=1, group=group_session)
group_risk = "Quản lý Rủi ro (Dashboard)"
risk_usd = input.float(100.0, "Số tiền rủi ro mỗi lệnh ($)", minval=1.0, group=group_risk)
group_sl_custom = "Cấu hình Stop Loss (SL)"
sl_mode = input.string("Dragon", "Chế độ SL", options= , group=group_sl_custom)
lookback_x = input.int(5, "Số nến (X) cho Swing SL", minval=1, group=group_sl_custom)
group_htf = "Lọc Đa khung thời gian (MTF)"
htf_res = input.timeframe("30", "Chọn khung HTF", group=group_htf)
group_sonic = "Cấu hình Sonic R"
vol_mult = input.float(1.5, "Đột biến Volume", minval=1.0)
max_waves = input.int(4, "Ưu tiên n nhịp đầu", minval=1)
trade_cd = input.int(5, "Khoảng cách lệnh (nến)", minval=1)
group_tp = "Quản lý SL/TP & Dòng kẻ"
rr_tp1 = input.float(1.0, "TP1 (RR)", step=0.1)
rr_tp2 = input.float(2.0, "TP2 (RR)", step=0.1)
rr_tp3 = input.float(3.0, "TP3 (RR)", step=0.1)
rr_tp4 = input.float(4.0, "TP4 (RR)", step=0.1)
line_len = input.int(15, "Chiều dài dòng kẻ", minval=1)
// --- 1. KIỂM TRA PHIÊN & HTF ---
is_in_sess1 = not na(time(timeframe.period, session_time, "America/New_York"))
is_in_sess2 = not na(time(timeframe.period, session_time2, "America/New_York"))
is_in_session = use_session ? (is_in_sess1 or is_in_sess2) : true
var int trades_count = 0
is_new_session = is_in_session and not is_in_session
if is_new_session
trades_count := 0
htf_open = request.security(syminfo.tickerid, htf_res, open, lookahead=barmerge.lookahead_on)
htf_close = request.security(syminfo.tickerid, htf_res, close, lookahead=barmerge.lookahead_on)
is_htf_trend = htf_close >= htf_open ? 1 : -1
// --- 2. TÍNH TOÁN CHỈ BÁO ---
ema89 = ta.ema(close, 89)
ema34H = ta.ema(high, 34)
ema34L = ta.ema(low, 34)
atr = ta.atr(14)
avgVol = ta.sma(volume, 20)
slope89 = (ema89 - ema89 ) / atr
hasSlope = math.abs(slope89) > 0.12
isSqueezed = math.abs(ta.ema(close, 34) - ema89) < (atr * 0.5)
var int waveCount = 0
if not hasSlope
waveCount := 0
newWave = hasSlope and ((low <= ema34H and close > ema34H) or (high >= ema34L and close < ema34L))
if newWave and not newWave
waveCount := waveCount + 1
// --- 3. LOGIC VÀO LỆNH ---
isMarubozu = math.abs(close - open) / (high - low) > 0.8
highVol = volume > avgVol * vol_mult
buyCondition = is_in_session and (trades_count < max_trades_per_session) and waveCount <= max_waves and is_htf_trend == 1 and
(isMarubozu or highVol) and close > ema34H and low >= ema89 and
(slope89 > 0.1 or isSqueezed ) and close > open
sellCondition = is_in_session and (trades_count < max_trades_per_session) and waveCount <= max_waves and is_htf_trend == -1 and
(isMarubozu or highVol) and close < ema34L and high <= ema89 and
(slope89 < -0.1 or isSqueezed ) and close < open
// --- 4. QUẢN LÝ LỆNH ---
var float last_entry = na
var float last_sl = na
var float last_tp1 = na
var float last_tp2 = na
var float last_tp3 = na
var float last_tp4 = na
var string last_type = "NONE"
var int lastBar = 0
trigger_buy = buyCondition and (bar_index - lastBar > trade_cd)
trigger_sell = sellCondition and (bar_index - lastBar > trade_cd)
// --- 5. TÍNH TOÁN SL & LOT SIZE ---
float contract_size = 1.0
if str.contains(syminfo.ticker, "XAU") or str.contains(syminfo.ticker, "GOLD")
contract_size := 100
// Logic tính SL linh hoạt
float swing_low = ta.lowest(low, lookback_x)
float swing_high = ta.highest(high, lookback_x)
float temp_sl_calc = na
if trigger_buy
temp_sl_calc := (sl_mode == "Dragon") ? ema34L : swing_low
if trigger_sell
temp_sl_calc := (sl_mode == "Dragon") ? ema34H : swing_high
float sl_dist_calc = math.abs(close - temp_sl_calc)
float calc_lots = (sl_dist_calc > 0) ? (risk_usd / (sl_dist_calc * contract_size)) : 0
if (trigger_buy or trigger_sell)
trades_count := trades_count + 1
lastBar := bar_index
last_type := trigger_buy ? "BUY" : "SELL"
last_entry := close
last_sl := temp_sl_calc
float riskAmt = math.abs(last_entry - last_sl)
last_tp1 := trigger_buy ? last_entry + (riskAmt * rr_tp1) : last_entry - (riskAmt * rr_tp1)
last_tp2 := trigger_buy ? last_entry + (riskAmt * rr_tp2) : last_entry - (riskAmt * rr_tp2)
last_tp3 := trigger_buy ? last_entry + (riskAmt * rr_tp3) : last_entry - (riskAmt * rr_tp3)
last_tp4 := trigger_buy ? last_entry + (riskAmt * rr_tp4) : last_entry - (riskAmt * rr_tp4)
// Vẽ dòng kẻ
line.new(bar_index, last_entry, bar_index + line_len, last_entry, color=color.new(color.gray, 50), width=2)
line.new(bar_index, last_sl, bar_index + line_len, last_sl, color=color.red, width=2, style=line.style_dashed)
line.new(bar_index, last_tp1, bar_index + line_len, last_tp1, color=color.green, width=1)
line.new(bar_index, last_tp2, bar_index + line_len, last_tp2, color=color.lime, width=1)
line.new(bar_index, last_tp3, bar_index + line_len, last_tp3, color=color.aqua, width=1)
line.new(bar_index, last_tp4, bar_index + line_len, last_tp4, color=color.blue, width=2)
// KÍCH HOẠT ALERT()
string alert_msg = (trigger_buy ? "BUY " : "SELL ") + syminfo.ticker + " at " + str.tostring(close) + " | SL Mode: " + sl_mode + " | Lot: " + str.tostring(calc_lots, "#.##") + " | SL: " + str.tostring(last_sl, format.mintick)
alert(alert_msg, alert.freq_once_per_bar_close)
// --- 6. CẢNH BÁO CỐ ĐỊNH ---
alertcondition(trigger_buy, title="Sonic R BUY Alert", message="Sonic R BUY Signal Detected")
alertcondition(trigger_sell, title="Sonic R SELL Alert", message="Sonic R SELL Signal Detected")
// --- 7. DASHBOARD & PLOT ---
var table sonic_table = table.new(position.top_right, 2, 10, bgcolor=color.new(color.black, 70), border_width=1, border_color=color.gray)
if barstate.islast
table.cell(sonic_table, 0, 0, "NY SESSION", text_color=color.white), table.cell(sonic_table, 1, 0, last_type, text_color=(last_type == "BUY" ? color.lime : color.red))
table.cell(sonic_table, 0, 1, "SL Mode:", text_color=color.white), table.cell(sonic_table, 1, 1, sl_mode, text_color=color.orange)
table.cell(sonic_table, 0, 2, "Trades this Sess:", text_color=color.white), table.cell(sonic_table, 1, 2, str.tostring(trades_count) + "/" + str.tostring(max_trades_per_session), text_color=color.yellow)
table.cell(sonic_table, 0, 3, "LOT SIZE:", text_color=color.orange), table.cell(sonic_table, 1, 3, str.tostring(calc_lots, "#.##"), text_color=color.orange)
table.cell(sonic_table, 0, 4, "Entry:", text_color=color.white), table.cell(sonic_table, 1, 4, str.tostring(last_entry, format.mintick), text_color=color.yellow)
table.cell(sonic_table, 0, 5, "SL:", text_color=color.white), table.cell(sonic_table, 1, 5, str.tostring(last_sl, format.mintick), text_color=color.red)
table.cell(sonic_table, 0, 6, "TP1:", text_color=color.gray), table.cell(sonic_table, 1, 6, str.tostring(last_tp1, format.mintick), text_color=color.green)
table.cell(sonic_table, 0, 7, "TP2:", text_color=color.gray), table.cell(sonic_table, 1, 7, str.tostring(last_tp2, format.mintick), text_color=color.lime)
table.cell(sonic_table, 0, 8, "TP3:", text_color=color.gray), table.cell(sonic_table, 1, 8, str.tostring(last_tp3, format.mintick), text_color=color.aqua)
table.cell(sonic_table, 0, 9, "TP4:", text_color=color.gray), table.cell(sonic_table, 1, 9, str.tostring(last_tp4, format.mintick), text_color=color.blue)
plot(ema89, color=slope89 > 0.1 ? color.lime : slope89 < -0.1 ? color.red : color.gray, linewidth=2)
p_high = plot(ema34H, color=color.new(color.blue, 80))
p_low = plot(ema34L, color=color.new(color.blue, 80))
fill(p_high, p_low, color=color.new(color.blue, 96))
plotshape(trigger_buy, "BUY", shape.triangleup, location.belowbar, color=color.green, size=size.small)
plotshape(trigger_sell, "SELL", shape.triangledown, location.abovebar, color=color.red, size=size.small)
bgcolor(isSqueezed ? color.new(color.yellow, 92) : na)
bgcolor(not is_in_session ? color.new(color.gray, 96) : na)
Global M2 with correlation table, by Colin (No linear - Trader Qno more linear line
Now works perfectly CRYPTOCAP:BTC / $ eth chart
make sure that the time frame is set as daily
SWEEP HTF CANDLE - BY LIONLEE - 0792281999// This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// © CandelaCharts
//@version=6
indicator("CandelaCharts - HTF Sweeps", shorttitle = "CandelaCharts - HTF Sweeps", overlay = true, max_lines_count = 500, max_labels_count = 500, max_boxes_count = 500, max_bars_back = 500, max_polylines_count = 100)
// # ========================================================================= #
// # | Colors |
// # ========================================================================= #
//#region
// # Core -------------------------------------------------------------------- #
colors_white = color.white
colors_black = color.black
colors_purple = color.purple
colors_red = color.red
colors_gray = color.gray
colors_blue = color.blue
colors_orange = color.orange
colors_green = color.green
color_transparent = #ffffff00
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | Inputs |
// # ========================================================================= #
//#region
// # General ----------------------------------------------------------------- #
general_font = input.string("Monospace", "Text ", options = , inline = "1.0", group = "General")
general_text = input.string("Tiny", "", options = , inline = "1.0", group = "General")
general_brand_show = input.bool(false, "Hide Brand", group = "General")
htf_sweeps_tf_1_show = input.bool(true, "HTF I ", inline = "1.0", group = "Timeframes")
htf_sweeps_tf_1_tf = input.timeframe("15", "", inline = "1.0", group = "Timeframes")
htf_sweeps_tf_1_number = input.int(10, "", inline = "1.0", group = "Timeframes", minval = 1, maxval = 60)
htf_sweeps_tf_1_map = input.bool(false, "M", inline = "1.0", group = "Timeframes", tooltip = "Map this HTF to LTF")
htf_sweeps_tf_2_show = input.bool(true, "HTF II ", inline = "2.0", group = "Timeframes")
htf_sweeps_tf_2_tf = input.timeframe("60", "", inline = "2.0", group = "Timeframes")
htf_sweeps_tf_2_number = input.int(8, "", inline = "2.0", group = "Timeframes", minval = 1, maxval = 60)
htf_sweeps_tf_2_map = input.bool(true, "M", inline = "2.0", group = "Timeframes")
htf_sweeps_tf_3_show = input.bool(true, "HTF III ", inline = "3.0", group = "Timeframes")
htf_sweeps_tf_3_tf = input.timeframe("240", "", inline = "3.0", group = "Timeframes")
htf_sweeps_tf_3_number = input.int(6, "", inline = "3.0", group = "Timeframes", minval = 1, maxval = 60)
htf_sweeps_tf_3_map = input.bool(false, "M", inline = "3.0", group = "Timeframes")
htf_sweeps_tf_4_show = input.bool(true, "HTF IV ", inline = "4.0", group = "Timeframes")
htf_sweeps_tf_4_tf = input.timeframe("1D", "", inline = "4.0", group = "Timeframes")
htf_sweeps_tf_4_number = input.int(4, "", inline = "4.0", group = "Timeframes", minval = 1, maxval = 60)
htf_sweeps_tf_4_map = input.bool(false, "M", inline = "4.0", group = "Timeframes")
htf_sweeps_tf_5_show = input.bool(true, "HTF V ", inline = "5.0", group = "Timeframes")
htf_sweeps_tf_5_tf = input.timeframe("1W", "", inline = "5.0", group = "Timeframes")
htf_sweeps_tf_5_number = input.int(2, "", inline = "5.0", group = "Timeframes", minval = 1, maxval = 60)
htf_sweeps_tf_5_map = input.bool(false, "M", inline = "5.0", group = "Timeframes")
htf_sweeps_tf_6_show = input.bool(false, "HTF VI ", inline = "6.0", group = "Timeframes")
htf_sweeps_tf_6_tf = input.timeframe("1M", "", inline = "6.0", group = "Timeframes")
htf_sweeps_tf_6_number = input.int(1, "", inline = "6.0", group = "Timeframes", minval = 1, maxval = 60)
htf_sweeps_tf_6_map = input.bool(false, "M", inline = "6.0", group = "Timeframes")
htf_sweeps_bull_color = input.color(colors_green, "Coloring ", inline = "1.0", group = "HTF")
htf_sweeps_bear_color = input.color(colors_black, "", inline = "1.0", group = "HTF")
htf_sweeps_wick_border_color = input.color(colors_black, "", inline = "1.0", group = "HTF")
htf_sweeps_offset = input.int(10, "Offset ", minval = 1, inline = "2.0", group = "HTF", tooltip = "The distance from the current chart candles.")
htf_sweeps_space = input.int(1, "Space ", minval = 1, inline = "3.0", maxval = 4, group = "HTF", tooltip = "Space between candles")
htf_sweeps_margin = input.int(10, "Margin ", minval = 1, inline = "4.0", group = "HTF", tooltip = "The distance between HTF group candles.")
htf_sweeps_candle_width = input.string("Small", "Size ", inline = "5.0", group = "HTF", options = , tooltip = "Candle size")
htf_sweeps_label_show = input.bool(true, "Labels ", inline = "6.0", group = "HTF")
htf_sweeps_label_size = input.string("Large", "", inline = "6.0", group = "HTF", options = )
htf_sweeps_label_position = input.string("Top", "", inline = "6.0", group = "HTF", options = , tooltip = " - Size of the label - Position of the label - Text color of the label")
htf_sweeps_label_color = input.color(colors_black, "", inline = "6.0", group = "HTF")
// htf_sweeps_bias_show = input.bool(true, "Bias ", inline = "6.0", group = "HTF")
// htf_sweeps_bias_bull_color = input.color(colors_green, "", inline = "6.0", group = "HTF")
// htf_sweeps_bias_bear_color = input.color(colors_red, "", inline = "6.0", group = "HTF")
// htf_sweeps_time_show = input.bool(true, "Time ", inline = "7.0", group = "HTF")
// htf_sweeps_time_color = input.color(colors_gray, "", inline = "7.0", group = "HTF")
htf_sweeps_ltf_trace_h_l_show = input.bool(true, "H/L Line ", inline = "1.0", group="LTF")
htf_sweeps_ltf_trace_h_l_style = input.string('····', '', options = , inline = "1.0", group="LTF")
htf_sweeps_ltf_trace_h_l_width = input.int(1, '', inline = "1.0", minval = 0, maxval = 4, group="LTF")
htf_sweeps_ltf_trace_h_l_color = input.color(color.new(colors_gray, 50), "", inline = "1.0", group="LTF")
htf_sweeps_ltf_trace_o_c_line_show = input.bool(true, "O/C Line ", inline = "2.0", group = "LTF")
htf_sweeps_ltf_trace_o_c_line_style = input.string('⎯⎯⎯', "", options = , inline = "2.0", group = "LTF")
htf_sweeps_ltf_trace_o_c_line_width = input.int(1, '', inline = "2.0", minval = 0, maxval = 4, group = "LTF")
htf_sweeps_ltf_trace_o_c_line_color = input.color(color.new(colors_gray, 50), "", inline = "2.0", group = "LTF")
htf_sweeps_sweep_show = input.bool(true, "Sweep ", inline = "1.0", group = "Sweep")
htf_sweeps_sweep_ltf_show = input.bool(true, "LTF ", inline = "1.0", group = "Sweep")
htf_sweeps_sweep_htf_show = input.bool(true, "HTF", inline = "1.0", group = "Sweep", tooltip = "Show sweeps. - Show sweeps on LTF. - Show sweeps on HTF.")
htf_sweeps_sweep_line_style = input.string('⎯⎯⎯', " ", options = , inline = "1.1", group = "Sweep")
htf_sweeps_sweep_line_width = input.int(1, '', inline = "1.1", group = "Sweep")
htf_sweeps_sweep_line_color = input.color(colors_black, "", inline = "1.1", group = "Sweep")
htf_sweeps_i_sweep_show = input.bool(false, "I-sweep ", inline = "2.0", group = "Sweep")
htf_sweeps_i_sweep_ltf_show = input.bool(true, "LTF ", inline = "2.0", group = "Sweep")
htf_sweeps_i_sweep_htf_show = input.bool(true, "HTF", inline = "2.0", group = "Sweep", tooltip = "Show invalidated sweeps. - Show invalidated sweeps on LTF. - Show invalidated sweeps on HTF.")
htf_sweeps_i_sweep_line_style = input.string('----', " ", options = , inline = "2.1", group = "Sweep")
htf_sweeps_i_sweep_line_width = input.int(1, '', inline = "2.1", group = "Sweep")
htf_sweeps_i_sweep_line_color = input.color(colors_gray, "", inline = "2.1", group = "Sweep")
htf_sweeps_real_time_sweep_show = input.bool(false, "Real-time", inline = "3.0", group = "Sweep", tooltip = "Control visibility of Real-time Sweeps on LTF and HTF")
// htf_sweeps_dashboard_info_show = input.bool(true, "Panel ", inline = "1.0", group = "Dashboard")
// htf_sweeps_dashboard_info_position = input.string("Bottom Center", "", options = , inline = "1.0", group = "Dashboard", tooltip = "The dashboard will display only the HTF that is mapped to LTF")
htf_sweeps_alerts_sweep_formation = input.bool(false, "Sweep Formation", inline = "1.0", group = "Alerts")
htf_sweeps_alerts_sweep_invalidation = input.bool(false, "Sweep Invalidation", inline = "2.0", group = "Alerts")
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | UDTs |
// # ========================================================================= #
//#region
type UDT_Store
line bin_ln
box bin_box
label bin_lbl
polyline bin_polyline
type UDT_Sweep
string tf
int x1
float y
int x2
bool bull
// sweep is invalidated
bool invalidated = false
// id of htf candle, that invalidated sweep
int invalidated_on
// if sweep is invalidated on candle that forms a sweep, then sweep will be removed
bool removed = false
// mark sweep as formed after last candle that forms a sweep is closed and sweep was not invalidated
bool formed = false
type UDT_HTF_Candle
int num
int index
string tf
// real coordinates of HTF candle
float o
float c
float h
float l
int o_idx
int c_idx
int h_idx
int l_idx
int ot
int ct
// position of HTF candle on chart
int candle_left
int candle_rigth
float candle_top
float candle_bottom
int wick_x
int shift
bool is_closed
array htf_sweeps
array ltf_sweeps
bool bull
bool bull_sweep
bool bear_sweep
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | Bin |
// # ========================================================================= #
//#region
var UDT_Store bin = UDT_Store.new(
bin_ln = array.new()
, bin_box = array.new()
, bin_lbl = array.new()
, bin_polyline = array.new()
)
method clean_bin(UDT_Store store) =>
for obj in store.bin_ln
obj.delete()
for obj in store.bin_box
obj.delete()
for obj in store.bin_lbl
obj.delete()
for obj in store.bin_polyline
obj.delete()
store.bin_ln.clear()
store.bin_box.clear()
store.bin_lbl.clear()
store.bin_polyline.clear()
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | Functions |
// # ========================================================================= #
//#region
method text_size(string size) =>
out = switch size
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
"Huge" => size.huge
"Auto" => size.auto
out
method line_style(string style) =>
out = switch style
'⎯⎯⎯' => line.style_solid
'----' => line.style_dashed
'····' => line.style_dotted
method font_style(string font) =>
out = switch font
'Default' => font.family_default
'Monospace' => font.family_monospace
method candle_size(string size) =>
out = switch size
'Tiny' => 2
'Small' => 4
'Medium' => 6
'Large' => 8
'Huge' => 10
out
method tf_label(string tf) =>
tfl = tf
if tfl == ''
tfl := timeframe.period
out = switch tfl
'1' => '1m'
'2' => '2m'
'3' => '3m'
'5' => '5m'
'10' => '10m'
'15' => '15m'
'20' => '20m'
'30' => '30m'
'45' => '45m'
'60' => '1H'
'90' => '90m'
'120' => '2H'
'180' => '3H'
'240' => '4H'
'480' => '8H'
'540' => '9H'
'720' => '12H'
=> tfl
out
const string default_tz = "America/New_York"
var string htf_sweeps_tz = default_tz
get_short_dayofweek(int d) =>
switch d
dayofweek.monday => 'MON'
dayofweek.tuesday => 'TUE'
dayofweek.wednesday => 'WED'
dayofweek.thursday => 'THU'
dayofweek.friday => 'FRI'
dayofweek.saturday => 'SAT'
dayofweek.sunday => 'SUN'
=> ''
get_week_of_month(int t) =>
y = year(t)
m = month(t)
d = dayofmonth(t)
// Timestamp of first day of the same month
firstDay = timestamp(y, m, 1, 0, 0)
// Day of month index starting from 0 → (0–30)
dayIndex = d - 1
// Week index starting from 0 → (0–4)
weekIndex = int(dayIndex / 7)
// Week number starting from 1 → (1–5)
str.tostring(weekIndex + 1)
get_short_month(int t) =>
var string months = array.from(
"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC")
m = month(t)
m >= 1 and m <= array.size(months) ? array.get(months, m - 1) : ""
method candle_time_label(UDT_HTF_Candle candle) =>
string lbl = ""
if timeframe.in_seconds(candle.tf) >= timeframe.in_seconds("12M")
lbl := str.format_time(candle.ot, "yyyy", htf_sweeps_tz)
else if timeframe.in_seconds(candle.tf) >= timeframe.in_seconds("1M")
lbl := get_short_month(candle.ot)
else if timeframe.in_seconds(candle.tf) >= timeframe.in_seconds("1W")
lbl := get_week_of_month(candle.ot)
else if timeframe.in_seconds(candle.tf) >= timeframe.in_seconds("1D")
// Get date components in the selected timezone
y = year(candle.ot, htf_sweeps_tz)
m = month(candle.ot, htf_sweeps_tz)
d = dayofmonth(candle.ot, htf_sweeps_tz)
// Create timestamp at noon for that date in the selected timezone (using noon to avoid timezone edge cases)
date_ts = timestamp(htf_sweeps_tz, y, m, d, 12, 0, 0)
// Add 1 day to account for timezone offset
date_ts := date_ts + 86400000
// Get day of week for that date
lbl := get_short_dayofweek(dayofweek(date_ts, htf_sweeps_tz))
else
lbl := str.format_time(candle.ot, "HH:mm", htf_sweeps_tz)
lbl
// Returns formatted remaining time until current HTF candle close.
// Format: " HH:MM:SS"
get_htf_remaining_time(int from, string tf, string ses, string tz) =>
ct = time_close(tf, ses, na(tz) ? "" : tz)
if na(ct) or na(from)
""
else
// Remaining time in ms (clamped to 0 so it never goes negative)
remaining_ms = math.max(ct - from, 0)
// Total whole seconds remaining
remaining_sec = int(remaining_ms / 1000)
// Unit constants (seconds)
sec_per_min = 60
sec_per_hour = 60 * sec_per_min
sec_per_day = 24 * sec_per_hour
sec_per_month = 30 * sec_per_day
sec_per_year = 365 * sec_per_day
// Break down into Y / M / D / H / M / S (all ints)
years = int(remaining_sec / sec_per_year)
rem_after_years = remaining_sec % sec_per_year
months = int(rem_after_years / sec_per_month)
rem_after_months = rem_after_years % sec_per_month
days = int(rem_after_months / sec_per_day)
rem_after_days = rem_after_months % sec_per_day
hours = int(rem_after_days / sec_per_hour)
rem_after_hours = rem_after_days % sec_per_hour
minutes = int(rem_after_hours / sec_per_min)
seconds = rem_after_hours % sec_per_min
// Only show non-zero units
year_str = years > 0 ? str.format("{0}Y ", str.tostring(years, "#")) : ""
month_str = months > 0 ? str.format("{0}M ", str.tostring(months, "#")) : ""
day_str = days > 0 ? str.format("{0}D ", str.tostring(days, "#")) : ""
time_str = str.format("{0}:{1}:{2}",
str.tostring(hours, "00"),
str.tostring(minutes, "00"),
str.tostring(seconds, "00"))
year_str + month_str + day_str + time_str
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | Variables |
// # ========================================================================= #
//#region
var ltf = timeframe.period
var htf_1_candles = array.new()
var htf_2_candles = array.new()
var htf_3_candles = array.new()
var htf_4_candles = array.new()
var htf_5_candles = array.new()
var htf_6_candles = array.new()
var htf_candle_width = candle_size(htf_sweeps_candle_width)
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | Alert Methods |
// # ========================================================================= #
//#region
method enable_sweep_formed_alert(UDT_Sweep sweep) =>
if not na(sweep) and htf_sweeps_alerts_sweep_formation
if not sweep.invalidated
if sweep.bull
alert(str.format("Bullish HTF Sweep ({0}) formed on {1}. Price level {2, number, currency}", tf_label(sweep.tf), syminfo.ticker, sweep.y))
else
alert(str.format("Bearish HTF Sweep ({0}) formed on {1}. Price level {2, number, currency}", tf_label(sweep.tf), syminfo.ticker, sweep.y))
sweep
method enable_sweep_invalidated_alert(UDT_Sweep sweep) =>
if not na(sweep) and htf_sweeps_alerts_sweep_invalidation
if not sweep.invalidated
if sweep.bull
alert(str.format("Bullish HTF Sweep ({0}) invalidated on {1}. Price level {2, number, currency}", tf_label(sweep.tf), syminfo.ticker, sweep.y))
else
alert(str.format("Bearish HTF Sweep ({0}) invalidated on {1}. Price level {2, number, currency}", tf_label(sweep.tf), syminfo.ticker, sweep.y))
sweep
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | HTF Sweeps |
// # ========================================================================= #
//#region
method session_begins(string tf, string ses, string tz) =>
ta.change(time(tf, ses, na(tz) ? "" : tz))!= 0
method in_session(string tf, string ses, string tz) =>
t = time(tf, ses, na(tz) ? "" : tz)
ct = time_close(tf, ses, na(tz) ? "" : tz)
not na(t) and not na(ct)
method position_ltf_sweeps(array htf_candles) =>
count = htf_candles.size()
if count == 1
candle = htf_candles.get(0)
for in candle.ltf_sweeps
sweep.x2 := candle.c_idx
if count >= 2
candle = htf_candles.get(1)
next_candle = htf_candles.get(0)
for in candle.ltf_sweeps
sweep.x2 := next_candle.c_idx
htf_candles
method position_htf_sweeps(array htf_candles, int buffer) =>
count = htf_candles.size()
if count > 1
c_last = htf_candles.get(0)
for in htf_candles
for in candle.htf_sweeps
sweep.x2 := c_last.candle_rigth + buffer
sweep.x1 := candle.wick_x
htf_candles
method invalidate_sweep(UDT_Sweep sweep, UDT_HTF_Candle c2) =>
c2_bull = c2.bull
// if body of next candle cross sweep
invalidated = not na(sweep.y) and (sweep.bull ? (c2_bull ? sweep.y < c2.c : sweep.y < c2.o) : (c2_bull ? sweep.y > c2.o : sweep.y > c2.c))
invalidated
method invalidate_sweeps(array htf_candles) =>
count = htf_candles.size()
if count > 1
for i = count - 1 to 1
c1 = htf_candles.get(i)
for in c1.ltf_sweeps
if not sweep.removed and na(sweep.invalidated_on)
for k = i - 1 to 0
c2 = htf_candles.get(k)
htf_sweep = c1.htf_sweeps.get(j)
invalidated = sweep.invalidate_sweep(c2)
// invalidation by candle of sweep
if sweep.x2 <= c2.c_idx and sweep.x2 > c2.o_idx
if not c2.is_closed
if not sweep.invalidated and htf_sweeps_real_time_sweep_show
sweep.enable_sweep_invalidated_alert()
sweep.invalidated := invalidated
htf_sweep.invalidated := sweep.invalidated
else
if invalidated and na(sweep.invalidated_on)
sweep.invalidated_on := invalidated ? c2.o_idx : na
htf_sweep.invalidated_on := sweep.invalidated_on
break
else if na(sweep.invalidated_on)
// invalidation by the next candle
if not c2.is_closed
if not sweep.invalidated and htf_sweeps_real_time_sweep_show
sweep.enable_sweep_invalidated_alert()
sweep.invalidated := invalidated
htf_sweep.invalidated := sweep.invalidated
else
if invalidated
if not sweep.invalidated
sweep.enable_sweep_invalidated_alert()
sweep.invalidated := invalidated
sweep.invalidated_on := invalidated ? c2.o_idx : na
htf_sweep.invalidated := sweep.invalidated
htf_sweep.invalidated_on := sweep.invalidated_on
break
// filter removed sweeps
c2 = htf_candles.get(i - 1)
if not sweep.formed and not sweep.removed
if c2.is_closed
htf_sweep = c1.htf_sweeps.get(j)
if sweep.invalidated and not na(sweep.invalidated_on)
// if sweep is invalidated on candle that forms a sweep, then sweep will be removed
if not sweep.formed
sweep.removed := true
htf_sweep.removed := true
else
// mark sweep as formed after last candle that forms a sweep is closed and sweep was not invalidated
if not sweep.formed
sweep.formed := true
htf_sweep.formed := true
htf_candles
detect_sweep(UDT_HTF_Candle c1, UDT_HTF_Candle c2) =>
c1_bull = c1.bull
c2_bull = c2.bull
bull_sweep_in_range = c2_bull ? (c1_bull ? (c2.c < c1.h) : (c2.c < c1.h)) : (c1_bull ? (c2.o < c1.h) : (c2.o < c1.h))
is_bull_sweep = c2.h > c1.h and bull_sweep_in_range
bear_sweep_in_range = c2_bull ? (c1_bull ? (c2.o > c1.l) : (c2.o > c1.l)) : (c1_bull ? (c2.c > c1.l) : (c2.c > c1.l))
is_bear_sweep = c2.l < c1.l and bear_sweep_in_range
if is_bull_sweep
if not c1.bull_sweep
htf_sweep = UDT_Sweep.new(x1=c1.h_idx, x2=c2.c_idx, y=c1.h, bull=true, tf=c1.tf)
ltf_sweep = UDT_Sweep.new(x1=c1.h_idx, x2=c2.c_idx, y=c1.h, bull=true, tf=c1.tf)
c1.htf_sweeps.push(htf_sweep)
c1.ltf_sweeps.push(ltf_sweep)
c1.bull_sweep := true
ltf_sweep.enable_sweep_formed_alert()
else if is_bear_sweep
if not c1.bear_sweep
htf_sweep = UDT_Sweep.new(x1=c1.l_idx, x2=c2.c_idx, y=c1.l, bull=false, tf=c1.tf)
ltf_sweep = UDT_Sweep.new(x1=c1.l_idx, x2=c2.c_idx, y=c1.l, bull=false, tf=c1.tf)
c1.htf_sweeps.push(htf_sweep)
c1.ltf_sweeps.push(ltf_sweep)
c1.bear_sweep := true
ltf_sweep.enable_sweep_formed_alert()
method detect_sweeps(array htf_candles) =>
count = htf_candles.size()
if count > 1
size = math.min(4, count - 1)
for i = size to 1
c1 = htf_candles.get(i)
c2 = htf_candles.get(i - 1)
if not c2.is_closed and c1.htf_sweeps.size() <= 2
detect_sweep(c1, c2)
htf_candles.position_ltf_sweeps()
htf_candles.invalidate_sweeps()
htf_candles
method draw_sweep(UDT_Sweep sweep, bool ltf) =>
if sweep.invalidated
if htf_sweeps_i_sweep_show
if ltf and htf_sweeps_i_sweep_ltf_show or not ltf and htf_sweeps_i_sweep_htf_show
if htf_sweeps_real_time_sweep_show ? true : not sweep.removed and not na(sweep.invalidated_on)
bin.bin_ln.push(line.new(x1=sweep.x1, y1=sweep.y, x2=sweep.x2, y2=sweep.y, xloc = xloc.bar_index, color = htf_sweeps_i_sweep_line_color, style = line_style(htf_sweeps_i_sweep_line_style), width = htf_sweeps_i_sweep_line_width))
else
if htf_sweeps_sweep_show
if ltf and htf_sweeps_sweep_ltf_show or not ltf and htf_sweeps_sweep_htf_show
bin.bin_ln.push(line.new(x1=sweep.x1, y1=sweep.y, x2=sweep.x2, y2=sweep.y, xloc = xloc.bar_index, color = htf_sweeps_sweep_line_color, style = line_style(htf_sweeps_sweep_line_style), width = htf_sweeps_sweep_line_width))
sweep
is_bullish_candle(float c, float o, float h, float l) =>
if c == o
math.abs(o - h) < math.abs(o - l)
else
c > o
method add_htf_candle(array htf_candles, UDT_HTF_Candle candle, int total_candles_number)=>
if not na(candle)
if htf_candles.size() >= total_candles_number
htf_candles.pop()
htf_candles.unshift(candle)
htf_candles
method detect_htf_candle(array htf_candles, string tf, string ltf) =>
UDT_HTF_Candle htf_candle = na
if session_begins(tf, "", na) or htf_candles.size()==0
UDT_HTF_Candle candle = UDT_HTF_Candle.new(tf = tf, htf_sweeps = array.new(), ltf_sweeps = array.new())
candle.o := open
candle.c := close
candle.h := high
candle.l := low
candle.o_idx := bar_index
candle.c_idx := bar_index
candle.h_idx := bar_index
candle.l_idx := bar_index
candle.ot := time
candle.bull := is_bullish_candle(candle.c, candle.o, candle.h, candle.l)
if htf_candles.size() > 0
last_candle = htf_candles.get(0)
last_candle.is_closed := true
last_candle.ct := time
htf_candle := candle
else if in_session(tf, "", na) and htf_candles.size()>0
candle = htf_candles.first()
candle.c := close
candle.c_idx := bar_index + 1
candle.ct := time
if high > candle.h
candle.h := high
candle.h_idx := bar_index
if low < candle.l
candle.l := low
candle.l_idx := bar_index
candle.bull := is_bullish_candle(candle.c, candle.o, candle.h, candle.l)
htf_candle
get_htf_candle_shift(int candle_index, int offset, int buffer, int width, int candles_amount)=>
offset + (width + buffer) * (candles_amount - candle_index - 1)
method position_htf_candle(UDT_HTF_Candle candle, int candle_index, int offset, int buffer, int width, int candles_amount) =>
candle.shift := get_htf_candle_shift(candle_index, offset, buffer, width, candles_amount)
candle.candle_left := last_bar_index + candle.shift
candle.candle_rigth := candle.candle_left + width
candle.candle_top := math.max(candle.o, candle.c)
candle.candle_bottom := math.min(candle.o, candle.c)
candle.wick_x := candle.candle_left + width/2
candle
method position_htf_candles(array htf_candles, int shift) =>
candles_amount = htf_candles.size()
for in htf_candles
candle.position_htf_candle(index, shift, htf_sweeps_space, htf_candle_width, candles_amount)
method draw_htf_candle(UDT_HTF_Candle candle) =>
candle_color = candle.bull ? htf_sweeps_bull_color : htf_sweeps_bear_color
bin.bin_box.push(box.new(left=candle.candle_left, top=candle.candle_top, right=candle.candle_rigth, bottom=candle.candle_bottom, border_color = htf_sweeps_wick_border_color, border_width = 1, bgcolor = candle_color))
bin.bin_ln.push(line.new(x1=candle.wick_x, y1=candle.h, x2=candle.wick_x, y2=candle.candle_top, color = htf_sweeps_wick_border_color))
bin.bin_ln.push(line.new(x1=candle.wick_x, y1=candle.candle_bottom, x2=candle.wick_x, y2=candle.l, color = htf_sweeps_wick_border_color))
candle
method draw_htf_label(array htf_candles, string tf) =>
float y_top = na
float y_bottom = na
int x_min = na
int x_max = na
for in htf_candles
switch htf_sweeps_label_position
"Both" =>
y_top := na(y_top) ? candle.h : math.max(y_top, candle.h)
y_bottom := na(y_bottom) ? candle.l : math.min(y_bottom, candle.l)
"Top" =>
y_top := na(y_top) ? candle.h : math.max(y_top, candle.h)
"Bottom" =>
y_bottom := na(y_bottom) ? candle.l : math.min(y_bottom, candle.l)
x_min := na(x_min) ? candle.wick_x : math.min(x_min, candle.wick_x)
x_max := na(x_max) ? candle.wick_x : math.max(x_max, candle.wick_x)
// time label for HTF candle
txt = candle.candle_time_label()
bin.bin_lbl.push(label.new(x = candle.wick_x, y = candle.l, text = txt, tooltip = str.format("HTF candle open {0}", str.format_time(candle.ot, "yyyy-MM-dd HH:mm Z", htf_sweeps_tz)), xloc=xloc.bar_index, color=color_transparent, style = label.style_label_up, textcolor = htf_sweeps_label_color, size=text_size("Tiny"), text_font_family=font_style(general_font)))
x = math.round(math.avg(x_min, x_max))
txt = tf_label(tf)
remaining_ms = get_htf_remaining_time(timenow, tf, "", na)
if not na(y_top)
bin.bin_lbl.push(label.new(x = x, y = y_top, text = txt, tooltip = str.format("HTF {0}", txt), xloc=xloc.bar_index, color=color_transparent, style=label.style_label_down, textcolor=htf_sweeps_label_color, size=text_size(htf_sweeps_label_size), text_font_family=font_style(general_font)))
bin.bin_lbl.push(label.new(x = x, y = y_top, text = remaining_ms, tooltip = str.format("Time remaining until active HTF candle close {0}", remaining_ms), xloc=xloc.bar_index, color=color_transparent, style=label.style_label_down, textcolor=htf_sweeps_label_color, size=text_size("Tiny"), text_font_family=font_style(general_font)))
if not na(y_bottom)
bin.bin_lbl.push(label.new(x = x, y = y_bottom, text = txt, tooltip = str.format("HTF {0}", txt), xloc=xloc.bar_index, color=color_transparent, style=label.style_label_up, textcolor=htf_sweeps_label_color, size=text_size(htf_sweeps_label_size), text_font_family=font_style(general_font)))
// if htf_sweeps_bias_show and htf_candles.size() > 1
// c1 = htf_candles.get(0)
// c2 = htf_candles.get(1)
// bullish = c1.h > c2.h and c1.l > c2.l
// bearish = c1.h < c2.h and c1.l < c2.l
// bin.bin_lbl.push(label.new(x = x, y = na(y_top) ? y_bottom : y_top, text = " ", xloc=xloc.bar_index, color = bullish ? htf_sweeps_bias_bull_color : htf_sweeps_bias_bear_color, style = bullish ? label.style_arrowup : label.style_arrowdown, size = size.normal))
htf_candles
method draw_ltf_open_close_line(UDT_HTF_Candle candle) =>
y1 = math.min(candle.o, candle.c)
y2 = math.max(candle.c, candle.o)
bin.bin_ln.push(line.new(x1=candle.ot, y1=y1, x2=candle.ot, y2=y2, xloc = xloc.bar_time, extend = extend.both, color = htf_sweeps_ltf_trace_o_c_line_color, style = line_style(htf_sweeps_ltf_trace_o_c_line_style), width = htf_sweeps_ltf_trace_o_c_line_width))
candle
method draw_ltf_high_line(UDT_HTF_Candle candle) =>
bin.bin_ln.push(line.new(x1=candle.ot, y1=candle.h, x2=candle.ct, y2=candle.h, xloc = xloc.bar_time, extend = extend.none, color = htf_sweeps_ltf_trace_h_l_color, style = line_style(htf_sweeps_ltf_trace_h_l_style), width = htf_sweeps_ltf_trace_h_l_width))
candle
method draw_ltf_low_line(UDT_HTF_Candle candle) =>
bin.bin_ln.push(line.new(x1=candle.ot, y1=candle.l, x2=candle.ct, y2=candle.l, xloc = xloc.bar_time, extend = extend.none, color = htf_sweeps_ltf_trace_h_l_color, style = line_style(htf_sweeps_ltf_trace_h_l_style), width = htf_sweeps_ltf_trace_h_l_width))
candle
method plot_ltf(array htf_candles) =>
for in htf_candles
if htf_sweeps_ltf_trace_o_c_line_show
candle.draw_ltf_open_close_line()
if htf_sweeps_ltf_trace_h_l_show
candle.draw_ltf_high_line()
candle.draw_ltf_low_line()
for in candle.ltf_sweeps
ltf_sweep.draw_sweep(true)
htf_candles
method plot_htf(array htf_candles, string tf, bool ltf_map) =>
htf_candles.position_htf_sweeps(htf_sweeps_space)
for in htf_candles
candle.draw_htf_candle()
for in candle.htf_sweeps
htf_sweep.draw_sweep(false)
if htf_sweeps_label_show
htf_candles.draw_htf_label(tf)
if ltf_map
htf_candles.plot_ltf()
htf_candles
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | Plotting |
// # ========================================================================= #
//#region
bin.clean_bin()
var tf_1_show = htf_sweeps_tf_1_show and timeframe.in_seconds(timeframe.period) < timeframe.in_seconds(htf_sweeps_tf_1_tf)
var tf_2_show = htf_sweeps_tf_2_show and timeframe.in_seconds(timeframe.period) < timeframe.in_seconds(htf_sweeps_tf_2_tf)
var tf_3_show = htf_sweeps_tf_3_show and timeframe.in_seconds(timeframe.period) < timeframe.in_seconds(htf_sweeps_tf_3_tf)
var tf_4_show = htf_sweeps_tf_4_show and timeframe.in_seconds(timeframe.period) < timeframe.in_seconds(htf_sweeps_tf_4_tf)
var tf_5_show = htf_sweeps_tf_5_show and timeframe.in_seconds(timeframe.period) < timeframe.in_seconds(htf_sweeps_tf_5_tf)
var tf_6_show = htf_sweeps_tf_6_show and timeframe.in_seconds(timeframe.period) < timeframe.in_seconds(htf_sweeps_tf_6_tf)
if tf_1_show
htf_1_candle = htf_1_candles.detect_htf_candle(htf_sweeps_tf_1_tf, ltf)
htf_1_candles.add_htf_candle(htf_1_candle, htf_sweeps_tf_1_number)
htf_1_candles.detect_sweeps()
if tf_2_show
htf_2_candle = htf_2_candles.detect_htf_candle(htf_sweeps_tf_2_tf, ltf)
htf_2_candles.add_htf_candle(htf_2_candle, htf_sweeps_tf_2_number)
htf_2_candles.detect_sweeps()
if tf_3_show
htf_3_candle = htf_3_candles.detect_htf_candle(htf_sweeps_tf_3_tf, ltf)
htf_3_candles.add_htf_candle(htf_3_candle, htf_sweeps_tf_3_number)
htf_3_candles.detect_sweeps()
if tf_4_show
htf_4_candle = htf_4_candles.detect_htf_candle(htf_sweeps_tf_4_tf, ltf)
htf_4_candles.add_htf_candle(htf_4_candle, htf_sweeps_tf_4_number)
htf_4_candles.detect_sweeps()
if tf_5_show
htf_5_candle = htf_5_candles.detect_htf_candle(htf_sweeps_tf_5_tf, ltf)
htf_5_candles.add_htf_candle(htf_5_candle, htf_sweeps_tf_5_number)
htf_5_candles.detect_sweeps()
if tf_6_show
htf_6_candle = htf_6_candles.detect_htf_candle(htf_sweeps_tf_6_tf, ltf)
htf_6_candles.add_htf_candle(htf_6_candle, htf_sweeps_tf_6_number)
htf_6_candles.detect_sweeps()
if barstate.islast
offset = htf_sweeps_offset
if tf_1_show
htf_1_candles.position_htf_candles(offset)
htf_1_candles.plot_htf(htf_sweeps_tf_1_tf, htf_sweeps_tf_1_map)
offset += get_htf_candle_shift(0, htf_sweeps_margin, htf_sweeps_space, htf_candle_width, htf_sweeps_tf_1_number)
if tf_2_show
htf_2_candles.position_htf_candles(offset)
htf_2_candles.plot_htf(htf_sweeps_tf_2_tf, htf_sweeps_tf_2_map)
offset += get_htf_candle_shift(0, htf_sweeps_margin, htf_sweeps_space, htf_candle_width, htf_sweeps_tf_2_number)
if tf_3_show
htf_3_candles.position_htf_candles(offset)
htf_3_candles.plot_htf(htf_sweeps_tf_3_tf, htf_sweeps_tf_3_map)
offset += get_htf_candle_shift(0, htf_sweeps_margin, htf_sweeps_space, htf_candle_width, htf_sweeps_tf_3_number)
if tf_4_show
htf_4_candles.position_htf_candles(offset)
htf_4_candles.plot_htf(htf_sweeps_tf_4_tf, htf_sweeps_tf_4_map)
offset += get_htf_candle_shift(0, htf_sweeps_margin, htf_sweeps_space, htf_candle_width, htf_sweeps_tf_4_number)
if tf_5_show
htf_5_candles.position_htf_candles(offset)
htf_5_candles.plot_htf(htf_sweeps_tf_5_tf, htf_sweeps_tf_5_map)
offset += get_htf_candle_shift(0, htf_sweeps_margin, htf_sweeps_space, htf_candle_width, htf_sweeps_tf_5_number)
if tf_6_show
htf_6_candles.position_htf_candles(offset)
htf_6_candles.plot_htf(htf_sweeps_tf_6_tf, htf_sweeps_tf_6_map)
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
// # ========================================================================= #
// # | Brand |
// # ========================================================================= #
//#region
if barstate.isfirst and general_brand_show == false
var table brand = table.new(position.bottom_right, 1, 1, bgcolor = chart.bg_color)
table.cell(brand, 0, 0, "© CandelaCharts", text_color = colors_gray, text_halign = text.align_center, text_size = text_size(general_text), text_font_family = font_style(general_font))
//#endregion
// # ========================================================================= #
// # | End |
// # ========================================================================= #
Pair Correlation Oscillator (Overlay)Pair Correlation Oscillator (Overlay)
Overview
This open-source TradingView indicator computes the Pearson correlation coefficient between the chart's instrument (Ticker A) and a user-selected instrument (Ticker B). The correlation is displayed as an oscillator within the range −1..+1:
+1 — perfect positive correlation
0 — no linear correlation
−1 — perfect inverse correlation
Key features
Default window: 500 bars (configurable)
Option to compute correlation on log returns (recommended for comparing different instruments)
Option to exclude the current unfinished bar (use previous completed bars only)
Overlaid line + histogram columns for immediate visual interpretation
Alert examples included (commented out) for high correlation thresholds
Inputs
Ticker 2 — the other instrument to compare against (Ticker 1 is always the chart symbol)
Correlation length — window in bars for the rolling correlation (default 500)
Use log returns — converts price series to log returns before correlation (recommended)
Exclude current bar — shift series by 1 to use only completed bars
How to use
Add the script to your chart and set Ticker 2 to the instrument you want to correlate with the chart symbol.
Choose Use log returns = true for price-to-price comparisons (it removes level bias).
Optionally enable Exclude current bar for more stable signals if you do not want the live unfinished bar affecting results.
Use the line/histogram and label shown on the chart to inspect correlation in real time.
Limitations & notes
Correlation measures linear relationship over the chosen window — non-linear relationships won't be captured.
Very different tickers (e.g., price scales, very low liquidity) may show noisy correlation; use returns and longer windows in such cases.
This indicator is for information/analysis only — not trading advice.
Solar Flares 2025 X & M Class This indicator plots vertical lines on your chart at the exact timestamps of the strongest solar flares recorded in 2025.
X-class flares are shown in light yellow
M-class flares are shown in light blue
All timestamps are based on the maximum intensity time of each flare (default timezone: UTC, adjustable in settings).
Features
Toggle X-class and M-class flares independently
Adjustable line width
Uses precise intraday timestamps (not daily approximations)
Designed as a timing overlay for market cycle research and event clustering
This tool is intended for exploratory and correlation analysis, allowing traders and researchers to visually compare periods of heightened solar activity with market behavior.
Data is hard-coded from the 2025 top solar flare catalog and loads once on script initialization for performance.
Adaptive MTF EMA (auto TF)Adaptive MTF EMA (Auto TF) — Mid & Slow EMA that adjusts with chart timeframe
by @theadventuredan
This indicator plots two Higher-Timeframe EMAs (a Mid and a Slow EMA) on your current chart — but unlike normal MTF EMA scripts, the higher timeframes adapt automatically when you change the chart timeframe.
Instead of having to reconfigure TFs every time you switch from 5m to 15m to 1h, the indicator keeps the same “relationship” by using timeframe multipliers:
Mid TF = current chart TF × Mid Multiplier
Slow TF = current chart TF × Slow Multiplier
Example (default multipliers: 3× and 12×):
On 5m: Mid = 15m, Slow = 60m
On 15m: Mid = 45m, Slow = 180m (3h)
On 1h: Mid = 3h, Slow = 12h
This is especially useful if you use MTF EMA alignment as a trend filter (e.g., Mid EMA above Slow EMA = bullish bias).
How it works
The script reads your current chart timeframe using timeframe.in_seconds(timeframe.period) and converts it into minutes.
It calculates the adaptive MTF targets:
midMin = curMin × midMult
slowMin = curMin × slowMult
It requests the EMA from those higher timeframes via request.security() and plots them on your chart.
Optional:
A label can display the currently calculated Mid and Slow TFs (in minutes).
Inputs
EMA Length: EMA period (default 50)
Mid TF Multiplier: how many times higher the mid timeframe should be (default 3)
Slow TF Multiplier: how many times higher the slow timeframe should be (default 12)
Use confirmed HTF values (safer):
When enabled, the script uses the previous HTF EMA value (EMA ) to reduce behavior caused by partially formed higher-timeframe candles.
This may lag slightly but is often preferred for signal consistency.
Show TF label: shows a label with the current adaptive TFs
Notes / Limitations
Because the higher timeframe is derived by multiplication, some results may produce less common timeframes (e.g., 45m or 12h). This is expected.
MTF values depend on request.security() and will always reflect higher-timeframe candle logic (especially during an unclosed HTF candle). If you want less “in-progress candle” behavior, enable Use confirmed HTF values.
This is an EMA overlay tool — not a standalone buy/sell system.
Suggested usage
Trend bias filter: Mid EMA > Slow EMA = bullish bias, Mid < Slow = bearish bias
Entry alignment: use the adaptive EMAs as “context” while trading lower TF setups
Dynamic market structure: switch timeframes while keeping consistent “one step higher / two steps higher” EMA reference






















