Add new moving average implementations: LTMA, MCNMA, NLMA, NMA, NYQMA, RAIN, and TRAMA

- LTMA (Linear Trend Moving Average): Introduces a predictive moving average using dual cascaded EMAs for trend estimation.
- MCNMA (McNicholl EMA): Implements a zero-lag TEMA using a cascaded EMA structure for enhanced responsiveness.
- NLMA (Non-Lag Moving Average): Utilizes a damped cosine kernel to achieve reduced lag in moving averages.
- NMA (Natural Moving Average): Adapts smoothing based on volatility profiles using a square-root kernel.
- NYQMA (Nyquist Moving Average): Applies the Nyquist-Shannon theorem to prevent aliasing in cascaded moving averages.
- RAIN (Rainbow Moving Average): Combines multiple SMA layers with weighted averages for multi-scale smoothing.
- TRAMA (Trend Regularity Adaptive Moving Average): Adapts smoothing based on the frequency of new highs and lows in price data.
This commit is contained in:
Miha Kralj
2026-02-20 21:40:32 -08:00
parent cbeefc9d64
commit 90d5638008
121 changed files with 9595 additions and 6315 deletions
+49
View File
@@ -0,0 +1,49 @@
# BETADIST: Beta Distribution CDF
BETADIST computes the cumulative distribution function of the Beta distribution applied to a min-max normalized price series. The source price is first normalized to $[0, 1]$ over a lookback window, then passed through the regularized incomplete beta function $I_x(\alpha, \beta)$ to produce a probability-mapped oscillator. The two shape parameters $\alpha$ and $\beta$ control the nonlinear mapping: symmetric parameters ($\alpha = \beta$) produce a sigmoid-like transformation centered at 0.5, while asymmetric parameters skew the mapping to emphasize extremes in either direction.
## Historical Context
The Beta distribution is one of the fundamental distributions in Bayesian statistics, serving as the conjugate prior for Bernoulli and binomial processes. Its application to financial time series normalization leverages the distribution's unique property of being defined on the bounded interval $[0, 1]$, making it a natural fit for min-max normalized price data. The CDF transformation converts a uniformly-distributed normalized price into a probability-weighted oscillator where the shape parameters control sensitivity to price levels within the range. When $\alpha = \beta = 1$, the Beta distribution reduces to the uniform distribution (no transformation); when $\alpha = \beta = 2$, it produces a smooth S-curve that compresses extremes and expands the midrange. The regularized incomplete beta function required for the CDF has no elementary closed form and requires numerical methods — this implementation uses Lentz's continued fraction algorithm, the standard approach in numerical libraries (NAG, CEPHES, Numerical Recipes).
## Architecture & Physics
### Three-Stage Pipeline
1. **Min-Max Normalization:** Scans the lookback window to find minimum and maximum values, then maps the current source to $x \in [0, 1]$. If the range is zero (flat price), defaults to 0.5.
2. **Lanczos Log-Gamma:** The Lanczos approximation with $g = 7$ and 9 coefficients computes $\ln\Gamma(z)$ for any positive $z$. This is used internally by the continued fraction to compute the prefactor of the incomplete beta function.
3. **Lentz Continued Fraction:** The regularized incomplete beta function $I_x(a, b)$ is evaluated via the modified Lentz algorithm. A symmetry flip is applied when $x > (a+1)/(a+b+2)$ to ensure convergence of the continued fraction from the correct side. Convergence typically requires 10-20 iterations for standard parameter ranges.
## Mathematical Foundation
**Min-max normalization:**
$$x_t = \frac{S_t - \min_{i \in [t-n, t]} S_i}{\max_{i \in [t-n, t]} S_i - \min_{i \in [t-n, t]} S_i}$$
**Beta CDF (regularized incomplete beta function):**
$$I_x(\alpha, \beta) = \frac{B(x; \alpha, \beta)}{B(\alpha, \beta)} = \frac{\int_0^x t^{\alpha-1}(1-t)^{\beta-1}\,dt}{B(\alpha, \beta)}$$
**Lentz continued fraction** for $I_x(a, b)$:
$$I_x(a,b) = \frac{x^a (1-x)^b}{a \cdot B(a,b)} \cdot \cfrac{1}{1+\cfrac{d_1}{1+\cfrac{d_2}{1+\cdots}}}$$
where $d_{2m} = \frac{m(b-m)x}{(a+2m-1)(a+2m)}$ and $d_{2m+1} = \frac{-(a+m)(a+b+m)x}{(a+2m)(a+2m+1)}$
**Symmetry flip:** If $x > \frac{a+1}{a+b+2}$, compute $I_x(a,b) = 1 - I_{1-x}(b,a)$
**Lanczos log-gamma** ($g = 7$, 9 coefficients):
$$\ln\Gamma(z) = \frac{1}{2}\ln(2\pi) + (z - \tfrac{1}{2})\ln(t) - t + \ln\left(\sum_{k=0}^{8} \frac{c_k}{z+k}\right)$$
where $t = z + g - \frac{1}{2}$
**Default parameters:** period = 50, alpha = 2.0, beta = 2.0.
## Resources
- Abramowitz, M. & Stegun, I. (1964). *Handbook of Mathematical Functions*, Chapter 26
- Press, W. et al. (2007). *Numerical Recipes*, 3rd ed. Cambridge, §6.4 (Incomplete Beta Function)
- PineScript reference: [`betadist.pine`](betadist.pine)
+43
View File
@@ -0,0 +1,43 @@
# BINOMDIST: Binomial Distribution CDF
BINOMDIST computes the cumulative distribution function of the Binomial distribution, mapping a min-max normalized price to a success probability $p$ and evaluating $P(X \leq k)$ for $X \sim \text{Binomial}(n, p)$. The normalized price position within its lookback range determines the probability of success per trial, while the trial count $n$ and threshold $k$ control the shape of the CDF response. The output is a $[0, 1]$ bounded oscillator where values near 0 indicate the price-derived probability makes $k$ or fewer successes very unlikely (bullish pressure), and values near 1 indicate $k$ successes are very likely (established range).
## Historical Context
The Binomial distribution, formalized by Jakob Bernoulli in 1713 and refined by Abraham de Moivre, is the foundational discrete probability distribution for counting successes in independent trials. Its CDF application to financial time series transforms the continuous price position into a discrete probabilistic framework: "given the current price's relative position as a probability, how likely is it that at most $k$ out of $n$ events would succeed?" This reframing provides a nonlinear transformation that is particularly sensitive around the probability values where $k/n$ transitions from unlikely to likely. The log-space summation technique used here avoids factorial overflow for large $n$, leveraging the Lanczos log-gamma approximation for $\ln(n!)$ computation.
## Architecture & Physics
### Two-Stage Pipeline
1. **Min-Max Normalization:** The source is normalized to $p \in [0, 1]$ over the lookback window. This probability represents the "success rate" implied by the price's position within its recent range.
2. **Binomial CDF Summation:** The CDF $P(X \leq k)$ is computed as a direct sum of binomial probabilities from $i = 0$ to $k$. Each term is computed in log-space to avoid overflow: $\ln\binom{n}{i} + i\ln(p) + (n-i)\ln(1-p)$, then exponentiated and accumulated. The log-binomial coefficient uses the Lanczos log-gamma function.
### Edge Cases
- $p \leq 0$: All mass at $X = 0$, so $P(X \leq k) = 1$ for any $k \geq 0$
- $p \geq 1$: All mass at $X = n$, so $P(X \leq k) = 1$ only if $k \geq n$
- Result is clamped to $[0, 1]$ to guard against floating-point accumulation drift
## Mathematical Foundation
**Binomial CDF:**
$$P(X \leq k) = \sum_{i=0}^{k} \binom{n}{i} p^i (1-p)^{n-i}$$
**Log-space computation** (avoids factorial overflow):
$$\ln\binom{n}{i} = \ln\Gamma(n+1) - \ln\Gamma(i+1) - \ln\Gamma(n-i+1)$$
$$P(X \leq k) = \sum_{i=0}^{k} \exp\!\left[\ln\binom{n}{i} + i\ln(p) + (n-i)\ln(1-p)\right]$$
**Lanczos log-gamma** ($g = 7$, 9 coefficients): same as BETADIST.
**Default parameters:** period = 50, trials = 20, threshold = 10 (symmetric: $k = n/2$).
## Resources
- Bernoulli, J. (1713). *Ars Conjectandi*
- Press, W. et al. (2007). *Numerical Recipes*, 3rd ed., §6.2 (Incomplete Beta as alternative)
- PineScript reference: [`binomdist.pine`](binomdist.pine)
+55
View File
@@ -0,0 +1,55 @@
# CWT: Continuous Wavelet Transform
CWT computes the magnitude of the Continuous Wavelet Transform at a specified scale using the Morlet wavelet, providing a time-frequency decomposition that measures the energy content of a specific frequency band at each point in time. Unlike Fourier analysis which loses time localization, the wavelet transform maintains both time and frequency information simultaneously. The output is a non-negative magnitude series where peaks indicate strong presence of the target frequency (determined by the scale parameter) and troughs indicate absence of that frequency component.
## Historical Context
The wavelet transform emerged from seismology and signal processing in the 1980s, with foundational work by Jean Morlet (a geophysicist analyzing seismic reflections) and Alex Grossmann. The Morlet wavelet — a complex sinusoid modulated by a Gaussian envelope — became the standard analyzing wavelet due to its optimal time-frequency resolution (it achieves the Heisenberg uncertainty lower bound). In financial applications, CWT provides multi-resolution analysis: by varying the scale parameter, traders can identify dominant cycles at different timeframes without the windowing artifacts of short-time Fourier transforms. The scale parameter directly controls which frequency band is analyzed: larger scales capture lower frequencies (longer cycles), smaller scales capture higher frequencies (shorter cycles). The relationship between scale $s$ and approximate cycle period is $P \approx \frac{2\pi s}{\omega_0}$ where $\omega_0$ is the central frequency (default 6.0).
## Architecture & Physics
### Morlet Wavelet Convolution
The CWT at scale $s$ is computed as the inner product of the signal with a scaled, translated Morlet wavelet:
$$W(t, s) = \frac{1}{\sqrt{s}} \sum_{k=-K}^{K} x(t-k) \cdot \psi^*\!\left(\frac{k}{s}\right)$$
The Morlet wavelet $\psi(t) = e^{-t^2/2} e^{i\omega_0 t}$ decomposes into real (cosine) and imaginary (sine) parts, both modulated by a Gaussian envelope.
### Implementation Details
- **Half-window:** $K = \text{round}(3s)$, ensuring the Gaussian envelope decays to $<0.01$ at the edges ($e^{-4.5} \approx 0.011$).
- **Real and imaginary sums:** Computed separately, then combined as $|W| = \sqrt{\text{Re}^2 + \text{Im}^2}$.
- **Normalization:** The $1/\sqrt{s}$ factor ensures energy preservation across scales.
### Complexity
$O(K)$ per bar where $K = 6s + 1$. For scale = 10, this is 61 multiply-adds per bar.
## Mathematical Foundation
**Morlet wavelet:**
$$\psi(t) = e^{-t^2/2} \cdot e^{i\omega_0 t}$$
**CWT at scale $s$ and time $t$:**
$$W(t, s) = \frac{1}{\sqrt{s}} \sum_{k=-K}^{K} x_{t+k} \cdot e^{-k^2/(2s^2)} \cdot e^{-i\omega_0 k/s}$$
**Magnitude (power at scale $s$):**
$$|W(t,s)| = \sqrt{\left(\sum_k x_k \cdot g_k \cos\theta_k\right)^2 + \left(\sum_k x_k \cdot g_k \sin\theta_k\right)^2} \cdot \frac{1}{\sqrt{s}}$$
where $g_k = e^{-k^2/(2s^2)}$ and $\theta_k = \omega_0 k / s$
**Scale-to-period relationship:**
$$P \approx \frac{2\pi s}{\omega_0}$$
**Default parameters:** scale = 10.0, omega = 6.0 (corresponding to period $\approx 10.5$ bars).
## Resources
- Morlet, J. et al. (1982). "Wave propagation and sampling theory." *Geophysics*, 47(2): 203-236
- Torrence, C. & Compo, G.P. (1998). "A Practical Guide to Wavelet Analysis." *Bulletin of the American Meteorological Society*
- PineScript reference: [`cwt.pine`](cwt.pine)
+69
View File
@@ -0,0 +1,69 @@
# DWT: Discrete Wavelet Transform
The Discrete Wavelet Transform decomposes a price series into multi-resolution frequency components using the a trous (with holes) stationary Haar wavelet. Unlike decimated DWT, the stationary variant preserves time alignment at every scale, producing an approximation (trend) and detail coefficients (noise/cycles) at each decomposition level. Each level doubles the effective receptive field: level $L$ captures structure at $2^L$ bars. With 1-8 levels and $O(L)$ per-bar cost, DWT provides a complete multi-scale decomposition that cleanly separates trend from noise without the phase distortion inherent in moving-average cascades.
## Historical Context
Classical wavelet analysis traces to Jean Morlet's 1980s seismology work, with formal DWT construction by Stephane Mallat (1989) and Ingrid Daubechies (1988). The a trous algorithm (Holschneider et al., 1989) emerged as a shift-invariant alternative to Mallat's decimated pyramid, sacrificing orthogonality for translation invariance. For financial series where exact bar alignment matters more than basis orthogonality, the stationary variant dominates.
The Haar wavelet is the simplest possible mother wavelet: a step function that computes local averages and differences. While it lacks the smoothness of Daubechies-N wavelets, its simplicity means zero multiplications beyond the 0.5 scaling factor, and its compact support (2 taps) minimizes boundary artifacts. For price series where discontinuities (gaps, jumps) are common, the Haar basis actually outperforms smoother wavelets that assume continuous derivatives that do not exist in market data.
The multi-resolution analysis (MRA) framework guarantees perfect reconstruction: summing the approximation at any level with all detail coefficients from that level back to level 1 recovers the original signal exactly. This property is critical for attribution: the energy (variance) at each scale sums to the total variance, providing a complete variance decomposition across time scales.
## Architecture and Physics
The implementation uses an unrolled cascade of 8 levels, each conditionally executed based on the `levels` parameter. At level $j$, the approximation is the average of the current approximation and its value $2^{j-1}$ bars ago, with the detail coefficient being their difference.
**Pipeline structure:**
1. **Level 1**: Average source with 1-bar-ago source (2-bar window)
2. **Level 2**: Average level-1 approx with its 2-bar-ago value (4-bar effective window)
3. **Level $j$**: Average level-$(j-1)$ approx with its $2^{j-1}$-bar-ago value ($2^j$-bar effective window)
The `output` selector chooses which component to return: 0 for the deepest approximation (smooth trend), or 1-8 for the detail coefficient at that level. Detail level 1 captures the highest-frequency noise (2-bar oscillations); detail level $L$ captures oscillations at the $2^L$-bar scale.
**Boundary handling** uses `nz()` substitution: when historical data is unavailable at the required lag, the algorithm uses the current approximation value. This introduces a warm-up transient of $2^L$ bars for level $L$, after which the decomposition stabilizes.
**Stationarity property**: Because no downsampling occurs, every output sample aligns exactly with its input bar. This permits direct overlay of approximation on price and meaningful bar-by-bar analysis of detail coefficients.
## Mathematical Foundation
The a trous Haar wavelet decomposition at level $j$:
$$c_j[n] = \frac{1}{2}\bigl(c_{j-1}[n] + c_{j-1}[n - 2^{j-1}]\bigr)$$
$$d_j[n] = c_{j-1}[n] - c_j[n]$$
where $c_0[n] = x[n]$ is the input source.
**Perfect reconstruction** at any level $L$:
$$x[n] = c_L[n] + \sum_{j=1}^{L} d_j[n]$$
**Effective window** at level $j$ is $2^j$ bars. The Haar scaling function at level $j$ is:
$$\phi_j[n] = 2^{-j/2} \cdot \mathbf{1}_{[0,\, 2^j)}(n)$$
**Variance decomposition**: Since detail coefficients at different levels are uncorrelated:
$$\text{Var}(x) = \text{Var}(c_L) + \sum_{j=1}^{L} \text{Var}(d_j)$$
**Parameter ranges**: `levels` $\in [1, 8]$, `output` $\in [0, \text{levels}]$. Maximum lookback is $2^{\text{levels}}$ bars (256 bars at level 8).
```
DWT(source, levels, output):
c[0] = source
for j = 1 to levels:
c[j] = 0.5 * (c[j-1] + c[j-1][2^(j-1)])
d[j] = c[j-1] - c[j]
if output == 0: return c[levels] // approximation (trend)
else: return d[output] // detail at selected level
```
## Resources
- Mallat, S. "A Theory for Multiresolution Signal Decomposition: The Wavelet Representation." IEEE Trans. PAMI, 1989.
- Daubechies, I. "Ten Lectures on Wavelets." SIAM, 1992.
- Holschneider, M. et al. "A Real-Time Algorithm for Signal Analysis with the Help of the Wavelet Transform." Wavelets: Time-Frequency Methods and Phase Space, 1989.
- Percival, D. & Walden, A. "Wavelet Methods for Time Series Analysis." Cambridge University Press, 2000.
- Gencay, R., Selcuk, F. & Whitcher, B. "An Introduction to Wavelets and Other Filtering Methods in Finance and Economics." Academic Press, 2002.
+71
View File
@@ -0,0 +1,71 @@
# EXPDIST: Exponential Distribution CDF
The Exponential Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the exponential distribution, producing an output in $[0, 1]$. The exponential distribution models memoryless waiting times: the probability that a normalized value falls below a threshold depends only on the rate parameter $\lambda$, not on any history. Higher $\lambda$ values compress the CDF curve toward zero, making the indicator more sensitive to small normalized deviations. With $O(N)$ normalization and $O(1)$ CDF evaluation, EXPDIST provides a nonlinear percentile ranking that emphasizes the lower end of the price range while compressing the upper end.
## Historical Context
The exponential distribution is the continuous analog of the geometric distribution, first studied systematically by Agner Krarup Erlang (1909) in the context of telephone call modeling. Its defining property is memorylessness: $P(X > s + t \mid X > s) = P(X > t)$, making it the unique continuous distribution where the conditional probability of waiting another $t$ units is independent of time already elapsed.
In quantitative finance, the exponential CDF appears in several contexts: modeling inter-arrival times of trades (market microstructure), as a probability integral transform for goodness-of-fit testing, and as a nonlinear rescaling that emphasizes proximity to recent lows. The min-max normalization step maps raw prices into $[0, 1]$, and the CDF then provides a probabilistic interpretation: the output represents the probability that an exponentially-distributed random variable with rate $\lambda$ would fall at or below the normalized price level.
Unlike the normal or Student-t CDFs, the exponential CDF has a closed-form expression requiring only a single `exp()` call. This makes it computationally attractive for real-time applications where the heavier special-function machinery (incomplete beta, error function) of other distributions is unnecessary.
## Architecture and Physics
The indicator follows the standard two-phase pattern used across all distribution CDF indicators in this library:
**Phase 1: Min-max normalization** scans the lookback window of `period` bars to find the minimum and maximum values, then maps the current source value to $[0, 1]$:
$$x = \frac{\text{source} - \text{min}}{\text{max} - \text{min}}$$
If the range is zero (flat price), $x$ defaults to 0.5. This normalization is $O(N)$ per bar where $N$ is the period.
**Phase 2: CDF evaluation** applies the exponential CDF in $O(1)$:
$$F(x) = 1 - e^{-\lambda x}$$
with the boundary condition $F(x) = 0$ for $x \le 0$.
**Rate parameter effects**: $\lambda = 1$ gives a gentle S-curve with $F(0.5) \approx 0.39$. $\lambda = 3$ (default) gives $F(0.5) \approx 0.78$, strongly biasing toward 1.0 for values in the upper half of the range. $\lambda = 10$ saturates near 1.0 for almost any positive normalized value, functioning as a near-binary above/below-midpoint indicator.
## Mathematical Foundation
The exponential distribution with rate parameter $\lambda > 0$ has PDF and CDF:
$$f(x; \lambda) = \lambda e^{-\lambda x}, \quad x \ge 0$$
$$F(x; \lambda) = 1 - e^{-\lambda x}, \quad x \ge 0$$
**Moments of the exponential distribution:**
$$E[X] = \frac{1}{\lambda}, \quad \text{Var}(X) = \frac{1}{\lambda^2}, \quad \text{Skew} = 2, \quad \text{Kurt} = 6$$
**Inverse CDF** (quantile function):
$$F^{-1}(p) = -\frac{\ln(1 - p)}{\lambda}$$
The **memoryless property**:
$$P(X > s + t \mid X > s) = P(X > t) = e^{-\lambda t}$$
**Parameter constraints**: `period` $> 0$, $\lambda > 0$. Output is bounded $[0, 1]$.
```
EXPDIST(source, period, lambda):
// Phase 1: min-max normalization
min_val = min(source[0..period-1])
max_val = max(source[0..period-1])
range = max_val - min_val
x = range > 0 ? (source - min_val) / range : 0.5
// Phase 2: exponential CDF
if x <= 0: return 0.0
return 1.0 - exp(-lambda * x)
```
## Resources
- Erlang, A.K. "The Theory of Probabilities and Telephone Conversations." Nyt Tidsskrift for Matematik B, 1909.
- Johnson, N.L., Kotz, S. & Balakrishnan, N. "Continuous Univariate Distributions, Vol. 1." Wiley, 1994.
- Ross, S. "Introduction to Probability Models." Academic Press, 12th edition, 2019.
- Cont, R. "Empirical Properties of Asset Returns: Stylized Facts and Statistical Issues." Quantitative Finance, 2001.
+73
View File
@@ -0,0 +1,73 @@
# FDIST: F-Distribution CDF
The F-Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the F-distribution (Fisher-Snedecor distribution), producing an output in $[0, 1]$. The F-distribution arises as the ratio of two chi-squared random variables divided by their respective degrees of freedom, making it the natural distribution for variance ratio tests. By mapping normalized price through the regularized incomplete beta function with parameters tied to degrees of freedom $d_1$ and $d_2$, FDIST provides a probabilistic ranking that is asymmetric: the CDF shape changes qualitatively depending on whether $d_1 < d_2$, $d_1 = d_2$, or $d_1 > d_2$, giving traders control over the nonlinear response curve.
## Historical Context
The F-distribution was developed independently by George Snedecor (1934) and Ronald Fisher (1924), though Fisher's earlier work on variance ratios laid the theoretical foundation. The distribution is named in Fisher's honor by Snedecor. Its primary statistical application is the F-test for comparing variances of two populations, and it forms the backbone of ANOVA (Analysis of Variance), one of the most widely used statistical procedures.
In financial applications, the F-distribution appears in variance ratio tests (Lo and MacKinlay, 1988) used to test the random walk hypothesis. The CDF form used here repurposes the distribution's shape as a nonlinear mapping: with equal degrees of freedom ($d_1 = d_2$), the CDF is approximately symmetric around 0.5; with $d_1 \gg d_2$, the curve shifts left (more probability mass near zero); with $d_1 \ll d_2$, it shifts right. This parameter-controlled asymmetry distinguishes FDIST from simpler sigmoid-like transformations.
The implementation uses the same Lanczos log-gamma and Lentz continued fraction machinery as BETADIST, since the F-distribution CDF reduces to a regularized incomplete beta function through a variable substitution.
## Architecture and Physics
The computation follows a three-phase pipeline:
**Phase 1: Min-max normalization** scans `period` bars to find extrema, then maps the current source to $x \in [0, 1]$. Zero-range defaults to 0.5.
**Phase 2: Variable transformation** converts the normalized value $x$ to the beta function argument:
$$t = \frac{d_1 \cdot x}{d_1 \cdot x + d_2}$$
This maps $x \in [0, \infty)$ to $t \in [0, 1)$, which is the domain of the regularized incomplete beta function. Since input $x$ is already in $[0, 1]$, the effective range of $t$ is $[0, d_1/(d_1 + d_2)]$.
**Phase 3: Regularized incomplete beta** evaluates $I_t(d_1/2, d_2/2)$ using the Lentz continued fraction algorithm. The implementation includes a reflection step when $x > (a+1)/(a+b+2)$ to ensure the continued fraction converges from the faster side. Convergence typically requires 10-20 iterations to reach $\epsilon = 10^{-10}$.
**Shared infrastructure**: The `lnGamma()` function uses the Lanczos approximation with $g = 7$ and 9 coefficients, identical to the implementation in BETADIST and other distribution indicators. The `betaReg()` continued fraction is likewise shared.
## Mathematical Foundation
The F-distribution with $d_1$ numerator and $d_2$ denominator degrees of freedom has PDF:
$$f(x; d_1, d_2) = \frac{1}{B(d_1/2, d_2/2)} \cdot \left(\frac{d_1}{d_2}\right)^{d_1/2} \cdot \frac{x^{d_1/2 - 1}}{(1 + d_1 x / d_2)^{(d_1+d_2)/2}}$$
The CDF is expressed via the regularized incomplete beta function:
$$F(x; d_1, d_2) = I_t\!\left(\frac{d_1}{2}, \frac{d_2}{2}\right), \quad t = \frac{d_1 x}{d_1 x + d_2}$$
where the **regularized incomplete beta function** is:
$$I_x(a, b) = \frac{B(x; a, b)}{B(a, b)} = \frac{1}{B(a, b)} \int_0^x t^{a-1}(1-t)^{b-1}\,dt$$
**Lentz continued fraction** for $I_x(a, b)$:
$$I_x(a,b) = \frac{x^a (1-x)^b}{a \cdot B(a,b)} \cdot \cfrac{1}{1 + \cfrac{d_1}{1 + \cfrac{d_2}{1 + \cdots}}}$$
with convergents $d_m$ defined by the even/odd recurrence involving $a$, $b$, and $x$.
**Parameter constraints**: `period` $> 0$, $d_1 > 0$, $d_2 > 0$. Output is bounded $[0, 1]$.
```
FDIST(source, period, d1, d2):
// Phase 1: min-max normalization
min_val = min(source[0..period-1])
max_val = max(source[0..period-1])
range = max_val - min_val
x = range > 0 ? (source - min_val) / range : 0.5
// Phase 2: variable transformation
safe_x = max(0, x)
t = d1 * safe_x / (d1 * safe_x + d2)
// Phase 3: regularized incomplete beta via Lentz CF
return betaReg(t, d1/2, d2/2)
```
## Resources
- Fisher, R.A. "On a Distribution Yielding the Error Functions of Several Well Known Statistics." Proc. International Mathematical Congress, Toronto, 1924.
- Snedecor, G.W. "Calculation and Interpretation of Analysis of Variance and Covariance." Collegiate Press, 1934.
- Press, W.H. et al. "Numerical Recipes: The Art of Scientific Computing." 3rd edition, Cambridge University Press, 2007. Chapter 6.4 (Incomplete Beta Function).
- Lo, A. & MacKinlay, A.C. "Stock Market Prices Do Not Follow Random Walks: Evidence from a Simple Specification Test." Review of Financial Studies, 1988.
- Lentz, W.J. "Generating Bessel Functions in Mie Scattering Calculations Using Continued Fractions." Applied Optics, 1976.
+94
View File
@@ -0,0 +1,94 @@
# FFT: Fast Fourier Transform (Dominant Cycle Detector)
The FFT indicator computes the dominant cycle period in a price series using a Discrete Fourier Transform with a Hanning window. Rather than outputting frequency-domain magnitudes, it returns the estimated dominant cycle period in bars, making it directly usable as an adaptive period input for other indicators. The implementation uses a brute-force DFT over a constrained frequency band (not a radix-2 FFT), with parabolic interpolation on the magnitude spectrum to achieve sub-bin frequency resolution. With window sizes of 32, 64, or 128 and $O(N \cdot N/2)$ complexity per bar, the indicator trades computational cost for precise cycle detection within user-specified period bounds.
## Historical Context
The Fourier transform, formalized by Joseph Fourier (1822), decomposes any periodic signal into sinusoidal components. The Fast Fourier Transform algorithm (Cooley and Tukey, 1965) reduced the DFT from $O(N^2)$ to $O(N \log N)$, enabling real-time spectral analysis. However, for the small window sizes used in financial cycle detection (32-128 samples), the asymptotic advantage of FFT over DFT is minimal, and the DFT avoids the power-of-two length constraint.
John Ehlers pioneered the application of spectral analysis to financial markets in the 1990s and 2000s, using DFT-based cycle measurement to create adaptive indicators. His work demonstrated that financial time series contain quasi-periodic cycles with time-varying periods, typically in the 6-40 bar range. The dominant cycle period, extracted via spectral peak detection, can drive adaptive moving averages (MAMA, FAMA), adaptive RSI, and other indicators that benefit from knowing the current market rhythm.
The Hanning window (also called Hann window, after Julius von Hann) is applied to reduce spectral leakage. Without windowing, the sharp truncation of a finite data segment creates artificial high-frequency components that contaminate the spectrum. The Hanning window tapers the data to zero at both ends, suppressing sidelobes at the cost of slightly wider main lobes (reduced frequency resolution).
## Architecture and Physics
The computation pipeline has four stages:
**Stage 1: Windowed DFT** computes the real and imaginary components of the Fourier coefficients for frequency bins $k$ ranging from `minBin` to `maxBin`:
$$X[k] = \sum_{n=0}^{N-1} x[n] \cdot w[n] \cdot e^{-j 2\pi k n / N}$$
where $w[n] = 0.5 - 0.5\cos(2\pi n/N)$ is the Hanning window. Only bins corresponding to periods in `[minPeriod, maxPeriod]` are evaluated, reducing computation.
**Stage 2: Power spectrum peak** finds the bin $k^*$ with maximum squared magnitude $|X[k]|^2 = \text{Re}^2 + \text{Im}^2$. During the search, the magnitudes of the bins adjacent to the peak (one before, one after) are captured for interpolation.
**Stage 3: Parabolic interpolation** refines the peak location using a three-point parabola fit on the magnitudes at bins $k^*-1$, $k^*$, $k^*+1$:
$$\delta = \frac{M_{k^*-1} - M_{k^*+1}}{M_{k^*-1} + 2 M_{k^*} + M_{k^*+1}}$$
The refined dominant period is $N / (k^* + \delta)$.
**Stage 4: Clamping** ensures the output stays within `[minPeriod, maxPeriod]`.
**Window size trade-offs**: $N = 32$ gives coarse resolution (period bins spaced ~1 bar apart) but fast response; $N = 128$ gives fine resolution (~0.25 bar spacing) but sluggish adaptation. The default $N = 64$ balances resolution and responsiveness.
## Mathematical Foundation
The **Discrete Fourier Transform** for $N$ samples:
$$X[k] = \sum_{n=0}^{N-1} x[n] \cdot e^{-j 2\pi k n / N}, \quad k = 0, 1, \ldots, N-1$$
**Hanning window**:
$$w[n] = 0.5 - 0.5\cos\!\left(\frac{2\pi n}{N}\right)$$
**Frequency-to-period** mapping: bin $k$ corresponds to period $T = N/k$ bars.
**Bin range** from period bounds:
$$k_{\min} = \max\!\left(1,\; \left\lfloor\frac{N}{T_{\max}}\right\rfloor\right), \quad k_{\max} = \min\!\left(\frac{N}{2},\; \left\lfloor\frac{N}{T_{\min}}\right\rfloor\right)$$
**Power spectrum**: $P[k] = \text{Re}(X[k])^2 + \text{Im}(X[k])^2$
**Parabolic interpolation** for sub-bin precision:
$$\hat{k} = k^* + \frac{P[k^*-1] - P[k^*+1]}{P[k^*-1] + 2P[k^*] + P[k^*+1]}$$
$$T_{\text{dominant}} = \frac{N}{\hat{k}}$$
**Parameter constraints**: `windowSize` $\in \{32, 64, 128\}$, `minPeriod` $\ge 2$, `maxPeriod` $\le N/2$.
```
FFT(source, windowSize, minPeriod, maxPeriod):
N = windowSize
twoPiOverN = 2 * pi / N
minBin = max(1, N / maxPeriod)
maxBin = min(N/2, N / minPeriod)
maxMag = 0; peakBin = 0
for k = minBin to maxBin:
re = 0; im = 0
for n = 0 to N-1:
w = 0.5 - 0.5 * cos(twoPiOverN * n) // Hanning
xw = source[n] * w
angle = twoPiOverN * k * n
re += xw * cos(angle)
im -= xw * sin(angle)
mag = re*re + im*im
if mag > maxMag:
track neighbor magnitudes
maxMag = mag; peakBin = k
// Parabolic interpolation
shift = (magBefore - magAfter) / (magBefore + 2*maxMag + magAfter)
dominantPeriod = N / (peakBin + shift)
return clamp(dominantPeriod, minPeriod, maxPeriod)
```
## Resources
- Cooley, J.W. & Tukey, J.W. "An Algorithm for the Machine Calculation of Complex Fourier Series." Mathematics of Computation, 1965.
- Ehlers, J.F. "Cycle Analytics for Traders." Wiley, 2013.
- Ehlers, J.F. "Rocket Science for Traders." Wiley, 2001.
- Harris, F.J. "On the Use of Windows for Harmonic Analysis with the Discrete Fourier Transform." Proc. IEEE, 1978.
- Oppenheim, A.V. & Schafer, R.W. "Discrete-Time Signal Processing." 3rd edition, Pearson, 2010.
+78
View File
@@ -0,0 +1,78 @@
# GAMMADIST: Gamma Distribution CDF
The Gamma Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the gamma distribution, producing an output in $[0, 1]$. The gamma distribution generalizes the exponential distribution by adding a shape parameter $\alpha$ that controls whether the PDF is monotonically decreasing ($\alpha < 1$), exponential ($\alpha = 1$), or bell-shaped with a right skew ($\alpha > 1$). Combined with a rate parameter $\beta$ that scales the normalized input, GAMMADIST provides a flexible nonlinear mapping with controllable asymmetry. The CDF is computed via the regularized lower incomplete gamma function using series expansion or Lentz continued fraction, selecting the faster-converging method based on the argument relative to the shape parameter.
## Historical Context
The gamma distribution was first studied by Leonard Euler (1729) through his generalization of the factorial function to the gamma function $\Gamma(z)$. The distribution itself was formalized by Karl Pearson (1893) as part of his system of frequency curves, where it appears as a Type III distribution. The incomplete gamma function, central to computing the CDF, was tabulated extensively by Pearson (1922) before computational methods made tables obsolete.
In finance, the gamma distribution models positively-skewed quantities: waiting times between events (generalizing the exponential), aggregate claim sizes in insurance (actuarial science), and the distribution of realized volatility (which is approximately gamma-distributed under certain stochastic volatility models). The chi-squared distribution is a special case with $\alpha = k/2$ and $\beta = 2$ (where $k$ is degrees of freedom), connecting GAMMADIST to variance-based statistical tests.
The implementation uses two complementary algorithms for the regularized incomplete gamma function: a series expansion that converges rapidly for $x < \alpha + 1$, and a Lentz continued fraction for $x \ge \alpha + 1$. This split ensures convergence in approximately 10-30 iterations across the entire parameter space.
## Architecture and Physics
The computation follows a three-phase pipeline:
**Phase 1: Min-max normalization** scans `period` bars for extrema, maps the current source to $x \in [0, 1]$, then scales by the rate parameter: $\text{scaled} = \max(0, x \cdot \beta)$.
**Phase 2: Algorithm selection** chooses between series and continued fraction based on the relationship between the scaled input and the shape parameter:
- If $\text{scaled} < \alpha + 1$: use the series expansion (converges from below)
- If $\text{scaled} \ge \alpha + 1$: use $1 - Q(\alpha, \text{scaled})$ via continued fraction (converges from above)
**Phase 3: CDF evaluation** computes the regularized lower incomplete gamma function $P(\alpha, \text{scaled})$.
The **series expansion** accumulates terms $\delta_n = x^n / (\alpha(\alpha+1)\cdots(\alpha+n))$ until the relative change drops below $10^{-10}$, then multiplies by the normalization factor $x^\alpha e^{-x} / \Gamma(\alpha)$.
The **continued fraction** (Lentz algorithm) evaluates the complementary function $Q(\alpha, x) = 1 - P(\alpha, x)$ using the recurrence with convergents $a_i = -i(i - \alpha)$ and $b_i = x + 2i + 1 - \alpha$.
**Shape parameter effects**: $\alpha = 1$ reduces to exponential distribution. $\alpha = 2, \beta = 3$ (default) gives a moderate right-skewed S-curve. Large $\alpha$ approaches a normal CDF shape.
## Mathematical Foundation
The gamma distribution with shape $\alpha > 0$ and rate $\beta > 0$ has PDF:
$$f(x; \alpha, \beta) = \frac{\beta^\alpha}{\Gamma(\alpha)} x^{\alpha-1} e^{-\beta x}, \quad x > 0$$
The CDF is the **regularized lower incomplete gamma function**:
$$F(x; \alpha, \beta) = P(\alpha, \beta x) = \frac{\gamma(\alpha, \beta x)}{\Gamma(\alpha)} = \frac{1}{\Gamma(\alpha)} \int_0^{\beta x} t^{\alpha-1} e^{-t}\,dt$$
**Series expansion** for $P(a, x)$ when $x < a + 1$:
$$P(a, x) = e^{-x} x^a \sum_{n=0}^{\infty} \frac{x^n}{a(a+1)\cdots(a+n)}$$
**Continued fraction** for $Q(a, x) = 1 - P(a, x)$ when $x \ge a + 1$:
$$Q(a, x) = e^{-x} x^a \cdot \cfrac{1}{x + 1 - a + \cfrac{1 \cdot (1-a)}{x + 3 - a + \cfrac{2 \cdot (2-a)}{x + 5 - a + \cdots}}}$$
**Log-gamma** via Lanczos approximation ($g = 7$, 9 coefficients):
$$\ln\Gamma(z) = \frac{1}{2}\ln(2\pi) + \left(z - \frac{1}{2}\right)\ln(z + g - \frac{1}{2}) - (z + g - \frac{1}{2}) + \ln\!\left(\sum_{k=0}^{8} \frac{c_k}{z + k}\right)$$
**Parameter constraints**: `period` $> 0$, $\alpha > 0$, $\beta > 0$. Output is bounded $[0, 1]$.
```
GAMMADIST(source, period, shape, rate):
// Phase 1: min-max normalization + scaling
min_val = min(source[0..period-1])
max_val = max(source[0..period-1])
range = max_val - min_val
x = range > 0 ? (source - min_val) / range : 0.5
scaled = max(0, x * rate)
// Phase 2-3: regularized lower incomplete gamma
if scaled <= 0: return 0.0
if scaled < shape + 1:
return gammaSeries(shape, scaled) // series expansion
else:
return 1.0 - gammaCF(shape, scaled) // continued fraction
```
## Resources
- Pearson, K. "Contributions to the Mathematical Theory of Evolution." Phil. Trans. Royal Society, 1893.
- Lanczos, C. "A Precision Approximation of the Gamma Function." SIAM J. Numerical Analysis B, 1964.
- Press, W.H. et al. "Numerical Recipes: The Art of Scientific Computing." 3rd edition, Cambridge University Press, 2007. Chapter 6.2 (Incomplete Gamma Function).
- Lentz, W.J. "Generating Bessel Functions in Mie Scattering Calculations Using Continued Fractions." Applied Optics, 1976.
- Johnson, N.L., Kotz, S. & Balakrishnan, N. "Continuous Univariate Distributions, Vol. 1." Wiley, 1994.
+90
View File
@@ -0,0 +1,90 @@
# IFFT: Inverse Fast Fourier Transform (Spectral Filter)
The Inverse FFT indicator reconstructs a smoothed version of the price series by performing a forward DFT, retaining only the lowest-frequency harmonics, and synthesizing the output via inverse transform. The result is a spectral low-pass filter that preserves the dominant cyclical components while discarding high-frequency noise. By controlling the number of retained harmonics $H$, the user adjusts the smoothness/responsiveness trade-off: $H = 1$ yields a near-sinusoidal trend, while $H = N/2$ reproduces the original (windowed) signal. The indicator overlays on price and provides a frequency-domain alternative to conventional moving averages.
## Historical Context
Spectral filtering via Fourier decomposition dates to Joseph Fourier's 1822 work on heat conduction, where he showed that any periodic function can be represented as a sum of sinusoids. The idea of reconstructing a signal from a subset of its Fourier coefficients is foundational to signal compression (JPEG, MP3) and has been applied to financial time series since the 1970s.
John Ehlers brought spectral methods to mainstream technical analysis through his books on cycle analytics. His approach typically uses the DFT to identify the dominant cycle, then constructs adaptive filters tuned to that cycle. The IFFT indicator takes the complementary approach: rather than extracting a single cycle period, it reconstructs the signal from the $H$ lowest-frequency components, producing a multi-harmonic trend estimate.
The Hanning window applied before the forward DFT reduces spectral leakage, ensuring that the retained harmonics accurately represent the true low-frequency content rather than artifacts of the window boundary. The inverse step only uses the real part of the synthesis (cosine terms), since the output must be a real-valued price estimate. The factor of 2 in the inverse accounts for the conjugate symmetry of real-valued DFT coefficients.
## Architecture and Physics
The computation has three stages executed per bar:
**Stage 1: DC component** computes the windowed mean of the source over the window. This is the zero-frequency (average level) component:
$$\text{DC} = \frac{1}{N}\sum_{n=0}^{N-1} x[n] \cdot w[n]$$
**Stage 2: Forward DFT for harmonics $k = 1$ to $H$** computes the real and imaginary Fourier coefficients for each retained harmonic. The Hanning window $w[n] = 0.5 - 0.5\cos(2\pi n/N)$ is applied to every sample.
**Stage 3: Inverse synthesis** reconstructs the current bar's value by summing the DC component plus twice the real part of each harmonic evaluated at $n = 0$ (the current bar):
$$\hat{x}[0] = \frac{\text{DC}_{\text{Re}}}{N} + \sum_{k=1}^{H} \frac{2 \cdot \text{Re}(X[k])}{N}$$
The factor $2/N$ accounts for: (1) the $1/N$ normalization of the inverse DFT, and (2) the factor of 2 from collapsing the conjugate-symmetric negative frequencies.
**Complexity**: The forward DFT for $H$ harmonics costs $O(N \cdot H)$ multiply-adds per bar. With $N = 64$ and $H = 5$ (defaults), this is ~320 multiply-adds per bar. The inverse synthesis at $n = 0$ reduces to just summing the real components, costing $O(H)$.
**Smoothness control**: Fewer harmonics produce smoother output but introduce more lag and lose detail. The relationship between harmonics and equivalent moving average length is roughly: $H$ harmonics approximate the smoothness of an $N/(2H)$-period moving average, but with better frequency selectivity (sharper cutoff).
## Mathematical Foundation
The **forward DFT** with Hanning window:
$$X[k] = \sum_{n=0}^{N-1} x[n] \cdot w[n] \cdot e^{-j 2\pi k n / N}$$
where $w[n] = 0.5 - 0.5\cos(2\pi n / N)$.
The **inverse DFT** evaluated at the current bar ($n = 0$):
$$\hat{x}[0] = \frac{1}{N}\sum_{k=0}^{N-1} X[k] \cdot e^{j 2\pi k \cdot 0 / N} = \frac{1}{N}\sum_{k=0}^{N-1} X[k]$$
Since $e^{j \cdot 0} = 1$, the inverse at $n = 0$ is simply the sum of all retained coefficients divided by $N$.
For a real-valued signal, $X[N-k] = X[k]^*$, so:
$$\hat{x}[0] = \frac{X[0]}{N} + \frac{2}{N}\sum_{k=1}^{H} \text{Re}(X[k])$$
**Parseval's theorem** relates the energy retained:
$$\frac{\sum_{k=0}^{H} |X[k]|^2}{\sum_{k=0}^{N/2} |X[k]|^2} = \text{fraction of signal energy preserved}$$
**Parameter constraints**: `windowSize` $\in \{32, 64, 128\}$, `numHarmonics` $\ge 1$ (clamped to $N/2$).
```
IFFT(source, windowSize, numHarmonics):
N = windowSize
H = min(numHarmonics, N/2)
twoPiOverN = 2 * pi / N
// DC component (k=0)
dcRe = 0
for n = 0 to N-1:
w = 0.5 - 0.5 * cos(twoPiOverN * n)
dcRe += source[n] * w
result = dcRe / N
// Harmonics k=1..H
for k = 1 to H:
re = 0; im = 0
for n = 0 to N-1:
w = 0.5 - 0.5 * cos(twoPiOverN * n)
xw = source[n] * w
angle = twoPiOverN * k * n
re += xw * cos(angle)
im -= xw * sin(angle)
result += 2 * re / N // inverse at n=0
return result
```
## Resources
- Fourier, J.B.J. "Theorie Analytique de la Chaleur." Firmin Didot, 1822.
- Ehlers, J.F. "Cycle Analytics for Traders." Wiley, 2013.
- Oppenheim, A.V. & Schafer, R.W. "Discrete-Time Signal Processing." 3rd edition, Pearson, 2010.
- Bloomfield, P. "Fourier Analysis of Time Series: An Introduction." 2nd edition, Wiley, 2000.
- Priestley, M.B. "Spectral Analysis and Time Series." Academic Press, 1981.
+75
View File
@@ -0,0 +1,75 @@
# LOGNORMDIST: Log-Normal Distribution CDF
The Log-Normal Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the log-normal distribution, producing an output in $[0, 1]$. A random variable $X$ is log-normally distributed when $\ln(X)$ follows a normal distribution. This makes the log-normal CDF natural for financial data, where multiplicative returns (log-returns) are approximately normally distributed. The indicator min-max normalizes the source to $(0, 1]$, takes the natural logarithm, standardizes by parameters $\mu$ and $\sigma$, then evaluates the standard normal CDF. The result emphasizes values near the bottom of the recent range (where the logarithm diverges) and compresses values near the top.
## Historical Context
The log-normal distribution was first described by Francis Galton (1879) and formalized by Donald McAlister (1879) in a paper read to the Royal Society. It gained prominence in finance through Louis Bachelier's thesis (1900) on price speculation and was later adopted as the foundation of the Black-Scholes option pricing model (1973), where stock prices are assumed to follow geometric Brownian motion, making the price at any future time log-normally distributed.
The log-normal assumption remains the default model in quantitative finance despite well-documented violations (fat tails, volatility clustering). Its mathematical tractability and the economic argument that prices cannot go negative (the log-normal support is $(0, \infty)$) make it a reasonable first approximation. The CDF form used here provides a probability integral transform: if the normalized price truly followed a log-normal distribution with parameters $\mu$ and $\sigma$, the output would be uniformly distributed on $[0, 1]$.
The implementation reduces the log-normal CDF to the standard normal CDF through the substitution $z = (\ln x - \mu)/\sigma$, then uses the Abramowitz and Stegun rational approximation (formula 7.1.26) for $\Phi(z)$, achieving accuracy of approximately $1.5 \times 10^{-7}$.
## Architecture and Physics
The computation follows a three-phase pipeline:
**Phase 1: Min-max normalization** scans `period` bars for extrema, maps the current source to $x \in [0, 1]$. A floor of $10^{-10}$ is applied to prevent $\ln(0)$.
**Phase 2: Log-standardization** computes $z = (\ln x - \mu) / \sigma$. With default $\mu = 0, \sigma = 1$, this simplifies to $z = \ln(x)$. Since $x \in (0, 1]$, $z \in (-\infty, 0]$, so default parameters place most output in $[0, 0.5]$. Shifting $\mu$ negative or increasing $\sigma$ spreads the output across the full $[0, 1]$ range.
**Phase 3: Normal CDF** evaluates $\Phi(z)$ using the Abramowitz and Stegun approximation with 5 polynomial coefficients:
$$\Phi(z) = 1 - \phi(|z|) \cdot (b_1 t + b_2 t^2 + b_3 t^3 + b_4 t^4 + b_5 t^5)$$
where $t = 1/(1 + 0.2316419|z|)$ and $\phi(z) = e^{-z^2/2}/\sqrt{2\pi}$.
**Parameter effects**: $\mu$ shifts the inflection point of the S-curve along the logarithmic axis. $\sigma$ controls the steepness: small $\sigma$ produces a sharp transition, large $\sigma$ produces a gradual one. For financial applications, $\mu = -1, \sigma = 0.5$ centers the CDF near the geometric midpoint of the $[0, 1]$ range.
## Mathematical Foundation
If $X \sim \text{LogNormal}(\mu, \sigma^2)$, then $\ln(X) \sim N(\mu, \sigma^2)$, and the CDF is:
$$F(x; \mu, \sigma) = \Phi\!\left(\frac{\ln x - \mu}{\sigma}\right), \quad x > 0$$
where $\Phi$ is the standard normal CDF.
**Moments of the log-normal distribution:**
$$E[X] = e^{\mu + \sigma^2/2}$$
$$\text{Var}(X) = (e^{\sigma^2} - 1) \cdot e^{2\mu + \sigma^2}$$
$$\text{Skew} = (e^{\sigma^2} + 2)\sqrt{e^{\sigma^2} - 1}$$
**Standard normal CDF** (Abramowitz and Stegun 7.1.26):
$$\Phi(z) = 1 - \frac{e^{-z^2/2}}{\sqrt{2\pi}} \sum_{i=1}^{5} b_i t^i, \quad t = \frac{1}{1 + 0.2316419|z|}$$
with $b_1 = 0.319381530$, $b_2 = -0.356563782$, $b_3 = 1.781477937$, $b_4 = -1.821255978$, $b_5 = 1.330274429$.
**Parameter constraints**: `period` $> 0$, $\sigma > 0$, $\mu \in \mathbb{R}$. Output is bounded $[0, 1]$.
```
LOGNORMDIST(source, period, mu, sigma):
// Phase 1: min-max normalization
min_val = min(source[0..period-1])
max_val = max(source[0..period-1])
range = max_val - min_val
x = range > 0 ? (source - min_val) / range : 0.5
safe_x = max(1e-10, x)
// Phase 2: log-standardization
z = (ln(safe_x) - mu) / sigma
// Phase 3: standard normal CDF
return normalCdf(z)
```
## Resources
- Galton, F. "The Geometric Mean, in Vital and Social Statistics." Proc. Royal Society, 1879.
- Aitchison, J. & Brown, J.A.C. "The Lognormal Distribution." Cambridge University Press, 1957.
- Black, F. & Scholes, M. "The Pricing of Options and Corporate Liabilities." Journal of Political Economy, 1973.
- Abramowitz, M. & Stegun, I. "Handbook of Mathematical Functions." NBS Applied Mathematics Series 55, 1964. Formula 7.1.26.
- Limpert, E., Stahel, W. & Abbt, M. "Log-normal Distributions across the Sciences: Keys and Clues." BioScience, 2001.
+95
View File
@@ -0,0 +1,95 @@
# NORMDIST: Normal Distribution CDF
The Normal Distribution CDF transforms a z-score normalized price into the cumulative distribution function of the Gaussian distribution, producing an output in $[0, 1]$. Unlike other distribution indicators in this library that use min-max normalization, NORMDIST computes a rolling mean and standard deviation over the lookback window, converting the raw price to a z-score, then applies optional $\mu$ and $\sigma$ parameters for further shaping. The result represents the probability that a standard normal random variable would fall at or below the observed z-score. This makes NORMDIST a direct percentile ranking under the assumption of normally distributed returns, with the output naturally centered at 0.5 when the price is at its rolling mean.
## Historical Context
The normal distribution was discovered independently by Abraham de Moivre (1733) as a limit of the binomial distribution, and by Carl Friedrich Gauss (1809) in the context of astronomical measurement errors. Pierre-Simon Laplace (1812) proved the central limit theorem, establishing that sums of independent random variables converge to the normal distribution regardless of the underlying distribution.
In finance, the normal distribution assumption for asset returns was formalized by Harry Markowitz (1952) in Modern Portfolio Theory and Louis Bachelier (1900) in his thesis on speculation. Despite well-known departures (fat tails, skewness, volatility clustering), the normal CDF remains the most widely used probability transform in quantitative finance. It underpins the Black-Scholes formula, Value-at-Risk calculations, and the Sharpe ratio.
The z-score normalization approach used here is more statistically grounded than the min-max normalization used by other distribution indicators: it captures the rolling distributional properties (mean, variance) of the price series rather than just the range. This means NORMDIST adapts to both the level and the volatility of the price, making readings directly interpretable as "number of standard deviations from the mean."
## Architecture and Physics
The computation follows a three-phase pipeline:
**Phase 1: Rolling statistics** computes the mean and standard deviation over the lookback window using a single-pass algorithm:
$$\bar{x} = \frac{1}{n}\sum_{i=0}^{n-1} x_i, \quad s = \sqrt{\frac{1}{n}\sum_{i=0}^{n-1} x_i^2 - \bar{x}^2}$$
NaN values are excluded from the count. If fewer than 2 valid values exist, the output defaults to 0.5.
**Phase 2: Z-score with parameter adjustment** converts the price to a z-score relative to the rolling distribution, then applies the user-specified shift and scale:
$$z = \frac{x - \bar{x}}{s}, \quad z_{\text{final}} = \frac{z - \mu}{\sigma}$$
With defaults $\mu = 0, \sigma = 1$, $z_{\text{final}} = z$ (standard z-score). Increasing $\sigma$ compresses the CDF curve (less sensitive to deviations); shifting $\mu$ moves the midpoint away from the rolling mean.
**Phase 3: Error function approximation** evaluates $\Phi(z)$ using the Abramowitz and Stegun formula (7.1.26) with 3 polynomial terms in the exponential approximation of `erf`:
$$\text{erf}(x) \approx 1 - (a_1 t + a_2 t^2 + a_3 t^3) \cdot e^{-x^2}$$
where $t = 1/(1 + 0.47047|x|)$. The CDF is then $\Phi(z) = 0.5(1 + \text{erf}(z/\sqrt{2}))$.
**Accuracy**: The 3-term Abramowitz-Stegun approximation achieves maximum error of $\sim 2.5 \times 10^{-5}$, sufficient for indicator applications. For higher precision, the 5-term version (used in LOGNORMDIST) reduces error to $\sim 1.5 \times 10^{-7}$.
## Mathematical Foundation
The standard normal PDF and CDF:
$$\phi(z) = \frac{1}{\sqrt{2\pi}} e^{-z^2/2}$$
$$\Phi(z) = \frac{1}{2}\left(1 + \text{erf}\!\left(\frac{z}{\sqrt{2}}\right)\right) = \int_{-\infty}^{z} \phi(t)\,dt$$
The **error function**:
$$\text{erf}(x) = \frac{2}{\sqrt{\pi}} \int_0^x e^{-t^2}\,dt$$
**Abramowitz and Stegun 3-term approximation**:
$$\text{erf}(x) \approx 1 - (a_1 t + a_2 t^2 + a_3 t^3) e^{-x^2}, \quad t = \frac{1}{1 + 0.47047\,|x|}$$
with $a_1 = 0.3480242$, $a_2 = -0.0958798$, $a_3 = 0.7478556$.
**Z-score normalization** (population standard deviation, not sample):
$$z = \frac{x - \bar{x}}{s}, \quad s = \sqrt{\frac{\sum x_i^2}{n} - \left(\frac{\sum x_i}{n}\right)^2}$$
**Key CDF values**: $\Phi(0) = 0.5$, $\Phi(1) \approx 0.841$, $\Phi(2) \approx 0.977$, $\Phi(-1) \approx 0.159$, $\Phi(-2) \approx 0.023$.
**Parameter constraints**: `period` $> 0$, $\sigma > 0$, $\mu \in \mathbb{R}$. Output is bounded $[0, 1]$.
```
NORMDIST(source, period, mu, sigma):
// Phase 1: rolling statistics
sum = 0; sumSq = 0; count = 0
for i = 0 to period-1:
if not NaN(source[i]):
sum += source[i]
sumSq += source[i]^2
count += 1
if count < 2: return 0.5
mean = sum / count
variance = sumSq/count - mean^2
stddev = sqrt(max(0, variance))
// Phase 2: z-score with parameter adjustment
z = stddev > 0 ? (source - mean) / stddev : 0
z_final = (z - mu) / sigma
// Phase 3: erf approximation -> CDF
x = z_final / sqrt(2)
t = 1 / (1 + 0.47047 * |x|)
erf = 1 - (0.3480242*t + (-0.0958798)*t^2 + 0.7478556*t^3) * exp(-x^2)
if x < 0: erf = -erf
return 0.5 * (1 + erf)
```
## Resources
- Gauss, C.F. "Theoria Motus Corporum Coelestium." 1809.
- Abramowitz, M. & Stegun, I. "Handbook of Mathematical Functions." NBS Applied Mathematics Series 55, 1964. Formulas 7.1.25-7.1.28.
- Markowitz, H. "Portfolio Selection." Journal of Finance, 1952.
- Johnson, N.L., Kotz, S. & Balakrishnan, N. "Continuous Univariate Distributions, Vol. 1." Wiley, 1994.
- Hart, J.F. et al. "Computer Approximations." Wiley, 1968.
+80
View File
@@ -0,0 +1,80 @@
// The MIT License (MIT)
// © mihakralj
//@version=6
indicator("Normal Distribution CDF (NORMDIST)", "NORMDIST", overlay=false, precision=6)
//@function Computes Normal Distribution CDF for a normalized price series
//@param source Series to transform
//@param period Lookback period for z-score normalization
//@param mu Mean parameter (0.0 for standard normal after z-score)
//@param sigma Standard deviation parameter (1.0 for standard normal after z-score)
//@returns CDF value in [0,1]: Φ(z) = 0.5 × (1 + erf(z / √2))
//@optimized O(period) per bar for mean/variance scan; CDF itself is O(1)
normdist(series float source, simple int period, simple float mu, simple float sigma) =>
if period <= 0
runtime.error("Period must be greater than 0")
if sigma <= 0.0
runtime.error("Sigma must be greater than 0")
// Compute rolling mean and standard deviation over lookback
float sum = 0.0
float sumSq = 0.0
int count = 0
for i = 0 to period - 1
float v = source[i]
if not na(v)
sum += v
sumSq += v * v
count += 1
float result = 0.5
if count >= 2
float mean = sum / count
float variance = (sumSq / count) - (mean * mean)
float stddev = variance > 0.0 ? math.sqrt(variance) : 0.0
// Z-score: normalize source relative to its own rolling distribution
float z = stddev > 0.0 ? (source - mean) / stddev : 0.0
// Apply user-specified mu/sigma shift: z_final = (z - mu) / sigma
float z_final = (z - mu) / sigma
// Approximate erf via Abramowitz & Stegun (max error < 1.5e-7)
// erf(x) = 1 - (a1*t + a2*t^2 + a3*t^3) * exp(-x^2)
// where t = 1 / (1 + 0.47047 * |x|)
float x = z_final / math.sqrt(2.0)
float ax = math.abs(x)
float t = 1.0 / (1.0 + 0.47047 * ax)
float t2 = t * t
float t3 = t2 * t
float a1 = 0.3480242
float a2 = -0.0958798
float a3 = 0.7478556
float erfApprox = 1.0 - (a1 * t + a2 * t2 + a3 * t3) * math.exp(-(ax * ax))
float erf = x >= 0.0 ? erfApprox : -erfApprox
// CDF: Φ(z) = 0.5 * (1 + erf(z / sqrt(2)))
result := 0.5 * (1.0 + erf)
result
// ---------- Main loop ----------
// Inputs
i_source = input.source(close, "Source")
i_period = input.int(50, "Lookback Period", minval=2, maxval=5000, tooltip="Rolling window for z-score normalization")
i_mu = input.float(0.0, "Mu (μ)", step=0.1, tooltip="Mean shift parameter (0 = standard normal)")
i_sigma = input.float(1.0, "Sigma (σ)", minval=0.01, step=0.1, tooltip="Scale parameter (1 = standard normal)")
// Calculation
float result = normdist(i_source, i_period, i_mu, i_sigma)
// Plot
plot(result, "NORMDIST", color=color.yellow, linewidth=2)
hline(0.5, "Midline", color=color.gray, linestyle=hline.style_dotted)
hline(0.975, "Upper 2σ", color=color.red, linestyle=hline.style_dashed)
hline(0.025, "Lower 2σ", color=color.green, linestyle=hline.style_dashed)
hline(0.841, "Upper 1σ", color=color.orange, linestyle=hline.style_dashed)
hline(0.159, "Lower 1σ", color=color.teal, linestyle=hline.style_dashed)
+73
View File
@@ -0,0 +1,73 @@
# POISSONDIST: Poisson Distribution CDF
The Poisson Distribution CDF computes the probability $P(X \le k)$ for a Poisson random variable whose rate parameter $\lambda$ is derived from the min-max normalized price. The Poisson distribution models the number of events in a fixed interval given a constant average rate, making it natural for count-based financial metrics (trade arrivals, tick counts, order flow). The implementation maps normalized price to $\lambda$ via a scale factor, then evaluates the CDF using the identity $P(X \le k) = 1 - P(k+1, \lambda)$ where $P(a, x)$ is the regularized lower incomplete gamma function. This reuses the same Lanczos log-gamma and series/continued-fraction infrastructure as GAMMADIST.
## Historical Context
The Poisson distribution was derived by Simeon Denis Poisson (1837) as a limiting case of the binomial distribution when the number of trials is large and the success probability is small. Ladislaus Bortkiewicz (1898) famously demonstrated its applicability by modeling deaths from horse kicks in the Prussian army, establishing it as the canonical distribution for rare events.
In financial markets, Poisson processes model trade arrivals in market microstructure theory (O'Hara, 1995), jump events in Merton's jump-diffusion model (1976), and order book dynamics. The CDF form used here provides a probability-weighted indicator: for a given threshold $k$ and price-derived rate $\lambda$, the output answers "what is the probability that a Poisson process with rate proportional to the normalized price would produce at most $k$ events?"
When the normalized price is low (near 0), $\lambda$ is small and the CDF is close to 1 (almost certainly $\le k$ events). When normalized price approaches 1, $\lambda$ is large and the CDF drops (many events expected, exceeding $k$ becomes likely). The `lambda_scale` parameter controls the dynamic range: higher values cause broader CDF variation across the $[0, 1]$ normalized range.
## Architecture and Physics
The computation follows a three-phase pipeline:
**Phase 1: Min-max normalization** scans `period` bars for extrema, maps the current source to $x \in [0, 1]$, then derives the rate: $\lambda = \max(0, x \cdot \text{lambda\_scale})$.
**Phase 2: Degenerate case** handles $\lambda = 0$ by returning 1.0 (Poisson with rate 0 puts all mass at $X = 0$, so $P(X \le k) = 1$ for any $k \ge 0$).
**Phase 3: Gamma function identity** uses the well-known relationship between the Poisson CDF and the regularized incomplete gamma function:
$$P(X \le k) = 1 - P(k + 1, \lambda) = Q(k + 1, \lambda)$$
where $P(a, x)$ is the regularized lower incomplete gamma and $Q$ is its complement. The implementation delegates to `gammaP()`, which internally selects between series expansion (for $\lambda < k + 2$) and Lentz continued fraction (otherwise).
**Threshold parameter $k$**: Integer-valued, controls the step function shape. Small $k$ (0-2) creates a steep CDF that drops rapidly as $\lambda$ increases. Large $k$ (10+) creates a gentle curve that stays near 1.0 until $\lambda$ significantly exceeds $k$.
## Mathematical Foundation
The Poisson distribution with rate $\lambda > 0$ has PMF:
$$P(X = n) = \frac{\lambda^n e^{-\lambda}}{n!}, \quad n = 0, 1, 2, \ldots$$
The CDF is:
$$F(k; \lambda) = P(X \le k) = e^{-\lambda} \sum_{n=0}^{k} \frac{\lambda^n}{n!}$$
The **gamma function identity** connects this to the incomplete gamma:
$$P(X \le k) = 1 - P(k+1, \lambda) = \frac{\Gamma(k+1, \lambda)}{k!}$$
where $\Gamma(a, x) = \int_x^\infty t^{a-1} e^{-t}\,dt$ is the upper incomplete gamma function and $P(a, x) = \gamma(a, x)/\Gamma(a)$ is the regularized lower incomplete gamma.
**Moments**: $E[X] = \lambda$, $\text{Var}(X) = \lambda$, $\text{Skew} = 1/\sqrt{\lambda}$.
**Normal approximation**: For large $\lambda$, $\text{Poisson}(\lambda) \approx N(\lambda, \lambda)$.
**Parameter constraints**: `period` $> 0$, $k \ge 0$ (integer), `lambda_scale` $> 0$. Output is bounded $[0, 1]$.
```
POISSONDIST(source, period, k, lambda_scale):
// Phase 1: min-max normalization + rate derivation
min_val = min(source[0..period-1])
max_val = max(source[0..period-1])
range = max_val - min_val
x = range > 0 ? (source - min_val) / range : 0.5
lambda = max(0, x * lambda_scale)
// Phase 2: degenerate case
if lambda <= 0: return 1.0
// Phase 3: CDF via incomplete gamma identity
return 1.0 - gammaP(k + 1, lambda)
```
## Resources
- Poisson, S.D. "Recherches sur la probabilite des jugements en matiere criminelle et en matiere civile." 1837.
- Bortkiewicz, L. "Das Gesetz der kleinen Zahlen." Teubner, 1898.
- Merton, R.C. "Option Pricing When Underlying Stock Returns Are Discontinuous." Journal of Financial Economics, 1976.
- O'Hara, M. "Market Microstructure Theory." Blackwell, 1995.
- Press, W.H. et al. "Numerical Recipes: The Art of Scientific Computing." 3rd edition, Cambridge University Press, 2007. Chapter 6.2.
+86
View File
@@ -0,0 +1,86 @@
# TDIST: Student's t-Distribution CDF
The Student's t-Distribution CDF transforms a min-max normalized price into the cumulative distribution function of Student's t-distribution, producing an output in $[0, 1]$. The t-distribution is the normal distribution's heavier-tailed cousin: as degrees of freedom $\nu$ increase, it converges to the Gaussian; at low $\nu$ it accommodates extreme values that the normal distribution would assign negligible probability. The implementation normalizes price to $[0, 1]$, maps to a t-statistic via linear scaling to $[-3, +3]$, then evaluates the CDF through the regularized incomplete beta function. This makes TDIST a robust percentile ranking that is less sensitive to outliers than NORMDIST.
## Historical Context
The t-distribution was derived by William Sealy Gosset (1908), publishing under the pseudonym "Student" while employed at the Guinness brewery. Gosset needed to make statistical inferences from small sample sizes where the population variance was unknown. Ronald Fisher (1925) generalized the distribution and introduced the degrees-of-freedom parameter.
In finance, the t-distribution has become central to fat-tailed modeling. Empirical studies consistently show that asset returns have heavier tails than the normal distribution (Mandelbrot, 1963; Fama, 1965). The t-distribution with $\nu \approx 4\text{-}6$ provides a reasonable fit to daily equity returns, and it underpins GARCH-t models, Student-t copulas in credit risk, and robust regression in factor modeling.
The CDF is computed via the identity connecting it to the regularized incomplete beta function:
$$F(t; \nu) = \begin{cases} 1 - \frac{1}{2} I_x\!\left(\frac{\nu}{2}, \frac{1}{2}\right) & t \ge 0 \\ \frac{1}{2} I_x\!\left(\frac{\nu}{2}, \frac{1}{2}\right) & t < 0 \end{cases}$$
where $x = \nu/(\nu + t^2)$. This reuses the same Lanczos log-gamma and Lentz continued fraction infrastructure as BETADIST and FDIST.
## Architecture and Physics
The computation follows a four-phase pipeline:
**Phase 1: Min-max normalization** scans `period` bars for extrema, maps the current source to $x \in [0, 1]$.
**Phase 2: t-statistic mapping** transforms $x$ to a t-value via linear scaling:
$$t = (x - 0.5) \times 6.0$$
This maps $[0, 1]$ to $[-3, +3]$, covering approximately 99.7% of the standard normal range and the bulk of any t-distribution with $\nu \ge 3$.
**Phase 3: Beta function argument** converts the t-statistic to the incomplete beta argument:
$$\text{bx} = \frac{\nu}{\nu + t^2}$$
For $t = 0$, $\text{bx} = 1$ and the CDF returns 0.5 (symmetric around zero). As $|t|$ grows, $\text{bx}$ approaches 0.
**Phase 4: Regularized incomplete beta** evaluates $I_{\text{bx}}(\nu/2, 1/2)$ via the Lentz continued fraction with symmetry flip for numerical stability. The sign of $t$ determines whether the result is in the lower or upper tail.
**Degrees-of-freedom effects**: $\nu = 1$ gives the Cauchy distribution (extremely heavy tails, no finite mean). $\nu = 5$ gives moderately heavy tails. $\nu = 30$ is nearly indistinguishable from the normal. $\nu \to \infty$ converges to $N(0, 1)$.
## Mathematical Foundation
The Student's t-distribution with $\nu$ degrees of freedom has PDF:
$$f(t; \nu) = \frac{\Gamma\!\left(\frac{\nu+1}{2}\right)}{\sqrt{\nu\pi}\;\Gamma\!\left(\frac{\nu}{2}\right)} \left(1 + \frac{t^2}{\nu}\right)^{-(\nu+1)/2}$$
The CDF via regularized incomplete beta:
$$F(t; \nu) = \begin{cases} 1 - \frac{1}{2} I_x\!\left(\frac{\nu}{2}, \frac{1}{2}\right) & t \ge 0 \\[4pt] \frac{1}{2} I_x\!\left(\frac{\nu}{2}, \frac{1}{2}\right) & t < 0 \end{cases}$$
where $x = \frac{\nu}{\nu + t^2}$.
**Moments** (defined only when $\nu$ is sufficiently large):
$$E[T] = 0 \;(\nu > 1), \quad \text{Var}(T) = \frac{\nu}{\nu - 2} \;(\nu > 2), \quad \text{Kurt} = \frac{6}{\nu - 4} \;(\nu > 4)$$
**Convergence to normal**: As $\nu \to \infty$, $t_\nu \to N(0,1)$. For practical purposes, $\nu \ge 30$ produces CDF values within $10^{-3}$ of the normal CDF.
**Parameter constraints**: `period` $> 0$, $\nu > 0$. Output is bounded $[0, 1]$.
```
TDIST(source, period, df):
// Phase 1: min-max normalization
min_val = min(source[0..period-1])
max_val = max(source[0..period-1])
range = max_val - min_val
x = range > 0 ? (source - min_val) / range : 0.5
// Phase 2: t-statistic mapping
t = (x - 0.5) * 6.0
// Phase 3: beta argument
bx = df / (df + t*t)
// Phase 4: CDF via incomplete beta
ibeta = betaReg(bx, df/2, 0.5)
if t >= 0: return 1.0 - 0.5 * ibeta
else: return 0.5 * ibeta
```
## Resources
- Student (Gosset, W.S.). "The Probable Error of a Mean." Biometrika, 1908.
- Fisher, R.A. "Statistical Methods for Research Workers." Oliver and Boyd, 1925.
- Mandelbrot, B. "The Variation of Certain Speculative Prices." Journal of Business, 1963.
- Fama, E.F. "The Behavior of Stock-Market Prices." Journal of Business, 1965.
- Bollerslev, T. "Generalized Autoregressive Conditional Heteroskedasticity." Journal of Econometrics, 1986.
- Press, W.H. et al. "Numerical Recipes: The Art of Scientific Computing." 3rd edition, Cambridge University Press, 2007. Chapter 6.4.
+86
View File
@@ -0,0 +1,86 @@
# WEIBULLDIST: Weibull Distribution CDF
The Weibull Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the Weibull distribution, producing an output in $[0, 1]$. The Weibull distribution is a flexible two-parameter family that subsumes the exponential distribution ($k = 1$) and approximates the normal distribution ($k \approx 3.6$) as special cases. Its closed-form CDF requires only `pow` and `exp`, making it the computationally cheapest distribution indicator after EXPDIST. The shape parameter $k$ controls the CDF curvature: $k < 1$ produces a concave curve (rapid initial rise), $k = 1$ gives the exponential, $k = 2$ produces the Rayleigh distribution, and $k > 3$ creates an S-shaped curve approaching Gaussian behavior.
## Historical Context
The Weibull distribution was formalized by Waloddi Weibull (1951) for modeling material fatigue and breaking strength, though the mathematical form appeared earlier in work by Rosin and Rammler (1933) on particle size distributions and Frechet (1927) on extreme value theory. It is one of three extreme value distributions (alongside Gumbel and Frechet), making it theoretically grounded for modeling maxima and minima of samples.
In engineering, the Weibull distribution dominates reliability analysis: the shape parameter $k$ (also called the Weibull modulus) characterizes the failure rate. $k < 1$ means decreasing failure rate (infant mortality), $k = 1$ means constant failure rate (random failures), and $k > 1$ means increasing failure rate (wear-out). This maps to financial interpretation: $k < 1$ emphasizes breakouts from the bottom of the range (rapid CDF rise for small normalized values), while $k > 1$ emphasizes breakouts near the top (CDF stays low until normalized value approaches the scale parameter).
The scale parameter $\lambda$ controls the characteristic life: the value at which the CDF equals $1 - e^{-1} \approx 0.632$. With default $\lambda = 0.5$, the CDF reaches 63.2% when the normalized price is at the midpoint of the recent range.
## Architecture and Physics
The computation follows a two-phase pipeline:
**Phase 1: Min-max normalization** scans `period` bars for extrema, maps the current source to $x \in [0, 1]$. Zero-range defaults to 0.5.
**Phase 2: Closed-form CDF** evaluates:
$$F(x) = 1 - \exp\!\left(-\left(\frac{x}{\lambda}\right)^k\right)$$
with a floor of $x = 0$ (negative values impossible after normalization). The computation requires one division, one `pow`, one negation, and one `exp`. No special functions, no iterations, no convergence checks.
**Shape parameter effects on the CDF curve:**
| $k$ | Character | Financial Interpretation |
|-----|-----------|------------------------|
| 0.5 | Steep concave | Highly sensitive to any move off the low |
| 1.0 | Exponential | Memoryless; equivalent to EXPDIST with $\lambda = 1/\text{scale}$ |
| 2.0 | Rayleigh | Linear failure rate; moderate S-curve |
| 3.6 | Near-Gaussian | Approximate normal CDF shape |
| 5.0+ | Steep sigmoid | Insensitive until price nears the scale point, then jumps |
**Scale parameter effects**: $\lambda = 0.25$ compresses the transition zone toward low normalized values (CDF saturates quickly). $\lambda = 1.0$ spreads the transition across the entire $[0, 1]$ range (CDF is gentler). Default $\lambda = 0.5$ centers the characteristic value at the midpoint.
## Mathematical Foundation
The Weibull distribution with shape $k > 0$ and scale $\lambda > 0$ has PDF and CDF:
$$f(x; k, \lambda) = \frac{k}{\lambda}\left(\frac{x}{\lambda}\right)^{k-1} \exp\!\left(-\left(\frac{x}{\lambda}\right)^k\right), \quad x \ge 0$$
$$F(x; k, \lambda) = 1 - \exp\!\left(-\left(\frac{x}{\lambda}\right)^k\right), \quad x \ge 0$$
**Inverse CDF** (quantile function):
$$F^{-1}(p) = \lambda \left(-\ln(1 - p)\right)^{1/k}$$
**Moments:**
$$E[X] = \lambda\,\Gamma\!\left(1 + \frac{1}{k}\right)$$
$$\text{Var}(X) = \lambda^2 \left[\Gamma\!\left(1 + \frac{2}{k}\right) - \Gamma^2\!\left(1 + \frac{1}{k}\right)\right]$$
**Hazard function** (failure rate):
$$h(x) = \frac{f(x)}{1 - F(x)} = \frac{k}{\lambda}\left(\frac{x}{\lambda}\right)^{k-1}$$
This is increasing for $k > 1$, constant for $k = 1$, and decreasing for $k < 1$.
**Special cases**: $k = 1 \Rightarrow \text{Exponential}(\lambda)$. $k = 2 \Rightarrow \text{Rayleigh}(\lambda/\sqrt{2})$.
**Parameter constraints**: `period` $> 0$, $k > 0$, $\lambda > 0$. Output is bounded $[0, 1]$.
```
WEIBULLDIST(source, period, shape, scale):
// Phase 1: min-max normalization
min_val = min(source[0..period-1])
max_val = max(source[0..period-1])
range = max_val - min_val
x = range > 0 ? (source - min_val) / range : 0.5
// Phase 2: closed-form CDF
safe_x = max(0, x)
ratio = safe_x / scale
raised = pow(ratio, shape)
return 1.0 - exp(-raised)
```
## Resources
- Weibull, W. "A Statistical Distribution Function of Wide Applicability." Journal of Applied Mechanics, 1951.
- Frechet, M. "Sur la loi de probabilite de l'ecart maximum." Ann. Soc. Polon. Math., 1927.
- Rinne, H. "The Weibull Distribution: A Handbook." CRC Press, 2009.
- Abernethy, R.B. "The New Weibull Handbook." 5th edition, 2006.
- Johnson, N.L., Kotz, S. & Balakrishnan, N. "Continuous Univariate Distributions, Vol. 1." Wiley, 1994.