Laguerre implementation

Posted By: TrumpLost

Laguerre implementation - 04/25/22 04:35

I want to replicate the Laguerre filter in Python for my notebook research, but I don't fully understand how it works. I've read through Ehler's paper but I don't completely understand that either.

The main thing I'm confused about in the lite-C code is this line:
Code
vars L = series(Data[0],8);


Here's the full code:
Code
var Laguerre(var *Data, var alpha)
{
   vars L = series(Data[0],8);
	SETSERIES(Data,0);
	if(alpha > 1.) alpha = smoothF(alpha);
	var alpha1 = 1.-alpha;

   L[0] = alpha*Data[0] + alpha1*L[1];
   L[2] = -alpha1*L[0] + L[1] + alpha1*L[2+1];
   L[4] = -alpha1*L[2] + L[2+1] + alpha1*L[4+1];
   L[6] = -alpha1*L[4] + L[4+1] + alpha1*L[6+1];
   
	return (L[0]+2.*L[2]+2.*L[4]+L[6])/6.;
}


And here's a rewrite in Python, which I think is not right.
Code
class Laguerre():
    def __init__(self, data: pd.Series, period):
        self.L = np.zeros(8)
        self.data0 = data[0]
        self.L[0] = self.data0
        if(period > 1):
            period = smoothF(period)
        self.period1 = 1 - period

    def Update(self, price: float):
        self.L[0] = price * self.data0 + self.period1 * self.L[1]
        self.L[2] = -self.period1 * self.L[0] + self.L[1] + self.period1 * self.L[2+1]
        self.L[4] = -self.period1 * self.L[2] + self.L[2+1] + self.period1 * self.L[4+1]
        self.L[6] = -self.period1 * self.L[4] + self.L[4+1] + self.period1 * self.L[6+1]
        return (self.L[0] + 2 * self.L[2] + 2 * self.L[4] + self.L[6]) / 6


Would really appreciate some insights as to how L in the original functions. I don't see where L[1] is being assigned a value, are the values inside the L list rolling forward each time this function runs? What does SETSERIES() do? I couldn't find it in the manual. And what is the return value from series(Data[0],8)?

Thanks.
Posted By: Petra

Re: Laguerre implementation - 04/25/22 07:47

Yes series are rolled forward, and SETSERIES is a debugging macro and has no meaning for conversion.
Posted By: AndrewAMD

Re: Laguerre implementation - 04/25/22 11:29

Originally Posted by TrumpLost
And what is the return value from series(Data[0],8)?
A pointer to your array of eight doubles. (a.k.a. vars)
https://zorro-project.com/manual/en/series.htm
Posted By: TrumpLost

Re: Laguerre implementation - 04/26/22 02:40

Originally Posted by AndrewAMD
Originally Posted by TrumpLost
And what is the return value from series(Data[0],8)?
A pointer to your array of eight doubles. (a.k.a. vars)
https://zorro-project.com/manual/en/series.htm


So when this line runs the first time, 7 of the 8 positions are initialized to some default? Is it 0? The second time this line runs, it automatically retains 7 of the items from the previous run, shifts the list forward by 1, and inserts the value of `Data[0]` in the first position?
Posted By: TrumpLost

Re: Laguerre implementation - 04/27/22 14:27

Here is the working Python code. It's really slow, especially if applied to lower timeframes, so perhaps what would be useful is an implementation in the form of a numpy extension.

Code
class Laguerre():
    def __init__(self, alpha=0.5):
        if alpha > 1.0:
            self.alpha = smoothF(alpha)
        else:
            self.alpha = alpha
        self.L = None
        self.initialized = False

    def Update(self, price):
        if not self.initialized:
            self.L = np.array([price for _ in range(1, 8)])
            self.initialized = True
        self.L = np.insert(self.L, 0, price, axis=0)[:8]
        alpha1 = 1.0-self.alpha
        self.L[0] = self.alpha * price + alpha1 * self.L[1]
        self.L[2] = -alpha1 * self.L[0] + self.L[1] + alpha1 * self.L[3]
        self.L[4] = -alpha1 * self.L[2] + self.L[3] + alpha1 * self.L[5]
        self.L[6] = -alpha1 * self.L[4] + self.L[5] + alpha1 * self.L[7]
        return (self.L[0] + 2.0 * self.L[2] + 2.0 * self.L[4] + self.L[6]) / 6.0


Here's the notebook snippet where I'm generating the smoothed curve:
Code
L = Laguerre(0.5)

for i, r in df.iterrows():
    df.loc[i,'L'] = L.Update(r.Close)


I'm wondering, is the intent of Zorro to be able to do the sort of data research that people are normally using jupyter notebooks for? Because Python is painfully slow, but tools like pandas and numpy are not, and work really well with matplotlib. Any advice is much appreciated.
Posted By: Petra

Re: Laguerre implementation - 04/27/22 17:20

I dont know if that was the intent of Zorro, but a discussion of programming languages for algo trading is here: https://financial-hacker.com/hackers-tools-zorro-and-r/
Posted By: TrumpLost

Re: Laguerre implementation - 05/09/22 16:37

In case anyone finds it useful, here's the laguerre function as a numpy extension.
https://github.com/rm-rf-etc/ehlers

It's much faster. I'll try to get this published as a module so others can get it using pip.
Posted By: rki

Re: Laguerre implementation - 04/08/23 19:13

Below works

from numba import njit

@njit
def laguerre (data, alpha):
alpha=alpha if alpha < 1 else 2/(alpha+1)
alpha1=1-alpha
out=[]

for i in range(len(data)):
if i==0:
L=np.array([data[i] for _ in range(8)])

L[0] = alpha * data[i] + alpha1 * L[1]
L[2] = -alpha1 * L[0] + L[1] + alpha1 * L[3]
L[4] = -alpha1 * L[2] + L[3] + alpha1 * L[5]
L[6] = -alpha1 * L[4] + L[5] + alpha1 * L[7]

myout=(L[0]+2.*L[2]+2.*L[4]+L[6])/6.
out.append (myout)

L=np.roll(L, 1)
return out
© 2024 lite-C Forums