// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("NET: Ehlers Noise Elimination Technology", "NET", overlay = false)
//@function Calculates Ehlers Noise Elimination Technology using Kendall Tau-a
//@param source Series to calculate NET from
//@param period Lookback window for Kendall correlation (>= 2)
//@returns Kendall tau coefficient [-1, +1]
//@optimized O(n²) pairwise concordance/discordance per bar
// ——— Inputs ———
int p_period = input.int(14, "Period", minval = 2, maxval = 100,
tooltip = "Lookback window for Kendall tau. Larger = smoother but slower response.")
string p_source = input.string("Close", "Source",
options = ["Close", "HL2", "HLC3", "OHLC4", "Open", "High", "Low"])
// ——— Source selector ———
float src = switch p_source
"Close" => close
"HL2" => hl2
"HLC3" => hlc3
"OHLC4" => ohlc4
"Open" => open
"High" => high
"Low" => low
// ——— Noise Elimination Technology (Kendall Tau-a) ———
// Reference: John F. Ehlers, "Noise Elimination Technology" (TASC, December 2020)
//
// Algorithm:
// Store last 'period' values: X[0]=current, X[1]=1 bar ago, ..., X[N-1]=oldest
// For each pair (i, k) where i > k (i is older, k is newer):
// Num -= Sign(X[i] - X[k])
// Denom = 0.5 * period * (period - 1)
// NET = Num / Denom
//
// When price is rising, newer values > older values → Sign(older-newer) < 0 → -Sign > 0 → NET positive
// When price is falling, newer values < older values → Sign(older-newer) > 0 → -Sign < 0 → NET negative
// Output bounded [-1, +1]: fraction of concordant minus discordant pairs
net(float source, int period) =>
float num = 0.0
for i = 1 to period - 1
for k = 0 to i - 1
num -= math.sign(source[i] - source[k])
float denom = 0.5 * period * (period - 1)
float result = denom > 0 ? num / denom : 0.0
result
// ——— Compute ———
float filt = net(src, p_period)
// ——— Plot ———
hline(0, "Zero", color = color.gray, linestyle = hline.style_dotted)
hline(0.5, "+0.5", color = color.new(color.green, 70), linestyle = hline.style_dotted)
hline(-0.5, "-0.5", color = color.new(color.red, 70), linestyle = hline.style_dotted)
plot(filt, "NET", color = filt >= 0 ? color.green : color.red, linewidth = 2)