NW Volume Profile - Kernel-Smoothed [Dots3Red]📊 NW VOLUME PROFILE - KERNEL-SMOOTHED
A volume profile answers a different question than a normal chart. Instead of "how much traded today," it asks "how much traded at each price." This version applies Nadaraya-Watson kernel smoothing to that profile before reading any level off it — turning a jagged, noisy histogram into the actual underlying distribution of where volume concentrated.
🎯 WHY THIS MATTERS
A raw volume profile is built from independent price bins — each one only knows its own volume, nothing about its neighbors. That makes it noisy: a single oversized candle can create a spike that looks like an important level but is really just where one bar happened to land. Reading real structure off a raw histogram means squinting past that noise.
This script smooths the profile before drawing anything. Every bin's displayed value becomes a weighted average of its neighborhood — nearby bins count heavily, distant bins barely at all, following a Gaussian curve. The lumps from individual candles melt away, and what's left is the true shape of the distribution that was underneath the noise the whole time. All the levels described below — POC, Value Area, HVN, LVN — are read from that smoothed curve, not the raw one.
🧮 HOW THE SMOOTHING WORKS
Each price bin's raw volume gets replaced by:
smoothed(i) = Σⱼ w(i,j) · raw / Σⱼ w(i,j)
where w(i,j) is a Gaussian weight based on how many bins apart i and j are, controlled by the Bandwidth setting. A small bandwidth stays close to the raw histogram; a large one produces one broad, simplified hump. This is genuine kernel regression applied across the price axis, not a moving average or a visual blur — it's the same mathematical technique used in the smoothed lines several Dots3Red scripts already use for slope/trend estimation, applied here to a distribution instead of a time series.
Toggle "Show Raw Histogram Behind" to see the original jagged bars faintly displayed underneath the smoothed profile — a direct before/after comparison on your own chart.
📏 WHAT EACH LEVEL MEANS
🟡 POC (Point of Control) — the single price with the highest smoothed volume. The market's center of gravity for the current window; price tends to be pulled back toward it.
🔵 Value Area — the price region around the POC containing a configurable share of total volume (default 70%). Price trading inside it is trading at a level the market recently agreed was fair — chop and rotation are common here. Price breaking out of it is the market rejecting that agreement, which is often when moves extend rather than stall.
🟢 HVN (High Volume Node) — a secondary local peak in the smoothed distribution. Acts like a sticky zone; price tends to slow down or pause when revisiting one.
🔴 LVN (Low Volume Node) — a local trough where very little volume ever traded. Acts like a thin spot; price tends to move through it quickly rather than lingering, since few positions were ever opened there.
HVN and LVN are drawn as full-width dotted lines across the chart (not just labels at the profile edge), specifically so they stay visible and trackable even after price has moved well away from where the profile itself was drawn.
🧭 HOW TO USE
👀 Start with where price sits relative to the Value Area. Inside it: expect rotation and two-way trade. Outside it: the move has already broken from recent consensus, which historically has more follow-through than reversion.
🧲 Treat POC as a magnet, not a wall. It is the level most likely to be revisited, not a guaranteed reversal point. How price behaves when it gets there — accepted or rejected — is the actual signal, not the level itself.
🐌 Expect hesitation at HVNs. A move approaching an HVN from your prior window is approaching a zone where the market has previously done a lot of business — some slowing or consolidation there is common.
⚡ Expect speed through LVNs. A thin zone with very little historical volume tends to get crossed quickly rather than acting as support or resistance. If price is moving toward one, a fast move through it before finding real support/resistance at the next node is a reasonable expectation.
🔧 Adjust Bandwidth to match what you're looking for. A tighter bandwidth reveals more granular structure (closer to raw); a wider one collapses the profile into its dominant, unmistakable levels. There's no universally correct setting — it depends on whether you want detail or clarity.
💡 EXAMPLE
Say the profile shows POC at 61,200, a Value Area from 60,400 to 62,100, and an LVN line sitting at 59,800. Price later drops to 60,450 — right at the edge of the Value Area. Two distinct scenarios are now readable from the profile: if price holds and turns back up, the 61,200 POC above is the natural target the market has repeatedly gravitated toward. If instead price breaks below 60,400, the empty LVN at 59,800 offers little historical volume to slow the decline — a fast move through that zone before finding the next real level is the more likely path. Same chart, two different expectations, both read directly off the same profile without any additional indicator.
⚙️ SETTINGS
📊 Profile
• Lookback (bars) — size of the rolling window the profile is built from
• Price Bins — vertical resolution of the profile
• Body Volume Only — distribute volume across the candle body instead of the full high-low range
🧮 Kernel Smoothing
• Bandwidth — width of the Gaussian kernel in bin units; controls detail vs. simplification
📏 Levels
• Value Area % — share of total volume the Value Area is expanded to contain
• Node Detection Leg — how many neighboring bins define a local peak/trough
• LVN Max Ratio of POC — how thin a trough must be, relative to POC, to count as an LVN
🎨 Visualization
• Show Raw Histogram Behind, POC Line, Value Area, HVN/LVN Marks — each independently toggleable
• Profile Width — how far the profile extends horizontally
🖥️ Dashboard
• Show/hide, position — displays current POC, Value Area bounds, node counts, and the active window/bandwidth settings
📝 NOTES
This profile is a rolling window — its levels update as the window slides forward with each new bar, which is expected behavior for a volume profile rather than a repainting signal (nothing appears and then vanishes; the underlying window is simply moving). Thin-volume symbols will produce a ragged profile regardless of smoothing settings — this tool is most informative on liquid instruments with consistent volume.
⚠️ DISCLAIMER
This is an analytical and visualization tool. It does not generate trade signals and does not constitute financial advice. Historical volume concentration at a given level does not guarantee how price will behave there in the future. Indicator

Breakout & Retest Entry Signals & the Break-vs-RetestOVERVIEW
"Wait for the retest" is the most repeated piece of advice in breakout trading. It is also, as far as I can tell, completely untested by the people who repeat it.
This tool settles it — on your instrument, with your settings — by taking BOTH entries on the SAME breaks and grading them against the same control:
PER-TRADE EDGE expectancy vs control · n
Break entry +0.09R +0.02R · n=412
Retest — CLEAN +0.31R +0.02R · n=118
Retest — DEEP -0.04R +0.02R · n=76
clean vs deep (t) 3.41 CLEAN IS BETTER
BUT — HOW OFTEN DO YOU GET IT?
Breaks that ever retested 47.0% (194/412)
after a run of >3 closes 31.2% vs 55.8% otherwise
False-break rate 13.3%
EXPECTED VALUE PER BREAK
Take every break +0.09R (100% of breaks)
Wait for the retest +0.06R (47% of breaks)
VERDICT NO DIFFERENCE — pick either
That last block is the entire point. A better per-trade edge is worthless if you only get the trade half the time — so the WAIT policy is scored as P(retest) x E , because on every break that never retests you get NOTHING. The two are then compared with a significance test, and the verdict is allowed to be "no difference".
It is a research and framing tool. NOT a strategy, NOT a signal service, NOT a validated edge.
WHAT IT ALREADY FOUND — measured live on NIFTY futures
timeframe breaks retested false breaks verdict
1m 334 49.4% 29.6% NO DIFFERENCE
3m 323 53.3% 13.6% NO DIFFERENCE
5m 328 53.4% 14.0% NO DIFFERENCE
15m 306 51.0% 12.7% TAKE THE BREAK
1h 274 50.0% 16.4% NO DIFFERENCE
TWO THINGS JUMP OUT.
The retest rate is 50-53% on every timeframe. Bulkowski, measuring throwbacks across 10,348 chart patterns on US daily stocks, found 50-60%. A completely different market, a completely different method, and the same number. That is a real phenomenon, not an artefact of the detector.
The false-break rate is 26.5% on the 1m and 13-15% everywhere else. THE ONE-MINUTE BREAK IS TWICE AS LIKELY TO BE A LIE. That is not folklore, it is this instrument's own number, and it is exactly the kind of thing a trader should know before choosing a timeframe.
And the verdict, on four of the five: NO DIFFERENCE — pick either. Once the geometry is honest and the test is a real one, the great break-versus-retest argument simply does not resolve on this instrument at most speeds. On the 15m it does resolve — and it says TAKE THE BREAK, which is the opposite of what almost everyone will tell you.
That is what a measurement looks like. It disagrees with the folklore on one timeframe, refuses to take a side on four others, and does not care what you were hoping for. No tool that needs to sell you a signal would ever print "NO DIFFERENCE".
THE ONE THING EVERYONE GETS BACKWARDS
Thomas Bulkowski measured throwbacks and pullbacks across 10,348 chart patterns. His finding:
"Do throwbacks hurt performance? YES: 97% of the time chart patterns with upward breakouts
perform better post-breakout WITHOUT a throwback."
"Do pullbacks hurt performance? YES: 91% of chart pattern types with downward breakouts
perform better if a pullback does NOT occur."
Read that again. The retest is not a gift. It is a SYMPTOM — evidence that the move is weak, that supply came back, that the break did not have the strength to run.
And yet "wait for the retest" is good advice for a completely different reason: it gives you a better price and a tighter stop.
BOTH ARE TRUE AT ONCE. They are two opposing effects on the same trade, and they have never been put on one scale and netted out. That is what this script does. The retest may still win — a better entry can outweigh a weaker move — but nobody has ever checked, and the answer is different on every instrument and every timeframe.
A CLEAN RETEST AND A DEEP ONE ARE NOT THE SAME EVENT
Bulkowski again, and this is his sharpest single finding on the subject: during a throwback, if price REMAINS ABOVE the breakout price the subsequent rise averages 40%. If it drops BELOW the breakout price and then recovers, the rise averages 29%. That is 400 samples versus 2,767.
Pooling those two throws away the strongest signal in the whole idea. So they are separated:
CLEAN retest — price came back and touched the level, but never CLOSED back through it.
DEEP retest — price CLOSED back through the level, then recovered.
They are graded separately, tested against each other, and labelled separately on the chart. If clean beats deep on your instrument, then "wait for the retest" is not one rule — it is two, and only one of them works.
AND CAN YOU SEE IT COMING?
The real, unpriced cost of a WAIT policy is that roughly half the time you never get filled. So it matters enormously whether you can predict which breaks will retest.
Bulkowski found that if price has more than three consecutively higher closes ending the day before the breakout, the throwback probability drops materially. So the panel reports the retest rate SPLIT BY THAT:
after a run of >3 closes 31.2% vs 55.8% otherwise
If the split is real on your instrument, then after a strong run into the break you should simply TAKE IT — because the retest you are waiting for is probably never coming.
IS YOUR VOLUME FILTER EARNING ITS KEEP?
Every trader is taught that a breakout must be confirmed by volume. Bulkowski's volume study says that after an ABOVE-average-volume breakout, FAILURES DOUBLE and the likelihood of a throwback TRIPLES, while the move itself is barely better.
That is testable — but only if the low-volume breaks are allowed into the sample. So VOLUME IS NOT A GATE ON THE RECORD. Every break is recorded; volume gates only the SIGNAL. The panel then reports what your filter is actually worth:
Break ON volume +0.11R n=246
Break OFF volume +0.06R n=166
on vs off (t) 0.82 no difference — it is doing nothing
The record is a fact about the market. The filter is a decision about the trade. They are kept apart, and this is what happens when you stop assuming and start measuring.
IDENTICAL GEOMETRY — and why this is not a detail
The target used to be THE NEXT OPPOSING LEVEL. That quietly destroyed the entire experiment.
The BREAK entry sits PAST the level (it closed through it). The RETEST entry sits BACK AT the level. So the retest is systematically FARTHER from the next opposing level, and was therefore being handed a BIGGER R:R for the SAME RISK — on every single trade, by construction. Live, that produced an R:R of 5.0 on one timeframe and 0.66 on another, and the on-chart key was cheerfully claiming "identical geometry" while the geometry was tilted toward the retest.
The trade now uses a FIXED R multiple, identical for the break, the retest and the control. The next opposing level is still drawn, and still tested — separately, as a descriptive statistic, with its hit rate reported next to its distance in R.
THE ANTI-BIAS GUARDS
ENTRY IS THE CLOSE, for both entries and for the control. Entering the retest AT the level — a better price than the close — while the break enters at its close would hand the retest a free head start on every trade, and settle the oldest argument in trading by rigging it.
THE CONTROL IS DIRECTION-MATCHED. Breaks run with the trend, so a direction-skewed event set measured against a symmetric 50/50 control inherits the drift for free and calls it an edge. Longs are compared only with control longs, shorts only with control shorts, and the control is blended back using the events' OWN direction mix.
EVERY VERDICT IS A TEST, NOT A COMPARISON. Break-vs-wait, clean-vs-deep, volume-on-vs-off — each is a Welch t-test that has to clear |t| > 1.96 before it is allowed to be a finding. For the wait policy, the variance of P(retest) x E is propagated by the delta method, because it is a product of two estimates and both carry error. A verdict that flips on a tenth of an R is not a verdict, it is noise wearing a costume.
Both barriers on one bar: the STOP is assumed first — conservative, and the only assumption that cannot flatter the result. Unresolved trades at the horizon are marked to market, not booked as losses.
THE LEVELS
Levels come from the extrema of a KERNEL-SMOOTHED price series (Nadaraya-Watson) rather than raw pivots, so they track the structure rather than the noise. A break requires a CLOSE beyond the level with displacement, not a wick. A false break is one that closes back inside quickly. All of it is computed on confirmed bars; the kernel is causal and never looks forward.
NON-REPAINT
The kernel confirms an extremum a half-window late, so a level appears some bars AFTER the swing that created it. That lag is the price of not repainting and it is paid deliberately. Levels, breaks, false breaks, retests, signals and every calibration event are computed on CONFIRMED bars only. Nothing is drawn and then moved.
DATA AND SCOPE
Any symbol, any timeframe. ATR-normalised throughout. Volume improves the SIGNAL but is not required, and it never gates the RECORD.
EXPORTS (Data Window — consume from other scripts via input.source())
EXP_Level, EXP_Break, EXP_FalseBreak, EXP_Retest, EXP_Entry, EXP_Stop, EXP_Target, EXP_NextLevel, EXP_WaitEdge
CONCEPT CREDIT
Support/resistance, polarity and the breakout-retest idea are long-standing public trading concepts with no single author; the written tradition runs through Charles Dow, Richard Wyckoff and Edwards & Magee. The formal TRADING-RANGE BREAK was first tested at scale by William Brock, Josef Lakonishok and Blake LeBaron, Journal of Finance 47(5), 1992 — and their results were later shown to be vulnerable to data-snooping (Sullivan, Timmermann and White, 1999), which is exactly why this tool measures the rule on YOUR instrument rather than asserting it.
The throwback and pullback statistics that motivate the clean/deep split, the run-length predictor and the volume test are from Thomas Bulkowski ("Encyclopedia of Chart Patterns"; thepatternsite.com). His numbers are measured on US daily stocks. Whether they hold on YOUR instrument is precisely the question this script exists to answer — and it may well answer "no".
Nadaraya-Watson kernel regression — Nadaraya and Watson (1964); its use for technical pattern recognition — Lo, Mamaysky and Wang, Journal of Finance 55(4), 2000. Triple-barrier forward labelling — Marcos Lopez de Prado. Welch's t-test — B. L. Welch. ATR — J. Welles Wilder.
The break-vs-wait availability weighting, the delta-method significance test, the clean/deep retest split, the volume-filter test and the direction-matched control are the author's own. Clean-room implementation; no third-party Pine code is reused. Not affiliated with, nor endorsed by, any of the above.
HONESTY AND LIMITATIONS
Calibration is IN-SAMPLE, with no costs or slippage, and uses overlapping windows. A proven in-sample edge is NOT a guarantee out-of-sample. Real fills, spreads and commissions will reduce it — and they will hurt the break entry more than the retest entry, because the break enters into momentum.
Bulkowski's throwback statistics are measured on US daily stocks over decades. They are the reason the questions are asked. They are NOT the answer, and this tool will tell you so if your instrument disagrees.
The verdict is allowed to be "NO DIFFERENCE — pick either", and on many instruments it will be. That is a real result. A tool that cannot report its own failure is an advertisement, not a measurement.
Nothing in this script predicts price.
DISCLAIMER
Research and educational tool only. NOT financial advice, NOT a recommendation, and NO guarantee of results. Entry, stop and target output is arithmetic, not advice. Trading carries risk of loss. Test out-of-sample and make your own decisions. The author accepts no liability for any use.
Indicator

