FX Strike — EMAs + ATR Trailing StopsThe FX Strike Overlay combines three key moving averages with ATR-based trailing stops to create a clear, rule-based trading framework.
EMAs (200, 50, 20): Define macro trend, active trend, and entry trigger.
ATR Trailing Stop: Adapts dynamically to volatility to manage stop-loss placement and trend exits.
Pullback Zone Shading (20↔50): Highlights high-probability continuation areas.
Flip Markers & Alerts: Optional signals when price crosses the ATR trail or reclaims the 20 EMA in trend.
How to Use:
Follow the 200/50 EMA alignment for trend bias.
Look for pullbacks to the 50 EMA and reclaims of the 20 EMA for entries.
Place stops at the ATR trail line, and let it manage exits dynamically.
Use with Volume Profile or support/resistance levels for profit targets.
This tool was designed with a clean black/gold theme for traders who value simplicity, discipline, and clarity.
Göstergeler ve stratejiler
Liquidity PocketLiquidity Pocket Indicator
This indicator identifies and tracks institutional liquidity zones through pivot-based support and resistance analysis, providing visual confirmation when price returns to test these critical levels.
Core Functionality:
Dynamic Pivot Detection: Automatically identifies swing highs and lows using customizable lookback parameters
Multi-Timeframe Analysis: Option to analyze pivots from higher timeframes while displaying on current chart
Liquidity Line Tracking: Draws horizontal lines from pivot points that extend until price interference occurs
Sweep Confirmation: Generates signals when price returns to test previously established pivot levels
Key Features:
Adaptive Timeframe Selection: Choose specific timeframes or use automatic multiplier system (Lvl1-Lvl4) for systematic higher timeframe analysis
Dynamic Line Management: Automatically manages active lines with performance optimization through maximum line limits
Visual Confirmation System: Customizable display options including line styles, candle coloring, and liquidity sweep signals
ATR-Based Signal Positioning: Intelligent signal placement using Average True Range calculations for optimal visibility
Signal Logic:
The indicator monitors when price returns to previously established pivot levels, interpreting these interactions as liquidity sweeps or institutional order execution zones. Signals trigger upon contact with tracked levels, providing confirmation of institutional interest areas.
Customization Options:
Adjustable pivot sensitivity through left/right bar lookback settings
Comprehensive visual customization including colors, line styles, and signal symbols
Performance controls with maximum active line limits
Alert system for real-time liquidity event notifications
This tool excels at identifying where institutional players may have placed orders, making it valuable for understanding market structure and potential reversal zones.
自定义均线系统A customizable Moving Average indicator that lets you freely choose the period values you want, and automatically plots them on the candlestick chart. This flexibility helps traders quickly adjust their analysis style, compare different trends, and fine-tune strategies without switching between multiple fixed indicators.
Lanxang Pin Bar Pro V.2How to use (step-by-step)
Mark context first
Draw your Supply/Demand zones and note HTF structure (H1).
Use the indicator as a price action confirmation at those POIs.
Wait for a pin bar at a level
Bullish pin: long lower wick rejecting demand; Bearish pin: long upper wick rejecting supply.
Ensure it prints within your session and passes ATR/shape filters.
Choose your entry style
Conservative: Enter on break of pin high (bull) / low (bear).
Aggressive (RR-optimized): Place a limit near the 50% retrace of the pin bar (you removed lines, so measure the midpoint quickly: (High+Low)/2 from the data box).
Place stop
Beyond the wick + small buffer (e.g., 10–20 pts on XAUUSD M5–M15).
Keep SL reasonable (≤ ~1–1.2× ATR of your entry TF).
Targets & management
T1 = 1R, take partial, move to BE after structure break or at 1R depending on volatility.
T2 at the next opposing SD zone, prior swing, or session high/low.
Let a small runner trail via swing highs/lows if trend is strong.
Risk
Keep risk fixed % (e.g., 1%) per trade. Your math is already RR-driven—perfect for journaling and expectancy.
Recommended defaults (XAUUSD, M5–M30)
Min Wick : Body Ratio = 2.0–2.5
Max Body / Range = 0.30–0.35
Min Range as ATR multiple = 0.8–1.0
HTF = 60 min; EMAs = 50/200
Sessions = London core + NY open
Alerts
Turn on alerts for Bullish Pin Bar / Bearish Pin Bar (and optionally “Entry Trigger” if you use it).
Use them to route to your phone or EA bridge (you already use webhook flows).
Pro tips (fits your SMC style)
Prefer pins that sweep liquidity (wick pokes above equal highs / below equal lows) and close back inside your zone.
Extra confluence: FVG edge, HTF OB boundary, or daily/weekly high/low.
Skip mid-range pins with no level.
Track R results in your journal to monitor expectancy.
Liquidation Strategy💣 Liquidation Strategy (High-Level Overview + Usage)
This strategy is built to trade extreme liquidation events on crypto exchanges like Bybit or OKX, using TradingView’s Liquidations indicator as input.
🔧 Core Logic
Long entries: Triggered when long liquidation values spike above a set threshold.
Short entries: Triggered when short liquidation values drop below a negative threshold.
Optional EMA filter ensures liquidation values are significantly above/below their moving average.
RSI crossover logic is used to exit trades.
🛠️ Usage Instructions
Add the Liquidations Indicator: Go to TradingView → Indicators → Search for “Liquidations” under the Financials section.
Select the Correct Chart: Use a chart from Bybit or OKX, as these exchanges provide liquidation data.
Link the Data Sources: In the strategy settings, set: Long Liquidation Data to the long liquidation series from the indicator. Short Liquidation Data to the short liquidation series.
Overlay the Strategy: You can overlay this strategy directly on the Liquidations indicator for better visual alignment.
LFT Foundation Entry MarksThis algorithm highlights optimal long entry points. Once the entry conditions break down—indicating the price is likely to decline—the signals stop, allowing the user to exit before the drop
W Bottom Reversal Strategy W Bottom Reversal Strategy (15m-close entries; intrabar TP; daily MACD exit; JSON alerts v49.3-expire2)
Overview
A precision reversal strategy designed for 15-minute charts on liquid symbols. It detects a capitulation-and-stabilization “W” base using 1-hour (1H) context, confirms momentum improvement, then enters only on bar close to avoid early/“ghost” signals. Exits combine a fast intrabar take-profit (~2.7%) with a daily MACD risk-off exit that closes positions when higher-timeframe momentum turns against the setup.
How it works (high-level, matching code)
1H volatility + oversold gate (arming)
Compute 1H Bollinger-style bands (basis = SMA(close, bbLength=20), stdev multiplier bbMult=2.0).
Arm the setup when a 1H bar closes with price < 1H lower band and 1H RSI( rsiLength=14 ) < rsiThreshold (default 20.0).
1H momentum flip → pending entry
When a new 1H bar closes and 1H MACD line (EMA12−EMA26) crosses above 0 while armed and flat, set an entryPending flag.
This does not enter yet—it prepares a confirmed, bar-close entry on the lower timeframe.
Bar-close execution on the chart timeframe (15m)
On the next 15m bar close (or within N bars, see below) and still flat, fire the entry using a limit order at close × (1 − 0.00001) (≈ 0.001% below close) to reduce slippage and maintain chart/alert alignment.
Anti-late filter (no stale triggers)
If the pending entry doesn’t trigger within N chart bars (input: “Pending entry valid for N chart bars”, default 1, range 1–8), it expires and the arm state resets. This prevents late fills long after the 1H confirmation.
Exit logic
Primary: Standing intrabar take-profit at +2.7% from the average entry price (managed via strategy.exit limit).
Risk-off: On daily bar close, if Daily MACD line (EMA12−EMA26) crosses under 0, close the position (flat on daily momentum flip).
Default Properties (used for this publication)
Timeframe: 15m (with 1H and Daily higher-timeframe confirmations via request.security)
Initial capital: $10,000
Position sizing: Percent of equity = 10% per trade (enters only when flat; no stacking while in a position)
Commission: 0.05% per side
Slippage: Recommend 1 tick in Strategy Properties for realistic fills
Inputs exposed:
BB Length: 20 • BB Multiplier: 2.0
RSI Length: 14 • RSI Threshold: 20.0
MACD: Short 12, Long 26, Signal 9 (signal kept for compatibility; logic uses MACD line vs 0)
Pending entry valid for N chart bars: default 1 (1–8)
Execution behavior (per code):
calc_on_every_tick = false (evaluates on bar close)
process_orders_on_close = true (orders placed at bar close)
Limit entry at close −0.001%
Intrabar TP (2.7%)
Daily risk-off exit on MACD<0 at daily bar close
Alerts (exact behavior in code)
Uses alert() function calls with standardized JSON.
Set your alert to “Only alert() function calls” and “Once per bar close.”
Two events are emitted:
LONG_CONFIRMED on entry fire (15m bar close)
EXIT_CONFIRMED_DAILY_MACD on daily MACD<0 (daily bar close)
JSON fields include: event, version ("v49.3-expire2"), symbol, interval, price, and time.
How to use
Apply on liquid tickers (tight spreads, healthy volume).
Keep defaults initially; run across a broad, liquid watchlist to gather a proper sample.
For automation, route bar-close alerts to your executor; confirm broker lot/route settings and that limit orders at close −0.001% are acceptable.
Expect fewer signals in powerful trends; the daily risk-off helps cut failed bases.
Methodology & expectations (results transparency)
Evaluate on a dataset yielding 100+ trades before drawing conclusions.
Keep commission & slippage enabled (see defaults).
Risk sizing: With 10% of equity per trade and flat-to-flat entries, exposure aligns with typical 5–10% guidance.
No performance guarantees—outcomes depend on symbol selection, volatility regime, news, and execution quality.
Originality & value (vendor justification)
While it uses familiar building blocks (BB/RSI/MACD), the edge comes from the 1H volatility + oversold arming, 1H momentum flip, strict 15m bar-close limit execution, and the N-bar pending expiry that prevents stale triggers—paired with a dual-exit design (intrabar TP + daily risk-off). The focus is on reducing premature fills, keeping alerts 1:1 with chart marks, and capturing the first impulse out of a W-base.
Disclaimers
For educational purposes only; not financial advice. Paper-test first. Verify alerts, fills, and symbol liquidity with your broker before live use.
Changelog: v49.3-expire2 — Bar-close limit entries; anti-late pending window; standardized JSON alerts; intrabar 2.7% TP; daily MACD risk-off exit.
Ultimate Indicator [CSN]youtu.be Strategy Rules
Key Levels Identification
Mark Gann Levels on the chart.
These act as major support and resistance zones.
Trade Trigger (Remaining Box Indicator)
If the Remaining Box indicator shows more than 6 ticks in one direction, prepare for a trade in that direction.
This ensures momentum is strong enough to sustain a move.
Supply & Demand Zone Filter
Avoid entries if a strong Supply (for longs) or Demand (for shorts) zone is nearby.
Only take trades in clean zones where price has space to move.
Entry Criteria
Long Trade:
Price bounces or sustains above a Gann Support level.
Remaining Box indicator shows >6 bullish ticks.
No immediate Supply zone above.
Short Trade:
Price rejects or sustains below a Gann Resistance level.
Remaining Box indicator shows >6 bearish ticks.
No immediate Demand zone below.
Risk Management
Stop Loss: Just beyond the Gann level or nearest minor swing point.
Target: Next major Gann level or until momentum weakens (Remaining Box ticks reduce).
Risk-Reward: Minimum 1:2 ratio.
This way, your system becomes rule-based:
Gann levels = structure
Remaining Box = momentum filter
Supply & Demand zones = safety filter
Vibration Bars based on previous day price ActionThe scripts predicts the future bars where reversal may happen. Watch the price action near that bars for high risk reward trades.
Quantel.io FVG & IFVG ICT IndicatorThe Quantel.io FVG & iFVG ICT Indicator identifies Fair Value Gaps (FVGs) and Inversion Fair Value Gaps (iFVGs) with precision, helping traders spot liquidity imbalances and potential trap zones.
💡 How to Use:
Detect FVG zones where price is likely to return for liquidity grabs or reversals.
Identify iFVG zones to anticipate market traps or potential continuation moves.
Combine with ICT concepts, liquidity sweeps, BOS/CHOCH, or swing structure for optimal entries.
✅ Features:
Dynamic plotting of FVG and iFVG zones with clear box visualization.
Highlights key imbalance areas for easier market structure reading.
Compatible with all timeframes and markets (forex, indices, crypto).
⚠️ Disclaimer: This tool is for educational purposes only. Not financial advice. Always confirm with your own analysis and risk management.
Quantel.io ICT Killzones & PivotsICT Killzones & Pivots
The ICT Killzones & Pivots indicator helps traders visualize key trading sessions and pivot levels for better intraday decision-making. It automatically highlights:
Killzones – major trading sessions (Tokyo, London, New York) with colored boxes.
Pivot Levels – daily, weekly, or custom pivots for support/resistance guidance.
💡 How to Use:
Monitor killzone boxes to time entries and exits during high-volume periods.
Combine pivot levels with session context to anticipate reversals, breakouts, or retests.
Works on all markets (forex, indices, crypto) and all timeframes.
✅ Features:
Color-coded session boxes for clear visual context.
Automatic pivot plotting with adjustable settings.
Lightweight and clean chart display.
⚠️ Disclaimer: This indicator is for educational purposes only. Not financial advice. Always confirm signals with your own analysis and risk management.
AC Trader - Super TrendThis is a candlestick pattern indicator (Marubozu, Engulfing, Pinbar) that cuts through the EMA lines (20/50/200). AE can change the EMA indicators as desired. For example, EMA 34/89/200. There is a general warning for candlestick patterns when cutting through the EMA.
Quantel iFVG & Breakout DetectorThe Quantel iFVG & Breakout Detector is a precision tool designed to highlight inversion fair value gaps (iFVGs) and breakout opportunities with crystal-clear visuals. It plots:
Arrow Signals – to mark breakout confirmations.
Box Highlights – to show active iFVG zones and breakout ranges.
💡 How to Use:
Use the arrows as directional cues for potential entries after a confirmed breakout.
Watch the highlighted boxes to identify imbalances and zones of interest for reversals or continuation.
Best combined with liquidity sweeps, BOS/CHOCH, or higher timeframe bias for stronger confirmation.
✅ Features:
Automatic detection of iFVGs with dynamic zone plotting.
Breakout confirmation arrows for easy trade visualization.
Clean, uncluttered chart display suitable for all timeframes.
⚠️ Disclaimer: This tool is for educational purposes only. Not financial advice. Always combine signals with your own trading plan and risk management.
SAPSAN TRADE: Liquidity & Market Manipulation TrackingThe SAPSAN TRADE: Liquidity & Market Manipulation Tracking indicator helps track market liquidity and detect potential manipulations by major participants. It analyzes volume flows, market maker activity, and unusual volatility changes, allowing traders to:
Identify zones with high concentration of large orders.
Detect abnormal price movements and market “traps.”
Assess buyer and seller pressure for informed trading decisions.
Use in scalping, intraday trading, and analysis of cryptocurrencies, stocks, and forex.
The indicator supports alert settings:
Notifications when activity exceeds a specified threshold.
Signals for increasing or decreasing liquidity in key zones.
Alerts for potential market manipulations to react promptly to price movements.
RU
Индикатор SAPSAN TRADE: Liquidity & Market Manipulation Tracking позволяет отслеживать ликвидность рынка и выявлять возможные манипуляции со стороны крупных участников. Он анализирует объемные потоки, активность маркет-мейкеров и нетипичные изменения волатильности, чтобы помочь трейдерам:
Определять зоны концентрации крупных ордеров.
Выявлять аномальные движения цены и «ловушки» на рынке.
Оценивать давление покупателей и продавцов для принятия обоснованных торговых решений.
Использовать в стратегиях скальпинга, внутридневной торговли и анализа криптовалют, акций и форекс.
Индикатор поддерживает настройку алертов (уведомлений):
Оповещения при превышении заданного порога активности.
Сигналы о повышении или снижении ликвидности в ключевых зонах.
Уведомления о потенциальных манипуляциях, чтобы вовремя реагировать на рыночные изменения.
Quantel NY Open Break and Retest ModelThe Quantel NY Open Break & Retest Model is a complete trading tool built around the New York session breakout-retest strategy. It automatically identifies key NY session levels and generates ready-to-trade setups with:
Entry Signals – triggered on confirmed break & retest patterns.
Stop Loss (SL) Placement – anchored to structural invalidation levels.
Take Profit (TP) Targets – dynamically mapped using session range and market context.
💡 How to Use:
Designed for intraday traders focusing on New York session volatility (8:30 – 11:30 EST).
Look for signals after the initial NY session impulse move, when liquidity sweeps and retests often occur.
Combine with higher timeframe bias or liquidity indicators for maximum precision.
✅ Features:
Fully automated entry/exit framework for NY session trades.
Adaptive SL/TP placement with risk-reward focus.
Works across assets (indices, forex, crypto) with customizable settings.
⚠️ Disclaimer: This script is for educational purposes only. Not financial advice. Always confirm with your own analysis and apply proper risk management.
ELLIOT WAVE TP11OFC5//@version=6
indicator("TP11OFC5", overlay=true, scale=scale.right, max_lines_count=500, max_labels_count=500, max_boxes_count=500, max_bars_back=5000)
//──────────────────────────────── Inputs: Masked Names ───────────────────────────────
// yelow group (EMA200 + 5up/5down)
group200 = "yelow group"
emaLen200 = input.int(200, "yelow length", minval=1, group=group200)
show200Mid = input.bool(true, "show big brown", group=group200) // EMA200 mid
show200_5u = input.bool(true, "show yelow group up", group=group200) // 5up (EMA200)
show200_5d = input.bool(true, "show yelow group down",group=group200) // 5down (EMA200)
// Colors (masked)
groupClrMA = "Colors — lines"
colMid200 = input.color(color.rgb(100, 50, 0), "big brown", group=groupClrMA) // EMA200 mid
col5band = input.color(color.rgb(247, 212, 14), "yelow up/down", group=groupClrMA) // 5up/5down
col85_4 = input.color(color.rgb(9, 77, 202), "blue up/down (x4)",group=groupClrMA) // EMA85 4up/4down
col35 = input.color(color.rgb(7, 9, 155), "big blue", group=groupClrMA) // EMA35
colPNR = input.color(color.rgb(255,17,0), "pn", group=groupClrMA) // PNR
// blue group (EMA85 — 4 up/down)
group85 = "blue group"
emaLen85 = input.int(85, "blue length", minval=1, group=group85)
show85_4u = input.bool(true, "show blue group up", group=group85)
show85_4d = input.bool(true, "show blue group down", group=group85)
// big blue (EMA35)
group35 = "big blue"
emaLen35 = input.int(35, "big blue length", minval=1, group=group35)
useClose35 = input.bool(false, "big blue use close (else effClose)", group=group35)
showEMA35 = input.bool(true, "show big blue", group=group35)
// pn (PNR)
groupPNR = "pn"
pnrLen = input.int(15, "window size", minval=1, group=groupPNR)
pnrPerc = input.int(50, "percentile (0–100)", minval=0, maxval=100, group=groupPNR)
pnrSrc = input.source(close, "source", group=groupPNR)
showPNR = input.bool(true, "show pn", group=groupPNR)
// di (DSI)
groupDSI = "di"
showDSI = input.bool(true, "show di", group=groupDSI)
atrMovement= input.float(1.0, "movement required", step=0.5, group=groupDSI)
lookback = input.int(25, "high/low lookback", step=5, group=groupDSI)
maxZoneSize= input.float(2.5, "max zone size ", step=0.5, group=groupDSI)
newStructureReset = input.int(25, "zone update count before reset", step=5, group=groupDSI)
drawPreviousStructure = input.bool(true, "draw previous zones", group=groupDSI)
groupClrDSI = "Colors — zones"
dsiBullColor = input.color(color.rgb(178, 240, 180), "bull color", group=groupClrDSI)
dsiBearColor = input.color(color.rgb(240, 206, 206), "bear color", group=groupClrDSI)
//──────────────────────────────── FE (Trend-base Fibo) ───────────────────────────────
groupFE = "targets — FE"
feLenBars = input.int(35, "FE length (bars) from P3", minval=5, group=groupFE)
feLife = input.int(500, "FE lifespan (bars) before delete", minval=50, group=groupFE)
showFE = input.bool(true, "show FE", group=groupFE)
roundToTick = input.bool(true, "round FE to tick", group=groupFE)
// FE levels on/off
show95_105 = input.bool(true, "show band", group=groupFE)
show1618 = input.bool(true, "show 1", group=groupFE)
show2618 = input.bool(true, "show 2", group=groupFE)
show3618 = input.bool(true, "show 3", group=groupFE)
show4618 = input.bool(true, "show 4", group=groupFE)
// FE colors
colBand = input.color(color.rgb(79, 247, 46), "line", group=groupFE)
colBandFill = input.color(color.new(#8be95f, 85), "band", group=groupFE)
col1618 = input.color(color.orange, "1line", group=groupFE)
col2618 = input.color(color.fuchsia, "2line", group=groupFE)
col3618 = input.color(color.new(color.purple, 0), "3line", group=groupFE)
col4618 = input.color(color.new(color.maroon, 0), "4line", group=groupFE)
//──────────────────────────────── P-series (เดิม) ───────────────────────────────
groupP1P2P3 = "P-series options"
p1Lookback = input.int(200, "P1 max left scan", minval=20, group=groupP1P2P3)
rightWinBars = input.int(5, "P2 right confirm bars", minval=1, group=groupP1P2P3)
p3MaxWindowBars = input.int(600, "P3 max window (bars)", minval=50, maxval=5000, step=50, group=groupP1P2P3)
resetWithinBars = input.int(50, "reset old set if new within (bars)", minval=1, group=groupP1P2P3)
// >>> NEW: ระยะห่างขั้นต่ำ P1/P3 จาก P2 <<<
minGapBars = input.int(5, "Min gap bars: P1/P3 must be at least this far from P2", minval=1, group=groupP1P2P3)
// ── NEW: De-duplicate labels (no same-type within N bars; keep latest) ─────────────
groupDeDup = "Labels — de-dup"
dedupWinBars = input.int(50, "No same-type label within N bars", minval=1, group=groupDeDup)
// ──────────────────────────────── New: P2 window rule ───────────────────────────────
groupP2Win = "P2 window rule"
p2NewWithinBars = input.int(50, "Window N bars: new P2 within N must be better than last P2 (L: higher / S: lower)", minval=1, group=groupP2Win)
//──────────────────────────────── Visual options ───────────────────────────────
groupPviz = "Visual — Body highlights & labels"
showBodyBoxes = input.bool(true, "show body boxes", group=groupPviz)
P1BoxFullCandle = input.bool(false, "P1: full candle box", group=groupPviz)
P2BoxFullCandle = input.bool(false, "P2: full candle box", group=groupPviz)
P3BoxFullCandle = input.bool(false, "P3: full candle box", group=groupPviz)
P1BoxColor = input.color(color.black, "P1 box color", group=groupPviz)
P1BoxFillTransp = input.int(85, "P1 box fill transp", minval=0, maxval=100, group=groupPviz)
P2BoxColor = input.color(color.lime, "P2 box color", group=groupPviz)
P2BoxFillTransp = input.int(70, "P2 box fill transp", minval=0, maxval=100, group=groupPviz)
P3BoxColor = input.color(color.orange, "P3 box color", group=groupPviz)
P3BoxFillTransp = input.int(70, "P3 box fill transp", minval=0, maxval=100, group=groupPviz)
BoxBorderTransp = input.int(0, "box border transp", minval=0, maxval=100, group=groupPviz)
recolorBars = input.bool(true, "barcolor P1/P2/P3", group=groupPviz)
colP1Candle = input.color(color.black, "P1 candle", group=groupPviz)
colP2Candle = input.color(color.lime, "P2 candle", group=groupPviz)
colP3Candle = input.color(color.orange,"P3 candle", group=groupPviz)
showP1Label = input.bool(true, "show P1 label", group=groupPviz)
showP2Label = input.bool(true, "show P2 label", group=groupPviz)
showP3Label = input.bool(true, "show P3 label", group=groupPviz)
PLabelTextColor = input.color(color.white, "label text color", group=groupPviz)
PLabelBgColor = input.color(color.black, "label bg color", group=groupPviz)
// ── Label placement/offset (split LONG/SHORT) ───────────────────────────────
groupLbl = "Labels — placement"
LP_AUTO = "Auto"
LP_ABOVE = "Above"
LP_BELOW = "Below"
OM_TICKS = "Ticks"
OM_ATR = "ATR"
lblPlaceLong = input.string(LP_ABOVE, "Placement (LONG)", options= , group=groupLbl)
lblPlaceShort = input.string(LP_BELOW, "Placement (SHORT)", options= , group=groupLbl)
lblOffsetMet = input.string(OM_ATR, "Offset method", options= , group=groupLbl)
lblTicks = input.int(5, "Ticks offset", minval=0, group=groupLbl)
lblAtrLen = input.int(14, "ATR length", minval=1, group=groupLbl)
lblAtrMult = input.float(0.25, "ATR multiple", minval=0.0, step=0.05, group=groupLbl)
lblSizeSel = input.string("small", "Label size", options= , group=groupLbl)
lblBgTransp = input.int(0, "Label BG transparency", minval=0, maxval=100, group=groupLbl)
//──────────────────────────────── Manual (แทน Override) ─────────────────────────
PM_OPEN = "Open"
PM_CLOSE = "Close"
PM_MID = "Mid"
PM_HIGH = "High"
PM_LOW = "Low"
PM_CUST = "Custom"
PK_TIME = "Time"
PK_OFF = "Offset"
// LONG
groupManL = "Manual (LONG)"
useManP1L = input.bool(false, "Use P1 manual (L)", group=groupManL)
pickP1L = input.string(PK_TIME, "P1 pick mode (L)", options= , group=groupManL)
manP1L_t = input.time(timestamp("01 Jan 2024 00:00 +0000"), "P1 time (L)", group=groupManL)
manP1L_of = input.int(-5, "P1 offset (bars, L)", group=groupManL)
pmP1L = input.string(PM_OPEN, "P1 price mode (L)", options= , group=groupManL)
p1L_custom= input.float(0.0, "P1 custom price (L)", group=groupManL)
useManP2L = input.bool(false, "Use P2 manual (L)", group=groupManL)
pickP2L = input.string(PK_TIME, "P2 pick mode (L)", options= , group=groupManL)
manP2L_t = input.time(timestamp("01 Jan 2024 00:00 +0000"), "P2 time (L)", group=groupManL)
manP2L_of = input.int(-3, "P2 offset (bars, L)", group=groupManL)
pmP2L = input.string(PM_CLOSE, "P2 price mode (L)", options= , group=groupManL)
p2L_custom= input.float(0.0, "P2 custom price (L)", group=groupManL)
useManP3L = input.bool(false, "Use P3 manual (L)", group=groupManL)
pickP3L = input.string(PK_TIME, "P3 pick mode (L)", options= , group=groupManL)
manP3L_t = input.time(timestamp("01 Jan 2024 00:00 +0000"), "P3 time (L)", group=groupManL)
manP3L_of = input.int(-1, "P3 offset (bars, L)", group=groupManL)
pmP3L = input.string(PM_OPEN, "P3 price mode (L)", options= , group=groupManL)
p3L_custom= input.float(0.0, "P3 custom price (L)", group=groupManL)
// SHORT
groupManS = "Manual (SHORT)"
useManP1S = input.bool(false, "Use P1 manual (S)", group=groupManS)
pickP1S = input.string(PK_TIME, "P1 pick mode (S)", options= , group=groupManS)
manP1S_t = input.time(timestamp("01 Jan 2024 00:00 +0000"), "P1 time (S)", group=groupManS)
manP1S_of = input.int(-5, "P1 offset (bars, S)", group=groupManS)
pmP1S = input.string(PM_OPEN, "P1 price mode (S)", options= , group=groupManS)
p1S_custom= input.float(0.0, "P1 custom price (S)", group=groupManS)
useManP2S = input.bool(false, "Use P2 manual (S)", group=groupManS)
pickP2S = input.string(PK_TIME, "P2 pick mode (S)", options= , group=groupManS)
manP2S_t = input.time(timestamp("01 Jan 2024 00:00 +0000"), "P2 time (S)", group=groupManS)
manP2S_of = input.int(-3, "P2 offset (bars, S)", group=groupManS)
pmP2S = input.string(PM_CLOSE, "P2 price mode (S)", options= , group=groupManS)
p2S_custom= input.float(0.0, "P2 custom price (S)", group=groupManS)
useManP3S = input.bool(false, "Use P3 manual (S)", group=groupManS)
pickP3S = input.string(PK_TIME, "P3 pick mode (S)", options= , group=groupManS)
manP3S_t = input.time(timestamp("01 Jan 2024 00:00 +0000"), "P3 time (S)", group=groupManS)
manP3S_of = input.int(-1, "P3 offset (bars, S)", group=groupManS)
pmP3S = input.string(PM_OPEN, "P3 price mode (S)", options= , group=groupManS)
p3S_custom= input.float(0.0, "P3 custom price (S)", group=groupManS)
// Buttons: Reset (UI switches)
groupBtnL = "Manual Controls — Buttons (LONG)"
btnResetAllL = input.bool(false, "Reset ALL manual (L)", group=groupBtnL)
btnResetP1L = input.bool(false, "Reset P1 manual (L)", group=groupBtnL)
btnResetP2L = input.bool(false, "Reset P2 manual (L)", group=groupBtnL)
btnResetP3L = input.bool(false, "Reset P3 manual (L)", group=groupBtnL)
groupBtnS = "Manual Controls — Buttons (SHORT)"
btnResetAllS = input.bool(false, "Reset ALL manual (S)", group=groupBtnS)
btnResetP1S = input.bool(false, "Reset P1 manual (S)", group=groupBtnS)
btnResetP2S = input.bool(false, "Reset P2 manual (S)", group=groupBtnS)
btnResetP3S = input.bool(false, "Reset P3 manual (S)", group=groupBtnS)
// ── Momentary Reset (edge-detect) ───────────────────────────────
var bool resetReqAllL = false
var bool resetReqP1L = false
var bool resetReqP2L = false
var bool resetReqP3L = false
var bool resetReqAllS = false
var bool resetReqP1S = false
var bool resetReqP2S = false
var bool resetReqP3S = false
bool fireAllL = ta.change(btnResetAllL) and btnResetAllL
bool fireP1L = ta.change(btnResetP1L) and btnResetP1L
bool fireP2L = ta.change(btnResetP2L) and btnResetP2L
bool fireP3L = ta.change(btnResetP3L) and btnResetP3L
bool fireAllS = ta.change(btnResetAllS) and btnResetAllS
bool fireP1S = ta.change(btnResetP1S) and btnResetP1S
bool fireP2S = ta.change(btnResetP2S) and btnResetP2S
bool fireP3S = ta.change(btnResetP3S) and btnResetP3S
if fireAllL
resetReqAllL := true
resetReqP1L := true
resetReqP2L := true
resetReqP3L := true
if fireP1L
resetReqP1L := true
if fireP2L
resetReqP2L := true
if fireP3L
resetReqP3L := true
if fireAllS
resetReqAllS := true
resetReqP1S := true
resetReqP2S := true
resetReqP3S := true
if fireP1S
resetReqP1S := true
if fireP2S
resetReqP2S := true
if fireP3S
resetReqP3S := true
//──────────────────────────────── Core helpers ───────────────────────────────
float effClose = close >= open ? math.max(open, close) : math.min(open, close)
f_bodyTop(_o, _c) => math.max(_o, _c)
f_bodyBot(_o, _c) => math.min(_o, _c)
f_midBody_at(_i) =>
float bt = f_bodyTop(open , close )
float bb = f_bodyBot(open , close )
(bt + bb) / 2.0
f_core(_len) =>
float mid = ta.ema(effClose, _len)
float _dev = ta.stdev(effClose, _len)
float devS = _dev == 0.0 ? na : _dev
float plus = na(mid) or na(devS) ? na : (close > mid ? (close - mid) / devS : 0.0)
float minus = na(mid) or na(devS) ? na : (close < mid ? (mid - close) / devS : 0.0)
float mmax = na(plus) or na(minus) ? na : math.max(plus, minus)
float lm = ta.ema(mmax, _len)
f_core_src(_src, _len) =>
float mid = ta.ema(_src, _len)
float _dev = ta.stdev(_src, _len)
float devS = _dev == 0.0 ? na : _dev
float plus = na(mid) or na(devS) ? na : (_src > mid ? (_src - mid) / devS : 0.0)
float minus = na(mid) or na(devS) ? na : (_src < mid ? (mid - _src) / devS : 0.0)
float mmax = na(plus) or na(minus) ? na : math.max(plus, minus)
float lm = ta.ema(mmax, _len)
// Price by mode
f_price_by_mode(off, mode, custom) =>
switch mode
PM_OPEN => open
PM_CLOSE => close
PM_MID => (math.max(open , close ) + math.min(open , close ))/2.0
PM_HIGH => high
PM_LOW => low
PM_CUST => custom > 0 ? (roundToTick ? math.round(custom / syminfo.mintick) * syminfo.mintick : custom) : na
=> na
// NEW: Gap helpers
f_gap_ok_left(p1Abs, p2Abs) =>
not na(p1Abs) and not na(p2Abs) and (p2Abs - p1Abs) >= minGapBars
f_gap_ok_right(p3Abs, p2Abs) =>
not na(p3Abs) and not na(p2Abs) and (p3Abs - p2Abs) >= minGapBars
//──────────────────────────────── yelow group (EMA200 + 5up/5down) ───────────────────
= f_core_src(close, emaLen200)
phi_adj = 1.38196601
float fiveUp_200 = na(mid200) or na(dev200) or na(lm200) ? na : mid200 + (lm200 * phi_adj) * dev200
float fiveDown_200 = na(mid200) or na(dev200) or na(lm200) ? na : mid200 - (lm200 * phi_adj) * dev200
plot(show200_5d ? fiveDown_200 : na, title="yelow group down", color=col5band, linewidth=3)
plot(show200Mid ? mid200 : na, title="big brown", color=colMid200, linewidth=3)
plot(show200_5u ? fiveUp_200 : na, title="yelow group up", color=col5band, linewidth=3)
//──────────────────────────────── blue group (EMA85 — 4 up/down) ────────────────────
= f_core(emaLen85)
float up4_85 = na(mid85) or na(dev85) or na(lm85) ? na : mid85 + lm85 * dev85
float down4_85 = na(mid85) or na(dev85) or na(lm85) ? na : mid85 - lm85 * dev85
float fiveUp_85 = na(mid85) or na(dev85) or na(lm85) ? na : mid85 + (lm85 * phi_adj) * dev85
float fiveDown_85 = na(mid85) or na(dev85) or na(lm85) ? na : mid85 - (lm85 * phi_adj) * dev85
plot(show85_4u ? up4_85 : na, title="blue group up", color=col85_4, linewidth=2)
plot(show85_4d ? down4_85 : na, title="blue group down", color=col85_4, linewidth=2)
// big blue (EMA35)
float ema35 = useClose35 ? ta.ema(close, emaLen35) : ta.ema(effClose, emaLen35)
plot(showEMA35 ? ema35 : na, title="big blue", color=col35, linewidth=2)
// pn (PNR)
float pnr = na
if bar_index >= pnrLen - 1
float win = array.new_float()
for i = 0 to pnrLen - 1
array.push(win, pnrSrc )
array.sort(win)
float rankF = (pnrPerc / 100.0) * (pnrLen - 1)
int idx = int(math.round(rankF))
idx := math.max(0, math.min(idx, pnrLen - 1))
pnr := array.get(win, idx)
plot(showPNR ? pnr : na, title="pn", color=colPNR, linewidth=2)
//──────────────────────────────── Masked EMA Clouds (line 1–5) ───────────────────────
groupCloud = "line clouds"
showClouds = input.bool(true, "show lines clouds", group=groupCloud)
l1Len = input.int(5, "line 1 length", minval=1, group=groupCloud)
l2Len = input.int(8, "line 2 length", minval=1, group=groupCloud)
l3Len = input.int(21, "line 3 length", minval=1, group=groupCloud)
l4Len = input.int(34, "line 4 length", minval=1, group=groupCloud)
l5Len = input.int(50, "line 5 length", minval=1, group=groupCloud)
cloudUpColor = input.color(color.green, "cloud up color", group=groupCloud)
cloudDnColor = input.color(color.red, "cloud down color", group=groupCloud)
cloudTransp = input.int(60, "cloud transparency (0–100)", minval=0, maxval=100, group=groupCloud)
l1 = ta.ema(close, l1Len)
l2 = ta.ema(close, l2Len)
l3 = ta.ema(close, l3Len)
l4 = ta.ema(close, l4Len)
l5 = ta.ema(close, l5Len)
// พล็อตเส้นพราง (transp=100) และใช้ชื่อ line 1..5
p1 = plot(showClouds ? l1 : na, color=color.new(color.gray, 100), style=plot.style_line, linewidth=1, title="line 1")
p2 = plot(showClouds ? l2 : na, color=color.new(color.gray, 100), style=plot.style_line, linewidth=1, title="line 2")
p3 = plot(showClouds ? l3 : na, color=color.new(color.gray, 100), style=plot.style_line, linewidth=1, title="line 3")
p4 = plot(showClouds ? l4 : na, color=color.new(color.gray, 100), style=plot.style_line, linewidth=1, title="line 4")
p5 = plot(showClouds ? l5 : na, color=color.new(color.gray, 100), style=plot.style_line, linewidth=1, title="line 5")
// เรียก fill ที่ "global scope" แล้วคุมการแสดงผลด้วยสี (ถ้าไม่โชว์ให้ทำเป็นโปร่งใส)
cloud23Color = showClouds ? (l2 > l3 ? color.new(cloudUpColor, cloudTransp) : color.new(cloudDnColor, cloudTransp)) : color.new(color.black, 100)
cloud45Color = showClouds ? (l4 > l5 ? color.new(cloudUpColor, cloudTransp) : color.new(cloudDnColor, cloudTransp)) : color.new(color.black, 100)
fill(p2, p3, color=cloud23Color, title="cloud 2–3")
fill(p4, p5, color=cloud45Color, title="cloud 4–5")
//──────────────────────────────── Utilities ───────────────────────────────
isGreen_at(i) => close > open
isRed_at(i) => close < open
bodyTop_at(i) => f_bodyTop(open , close )
f_frac_body_above_line(i, lineV) =>
float bt = bodyTop_at(i), bb = f_bodyBot(open , close )
float body = bt - bb
body <= 0 or na(lineV) ? 0.0 : math.max(0.0, bt - math.max(bb, lineV)) / body
f_frac_body_below_line(i, lineV) =>
float bt = bodyTop_at(i), bb = f_bodyBot(open , close )
float body = bt - bb
body <= 0 or na(lineV) ? 0.0 : math.max(0.0, math.min(bt, lineV) - bb) / body
// Draw helpers
var box PBOXES = array.new_box()
var label PLABELS = array.new_label()
f_delete_boxes(box arr) =>
int n = array.size(arr)
for k = 0 to n - 1
int i = n - 1 - k
box.delete(array.get(arr, i))
array.clear(arr)
f_delete_labels(label arr) =>
int n = array.size(arr)
for k = 0 to n - 1
int i = n - 1 - k
label.delete(array.get(arr, i))
array.clear(arr)
// size mapper
f_lbl_size(s) =>
s == "tiny" ? size.tiny : s == "large" ? size.large : s == "normal" ? size.normal : size.small
// helper: one-line label.new
f_make_label(_x, _y, _text, _placeAbove) =>
label.new(_x, _y, _text, xloc=xloc.bar_time, style=(_placeAbove ? label.style_label_down : label.style_label_up), textcolor=PLabelTextColor, color=color.new(PLabelBgColor, lblBgTransp), size=f_lbl_size(lblSizeSel))
// smarter label placement (split LONG/SHORT) → return handles
f_add_label_ret(_abs, _text, _isLong) =>
label lb = na
int off = bar_index - _abs
if off >= 0 and off <= 5000 and not na(time ) and not na(high ) and not na(low )
float pad = lblOffsetMet == OM_TICKS ? (syminfo.mintick * lblTicks) : (ta.atr(lblAtrLen) * lblAtrMult)
string opt = _isLong ? lblPlaceLong : lblPlaceShort
bool placeAbove = (opt == LP_ABOVE) ? true : (opt == LP_BELOW) ? false : (close >= open )
float yPos = placeAbove ? (high + pad) : (low - pad)
lb := f_make_label(time , yPos, _text, placeAbove)
array.push(PLABELS, lb)
if array.size(PLABELS) > 500
label.delete(array.get(PLABELS, 0))
array.remove(PLABELS, 0)
lb
// draw mark → return
f_draw_mark_group(_abs, _full, _boxCol, _fillT, _borderT, _labelOn, _labelText, _isLong) =>
box nb = na
label lb = na
if not na(_abs)
int off = bar_index - _abs
if off >= 0 and off <= 5000
float top = _full ? high : bodyTop_at(off)
float bot = _full ? low : f_bodyBot(open , close )
if showBodyBoxes
nb := box.new(math.max(0, int(_abs) - 1), math.max(top, bot), int(_abs), math.min(top, bot), xloc=xloc.bar_index, bgcolor=color.new(_boxCol, _fillT), border_color=color.new(_boxCol, _borderT))
array.push(PBOXES, nb)
if array.size(PBOXES) > 500
box.delete(array.get(PBOXES, 0))
array.remove(PBOXES, 0)
if _labelOn
lb := f_add_label_ret(_abs, _labelText, _isLong)
//───────────────────── De-dup helpers (keep latest; delete older within window) ─────
f_del_if_exists(_bx, _lb) =>
if not na(_bx)
box.delete(_bx)
if not na(_lb)
label.delete(_lb)
// Strict int for last Abs to avoid NA-type errors
var int L_lastP1Abs = int(na)
var int L_lastP2Abs = int(na)
var int L_lastP3Abs = int(na)
var int S_lastP1Abs = int(na)
var int S_lastP2Abs = int(na)
var int S_lastP3Abs = int(na)
// IMPORTANT: declare one per line to keep type info on all variables
var box L_lastP1Box = na
var box L_lastP2Box = na
var box L_lastP3Box = na
var box S_lastP1Box = na
var box S_lastP2Box = na
var box S_lastP3Box = na
var label L_lastP1Lbl = na
var label L_lastP2Lbl = na
var label L_lastP3Lbl = na
var label S_lastP1Lbl = na
var label S_lastP2Lbl = na
var label S_lastP3Lbl = na
// >>> NEW: true-last P2 trackers (separate from de-dup) <<<
var int L_prevP2Abs = int(na)
var float L_prevP2Close = na
var int S_prevP2Abs = int(na)
var float S_prevP2Close = na
// enforce unique per type & side
f_enforce_and_set(_newAbs, _newBox, _newLbl, _lastAbs, _lastBox, _lastLbl) =>
bool keepNew = true
int lastAbsNew = _lastAbs
box lastBoxNew = _lastBox
label lastLblNew = _lastLbl
if not na(_lastAbs) and math.abs(_newAbs - _lastAbs) <= dedupWinBars
if _newAbs > _lastAbs
f_del_if_exists(_lastBox, _lastLbl)
lastAbsNew := _newAbs
lastBoxNew := _newBox
lastLblNew := _newLbl
else
f_del_if_exists(_newBox, _newLbl)
keepNew := false
else
lastAbsNew := _newAbs
lastBoxNew := _newBox
lastLblNew := _newLbl
//──────────────────────────────── FE helpers ───────────────────────────────
f_rt(v) => roundToTick ? math.round(v / syminfo.mintick) * syminfo.mintick : v
var line FE_l95 = array.new_line()
var line FE_l105 = array.new_line()
var line FE_l161 = array.new_line()
var line FE_l261 = array.new_line()
var line FE_l361 = array.new_line()
var line FE_l461 = array.new_line()
var linefill FE_fill = array.new_linefill()
var int FE_born = array.new_int()
f_delete_fe_index(idx) =>
int nAll = array.size(FE_born)
if idx >= 0 and idx < nAll
if idx < array.size(FE_fill)
linefill.delete(array.get(FE_fill, idx))
if idx < array.size(FE_l95)
line.delete(array.get(FE_l95, idx))
if idx < array.size(FE_l105)
line.delete(array.get(FE_l105, idx))
if idx < array.size(FE_l161)
line.delete(array.get(FE_l161, idx))
if idx < array.size(FE_l261)
line.delete(array.get(FE_l261, idx))
if idx < array.size(FE_l361)
line.delete(array.get(FE_l361, idx))
if idx < array.size(FE_l461)
line.delete(array.get(FE_l461, idx))
if idx < array.size(FE_l95)
array.remove(FE_l95, idx)
if idx < array.size(FE_l105)
array.remove(FE_l105, idx)
if idx < array.size(FE_l161)
array.remove(FE_l161, idx)
if idx < array.size(FE_l261)
array.remove(FE_l261, idx)
if idx < array.size(FE_l361)
array.remove(FE_l361, idx)
if idx < array.size(FE_l461)
array.remove(FE_l461, idx)
if idx < array.size(FE_fill)
array.remove(FE_fill, idx)
array.remove(FE_born, idx)
f_clear_all_fe() =>
int n = array.size(FE_born)
for k = 0 to n - 1
int i = n - 1 - k
f_delete_fe_index(i)
// ───────────── ADD: helper แปลง bar-abs → time (ms) ─────────────
f_abs_to_time(_abs) =>
if na(_abs)
na
else
int off = bar_index - _abs
if off < 0
na
else
int tfms = timeframe.in_seconds(timeframe.period) * 1000
off <= 5000 ? time : (time - off * tfms)
// ───────────── REPLACE: f_add_fe_set เดิม ด้วยเวอร์ชันกัน error ─────────────
f_add_fe_set(p3Abs, y95, y105, y161, y261, y361, y461) =>
int off = bar_index - p3Abs
bool useTime = off > 4500
int tfms = timeframe.in_seconds(timeframe.period) * 1000
color c95 = show95_105 ? colBand : color.new(colBand, 100)
color c105 = show95_105 ? colBand : color.new(colBand, 100)
color c161 = show1618 ? col1618 : color.new(col1618, 100)
color c261 = show2618 ? col2618 : color.new(col2618, 100)
color c361 = show3618 ? col3618 : color.new(col3618, 100)
color c461 = show4618 ? col4618 : color.new(col4618, 100)
// <<< แก้ไขตรงนี้: ประกาศตัวแปร line ทีละบรรทัด >>>
line l95 = na
line l105 = na
line l161 = na
line l261 = na
line l361 = na
line l461 = na
linefill lf = na
if not useTime
int x1 = p3Abs
int x2 = p3Abs + feLenBars
l95 := line.new(x1, y95, x2, y95, xloc=xloc.bar_index, extend=extend.none, color=c95, width=3)
l105 := line.new(x1, y105, x2, y105, xloc=xloc.bar_index, extend=extend.none, color=c105, width=3)
l161 := line.new(x1, y161, x2, y161, xloc=xloc.bar_index, extend=extend.none, color=c161, width=2)
l261 := line.new(x1, y261, x2, y261, xloc=xloc.bar_index, extend=extend.none, color=c261, width=2)
l361 := line.new(x1, y361, x2, y361, xloc=xloc.bar_index, extend=extend.none, color=c361, width=2)
l461 := line.new(x1, y461, x2, y461, xloc=xloc.bar_index, extend=extend.none, color=c461, width=2)
lf := linefill.new(l95, l105, color= show95_105 ? colBandFill : color.new(color.black, 100))
else
int t1 = f_abs_to_time(p3Abs)
int t2 = int(na)
if not na(t1)
t2 := t1 + feLenBars * tfms
l95 := line.new(t1, y95, t2, y95, xloc=xloc.bar_time, extend=extend.none, color=c95, width=3)
l105 := line.new(t1, y105, t2, y105, xloc=xloc.bar_time, extend=extend.none, color=c105, width=3)
l161 := line.new(t1, y161, t2, y161, xloc=xloc.bar_time, extend=extend.none, color=c161, width=2)
l261 := line.new(t1, y261, t2, y261, xloc=xloc.bar_time, extend=extend.none, color=c261, width=2)
l361 := line.new(t1, y361, t2, y361, xloc=xloc.bar_time, extend=extend.none, color=c361, width=2)
l461 := line.new(t1, y461, t2, y461, xloc=xloc.bar_time, extend=extend.none, color=c461, width=2)
lf := linefill.new(l95, l105, color= show95_105 ? colBandFill : color.new(color.black, 100))
array.push(FE_l95, l95)
array.push(FE_l105, l105)
array.push(FE_l161, l161)
array.push(FE_l261, l261)
array.push(FE_l361, l361)
array.push(FE_l461, l461)
array.push(FE_fill, lf)
array.push(FE_born, bar_index)
f_find_abs_by_time(t) =>
int bestAbs = na
if na(t)
na
else
int maxBack = math.min(5000, bar_index)
int bestDiff = 1000000000
for i = 0 to maxBack
int ti = time
int diff = ti > t ? (ti - t) : (t - ti)
if diff < bestDiff
bestDiff := diff
bestAbs := bar_index - i
bestAbs
//──────────────────────────────── P3 picker (แบบเดิม/คลาสสิก) ─────────────────────
f_pickP3_abs(sAbs, eAbs, isLong) =>
if na(sAbs) or na(eAbs)
else
int eInit = math.min(eAbs, bar_index)
int sInit = sAbs
int s = math.max(sInit, bar_index - 10000)
int e = eInit
if s > e
else
float levels = array.new_float()
int counts = array.new_int()
int firstI = array.new_int()
int maxRun = array.new_int()
float prevBin = na
int curRun = 0
float minLowGreen = 1e100
int minLowGreenI = na
float minLowRed = 1e100
int minLowRedI = na
float minLowAll = 1e100
int minLowAllI = na
float maxHighRed = -1e100
int maxHighRedI = na
float maxHighGreen = -1e100
int maxHighGreenI= na
float maxHighAll = -1e100
int maxHighAllI = na
for t = s to e
int tOff = bar_index - t
if tOff < 0 or tOff > 10000
continue
float bin = math.round(open / syminfo.mintick) * syminfo.mintick
int idx = array.indexof(levels, bin)
if idx == -1
array.push(levels, bin)
array.push(counts, 1)
array.push(firstI, t)
array.push(maxRun, 1)
curRun := 1
else
array.set(counts, idx, array.get(counts, idx) + 1)
if not na(prevBin) and bin == prevBin
curRun += 1
else
curRun := 1
int prevMax = array.get(maxRun, idx)
if curRun > prevMax
array.set(maxRun, idx, curRun)
prevBin := bin
// ... (ส่วนท้ายของ f_pickP3_abs เดิม)
int needCnt = 2
int best = -1, bestCnt = 0, bestRun = 0, bestFirst = 1000000000
int L = array.size(levels)
if L > 0
for m = 0 to L - 1
int c = array.get(counts, m)
if c >= needCnt
int r = array.get(maxRun, m)
int f = array.get(firstI, m)
if c > bestCnt or (c == bestCnt and (r > bestRun or (r == bestRun and f < bestFirst)))
best := m
bestCnt := c
bestRun := r
bestFirst := f
if best != -1
int pickAbs = array.get(firstI, best)
float pickPx = array.get(levels, best)
else
if isLong
// เลือกจาก logic เดิม (ย่อ)
float minLowGreen = 1e100
int minLowGreenI = na
float minLowRed = 1e100
int minLowRedI = na
float minLowAll = 1e100
int minLowAllI = na
for t2 = s to e
int toff2 = bar_index - t2
if toff2 < 0 or toff2 > 10000
continue
bool g = close > open
bool r = close < open
if g and low < minLowGreen
minLowGreen := low
minLowGreenI := t2
if r and low < minLowRed
minLowRed := low
minLowRedI := t2
if low < minLowAll
minLowAll := low
minLowAllI := t2
bool redIsGlobalMin = not na(minLowRedI) and (minLowRed <= minLowAll + 0.0)
if redIsGlobalMin
int offR = bar_index - minLowRedI
[close , minLowRedI]
else
int useAbs = na(minLowGreenI) ? minLowAllI : minLowGreenI
int offU = bar_index - useAbs
[open , useAbs]
else
float maxHighRed = -1e100
int maxHighRedI = na
float maxHighGreen = -1e100
int maxHighGreenI= na
float maxHighAll = -1e100
int maxHighAllI = na
for t3 = s to e
int toff3 = bar_index - t3
if toff3 < 0 or toff3 > 10000
continue
bool g2 = close > open
bool r2 = close < open
if r2 and high > maxHighRed
maxHighRed := high
maxHighRedI := t3
if g2 and high > maxHighGreen
maxHighGreen := high
maxHighGreenI:= t3
if high > maxHighAll
maxHighAll := high
maxHighAllI := t3
bool greenIsGlobalMax = not na(maxHighGreenI) and (maxHighGreen >= maxHighAll - 0.0)
if greenIsGlobalMax
int offG = bar_index - maxHighGreenI
[close , maxHighGreenI]
else
int useAbsS = na(maxHighRedI) ? maxHighAllI : maxHighRedI
int offS = bar_index - useAbsS
[open , useAbsS]
//──────────────────────────────── P1/P2/P3 (Auto; state) ────────────────
// LONG state vars
var int L_P1Abs = int(na)
var int L_P2Abs = int(na)
var int L_P3Abs = int(na)
var int L_winOpenAbs = int(na)
var float L_P1Open = na
var float L_P2Close = na
var float L_P3Px = na
var float L_P2_bodyTop = na
var float L_P2_bodyBot = na
// SHORT state vars
var int S_P1Abs = int(na)
var int S_P2Abs = int(na)
var int S_P3Abs = int(na)
var int S_winOpenAbs = int(na)
var float S_P1Open = na
var float S_P2Close = na
var float S_P3Px = na
var float S_P2_bodyTop = na
var float S_P2_bodyBot = na
// draw-set containers
var box L_SET_BOX = array.new_box()
var label L_SET_LBL = array.new_label()
var box S_SET_BOX = array.new_box()
var label S_SET_LBL = array.new_label()
// scanners
var bool L_seek = false
var bool L_confirmActive = false
var int L_runMaxAbs = int(na)
var float L_runMaxClose = na
var int L_candAbs = int(na)
var float L_candClose = na
var bool S_seek = false
var bool S_confirmActive = false
var int S_runMinAbs = int(na)
var float S_runMinClose = na
var int S_candAbs = int(na)
var float S_candClose = na
// LONG: seed/confirm P2 (UPDATED: ต้องทั้งแท่งอยู่เหนือ fiveUp_200)
if not L_seek and not L_confirmActive
float __btL = math.max(open, close)
float __bbL = math.min(open, close)
float __fiveL = fiveUp_200
bool startLongSeed = close > open and not na(__fiveL) and (__bbL >= __fiveL)
if startLongSeed
L_seek := true
L_runMaxAbs := bar_index
L_runMaxClose := close
if L_confirmActive
if close > L_candClose and close > open
L_seek := true
L_confirmActive := false
L_candAbs := int(na)
L_candClose := na
L_runMaxAbs := bar_index
L_runMaxClose := close
else if bar_index >= L_candAbs + rightWinBars
bool acceptL = true
// ตรวจซ้ำที่แท่งผู้สมัคร (ทั้งแท่งต้องอยู่เหนือ fiveUp_200)
int offCandL = bar_index - L_candAbs
float _btL = math.max(open , close )
float _bbL = math.min(open , close )
float _fiveL = fiveUp_200
bool bodyAbove5 = not na(_fiveL) and (_bbL >= _fiveL)
acceptL := acceptL and bodyAbove5
if not na(L_prevP2Abs)
int dBarsL = L_candAbs - L_prevP2Abs
if dBarsL <= p2NewWithinBars
acceptL := acceptL and (L_candClose > L_prevP2Close)
if not acceptL
L_seek := true
L_confirmActive := false
L_runMaxAbs := bar_index
L_runMaxClose := close
L_candAbs := int(na)
L_candClose := na
else
array.clear(L_SET_BOX)
array.clear(L_SET_LBL)
L_P2Abs := L_candAbs
resetReqAllL := false
resetReqP1L := false
resetReqP2L := false
resetReqP3L := false
int offP2 = bar_index - L_P2Abs
L_P2Close := close
L_P2_bodyTop := math.max(open , close )
L_P2_bodyBot := math.min(open , close )
L_prevP2Abs := L_P2Abs
L_prevP2Close := L_P2Close
= f_draw_mark_group(L_P2Abs, false, P2BoxColor, P2BoxFillTransp, BoxBorderTransp, showP2Label, "P2", true)
= f_enforce_and_set(L_P2Abs, bxP2, lbP2, L_lastP2Abs, L_lastP2Box, L_lastP2Lbl)
if keepNewP2L
L_lastP2Abs := _newAbsP2L
L_lastP2Box := _newBoxP2L
L_lastP2Lbl := _newLblP2L
f_del_if_exists(L_lastP3Box, L_lastP3Lbl)
L_lastP3Abs := int(na)
L_lastP3Box := na
L_lastP3Lbl := na
L_P3Abs := int(na)
L_P3Px := na
f_clear_all_fe()
L_winOpenAbs := L_P2Abs + 1
int bestAbs = int(na)
float bestDist = na
for k = 1 to 50
int a = L_P2Abs - k
if a < 0
break
int off = bar_index - a
if off < 0 or off > 5000
continue
if close <= open
continue
float ema5u85 = fiveUp_85
if na(ema5u85)
continue
float bt = math.max(open , close )
float bb = math.min(open , close )
float body = bt - bb
float fracAbove = body <= 0 ? 0.0 : math.max(0.0, bt - math.max(bb, ema5u85))/body
if fracAbove >= 0.25
float d = math.abs(mid200 - (bt+bb)/2.0)
if na(bestDist) or d < bestDist or (d == bestDist and (na(bestAbs) or a < bestAbs))
bestDist := d
bestAbs := a
if not na(bestAbs) and f_gap_ok_left(bestAbs, L_P2Abs)
int offb = bar_index - bestAbs
L_P1Open := open
L_P1Abs := bestAbs
= f_draw_mark_group(L_P1Abs, false, P1BoxColor, P1BoxFillTransp, BoxBorderTransp, showP1Label, "P1", true)
= f_enforce_and_set(L_P1Abs, bxP1, lbP1, L_lastP1Abs, L_lastP1Box, L_lastP1Lbl)
if keepNewP1L
L_lastP1Abs := _newAbsP1L
L_lastP1Box := _newBoxP1L
L_lastP1Lbl := _newLblP1L
L_seek := false
L_confirmActive := false
L_candAbs := int(na)
L_candClose := na
L_runMaxAbs := int(na)
L_runMaxClose := na
if L_seek and not L_confirmActive
if close > open
if close > nz(L_runMaxClose, -1e100)
L_runMaxClose := close
L_runMaxAbs := bar_index
else if close < nz(L_runMaxClose, 1e100)
L_candAbs := L_runMaxAbs
L_candClose := L_runMaxClose
L_seek := false
L_confirmActive := true
else if open < nz(L_runMaxClose, 1e100)
L_candAbs := L_runMaxAbs
L_candClose := L_runMaxClose
L_seek := false
L_confirmActive := true
// SHORT: seed/confirm P2 (UPDATED: ต้องทั้งแท่งอยู่ใต้ fiveDown_200)
if not S_seek and not S_confirmActive
float __btS = math.max(open, close)
float __bbS = math.min(open, close)
float __fiveS = fiveDown_200
bool startShortSeed = close < open and not na(__fiveS) and (__btS <= __fiveS)
if startShortSeed
S_seek := true
S_runMinAbs := bar_index
S_runMinClose := close
if S_confirmActive
if close < S_candClose and close < open
S_seek := true
S_confirmActive := false
S_candAbs := int(na)
S_candClose := na
S_runMinAbs := bar_index
S_runMinClose := close
else if bar_index >= S_candAbs + rightWinBars
bool acceptS = true
// ตรวจซ้ำที่แท่งผู้สมัคร (ทั้งแท่งต้องอยู่ใต้ fiveDown_200)
int offCandS = bar_index - S_candAbs
float _btS = math.max(open , close )
float _bbS = math.min(open , close )
float _fiveS = fiveDown_200
bool bodyBelow5 = not na(_fiveS) and (_btS <= _fiveS)
acceptS := acceptS and bodyBelow5
if not na(S_prevP2Abs)
int dBarsS = S_candAbs - S_prevP2Abs
if dBarsS <= p2NewWithinBars
acceptS := acceptS and (S_candClose < S_prevP2Close)
if not acceptS
S_seek := true
S_confirmActive := false
S_runMinAbs := bar_index
S_runMinClose := close
S_candAbs := int(na)
S_candClose := na
else
array.clear(S_SET_BOX)
array.clear(S_SET_LBL)
S_P2Abs := S_candAbs
resetReqAllS := false
resetReqP1S := false
resetReqP2S := false
resetReqP3S := false
int offP2s = bar_index - S_P2Abs
S_P2Close := close
S_P2_bodyTop := math.max(open , close )
S_P2_bodyBot := math.min(open , close )
S_prevP2Abs := S_P2Abs
S_prevP2Close := S_P2Close
= f_draw_mark_group(S_P2Abs, false, P2BoxColor, P2BoxFillTransp, BoxBorderTransp, showP2Label, "P2", false)
= f_enforce_and_set(S_P2Abs, bxP2s, lbP2s, S_lastP2Abs, S_lastP2Box, S_lastP2Lbl)
if keepNewP2S
S_lastP2Abs := _newAbsP2S
S_lastP2Box := _newBoxP2S
S_lastP2Lbl := _newLblP2S
f_del_if_exists(S_lastP3Box, S_lastP3Lbl)
S_lastP3Abs := int(na)
S_lastP3Box := na
S_lastP3Lbl := na
S_P3Abs := int(na)
S_P3Px := na
f_clear_all_fe()
S_winOpenAbs := S_P2Abs + 1
int bestAbsS = int(na)
float bestDistS = na
for k = 1 to 50
int a = S_P2Abs - k
if a < 0
break
int off = bar_index - a
if off < 0 or off > 5000
continue
if close >= open
continue
float ema5d85 = fiveDown_85
if na(ema5d85)
continue
float bt = math.max(open , close )
float bb = math.min(open , close )
float body = bt - bb
float fracBelow = body <= 0 ? 0.0 : math.max(0.0, math.min(bt, ema5d85) - bb)/body
if fracBelow >= 0.25
float d = math.abs(mid200 - (bt+bb)/2.0)
if na(bestDistS) or d < bestDistS or (d == bestDistS and (na(bestAbsS) or a < bestAbsS))
bestDistS := d
bestAbsS := a
if not na(bestAbsS) and f_gap_ok_left(bestAbsS, S_P2Abs)
int offb = bar_index - bestAbsS
S_P1Open := open
S_P1Abs := bestAbsS
= f_draw_mark_group(S_P1Abs, false, P1BoxColor, P1BoxFillTransp, BoxBorderTransp, showP1Label, "P1", false)
= f_enforce_and_set(S_P1Abs, bxP1s, lbP1s, S_lastP1Abs, S_lastP1Box, S_lastP1Lbl)
if keepNewP1S
S_lastP1Abs := _newAbsP1S
S_lastP1Box := _newBoxP1S
S_lastP1Lbl := _newLblP1S
S_seek := false
S_confirmActive := false
S_candAbs := int(na)
S_candClose := na
S_runMinAbs := int(na)
S_runMinClose := na
if S_seek and not S_confirmActive
if close < open
if close < nz(S_runMinClose, 1e100)
S_runMinClose := close
S_runMinAbs := bar_index
else if close > nz(S_runMinClose, -1e100)
S_candAbs := S_runMinAbs
S_candClose := S_runMinClose
S_seek := false
S_confirmActive := true
else if open > nz(S_runMinClose, -1e100)
S_candAbs := S_runMinAbs
S_candClose := S_runMinClose
S_seek := false
S_confirmActive := true
// ---------- LONG: close P3 window (classic picker) ----------
if not na(L_winOpenAbs)
int sAbs = L_winOpenAbs
int eAbs = bar_index
float rangeBody = L_P2_bodyTop - L_P2_bodyBot
float T33 = L_P2_bodyBot + rangeBody/3.0
float T75 = L_P2_bodyBot + rangeBody*0.75
int barsInWin = bar_index - L_winOpenAbs + 1
bool allowNormal = barsInWin >= 5 and close > open and close >= T33
bool allowEarly = barsInWin < 5 and close > open and close >= T75
if allowNormal or allowEarly
= f_pickP3_abs(sAbs, eAbs, true)
if not na(p3AbsL) and f_gap_ok_right(p3AbsL, L_P2Abs)
L_P3Abs := p3AbsL
L_P3Px := p3PxL_tmp
= f_draw_mark_group(L_P3Abs, false, P3BoxColor, P3BoxFillTransp, BoxBorderTransp, showP3Label, "P3", true)
= f_enforce_and_set(L_P3Abs, bxP3, lbP3, L_lastP3Abs, L_lastP3Box, L_lastP3Lbl)
if keepNewP3L
L_lastP3Abs := _newAbsP3L
L_lastP3Box := _newBoxP3L
L_lastP3Lbl := _newLblP3L
if showFE and not na(L_P1Open) and not na(L_P2Close)
float W = L_P2Close - L_P1Open
if W > 0
float y95 = f_rt(L_P3Px + 0.95 * W)
float y105 = f_rt(L_P3Px + 1.05 * W)
float y1618 = f_rt(L_P3Px + 1.618 * W)
float y2618 = f_rt(L_P3Px + 2.618 * W)
float y3618 = f_rt(L_P3Px + 3.618 * W)
float y4618 = f_rt(L_P3Px + 4.618 * W)
f_clear_all_fe()
f_add_fe_set(L_P3Abs, y95, y105, y1618, y2618, y3618, y4618)
L_winOpenAbs := int(na)
// ---------- SHORT: close P3 window (classic picker) ----------
if not na(S_winOpenAbs)
int sAbsS = S_winOpenAbs
int eAbsS = bar_index
float rangeBodyS = S_P2_bodyTop - S_P2_bodyBot
float T33d = S_P2_bodyTop - rangeBodyS/3.0
float T75d = S_P2_bodyTop - rangeBodyS*0.75
int barsInWinS = bar_index - S_winOpenAbs + 1
bool allowNormalS = barsInWinS >= 5 and close < open and close <= T33d
bool allowEarlyS = barsInWinS < 5 and close < open and close <= T75d
if allowNormalS or allowEarlyS
= f_pickP3_abs(sAbsS, eAbsS, false)
if not na(p3AbsS) and f_gap_ok_right(p3AbsS, S_P2Abs)
S_P3Abs := p3AbsS
S_P3Px := p3PxS_tmp
= f_draw_mark_group(S_P3Abs, false, P3BoxColor, P3BoxFillTransp, BoxBorderTransp, showP3Label, "P3", false)
= f_enforce_and_set(S_P3Abs, bxP3s, lbP3s, S_lastP3Abs, S_lastP3Box, S_lastP3Lbl)
if keepNewP3S
S_lastP3Abs := _newAbsP3S
S_lastP3Box := _newBoxP3S
S_lastP3Lbl := _newLblP3S
if showFE and not na(S_P1Open) and not na(S_P2Close)
float Ws = S_P2Close - S_P1Open
if Ws < 0
float y95s = f_rt(S_P3Px + 0.95 * Ws)
float y105s = f_rt(S_P3Px + 1.05 * Ws)
float y1618s = f_rt(S_P3Px + 1.618 * Ws)
float y2618s = f_rt(S_P3Px + 2.618 * Ws)
float y3618s = f_rt(S_P3Px + 3.618 * Ws)
float y4618s = f_rt(S_P3Px + 4.618 * Ws)
f_clear_all_fe()
f_add_fe_set(S_P3Abs, y95s, y105s, y1618s, y2618s, y3618s, y4618s)
S_winOpenAbs := int(na)
//──────────────────────────────── Manual Layer (+ Reset Latches) ─────────────────────
f_pick_abs_from_manual(_use, _pickMode, _time, _offset) =>
if not _use
na
else
_pickMode == PK_TIME ? f_find_abs_by_time(_time) : (bar_index + _offset)
f_pick_price_from_manual(_use, _abs, _pmode, _custom) =>
if not _use or na(_abs)
na
else
int off = bar_index - _abs
off < 0 or off > 5000 ? na : f_price_by_mode(off, _pmode, _custom)
useP1L_eff = useManP1L and not (resetReqAllL or resetReqP1L)
useP2L_eff = useManP2L and not (resetReqAllL or resetReqP2L)
useP3L_eff = useManP3L and not (resetReqAllL or resetReqP3L)
useP1S_eff = useManP1S and not (resetReqAllS or resetReqP1S)
useP2S_eff = useManP2S and not (resetReqAllS or resetReqP2S)
useP3S_eff = useManP3S and not (resetReqAllS or resetReqP3S)
// Effective ABS
int L_P1Abs_eff = useP1L_eff ? f_pick_abs_from_manual(useP1L_eff, pickP1L, manP1L_t, manP1L_of) : L_P1Abs
int L_P2Abs_eff = useP2L_eff ? f_pick_abs_from_manual(useP2L_eff, pickP2L, manP2L_t, manP2L_of) : L_P2Abs
int L_P3Abs_eff = useP3L_eff ? f_pick_abs_from_manual(useP3L_eff, pickP3L, manP3L_t, manP3L_of) : L_P3Abs
int S_P1Abs_eff = useP1S_eff ? f_pick_abs_from_manual(useP1S_eff, pickP1S, manP1S_t, manP1S_of) : S_P1Abs
int S_P2Abs_eff = useP2S_eff ? f_pick_abs_from_manual(useP2S_eff, pickP2S, manP2S_t, manP2S_of) : S_P2Abs
int S_P3Abs_eff = useP3S_eff ? f_pick_abs_from_manual(useP3S_eff, pickP3S, manP3S_t, manP3S_of) : S_P3Abs
// Effective Prices
float L_P1Open_eff = useP1L_eff ? f_pick_price_from_manual(useP1L_eff, L_P1Abs_eff, pmP1L, p1L_custom) : L_P1Open
float L_P2Close_eff = useP2L_eff ? f_pick_price_from_manual(useP2L_eff, L_P2Abs_eff, pmP2L, p2L_custom) : L_P2Close
float L_P3Px_eff = useP3L_eff ? f_pick_price_from_manual(useP3L_eff, L_P3Abs_eff, pmP3L, p3L_custom) : L_P3Px
float S_P1Open_eff = useP1S_eff ? f_pick_price_from_manual(useP1S_eff, S_P1Abs_eff, pmP1S, p1S_custom) : S_P1Open
float S_P2Close_eff = useP2S_eff ? f_pick_price_from_manual(useP2S_eff, S_P2Abs_eff, pmP2S, p2S_custom) : S_P2Close
float S_P3Px_eff = useP3S_eff ? f_pick_price_from_manual(useP3S_eff, S_P3Abs_eff, pmP3S, p3S_custom) : S_P3Px
// Redraw labels/boxes if manual in effect (apply de-dup too) — with GAP RULE
bool needRedrawL = useP1L_eff or useP2L_eff or useP3L_eff
bool needRedrawS = useP1S_eff or useP2S_eff or useP3S_eff
if needRedrawL
f_delete_boxes(L_SET_BOX)
f_delete_labels(L_SET_LBL)
if not na(L_P1Abs_eff) and not na(L_P2Abs_eff) and f_gap_ok_left(L_P1Abs_eff, L_P2Abs_eff) and showP1Label
= f_draw_mark_group(L_P1Abs_eff, false, P1BoxColor, P1BoxFillTransp, BoxBorderTransp, true, "P1", true)
= f_enforce_and_set(L_P1Abs_eff, bx1, lb1, L_lastP1Abs, L_lastP1Box, L_lastP1Lbl)
if keepP1L_m
L_lastP1Abs := nAbsP1L_m
L_lastP1Box := nBoxP1L_m
L_lastP1Lbl := nLblP1L_m
if not na(L_P2Abs_eff) and showP2Label
= f_draw_mark_group(L_P2Abs_eff, false, P2BoxColor, P2BoxFillTransp, BoxBorderTransp, true, "P2", true)
= f_enforce_and_set(L_P2Abs_eff, bx2, lb2, L_lastP2Abs, L_lastP2Box, L_lastP2Lbl)
if keepP2L_m
L_lastP2Abs := nAbsP2L_m
L_lastP2Box := nBoxP2L_m
L_lastP2Lbl := nLblP2L_m
if not na(L_P3Abs_eff) and not na(L_P2Abs_eff) and f_gap_ok_right(L_P3Abs_eff, L_P2Abs_eff) and showP3Label
= f_draw_mark_group(L_P3Abs_eff, false, P3BoxColor, P3BoxFillTransp, BoxBorderTransp, true, "P3", true)
= f_enforce_and_set(L_P3Abs_eff, bx3, lb3, L_lastP3Abs, L_lastP3Box, L_lastP3Lbl)
if keepP3L_m
L_lastP3Abs := nAbsP3L_m
L_lastP3Box := nBoxP3L_m
L_lastP3Lbl := nLblP3L_m
if needRedrawS
f_delete_boxes(S_SET_BOX)
f_delete_labels(S_SET_LBL)
if not na(S_P1Abs_eff) and not na(S_P2Abs_eff) and f_gap_ok_left(S_P1Abs_eff, S_P2Abs_eff) and showP1Label
= f_draw_mark_group(S_P1Abs_eff, false, P1BoxColor, P1BoxFillTransp, BoxBorderTransp, true, "P1", false)
= f_enforce_and_set(S_P1Abs_eff, bx1s, lb1s, S_lastP1Abs, S_lastP1Box, S_lastP1Lbl)
if keepP1S_m
S_lastP1Abs := nAbsP1S_m
S_lastP1Box := nBoxP1S_m
S_lastP1Lbl := nLblP1S_m
if not na(S_P2Abs_eff) and showP2Label
= f_draw_mark_group(S_P2Abs_eff, false, P2BoxColor, P2BoxFillTransp, BoxBorderTransp, true, "P2", false)
= f_enforce_and_set(S_P2Abs_eff, bx2s, lb2s, S_lastP2Abs, S_lastP2Box, S_lastP2Lbl)
if keepP2S_m
S_lastP2Abs := nAbsP2S_m
S_lastP2Box := nBoxP2S_m
S_lastP2Lbl := nLblP2S_m
if not na(S_P3Abs_eff) and not na(S_P2Abs_eff) and f_gap_ok_right(S_P3Abs_eff, S_P2Abs_eff) and showP3Label
= f_draw_mark_group(S_P3Abs_eff, false, P3BoxColor, P3BoxFillTransp, BoxBorderTransp, true, "P3", false)
= f_enforce_and_set(S_P3Abs_eff, bx3s, lb3s, S_lastP3Abs, S_lastP3Box, S_lastP3Lbl)
if keepP3S_m
S_lastP3Abs := nAbsP3S_m
S_lastP3Box := nBoxP3S_m
S_lastP3Lbl := nLblP3S_m
// FE from effective points (Manual precedence) — add GAP RULE
bool canFE_L = showFE and not na(L_P1Open_eff) and not na(L_P2Close_eff) and not na(L_P3Px_eff) and not na(L_P1Abs_eff) and not na(L_P2Abs_eff) and not na(L_P3Abs_eff) and f_gap_ok_left(L_P1Abs_eff, L_P2Abs_eff) and f_gap_ok_right(L_P3Abs_eff, L_P2Abs_eff)
bool canFE_S = showFE and not na(S_P1Open_eff) and not na(S_P2Close_eff) and not na(S_P3Px_eff) and not na(S_P1Abs_eff) and not na(S_P2Abs_eff) and not na(S_P3Abs_eff) and f_gap_ok_left(S_P1Abs_eff, S_P2Abs_eff) and f_gap_ok_right(S_P3Abs_eff, S_P2Abs_eff)
if canFE_L
float W = L_P2Close_eff - L_P1Open_eff
if W > 0
float y95 = f_rt(L_P3Px_eff + 0.95 * W)
float y105 = f_rt(L_P3Px_eff + 1.05 * W)
float y1618 = f_rt(L_P3Px_eff + 1.618 * W)
float y2618 = f_rt(L_P3Px_eff + 2.618 * W)
float y3618 = f_rt(L_P3Px_eff + 3.618 * W)
float y4618 = f_rt(L_P3Px_eff + 4.618 * W)
f_clear_all_fe()
f_add_fe_set(L_P3Abs_eff, y95, y105, y1618, y2618, y3618, y4618)
else if canFE_S
float Ws = S_P2Close_eff - S_P1Open_eff
if Ws < 0
float y95s = f_rt(S_P3Px_eff + 0.95 * Ws)
float y105s = f_rt(S_P3Px_eff + 1.05 * Ws)
float y1618s = f_rt(S_P3Px_eff + 1.618 * Ws)
float y2618s = f_rt(S_P3Px_eff + 2.618 * Ws)
float y3618s = f_rt(S_P3Px_eff + 3.618 * Ws)
float y4618s = f_rt(S_P3Px_eff + 4.618 * Ws)
f_clear_all_fe()
f_add_fe_set(S_P3Abs_eff, y95s, y105s, y1618s, y2618s, y3618s, y4618s)
// FE lifespan cleanup
int nBorn = array.size(FE_born)
if nBorn > 0
for k = 0 to nBorn - 1
int idx = nBorn - 1 - k
int born = array.get(FE_born, idx)
if bar_index - born > feLife
f_delete_fe_index(idx)
// Candle coloring
bool isP1_bar = (not na(L_P1Abs_eff) and bar_index == L_P1Abs_eff) or (not na(S_P1Abs_eff) and bar_index == S_P1Abs_eff)
bool isP2_bar = (not na(L_P2Abs_eff) and bar_index == L_P2Abs_eff) or (not na(S_P2Abs_eff) and bar_index == S_P2Abs_eff)
bool isP3_bar = (not na(L_P3Abs_eff) and bar_index == L_P3Abs_eff) or (not na(S_P3Abs_eff) and bar_index == S_P3Abs_eff)
color _candleCol = na
_candleCol := isP3_bar ? colP3Candle : (isP2_bar ? colP2Candle : (isP1_bar ? colP1Candle : na))
barcolor(recolorBars ? _candleCol : na)
// Reserve style slot
plot(showFE ? na : na, title="fe-slot")
//──────────────────────────────── di (DSI; masked) ───────────────────────────
float dsi_atr = ta.atr(14)
float dsi_highestBody = open > close ? open : close
float dsi_lowestBody = open > close ? close : open
var float dsi_res1 = na
var float dsi_res2 = na
var float dsi_sup1 = na
var float dsi_sup2 = na
var bool dsi_lookForNewResistance = true
var bool dsi_lookForNewSupport = true
var float dsi_prevRes1 = na
var float dsi_prevRes2 = na
var float dsi_prevSup1 = na
var float dsi_prevSup2 = na
var float dsi_atrSaved = na
var float dsi_potR1 = na
var float dsi_potR2 = na
var float dsi_potS1 = na
var float dsi_potS2 = na
if high == ta.highest(high, lookback) and high < high and dsi_lookForNewResistance
float r1 = high
float hb2 = (open > close ? open : close )
float hb1 = (open > close ? open : close )
float hb0 = (open > close ? open : close)
float r2 = hb2 > hb1 ? hb2 : (hb0 > hb1 ? hb0 : hb1)
if (r1 - r2) / dsi_atr <= maxZoneSize
dsi_lookForNewResistance := false
dsi_potR1 := r1
dsi_potR2 := r2
dsi_atrSaved := dsi_atr
if low == ta.lowest(low, lookback) and low > low and dsi_lookForNewSupport
float s1 = low
float lb2 = (open > close ? close : open )
float lb1 = (open > close ? close : open )
float lb0 = (open > close ? close : open)
float s2 = lb2 < lb1 ? lb2 : (lb0 < lb1 ? lb0 : lb1)
if (s2 - s1) / dsi_atr <= maxZoneSize
dsi_lookForNewSupport := false
dsi_potS1 := s1
dsi_potS2 := s2
dsi_atrSaved := dsi_atr
if close > dsi_potR1 and barstate.isconfirmed
dsi_potR1 := na
dsi_potR2 := na
if close < dsi_potS1 and barstate.isconfirmed
dsi_potS1 := na
dsi_potS2 := na
if not na(dsi_potR1) and dsi_potR1 - low >= (nz(dsi_atrSaved, dsi_atr) * atrMovement)
dsi_prevRes1 := na(dsi_prevRes1) ? dsi_potR1 : dsi_prevRes1
dsi_prevRes2 := na(dsi_prevRes2) ? dsi_potR2 : dsi_prevRes2
dsi_res1 := dsi_potR1
dsi_res2 := dsi_potR2
dsi_potR1 := na
dsi_potR2 := na
if not na(dsi_potS1) and high - dsi_potS1 >= (nz(dsi_atrSaved, dsi_atr) * atrMovement)
dsi_prevSup1 := na(dsi_prevSup1) ? dsi_potS1 : dsi_prevSup1
dsi_prevSup2 := na(dsi_prevSup2) ? dsi_potS2 : dsi_prevSup2
dsi_sup1 := dsi_potS1
dsi_sup2 := dsi_potS2
dsi_potS1 := na
dsi_potS2 := na
var int dsi_supCount = 0
var int dsi_resCount = 0
if close >= dsi_res1 and barstate.isconfirmed
dsi_lookForNewResistance := true
dsi_lookForNewSupport := true
dsi_resCount += 1
if close <= dsi_sup1 and barstate.isconfirmed
dsi_lookForNewSupport := true
dsi_lookForNewResistance := true
dsi_supCount += 1
if (close > dsi_res1 and na(dsi_prevRes1) and barstate.isconfirmed) or na(dsi_prevRes1) or dsi_resCount >= newStructureReset
dsi_prevRes1 := dsi_res1
dsi_prevRes2 := dsi_res2
dsi_resCount := 0
if (close < dsi_sup1 and na(dsi_prevSup1) and barstate.isconfirmed) or na(dsi_prevSup1) or dsi_supCount >= newStructureReset
dsi_prevSup1 := dsi_sup1
dsi_prevSup2 := dsi_sup2
dsi_supCount := 0
if close < dsi_prevRes2 and barstate.isconfirmed
dsi_prevRes1 := na
dsi_prevRes2 := na
if close > dsi_prevSup2 and barstate.isconfirmed
dsi_prevSup1 := na
dsi_prevSup2 := na
dsi_r1plot = plot(showDSI and (dsi_res1 == dsi_res1 ) ? dsi_res1 : na, color=close >= dsi_res1 ? dsiBullColor : dsiBearColor, style=plot.style_linebr, title="di R1")
dsi_r2plot = plot(showDSI and (dsi_res1 == dsi_res1 ) ? dsi_res2 : na, color=close >= dsi_res1 ? dsiBullColor : dsiBearColor, style=plot.style_linebr, title="di R2")
fill(dsi_r1plot, dsi_r2plot, color=showDSI ? (close > dsi_res1 ? dsiBullColor : color.new(dsiBearColor, 50)) : color.new(color.black, 100), title="di Resistance Zone")
dsi_s1plot = plot(showDSI and (dsi_sup1 == dsi_sup1 ) ? dsi_sup1 : na, color=close < dsi_sup1 ? dsiBearColor : dsiBullColor, style=plot.style_linebr, title="di S1")
dsi_s2plot = plot(showDSI and (dsi_sup1 == dsi_sup1 ) ? dsi_sup2 : na, color=close < dsi_sup1 ? dsiBearColor : dsiBullColor, style=plot.style_linebr, title="di S2")
fill(dsi_s1plot, dsi_s2plot, color=showDSI ? (close < dsi_sup1 ? dsiBearColor : color.new(dsiBullColor, 50)) : color.new(color.black, 100), title="di Support Zone")
dsi_ps1plot = plot(showDSI and drawPreviousStructure and (dsi_prevSup1 == dsi_prevSup1 ) and (dsi_prevSup1 != dsi_sup1) ? dsi_prevSup1 : na, color=dsiBearColor, style=plot.style_linebr, title="di PS1")
dsi_ps2plot = plot(showDSI and drawPreviousStructure and (dsi_prevSup1 == dsi_prevSup1 ) and (dsi_prevSup1 != dsi_sup1) ? dsi_prevSup2 : na, color=dsiBearColor, style=plot.style_linebr, title="di PS2")
fill(dsi_ps1plot, dsi_ps2plot, color=showDSI and drawPreviousStructure ? color.new(dsiBearColor, 10) : color.new(color.black, 100), title="di Previous Support Zone")
dsi_pr1plot = plot(showDSI and drawPreviousStructure and (dsi_prevRes1 == dsi_prevRes1 ) and (dsi_prevRes1 != dsi_res1) ? dsi_prevRes1 : na, color=dsiBullColor, style=plot.style_linebr, title="di PR1")
dsi_pr2plot = plot(showDSI and drawPreviousStructure and (dsi_prevRes1 == dsi_prevRes1 ) and (dsi_prevRes1 != dsi_res1) ? dsi_prevRes2 : na, color=dsiBullColor, style=plot.style_linebr, title="di Previous Resistance Zone")
//────────────────────────── Elliptic Bands (masked, locked) ──────────────────────────
groupEllipse = "es bands"
EB_show = input.bool(true, "show es bands", group=groupEllipse)
EB_midColor = input.color(color.rgb(229,236,241), "mid color", group=groupEllipse)
EB_upColor = input.color(color.green, "upper color", group=groupEllipse)
EB_dnColor = input.color(color.red, "lower color", group=groupEllipse)
EB_fillTransp = input.int(80, "band transparency (0–100)", minval=0, maxval=100, group=groupEllipse)
EB_showFill = input.bool(false, "fill es cloud", group=groupEllipse)
EB_showSignals = input.bool(true, "show es signals", group=groupEllipse)
EB_buyColor = input.color(color.green, "buy signal color", group=groupEllipse)
EB_sellColor = input.color(color.red, "sell signal color", group=groupEllipse)
// locked params
const int EB_MA_LEN = 50
const int EB_PERIOD = 50
const float EB_MULTI = 2.0
float EB_central_ma = ta.sma(close, EB_MA_LEN)
float EB_b = ta.stdev(close, EB_MA_LEN) * EB_MULTI
int EB_cycle_pos = bar_index % EB_PERIOD
float EB_x = 2.0 * (EB_cycle_pos / EB_PERIOD) - 1.0
float EB_offset = EB_b * math.sqrt(math.max(0.0, 1.0 - EB_x * EB_x))
float EB_band_upper = EB_central_ma + EB_offset
float EB_band_lower = EB_central_ma - EB_offset
// plot lines (upper/lower/mid)
EB_p_mid = plot(EB_show ? EB_central_ma : na, title="es mid", color=EB_midColor, linewidth=1)
EB_p_up = plot(EB_show ? EB_band_upper : na, title="es upper", color=EB_upColor)
EB_p_dn = plot(EB_show ? EB_band_lower : na, title="es lower", color=EB_dnColor)
// fill only if EB_showFill = true
EB_fillColor = (EB_show and EB_showFill) ? color.new(color.gray, EB_fillTransp) : color.new(color.gray, 100)
fill(EB_p_up, EB_p_dn, color=EB_fillColor, title="es cloud")
// signals
bool EB_buy = EB_show and close < nz(EB_band_lower ) and close >= nz(EB_band_lower) and close <= nz(EB_band_upper) and barstate.isconfirmed
bool EB_sell = EB_show and close > nz(EB_band_upper ) and close >= nz(EB_band_lower) and close <= nz(EB_band_upper) and barstate.isconfirmed
plotshape(EB_showSignals and EB_buy, title="es buy", location=location.belowbar, color=EB_buyColor, style=shape.triangleup, size=size.tiny)
plotshape(EB_showSignals and EB_sell, title="es sell", location=location.abovebar, color=EB_sellColor, style=shape.triangledown, size=size.tiny)
// Wave Labels (1–5) — minimal module for tp11ofc1 (Pine v6) — labels only
//──────────────────────────────────────────────────────────────────────────────
groupEW = "Wave labels (Elliott)"
srcHiSel = input.string("high", "High source", options= , group=groupEW)
srcLoSel = input.string("low", "Low source", options= , group=groupEW)
ew_hi = srcHiSel == "high" ? high : srcHiSel == "close" ? close : math.max(open, close)
ew_lo = srcLoSel == "low" ? low : srcLoSel == "close" ? close : math.min(open, close)
ewShowS1 = input.bool(true, "Show wave S", group=groupEW, inline="s1")
ewLen1 = input.int(4, "len", minval=1, group=groupEW, inline="s1")
ewCol1 = input.color(color.new(color.red,0), "", group=groupEW, inline="s1")
ewShowS2 = input.bool(true, "Show wave M", group=groupEW, inline="s2")
ewLen2 = input.int(8, "len", minval=1, group=groupEW, inline="s2")
ewCol2 = input.color(color.new(#0d86e9, 0), "", group=groupEW, inline="s2")
ewShowS3 = input.bool(true, "Show wave L", group=groupEW, inline="s3")
ewLen3 = input.int(16, "len", minval=1, group=groupEW, inline="s3")
ewCol3 = input.color(color.new(#470303, 0),"", group=groupEW, inline="s3")
ewSizeStr = input.string("small","Label size", options= , group=groupEW)
ew_lsize(s) => s=="tiny"?size.tiny:s=="normal"?size.normal:s=="large"?size.large:size.small
type _ZZ
int d
int x
float y
newZZ() => _ZZ.new(array.new_int(), array.new_int(), array.new_float())
f_push_pivot(_aZZ, _dir, _x1, _y1, _x2, _y2) =>
_aZZ.d.unshift(_dir)
_aZZ.x.unshift(_x2)
_aZZ.y.unshift(_y2)
if array.size(_aZZ.d) > 12
_ = array.pop(_aZZ.d)
_ = array.pop(_aZZ.x)
_ = array.pop(_aZZ.y)
var label EW_LABELS = array.new_label()
f_add_label(_x, _y, _txt, _col, _up) =>
label lb = label.new(_x, _y, text=_txt, style=_up?label.style_label_down:label.style_label_up, textcolor=_col, color=color.new(color.black, 100), size=ew_lsize(ewSizeStr), xloc=xloc.bar_index)
array.push(EW_LABELS, lb)
if array.size(EW_LABELS) > 500
label.delete(array.get(EW_LABELS, 0))
array.remove(EW_LABELS, 0)
f_check_motive_bull(_1y,_2y,_3y,_4y,_5y,_6y) =>
_W5 = _6y - _5y
_W3 = _4y - _3y
_W1 = _2y - _1y
_min = math.min(_W1,_W3,_W5)
(_W3 != _min) and (_6y > _4y) and (_3y > _1y) and (_5y > _2y)
f_check_motive_bear(_1y,_2y,_3y,_4y,_5y,_6y) =>
_W5 = _5y - _6y
_W3 = _3y - _4y
_W1 = _1y - _2y
_min = math.min(_W1,_W3,_W5)
(_W3 != _min) and (_4y > _6y) and (_1y > _3y) and (_2y > _5y)
f_wave_labels(_enabled, _len, _col, _rowSep) =>
if _enabled
var _ZZ zz = newZZ()
if barstate.isfirst
for _=0 to 10
array.unshift(zz.d, 0)
array.unshift(zz.x, 0)
array.unshift(zz.y, 0)
x2 = bar_index - 1
ph = ta.pivothigh(ew_hi, _len, 1)
pl = ta.pivotlow (ew_lo, _len, 1)
if not na(ph)
dir = array.get(zz.d, 0)
x1 = array.get(zz.x, 0)
y1 = array.get(zz.y, 0)
y2h = nz(ew_hi )
if dir < 1
f_push_pivot(zz, 1, x1, y1, x2, y2h)
else if ph > y1
array.set(zz.x, 0, x2)
array.set(zz.y, 0, y2h)
_6x = x2, _6y = y2h
_5x = array.get(zz.x,1), _5y = array.get(zz.y,1)
_4x = array.get(zz.x
Quantel Swing ProQuantel Swing Pro is a precision tool designed for traders who want structured swing trade setups with clear rules. The indicator automatically provides:
Entry Signals – optimized swing trade triggers.
Stop Loss (SL) Levels – risk management boundaries based on recent structure.
Take Profit (TP) Targets – dynamic profit zones calculated using volatility and swing ranges.
💡 How to Use:
Ideal for swing trades on 4H, Daily, or Weekly charts (works across all timeframes).
Signals provide a full trade idea: entry, stop, and take profit levels.
Best used with trend confirmation tools (moving averages, higher timeframe bias, or liquidity sweeps).
✅ Features:
Complete trade framework in one tool.
Clean, easy-to-read chart signals.
Adjustable settings to fit your strategy and risk profile.
⚠️ Disclaimer: This tool is for educational purposes only. Not financial advice. Use at your own risk and always confirm signals with your personal trading plan.
KK🚦LightKK Light is for 5min ~ 15min ETH/BTC only
The red triangles indicate selling, and the green ones indicate buying.
When the colored lights appear, you should be more careful.
The colored squares mean that you should stop what you're doing right now.
You can contact me for more details
Session Liquidity & Sweep DetectorThis indicator automatically detects and marks key liquidity sweep events on your chart:
LLS (Lower Liquidity Sweep): Price sweeps below prior lows to grab liquidity.
LHS (Lower High Sweep): Price sweeps above a minor high before rejecting.
ALS (Above Liquidity Sweep): Price sweeps above a key high, often signaling liquidity collection.
AHS (Above High Sweep): Price takes out a previous swing high, indicating possible trap or breakout.
How to Use:
Use signals as confluence with your trading system, not as stand-alone buy/sell triggers.
LLS/ALS can mark areas where liquidity is grabbed before reversal.
LHS/AHS can help identify false breakouts and stop hunts around key levels.
Combine with FVGs, BOS/CHOCH, or PO3 models for maximum effectiveness.
Features:
Clean on-chart signals for all 4 sweep types.
Works on all timeframes and symbols.
Helps traders spot liquidity hunts & manipulation points.
Disclaimer: This tool is for educational purposes only. Not financial advice. Always combine with your own analysis and risk management.
Resistance & Support Trends (Full Body No-Touch)This indicator builds and maintains time-anchored Resistance and Support trendlines with up to three localized depths on each side.
A line is marked broken only when a single bar’s entire candle body is cleanly beyond it—no edge touching—using strict, one-sided logic:
- accumulation (close > open) can break Resistance
- distribution (close < open) can break Support.
Anchors can be selected manually by date/time, broken lines remain as dashed context, and active trends extend forward for ongoing guidance. Customize colors, show/hide depths and markers, and read the structure at a glance to track primary trends and nearer-term swings with high confidence.
XAUUSD/SPX Slope with MACDThe XAUUSD/SPX Slope with MACD Indicator tracks the slope of the XAUUSD (Gold) to SPX (S&P 500) ratio using linear regression over a customizable lookback period (default 20 bars), plotted as a blue line to show Gold’s relative performance against stocks. A MACD overlay (fast: 12, slow: 26, signal: 9, scaled by 5) is applied to the slope, with a green MACD line, red signal line, and green/red histogram to highlight momentum. A positive slope indicates Gold outperforming SPX, while MACD trends provide additional context. A zero line and background coloring (green for positive slope, red for negative) aid interpretation. Ensure XAUUSD and SPX symbols are supported by your platform.
Usage Notes:
Interpretation:
Slope (Blue): Positive values indicate Gold outperforming SPX; negative values show SPX outperforming.
MACD Components: The green MACD line, red signal line, and histogram (green for positive, red for negative) reflect momentum in the slope. Crossovers or histogram shifts can be analyzed manually for potential trend changes.
Customization: Adjust lookback, macd_fast, macd_slow, or macd_signal to tune sensitivity. The MACD scale is fixed at 5 for clarity.
Symbol Check: Verify "XAUUSD" and "SPX" match your platform’s tickers (e.g., "GOLD" or "SP500").
SAPSAN TRADE: Macro / CryptoSAPSAN TRADE: Macro / Crypto displays key macroeconomic indicators that affect the cryptocurrency market: the US Dollar Index (DXY), US inflation (CPI), and Federal Reserve interest rates (FEDFUNDS). The indicator plots the current values and EMAs for each indicator, visualizes changes with histograms and background colors, and shows a table with the latest values on the most recent candle.
Ideal for traders who want to consider macroeconomic factors in crypto analysis and track the real-time dynamics of key economic indicators.
RU
SAPSAN TRADE: Macro / Crypto отображает ключевые макроэкономические показатели, влияющие на криптовалютный рынок: индекс доллара США (DXY), инфляцию (CPI) и процентные ставки ФРС (FEDFUNDS). Индикатор строит значения и EMA для каждого показателя, а также визуализирует изменения через гистограммы и фоновое окрашивание. На последней свече выводится таблица с актуальными значениями всех выбранных макроиндикаторов.
Идеально подходит для трейдеров, которые учитывают макроэкономические факторы при анализе крипторынка и хотят видеть динамику ключевых индексов в реальном времени.