MFI/RSI Divergence Lower하단 지표 구성 및 활용법
MFI (Aqua Line): 거래량이 가중된 자금 흐름입니다. 지지선 근처에서 이 선이 저점을 높이면(다이버전스) 강력한 매수 신호입니다.
RSI (Yellow Line): 가격의 상대적 강도입니다. MFI와 함께 움직임을 비교하여 보조적으로 활용합니다.
리페인팅 방지 핵심: offset=-lb_r 설정을 통해, 지표가 확정되는 시점(피벗 완성 시점)에 정확히 신호가 표시되도록 구현했습니다. 이는 과거 백테스트 결과와 실시간 매매 결과가 일치하도록 보장합니다.
실전 응용
지지/저항 필터: 이 지표 단독으로 사용하기보다, 차트 상의 주요 지지선에 가격이 위치했을 때 발생하는 BULL DIV 신호만 골라 매수하면 승률이 극대화됩니다.
손절/익절 최적화: 현재 1.5% 손절, 3% 익절로 설정되어 있습니다. 종목의 변동성(ATR)에 따라 group_risk에서 수치를 조정하며 최적의 수익 곡선을 찾아보십시오.
//@version=6
strategy("Hybrid MFI/RSI Divergence Lower",
overlay=false, // 하단 지표 설정을 위해 false
initial_capital=10000,
default_qty_type=strategy.percent_of_equity,
default_qty_value=10,
commission_type=strategy.commission.percent,
commission_value=0.05,
slippage=1)
// --- ---
group_date = "1. 백테스트 기간"
start_time = input.time(timestamp("2024-01-01 00:00:00"), "시작일", group=group_date)
end_time = input.time(timestamp("2026-12-31 23:59:59"), "종료일", group=group_date)
within_window() => time >= start_time and time <= end_time
group_osc = "2. 오실레이터 설정"
mfi_len = input.int(14, "MFI 기간", group=group_osc)
rsi_len = input.int(14, "RSI 기간", group=group_osc)
ob_level = input.int(80, "과매수 기준", group=group_osc)
os_level = input.int(20, "과매도 기준", group=group_osc)
group_div = "3. 다이버전스 감도"
lb_l = input.int(5, "피벗 왼쪽 범위", group=group_div)
lb_r = input.int(5, "피벗 오른쪽 범위", group=group_div)
group_risk = "4. 리스크 관리"
tp_pct = input.float(3.0, "익절 (%)", step=0.1, group=group_risk) / 100
sl_pct = input.float(1.5, "손절 (%)", step=0.1, group=group_risk) / 100
// --- ---
mfi_val = ta.mfi(close, mfi_len)
rsi_val = ta.rsi(close, rsi_len)
avg_val = (mfi_val + rsi_val) / 2 // MFI와 RSI의 평균값으로 부드러운 흐름 파악
// --- ---
// 저점 피벗 탐지 (MFI 기준)
pl = ta.pivotlow(mfi_val, lb_l, lb_r)
ph = ta.pivothigh(mfi_val, lb_l, lb_r)
// Bullish Divergence (상승 다이버전스)
var float last_pl_mfi = na
var float last_pl_price = na
bool is_bull_div = false
if not na(pl)
last_pl_mfi := mfi_val
last_pl_price := low
// 이전 저점 탐색
float prev_pl_mfi = ta.valuewhen(not na(pl), mfi_val , 1)
float prev_pl_price = ta.valuewhen(not na(pl), low , 1)
if low < prev_pl_price and mfi_val > prev_pl_mfi
is_bull_div := true
// Bearish Divergence (하락 다이버전스)
var float last_ph_mfi = na
var float last_ph_price = na
bool is_bear_div = false
if not na(ph)
last_ph_mfi := mfi_val
last_ph_price := high
float prev_ph_mfi = ta.valuewhen(not na(ph), mfi_val , 1)
float prev_ph_price = ta.valuewhen(not na(ph), high , 1)
if high > prev_ph_price and mfi_val < prev_ph_mfi
is_bear_div := true
// --- ---
if within_window()
if is_bull_div
strategy.entry("Bull", strategy.long, comment="Bull Div")
if is_bear_div
strategy.entry("Bear", strategy.short, comment="Bear Div")
strategy.exit("ExB", "Bull", limit=strategy.position_avg_price * (1 + tp_pct), stop=strategy.position_avg_price * (1 - sl_pct))
strategy.exit("ExS", "Bear", limit=strategy.position_avg_price * (1 - tp_pct), stop=strategy.position_avg_price * (1 + sl_pct))
// --- ---
// 배경 레이아웃
hline(ob_level, "Overbought", color=color.new(color.red, 50), linestyle=hline.style_dashed)
hline(50, "Middle", color=color.new(color.gray, 70))
hline(os_level, "Oversold", color=color.new(color.green, 50), linestyle=hline.style_dashed)
// 메인 지표 플롯
plot(mfi_val, "MFI (Money Flow)", color=color.new(color.aqua, 0), linewidth=2)
plot(rsi_val, "RSI (Momentum)", color=color.new(color.yellow, 50), linewidth=1)
// 다이버전스 발생 시 하단 지표 영역에 선 그리기
plotshape(is_bull_div ? mfi_val : na, "Bull Div Circle", shape.circle, location.absolute, color.green, size=size.tiny, offset=-lb_r)
plotshape(is_bear_div ? mfi_val : na, "Bear Div Circle", shape.circle, location.absolute, color.red, size=size.tiny, offset=-lb_r)
// 과매수/과매도 배경색
fill(hline(ob_level), hline(100), color.new(color.red, 90))
fill(hline(0), hline(os_level), color.new(color.green, 90))
インジケーターとストラテジー
SelfContained Momentum Screener (TT+Momentum+Vol+VCP)This script is a self-contained Pine Screener indicator that does not rely on indexes or external symbols. It uses Minervini’s Trend Template to confirm a strong uptrend structure, then evaluates mid-term momentum (6–12 months) and short-term momentum (about 1 month). Optional volume spikes and volatility contraction (simple VCP) can be toggled on or off. The screener filters for stocks that have risen strongly, maintain recent momentum, and show tight consolidation near highs, making it suitable for efficiently identifying high-quality momentum candidates.
このスクリプトは、指数や外部データを使わず自己完結で動作するPineスクリーナー用インジケーターです。ミネルビニのTrend Templateで上昇トレンドの構造を確認し、中長期モメンタム(6〜12か月)と短期モメンタム(約1か月)で勢いを判定します。必要に応じて出来高スパイクと高値圏でのボラティリティ収縮(VCP簡易)をON/OFFでき、条件を満たした銘柄のみを抽出します。強く上昇してきており、直近も勢いがあり、かつ高値圏で締まっている銘柄を効率的に見つけるためのスクリーナーです。
Key timings for indicesThis indicator has following key levels
9:30 am open
opening range low
opening range high
8 am low
8 am high
midnight open
Bitget Pro Sinyal [Optimized v2]11 gösterge onaylı sinyaller yatırım tavsiyesi değildir kendi kullandıgım sinyaller
BERNA (Boundary-Encoded Resonance Network Architecture)BERNA — Boundary-Encoded Resonance Network Architecture
BERNA is a research-grade indicator that estimates the remaining structural capacity of the current market regime.
Unlike trend, volatility, or momentum tools, BERNA does not measure price direction — it measures how much of the regime’s internal capacity has already been consumed.
This script implements the BERNA model published on Zenodo (Bülent Duman, 2026).
It is intentionally minimal and uses only OHLC data.
What BERNA measures
BERNA outputs a structural capacity state:
τ = Σ / Θ (normalized structural stress)
Λ = Θ − Σ (remaining structural capacity)
Interpretation:
High Λ / low τ → the regime has structural endurance
Rising τ → capacity is being consumed
τ → 1 (Λ → 0) → rupture proximity (capacity exhaustion)
This makes BERNA a forward-looking structural capacity variable, not a price oscillator.
What is inside this script
This implementation contains the following components:
Efficiency proxy (DERYA-like, but not the full public DERYA)
BERNA uses a simple microstructure efficiency proxy computed as:
E = |close − open| / (high − low)
This is conceptually “DERYA-like” but it is not the full DERYA framework.
No external/public DERYA source code is embedded here.
Standard technical primitives used
This script uses only basic primitives commonly found in technical analysis:
Absolute value and range normalization
Thresholding (regime binning)
Power transform on range (rng^p)
There is no EMA, RSI, MACD, ATR, ADX, Fisher, Kaufman, or other indicator embedded.
All computations are internal and deterministic.
3-state structural regime binning (K = 3)
The efficiency proxy E is discretized into three regimes using user thresholds:
Low efficiency
Mid efficiency
High efficiency
Each regime has its own capacity Θ and stress multiplier β.
Structural stress accumulation (Σ) and rupture proximity
Stress increment is defined as:
dΣ = β · (1 − E) · (range^p)
Σ accumulates inside a regime and is capped by Θ.
In this prototype, Σ resets on regime change by construction (regime-gated accumulation).
The rupture proximity is expressed through τ and Λ.
How to use BERNA
BERNA is designed as a regime-health and fragility overlay, not a buy/sell trigger.
Typical uses:
Detect when an ongoing move is structurally late-stage (τ high, Λ low)
Avoid initiating trades when capacity is nearly exhausted
Compare structural resilience across assets and regimes
Use alongside price/trend/volume systems for context
Do not use BERNA alone as a trading signal.
BERNA tells you “how much structure is left”, not “where price will go.”
Visuals
Efficiency (E) shows the bar-level microstructure efficiency proxy
τ shows normalized structural stress (capacity consumption)
Λ shows remaining structural capacity
Dotted lines mark warning and critical rupture proximity levels
Important notes
BERNA is not RSI, MACD, ATR, ADX, Fisher, Kaufman, or a volatility model
BERNA does not predict price direction
BERNA does not issue entry/exit signals
BERNA is a structural capacity diagnostic
This script does not embed any external/public indicator code; all logic is implemented directly in Pine.
Risk and disclaimer
This script is provided for research and analytical purposes only.
It is not financial advice and must not be used as a standalone trading system.
Markets are uncertain.
All trading decisions and risks remain entirely the responsibility of the user.
BERNA: Boundary-Encoded Resonance Network Architecture
A Structural Failure Theory of Financial Regimes Based on Endogenous Capacity Depletion
Author: Duman, Bülent
Affiliation: Independent Researcher
Reference: zenodo.org
daily reversalindicator that marks when the current daily candle (bullish or bearish) closes beyond the previous day’s High or Low.
Logic implemented
Bullish condition → Today closes above yesterday’s High
Bearish condition → Today closes below yesterday’s Low
Works only on Daily timeframe
Plots labels/arrows on the chart
Volume Participation Stars - by Praveen SigrohaSpot the next big move by identifying level of participation.
blue candle = extreme participation
red candle = higher participation
yellow candle = high participation
grey candle = nothing special
if extreme participation marked by star = be alert for the action
Commodity Channel Index// BUY CONDITION
buySignal = direction < 0 and ta.crossover(cci, -100)
// ENTRY PRICE
entryPrice = close
// STOP LOSS AT SUPERTREND
stopLoss = supertrend
// RISK CALCULATION
risk = entryPrice - stopLoss
// TARGET 1:2
target = entryPrice + (risk * 2)
// ALERT
alertcondition(buySignal, title="BUY", message="Supertrend Green + CCI Cross Above -100 | RR 1:2")
// OPTIONAL PLOTS
plotshape(buySignal, title="BUY Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY")
plot(stopLoss, title="Stop Loss", color=color.red)
plot(target, title="Target 1:2", color=color.green)
Manual Backtest Dashboard (100 Trades)Manual Backtest Dashboard (100 Trades) is a lightweight TradingView indicator designed to help traders manually record and evaluate their trading performance directly on the chart. This tool is built specifically for discretionary traders such as SMC, price action, scalping, and intraday traders who want to analyze their win rate and overall performance without relying on the Strategy Tester.
The indicator works by allowing users to input their trade results manually through the settings panel. Each trade is recorded using simple values: 1 for a winning trade, -1 for a losing trade, and 0 for an empty or uncounted trade. The dashboard automatically calculates the total number of trades entered, the number of wins and losses, and the win rate percentage in real time. Users do not need to fill all 100 trade slots, as only trades with non-zero values are included in the calculations.
This indicator does not place trades or generate buy and sell signals. Instead, it focuses purely on performance evaluation, making it ideal for subjective backtesting, forward testing, and manual trading journals. The dashboard is clean, lightweight, and does not clutter the price chart, ensuring a smooth and distraction-free trading experience. The script is stable, efficient, and does not repaint, making it a reliable tool for traders who want to track and improve their consistency over time.
Magic PP TouchLets make this bread, magic hour pattern
Wait for a break above the high or low and then enter in opposite direction.
ZigZag Volume Profile [Honestcowboy]The ZigZag Volume Profile Indicator is a combination of 2 very popular trading indicators, the volume profile and zigzag indicator. Instead of using predetermined sessions like traditional volume profile analysis. This indicator expands on zigzag indicators "legs" and draws a volume profile inside each zigzag leg.
What is a Volume Profile?
"Technical analysis tool showing trading volume at specific price levels, creating a horizontal histogram on the side of a chart to reveal areas of high buying/selling interest, unlike traditional volume bars showing volume over time. Key elements include the Point of Control (POC) for most traded price, the Value Area (VAH/VAL), identifying crucial support/resistance, and analyzing profile shapes (like D, B, P) to understand market balance and potential price targets, used by professionals to spot liquidity and market structure."
Key Differences
Does not have a value area but distinguishes each column in relation to the biggest column in percentage terms.
Does not take sessions into account instead using zigzag legs
🟦 CALCULATION
The zigzag volume profile first builds a standard zigzag indicator to find structure in the market. Using pivot points and a minimum % price move threshhold.
Then once it knows the zigzags it will use each leg as a time window to calculate a volume profile inside.
🔹Coloring each column:
The script will find the biggest column in the Profile and use that as a reference for all other columns. It will then decide for each column individually how big it is in % compared to the biggest column. It will use that percentage to decide which color to give it, top 20% will be red, top 40% purple, top 60% blue, top 80% green and all the rest yellow. The user is able to adjust these numbers for further customisation.
🟦 USAGE
The idea behind this indicator is, if you look at markets as different legs (moves) going in a zigzag pattern you might want to look deeper inside your previous moves and see where the actual liquidity/volume was during that move. The hypothesis here is you build trade ideas based on zigzags but then use the volume profiles.
Since volume and market structure are very well known concepts to discretionary traders I'm hoping this indicator might give some different perspective on this relation and help people create a trading approach based on it. Here's some quick cherry picked examples, just as a proof of concept:
🟦 SETTINGS
🔹ZIGZAG SETTINGS
Price Deviotion % : This is the minimum price move in % term from last pivot price needs to move to form a new pivot for the zigzag.
Pivot Legs (Left/Right): The amount of bars a high or a low needs to be higher/lower than to the left and right of the bar. 10 By default to create medium term zigzag
🔹Volume Profile
Profile Rows: The amount of rows in Y axis the zigzag is going to be sliced into to create the volume profile. Higher number is more detailed volume profile but also uses more box objects which is maxed at 500. 25 by default
Profiles to Display: The amount of volume profiles the indicator will draw back in time. Higher number means more history but also longer loading time. 20 by default
🔹Visual Settings
This part is pretty self explanatory and you have can manually select the colors used to create the volume profile. Refer back the the explanation about the "🔹coloring each column" section.
EURUSD Smart Signal Bot (15m + 1H) DkS-SignalBotEURUSD Smart Signal Bot (15m + 1H) is a signal-based indicator designed to identify buy and sell opportunities on the EURUSD forex pair.
It uses confluence from:
• 20 and 50 EMAs on the 15-minute timeframe for entries
• 200 EMA on the 1-hour timeframe to confirm the main trend
• RSI filter to measure momentum
• London and New York trading sessions filter
The indicator displays BUY and SELL signals, Stop Loss levels based on recent swing highs/lows, and Take Profit targets calculated using Risk/Reward (RR) ratios.
This tool is intended for intraday trading and structured scalping in the forex market.
⚠️ This indicator does not guarantee results and should be used with proper risk management.
Previous D/W/M OHLC LevelsPlots the previous completed Daily, Weekly, and Monthly Open, High, Low, and Close prices as horizontal levels on any timeframe.
Clean, lightweight, and trader-friendly:
• Previous Day (PDH/PDL) – light blue
• Previous Week (PWH/PWL) – gold
• Previous Month (PMH/PML) – orange-red
Great for support/resistance, breakout strategies, mean reversion, and keeping higher-timeframe context visible at a glance.
Simple, no repainting, works on all instruments and timeframes.
Open Interest Spaghetti - Multi ExchangeOpen Interest Spaghetti – Multi Exchange is a structural open-interest flow visualizer designed to expose where and when derivatives positioning is being built or unwound across major futures venues — without collapsing that information into a single, opaque aggregate line.
Instead of smoothing, normalizing, or trend-filtering open interest, this script intentionally preserves exchange-level granularity and plots each venue’s cumulative OI delta from a shared anchor point. The result is a “spaghetti” structure: multiple independent OI paths evolving in parallel, revealing divergence, dominance, and regime shifts in real time.
Core Idea and Originality
Most OI indicators do one of three things:
1) Plot raw open interest (slow, hard to interpret),
2) Plot OI change per bar (noisy, context-less),
3) Aggregate all exchanges into one line (information loss).
This script does none of those.
Instead, it implements an anchored cumulative delta framework applied individually to each exchange, using a common reset reference. This preserves path dependency — you see how positioning evolved since a known structural point, not just what happened on the last candle.
Key differentiators:
- Exchange-segmented OI accumulation
- Explicit anchor-based reset logic
- Optional normalization into percent-of-total OI
- No smoothing, no averages, no trend assumptions
This is not a trend indicator. It is a positioning flow map.
Data Construction and Normalization
Multi-Contract Aggregation (per exchange)
Each exchange’s total open interest is constructed by summing all available perpetual contracts:
- USD-margined
- USDT-margined
- USDC-margined
Where necessary, contract units are converted into a common base-coin representation so that all venues are directly comparable. This prevents distortions caused by mixed margin types.
The result is a true total OI per exchange, not a single contract proxy.
Anchored Cumulative Delta Logic
Let:
- OI(t) = total open interest at time t for a given exchange
- ΔOI(t)=OI(t) - OI(t-1)
For each bar:
- The script accumulates ΔOI forward in time
- This accumulation resets to zero whenever the anchor period changes
The anchor period is user-defined (default: Daily). At each reset:
- All exchange accumulators are cleared
- The current combined OI across all enabled exchanges is stored as the normalization baseline
This makes every plotted value interpretable as:
“Net positioning added or removed since the last anchor reset.”
Display Modes
1. Actual Change (default)
Plots the absolute net change in open interest since the anchor reset.
Interpretation:
- Large positive values → sustained position building
- Large negative values → sustained position unwinding
- Divergence between exchanges → uneven participation or venue-specific positioning
This mode preserves raw scale and is best for structural analysis.
2. Percent Change (normalized mode)
Each exchange’s cumulative delta is divided by the total combined OI at the anchor reset, then expressed as a percentage.
Percent Change = (Exchange Cumulative OI Delta / Total OI at Anchor) * 100
Interpretation:
- Removes absolute size bias between large and small exchanges
- Allows direct comparison of relative contribution
- Makes regime shifts easier to spot across different assets
This mode answers:
“Which exchange is driving the majority of positioning change relative to the market’s size?”
Visual and Structural Aids
- Zero baseline represents the anchor reset point
- Vertical dashed lines mark anchor transitions
- End-of-chart labels identify each exchange without relying on a legend
- All plots are unsmoothed and unfiltered by design
Noise is not removed — it is contextualized.
How Traders Use This
This indicator is most effective for:
- Detecting exchange-specific accumulation or distribution
- Identifying hidden divergence beneath price
- Confirming whether price moves are supported by broad positioning or isolated leverage
- Comparing how different venues react to the same market event
Typical interpretations:
- Price rising while OI spaghetti diverges → short covering or uneven leverage
- One exchange leading OI expansion → localized risk concentration
- Flat price with rising OI across venues → compression and potential expansion setup
What This Is Not
- Not a trend detector
- Not a momentum oscillator
- Not a signal generator
It provides structural context, not trade entries.
Summary
Open Interest Spaghetti – Multi Exchange is a flow-first, structure-aware OI framework that exposes how derivatives positioning evolves across venues from a shared reference point. By preserving exchange independence, anchoring accumulation, and offering optional normalization, it reveals information that aggregate or smoothed OI indicators inherently destroy.
If you trade derivatives and care where risk is building — not just that it is — this tool is designed for that exact purpose.
XRP / USDT Scalper PRO (Binance US) DkSAlert-AnalyticsXRP / USDT Scalper PRO (Binance US) DkSAlert-Analytics is an aggressive yet risk-aware scalping indicator designed specifically for trading XRPUSDT on Binance US, where higher trading fees are taken into account.
This script is built to filter low-quality trades and only trigger signals when the potential price movement clearly exceeds the Binance US trading fee (~0.57%).
The indicator combines multiple confirmations to produce high-probability BUY and SELL signals:
• Fast and mid EMAs for short-term trend and entries
• 200 EMA on the 1H timeframe for higher-timeframe trend direction
• Breakout detection based on recent swing highs and lows
• Volume confirmation to validate momentum
• RSI filter to avoid weak or exhausted moves
• Fee-aware risk filter to ensure trades have sufficient profit potential
The script automatically plots:
• BUY and SELL labels
• Stop Loss levels based on recent market structure
• Take Profit targets using a minimum Risk/Reward model
This indicator is designed for high-frequency scalping and short-term trading, while maintaining strict filters to reduce overtrading and fee impact.
⚠️ This script does not guarantee profits and should always be used with proper risk management.
Gold 2-Week Futures LevelsYou may change the color at bottom of script and i used 1h to mark out my levels, you may change it to fit your time frame.
DkS Market Structure Breakout Strategy Crypto & ForexDkS Market Structure Breakout Strategy Crypto & Forex
🔍 Overview
DkSPro – Universal Market Analysis is a structure-based trading strategy designed for Crypto and Forex markets, focused on trend alignment, breakout confirmation, and volume validation.
This strategy is built to filter low-quality trades, avoid ranging conditions, and reduce false breakouts by requiring multiple layers of confirmation before any trade is executed.
It is intended for scalping and intraday trading, prioritizing consistency and risk control over trade frequency.
🧠 Strategy Logic (How It Works)
DkSPro follows a sequential decision process, not a single-indicator signal:
Trend Bias (EMA Structure)
A fast and slow EMA define the directional bias.
Long trades are only allowed during bullish EMA alignment.
Short trades are only allowed during bearish EMA alignment.
This prevents counter-trend and ranging-market entries.
Market Structure & Breakout Validation
The strategy identifies recent swing highs and lows.
Trades are triggered only after a confirmed breakout of structure, not during consolidation.
This avoids early entries and false momentum moves.
Volume Confirmation
Volume must exceed its moving average by a defined multiplier.
This ensures participation and filters out low-liquidity breakouts.
Volume thresholds adapt depending on the selected trading mode.
Momentum Confirmation (RSI)
RSI is used strictly as a momentum filter, not as a standalone signal.
It confirms that price movement aligns with the breakout direction.
Risk Management (Mandatory)
Every position includes a predefined Stop Loss and Take Profit.
Position sizing is based on a fixed percentage of equity, keeping risk per trade within sustainable limits.
All conditions must align simultaneously; otherwise, no trade is executed.
⚙️ Trading Modes
SAFE Mode
Stronger volume and RSI thresholds
Fewer trades, higher selectivity
Designed for risk control and consistency
AGGRESSIVE Mode
Slightly relaxed filters
Higher trade frequency during strong momentum
Intended for experienced users only
📊 Markets & Assets
This strategy has been actively used and tested on:
🟢 Crypto (Binance / Binance.US)
SOL-USDT
XRP-USDT
Other high-liquidity pairs (BTC, ETH)
Crypto mode benefits from stronger volume confirmation to adapt to higher volatility.
🔵 Forex
Major pairs such as EURUSD, GBPUSD, USDJPY
Optimized for liquid markets with lower relative volume
The same structural logic applies to both markets, with volume behavior naturally adapting to each asset class.
⏱ Recommended Timeframes
Crypto: 5m – 15m
Forex: 15m – 1H
Lower timeframes (1m) are not recommended due to noise and unreliable volume behavior.
🧪 Backtesting & Settings Transparency
Default strategy properties are intentionally conservative to reflect realistic conditions:
Initial capital: $20,000
Position size: 2% of equity
Commission: 0.08%
Slippage: 1 tick
Fixed Stop Loss and Take Profit on every trade
Backtests should be performed on sufficient historical data (ideally 6–12 months) to ensure a statistically meaningful sample size (100+ trades).
📈 Originality & Usefulness
DkSPro is not a simple indicator mashup.
Each component serves a specific role in a layered confirmation system:
EMAs define direction
Structure defines timing
Volume validates participation
RSI confirms momentum
Risk management controls exposure
Removing any layer significantly reduces signal quality. The strategy is designed as a complete decision framework, not a signal generator.
⚠️ Important Notes
This script is an analysis and execution tool, not financial advice.
Market conditions change, and no strategy performs well in all environments.
Users are encouraged to backtest, forward test, and adjust position sizing according to their own risk tolerance.
🧩 Version Notice
This publication represents a consolidated and refined version of an internal experimental script.
No parallel or duplicate versions are intended.
All future improvements will be released exclusively using TradingView’s Update feature.
🇪🇸 Descripción en Español (Resumen)
DkSPro es una estrategia basada en estructura de mercado, diseñada para Crypto y Forex, que combina tendencia, ruptura de estructura, volumen y control de riesgo.
Solo opera cuando todas las condiciones se alinean, evitando rangos, falsas rupturas y sobreoperar.
Ha sido utilizada en Binance con pares como SOL-USDT y XRP-USDT, así como en Forex, siempre con gestión de riesgo fija y condiciones realistas.
MACD 12-26-9 with Slope, Convergence & Divergence1. Core Indicator: MACD (12-26-9)
The script uses the standard MACD:
Fast EMA: 12
Slow EMA: 26
Signal EMA: 9
It plots:
MACD Line → short-term vs long-term momentum
Signal Line → smoothed MACD
Histogram → distance between MACD and Signal
2. Histogram Slope (Momentum Acceleration)
What it is
The slope measures how fast the MACD histogram is changing.
histSlope = hist - hist
What it tells you
Positive slope → momentum accelerating
Negative slope → momentum slowing
Slope flip → early momentum shift (often before MACD cross)
Why it matters
MACD crosses are lagging.
Histogram slope gives early warning of momentum changes.
3. Convergence & Divergence (MACD vs Signal)
How it’s calculated
The script measures the distance between the MACD and Signal lines:
distance = abs(macdLine - signalLine)
Convergence → distance is shrinking
Divergence → distance is expanding
Interpretation
Convergence = compression / energy building
Divergence = expansion / trend strength or exhaustion
This is not price divergence, but internal momentum structure.
4. MACD Perimeter Threshold (Momentum Filter)
What it is
Horizontal bands above and below zero that define a “noise zone”.
Inside perimeter → weak / choppy momentum
Outside perimeter → strong momentum
Why it’s useful
Filters low-quality MACD crosses
Identifies compression → expansion
Helps spot trend exhaustion when momentum fades outside the band
5. Visual Encoding (What you see)
Histogram colors
Bright green / red → strong acceleration
Dull green / maroon → weakening momentum
Gray → indecision
MACD line color
Yellow → converging (compression)
Orange → diverging (expansion)
Blue → neutral
Markers
Up triangle → bullish convergence
Down triangle → bearish divergence
6. How traders use this indicator
Trend continuation
MACD above zero
Histogram positive
Slope rising
Divergence expanding
➡ Strong trend continuation
Pullback entries
Trend intact
Histogram pulls back toward zero
Slope turns up again
➡ High-probability re-entry
Breakout anticipation
Long convergence
Histogram flattening
Sudden slope expansion
➡ Breakout likely
Exhaustion warning
Large divergence
Histogram slope weakens
Momentum fails to expand
➡ Trend may stall or reverse
7. Best use cases
Works best as a momentum confirmation tool
Combine with:
Market structure
Support / resistance
Moving averages
Volume or Force Index
SpatialIndexYou can start using this now by inserthing this at the top of your indicator/strategy/library.
import ArunaReborn/SpatialIndex/1 as SI
Overview
SpatialIndex is a high-performance Pine Script library that implements price-bucketed spatial indexing for efficient proximity queries on large datasets. Instead of scanning through hundreds or thousands of items linearly (O(n)), this library provides O(k) bucket lookup where k is typically just a handful of buckets, dramatically improving performance for price-based filtering operations.
This library works with any data type through index-based references, making it universally applicable for support/resistance levels, pivot points, order zones, pattern detection points, Fair Value Gaps, and any other price-based data that needs frequent proximity queries.
Why This Library Exists
The Problem
When building advanced technical indicators that track large numbers of price levels (support/resistance zones, pivot points, order blocks, etc.), you often need to answer questions like:
- *"Which levels are within 5% of the current price?"*
- *"What zones overlap with this price range?"*
- *"Are there any significant levels near my entry point?"*
The naive approach is to loop through every single item and check its price. For 500 levels across multiple timeframes, this means 500 comparisons every bar . On instruments with thousands of historical bars, this quickly becomes a performance bottleneck that can cause scripts to time out or lag.
The Solution
SpatialIndex solves this by organizing items into price buckets —like filing cabinets organized by price range. When you query for items near $50,000, the library only looks in the relevant buckets (e.g., $49,000-$51,000 range), ignoring all other price regions entirely.
Performance Example:
- Linear scan: Check 500 items = 500 comparisons per query
- Spatial index: Check 3-5 buckets with ~10 items each = 30-50 comparisons per query
- Result: 10-16x faster queries
Key Features
Core Capabilities
- ✅ Generic Design : Works with any data type via index references
- ✅ Multiple Index Strategies : Fixed bucket size or ATR-based dynamic sizing
- ✅ Range Support : Index items that span price ranges (zones, gaps, channels)
- ✅ Efficient Queries : O(k) bucket lookup instead of O(n) linear scan
- ✅ Multiple Query Types : Proximity percentage, fixed range, exact price with tolerance
- ✅ Dynamic Updates : Add, remove, update items in O(1) time
- ✅ Batch Operations : Efficient bulk removal and reindexing
- ✅ Query Caching : Optional caching for repeated queries within same bar
- ✅ Statistics & Debugging : Built-in stats and diagnostic functions
### Advanced Features
- ATR-Based Bucketing : Automatically adjusts bucket sizes based on volatility
- Multi-Bucket Spanning : Items that span ranges are indexed in all overlapping buckets
- Reindexing Support : Handles array removals with automatic index shifting
- Cache Management : Configurable query caching with automatic invalidation
- Empty Bucket Cleanup : Automatically removes empty buckets to minimize memory
How It Works
The Bucketing Concept
Think of price space as divided into discrete buckets, like a histogram:
```
Price Range: $98-$100 $100-$102 $102-$104 $104-$106 $106-$108
Bucket Key: 49 50 51 52 53
Items:
```
When you query for items near $103:
1. Calculate which buckets overlap the $101.50-$104.50 range (keys 50, 51, 52)
2. Return items from only those buckets:
3. Never check items in buckets 49 or 53
Bucket Size Selection
Fixed Size Mode:
```pine
var SI.SpatialBucket index = SI.newSpatialBucket(2.0) // $2 per bucket
```
- Good for: Instruments with stable price ranges
- Example: For stocks trading at $100, 2.0 = 2% increments
ATR-Based Mode:
```pine
float atr = ta.atr(14)
var SI.SpatialBucket index = SI.newSpatialBucketATR(1.0, atr) // 1x ATR per bucket
SI.updateATR(index, atr) // Update each bar
```
- Good for: Instruments with varying volatility
- Adapts automatically to market conditions
- 1.0 multiplier = one bucket spans one ATR unit
Optimal Bucket Size:
The library includes a helper function to calculate optimal size:
```pine
float optimalSize = SI.calculateOptimalBucketSize(close, 5.0) // For 5% proximity queries
```
This ensures queries span approximately 3 buckets for optimal performance.
Index-Based Architecture
The library doesn't store your actual data—it only stores indices that point to your external arrays:
```pine
// Your data
var array levels = array.new()
var array types = array.new()
var array ages = array.new()
// Your index
var SI.SpatialBucket index = SI.newSpatialBucket(2.0)
// Add a level
array.push(levels, 50000.0)
array.push(types, "support")
array.push(ages, 0)
SI.add(index, array.size(levels) - 1, 50000.0) // Store index 0
// Query near current price
SI.QueryResult result = SI.queryProximity(index, close, 5.0)
for idx in result.indices
float level = array.get(levels, idx)
string type = array.get(types, idx)
// Work with your actual data
```
This design means:
- ✅ Works with any data structure you define
- ✅ No data duplication
- ✅ Minimal memory footprint
- ✅ Full control over your data
---
Usage Guide
Basic Setup
```pine
// Import library
import username/SpatialIndex/1 as SI
// Create index
var SI.SpatialBucket index = SI.newSpatialBucket(2.0)
// Your data arrays
var array supportLevels = array.new()
var array touchCounts = array.new()
```
Adding Items
Single Price Point:
```pine
// Add a support level at $50,000
array.push(supportLevels, 50000.0)
array.push(touchCounts, 1)
int levelIdx = array.size(supportLevels) - 1
SI.add(index, levelIdx, 50000.0)
```
Price Range (Zones/Gaps):
```pine
// Add a resistance zone from $51,000 to $52,000
array.push(zoneBottoms, 51000.0)
array.push(zoneTops, 52000.0)
int zoneIdx = array.size(zoneBottoms) - 1
SI.addRange(index, zoneIdx, 51000.0, 52000.0) // Indexed in all overlapping buckets
```
Querying Items
Proximity Query (Percentage):
```pine
// Find all levels within 5% of current price
SI.QueryResult result = SI.queryProximity(index, close, 5.0)
if array.size(result.indices) > 0
for idx in result.indices
float level = array.get(supportLevels, idx)
// Process nearby level
```
Fixed Range Query:
```pine
// Find all items between $49,000 and $51,000
SI.QueryResult result = SI.queryRange(index, 49000.0, 51000.0)
```
Exact Price with Tolerance:
```pine
// Find items at exactly $50,000 +/- $100
SI.QueryResult result = SI.queryAt(index, 50000.0, 100.0)
```
Removing Items
Safe Removal Pattern:
```pine
SI.QueryResult result = SI.queryProximity(index, close, 5.0)
if array.size(result.indices) > 0
// IMPORTANT: Sort descending to safely remove from arrays
array sorted = SI.sortIndicesDescending(result)
for idx in sorted
// Remove from index
SI.remove(index, idx)
// Remove from your data arrays
array.remove(supportLevels, idx)
array.remove(touchCounts, idx)
// Reindex to maintain consistency
SI.reindexAfterRemoval(index, idx)
```
Batch Removal (More Efficient):
```pine
// Collect indices to remove
array toRemove = array.new()
for i = 0 to array.size(supportLevels) - 1
if array.get(touchCounts, i) > 10 // Remove old levels
array.push(toRemove, i)
// Remove in descending order from data arrays
array sorted = array.copy(toRemove)
array.sort(sorted, order.descending)
for idx in sorted
SI.remove(index, idx)
array.remove(supportLevels, idx)
array.remove(touchCounts, idx)
// Batch reindex (much faster than individual reindexing)
SI.reindexAfterBatchRemoval(index, toRemove)
```
Updating Items
```pine
// Update a level's price (e.g., after refinement)
float newPrice = 50100.0
SI.update(index, levelIdx, newPrice)
array.set(supportLevels, levelIdx, newPrice)
// Update a zone's range
SI.updateRange(index, zoneIdx, 51000.0, 52500.0)
array.set(zoneBottoms, zoneIdx, 51000.0)
array.set(zoneTops, zoneIdx, 52500.0)
```
Query Caching
For repeated queries within the same bar:
```pine
// Create cache (persistent)
var SI.CachedQuery cache = SI.newCachedQuery()
// Cached query (returns cached result if parameters match)
SI.QueryResult result = SI.queryProximityCached(
index,
cache,
close,
5.0, // proximity%
1 // cache duration in bars
)
// Invalidate cache when index changes significantly
if bigChangeDetected
SI.invalidateCache(cache)
```
---
Practical Examples
Example 1: Support/Resistance Finder
```pine
//@version=6
indicator("S/R with Spatial Index", overlay=true)
import username/SpatialIndex/1 as SI
// Data storage
var array levels = array.new()
var array types = array.new() // "support" or "resistance"
var array touches = array.new()
var array ages = array.new()
// Spatial index
var SI.SpatialBucket index = SI.newSpatialBucket(close * 0.02) // 2% buckets
// Detect pivots
bool isPivotHigh = ta.pivothigh(high, 5, 5)
bool isPivotLow = ta.pivotlow(low, 5, 5)
// Add new levels
if isPivotHigh
array.push(levels, high )
array.push(types, "resistance")
array.push(touches, 1)
array.push(ages, 0)
SI.add(index, array.size(levels) - 1, high )
if isPivotLow
array.push(levels, low )
array.push(types, "support")
array.push(touches, 1)
array.push(ages, 0)
SI.add(index, array.size(levels) - 1, low )
// Find nearby levels (fast!)
SI.QueryResult nearby = SI.queryProximity(index, close, 3.0) // Within 3%
// Process nearby levels
for idx in nearby.indices
float level = array.get(levels, idx)
string type = array.get(types, idx)
// Check for touch
if type == "support" and low <= level and low > level
array.set(touches, idx, array.get(touches, idx) + 1)
else if type == "resistance" and high >= level and high < level
array.set(touches, idx, array.get(touches, idx) + 1)
// Age and cleanup old levels
for i = array.size(ages) - 1 to 0
array.set(ages, i, array.get(ages, i) + 1)
// Remove levels older than 500 bars or with 5+ touches
if array.get(ages, i) > 500 or array.get(touches, i) >= 5
SI.remove(index, i)
array.remove(levels, i)
array.remove(types, i)
array.remove(touches, i)
array.remove(ages, i)
SI.reindexAfterRemoval(index, i)
// Visualization
for idx in nearby.indices
line.new(bar_index, array.get(levels, idx), bar_index + 10, array.get(levels, idx),
color=array.get(types, idx) == "support" ? color.green : color.red)
```
Example 2: Multi-Timeframe Zone Detector
```pine
//@version=6
indicator("MTF Zones", overlay=true)
import username/SpatialIndex/1 as SI
// Store zones from multiple timeframes
var array zoneBottoms = array.new()
var array zoneTops = array.new()
var array zoneTimeframes = array.new()
// ATR-based spatial index for adaptive bucketing
var SI.SpatialBucket index = SI.newSpatialBucketATR(1.0, ta.atr(14))
SI.updateATR(index, ta.atr(14)) // Update bucket size with volatility
// Request higher timeframe data
= request.security(syminfo.tickerid, "240", )
// Detect HTF zones
if not na(htf_high) and not na(htf_low)
float zoneTop = htf_high
float zoneBottom = htf_low * 0.995 // 0.5% zone thickness
// Check if zone already exists nearby
SI.QueryResult existing = SI.queryRange(index, zoneBottom, zoneTop)
if array.size(existing.indices) == 0 // No overlapping zones
// Add new zone
array.push(zoneBottoms, zoneBottom)
array.push(zoneTops, zoneTop)
array.push(zoneTimeframes, "4H")
int idx = array.size(zoneBottoms) - 1
SI.addRange(index, idx, zoneBottom, zoneTop)
// Query zones near current price
SI.QueryResult nearbyZones = SI.queryProximity(index, close, 2.0) // Within 2%
// Highlight nearby zones
for idx in nearbyZones.indices
box.new(bar_index - 50, array.get(zoneBottoms, idx),
bar_index, array.get(zoneTops, idx),
bgcolor=color.new(color.blue, 90))
```
### Example 3: Performance Comparison
```pine
//@version=6
indicator("Spatial Index Performance Test")
import username/SpatialIndex/1 as SI
// Generate 500 random levels
var array levels = array.new()
var SI.SpatialBucket index = SI.newSpatialBucket(close * 0.02)
if bar_index == 0
for i = 0 to 499
float randomLevel = close * (0.9 + math.random() * 0.2) // +/- 10%
array.push(levels, randomLevel)
SI.add(index, i, randomLevel)
// Method 1: Linear scan (naive approach)
int linearCount = 0
float proximityPct = 5.0
float lowBand = close * (1 - proximityPct/100)
float highBand = close * (1 + proximityPct/100)
for i = 0 to array.size(levels) - 1
float level = array.get(levels, i)
if level >= lowBand and level <= highBand
linearCount += 1
// Method 2: Spatial index query
SI.QueryResult result = SI.queryProximity(index, close, proximityPct)
int spatialCount = array.size(result.indices)
// Compare performance
plot(result.queryCount, "Items Examined (Spatial)", color=color.green)
plot(linearCount, "Items Examined (Linear)", color=color.red)
plot(spatialCount, "Results Found", color=color.blue)
// Spatial index typically examines 10-50 items vs 500 for linear scan!
```
API Reference Summary
Initialization
- `newSpatialBucket(bucketSize)` - Fixed bucket size
- `newSpatialBucketATR(atrMultiplier, atrValue)` - ATR-based buckets
- `updateATR(sb, newATR)` - Update ATR for dynamic sizing
Adding Items
- `add(sb, itemIndex, price)` - Add item at single price point
- `addRange(sb, itemIndex, priceBottom, priceTop)` - Add item spanning range
Querying
- `queryProximity(sb, refPrice, proximityPercent)` - Query by percentage
- `queryRange(sb, priceBottom, priceTop)` - Query fixed range
- `queryAt(sb, price, tolerance)` - Query exact price with tolerance
- `queryProximityCached(sb, cache, refPrice, pct, duration)` - Cached query
Removing & Updating
- `remove(sb, itemIndex)` - Remove item
- `update(sb, itemIndex, newPrice)` - Update item price
- `updateRange(sb, itemIndex, newBottom, newTop)` - Update item range
- `reindexAfterRemoval(sb, removedIndex)` - Reindex after single removal
- `reindexAfterBatchRemoval(sb, removedIndices)` - Batch reindex
- `clear(sb)` - Remove all items
Utilities
- `size(sb)` - Get item count
- `isEmpty(sb)` - Check if empty
- `contains(sb, itemIndex)` - Check if item exists
- `getStats(sb)` - Get debug statistics string
- `calculateOptimalBucketSize(price, pct)` - Calculate optimal bucket size
- `sortIndicesDescending(result)` - Sort for safe removal
- `sortIndicesAscending(result)` - Sort ascending
Performance Characteristics
Time Complexity
- Add : O(1) for single point, O(m) for range spanning m buckets
- Remove : O(1) lookup + O(b) bucket cleanup where b = buckets item spans
- Query : O(k) where k = buckets in range (typically 3-5) vs O(n) linear scan
- Update : O(1) removal + O(1) addition = O(1) total
Space Complexity
- Memory per item : ~8 bytes for index reference + map overhead
- Bucket overhead : Proportional to price range coverage
- Typical usage : For 500 items with 50 active buckets ≈ 4-8KB total
Scalability
- ✅ 100 items : ~5-10x faster than linear scan
- ✅ 500 items : ~10-15x faster
- ✅ 1000+ items : ~15-20x faster
- ⚠️ Performance degrades if bucket size is too small (too many buckets)
- ⚠️ Performance degrades if bucket size is too large (too many items per bucket)
Best Practices
Bucket Size Selection
1. Start with 2-5% of asset price for percentage-based queries
2. Use ATR-based mode for volatile assets or multi-symbol scripts
3. Test bucket size using `calculateOptimalBucketSize()` function
4. Monitor with `getStats()` to ensure reasonable bucket count
Memory Management
1. Clear old items regularly to prevent unbounded growth
2. Use age tracking to remove stale data
3. Set maximum item limits based on your needs
4. Batch removals are more efficient than individual removals
Query Optimization
1. Use caching for repeated queries within same bar
2. Invalidate cache when index changes significantly
3. Sort results descending before removal iteration
4. Batch operations when possible (reindexing, removal)
Data Consistency
1. Always reindex after removal to maintain index alignment
2. Remove from arrays in descending order to avoid index shifting issues
3. Use batch reindex for multiple simultaneous removals
4. Keep external arrays and index in sync at all times
Limitations & Caveats
Known Limitations
- Not suitable for exact price matching : Use tolerance with `queryAt()`
- Bucket size affects performance : Too small = many buckets, too large = many items per bucket
- Memory usage : Scales with price range coverage and item count
- Reindexing overhead : Removing items mid-array requires index shifting
When NOT to Use
- ❌ Datasets with < 50 items (linear scan is simpler)
- ❌ Items that change price every bar (constant reindexing overhead)
- ❌ When you need ALL items every time (no benefit over arrays)
- ❌ Exact price level matching without tolerance (use maps instead)
When TO Use
- ✅ Large datasets (100+ items) with occasional queries
- ✅ Proximity-based filtering (% of price, ATR-based ranges)
- ✅ Multi-timeframe level tracking
- ✅ Zone/range overlap detection
- ✅ Price-based spatial filtering
---
Technical Details
Bucketing Algorithm
Items are assigned to buckets using integer division:
```
bucketKey = floor((price - basePrice) / bucketSize)
```
For ATR-based mode:
```
effectiveBucketSize = atrValue × atrMultiplier
bucketKey = floor((price - basePrice) / effectiveBucketSize)
```
Range Indexing
Items spanning price ranges are indexed in all overlapping buckets to ensure accurate range queries. The midpoint bucket is designated as the "primary bucket" for removal operations.
Index Consistency
The library maintains two maps:
1. `buckets`: Maps bucket keys → IntArray wrappers containing item indices
2. `itemToBucket`: Maps item indices → primary bucket key (for O(1) removal)
This dual-mapping ensures both fast queries and fast removal while maintaining consistency.
Implementation Note: Pine Script doesn't allow nested collections (map containing arrays directly), so the library uses an `IntArray` wrapper type to hold arrays within the map structure. This is an internal implementation detail that doesn't affect usage.
---
Version History
Version 1.0
- Initial release
Credits & License
License : Mozilla Public License 2.0 (TradingView default)
Library Type : Open-source educational resource
This library is designed as a public domain utility for the Pine Script community. As per TradingView library rules, this code can be freely reused by other authors. If you use this library in your scripts, please provide appropriate credit as required by House Rules.
Summary
SpatialIndex is a specialized library that solves a specific problem: fast proximity queries on large price-based datasets . If you're building indicators that track hundreds of levels, zones, or price points and need to frequently filter by proximity to current price, this library can provide 10-20x performance improvements over naive linear scanning.
The index-based architecture makes it universally applicable to any data type, and the ATR-based bucketing ensures it adapts to market conditions automatically. Combined with query caching and batch operations, it provides a complete solution for spatial data management in Pine Script.
Use this library when speed matters and your dataset is large.






