Machine Learning Price Bands Kernel Regression SignalsOVERVIEW
Every "AI band" on this platform draws two lines and asserts them. None of them can tell you how often price actually stays inside.
This one can — because it is built on a method that comes with a MATHEMATICAL COVERAGE GUARANTEE, and then it CHECKS WHETHER IT KEPT THE PROMISE, live, on your chart:
Coverage (empirical vs nominal) 89.1% vs 90% n = 20,266
Is the miss REAL? -0.9 pp z = -4.3 (real)
Verdict undercovering — real, but small
That is not a band. That is a prediction interval that has been audited, and it is the whole reason this tool exists.
It is a research and framing tool. NOT a strategy, NOT a signal service, NOT a validated edge.
THE MACHINE LEARNING, SPELLED OUT — no buzzwords, here is the actual model
1. NADARAYA-WATSON KERNEL REGRESSION. Non-parametric: no functional form is assumed, the data chooses the shape. Each past bar votes on the current estimate with a Gaussian weight that decays with distance. This is the same estimator Lo, Mamaysky and Wang used in the Journal of Finance to make chart-pattern recognition objective. It is real machine learning, and it is sixty years old.
The kernel here is CAUSAL. It only ever looks backwards. A centred kernel — the kind most "Nadaraya-Watson envelope" scripts use — peeks at bars that have not happened yet, and that is why their historical fit looks so much better than their live one.
2. BANDWIDTH BY PREDICTIVE MODEL SELECTION. The bandwidth h is the only real parameter, and it is not a magic number: several candidates are run in parallel and scored on their ROLLING ONE-STEP-AHEAD SQUARED ERROR. The winner is used. That is honest model selection — the criterion you would use to choose any forecaster — rather than a knob you turn until the chart looks nice.
3. CONFORMAL PREDICTION INTERVALS. The half-width is the (1-alpha) empirical quantile of the recent ABSOLUTE one-step-ahead errors. Under exchangeability this carries a FINITE-SAMPLE coverage guarantee, with NO distributional assumption at all: no normality, no GARCH, no volatility model. The model's own recent mistakes size the band — which is why it widens when the model starts being WRONG, not merely when price starts moving.
4. ADAPTIVE CONFORMAL INFERENCE — Gibbs and Candes, NeurIPS 2021.
Here is the problem with plain conformal prediction on markets, stated plainly: its guarantee holds under EXCHANGEABILITY, and financial returns are the textbook counterexample. Volatility CLUSTERS. So a residual quantile computed over a trailing window is always a step behind, the band is too narrow exactly when it matters, and the misses bunch together. Coverage lands quietly under nominal. Measured live on NIFTY futures before this was added: 89.1% against a nominal 90%, on the 1m, the 3m and the 1h, every one of them roughly four standard errors below target. Not a bug. The assumption breaking.
ACI makes the miscoverage level a LEARNED parameter:
alpha(t+1) = alpha(t) + gamma * (alpha - err(t))
Miss the interval and alpha falls, so the quantile rises and the band WIDENS. Cover it and alpha creeps back, so the band TIGHTENS. Long-run coverage provably converges to the target IRRESPECTIVE OF THE DATA GENERATING PROCESS — no exchangeability assumption anywhere.
A band that notices it is undercovering and fixes itself. Watch the alpha row: where it settles BELOW nominal is a direct measurement of how badly exchangeability fails on your instrument.
MEASURED, ON THE SAME INSTRUMENT, BEFORE AND AFTER:
timeframe plain conformal with ACI
1m 89.1% 90.1%
3m 89.1% 90.1%
5m 89.1% 90.1%
15m 90.1% 90.1%
1h 89.1% 90.1%
(nominal 90%)
Five timeframes, a four-standard-error undercoverage on four of them, closed. The binomial test now returns "calibrated — within sampling noise" and means it. That is not a backtest of a trading rule. That is a mathematical promise being kept, and being checked.
5. NORMALISED NONCONFORMITY — Papadopoulos et al. (2008), Lei et al. (2018).
The plain score |price - fit| is a SCALAR, which means the band is THE SAME WIDTH in a dead tape and in a crash. It therefore OVERCOVERS in calm and UNDERCOVERS in chaos — and the single marginal coverage figure is the average of those two errors, looking correct while being wrong in both directions.
Normalising divides each residual by a local scale estimate before taking the quantile, and multiplies it back when drawing:
score = |price - fit| / sigma band = fit +/- q * sigma
The band now scales with LOCAL DIFFICULTY — and note it is the MODEL'S difficulty, not the market's volatility. Related, but not the same thing, and the first one is what a prediction interval is actually about.
6. THE COVERAGE AUDIT. A guarantee you do not verify is just a claim.
TWO QUESTIONS ABOUT THE COVERAGE, AND THE PANEL ANSWERS BOTH
IS THE MISS REAL? That is a binomial z-test and it needs no tolerance at all. Each bar is a Bernoulli trial with p = nominal, so the standard error of the observed coverage is sqrt(p(1-p)/n).
IS THE MISS BIG ENOUGH TO CARE ABOUT? That is a judgement, and you set it.
These are NOT the same question, and conflating them is how a band gets waved through as "calibrated". Measured live on NIFTY futures: at n = 20,266 the standard error is 0.21 pp, so an empirical coverage of 89.1% against a nominal 90% is a 0.9 pp miss — FOUR STANDARD ERRORS. Unmistakably real. Arguably too small to trade differently. A 5 pp tolerance called that "calibrated", which was the headline row of the script asserting the one thing the script exists to verify, and asserting it wrongly.
The panel now reports the size of the miss, its significance, and a verdict that distinguishes "within sampling noise" from "real, but small" from "MISCALIBRATED — do not trust the band". You get to decide which of those matters to you, and you get the numbers to decide with.
AND THEN THE ROW NOBODY HAS: CONDITIONAL COVERAGE
Coverage 90.0% vs 90% n = 20,178
calm / normal / turbulent 96.4% · 90.1% · 83.2%
A single marginal number can read a perfect 90% while the interval covers 96% of quiet bars and 83% of violent ones. Ninety per cent is then the AVERAGE OF TWO ERRORS — it looks right while being wrong in both directions, and it is wrong in the direction that costs you money exactly when it costs you money.
Exact conditional coverage is provably impossible without strong assumptions. But you can always MEASURE it, and almost nobody does. Bars are split into calm, normal and turbulent thirds by the percentile rank of ATR, and coverage is scored inside each. If the three numbers fan apart, the band is not breathing — and the normalised score is what closes the gap.
Turn the normalised score off and watch those three fan out. That is the demonstration.
FADE OR FOLLOW? THE TOOL DOES NOT PRETEND TO KNOW
Price leaving a 90% interval is statistically unusual. Whether to FADE it (an outlier, so bet on reversion) or FOLLOW it (the model has broken, so bet on the new regime) is an EMPIRICAL question, and the honest answer is often neither.
So both are logged, both are graded, and BOTH ARE TESTED AGAINST EACH OTHER.
That last part matters more than it sounds. Knowing that fading beats an unconditional control, and that following also beats an unconditional control, does not answer the question a trader is actually asking at a band break — which of the two should I do? They are mutually exclusive responses to the SAME event. So they are run head to head with a Welch t-test, and the answer is allowed to be:
FADE or FOLLOW? NEITHER — the break does not tell you which
If the difference does not clear the noise, then on this instrument the break carries no directional information, and saying so IS the finding. A tool that cannot report its own failure is an advertisement, not a measurement.
And the chart agrees with the panel. An unproven direction is still drawn — it is arithmetic, and you may want it — but it is drawn MUTED and labelled "(not proven)". It used to print "Follow the break" in full colour while the panel directly beneath it said "neither proven". The paint has to agree with the code.
THE ANTI-BIAS GUARDS
ENTRY IS THE CLOSE, for the event and for the control alike. A band break is a SIGNAL, not a fill. Entering at the band — a better price — while the control enters at the close hands every signal a free head start and manufactures an edge out of nothing.
THE CONTROL IS DIRECTION-MATCHED. In a downtrend there are more break-downs than break-ups, so FOLLOW skews short and FADE skews long. A direction-skewed event set measured against a 50/50 control inherits the index drift for free and calls it an edge. Longs are compared only with control longs, shorts only with control shorts, and the control is blended back using the events' OWN direction mix.
IDENTICAL GEOMETRY. Every event and every control trade uses the same stop and the same R multiple, so the comparison is apples to apples.
Both barriers on one bar: the STOP is assumed first — conservative, and the only assumption that cannot flatter the result. Unresolved trades at the horizon are marked to market, not booked as losses. Nothing is marked proven below t = 1.96.
NON-REPAINT
The kernel is causal, the bandwidth is chosen on past error only, the interval is built from past residuals, and coverage is scored by asking whether the actual close landed inside the interval that was published BEFORE it. Everything is computed on confirmed bars. Nothing is drawn and then moved.
WHY THESE PARTS ARE ONE TOOL
The regression gives the trend. Without the interval, a band is a guess. Without model selection, the bandwidth is a knob you turn until you like the picture. Without the coverage audit, a conformal interval is an unverified promise. And without the signal calibration, "price left the band" is folklore. Each piece is worthless alone — which is exactly why they ship together.
DATA AND SCOPE
Any symbol, any timeframe. ATR-normalised throughout. No volume required.
EXPORTS (Data Window — consume from other scripts via input.source())
EXP_Fit, EXP_Upper, EXP_Lower, EXP_Bandwidth, EXP_Coverage, EXP_Miscal, EXP_Signal, EXP_Entry, EXP_Stop, EXP_Target
CONCEPT CREDIT
Nadaraya-Watson kernel regression — E. A. Nadaraya and G. S. Watson (1964). Its use for technical pattern recognition in finance — Andrew W. Lo, Harry Mamaysky and Jiang Wang, "Foundations of Technical Analysis", Journal of Finance 55(4), 2000. Conformal prediction — Vladimir Vovk, Alexander Gammerman and Glenn Shafer; the split/inductive form used here follows Papadopoulos et al. and Lei et al. Triple-barrier forward labelling — Marcos Lopez de Prado. Welch's t-test — B. L. Welch. ATR — J. Welles Wilder.
The causal-kernel implementation, the parallel bandwidth selection, the live coverage audit, the binomial calibration test and the fade-versus-follow head-to-head are the author's own. Clean-room implementation; no third-party Pine code is reused. Not affiliated with, nor endorsed by, any of the above.
HONESTY AND LIMITATIONS
Conformal coverage is guaranteed under EXCHANGEABILITY. Financial returns are NOT exchangeable — volatility clusters, regimes shift — so the guarantee is approximate in practice. THAT IS PRECISELY WHY THE COVERAGE IS AUDITED LIVE INSTEAD OF ASSUMED. When empirical coverage drifts from nominal you are watching the assumption break, in real time, and you should believe what you see rather than the label.
A prediction interval says where price is LIKELY TO BE. It says nothing about DIRECTION, and it is not a forecast. Coverage being correct does not make band breaks tradeable — those are two different claims, and the tool tests them separately for exactly that reason.
Calibration figures are IN-SAMPLE, with no costs or slippage, and use overlapping windows. A proven in-sample edge is NOT a guarantee out-of-sample. Nothing here predicts price.
DISCLAIMER
Research and educational tool only. NOT financial advice, NOT a recommendation, and NO guarantee of results. Entry, stop and target output is arithmetic, not advice. Trading carries risk of loss. Test out-of-sample and make your own decisions. The author accepts no liability for any use. Indicator

