Files
QuanTAlib/lib/numerics/standardize/standardize.pine
T
Miha Kralj 86fe32a682 SIMD Refactor: Merge simd-dev into dev (#55)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
Co-authored-by: Warp <agent@warp.dev>
2026-01-18 19:02:03 -08:00

63 lines
2.4 KiB
Plaintext

// The MIT License (MIT)
// © mihakralj
//@version=6
indicator("Standardization (Z-score)", "STANDARDIZE", overlay=false, precision=4)
//@function Calculates the Z-score of a series over a lookback period.
//@doc https://github.com/mihakralj/pinescript/blob/main/indicators/numerics/standardize.md
//@param src series float Input data series.
//@param len simple int Lookback period for calculating mean and standard deviation (must be > 1 for sample stdev).
//@returns series float The Z-score of the current data point, or na if issues like insufficient data or zero stdev for a non-mean current value.
standardize(series float src, simple int len) =>
if len <= 1
float(na)
var S1 = 0.0
var S2 = 0.0
var N = 0
var float[] window_data_vals = array.new_float(0)
var bool[] window_data_is_na = array.new_bool(0)
float x_new = src[0]
bool x_new_is_na = na(x_new)
if array.size(window_data_vals) == len
float x_old_val = array.get(window_data_vals, 0)
bool x_old_was_na = array.get(window_data_is_na, 0)
array.shift(window_data_vals)
array.shift(window_data_is_na)
if not x_old_was_na
S1 -= x_old_val
S2 -= x_old_val * x_old_val
N -= 1
array.push(window_data_vals, x_new_is_na ? 0.0 : x_new)
array.push(window_data_is_na, x_new_is_na)
if not x_new_is_na
S1 += x_new
S2 += x_new * x_new
N += 1
float z_score = na
if N < 2
z_score := na
else
float mean_val = S1 / N
float variance_pop = (S2 / N) - (mean_val * mean_val)
variance_pop := variance_pop < 1e-10 ? 0.0 : variance_pop
float variance_sample = variance_pop * N / (N - 1)
float stdev_val = math.sqrt(variance_sample)
if x_new_is_na
z_score := na
else if stdev_val > 1e-10
z_score := (x_new - mean_val) / stdev_val
else
z_score := (math.abs(x_new - mean_val) < 1e-10) ? 0.0 : na
z_score
// Inputs
i_source = input.source(close, title="Source")
i_length = input.int(20, title="Lookback Period", minval=2, tooltip="Period for mean and standard deviation. Must be at least 2 for stdev.")
// Calculation
z_score_value = standardize(i_source, i_length) // Renamed for clarity
// Plot
plot(z_score_value, "Z-score", color=color.yellow, linewidth=2)
hline(0, "Zero Line", color=color.gray, linestyle=hline.style_dashed)