Files
2026-02-23 17:27:35 -08:00

52 lines
2.4 KiB
Plaintext

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0
// https://mozilla.org/MPL/2.0/
// © QuanTAlib
//@version=6
indicator("WINS: Winsorized Mean Moving Average", shorttitle="WINS", overlay=true)
// @function Calculates the Winsorized Mean Moving Average.
// Sorts the lookback window, then replaces (not discards) the lowest and
// highest winPct% of values with the boundary values at the trim point.
// This robust estimator reduces outlier influence while retaining the
// full sample size (unlike trimmed mean which discards).
// winPct=0 → SMA, winPct=50 → all values equal the median pair.
// @param src Series to smooth.
// @param period Window length. Must be >= 3.
// @param winPct Percentage of values to winsorize from each tail (0-49). Default 10.
// @returns The winsorized mean value.
wins(series float src, simple int period, simple int winPct) =>
// Number of values to winsorize from each end
int winCount = math.max(int(period * winPct / 100.0), 0)
if winCount >= period / 2
winCount := (period - 1) / 2
// Collect values into array and sort
float[] vals = array.new_float(period)
for i = 0 to period - 1
array.set(vals, i, nz(src[i]))
array.sort(vals, order.ascending)
// Replace tail values with boundary values
float lowerBound = array.get(vals, winCount)
float upperBound = array.get(vals, period - 1 - winCount)
for i = 0 to winCount - 1
array.set(vals, i, lowerBound)
array.set(vals, period - 1 - i, upperBound)
// Average all values (including replaced ones)
float sum = 0.0
for i = 0 to period - 1
sum += array.get(vals, i)
sum / period
// ── Inputs ──────────────────────────────────────────────
p = input.int(20, "Period", minval=3)
w = input.int(10, "Winsorize %", minval=0, maxval=49, tooltip="Percentage winsorized from each tail. 0=SMA")
// ── Calculation ─────────────────────────────────────────
result = wins(close, p, w)
// ── Plot ────────────────────────────────────────────────
plot(result, "WINS", color=color.yellow, linewidth=2)