alexgrover

Approximating A Least Square Moving Average In Pine

Education
OANDA:EURUSD   Euro / U.S. Dollar
Least Squares Moving Average, Running Least Squares, Regression Line or even Running Line, this method is among the most popular ones in statistics and technical analysis.

The LSMA is extremely useful, it approximate the price pretty well and can be considered as one of the best low-lagging filters out there. Knowing how this filter is made can be really interesting. May the methods i share below inspire you to create great indicators or start coding in pine :)

A Least Squares Moving Average is defined by Tradingview as :

A line that best fits the prices specified over a user-defined time period. It is calculated using the least squares method. The result of this function is calculated using the formula: linreg = intercept + slope * (length - 1 - offset), where length is the y argument, offset is the z argument, intercept and slope are the values calculated with the least squares method on source series (x argument).

Alright, we wont use the offset parameter for our approximations, so how to calculate a least squares moving average ? If you find the mathematical formula of it you will certainly ask yourself "what are all of those maths" . But its ok, in the Pinescript you can just use the linreg() function, or you could calculate it like that :

slope = correlation(close,n,length) * (stdev(close,length)/stdev(n,length))
intercept = sma(close,length) - slope*sma(n,length)
linreg = slope*n + intercept


Ok, but can we use different estimation methods ? Certainly, the key of the LSMA is only the correlation coefficient after all, all the other parameters can be estimated.

Standard Score Or Rescaling A Line To The Price

Rescaling a line to the price is easy to do, it will give a similar result as the LSMA but it is faster to write, here the code :

A = (n - sma(n,length))/stdev(n,length) * correlation(close,n,length)
B = sma(close,length) + A*stdev(close,length)


Easier no ? We first standardized a line (n) and multiplied it by its correlation with the price, our first parameter A is dimensionless.
Then we rescaled the result to the price by multiplying our parameter with the price standard deviation and summing this result to the price moving average.

here the difference between our method and the classic LSMA of both period 100


If you put both together you wont see any difference. Overshoots can be reduced by modifying the standard deviation size.

Correlation Rescaling

The correlation coefficient is the core of a LSMA, if we rescale it we can approximate a LSMA, here the code :

a = (correlation(close,n,length) + 1)/2
b = sma(close,length) + stdev(close,length)*1.7
c = sma(close,length) - stdev(close,length)*1.7
k = c + a*(b-c)


The correlation coefficient oscillate in a range of 1/-1, we first scale it in a range of 1/0. Then you may have recognized the b and c formulas, they are the one used in bollinger bands,
the standard deviation is multiplied by 1.7 because it was the number who best approximated a LSMA, but it could be any number defined by the user, something interesting is that this method to can fix overshoots in a classic LSMA using lower multiplier. Since our correlation is in a range of 1/0 we can rescale it to the price thanks to the method used in k.

In red our method, in blue the LSMA of both period 100.


Here the standard deviation is not multiplied by a number, this result in less overshoot.


In order to have even more manipulation over the LSMA i will try to estimate the correlation coefficient the best i can :)

So here you go, i hope you will find a use for it.

Check out the indicators we are making at luxalgo: www.tradingview.com/u/LuxAlgo/
Disclaimer

The information and publications are not meant to be, and do not constitute, financial, investment, trading, or other types of advice or recommendations supplied or endorsed by TradingView. Read more in the Terms of Use.