Pinescript Custom Performance BoostThis small script is a custom function that works similarly to the built-in calc_bars_count and max_bars_back functions, but can be used far more flexibly and significantly reduces the required computation time of Pine Script scripts.
The advantages over calc_bars_count are substantial.
The standard function works with a fixed value, e.g. calc_bars_count = 20000. The custom function, on the other hand, works on a percentage basis, e.g. with 20% of the total available chart bars.
In addition, calc_bars_count always affects the entire code, while the custom function can be applied selectively to specific parts of the script.
These two differences enable a much more flexible and efficient usage.
Fixed number of bars vs. percentage-based limitation:
The number of available bars varies greatly, not only depending on the ticker and timeframe used, but also on the TradingView subscription (approx. 5,000–40,000 historical bars).
For example, when using calc_bars_count = 20000, only charts that have more than 20,000 candles benefit. If the available number of bars is lower, there is no performance benefit at all until the value is changed after the first slow calculation.
When using the custom function with, for example, 50%, only 50% of the available bars are always calculated, regardless of how many bars are available. This results in a performance gain with shorter calculation times regardless of the chart.
Entire code vs. partial code sections:
calc_bars_count = 20000 affects the entire code globally, meaning the script processes data from only those 20,000 bars.
The custom function, however, can be used selectively for specific sections of the code. This makes it possible to continue accessing certain values across all available bars, while limiting only the truly computation-intensive parts of the script to a percentage-based range.
In this way, computation time can be drastically reduced without restricting the overall size of the data sets.
It is also possible to imitate max_bars_back and selectively limit specific values instead of limiting all of them.
I hope this is useful to some of you. Have fun with it!
지표 및 전략
Swing IA Cockpit [v2]//@version=5
indicator("Swing IA Cockpit ", overlay=true, max_bars_back=500)
// === INPUTS ===
mode = input.string("Pullback", title="Entry Mode", options= )
corrLen = input.int(60, "Correlation Window Length")
scoreWeightBias = input.float(0.6, title="Weight: Bias", minval=0, maxval=1)
scoreWeightTiming = 1.0 - scoreWeightBias
// === INDICATEURS H1 ===
ema200_H1 = ta.ema(close, 200)
ema50_H1 = ta.ema(close, 50)
rsi_H1 = ta.rsi(close, 14)
donchianHigh = ta.highest(high, 20)
donchianLow = ta.lowest(low, 20)
atr_H1 = ta.atr(14)
avgATR_H1 = ta.sma(atr_H1, 50)
body = math.abs(close - open)
avgBody = ta.sma(body, 20)
// === H4 / D1 ===
close_H4 = request.security(syminfo.tickerid, "240", close)
ema200_H4 = request.security(syminfo.tickerid, "240", ta.ema(close, 200))
rsi_H4 = request.security(syminfo.tickerid, "240", ta.rsi(close, 14))
atr_H4 = request.security(syminfo.tickerid, "240", ta.atr(14))
avgATR_H4 = request.security(syminfo.tickerid, "240", ta.sma(ta.atr(14), 50))
close_D1 = request.security(syminfo.tickerid, "D", close)
ema200_D1 = request.security(syminfo.tickerid, "D", ta.ema(close, 200))
// === CORRÉLATIONS ===
dxy = request.security("TVC:DXY", "60", close)
spx = request.security("SP:SPX", "60", close)
gold = request.security("OANDA:XAUUSD", "60", close)
corrDXY = ta.correlation(close, dxy, corrLen)
corrSPX = ta.correlation(close, spx, corrLen)
corrGold = ta.correlation(close, gold, corrLen)
// === LOGIQUE BIAIS ===
biasLong = close_D1 > ema200_D1 and close_H4 > ema200_H4 and rsi_H4 >= 55
biasShort = close_D1 < ema200_D1 and close_H4 < ema200_H4 and rsi_H4 <= 45
bias = biasLong ? "LONG" : biasShort ? "SHORT" : "NEUTRAL"
// === LOGIQUE TIMING ===
isBreakoutLong = mode == "Breakout" and high > donchianHigh and close > ema200_H1 and rsi_H1 > 50
isBreakoutShort = mode == "Breakout" and low < donchianLow and close < ema200_H1 and rsi_H1 < 50
var float breakoutPrice = na
var int breakoutBar = na
if isBreakoutLong or isBreakoutShort
breakoutPrice := close
breakoutBar := bar_index
validPullbackLong = mode == "Pullback" and not na(breakoutBar) and bar_index <= breakoutBar + 3 and close > ema50_H1 and low <= ema50_H1
validPullbackShort = mode == "Pullback" and not na(breakoutBar) and bar_index <= breakoutBar + 3 and close < ema50_H1 and high >= ema50_H1
timingLong = isBreakoutLong or validPullbackLong
timingShort = isBreakoutShort or validPullbackShort
// === SCORES ===
scoreTrend = (close_D1 > ema200_D1 ? 20 : 0) + (close_H4 > ema200_H4 ? 20 : 0)
scoreMomentumBias = (rsi_H4 >= 55 or rsi_H4 <= 45) ? 20 : 10
scoreCorr = 0
scoreCorr += biasLong and corrDXY < 0 ? 10 : 0
scoreCorr += biasLong and corrSPX > 0 ? 10 : 0
scoreCorr += biasLong and corrGold >= 0 ? 10 : 0
scoreCorr += biasShort and corrDXY > 0 ? 10 : 0
scoreCorr += biasShort and corrSPX < 0 ? 10 : 0
scoreCorr += biasShort and corrGold <= 0 ? 10 : 0
scoreCorr := math.min(scoreCorr, 30)
scoreVolBias = atr_H4 > avgATR_H4 ? 10 : 0
scoreBias = scoreTrend + scoreMomentumBias + scoreCorr + scoreVolBias
scoreStruct = (timingLong or timingShort) ? 40 : 0
scoreMomentumTiming = rsi_H1 > 50 or rsi_H1 < 50 ? 25 : 10
scoreTrendH1 = (close > ema50_H1 and ema50_H1 > ema200_H1) or (close < ema50_H1 and ema50_H1 < ema200_H1) ? 20 : 10
scoreVolTiming = atr_H1 > avgATR_H1 ? 15 : 5
scoreTiming = scoreStruct + scoreMomentumTiming + scoreTrendH1 + scoreVolTiming
scoreTotal = scoreBias * scoreWeightBias + scoreTiming * scoreWeightTiming
scoreLong = biasLong ? scoreTotal : 0
scoreShort = biasShort ? scoreTotal : 0
delta = scoreLong - scoreShort
scoreExtMomentum = (rsi_H4 > 55 ? 10 : 0)
scoreExtVol = atr_H4 > avgATR_H4 ? 10 : 0
scoreExtStructure = body > avgBody ? 10 : 5
scoreExtCorr = (scoreCorr > 15 ? 10 : 5)
scoreExtension = scoreExtMomentum + scoreExtVol + scoreExtStructure + scoreExtCorr
// === VERDICT FINAL ===
verdict = "NO TRADE"
verdict := bias == "NEUTRAL" or math.abs(delta) < 10 or scoreTotal < 70 ? "NO TRADE" :
scoreTotal < 80 ? "WAIT" :
scoreTotal >= 85 and math.abs(delta) >= 20 and scoreExtension >= 60 ? "TRADE A+" :
"TRADE"
// === TABLE COCKPIT ===
var table cockpit = table.new(position.top_right, 2, 9, border_width=1)
if bar_index % 5 == 0
table.cell(cockpit, 0, 0, "Bias", bgcolor=color.gray)
table.cell(cockpit, 1, 0, bias)
table.cell(cockpit, 0, 1, "ScoreBias", bgcolor=color.gray)
table.cell(cockpit, 1, 1, str.tostring(scoreBias))
table.cell(cockpit, 0, 2, "ScoreTiming", bgcolor=color.gray)
table.cell(cockpit, 1, 2, str.tostring(scoreTiming))
table.cell(cockpit, 0, 3, "ScoreTotal", bgcolor=color.gray)
table.cell(cockpit, 1, 3, str.tostring(scoreTotal))
table.cell(cockpit, 0, 4, "ScoreLong", bgcolor=color.gray)
table.cell(cockpit, 1, 4, str.tostring(scoreLong))
table.cell(cockpit, 0, 5, "ScoreShort", bgcolor=color.gray)
table.cell(cockpit, 1, 5, str.tostring(scoreShort))
table.cell(cockpit, 0, 6, "Delta", bgcolor=color.gray)
table.cell(cockpit, 1, 6, str.tostring(delta))
table.cell(cockpit, 0, 7, "Extension", bgcolor=color.gray)
table.cell(cockpit, 1, 7, str.tostring(scoreExtension))
table.cell(cockpit, 0, 8, "Verdict", bgcolor=color.gray)
table.cell(cockpit, 1, 8, verdict, bgcolor=verdict == "TRADE A+" ? color.green : verdict == "TRADE" ? color.lime : verdict == "WAIT" ? color.orange : color.red)
// === ALERTS ===
alertcondition(verdict == "TRADE A+" and bias == "LONG", title="TRADE A+ LONG", message="TRADE A+ signal long")
alertcondition(verdict == "TRADE A+" and bias == "SHORT", title="TRADE A+ SHORT", message="TRADE A+ signal short")
alertcondition(verdict == "NO TRADE", title="NO TRADE / RANGE", message="Marché confus ou neutre — pas de trade")
DF Advanced Sector & RS AnalysisDF Advanced Sector & RS Analysis
Overview
This indicator is an all-in-one dashboard designed to give you an instant "health check" on any asset. Instead of opening multiple charts to check the market trend, sector performance, and fundamentals, this tool brings all that data into a single table on your screen.
It automatically detects if you are looking at a Stock, Crypto, or Forex pair and adjusts its benchmarks accordingly.
Key Features
1. Smart Asset Detection
Stocks: Compares performance against the S&P 500 (SPY).
Crypto: Compares performance against Bitcoin (BTC).
Forex: Compares performance against the US Dollar Index (DXY).
2. Sector Intelligence (Stocks Only)
If you are trading a stock, the indicator automatically identifies its sector (e.g., Technology, Energy, Finance) and compares the stock against that specific sector ETF.
Sector Trend: Tells you if the sector is in an Uptrend or Downtrend.
vs Sector: Shows if your stock is outperforming its own industry.
3. Relative Strength (RS) & Alpha
RS Rating (0-100): A score derived from RSI logic that measures how strong the asset is compared to the benchmark. A score above 70 is bullish.
Alpha: Shows how much the asset is beating (or lagging) the market over the last 20 days.
4. Fundamental Snapshot
Growth: Displays EPS (Earnings) and Revenue growth. You can toggle these between TTM (Trailing 12 Months) for a smoother view or Quarterly for recent performance.
Valuation: Displays the P/E Ratio (TTM). This is always calculated using Trailing Twelve Month data to provide a standard valuation metric.
5. The "Verdict" Score
The indicator combines Technicals, Fundamentals, and Sector Strength into a final 0-100 Score:
STRONG (Green): High probability setup (Score > 70).
NEUTRAL (Grey): Mixed signals (Score 50-70).
RISK (Red): Weak performance or fundamentals (Score < 50).
How to Use
Add to Chart: The table will appear in the corner of your screen.
Check the Score: Look for assets with a "STRONG" verdict.
Analyze the RS: Ensure the RS Rating is high (green) to confirm the asset is a market leader.
Check the Sector: For stocks, it is safer to buy when the "Sector Trend" is UP.
Settings
Table Position: Move the dashboard to any corner of the screen.
Text Size: Adjust the size to fit your screen resolution.
Financials Mode:
TTM: Uses 12-month data (Smoother, standard for long-term analysis).
Quarterly: Uses the most recent quarter vs. the same quarter last year (More volatile, good for earnings plays).
Note: P/E Ratio is always TTM regardless of this setting.
Disclaimer
This tool is for informational purposes only and does not constitute financial advice. Always do your own research before trading.
ROC-WMA bull bear indicatorROC-Weighted MA Oscillator
based on Seequant indicator
The ROC-Weighted MA Oscillator (ROCWMA) is a momentum-driven oscillator designed to expose hidden acceleration and deceleration phases in price action by dynamically weighting a moving average with the normalized Rate of Change (ROC).
Instead of treating all price deviations equally, this indicator amplifies meaningful moves and suppresses low-energy noise, making it particularly effective in scalping, intraday trading, and momentum reversals.
🔧 Core Concept
A base moving average (SMA, EMA, TEMA, DEMA, HMA, ALMA, etc.)
Weighted by normalized ROC
Transformed into a Z-score oscillator for comparability across assets
Smoothed with a signal line for timing precision
Result: a context-aware oscillator that adapts to market intensity.
📊 What the Oscillator Shows
Bullish momentum when histogram is positive and expanding
Bearish momentum when histogram is negative and expanding
Neutral zone to filter chop and avoid over-trading
Automatic color logic to highlight regime changes
Optional candle coloring reflects the active momentum state.
🎯 Signal-Based Price Markers (Advanced Feature)
This script includes price-chart markers when:
The signal line retraces to X% of the maximum oscillator bar of the current momentum phase
AND the signal slope confirms exhaustion (rising or falling)
Key characteristics:
Adaptive thresholds (relative, not fixed)
Separate logic for bullish and bearish phases
Reset on each neutral-zone transition
Configurable number of markers per momentum cycle
This makes the indicator particularly useful for:
Pullback entries
Momentum fading
Timing partial exits
⚙️ Customization
Fully adjustable ROC length, MA type, signal length
Neutral zone threshold control
Multiple color schemes
Optional candle coloring
Adaptive signal-to-oscillator percentage logic
🧠 Best Use Cases
Scalping (M1–M5)
Intraday momentum confirmation
Pullback and exhaustion detection
Cross-asset trading (FX, indices, crypto, metals)
ROCWMA is not a lagging oscillator.
It is a momentum intensity detector built to reveal when price moves matter.
CTR Weekly MA + 1D MA (improved)This does what the previous version does but more. I've added color candles to match the three weekly MAs. It helps show the stronger pullback as it goes deeper into each of the 3 weekly MAs and once the pullback is over and price goes back above or below the lowest or highest MA (depending on whether you are trading in a bear market or bull market) the candle colors will turn bright green or bright red.
Weighted NIFTY 5D Directional BreadthOverview
This indicator measures market participation quality within the NIFTY index by tracking how many heavily-weighted stocks are contributing to index direction over a rolling 5-day period.
Instead of counting simple up/down closes, it evaluates directional momentum × index weight, making it far more reliable for identifying narrow leadership, distribution, and late-stage rallies.
Why this indicator matters
Indexes can continue making higher highs even when only a few large stocks are doing the lifting.
This tool reveals what price alone hides:
Whether participation is broad or narrowing
When index highs are being driven by fewer contributors
Early warnings of fragility before corrections
How it works
Each selected NIFTY stock is assigned a weight approximating index influence
The indicator checks whether each stock is up or down versus its 5-day close
Directional signals are weighted and aggregated
The result is a single breadth line reflecting true contribution strength
Positive values → weighted participation is supportive
Negative values → weighted drag beneath the index
How to interpret
Index Higher High + Indicator Lower High
→ Narrow leadership, distribution risk
Indicator turns down before price
→ Early loss of momentum
Sustained positive readings
→ Healthy, broad participation
Sustained negative readings
→ Market weakness beneath the surface
This is not a buy/sell signal, but a context and risk-assessment tool.
Best use cases
Identifying late-stage rallies
Confirming or rejecting breakouts
Risk management for index trades
Combining with price structure or momentum indicators
Notes
Designed for Daily and higher timeframes
Uses non-repainting logic
Best used alongside price action and structure
Disclaimer
This indicator is intended for educational and analytical purposes only.
It does not provide financial advice or trade recommendations.
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
KRXNameMapperLibrary "KRXNameMapper"
TODO: add library description here
getCompanyName(code)
TODO: add function description here
Parameters:
code (string)
Returns: TODO: add what function returns
1of1 Trades Expected Ranges (Friday Close Calculator)Expected Ranges (Friday Close Calculator)
Expected Ranges is a simple, non-plotting calculator designed for weekly market preparation.
It uses the most recent Friday’s daily close as the base price and calculates an expected trading range for the upcoming week.
This indicator is intentionally built as a calculator only — it does not draw lines or zones on the chart. This ensures there is no bleed between symbols and allows traders to convert levels into permanent TradingView drawings (horizontal lines and shaded rectangles) that are stored per symbol in their account.
How It Works
Friday Close is automatically detected from the daily chart.
You input a single value for Expected Weekly Move.
The indicator calculates:
Upper Range = Friday Close + Expected Move
Lower Range = Friday Close − Expected Move
Values are displayed in a clean top-right panel for quick reference.
TX Stealth Pro: International EditionTX Stealth Pro is a high-performance, intra-day monitoring terminal specifically designed for index futures traders (optimized for Taiwan Index Futures - TX). This indicator merges a sleek, "Stealth" dashboard UI with critical session-based technical levels, allowing traders to monitor trend direction, volatility, and key liquidity zones without cluttering the price action.
Friendly Stretch Band Regime + Filters (Close Confirm + Hold)What it is
A calm, regime-based stretch band that highlights only three states: BUY zone, SELL zone, and Neutral. Designed to reduce noise and visual overload by avoiding markers, labels, and background tint.
How it works
Bands are built from an EMA basis ± ATR.
BUY Zone: price below lower band (lower band turns green)
SELL Zone: price above upper band (upper band turns red)
Neutral: price inside bands (bands grey)
Stability Options
Confirm on Close: requires CLOSE beyond the band (reduces wick spikes)
Hold Bars: holds zone state for N bars after the trigger ends (reduces flicker)
Optional Filters (applied only if enabled)
Trend filter (basis slope or slow EMA)
ATR expansion gate
Minimum exceed beyond band (ATR units)
Suggested Use
Best used as a clean “location/context” tool on swing timeframes (e.g., 4H). It can be paired with a separate momentum/confirmation tool.
Repainting & Disclaimer
Uses only current and historical bar data (no security() calls). Values may update on the realtime bar before close. Educational use only; not financial advice.
SolQuant WatermarkSOLQUANT WATERMARK
The SolQuant Watermark is a professional-grade utility script designed for traders, educators, and content creators who want to keep their charts organized and branded. By utilizing Pine Script’s table functions, this indicator ensures your custom text and symbol data stay pinned to the screen, regardless of where you scroll on the price action.
KEY FEATURES
Customizable Branding: Display your community name, website, or social handles anywhere on the chart.
Automated Symbol Data: Dynamic tracking of the current Asset, Timeframe, and Date—perfect for keeping screenshots contextually accurate.
Precision Placement: Choose from 9 different anchor points (Top-Left, Bottom-Right, etc.) to ensure the UI never interferes with your technical analysis.
Visual Scaling: 5 different size settings (Tiny to Huge) to accommodate high-resolution displays or mobile viewing.
Aesthetic Control: Fully adjustable color palettes, background transparency, and border toggles.
WHY USE A TABLE-BASED WATERMARK?
Unlike standard chart labels which are tied to specific price/time coordinates, this tool uses the Table API . This means:
The watermark stays in place while you scroll through history.
It doesn't disappear when you "hide" other drawing tools.
It scales consistently across different devices.
INSTRUCTIONS
1. Branding: Open settings and type your link or handle into the "Quote Text" area.
2. Symbol Info: Toggle the "Symbol Info" section to automatically display asset names and dates for your records.
3. Layout: Use the X and Y position dropdowns to move the modules if they overlap with your current price action or other indicators.
Note: This is a visual utility tool only. It does not provide trade signals or financial advice.
JAMS Intraday Forex EMA Trend Strategy (MTF + Sessions + DD)Strategy focused on following current trend with triple confirmation based on EMAs and VWAPs
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
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 |
// # ========================================================================= #
IBPDA Time Markers Daily OnlyThis indicator plots IBPDA (Interbank Price Delivery Algorithm) time markers based on true bar counts, not calendar days.
Unlike many time-cycle tools that rely on calendar arithmetic, this script calculates 20 / 40 / 60 daily candles, ensuring accuracy across:
market holidays
shortened sessions
exchange-specific trading calendars
It is intentionally restricted to the Daily timeframe, where each bar represents one completed trading session.
🔍 What This Indicator Does
Draws vertical lines at:
−20 / −40 / −60 bars (exact historical daily candles)
+20 / +40 / +60 bars (future projections for planning)
Uses bar index–based logic, not calendar dates
Prevents misuse by enforcing Daily timeframe only
Draws lines once per chart load to avoid clutter and object limits
⚙️ Key Design Choices (Important)
Past markers are exact
Past levels use time , which means “n completed daily sessions ago” — no approximation.
Future markers are projected
Since future bars do not exist yet, forward levels are projected using a configurable day-step. These are meant for time-window awareness, not precision forecasting.
No repainting
All levels are fixed once drawn.
🧠 How to Use (Best Practice)
IBPDA time levels are time magnets, not trade signals.
They work best when combined with:
Higher-timeframe PD arrays (weekly/monthly highs & lows)
Fair Value Gaps (FVGs)
Liquidity pools
Market structure shifts
Watch for price expansion, liquidity events, or displacement occurring near these time markers.
🛑 Limitations (By Design)
Daily timeframe only
Future levels are projections (exchange calendars cannot be predicted perfectly)
This script does not generate buy/sell signals
🎯 Intended Audience
This indicator is designed for:
ICT / SMC traders
Index futures traders (NQ, ES, YM, etc.)
Swing traders and position traders
Traders who respect time as a variable, not just price
🧩 Notes
Best used as a contextual framework, not a standalone strategy
Clean, lightweight, and safe for long-term chart usage
Built with strict Pine Script v5 compatibility and publishing standards
Price Range AnalyzerPrice Range Analyzer - 365-Day Market Context
Get instant market perspective with key price metrics calculated from daily timeframe data, regardless of your current chart interval.
📊 KEY FEATURES:
- 365-Day High/Low with percentage distance from current price
- Range Position indicator (0-100%) with color-coded zones
- Comparison vs 365-day average price
- ATR-based volatility assessment
- Automatic adaptation for new assets (uses available data)
- Clean, professional table (top-left position)
- Optional visual lines on chart
🎯 WHAT IT SHOWS:
1. 365D High - Highest price in period + % below current
2. 365D Low - Lowest price in period + % above current
3. Range Position - Where price sits in the range:
• 🟢 Very Low (0-20%): Strong buy zone
• 🟢 Low (20-40%): Bullish territory
• 🟡 Mid (40-60%): Neutral zone
• 🟠 High (60-80%): Bearish territory
• 🔴 Very High (80-100%): Strong sell zone
4. vs 365D Average - Distance from mean (reversion signal)
5. Volatility - ATR as % of price (Low/Medium/High)
💡 USE CASES:
- Quick assessment of support/resistance zones
- Identify overbought/oversold conditions
- Mean reversion trading opportunities
- Risk assessment via volatility levels
- Works on ALL timeframes (always uses daily data)
- Perfect for new listings (auto-adjusts to available history)
⚙️ SETTINGS:
- Adjustable lookback period (30-730 days)
- Toggle high/low/average lines on chart
- White background optimized table
Clean, simple, actionable. Know exactly where you stand in the bigger picture at a glance.
PowerDays - Day of the Week HUDDescription: Midnight HUD & Daily Session Dividers
This indicator is designed to provide a clean, "Heads-Up Display" (HUD) for daily session tracking. It solves the common problem of cluttered charts by pinning the days of the week to the top of the chart window in a perfectly horizontal line, ensuring they remain visible and aligned regardless of price volatility or vertical scrolling.
Key Features:
Strict Midnight Dividers: Unlike standard "New Day" indicators that trigger at the exchange open (which can be 6:00 PM for some futures or forex pairs), this indicator plots a vertical dashed line at exactly 00:00 based on your chart's time zone.
Centered HUD Labels: Days of the week (MONDAY, TUESDAY, etc.) are plotted in a level horizontal row at the top of the pane. Labels are mathematically centered between midnight dividers to provide a clear visual of the current trading day’s range.
"Error-Proof" Architecture: Built using primitive plotting methods to avoid common Pine Script "Undeclared Identifier" errors, ensuring high compatibility across different TradingView versions and devices.
Fully Customizable: Includes a built-in color picker to adjust the Royal Blue labels and session dividers to match your specific chart theme.
A+ ORB VWAP EMA Alerts//@version=5
indicator("A+ ORB VWAP EMA Alerts", overlay = true)
// ORB levels (set these from LuxAlgo each morning)
orbHigh = input.float(0.0, "ORB High", step = 0.1)
orbLow = input.float(0.0, "ORB Low", step = 0.1)
// EMAs and VWAP
emaFast = ta.ema(close, 9)
emaSlow = ta.ema(close, 21)
vwapVal = ta.vwap(hlc3)
// Conditions
longCond = (close > orbHigh) and (close > vwapVal) and (emaFast > emaSlow)
shortCond = (close < orbLow) and (close < vwapVal) and (emaFast < emaSlow)
// Alerts (single-line, plain ASCII)
alertcondition(longCond, "A+ LONG SETUP ORB VWAP EMA", "A+ LONG: ORB High accepted, above VWAP, EMA9 > EMA21 (5m close).")
alertcondition(shortCond, "A+ SHORT SETUP ORB VWAP EMA", "A+ SHORT: ORB Low accepted, below VWAP, EMA9 < EMA21 (5m close).")
Moon Phases Final Moon Phases Visualizer DescriptionThis script is a comprehensive tool for traders who incorporate lunar cycles into their analysis. Unlike many basic indicators, this one is optimized for Pine Script v6 and utilizes a precise astronomical calculation based on the synodic month cycle ($29.53059$ days).The indicator helps identify potential "turn window" periods often associated with New Moons and Full Moons in financial astrology and cyclical analysis.Key FeaturesDual Visualization: Displays a smooth lunar cycle oscillator ($0-100\%$) in a separate pane while simultaneously plotting phase labels directly on the price chart.Smart Overlays: Using the latest force_overlay technology, the script keeps your price scale clean while showing Moon emojis (🌕/🌑) and an info table in the main area.Real-time Tracking: An elegant dashboard in the top-right corner shows the current phase percentage and status at a glance.Full Moon & New Moon Alerts: Visual signals are generated at the exact peak of the cycle, making it easy to spot historical correlations with price reversals or volatility spikes.How to read it:🌕 Full Moon (50%): Often associated with high volatility or local price extremes.🌑 New Moon (0%/100%): Often marks the beginning of a new cycle or a potential trend exhaustion.The Curve: Watch the oscillator to anticipate approaching lunar events before they happen.Technical DetailsThe calculation is anchored to a high-precision historical New Moon timestamp (January 6, 2000), ensuring the phase accuracy remains consistent even when scrolling back through years of historical data.
Disclaimer: This indicator is for educational and entertainment purposes only. Lunar cycles are a part of financial astrology and cyclical analysis, but they should not be used as a standalone signal for trading. Past performance does not guarantee future results. Always use proper risk management and combine this tool with other technical or fundamental analysis methods. Not financial advice.






















