Files
QuanTAlib/lib/trends_FIR/pwma/Pwma.md
T

4.1 KiB
Raw Blame History

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
Signature pwma_signature
  • PWMA (Parabolic Weighted Moving Average) applies a parabolic (i^2) weighting scheme to the data window.
  • Similar: FWMA, WMA | 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. |