Support & Resistance Confluence Levels, Hold Record & ReversalOVERVIEW
Four lines. Two above price, two below. That is the whole chart.
Every other support/resistance tool has the opposite problem. It finds forty levels and leaves you to work out which two matter. Forty levels is not information, it is wallpaper — and a level you have to hunt for is a level you will not trade.
So this tool inverts the design. It does not ask "where are the levels?" It asks:
WHICH LEVEL WOULD I ACTUALLY TRADE, RIGHT NOW, AND WHY SHOULD I BELIEVE IT?
A price is only promoted to a level when SEVERAL INDEPENDENT METHODS AGREE ON IT. One method finding a level proves nothing — every method finds levels everywhere. The signal is AGREEMENT.
This is a research and framing tool. It is NOT a strategy, NOT a signal service, and NOT a validated edge.
THE SIX VOICES — four propose, two confirm
PROPOSERS. Each nominates candidate prices, independently:
◆ SWING PIVOT the classic. Where price actually turned.
~ KERNEL EXTREMUM the turning point of the SMOOTHED price (Nadaraya-Watson), which is the shape
rather than the noise. This is Lo, Mamaysky and Wang's method, and it finds
structurally different levels from a raw pivot. That independence is exactly
what makes agreement between the two worth something. Agreement between two
methods that make the same mistakes is worth nothing at all.
⇈ HIGHER TIMEFRAME a swing on the HTF. The level a bigger participant is watching.
▣ PRIOR PERIOD yesterday's high and low. Last week's high and low. The most watched prices on
any chart — and missing from almost every auto-S/R script on PulseWire.
CONFIRMERS. They do not nominate, they vouch:
▪ VOLUME NODE the level sits where volume actually transacted. Real business was done here,
not merely a turning point.
○ ROUND NUMBER the psychological grid.
Candidates within an ATR tolerance merge, and the merged level inherits every voice that spoke for it. A level needs MIN VOICES to exist at all. Everything below that is DISCARDED, not hidden. Then only the nearest two above and two below are drawn.
The label tells you why the level is there: "◆~▣▪ 4v held 3/4 24,247.00" — four independent voices, tested four times, held three.
AND THEN THE PART NOBODY DOES: WE TEST WHETHER CONFLUENCE ACTUALLY RANKS
"Levels are stronger when several methods agree" is one of the most repeated claims in technical analysis and almost nobody has ever checked it. It is checkable. So the panel reports:
High confluence (3+) +0.24R n=61 PROVEN
Low confluence -0.03R n=88
Control (unconditional) +0.02R n=240
DOES CONFLUENCE RANK? YES — more voices IS better
And the control is DIRECTION-MATCHED. Reversals at support are overwhelmingly LONG on a drifting index — and a long-biased event set compared against a 50/50 control is handed the drift for free and calls it an edge. Longs are compared only with control longs, shorts only with control shorts, and the control is then blended back using the events' OWN direction mix. It is a subtle trap and it will manufacture an edge out of nothing if you let it.
And the verdict is a TEST, not a comparison. High confluence is measured against low confluence with a Welch t-test, and the difference must clear |t| > 1.96 before it is allowed to be a finding. Below that, the panel prints the least satisfying answer there is — NO DIFFERENCE — because that is the honest one. A tool that reports a 0.02R gap as a verdict is not measuring anything, it is decorating.
If the extra voices do not rank on your instrument, then on your instrument they do not rank, and no amount of agreement between methods will change that. That row is the reason this script exists.
THE HOLD RECORD — and why "held 3/4" is not what most scripts mean by it
A TEST IS AN EPISODE, NOT A BAR. Price arrives at the level and the test stays OPEN until price LEAVES it — back the way it came (HELD) or straight through (BROKE). A bar that closes INSIDE the zone has resolved nothing and is counted as nothing.
Counting every touching bar as a completed test drops an entire consolidation into the denominator as failures, and manufactures hold rates near 10% that say nothing about the level and everything about the counter. An unresolved test is neither a hold nor a break, exactly as an unresolved trade is neither a win nor a loss.
AND A TEST IS AN APPROACH, NOT A BAR TOUCHING A BOX. Price exits the zone (HELD), the next bar dips straight back in — and without a re-arm rule that counts as a brand-new test. Chop sitting on a level then logs a hundred "tests" that were really one event. Measured live before this was fixed: 224 tests of a single level on a 5m chart, and hold rates that all landed between 61% and 75% no matter which level you looked at. A statistic that cannot tell any two levels apart is not measuring the levels — it is measuring the bar size. Price must now travel clear of the zone before the level can be tested again. One approach, one test.
The volume filter gates the SIGNAL and never the RECORD. A level that holds on thin volume still HELD. Quietly dropping it from the numerator while leaving it in the denominator is how a hold rate gets manufactured.
IF TWO ZONES OVERLAP, THEY ARE THE SAME LEVEL
The merge tolerance is held to at least the combined zone half-widths. Otherwise two levels a fraction of an ATR apart refuse to merge and then draw overlapping boxes anyway, and the geometry contradicts itself on the chart for anyone to see. It is a small thing that quietly tells you the tool was never looked at.
A LEVEL IS AN ANCHOR, NOT A TRAILING AVERAGE
Levels merge as new candidates arrive, and the merged price is a COUNT-WEIGHTED mean: the tenth candidate moves the level by a tenth of the gap, not half of it. This sounds like a detail. It is not. A level that moves halfway toward every new candidate will slide toward price — because price is where new candidates come from — until it is no longer an anchor at all, but a trailing average sitting in the middle of the action, "tested" on every swing. The maths here is the difference between a level and a moving average with extra steps.
Levels are retired by DISTANCE, and confluence buys REACH. A level far from price is useless however many voices it has; a level at price is what you are trading. But eviction cannot simply drop the weakest, either — every level is BORN with one voice, so a weakest-first rule kills every new level in the cradle, before it can earn a second, and the chart slowly fills with ancient far-away fossils while nothing can form where price actually is. Confluence buys a level the right to be further away. It does not buy it immortality.
THE REVERSAL TRADE — because nobody looks at a level to admire it
Price tests the level and closes back out. Entry at the CLOSE, stop beyond the level, target a fixed R multiple.
ENTRY IS THE CLOSE, for the event and for the control alike. A rejection is a SIGNAL, not a fill.
Entering at the level — a better price — while the control enters at the close hands every level a
free head start, and it would "win" without the level having done anything at all.
THE R MULTIPLE IS FIXED so that the event and the control are measured on IDENTICAL geometry. A
variable target against a fixed-target control is not a comparison: the near target is reached more
often AND resolves inside the grading horizon more often, so the two are not even being asked the
same question.
THE NEXT OPPOSING LEVEL is drawn too, and separately tested: is it reached before the stop, and HOW
FAR AWAY IS IT IN R? A hit rate with no distance attached is a fact about the distance, not about
the levels — a target half a unit of risk away being reached often proves nothing.
Signals fire only at the levels actually on screen. Every level keeps its record; only the ones you are watching can fire. You do not trade a level twelve levels away from price.
And when a level BREAKS, you are told. A level holding is the reversal; a level giving way is the other half of why anyone draws one. Breaks are marked with an x and carry their own alerts — reported as pure information, with no trade framed and no claim made, because the break is not what this engine calibrated. Saying so is cheaper than pretending otherwise.
NON-REPAINT, AND ITS HONEST COST
Pivots confirm some bars late. The kernel extremum confirms a half-window late — a centred kernel looks into the future, and we refuse to. So a level appears some bars AFTER the swing that created it. That lag is the price of not repainting and it is paid deliberately.
Levels, tests, holds, breaks, signals and every calibration event are computed on CONFIRMED bars only. The HTF read uses lookahead_off. Nothing is drawn and then moved.
DATA AND SCOPE
Any symbol, any timeframe. ATR-normalised throughout. Volume improves the score but is NOT required — without it the volume-node voice simply abstains rather than guessing.
HOW TO USE
0. Turn the KEY on once (Dashboard & theme > Show the key). It explains the six glyphs. Turn it off
again — you only need it the first time.
1. MIN VOICES is the one input that matters. 1 gives you the forty-line wallpaper every other S/R
script gives you. 2 requires agreement. 3 shows only the prices several independent methods
arrived at on their own. Raise it until the chart shows levels you would actually trade.
2. Read the hold record. "Held 3/4" tells you more than any colour ever will.
3. READ THE CONFLUENCE VERDICT BEFORE YOU WEIGHT ANY OF IT. If the voices do not rank here, a level
is a LOCATION, not a probability — treat it as context, not as a signal.
4. Wait for the rejection: price into the level, close back out, on real volume.
5. Entry, stop and target are drawn. They are arithmetic, not advice.
ALERTS
Support held · Resistance held · Any rejection · Support broke · Resistance broke
EXPORTS (Data Window — consume from other scripts via input.source())
EXP_Sup1, EXP_Sup2, EXP_Res1, EXP_Res2, EXP_SupVoices, EXP_ResVoices, EXP_Signal, EXP_Entry, EXP_Stop, EXP_Target, EXP_ConfluenceEdge
CONCEPT CREDIT
Support/resistance and polarity are long-standing public trading concepts with no single author; the written tradition runs through Charles Dow, Richard Wyckoff and Edwards & Magee.
The TRADING-RANGE BREAK — the formal S/R rule — was first tested at scale by William Brock, Josef Lakonishok and Blake LeBaron, "Simple Technical Trading Rules and the Stochastic Properties of Stock Returns", Journal of Finance 47(5), 1992. Their findings were later shown to be vulnerable to data-snooping (Sullivan, Timmermann and White, 1999) — which is precisely why this tool MEASURES the rule on your instrument instead of asserting it.
Nonparametric kernel regression for level detection is from Andrew W. Lo, Harry Mamaysky and Jiang Wang, Journal of Finance 55(4), 2000; the Nadaraya-Watson estimator is due to Nadaraya and Watson (1964). ATR — J. Welles Wilder. Triple-barrier forward labelling — Marcos Lopez de Prado. Welch's t-test — B. L. Welch.
The confluence gate, the voice model, the episode-based hold record, the confluence-ranking test and the direction-matched control are the author's own. Clean-room implementation; no third-party Pine code is reused. Not affiliated with, nor endorsed by, any of the above.
HONESTY AND LIMITATIONS
Calibration is IN-SAMPLE, with no costs or slippage, and uses overlapping windows. A proven in-sample edge is NOT a guarantee out-of-sample. Real fills, spreads and commissions will reduce it.
The confluence gate is one rule among many — a different tolerance gives different levels.
Confluence is TESTED here, not assumed. If the panel says the extra voices do not rank, then on this instrument they do not, and no amount of agreement between methods will change that.
Both barriers on one bar: the STOP is assumed first — conservative, and the only assumption that cannot flatter the result. Unresolved trades at the horizon are marked to market, not booked as losses. Nothing is marked PROVEN below t = 1.96, and nothing is rated at all below the minimum sample.
Nothing in this script predicts price.
DISCLAIMER
Research and educational tool only. NOT financial advice, NOT a recommendation, and NO guarantee of results. Entry, stop and target output is arithmetic, not advice. Trading carries risk of loss. Test out-of-sample and make your own decisions. The author accepts no liability for any use. Indicator

Adaptive Lorentzian Classification [Quantum Algo]Quantum ML Engine — Adaptive Lorentzian Classification
█ OVERVIEW
Quantum ML Engine is a machine-learning classifier that predicts the direction of price over a configurable horizon using an Approximate Nearest Neighbors (ANN) search across historical feature vectors. Instead of relying on a single oscillator, it compares the current bar's "fingerprint" — a vector of up to six normalized features — against thousands of past bars, finds the most similar market conditions, and lets those historical outcomes vote on what is likely to happen next.
By default the engine measures similarity with Lorentzian distance, log(1 + |Δ|), rather than Euclidean distance. Market data is heavily distorted around major events (CPI prints, FOMC, black swans), and Lorentzian distance naturally compresses these outliers — analogous to how mass warps space-time — so a single extreme bar cannot dominate the neighbor selection.
This is an original, fully self-contained implementation written from scratch with zero library imports. The concept of applying Lorentzian distance to kNN classification on charts was pioneered in the open-source work of @jdehorty (Machine Learning: Lorentzian Classification), building on earlier kNN studies by @capissimo. Full credit to both for the foundational research. This script does not reuse their code; it re-derives the approach independently and extends it in the ways described below.
█ WHAT IS DIFFERENT IN THIS IMPLEMENTATION
1 — Time-aligned training set
Each training sample pairs the feature vector recorded AT a given bar with the realized outcome over the following H bars. Features and labels are stored on the same time axis, so the classifier learns from correctly matched cause-and-effect pairs. There is no lookahead: a sample only enters the training set once its outcome is fully realized.
2 — ATR neutral-zone labeling
Historical moves smaller than a configurable multiple of ATR are labeled NEUTRAL instead of long/short. Sideways noise therefore never teaches the model a false directional lesson. Set the multiplier to 0 to disable.
3 — Six engineered features with importance weights
RSI, WaveTrend, CCI, ADX, MFI (volume flow) and Fisher Transform, each normalized to a common 0–1 scale. Every feature slot has its own weight input, so you can tell the engine which dimensions matter more for your market without removing features entirely.
4 — Four selectable distance metrics
Lorentzian (default), Manhattan, Euclidean, and a 50/50 Lorentzian-Manhattan Hybrid. Switching metrics changes the geometry of the neighborhood and is a powerful tuning lever per asset class.
5 — Distance-weighted voting with a confidence score
Closer neighbors vote louder (weight = 1 / (1 + distance)). The agreement between neighbors is expressed as a 0–100% confidence value printed on every bar, and a minimum-confidence gate suppresses low-conviction signals entirely.
6 — Adaptive K
The neighbor count automatically shrinks (up to 40%) when volatility ranks high over the last 100 bars, making the model more reactive in fast markets, and expands back in quiet regimes for stability. Can be disabled for a fixed K.
7 — Sliding training window
The engine always trains on the most recent N bars rather than the oldest bars in chart history, so the model reflects current market structure.
8 — Configurable prediction horizon
The training/holding horizon is an input (1–20 bars) instead of a hardcoded constant.
9 — Three exit modes
Fixed-horizon exits, dynamic kernel-slope exits, and an optional ATR trailing stop with the stop level plotted on the chart.
10 — Higher-timeframe confluence filter
Optionally require price to be above (longs) or below (shorts) an EMA on a higher timeframe of your choice.
█ HOW IT WORKS
1. On every bar, six features are computed and normalized.
2. The bar's feature vector is compared against samples inside the sliding training window, sampled with a minimum chronological spacing (default 4 bars) so neighbors come from distinct market episodes rather than one cluster.
3. A monotonic distance threshold maintains a stable pool of approximate nearest neighbors; when the pool exceeds K, the threshold resets to the 75th-percentile distance, allowing genuinely closer samples to rotate in over time.
4. Neighbors vote long / short / neutral, weighted by proximity. The weighted sum becomes the prediction; the degree of agreement becomes the confidence.
5. The raw signal is then passed through optional filters: volatility regime (recent ATR vs long-run ATR), trend regime (EMA separation normalized by ATR), ADX, EMA/SMA trend, higher-timeframe trend, and a Nadaraya-Watson kernel regression filter (rational quadratic estimate with a Gaussian crossover mode for smoother color transitions).
6. Entries print only when the ML signal, the confidence gate, and all enabled filters agree.
█ SETTINGS GUIDE
General — source, training window size, prediction horizon, neutral-zone width.
ML Engine — K, adaptive K toggle, chronological spacing, distance metric, distance weighting, minimum confidence.
Feature Engineering — feature type, parameters and weight for each of the six slots.
Filters — volatility, regime, ADX, EMA/SMA, higher-timeframe confluence.
Kernel — lookback, relative weighting, regression level, lag, smoothing mode.
Exits — fixed vs dynamic exits, ATR trailing stop and multiplier.
Display — bar colors, prediction labels (value + confidence), dashboard, color compression.
█ DASHBOARD
The on-chart panel shows the live signal, prediction confidence, current adaptive K, volatility and trend regime states, kernel bias, and a calibration win-rate. The calibration statistic simply checks whether price moved in the predicted direction over the horizon after each signal. It exists ONLY to give feedback while tuning features — it is not a backtest, includes no costs or risk management, and must not be treated as a performance claim.
█ USAGE NOTES
— Works on any symbol and timeframe; intraday (15m–4H) and daily charts are typical starting points. Crypto, FX, indices and equities all behave differently — retune the features and metric per market.
— Higher minimum confidence = fewer but more selective signals. Raising chronological spacing diversifies neighbors on lower timeframes.
— Signals are evaluated on bar close. Like any bar-close logic, the in-progress bar can change until it closes.
— Best used as a confluence layer inside a complete trading plan with your own risk management, not as a standalone buy/sell system.
█ CREDITS
Concept inspiration: @jdehorty (Machine Learning: Lorentzian Classification) and @capissimo (kNN implementations). This script is an independent, original implementation with the extensions listed above.
█ DISCLAIMER
This script is provided for educational and informational purposes only. It is not financial advice, and past behavior — including the on-chart calibration statistics — does not guarantee future results. Trading involves substantial risk of loss. Always do your own research and manage risk responsibly. Indicator

