// 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)