mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-28 01:37:43 +00:00
52 lines
2.4 KiB
Plaintext
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)
|