True Trend Oscillator + Price EnvelopeTrue Trend Oscillator + Price Envelope is a Pine v6 rebuild and expanded interpretation of the original True Trend Oscillator concept by wbburgin.
The original idea is simple but powerful:
• Convert ATR into a stochastic volatility / trend-energy reading
• Smooth that Stoch ATR reading with a Rational Quadratic Kernel
• Use RSI as the directional pressure input
• Build separate Bull Trend and Bear Trend lines from that shared volatility engine
In this rebuild, I kept the original spirit of the oscillator but expanded it into a fuller trend-energy framework with automatic timeframe-aware settings, cleaner visual controls, price-pane candles, and a chart-side ATR envelope.
────────────────────────────
Core Idea
────────────────────────────
The oscillator is built from two main pieces:
1. Volatility / trend energy
ATR is normalized through a stochastic calculation, then smoothed with a Rational Quadratic Kernel. This creates the “energy” side of the oscillator.
2. Directional pressure
RSI supplies the directional side of the model.
The two final oscillator lines are:
Bull Trend = sqrt(RSI × Smoothed Stoch ATR)
Bear Trend = sqrt((100 - RSI) × Smoothed Stoch ATR)
That means the Bull and Bear lines are both connected to the same volatility / trend-energy source, but RSI determines which side has more directional pressure.
────────────────────────────
How to Read the Oscillator
────────────────────────────
The oscillator has two main lines:
• Bull Trend line
• Bear Trend line
The leading line shows which side currently has control.
A few practical reads:
• Bull above Bear
Bull pressure is leading.
• Bear above Bull
Bear pressure is leading.
• Both lines rising together
Trend energy is expanding.
• Both lines falling together
Trend energy is cooling, compressing, or losing force.
• Both lines collapsing near zero
The market is moving into a low-energy / compression state.
This is one of the more important parts of the script. The oscillator is not only asking which side is leading but whether the move has enough volatility energy behind it to matter.
────────────────────────────
Active Trend Threshold
────────────────────────────
The active threshold is used to separate trend conditions from low-energy / range conditions.
A trend is only treated as active when the weaker side of the oscillator is above the active threshold.
In plain terms:
• Bull can be above Bear, but if both lines are too weak, the script treats the market as range / low energy.
• Bear can be above Bull, but if volatility energy is collapsing, the script does not force a strong trend read.
• When both sides clear the threshold, the leading side becomes more meaningful.
This helps reduce the “every crossover is a signal” problem that many simple oscillators can have.
────────────────────────────
Extreme Readings
────────────────────────────
The script includes an upper guide at 80. When the Bull Trend line pushes above 80, the script can highlight that as an extreme bull-energy condition. When the Bear Trend line pushes above 80, the script can highlight that as an extreme bear-energy condition.
By default:
• Bull extreme = orange
• Bear extreme = purple
These colors can also carry into the price candles and envelope visuals, making strong directional energy easier to spot without needing to stare only at the oscillator pane.
────────────────────────────
Auto / Manual Engine
────────────────────────────
The script includes an Auto / Manual engine profile.
Auto mode adjusts the main calculation settings based on the chart timeframe, including:
• ATR length
• Stochastic length
• RSI length
• Stoch smoothing
• Kernel lookback
• Kernel weighting
• Active range threshold
Manual mode unlocks the user-defined settings. When Auto mode is active, the manual inputs are grayed out so the settings panel stays easier to understand.
────────────────────────────
Price Candle Overlay
────────────────────────────
This rebuild includes a price-pane candle overlay using plotcandle() and force_overlay.
The candle overlay keeps the real OHLC candle shape intact, but recolors the body, wick, and border based on the active True Trend state.
The candle colors can represent:
• Bull trend
• Bear trend
• Range / low-energy
• Bull extreme
• Bear extreme
Body, wick, and border transparency are controlled separately, so the candle overlay can be made bold or subtle depending on the chart style.
────────────────────────────
True Trend Price Envelope
────────────────────────────
The script also includes a True Trend Price Envelope projected onto the main chart.
The envelope is built from:
• EMA(HLC3) basis
• ATR-based width
• True Trend strength expansion
As oscillator strength increases, the envelope can widen. This creates a chart-side visual map of how the oscillator’s trend-energy state is interacting with price.
The envelope behavior is designed around support / resistance style context:
• Bull-side pressure fills the upper half of the envelope
• Bear-side pressure fills the lower half of the envelope
• Bull pressure can plot the lower band as a support-style trail
• Bear pressure can plot the upper band as a resistance-style trail
• Neutral conditions can optionally show a soft neutral envelope or basis trail
This helps connect the oscillator pane back to price instead of leaving the oscillator isolated below the chart.
────────────────────────────
How I Use It
────────────────────────────
I use this script as a trend-energy and compression map.
A few practical ways to read it:
• When Bull is above Bear and both lines are rising, bull pressure is expanding with energy.
• When Bear is above Bull and both lines are rising, bear pressure is expanding with energy.
• When the leading side is still on top but both lines are falling, the move may be cooling or losing force.
• When both lines collapse toward zero, the market may be compressing or moving through a lower-energy phase.
• When price is holding the envelope trail in the same direction as the oscillator state, the price chart is confirming the oscillator pressure more cleanly.
• When oscillator pressure and price-envelope behavior disagree, that disagreement can be useful information by itself because it may point to chop, transition, or fading momentum.
• Extreme colors can help identify when directional energy is stretched rather than simply trending.
This is not meant to be a standalone buy/sell signal machine. It is a visual context tool designed to help organize trend direction, volatility energy, compression, and price confirmation.
────────────────────────────
Attribution
────────────────────────────
This script is a Pine v6 rebuild and expanded interpretation of the original True Trend Oscillator concept by wbburgin.
Original author / concept:
• © wbburgin
• Original PulseWire script:
This version adds my own Pine v6 structure, Auto / Manual timeframe behavior, expanded visuals, price-pane plotcandles, extreme-state coloring, and the True Trend Price Envelope.
Special thanks to jdehorty for the KernelFunctions library used for the Rational Quadratic Kernel smoothing.
As always, this script is a visual context tool. It is not financial advice and is not meant to replace risk management, market structure, support/resistance, volume analysis, or a complete trading plan.
────────────────────────────
Chart Examples
────────────────────────────
Indicator

