I've been trying to implement a low frequency cutoff in c++ which essentially takes a stream of numbers and smooths out the output (filtering out high frequency movement/jitter), however it is important the front weighted numbers are considered immediately as the data is time critical (it is to control a motion simulation base using output from a bit of game software). I've got a working weighted moving average algoithm but could do with something a little more responsive at the front end, and I found this:-
The pseudo-code there is as follows:
Inputs: Price(NumericSeries), Period(NumericSimple);
Variables: factor(0), lag(0);
if CurrentBar <= 1 then
ZLEMA = Price;
factor = 2/(Period+1);
lag = (Period-1)/2;
ZLEMA = factor*(2*Price-Price[lag]
) + (1-factor)*ZLEMA;
I've translated it in to C and my code is as follows:
* Zero-Latency Exponential Moving Average.
float zlema(float* vals, int numVals, int currentSample)
static float factor = 0;
static int lag = 0;
static float lastema = 0;
if(currentSample <= 1)
ema = vals;
factor = 2.0 / (((float) numVals) + 1.0);
lag = (numVals - 1) / 2;
ema = (factor * ((2.0 * vals) - vals[lag])) +
((1.0 - factor) * lastema);
lastema = ema;
However, it doesn't seem to behave quite as I'd expect. It seems to be nearly there but sometimes I get a slightly lower value than all items in the queue (when they are all higher).
My queue and the number of items in it are passed as parameters, with the most recent being at the front at all times, also I pass an incrementing counter starting at 0 as required by the function.
I'm not sure I've interpreted the meaning of 'ZLEMA' correctly as it's not clear in his pseudocode, so I've assumed this to be the last call's zlema and also I'm assuming 'Price' actually means 'Price'. Perhaps I've got this wrong?
Am I supposed to be copying the actual zlema calculated values back to my original queue before the next call? I don't change the original queue at all other than just shifting all values one to the end and inserting the latest at the beginning. The code I use to do this is:
static long cs0 = 0;
for(int cnt = NUM_AVERAGE_VALS - 1; cnt > 0; cnt--)
m_arrAct0AverageVals[cnt] = m_arrAct0AverageVals[cnt-1];
m_arrAct0AverageVals = lPos;
float lPosNew = zlema(m_arrAct0AverageVals, NUM_AVERAGE_VALS, cs0);
Would be extremely grateful if someone with a better understanding of the math could please sanity check this for me to see if I've got anything slightly wrong?
Thanks so much in advance if you can help!