SMC + Divergence Suite · TradingView (Pine v6)
SMC + Divergence Suite is a set of Pine Script v6 indicators and screeners for TradingView, built on Smart Money Concepts (a LuxAlgo SMC fork). The suite detects Order Blocks, Break of Structure (BOS), Change of Character (CHOCH) and Fair Value Gaps, and enforces an HTF/MTF bias filter, with multi-pair alerts grouped into chunks of 17 symbols. Alongside the SMC side, it ships a separate TD 9+13 plus multi-indicator divergence line, ported from LonesomeTheBlue's divergence work.
What sets it apart from an ordinary indicator is validation: the detection and execution logic was reimplemented in a Python backtester run on BTCUSDT 15M from 2017 to 2026 (roughly 299,000 bars), with the explicit goal of matching TradingView's Strategy Tester. Stack: Pine Script v6, Python, pandas, numba and Git for versioning.
Read the full case study →
The problem and motivation
Smart Money Concepts indicators are popular, but they share a fundamental weakness: they look convincing on a chart, yet nobody really knows whether their signals are profitable or just retroactively fitted noise. On TradingView, Pine code is bound to the platform engine, and testing a single configuration takes manual repainting, visual comparison and patience. You cannot run tens of thousands of parameter combinations, and you cannot audit why a given order filled at a given price.
The suite began as a fork of the SMC LuxAlgo code, brought up to Pine Script v6, and grew into a project with two tightly coupled parts: on one side the family of SMC indicators and strategies on TradingView, on the other an independent Python backtester that reproduces the same logic so it can be validated rigorously. The goal stated throughout the code is parity with TradingView's Strategy Tester: if the Python model and the Pine indicator produce the same trades, the backtest results become trustworthy.
Architecture and how it works
The Pine side comprises several entities: a single-pair indicator, a strategy variant with entries and exits, and a multi-pair screener. The core detector identifies Order Blocks (swing, internal and last), BOS and CHOCH, Fair Value Gaps, plus a higher-timeframe bias filter. On top of these sits a confluence system that scores a signal across multiple sources, a session filter and explicit repaint control.
The screener solves a real TradingView constraint: a single instance can request only a limited number of external symbols. The solution was to split the pair universe into chunks: each instance scans one chunk, and the user runs several instances to cover dozens of symbols. The screener was re-architected from five to ten chunks specifically to respect the security-call budget of the Premium plan. Each pair returns only primitive-typed tuples, to avoid Pine's known pitfalls around returning tuples from request.security.
The divergence line is a separate component: TD 9+13 (DeMark counting, with perfection logic on bars 8 or 9) combined with multi-oscillator divergence detection, ported from LonesomeTheBlue's work. Versions evolved from a single oscillator family to the full set of confluence sources, including multi-timeframe divergences and, where the TradingView plan allows, real footprint data (delta, POC, absorption).
The Python backtester and parity
The heart of validation is the Python backtester. It reimplements Order Block detection, the BOS and CHOCH state machine and the OB rejection logic, then runs them over the full BTCUSDT 15M series from 17.08.2017 to 09.03.2026, roughly 299,000 bars. The configuration in the code is aligned exactly to the input values of the TradingView entity: swing length, maximum rejection delay, maximum OB age, the 0.04% per-leg commission and the rest of the parameters are set to mirror exactly what the user sees in Pine.
The most important technical decision was moving the execution model from a 15-minute-bar evaluation to a per-minute evaluation. The V16.0 strategy replaced scalar request.security reads with request.security_lower_tf calls that return the full series of one-minute bars inside each chart bar. Order Block rejection, entry and stop-loss / take-profit checks are therefore evaluated minute by minute, exactly as in the Python loop. The strategy also enables the bar magnifier, so the broker emulator uses one-minute data for the true order of stop-loss versus take-profit fills within the same bar.
Engineering decisions and anti-fragility
Several subtle problems were resolved explicitly in the code, which says a lot about the project's maturity. One was the stop-geometry mirage: when an entry filled at the open of a gapped bar, the realized loss could far exceed the nominal risk. The fix, introduced in V16.2-Strat, was to recompute stop loss and take profit from the actual fill price rather than the signal price, mirroring the Python engine's behaviour.
Another was the intrabar entry storm: with the bar magnifier and after-fill recalculation, an alert could re-fire across several one-minute sub-bars and re-enter many times within a single one-hour bar. In one concrete case, the crash bar of 13.04.2024 at 23:00 produced seven full round-trips. The fix was a one-entry-per-bar guard using a varip variable, which persists inside the bar where a plain variable would have rolled back on recalculation. A rendering bug was also fixed here, where mitigated Order Blocks left a ghost box on the chart without affecting trade logic.
On performance, Order Block detection was identified as the real bottleneck: the pure Python loop cost between 18 and 66 seconds per swing length on the 299,000-bar series, and the parallel build was stalled by the slowest case. The fix was a faithful numba reimplementation, using a compact active list of the kind the reference library uses, avoiding a quadratic scan that would have been slower than pandas. The parity contract is strict: float32 dtype kept identical, sequential processing order bull before bear, and the Order Block, top and bottom arrays must match the reference implementation bit for bit.
Testing, sweeps and data
The backtester is not limited to a single configuration. There is a parallel sweep engine that runs at least ten thousand parameter variations per pair-timeframe combination, using multi-core multiprocessing and OB-detection caching keyed by swing length. The default grid produces 24,000 configurations per pair, sweeping stop-loss percentage, take-profit percentage, swing length, OB maturity and entry type. Benchmarking showed that 16 workers beat 32 on this cached-OB numeric workload, hyperthreading hurting in this specific case.
Data was collected both from crypto sources and from Dukascopy for forex, metals, stocks and indices, with dedicated fetch scripts and an .npz cache format alongside CSV. The parity check explicitly compares the Python engine's trade ledger against the Strategy Tester export from TradingView. Certain signal types, such as delta divergences that depend on TradingView's footprint, are clearly marked in the code as not backtestable, which reflects honesty about the limits of validation.
Outcome and current status
The project reached a high level of parity between model and platform: intermediate iterations reported profit-factor parity on the order of 98.5% on Order Block detection, and later work focused on closing the remaining gap, which was about execution-timing synchronization rather than detection. The version family evolved continuously, from the V14 and V15 series through V16.4, each step documented in the file headers with its motivation, the change and its impact on trades.
In its current form, the suite offers a practical toolkit for someone trading on Smart Money Concepts: SMC detectors on TradingView, multi-pair alerts, a complementary TD 9+13 divergence line and, beyond the chart, a backtester that allows rigorous verification of any configuration before risking real money. The value of the project lies not in one spectacular indicator, but in the discipline of aligning what is seen on the chart with what can be proven numerically.
Timeline
- 17/05/2026 Multi-pair screener re-architected to 10 chunks (V2.0), respecting the Premium plan's security-call budget.
- 19/05/2026 V16.0-Strat: per-minute execution model via request.security_lower_tf plus bar magnifier, for parity with the Python engine.
- 20/05/2026 Sweep engine grid expanded to 24,000 configurations per pair.
- 03/06/2026 V16.2-Strat: stop loss / take profit recomputed from the actual fill price, removing the stop-geometry mirage.
- 04/06/2026 V16.3-Strat: deterministic notional loss sizing and a one-entry-per-bar guard via varip.
- 12/06/2026 Additional tail data collected for crypto and the multi-asset Dukascopy series.