KernelLens🟦 KernelLens is a professional kernel regression library for Pine Script v6, providing eight mathematically rigorous Nadaraya–Watson estimators, a three-mode filter layer, a unified string dispatcher, and a suite of trading utilities — all built from the ground up on correct non-parametric statistics. Unlike existing Pine smoothing libraries — which inherit a decade-old loop-bound bug that silently reduces every kernel window to a handful of bars, regardless of the bandwidth parameter — KernelLens is built with auditable math, NA-safe iteration, input validation at every entry point, and academic references cited inline next to the formulas they describe.
The library integrates eight independent kernel families — Rational Quadratic, Gaussian, Periodic, Locally Periodic, Epanechnikov, Tricube, Triangular, and Cosine — behind a consistent API, with every raw estimator wrapped in a filter layer (None / Smooth / Zero Lag), a unified dispatcher for dropdown-driven kernel selection, and five utility exports covering slope detection, trend state, crossover signaling, residual confidence bands, and Silverman's rule-of-thumb bandwidth recommendation. Every public function validates its inputs, raises descriptive runtime errors on misuse, and returns `na` only when there is genuinely no data — never as a silent fallback.
🟦 MATHEMATICAL FOUNDATION
**The Nadaraya–Watson Estimator**
Given a source series `y_t` and a symmetric kernel `K` with scale parameter `ℓ` (the "bandwidth"), the Nadaraya–Watson estimator of the regression function `m(x) = E ` evaluated at the current bar is:
```
Σᵢ K(dᵢ / ℓ) · y_{t−i}
ŷ(t) = ───────────────────────
Σᵢ K(dᵢ / ℓ)
```
where `dᵢ` is the bar-distance from the kernel center and the sum runs over a finite window determined by the effective support of `K`.
The estimator is a locally weighted average: bars close to the kernel center contribute heavily, distant bars contribute proportionally less, and bars outside the support contribute nothing. It is asymptotically unbiased up to `O(ℓ²)` for twice-differentiable `m`, with variance of order `(n·ℓ)⁻¹` — the classical bias–variance trade-off that defines all non-parametric smoothers.
**Why Kernel Regression Beats Rolling Means**
A simple moving average gives every bar in the window the same weight. Kernel regression gives each bar a weight that decays smoothly with distance, producing:
- **Smoother output** — no step artifacts when bars enter / leave the window
- **Better bias control** — the peak of the kernel sits exactly on the point being estimated
- **Kernel-specific behavior** — compact-support kernels eliminate tail contamination entirely; Rational Quadratic's `α` parameter exposes multi-scale mixing; Periodic kernels resonate with known cycle lengths
The math has been the academic standard for non-parametric regression since Nadaraya (1964) and Watson (1964). KernelLens brings it to Pine Script v6 in its correct, bug-free form.
🟦 THE EIGHT KERNELS
All eight kernels implement the Nadaraya–Watson weighting scheme. They differ in support (compact versus infinite), smoothness (how many times differentiable), and how weight decays with distance.
| # | Kernel | Formula | Support | Smoothness | Character |
|---|---|---|---|---|---|
| 1 | **Rational Quadratic** | `(1 + d² / (2·α·ℓ²))^(−α)` | ℝ | C∞ | Multi-scale mixer — `α` controls stretch versus wiggle |
| 2 | **Gaussian (RBF)** | `exp(−d² / (2·ℓ²))` | ℝ | C∞ | The canonical smoother — smoothest possible with L² optimality |
| 3 | **Periodic** | `exp(−2·sin²(π·d/p) / ℓ²)` | ℝ | C∞ | Resonates with repetition distance `p` — ideal for cycles |
| 4 | **Locally Periodic** | Periodic · Gaussian | ℝ | C∞ | Seasonal patterns that slowly drift with trend |
| 5 | **Epanechnikov** | `(3/4)(1 − u²) · 𝟙{|u|≤1}` | | C⁰ | Asymptotically MSE-optimal (Watson 1964) — no tail contamination |
| 6 | **Tricube** | `(70/81)(1 − \|u\|³)³ · 𝟙{|u|≤1}` | | C² | The LOWESS standard — near-Gaussian with compact support |
| 7 | **Triangular** | `(1 − \|u\|) · 𝟙{|u|≤1}` | | C⁰ | Simplest non-uniform kernel — fastest to compute |
| 8 | **Cosine** | `(π/4)·cos(π·u/2) · 𝟙{|u|≤1}` | | C¹ | Raised-cosine taper — smoother boundary than Epanechnikov |
where `u = d/ℓ` and `𝟙` is the indicator function.
**Infinite-Support vs Compact-Support — Why Both Matter**
| | Infinite Support (RQ, Gauss, Periodic, LocPeriodic) | Compact Support (Epa, Tricube, Triangular, Cosine) |
|---|---|---|
| **Tail weight** | Never exactly zero | Exactly zero beyond ±ℓ |
| **Loop depth** | `3·ℓ` (3-σ cutoff, ≈99.7% mass) | Exactly `ℓ` |
| **Bar contamination** | Distant bars still pull the estimate a tiny amount | Distant bars cannot affect the estimate at all |
| **Best for** | Smooth trends, Gaussian-process intuition | Robust regression, outlier resistance |
KernelLens picks the correct loop depth automatically based on kernel family: `_depthInfinite` for Gaussian-family kernels, `_depthCompact` for bounded kernels, `_depthPeriodic` for Periodic (which must span enough cycles to reach stable weights).
**Why Eight, Not Four**
Most Pine kernel libraries ship only the four kernels from MacKay's Gaussian process tutorial. KernelLens adds the four compact-support classical kernels because:
- **Epanechnikov** minimises asymptotic mean squared error among all non-negative kernels of bounded support (Watson 1964) — it is the MSE-optimal baseline against which all other kernels are measured
- **Tricube** is the kernel used by LOWESS (Cleveland 1979), the de-facto standard for robust locally weighted scatterplot smoothing
- **Triangular** is the cheapest non-uniform compact kernel — useful when loop-budget matters on intraday charts with huge dataset size
- **Cosine** is C¹-continuous at the support boundary, unlike Epanechnikov's C⁰ discontinuity, producing visibly smoother transitions at kernel edges
Adding them makes the library an academically complete toolkit, not just a Pine port of one tutorial.
🟦 FILTER LAYER — NONE / SMOOTH / ZERO LAG
Every kernel export accepts a `_filter` parameter with three valid values. The filter layer is implemented identically across all eight kernels, so switching kernel families does not change filter behavior.
**"No Filter" — Single-Pass Raw Estimate**
```
ŷ = K(y)
```
One Nadaraya–Watson pass over the source. Cheapest mode, most reactive, fully represents the underlying kernel. Use this when you want the kernel's raw behavior with no additional smoothing or lag correction.
**"Smooth" — Double-Pass Estimate**
```
ŷ = K(K(y))
```
The kernel is applied once to the source, then applied again to its own output using the same bandwidth and the same parameters. The result is a more strongly smoothed curve at the cost of one extra loop pass per bar.
This is mathematically equivalent to convolving the kernel with itself — the effective kernel is wider and flatter, pulling longer-range context into each estimate without requiring the user to double the bandwidth.
**"Zero Lag" — Ehlers De-Lagged Estimate**
```
ŷ = 2·K(y) − K(K(y))
```
The ZLEMA identity from Ehlers (*Rocket Science for Traders*, 2000): subtract the smoothing lag from the raw estimate, effectively shifting the output back in time to match the source more closely.
The intuition: `K(y)` lags `y` by some amount; `K(K(y))` lags `K(y)` by the same amount; so `K(y) − K(K(y))` is an estimate of the lag itself, and adding it back to `K(y)` cancels out. The result tracks the source more tightly than either pass alone, at the cost of slightly noisier turning points.
**Lazy Evaluation — No Wasted Cycles**
In `"No Filter"` mode, the second pass is skipped entirely — it never runs. The filter branch uses an `if` block (not a ternary), so Pine's short-circuit semantics prevent the unused computation. A single kernel call costs one pass; `"Smooth"` or `"Zero Lag"` costs two. You only pay for what you use.
🟦 KERNEL CENTER OFFSET — THE `_phase` PARAMETER
Every KernelLens kernel takes a `_phase` parameter that shifts the kernel center into the past by `_phase` bars. It is the library's non-repainting knob.
**_phase = 0 — Live Estimate**
The kernel is centered on the current bar. The most recent price has maximum weight, and the estimate is as fresh as possible. Suitable for live signal generation, but the most recent bar can re-evaluate as it develops within its interval — standard Pine real-time behavior.
**_phase > 0 — Non-Repainting Historical Estimate**
The kernel center is moved `_phase` bars into the past. The estimate becomes the smoothed value *at that historical bar*, not the current bar. Once the bar at `bar_index − _phase` is fully confirmed (`barstate.isconfirmed`), its estimate cannot change again.
This is the standard trick for publishing kernel indicators that do not repaint: you get a stable, historically accurate curve at the cost of shifting the entire output `_phase` bars to the right on the chart. A `_phase = 25` call gives a curve that lags live price by 25 bars but is guaranteed stable for every past bar.
**Why It Belongs in the Library, Not the Caller**
Pushing `_phase` into the kernel's own loop is not the same as evaluating the kernel at a shifted source (`K(src )`). Shifting the source just uses a stale input with a current-bar-centered kernel, which still produces a fresh estimate of a stale series. KernelLens's `_phase` genuinely moves the kernel center, producing a historical-bar estimate that computes over the correct surrounding window.
🟦 NON-REPAINTING BEHAVIOR
Repainting is the single most-asked question about any Pine indicator, and the single most common source of silent failure when a retail trader moves from backtest to live. A strategy that looks flawless on historical bars and then bleeds money the moment it is deployed is almost always suffering from some form of repainting. KernelLens is engineered from first principles to eliminate every class of repainting by construction — not by patching symptoms, but by removing the dependencies that cause repainting in the first place.
**The Two Forms of Repainting**
| Form | Symptom | Typical Cause |
|---|---|---|
| **Historical repainting** | A bar that was closed days or weeks ago silently changes its plotted value when the chart is refreshed or scrolled | `request.security()` with `lookahead = barmerge.lookahead_on`, un-gated higher-timeframe data, or incorrect array rotation that reads into future bars |
| **Real-time repainting** | The plotted value on the live (current developing) bar flickers tick-by-tick as new price ticks arrive, then freezes at a final value when the bar closes | The indicator reads `close ` (or any current-bar value) inside a weighted sum — the current-bar weight changes every tick |
KernelLens avoids the first kind **entirely and unconditionally**: the library contains no `request.security` calls, no higher-timeframe lookups, no `lookahead_on` usage, and no array rotation that could leak future bars into the window. Every historical bar plotted by any KernelLens kernel is computed exclusively from bars that existed at the time that bar was closed. The plotted history is immutable.
Real-time repainting is controlled explicitly by the `_phase` parameter — it is the user's choice whether to accept tick-by-tick flicker on the live bar in exchange for zero lag (`_phase = 0`) or to eliminate the flicker entirely at the cost of a small fixed lag (`_phase ≥ 1`).
**Why Kernel Regression Normally Repaints (And How KernelLens Stops It)**
A traditional Nadaraya–Watson call centered on the current bar evaluates:
```
ŷ(t) = Σᵢ K(dᵢ/ℓ) · y_{t−i} for i = 0 … depth
```
On the live bar, the term `y_{t−0} = close ` is the current real-time price — which changes on every tick. Every tick moves the weighted sum, every tick moves the estimate, and the trader watching the chart sees the kernel plot flicker as the bar develops. The historical bars (where `close ` for that past bar is now fixed) are stable, but the live plot is unstable.
KernelLens's `_phase` parameter shifts the loop so the kernel runs over `i = _phase … _phase + depth`. With `_phase = 2`:
```
ŷ(t) = Σᵢ K((i−2)/ℓ) · y_{t−i} for i = 2 … 2 + depth
```
The sum no longer touches `close ` or `close ` — every bar it reads is already confirmed and cannot change. The live-bar kernel output is therefore identical from the first tick of the bar to the last tick of the bar, and identical again when the bar finally closes. There is no flicker and nothing to repaint.
**The Lag / Stability Trade-Off**
| `_phase` | Lag on Live Bar | Live-Bar Flicker | Historical Repainting | Best For |
|---|---|---|---|---|
| **0** | 0 bars | Yes (real-time only; history is stable) | None | Scalping, academic research, calibration |
| **1** | 1 bar | None | None | Fast day-trading; minimum acceptable lag for a live trading desk |
| **2** | 2 bars | None | None | Default for most users — the sweet spot between freshness and stability |
| **3** | 3 bars | None | None | Swing trading — extra margin against false flickers from erratic ticks |
| **5+** | 5+ bars | None | None | Position trading, long-term chart analysis, published signal marks |
Even at `_phase = 0`, **historical repainting never occurs** — only the live bar flickers during its own development. Once a bar closes, its plotted value is final; scrolling away and back, refreshing the chart, or re-opening PulseWire will never change that historical plot. The flicker is exclusively a live-bar tick-by-tick phenomenon.
**KernelLens as a Non-Repainting Primitive**
KernelLens exposes real-time flicker as an explicit, user-controlled trade-off rather than a hidden behavior. The caller picks any point on the spectrum from "fully live" (`_phase = 0`, maximum reactivity with tick-by-tick flicker) to "fully confirmed" (`_phase ≥ 1`, one or more bars of lag in exchange for a curve that never redraws) with a single integer parameter. Historical repainting — the dangerous form that silently rewrites past plots — is eliminated unconditionally regardless of `_phase`.
**How to Verify Non-Repainting Yourself**
Do not trust the word "non-repainting" from any library — always verify. KernelLens can be verified in about thirty seconds:
1. Load a chart with KernelLens on it using `_phase = 2` (or any value > 0).
2. Take a screenshot at any specific historical bar.
3. Scroll far to the left, refresh the chart, or reload the indicator.
4. Return to the same bar. The plotted value at that bar must be pixel-identical to the screenshot — because the computation on that bar used only the bars before it, which have not changed.
5. Repeat with `_phase = 0`. The historical bars must still be pixel-identical — only the live bar's plot can differ between observations, and only because the live bar's `close` is now a different number than it was when you took the screenshot.
For a stricter test, use PulseWire's **Bar Replay** mode. Enable Bar Replay, step forward one bar at a time, and watch the kernel plot on each newly-closed bar. With `_phase ≥ 1`, the value plotted on each newly-closed bar will exactly match what the indicator shows after you exit replay mode and view the same bar normally. This is the gold-standard test — Bar Replay reproduces live-bar tick arrival in a controlled way.
**Common Misconceptions**
> *"Any Pine indicator that uses `close` repaints."*
False. Using `close` on a confirmed bar does not repaint — the confirmed bar's close is locked. What can repaint is using `close` on the live bar, and only within that live bar's interval. KernelLens with `_phase > 0` never reads the live-bar close at all.
> *"`lookahead = barmerge.lookahead_on` is always wrong."*
Context-dependent. `lookahead_on` is used correctly in some multi-timeframe indicators to request a higher-TF value that is already settled on the lower TF. KernelLens does not use `request.security` at all, so this question does not apply — but for libraries that do, `lookahead_on` is only problematic when it leaks values from bars that were not yet closed at the lower-TF time of evaluation.
> *"Non-repainting means zero lag."*
False. Zero lag and non-repainting are orthogonal properties. KernelLens `_phase = 0` is zero lag with real-time flicker; `_phase = 2` is two-bar lag with no flicker. You can have any combination of the two, and the right choice depends on the trading style.
> *"The `FILTER_ZEROLAG` mode makes the indicator non-repainting."*
False. `FILTER_ZEROLAG` is an Ehlers-style de-lagging filter applied to the kernel output; it reduces the perceived lag of the estimate, but it does not affect whether the live bar flickers. Non-repainting is controlled exclusively by `_phase`. Choose `_phase` for repainting behavior, and `_filter` for smoothness / lag shape — they are independent knobs.
**When to Accept Real-Time Flicker (`_phase = 0`)**
Despite everything above, there are legitimate reasons to deliberately use `_phase = 0`:
- **Academic research and backtesting** — you want the kernel mathematics in its classical form, centered on the point being estimated, with no phase adjustment
- **Scalping on very short timeframes** — a 2-bar lag on a 1-minute chart is a 2-minute delay, which can matter when you are exiting within a 4-minute window
- **Visual calibration** — when you are choosing a bandwidth by eye, the live-bar flicker actually helps: you see how sensitive the curve is to each incoming tick, which is diagnostic information
- **Indicators that read the kernel output only on `barstate.isconfirmed`** — if your signal logic is gated by `if barstate.isconfirmed`, then live-bar flicker is invisible to your signal (it sees only the frozen close-of-bar value), and you can safely use `_phase = 0` with no practical consequence
For every other case — and especially for any live alert or automated trading system — use `_phase ≥ 1`. Two bars of lag on a clean, stable curve is almost always worth more than zero lag on a curve that redraws itself several times per bar.
🟦 UNIFIED DISPATCHER — `estimate()`
For indicators where the user picks a kernel from a dropdown, writing eight separate ternary branches is tedious and error-prone. KernelLens ships with a unified dispatcher that routes to the correct kernel based on a string argument:
```pine
import a_jabbaroff/KernelLens/1 as kl
line = kl.estimate(
kernelType = kl.KERNEL_GAUSS,
src = close,
bandwidth = 32,
shapeAlpha = 1.0,
period = 1,
phase = 2,
filter = kl.FILTER_SMOOTH)
```
The dispatcher forwards to the matching typed export, so there is no performance penalty versus calling the kernel directly — it is a compile-time routing pass. Unknown kernel names raise a descriptive `runtime.error` naming every valid alternative, so typos fail loudly instead of silently returning `na`.
**Public Constants**
KernelLens exposes its string constants so callers never type the magic values by hand:
| Constant | Value |
|---|---|
| `FILTER_NONE` | `"No Filter"` |
| `FILTER_SMOOTH` | `"Smooth"` |
| `FILTER_ZEROLAG` | `"Zero Lag"` |
| `KERNEL_RQ` | `"Rational Quadratic"` |
| `KERNEL_GAUSS` | `"Gaussian"` |
| `KERNEL_PERIODIC` | `"Periodic"` |
| `KERNEL_LOCPER` | `"Locally Periodic"` |
| `KERNEL_EPA` | `"Epanechnikov"` |
| `KERNEL_TRICUBE` | `"Tricube"` |
| `KERNEL_TRIANG` | `"Triangular"` |
| `KERNEL_COSINE` | `"Cosine"` |
Using the constants in your caller code means the Pine compiler — not a runtime string compare — catches typos at edit time.
🟦 UTILITY LAYER — FIVE PROFESSIONAL HELPERS
KernelLens ships with five utility exports that complement the core estimators. They are the functions you almost always write immediately after getting a smoothed line, factored out so you don't rewrite them in every indicator.
**`slope(estimate, step)` — Discrete First Derivative**
Returns `(y_t − y_{t−step}) / step`, the normalized rate of change over `step` bars. Use it to detect whether a kernel output is trending up, flat, or down — the foundation for any trend-following signal built on top of KernelLens.
```pine
rising = kl.slope(line, 3) > 0.0
```
**`trendState(estimate, step)` — Ternary Trend Indicator**
Returns `+1` if the estimate is rising, `−1` if falling, `0` if exactly flat over the window. A single-call replacement for hand-rolled `line > line ? 1 : line < line ? -1 : 0` ladders.
**`crossSignal(fast, slow)` — Bi-directional Crossover**
Returns `+1` on the bar where `fast` crosses above `slow` (bullish), `−1` on a bearish cross, and `0` otherwise. Built on `ta.crossover` / `ta.crossunder`, so the signal is non-repainting once the bar is confirmed.
**`confidenceBand(src, estimate, window)` — Residual Standard Deviation**
Computes the rolling standard deviation of `(src − estimate)` over a user-defined window. Use the return value as the half-width of a confidence band around the estimate:
```pine
est = kl.gaussian(close, 32, 2, kl.FILTER_SMOOTH)
sigma = kl.confidenceBand(close, est, 50)
upper = est + 1.96 * sigma
lower = est - 1.96 * sigma
```
This is a computationally cheap proxy for the full kernel-weighted local variance — ideal when you need visual bands without paying for a second weighted pass.
**`silvermanBandwidth(src, window)` — Optimal ℓ Suggestion**
Returns the Silverman rule-of-thumb bandwidth:
```
h ≈ 1.06 · σ · n^(−1/5)
```
where `σ` is the rolling standard deviation of the source and `n` is the window size. This is the classical starting point for Gaussian-family bandwidths in academic texts (Silverman 1986). Because Pine requires `simple int` for kernel bandwidth, the returned value is intended for diagnostic display — plot it, read it off the chart, then hard-code the rounded integer into the kernel call.
🟦 INPUT VALIDATION — FAIL LOUDLY, FAIL EARLY
Every public function in KernelLens validates its inputs through a set of internal `_assert*` helpers. Invalid arguments never produce silent `na` fallbacks or buried zero-divisions — they raise `runtime.error` with a descriptive message identifying the function, the parameter, and the expected range.
| Helper | Checks | Raises On |
|---|---|---|
| `_assertFilter` | Filter string is `FILTER_NONE`, `FILTER_SMOOTH`, or `FILTER_ZEROLAG` | Typos like `"No FIlter"` (capital I) — a bug that exists in at least one published kernel indicator |
| `_assertBandwidth` | Bandwidth is a strictly positive integer | Negative or zero bandwidth, which would cause division by zero or infinite loops |
| `_assertPeriod` | Period is a strictly positive integer | Zero period, which would cause `sin(π·d/0)` in Periodic kernels |
| `_assertAlpha` | Rational Quadratic shape parameter is strictly positive | Zero or negative `α`, which would invert the RQ formula |
Error messages are prefixed `KernelLens:` (or `KernelLens.:`) so they are easy to spot in the PulseWire runtime log. Every message names the parameter that failed, the value that was passed, and the set of valid alternatives — so a misconfigured chart tells you exactly what to fix.
🟦 LOOP DEPTH — THE BUG FIX THAT MOTIVATED KERNELLENS
The two most popular Pine kernel libraries on PulseWire share the same fatal bug: both compute their loop depth as
```pine
_size = array.size(array.from(_src))
```
where `array.from(_src)` creates a **one-element array containing the current value of `_src`**, so `_size` is always `1`. The loop then runs `for i = 0 to 1 + startAtBar`, effectively using only `startAtBar + 2` bars — completely ignoring the user's bandwidth. Every published kernel indicator built on those libraries inherits this silent miscalculation.
KernelLens replaces the broken helper with three explicit depth selectors:
| Helper | Depth | Used By |
|---|---|---|
| `_depthInfinite(bw)` | `max(bw · 3, 4)` | Gaussian, Rational Quadratic, Locally Periodic |
| `_depthCompact(bw)` | `max(bw, 4)` | Epanechnikov, Tricube, Triangular, Cosine |
| `_depthPeriodic(bw, p)` | `max(bw · 3, p · 10, 4)` | Periodic |
For Gaussian-family kernels, the `3·ℓ` cutoff captures approximately 99.7% of the kernel mass (the three-sigma rule). For compact-support kernels, the depth equals the bandwidth exactly — the loop terminates at the kernel's natural zero point. For Periodic kernels, the depth is the larger of the scale-based and cycle-based minima, so the loop always spans enough periods to produce a stable weighted average.
The loop counter `i` runs over bar offsets starting at `_phase`, every bar lookup is NA-checked before being incorporated into the sum, and the final `num / den` division is guarded against zero denominators. On a fresh chart, the kernel gracefully returns `na` for bars where the window extends past available history, rather than producing poisoned sums from implicit NA arithmetic.
🟦 API REFERENCE
**Core Kernel Estimators — Eight Exports**
| Export | Signature |
|---|---|
| `rationalQuadratic` | `(src, bandwidth, shapeAlpha, phase, filter) → float` |
| `gaussian` | `(src, bandwidth, phase, filter) → float` |
| `periodic` | `(src, bandwidth, period, phase, filter) → float` |
| `locallyPeriodic` | `(src, bandwidth, period, phase, filter) → float` |
| `epanechnikov` | `(src, bandwidth, phase, filter) → float` |
| `tricube` | `(src, bandwidth, phase, filter) → float` |
| `triangular` | `(src, bandwidth, phase, filter) → float` |
| `cosineKernel` | `(src, bandwidth, phase, filter) → float` |
**Unified Dispatcher**
| Export | Signature |
|---|---|
| `estimate` | `(kernelType, src, bandwidth, shapeAlpha, period, phase, filter) → float` |
**Utility Layer — Five Exports**
| Export | Signature |
|---|---|
| `slope` | `(estimate, step) → float` |
| `trendState` | `(estimate, step) → int` |
| `crossSignal` | `(fast, slow) → int` |
| `confidenceBand` | `(src, estimate, window) → float` |
| `silvermanBandwidth` | `(src, window) → float` |
**Parameter Types**
| Name | Pine Type | Description |
|---|---|---|
| `src` | `series float` | Source series (close, hl2, ohlc4, or any other price-derived series) |
| `bandwidth` | `simple int` | Kernel scale `ℓ`, must be `> 0` |
| `shapeAlpha` | `simple float` | Rational Quadratic shape parameter, must be `> 0` |
| `period` | `simple int` | Periodic repetition distance, must be `> 0` |
| `phase` | `simple int` | Kernel center offset in bars, must be `≥ 0` |
| `filter` | `simple string` | One of `FILTER_NONE`, `FILTER_SMOOTH`, `FILTER_ZEROLAG` |
| `kernelType` | `simple string` | One of the eight `KERNEL_*` constants |
| `step` | `simple int` | Finite-difference step for `slope` / `trendState`, must be `≥ 1` |
| `window` | `simple int` | Rolling window for `confidenceBand` / `silvermanBandwidth`, must be `≥ 2` |
🟦 USAGE EXAMPLES
**Minimal — One Gaussian Curve**
```pine
//@version=6
indicator("KernelLens — Gaussian Demo", overlay = true)
import a_jabbaroff/KernelLens/1 as kl
line = kl.gaussian(close, 32, 2, kl.FILTER_SMOOTH)
plot(line, "Gaussian", color = color.orange, linewidth = 2)
```
**Fast / Slow Crossover System**
```pine
//@version=6
indicator("KernelLens — RQ Crossover", overlay = true)
import a_jabbaroff/KernelLens/1 as kl
fast = kl.rationalQuadratic(close, 8, 1.0, 2, kl.FILTER_NONE)
slow = kl.rationalQuadratic(close, 32, 1.0, 2, kl.FILTER_SMOOTH)
cross = kl.crossSignal(fast, slow)
plot(fast, "Fast", color = color.aqua, linewidth = 2)
plot(slow, "Slow", color = color.orange, linewidth = 2)
plotshape(cross == 1, "Bull", location = location.belowbar,
color = color.lime, style = shape.triangleup, size = size.tiny)
plotshape(cross == -1, "Bear", location = location.abovebar,
color = color.red, style = shape.triangledown, size = size.tiny)
```
**Confidence Band Envelope**
```pine
//@version=6
indicator("KernelLens — Confidence Band", overlay = true)
import a_jabbaroff/KernelLens/1 as kl
est = kl.tricube(close, 48, 2, kl.FILTER_SMOOTH)
sigma = kl.confidenceBand(close, est, 50)
k = 1.96
upper = est + k * sigma
lower = est - k * sigma
plot(est, "Estimate", color = color.orange, linewidth = 2)
p1 = plot(upper, "+1.96σ", color = color.new(color.aqua, 70))
p2 = plot(lower, "−1.96σ", color = color.new(color.aqua, 70))
fill(p1, p2, color = color.new(color.aqua, 92))
```
**Dropdown-Driven Kernel Selection**
```pine
//@version=6
indicator("KernelLens — Dropdown", overlay = true)
import a_jabbaroff/KernelLens/1 as kl
kernelType = input.string(kl.KERNEL_GAUSS, "Kernel",
options = )
bandwidth = input.int(32, "Bandwidth", minval = 2)
alphaRQ = input.float(1.0,"RQ Alpha", minval = 0.01, step = 0.25)
period = input.int(20, "Period", minval = 1)
phase = input.int(2, "Phase", minval = 0)
filter = input.string(kl.FILTER_SMOOTH, "Filter",
options = )
line = kl.estimate(kernelType, close, bandwidth, alphaRQ, period, phase, filter)
plot(line, "KernelLens", color = color.orange, linewidth = 2)
```
🟦 TIMEFRAME PRESETS — BANDWIDTH BY STYLE
Kernel bandwidth is the single most important parameter. It controls the trade-off between reactivity (small `ℓ`, tight fit, noisier) and stability (large `ℓ`, smooth curve, slower to react). The presets below are tested starting points — adjust by ±25 % to taste.
---
**SCALPER — 1m / 3m / 5m**
| Parameter | Value |
|---|---|
| Bandwidth (ℓ) | 8 |
| Phase | 1 |
| Filter | `FILTER_NONE` |
| Best Kernel | Rational Quadratic or Gaussian |
| RQ shapeAlpha | 1.0 |
**Why:** Short bandwidth means the kernel reacts within a handful of bars. `FILTER_NONE` removes the double-pass lag, so the estimate tracks price as tightly as possible. Phase 1 keeps the estimate nearly live while still avoiding the current-bar tick noise.
---
**DAY TRADER — 15m / 30m / 1H**
| Parameter | Value |
|---|---|
| Bandwidth (ℓ) | 16 |
| Phase | 2 |
| Filter | `FILTER_SMOOTH` |
| Best Kernel | Gaussian or Tricube |
| RQ shapeAlpha | 1.0 |
**Why:** Balanced reactivity — the 16-bar Gaussian is the default Silverman range for intraday price data, and `FILTER_SMOOTH` removes most of the bar-to-bar chop without significantly increasing lag. Tricube provides near-identical behaviour with strict compact support and is preferred on noisy assets where outlier bars should not influence the curve.
---
**SWING TRADER — 4H / 1D**
| Parameter | Value |
|---|---|
| Bandwidth (ℓ) | 32 |
| Phase | 3 |
| Filter | `FILTER_SMOOTH` |
| Best Kernel | Rational Quadratic |
| RQ shapeAlpha | 2.0 |
**Why:** Swing trades need structural signals, not intraday noise. Rational Quadratic with `α = 2.0` mixes medium and long length scales, producing a curve that ignores transient spikes but catches genuine regime shifts. Phase 3 shifts the estimate three bars back so each swing decision is made against a fully confirmed kernel output.
---
**POSITION / LONG-TERM — 1D / 1W / 1M**
| Parameter | Value |
|---|---|
| Bandwidth (ℓ) | 64 |
| Phase | 5 |
| Filter | `FILTER_SMOOTH` or `FILTER_ZEROLAG` |
| Best Kernel | Gaussian or Locally Periodic |
| Period (if LP) | 52 (weekly cycle) |
**Why:** Position traders care about the macro trajectory. A Gaussian with ℓ = 64 produces a curve that only turns on genuine multi-month inflections. Locally Periodic with `period = 52` is the ideal choice when a clear seasonal cycle is present — it uses both the long-range Gaussian envelope and the 52-bar periodicity to highlight cycle turns that align with trend.
---
**RESEARCH — Academic / Backtest**
| Parameter | Value |
|---|---|
| Bandwidth (ℓ) | Compute via `silvermanBandwidth(src, 200)` |
| Phase | 0 |
| Filter | `FILTER_NONE` |
| Best Kernel | Epanechnikov |
**Why:** Epanechnikov is the MSE-optimal kernel; `FILTER_NONE` keeps the estimator in its classical single-pass form; `phase = 0` centers the kernel on the bar being evaluated. This is the configuration that matches the statistical literature exactly — use it when publishing research, running Monte-Carlo studies, or calibrating against reference implementations.
🟦 BANDWIDTH SELECTION
Bandwidth `ℓ` is the single most consequential choice in kernel regression. Too small and the estimate overfits local noise; too large and it flattens real structure. KernelLens exposes two helpers to support both manual and semi-automated bandwidth selection.
**Manual — Start with ℓ ≈ √n**
A practical starting point for financial time series: set `ℓ ≈ √window_of_interest`. If you care about 100-bar structure, try `ℓ = 10`. If you care about 400-bar structure, try `ℓ = 20`. Adjust by ±25 % based on how noisy the result looks.
**Silverman's Rule of Thumb**
The closed-form optimal bandwidth for Gaussian-family kernels under Gaussian source assumptions:
```
h ≈ 1.06 · σ · n^(−1/5)
```
Call `silvermanBandwidth(src, window)` to compute this value live. Because Pine requires `simple int` bandwidth at compile time, the returned value is for diagnostic use — plot it, read the stable value off the chart, then hard-code the rounded integer into your kernel calls.
**Leave-One-Out Cross-Validation (Manual)**
For academic rigor, compute the leave-one-out mean squared error for a range of bandwidths and pick the minimum. KernelLens does not automate this (it would require `series int` bandwidth, which Pine does not support inside kernel loops), but the formula is straightforward:
```
LOOCV(ℓ) = (1/n) · Σᵢ (yᵢ − ŷᵢ⁻ⁱ(ℓ))²
```
where `ŷᵢ⁻ⁱ` is the kernel estimate at bar `i` computed without including bar `i` in the sum. Evaluate offline, pick the minimum, hard-code the result.
🟦 FILTER SELECTION — WHEN TO USE EACH
| Filter | Best For | Avoid When |
|---|---|---|
| `FILTER_NONE` | Live signal generation, research / calibration, compact-support kernels on noisy data | Choppy markets where you need extra smoothing |
| `FILTER_SMOOTH` | Swing and position trades, confidence band midlines, most day-trading setups | Scalping — the double pass adds measurable lag |
| `FILTER_ZEROLAG` | Regime detection, crossover systems that need the curve to track price tightly | Low-volume assets — Zero Lag amplifies high-frequency noise |
The three filters use the same underlying kernel with the same bandwidth, so switching between them does not require re-tuning. Default to `FILTER_SMOOTH` when in doubt — it is the best-behaved option across the widest range of assets and timeframes.
🟦 COMPATIBILITY
KernelLens targets Pine Script v6 and runs on every PulseWire chart — no exchange, asset class, or timeframe restriction.
- **Crypto** — Spot, futures, perpetual contracts
- **Forex** — All majors, minors, and exotics
- **Equities** — Stocks, ETFs, indices
- **Commodities** — Metals, energy, agriculture
- **Timeframes** — 1 minute through Monthly
The library is deterministic — given the same source and parameters, every bar of every symbol produces the same estimate. No calibration is needed across assets; the bandwidth parameter alone controls smoothness, and the kernel formulas are scale-free in the source dimension. Silverman's bandwidth helper automatically adapts to each asset's volatility.
🟦 TECHNICAL NOTES
- **Pine Script v6** — uses the modern type system, strict type checking, and the `switch` expression in the unified dispatcher
- **Non-repainting** — kernel outputs for any confirmed bar depend only on that bar's history; there is no look-ahead, no `request.security` with lookahead, and no dependency on the unconfirmed current bar unless `_phase = 0` is deliberately chosen
- **NA-safe iteration** — every bar lookup inside a kernel loop is guarded by `if not na(y)`, so chart history gaps and warm-up bars cannot poison the weighted sum
- **Division-by-zero protection** — every kernel's final division checks `den > 0.0` and returns `na` if the denominator collapses (which can only happen on truly empty windows)
- **Input validation** — every public function asserts its preconditions up front via `_assertFilter`, `_assertBandwidth`, `_assertPeriod`, `_assertAlpha`, and raises `runtime.error` with a descriptive message on misuse — no silent `na` fallbacks
- **Lazy filter evaluation** — the `"No Filter"` path never executes the second kernel pass; the `if`-branch check short-circuits, so single-pass mode is as cheap as a raw kernel call
- **Correct loop bounds** — `_depthInfinite`, `_depthCompact`, and `_depthPeriodic` compute the correct window size per kernel family, fixing the silent `_size = 1` bug that plagues every other published Pine kernel library
- **No persistent state** — the library is purely functional: no `var`, no arrays, no history buffers that grow over time; every export is a pure expression of `(inputs) → output`, so Pine's `max_*_count` limits cannot be exceeded and the library cannot leak memory
- **O(bandwidth) per bar per kernel call** — the loop depth is bounded by the constants in Section 0; there is no hidden quadratic behavior and the cost scales linearly with the user-chosen bandwidth
- **Unicode-safe comments** — the source uses academic notation (`σ`, `ℓ`, `α`, `ŷ`, `ℝ`) where it improves readability; all strings are plain ASCII for runtime compatibility
🟦 ACADEMIC REFERENCES
Every kernel and every formula in KernelLens is cited inline in the source. The combined bibliography:
- **Nadaraya, E. A. (1964).** On estimating regression. *Theory of Probability & Its Applications*, 9(1), 141–142.
- **Watson, G. S. (1964).** Smooth regression analysis. *Sankhyā: The Indian Journal of Statistics, Series A*, 26(4), 359–372.
- **Cleveland, W. S. (1979).** Robust locally weighted regression and smoothing scatterplots. *Journal of the American Statistical Association*, 74(368), 829–836. *(Tricube kernel, LOWESS.)*
- **Silverman, B. W. (1986).** *Density Estimation for Statistics and Data Analysis*. Chapman & Hall, London. *(Bandwidth rule of thumb.)*
- **Wand, M. P. & Jones, M. C. (1995).** *Kernel Smoothing*. Chapman & Hall. *(Unified treatment of all eight kernels.)*
- **MacKay, D. J. C. (1998).** Introduction to Gaussian Processes. *NIPS Tutorial*. *(Periodic and Rational Quadratic kernels.)*
- **Ehlers, J. F. (2000).** *Rocket Science for Traders*. John Wiley & Sons. *(Zero-lag smoothing trick.)*
- **Rasmussen, C. E. & Williams, C. K. I. (2006).** *Gaussian Processes for Machine Learning*. MIT Press. *(Locally Periodic and Rational Quadratic kernels.)*
🟦 VERSIONING & LICENSE
- **Version** — 1.0.0
- **Pine Script** — v6
- **License** — Mozilla Public License 2.0
- **Status** — Production-ready
KernelLens follows semantic versioning. Minor versions add new exports without breaking existing ones; patch versions fix bugs; major versions may change function signatures and will be announced in the changelog.
🟦 DISCLAIMER
KernelLens is a mathematical library for non-parametric regression on financial time series using the Nadaraya–Watson method. The library is provided solely for educational and research purposes and does not constitute financial, investment, or trading advice.
Kernel regression is a local smoothing technique. It estimates the mean of a source series in the neighborhood of the current bar based on historical data, but it does not predict future prices, does not generate trading signals on its own, and does not guarantee the profitability of any strategy built on top of its output.
Past performance of any model does not guarantee future results. Markets contain systemic risks that cannot be eliminated by any amount of mathematical rigor in the kernel itself. Responsibility for any trading decisions made using this library rests entirely with the user. Always apply sound capital management, conduct your own independent analysis, and never risk capital you are not prepared to lose.
The author assumes no liability for direct or indirect losses incurred through the use of KernelLens or any indicator built on top of it. Library

