mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-15 17:18:05 +00:00
- Updated BBWN, BBWP, CCV, CV, CVI, EWMA, GKV, HLV, HV, Jvolty, JVOLTYN, MASSI, NATR, RSV, RV, RVI, TR, UI, VOV, VR, YZV indicators with documentation links. - Added documentation links for Aberration, Acceleration Bands, Andrews' Pitchfork, Adaptive Price Zone, ATR Bands, Bollinger Bands, Center of Gravity, Donchian Channels, Decay Min-Max Channel, Detrended Synthetic Price, EACP, EBSW, HOMOD, Jurik Volatility Bands, Keltner Channel, MA Envelope, Min-Max Channel, Price Channel, Regression Channels, Standard Deviation Channel, Stoller Average Range Channel, Super Trend Bands, Ultimate Bands, Ultimate Channel, VWAP Bands, and VWAP with Standard Deviation Bands.
62 lines
2.3 KiB
Plaintext
62 lines
2.3 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.
|
|
//@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)
|