# PWMA: Parabolic Weighted Moving Average > *Linear weighting is for people who think the world is flat. PWMA squares the weights, because recent data isn't just more important—it's exponentially more important.* | Property | Value | | ---------------- | -------------------------------- | | **Category** | Trend (FIR MA) | | **Inputs** | Source (close) | | **Parameters** | `period` | | **Outputs** | Single series (Pwma) | | **Output range** | Tracks input | | **Warmup** | `period` bars | | **PineScript** | [pwma.pine](pwma.pine) | | **Signature** | [pwma_signature](pwma_signature.md) | - PWMA (Parabolic Weighted Moving Average) applies a parabolic ($i^2$) weighting scheme to the data window. - **Similar:** [FWMA](../fwma/fwma.md), [WMA](../wma/wma.md) | **Complementary:** Trend filters | **Trading note:** Pascal-Weighted MA; weights from Pascals triangle for smooth, symmetric kernel. - Validated against TA-Lib, Skender, and Tulip reference implementations where available. PWMA (Parabolic Weighted Moving Average) applies a parabolic ($i^2$) weighting scheme to the data window. This assigns massive importance to the most recent data points while still technically including the older data. It's like a WMA on steroids. ## Historical Context While the WMA uses a linear triangle window ($1, 2, 3, \dots, n$), the PWMA uses a parabolic window ($1^2, 2^2, 3^2, \dots, n^2$). This was developed for traders who found the WMA too slow but the EMA too jittery. It provides a curve that turns faster than a WMA but is smoother than an EMA at the tail. ## Architecture & Physics The "physics" is defined by the weight function $W_i = i^2$. This shifts the center of gravity of the filter heavily towards the right (recent data). ## Mathematical Foundation $$ \text{PWMA} = \frac{\sum_{i=1}^{N} i^2 P_{t-N+i}}{\sum_{i=1}^{N} i^2} $$ The O(1) update logic involves cascading the sums: $$ S1_{new} = S1_{old} - \text{Oldest} + \text{Newest} $$ $$ S2_{new} = S2_{old} - S1_{old} + N \times \text{Newest} $$ $$ S3_{new} = S3_{old} - 2 S2_{old} + S1_{old} + N^2 \times \text{Newest} $$ ## Performance Profile ### Operation Count (Streaming Mode, Scalar) The O(1) algorithm uses triple cascading sums: | Operation | Count | Cost (cycles) | Subtotal | | :--- | :---: | :---: | :---: | | ADD/SUB | 9 | 1 | 9 | | MUL | 3 | 3 | 9 | | DIV | 1 | 15 | 15 | | **Total** | **13** | — | **~33 cycles** | **Hot path breakdown:** - S1 update: `S1_new = S1_old - oldest + newest` → 2 ADD/SUB - S2 update: `S2_new = S2_old - S1_old + N×newest` → 2 ADD/SUB + 1 MUL - S3 update: `S3_new = S3_old - 2×S2_old + S1_old + N²×newest` → 4 ADD/SUB + 2 MUL - Final: `PWMA = S3 / divisor` → 1 DIV (divisor precomputed) **Comparison with naive O(N) implementation:** | Mode | Complexity | Cycles (Period=100) | | :--- | :---: | :---: | | Naive (recalculate) | O(N) | ~700 cycles | | QuanTAlib O(1) | O(1) | ~33 cycles | | **Improvement** | **—** | **~21× faster** | ### Batch Mode (SIMD) PWMA batch can vectorize prefix-sum cascades: | Operation | Scalar Ops (512 bars) | SIMD Ops (AVX2) | Speedup | | :--- | :---: | :---: | :---: | | S1 prefix sum | 512 | 64 | 8× | | S2 cascaded sum | 1024 | 128 | 8× | | S3 cascaded sum | 1536 | 192 | 8× | ### Quality Metrics | Metric | Score | Notes | | :--- | :---: | :--- | | **Accuracy** | 10/10 | Matches mathematical definition exactly | | **Timeliness** | 9/10 | Very fast reaction to new data (heavy recent weighting) | | **Overshoot** | 3/10 | Parabolic weighting can cause overshoot | | **Smoothness** | 4/10 | Sensitive to recent noise | ## Validation Validated against Ooples. | Library | Status | Notes | | :--- | :--- | :--- | | **QuanTAlib** | ✅ | Validated. | | **Ooples** | ✅ | Matches `CalculateParabolicWeightedMovingAverage` | | **Skender** | N/A | Not implemented | | **TA-Lib** | N/A | Not implemented | | **Tulip** | N/A | Not implemented. |