Machine Learning SupertrendThe Machine Learning Supertrend is an advanced trend-following indicator that enhances the traditional Supertrend with Gaussian Process Regression (GPR) and kernel-based learning. Unlike conventional methods that rely purely on historical ATR values, this indicator integrates machine learning techniques to dynamically estimate volatility and forecast future price movements, resulting in a more adaptive and robust trend detection system.
At the core of this indicator lies Gaussian Process Regression (GPR), which utilizes a Radial Basis Function (RBF) kernel to model price distributions and anticipate future trends. Instead of simply looking at past price action, it constructs a kernel matrix, enabling a probabilistic approach to price forecasting. This allows the indicator to not only detect current trends but also project potential trend reversals with greater accuracy.
By applying machine learning to ATR estimation, the ML Supertrend dynamically adjusts its thresholds based on predicted values rather than a fixed multiplier. This makes the trend signals more responsive to market conditions, reducing false signals and minimizing whipsaws often seen with traditional Supertrend indicators. The upper and lower bands are no longer static but evolve based on the underlying price structure, improving the reliability of trend shifts.
When the price crosses these adaptive levels, the indicator detects a trend change and plots it accordingly. Green signifies a bullish trend, while red indicates a bearish one. Alerts can also be triggered when the trend shifts, allowing traders to react quickly to potential reversals.
What makes this approach powerful is its ability to adapt to different market conditions. Traditional ATR-based methods use fixed parameters that might not always be optimal, whereas this ML-driven Supertrend continuously refines its estimations based on real-time data. The result is a more intelligent, less lagging, and highly adaptive trend-following tool.
This indicator is particularly useful for traders looking to enhance trend-following strategies with AI-driven insights. It reduces noise, improves signal reliability, and even offers a degree of trend forecasting, making it ideal for those who want a more advanced and dynamic alternative to standard Supertrend indicators.
This indicator is provided for educational and informational purposes only. It does not constitute financial advice, and past performance is not indicative of future results. Trading involves risk, and users should conduct their own research and use proper risk management before making investment decisions. Indicator

