Files

69 lines
2.9 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Weibull Distribution CDF (WEIBULLDIST)", "WEIBULLDIST", overlay=false, precision=6)
//@function Calculates the Weibull Distribution CDF
//@param source Series to evaluate (typically close)
//@param period Lookback period for min-max normalization
//@param shape Shape parameter k (> 0) — controls distribution form
//@param scale Scale parameter λ (> 0) — scales the normalized price
//@returns CDF value F(x) in [0, 1]
//@description The Weibull distribution CDF has a simple closed form:
// F(x; k, λ) = 1 exp((x/λ)^k) for x ≥ 0
// F(x) = 0 for x < 0
// The source is min-max normalized over the lookback period to [0, 1],
// then treated as the input x to the CDF (no additional scaling needed
// since λ handles the effective range).
// Shape k controls the distribution form:
// k < 1: decreasing failure rate (early failures) — concave CDF
// k = 1: constant failure rate (exponential distribution) — same as EXPDIST
// k = 2: Rayleigh distribution — linear failure rate
// k > 3: approaches normal-like shape — S-curve CDF
// Scale λ controls how quickly CDF rises:
// larger λ → slower rise (more spread), smaller λ → faster saturation
// No special functions needed — only exp and pow. O(period) for min-max scan,
// CDF itself is O(1). Stateless pure function — no var state.
// Trading interpretation: CDF near 1.0 = price at top of recent range,
// near 0.0 = price at bottom. Shape k tunes sensitivity to extremes.
weibulldist(series float source, simple int period, simple float shape, simple float scale) =>
if period <= 0
runtime.error("Period must be greater than 0")
if shape <= 0.0
runtime.error("Shape parameter must be greater than 0")
if scale <= 0.0
runtime.error("Scale parameter must be greater than 0")
float src = nz(source)
float hi = src
float lo = src
for i = 1 to period - 1
float v = nz(source[i])
hi := math.max(hi, v)
lo := math.min(lo, v)
float range = hi - lo
float x = range == 0.0 ? 0.5 : (src - lo) / range
float safeX = math.max(0.0, x)
float ratio = safeX / scale
float raised = math.pow(ratio, shape)
1.0 - math.exp(-raised)
// ---------- Main loop ----------
// Inputs
i_source = input.source(close, "Source")
i_period = input.int(50, "Period", minval=1)
i_shape = input.float(2.0, "Shape (k)", minval=0.01, step=0.1)
i_scale = input.float(0.5, "Scale (λ)", minval=0.01, step=0.1)
// Calculation
weibull_value = weibulldist(i_source, i_period, i_shape, i_scale)
// Plot
plot(weibull_value, "WEIBULLDIST", color=color.yellow, linewidth=2)
hline(0.5, "Midline", color=color.gray, linestyle=hline.style_dotted)
hline(0.95, "Upper", color=color.red, linestyle=hline.style_dashed)
hline(0.05, "Lower", color=color.green, linestyle=hline.style_dashed)