OPEN-SOURCE SCRIPT
Aggiornato

Functionally Weighted Moving Average

266
OVERVIEW
An anchor-able moving average that weights historical prices with mathematical curves (shaping functions) such as Smoothstep, Ease In / Out, or even a Cubic Bézier. This level of configurability lends itself to more versatile price modeling, over conventional moving averages.


SESSION ANCHORS
Aside from VWAP, conventional moving averages do not allow you to use the first bar of each session as an anchor. This can make averages less useful near the open when price is sufficiently different from yesterdays close. For example, in this screenshot the EMA (blue) lags behind the sessionally anchored FWMA (yellow) at the open, making it slower to indicate a pivot higher.
istantanea
An incrementing length is what makes a moving average anchor-able. VWAP is designed to do this, indefinitely growing until a new anchor resets the average (which is why it doesn't have a length parameter). But conventional MA's are designed to have a set length (they do not increment). Combining these features, the FWMA treats the length like a maximum rather than a set length, incrementing up to it from the anchor (when enabled).

Quick aside: If you code and want to anchor a conventional MA, the length() function in my UtilityLibrary will help you do this.


Incrementing an averages length introduces near-anchor volatility. For this reason, the FWMA also includes an option to saturate the anchor with the source, making values near the anchor more resistant to change. The following screenshot illustrates how saturation affects the average near the anchor when disabled (aqua) and enabled (fuchsia).
istantanea

AVERAGING MATH
While there's nothing special about the math, it's worth documenting exactly how the average is affected by the anchor.

Average = Dot Product / Sum of Weights

Dot Product
This is the sum of element-wise multiplication between the Price and Weight arrays.

Dot Product = Price1 × Weight1 + Price2 × Weight2 + Price3 × Weight3 ...

When the Price and Weight arrays are equally sized (aka. the length is no longer incrementing from the anchor), there's a 1-1 mapping between Price and Weight indices. Anchoring, however, purges historical data from the Price array, making it temporarily smaller. When this happens, a dot product is synthesized by linearly interpolating for proportional indices (rather than a 1-1 mapping) to maintain the intended shape of weights.

Synthetic Dot Product = FirstPrice × FirstWeight + ... MidPrice × MidWeight ... + LastPrice × LastWeight

Sum of Weights
Exactly what it sounds like, the sum of weights used by the dot product operation. The sum of used weights may be less than the sum of all weights when the dot product is synthesized.

Sum of Weights = Weight1 + Weight2 + Weight3 ...


CALCULATING WEIGHTS
Shaping functions are mathematical curves used for interpolation. They are what give the Functionally Weighted Moving Average its name, and define how each historical price in the look back period is weighted.

The included shaping functions are:

In the following screenshot, the only difference between the three FWMA's is the shaping function (Ease In, Ease In Out, and Ease Out) illustrating how different curves can influence the responsiveness of an average.
istantanea
And here is the same example, but with anchor saturation disabled.
istantanea


ADJUSTING WEIGHTS
Each function outputs a range of values between 0 and 1. While you can't expand or shrink the range, you can nudge it higher or lower using the Scalar. For example, setting the scalar to -0.2 remaps to [-0.2, ..., 0.8], and +0.2 remaps to [0.2, ..., 1.2]. The following screenshot illustrates how -0.2 (lightest blue) and +0.2 (darkest blue) affect the average.
istantanea
Easing functions can be further adjusted with the Degree (how much the shaping function curves). There's an interactive example of this here and the following illustrates how a degrees 0, 1, and 20 (dark orange, orange, and light orange) affect the average.
istantanea

This level of configurability completely changes how a moving average models price for a given length, making the FWMA extremely versatile.


INPUTS
You can configure:
  • Length (how many historical bars to average)
  • Source (the bar value to average)
  • Offset (horizontal offset of the plot)
  • Weight (the shaping function)
  • Scalar (how much to adjust each weight)
  • Degree (how much to ease in / out)
  • Bézier Points (controls shape of Bézier)
  • Divisor & Anchor parameters
  • Style of the plot



BUT ... WHY?
We use moving averages to anticipate trend initialization, continuation, and termination. For a given look back period (length) we want the average to represent the data as accurately and smoothly as possible. The better it does this, the better it is at modeling price.

In this screenshot, both the FWMA (yellow) and EMA (blue) have a length of 9. They are both smooth, but one of them more accurately models price.
istantanea
You wouldn't necessarily want to trade with these FWMA parameters, but knowing it does a better job of modeling price allows you to confidently expand the model to larger timeframes for bigger moves. Here, both the FWMA (yellow) and EMA (blue) have a length of 195 (aka. 50% of NYSE market hours).
istantanea


INSPIRATION
I predominantly trade ETF derivatives and hold the position that markets are chaotic, not random. The salient difference being that randomness is entirely unpredictable, and chaotic systems can be modeled. The kind of analysis I value requires a very good pricing model.

The term "model" sounds more intimidating than it is. Math terms do that sometimes. It's just a mathematical estimation. That's it. For example, a regression is an "average regressing" model (aka. mean reversion), and LOWESS (Locally Weighted Scatterplot Smoothing) is a statistically rigorous local regression.

LOWESS is excellent for modeling data. Also, it's not practical for trading. It's computationally expensive and uses data to the right of the point it's averaging, which is impossible in realtime (everything to the right is in the future). But many techniques used within LOWESS are still valuable.

My goal was to create an efficient real time emulation of LOWESS. Specifically I wanted something that was weighted non-linearly, was efficient, left-side only, and data faithful. Incorporate trading paradigms (like anchoring) and you get a Functionally Weighted Moving Average.

The formulas for determining the weights in LOWESS are typically chosen just because they seem to work well. Meaning ... they can be anything, and there's no justification other than "looks about right". So having a variety of functions (aka. kernels) for the FWMA, and being able to slide the weight range higher or lower, allows you to also make it "look about right".

William Cleveland, prominent figure in statistics known for his contributions to LOWESS, preferred using a tri-cube weighting function. Using Weight = Ease Out In with the Degrees = 3 is comparable to this. Enjoy!
Note di rilascio
Added indicator page link to the top of the source code.

Declinazione di responsabilità

Le informazioni ed i contenuti pubblicati non costituiscono in alcun modo una sollecitazione ad investire o ad operare nei mercati finanziari. Non sono inoltre fornite o supportate da TradingView. Maggiori dettagli nelle Condizioni d'uso.