Machine Learning Price Target Prediction Signals [AlgoAlpha]Introducing the Machine Learning Price Target Predictions, a cutting-edge trading tool that leverages kernel regression to provide accurate price targets and enhance your trading strategy. This indicator combines trend-based signals with advanced machine learning techniques, offering predictive insights into potential price movements. Perfect for traders looking to make data-driven decisions with confidence.
What is Kernel Regression and How It Works
Kernel regression is a non-parametric machine learning technique that estimates the relationship between variables by weighting data points based on their similarity to a given input. The similarity is determined using a kernel function, such as the Gaussian (RBF) kernel, which assigns higher weights to closer data points and progressively lower weights to farther ones. This allows the model to make smooth and adaptive predictions, balancing recent data and historical trends.
Key Features
🎯 Predictive Price Targets : Uses kernel regression to estimate the magnitude of price movements.
📈 Dynamic Trend Analysis : Multiple trend detection methods, including EMA crossovers, Hull Moving Average, and SuperTrend.
🔧 Customizable Settings : Adjust bandwidth for kernel regression and tweak trend indicator parameters to suit your strategy.
📊 Visual Trade Levels : Displays take-profit and stop-loss levels directly on the chart with customizable colors.
📋 Performance Metrics : Real-time win rate, recommended risk-reward ratio, and training data size displayed in an on-chart table.
🔔 Alerts : Get notified for new trends, take-profit hits, and stop-loss triggers.
How to Use
🛠 Add the Indicator : Add it to your favorites and apply it to your chart. Configure the trend detection method (SuperTrend, HMA, or EMA crossover) and other parameters based on your preferences.
📊 Analyze Predictions : Observe the predicted move size, recommended risk-reward ratio, and trend direction. Use the displayed levels for trade planning.
🔔 Set Alerts : Enable alerts for trend signals, take-profit hits, or stop-loss triggers to stay informed without constant monitoring.
How It Works
The indicator calculates features such as price volatility, relative strength, and trend signals, which are stored during training periods. When a trend change is detected, the kernel regression model predicts the likely price move based on these features. Predictions are smoothed using the specified bandwidth to avoid overfitting while ensuring timely responses to feature changes. Visualized take-profit and stop-loss levels help traders optimize risk management. Real-time metrics like win rate and recommended risk-reward ratios provide actionable insights for decision-making. Indicator

Kernel Regression Envelope with SMI OscillatorThis script combines the predictive capabilities of the **Nadaraya-Watson estimator**, implemented by the esteemed jdehorty (credit to him for his excellent work on the `KernelFunctions` library and the original Nadaraya-Watson Envelope indicator), with the confirmation strength of the **Stochastic Momentum Index (SMI)** to create a dynamic trend reversal strategy. The core idea is to identify potential overbought and oversold conditions using the Nadaraya-Watson Envelope and then confirm these signals with the SMI before entering a trade.
**Understanding the Nadaraya-Watson Envelope:**
The Nadaraya-Watson estimator is a non-parametric regression technique that essentially calculates a weighted average of past price data to estimate the current underlying trend. Unlike simple moving averages that give equal weight to all past data within a defined period, the Nadaraya-Watson estimator uses a **kernel function** (in this case, the Rational Quadratic Kernel) to assign weights. The key parameters influencing this estimation are:
* **Lookback Window (h):** This determines how many historical bars are considered for the estimation. A larger window results in a smoother estimation, while a smaller window makes it more reactive to recent price changes.
* **Relative Weighting (alpha):** This parameter controls the influence of different time frames in the estimation. Lower values emphasize longer-term price action, while higher values make the estimator more sensitive to shorter-term movements.
* **Start Regression at Bar (x\_0):** This allows you to exclude the potentially volatile initial bars of a chart from the calculation, leading to a more stable estimation.
The script calculates the Nadaraya-Watson estimation for the closing price (`yhat_close`), as well as the highs (`yhat_high`) and lows (`yhat_low`). The `yhat_close` is then used as the central trend line.
**Dynamic Envelope Bands with ATR:**
To identify potential entry and exit points around the Nadaraya-Watson estimation, the script uses **Average True Range (ATR)** to create dynamic envelope bands. ATR measures the volatility of the price. By multiplying the ATR by different factors (`nearFactor` and `farFactor`), we create multiple bands:
* **Near Bands:** These are closer to the Nadaraya-Watson estimation and are intended to identify potential immediate overbought or oversold zones.
* **Far Bands:** These are further away and can act as potential take-profit or stop-loss levels, representing more extreme price extensions.
The script calculates both near and far upper and lower bands, as well as an average between the near and far bands. This provides a nuanced view of potential support and resistance levels around the estimated trend.
**Confirming Reversals with the Stochastic Momentum Index (SMI):**
While the Nadaraya-Watson Envelope identifies potential overextended conditions, the **Stochastic Momentum Index (SMI)** is used to confirm a potential trend reversal. The SMI, unlike a traditional stochastic oscillator, oscillates around a zero line. It measures the location of the current closing price relative to the median of the high/low range over a specified period.
The script calculates the SMI on a **higher timeframe** (defined by the "Timeframe" input) to gain a broader perspective on the market momentum. This helps to filter out potential whipsaws and false signals that might occur on the current chart's timeframe. The SMI calculation involves:
* **%K Length:** The lookback period for calculating the highest high and lowest low.
* **%D Length:** The period for smoothing the relative range.
* **EMA Length:** The period for smoothing the SMI itself.
The script uses a double EMA for smoothing within the SMI calculation for added smoothness.
**How the Indicators Work Together in the Strategy:**
The strategy enters a long position when:
1. The closing price crosses below the **near lower band** of the Nadaraya-Watson Envelope, suggesting a potential oversold condition.
2. The SMI crosses above its EMA, indicating positive momentum.
3. The SMI value is below -50, further supporting the oversold idea on the higher timeframe.
Conversely, the strategy enters a short position when:
1. The closing price crosses above the **near upper band** of the Nadaraya-Watson Envelope, suggesting a potential overbought condition.
2. The SMI crosses below its EMA, indicating negative momentum.
3. The SMI value is above 50, further supporting the overbought idea on the higher timeframe.
Trades are closed when the price crosses the **far band** in the opposite direction of the trade. A stop-loss is also implemented based on a fixed value.
**In essence:** The Nadaraya-Watson Envelope identifies areas where the price might be deviating significantly from its estimated trend. The SMI, calculated on a higher timeframe, then acts as a confirmation signal, suggesting that the momentum is shifting in the direction of a potential reversal. The ATR-based bands provide dynamic entry and exit points based on the current volatility.
**How to Use the Script:**
1. **Apply the script to your chart.**
2. **Adjust the "Kernel Settings":**
* **Lookback Window (h):** Experiment with different values to find the smoothness that best suits the asset and timeframe you are trading. Lower values make the envelope more reactive, while higher values make it smoother.
* **Relative Weighting (alpha):** Adjust to control the influence of different timeframes on the Nadaraya-Watson estimation.
* **Start Regression at Bar (x\_0):** Increase this value if you want to exclude the initial, potentially volatile, bars from the calculation.
* **Stoploss:** Set your desired stop-loss value.
3. **Adjust the "SMI" settings:**
* **%K Length, %D Length, EMA Length:** These parameters control the sensitivity and smoothness of the SMI. Experiment to find settings that work well for your trading style.
* **Timeframe:** Select the higher timeframe you want to use for SMI confirmation.
4. **Adjust the "ATR Length" and "Near/Far ATR Factor":** These settings control the width and sensitivity of the envelope bands. Smaller ATR lengths make the bands more reactive to recent volatility.
5. **Customize the "Color Settings"** to your preference.
6. **Observe the plots:**
* The **Nadaraya-Watson Estimation (yhat)** line represents the estimated underlying trend.
* The **near and far upper and lower bands** visualize potential overbought and oversold zones based on the ATR.
* The **fill areas** highlight the regions between the near and far bands.
7. **Look for entry signals:** A long entry is considered when the price touches or crosses below the lower near band and the SMI confirms upward momentum. A short entry is considered when the price touches or crosses above the upper near band and the SMI confirms downward momentum.
8. **Manage your trades:** The script provides exit signals when the price crosses the far band. The fixed stop-loss will also close trades if the price moves against your position.
**Justification for Combining Nadaraya-Watson Envelope and SMI:**
The combination of the Nadaraya-Watson Envelope and the SMI provides a more robust approach to identifying potential trend reversals compared to using either indicator in isolation. The Nadaraya-Watson Envelope excels at identifying potential areas where the price is overextended relative to its recent history. However, relying solely on the envelope can lead to false signals, especially in choppy or volatile markets. By incorporating the SMI as a confirmation tool, we add a momentum filter that helps to validate the potential reversals signaled by the envelope. The higher timeframe SMI further helps to filter out noise and focus on more significant shifts in momentum. The ATR-based bands add a dynamic element to the entry and exit points, adapting to the current market volatility. This mashup aims to leverage the strengths of each indicator to create a more reliable trading strategy.
Strategy

Cosine Kernel Regressions [QuantraSystems]Cosine Kernel Regressions
Introduction
The Cosine Kernel Regressions indicator (CKR) uses mathematical concepts to offer a unique approach to market analysis. This indicator employs Kernel Regressions using bespoke tunable Cosine functions in order to smoothly interpret a variety of market data, providing traders with incredibly clean insights into market trends.
The CKR is particularly useful for traders looking to understand underlying trends without the 'noise' typical in raw price movements. It can serve as a standalone trend analysis tool or be combined with other indicators for more robust trading strategies.
Legend
Fast Trend Signal Line - This is the foreground oscillator, it is colored upon the earliest confirmation of a change in trend direction.
Slow Trend Signal Line - This oscillator is calculated in a similar manner. However, it utilizes a lower frequency within the cosine tuning function, allowing it to capture longer and broader trends in one signal. This allows for tactical trading; the user can trade smaller moves without losing sight of the broader trend.
Case Study
In this case study, the CKR was used alongside the Triple Confirmation Kernel Regression Oscillator (KRO)
Initially, the KRO indicated an oversold condition, which could be interpreted as a signal to enter a long position in anticipation of a price rebound. However, the CKR’s fast trend signal line had not yet confirmed a positive trend direction - suggesting that entering a trade too early and without confirmation could be a mistake.
Waiting for a confirmed positive trend from the CKR proved beneficial for this trade. A few candles after the oversold signal, the CKR's fast trend signal line shifted upwards, indicating a strong upward momentum. This was the optimal entry point suggested by the CKR, occurring after the confirmation of the trend change, which significantly reduced the likelihood of entering during a false recovery or continuation of the downtrend.
This is one of the many uses of the CKR - by timing entries using the fast signal line , traders could avoid unnecessary losses by preventing premature entries.
Methodology
The methodology behind CKR is a multi-layered approach and utilizes many ‘base’ indicators.
Relative Strength Index
Stochastic Oscillator
Bollinger Band Percent
Chande Momentum Oscillator
Commodity Channel Index
Fisher Transform
Volume Zone Oscillator
The calculated output from each indicator is standardized and scaled before being averaged. This prevents any single indicator from overpowering the resulting signal.
// ╔════════════════════════════════╗ //
// ║ Scaling/Range Adjustment ║ //
// ╚════════════════════════════════╝ //
RSI_ReScale (_res ) => ( _res - 50 ) * 2.8
STOCH_ReScale (_stoch ) => ( _stoch - 50 ) * 2
BBPCT_ReScale (_bbpct ) => ( _bbpct - 0.5 ) * 120
CMO_ReScale (_chandeMO ) => ( _chandeMO * 1.15 )
CCI_ReScale (_cci ) => ( _cci / 2 )
FISH_ReScale (_fish1 ) => ( _fish1 * 30 )
VZO_ReScale (_VP, _TV ) => (_VP / _TV) * 110
These outputs are then fed into a customized cosine kernel regression function, which smooths the data, and combines all inputs into a single coherent output.
// ╔════════════════════════════════╗ //
// ║ COSINE KERNEL REGRESSIONS ║ //
// ╚════════════════════════════════╝ //
// Define a function to compute the cosine of an input scaled by a frequency tuner
cosine(x, z) =>
// Where x = source input
// y = function output
// z = frequency tuner
var y = 0.
y := math.cos(z * x)
Y
// Define a kernel that utilizes the cosine function
kernel(x, z) =>
var y = 0.
y := cosine(x, z)
math.abs(x) <= math.pi/(2 * z) ? math.abs(y) : 0. // cos(zx) = 0
// The above restricts the wave to positive values // when x = π / 2z
The tuning of the regression is adjustable, allowing users to fine-tune the sensitivity and responsiveness of the indicator to match specific trading strategies or market conditions. This robust methodology ensures that CKR provides a reliable and adaptable tool for market analysis.
Indicator

Kernels©2024, GoemonYae; copied from @jdehorty's "KernelFunctions" on 2024-03-09 to ensure future dependency compatibility. Will also add more functions to this script.
Library "KernelFunctions"
This library provides non-repainting kernel functions for Nadaraya-Watson estimator implementations. This allows for easy substition/comparison of different kernel functions for one another in indicators. Furthermore, kernels can easily be combined with other kernels to create newer, more customized kernels.
rationalQuadratic(_src, _lookback, _relativeWeight, startAtBar)
Rational Quadratic Kernel - An infinite sum of Gaussian Kernels of different length scales.
Parameters:
_src (float) : The source series.
_lookback (simple int) : The number of bars used for the estimation. This is a sliding value that represents the most recent historical bars.
_relativeWeight (simple float) : Relative weighting of time frames. Smaller values resut in a more stretched out curve and larger values will result in a more wiggly curve. As this value approaches zero, the longer time frames will exert more influence on the estimation. As this value approaches infinity, the behavior of the Rational Quadratic Kernel will become identical to the Gaussian kernel.
startAtBar (simple int)
Returns: yhat The estimated values according to the Rational Quadratic Kernel.
gaussian(_src, _lookback, startAtBar)
Gaussian Kernel - A weighted average of the source series. The weights are determined by the Radial Basis Function (RBF).
Parameters:
_src (float) : The source series.
_lookback (simple int) : The number of bars used for the estimation. This is a sliding value that represents the most recent historical bars.
startAtBar (simple int)
Returns: yhat The estimated values according to the Gaussian Kernel.
periodic(_src, _lookback, _period, startAtBar)
Periodic Kernel - The periodic kernel (derived by David Mackay) allows one to model functions which repeat themselves exactly.
Parameters:
_src (float) : The source series.
_lookback (simple int) : The number of bars used for the estimation. This is a sliding value that represents the most recent historical bars.
_period (simple int) : The distance between repititions of the function.
startAtBar (simple int)
Returns: yhat The estimated values according to the Periodic Kernel.
locallyPeriodic(_src, _lookback, _period, startAtBar)
Locally Periodic Kernel - The locally periodic kernel is a periodic function that slowly varies with time. It is the product of the Periodic Kernel and the Gaussian Kernel.
Parameters:
_src (float) : The source series.
_lookback (simple int) : The number of bars used for the estimation. This is a sliding value that represents the most recent historical bars.
_period (simple int) : The distance between repititions of the function.
startAtBar (simple int)
Returns: yhat The estimated values according to the Locally Periodic Kernel. Library

Triple Confirmation Kernel Regression Overlay [QuantraSystems]Kernel Regression Oscillator - Overlay
Introduction
The Kernel Regression Oscillator (ᏦᏒᎧ) represents an advanced tool for traders looking to capitalize on market trends.
This Indicator is valuable in identifying and confirming trend directions, as well as probabilistic and dynamic oversold and overbought zones.
It achieves this through a unique composite approach using three distinct Kernel Regressions combined in an Oscillator.
The additional Chart Overlay Indicator adds confidence to the signal.
Which is this Indicator.
This methodology helps the trader to significantly reduce false signals and offers a more reliable indication of market movements than more widely used indicators can.
Legend
The upper section is the Overlay. It features the Signal Wave to display the current trend.
Its Overbought and Oversold zones start at 50% and end at 100% of the selected Standard Deviation (default σ = 3), which can indicate extremely rare situations which can lead to either a softening momentum in the trend or even a mean reversion situation.
The lower one is the Base Chart.
The Indicator is linked here
It features the Kernel Regression Oscillator to display a composite of three distinct regressions, also displaying current trend.
Its Overbought and Oversold zones start at 50% and end at 100% of the selected Standard Deviation (default σ = 2), which can indicate extremely rare situations.
Case Study
To effectively utilize the ᏦᏒᎧ, traders should use both the additional Overlay and the Base
Chart at the same time. Then focus on capturing the confluence in signals, for example:
If the 𝓢𝓲𝓰𝓷𝓪𝓵 𝓦𝓪𝓿𝓮 on the Overlay and the ᏦᏒᎧ on the Base Chart both reside near the extreme of an Oversold zone the probability is higher than normal that momentum in trend may soften or the token may even experience a reversion soon.
If a bar is characterized by an Oversold Shading in both the Overlay and the Base Chart, then the probability is very high to experience a reversion soon.
In this case the trader may want to look for appropriate entries into a long position, as displayed here.
If a bar is characterized by an Overbought Shading in either Overlay or Base Chart, then the probability is high for momentum weakening or a mean reversion.
In this case the trade may have taken profit and closed his long position, as displayed here.
Please note that we always advise to find more confluence by additional indicators.
Recommended Settings
Swing Trading (1D chart)
Overlay
Bandwith: 45
Width: 2
SD Lookback: 150
SD Multiplier: 2
Base Chart
Bandwith: 45
SD Lookback: 150
SD Multiplier: 2
Fast-paced, Scalping (4min chart)
Overlay
Bandwith: 75
Width: 2
SD Lookback: 150
SD Multiplier: 3
Base Chart
Bandwith: 45
SD Lookback: 150
SD Multiplier: 2
Notes
The Kernel Regression Oscillator on the Base Chart is also sensitive to divergences if that is something you are keen on using.
For maximum confluence, it is recommended to use the indicator both as a chart overlay and in its Base Chart.
Please pay attention to shaded areas with Standard Deviation settings of 2 or 3 at their outer borders, and consider action only with high confidence when both parts of the indicator align on the same signal.
This tool shows its best performance on timeframes lower than 4 hours.
Traders are encouraged to test and determine the most suitable settings for their specific trading strategies and timeframes.
The trend following functionality is indicated through the "𝓢𝓲𝓰𝓷𝓪𝓵 𝓦𝓪𝓿𝓮" Line, with optional "Up" and "Down" arrows to denote trend directions only (toggle “Show Trend Signals”).
Methodology
The Kernel Regression Oscillator takes three distinct kernel regression functions,
used at similar weight, in order to calculate a balanced and smooth composite of the regressions. Part of it are:
The Epanechnikov Kernel Regression: Known for its efficiency in smoothing data by assigning less weight to data points further away from the target point than closer data points, effectively reducing variance.
The Wave Kernel Regression: Similarly assigning weight to the data points based on distance, it captures repetitive and thus wave-like patterns within the data to smoothen out and reduce the effect of underlying cyclical trends.
The Logistic Kernel Regression: This uses the logistic function in order to assign weights by probability distribution on the distance between data points and target points. It thus avoids both bias and variance to a certain level.
kernel(source, bandwidth, kernel_type) =>
switch kernel_type
"Epanechnikov" => math.abs(source) <= 1 ? 0.75 * (1 - math.pow(source, 2)) : 0.0
"Logistic" => 1/math.exp(source + 2 + math.exp(-source))
"Wave" => math.abs(source) <= 1 ? (1 - math.abs(source)) * math.cos(math.pi * source) : 0.
kernelRegression(src, bandwidth, kernel_type) =>
sumWeightedY = 0.
sumKernels = 0.
for i = 0 to bandwidth - 1
base = i*i/math.pow(bandwidth, 2)
kernel = kernel(base, 1, kernel_type)
sumWeightedY += kernel * src
sumKernels += kernel
(src - sumWeightedY/sumKernels)/src
// Triple Confirmations
Ep = kernelRegression(source, bandwidth, 'Epanechnikov' )
Lo = kernelRegression(source, bandwidth, 'Logistic' )
Wa = kernelRegression(source, bandwidth, 'Wave' )
By combining these regressions in an unbiased average, we follow our principle of achieving confluence for a signal or a decision, by stacking several edges to increase the probability that we are correct.
// Average
AV = math.avg(Ep, Lo, Wa)
The Standard Deviation bands take defined parameters from the user, in this case sigma of ideally between 2 to 3,
to help the indicator detect extremely improbable conditions and thus take an inversely probable signal from it to forward to the user.
The parameter settings and also the visualizations allow for ample customizations by the trader. The indicator comes with default and recommended settings.
For questions or recommendations, please feel free to seek contact in the comments.
Indicator

Triple Confirmation Kernel Regression Base [QuantraSystems]Kernel Regression Oscillator - BASE
Introduction
The Kernel Regression Oscillator (ᏦᏒᎧ) represents an advanced tool for traders looking to capitalize on market trends.
This Indicator is valuable in identifying and confirming trend directions, as well as probabilistic and dynamic oversold and overbought zones.
It achieves this through a unique composite approach using three distinct Kernel Regressions combined in an Oscillator. The additional Chart Overlay Indicator adds confidence to the signal.
This methodology helps the trader to significantly reduce false signals and offers a more reliable indication of market movements than more widely used indicators can.
Legend
The upper section is the Overlay. It features the Signal Wave to display the current trend.
Its Overbought and Oversold zones start at 50% and end at 100% of the selected Standard Deviation (default σ = 3), which can indicate extremely rare situations which can lead to either a softening momentum in the trend or even a mean reversion situation.
The lower one is the Base Chart - This Indicator.
It features the Kernel Regression Oscillator to display a composite of three distinct regressions, also displaying current trend.
Its Overbought and Oversold zones start at 50% and end at 100% of the selected Standard Deviation (default σ = 2), which can indicate extremely rare situations.
Case Study
To effectively utilize the ᏦᏒᎧ, traders should use both the additional Overlay and the Base
Chart at the same time. Then focus on capturing the confluence in signals, for example:
If the 𝓢𝓲𝓰𝓷𝓪𝓵 𝓦𝓪𝓿𝓮 on the Overlay and the ᏦᏒᎧ on the Base Chart both reside near the extreme of an Oversold zone the probability is higher than normal that momentum in trend may soften or the token may even experience a reversion soon.
If a bar is characterized by an Oversold Shading in both the Overlay and the Base Chart, then the probability is very high to experience a reversion soon.
In this case the trader may want to look for appropriate entries into a long position, as displayed here.
If a bar is characterized by an Overbought Shading in either Overlay or Base Chart, then the probability is high for momentum weakening or a mean reversion.
In this case the trade may have taken profit and closed his long position, as displayed here.
Please note that we always advise to find more confluence by additional indicators.
Recommended Settings
Swing Trading (1D chart)
Overlay
Bandwith: 45
Width: 2
SD Lookback: 150
SD Multiplier: 2
Base Chart
Bandwith: 45
SD Lookback: 150
SD Multiplier: 2
Fast-paced, Scalping (4min chart)
Overlay
Bandwith: 75
Width: 2
SD Lookback: 150
SD Multiplier: 3
Base Chart
Bandwith: 45
SD Lookback: 150
SD Multiplier: 2
Notes
The Kernel Regression Oscillator on the Base Chart is also sensitive to divergences if that is something you are keen on using.
For maximum confluence, it is recommended to use the indicator both as a chart overlay and in its Base Chart.
Please pay attention to shaded areas with Standard Deviation settings of 2 or 3 at their outer borders, and consider action only with high confidence when both parts of the indicator align on the same signal.
This tool shows its best performance on timeframes lower than 4 hours.
Traders are encouraged to test and determine the most suitable settings for their specific trading strategies and timeframes.
The trend following functionality is indicated through the "𝓢𝓲𝓰𝓷𝓪𝓵 𝓦𝓪𝓿𝓮" Line, with optional "Up" and "Down" arrows to denote trend directions only (toggle “Show Trend Signals”).
Methodology
The Kernel Regression Oscillator takes three distinct kernel regression functions,
used at similar weight, in order to calculate a balanced and smooth composite of the regressions. Part of it are:
The Epanechnikov Kernel Regression: Known for its efficiency in smoothing data by assigning less weight to data points further away from the target point than closer data points, effectively reducing variance.
The Wave Kernel Regression: Similarly assigning weight to the data points based on distance, it captures repetitive and thus wave-like patterns within the data to smoothen out and reduce the effect of underlying cyclical trends.
The Logistic Kernel Regression: This uses the logistic function in order to assign weights by probability distribution on the distance between data points and target points. It thus avoids both bias and variance to a certain level.
kernel(source, bandwidth, kernel_type) =>
switch kernel_type
"Epanechnikov" => math.abs(source) <= 1 ? 0.75 * (1 - math.pow(source, 2)) : 0.0
"Logistic" => 1/math.exp(source + 2 + math.exp(-source))
"Wave" => math.abs(source) <= 1 ? (1 - math.abs(source)) * math.cos(math.pi * source) : 0.
kernelRegression(src, bandwidth, kernel_type) =>
sumWeightedY = 0.
sumKernels = 0.
for i = 0 to bandwidth - 1
base = i*i/math.pow(bandwidth, 2)
kernel = kernel(base, 1, kernel_type)
sumWeightedY += kernel * src
sumKernels += kernel
(src - sumWeightedY/sumKernels)/src
// Triple Confirmations
Ep = kernelRegression(source, bandwidth, 'Epanechnikov' )
Lo = kernelRegression(source, bandwidth, 'Logistic' )
Wa = kernelRegression(source, bandwidth, 'Wave' )
By combining these regressions in an unbiased average, we follow our principle of achieving confluence for a signal or a decision, by stacking several edges to increase the probability that we are correct.
// Average
AV = math.avg(Ep, Lo, Wa)
The Standard Deviation bands take defined parameters from the user, in this case sigma of ideally between 2 to 3,
to help the indicator detect extremely improbable conditions and thus take an inversely probable signal from it to forward to the user.
The parameter settings and also the visualizations allow for ample customizations by the trader. The indicator comes with default and recommended settings.
For questions or recommendations, please feel free to seek contact in the comments. Indicator
