Joe, Global g_FirstBar, g_LastBar; g_FirstBar = 0; g_LastBar = BarCount-1;
BR, Dennis On Aug 6, 2010, at 4:53 PM, j0etr4der wrote: > Hi Dennis, > > I know I must be missing something blatantly obvious, but don't know what. > When I copy/paste your functions to a new Editor session and run Backtest I > get the following error: > > Error 29. Variable 'g_firstbar' used without having been initialized. > > If I initialize the globals outside the function - > > g_FirstBar = g_LastBar = 0; > > and then use this to see the results - > > Plot( EMA( Close, 15 ), "", colorBlack ); > Plot( ALFilter( Close, 15 ), "AL Filter", colorRed ); > > "AL Filter" is always 0. > > I'm using 5.30.1. > > > Best regards, > > Joe > > > > > --- In [email protected], Dennis Brown <se...@...> wrote: >> >> Hello, >> >> I spent a good deal of effort creating a very useful smooth moving average >> filter that was also fast. It is based on the John Ehlers Adaptive Laguerre >> Filter. I started with some code from "Mich" in the AB library a couple of >> years ago. >> >> http://www.amibroker.com/library/detail.php?id=772&hilite=PLOT >> >> The general problem with this adaptive filter is that is uses a loop within >> a loop for each bar. The time to execute is the number of bars times the >> look-back period. This made long periods impractically slow. >> >> I came up with a feedback method that worked well in a single loop. The >> speed became a normal linear function of the number of bars to process. >> >> This filter is excellent for de-trending. It is also very smooth. I use it >> as the basis of many indicators. I would not trade without it. Because the >> Periods input to the function can also be an array, it can be further >> adapted with inputs like volume. This makes some indicators even better. >> >> However, since I use it so often I would like it to run even faster. There >> are two different ways that could happen: >> >> 1. Convert the algorithm to run with array operations instead of a loop. I >> don't know how to do that with this algorithm. Perhaps someone with more >> experience with doing everything in arrays can look at this code and render >> an opinion on if it can be done (or even post the method). >> >> 2. Convert the inner loop of the algorithm into a DLL plugin. The guts of >> the loop is fairly straight forward and should not be hard to code in C++, >> but it is beyond my current level of development expertise. It would take >> me some time to do that myself. I am also in the process of converting to >> 64 bit W7. >> >> In any case, I am posting the AFL code for my prized filter for all to use. >> Hopefully someone will improve it with one of the above means and share it >> with me. >> >> Best regards, >> Dennis >> >> //================================================================ >> //AdaptiveLaGuerre function Last Updated 8/5/2010 by Dennis Brown >> //================================================================ >> // Smooth Adaptive Moving Average Filter, by Dennis Brown 9/6/2007 >> // Laguerre Filter section, by John Ehlers >> // Adaptive coeficient filter algorithm, by Dennis Brown >> // This adaptive filter runs orders of magnitudes faster than the original >> Ehlers version. >> // The speed of the original slowed geometrically by the feedback lookback >> bars. >> // There is no looking back in this version, so speed is linear to number >> of bars. >> // >> // decay is the decay time for historical error feedback significance --99 >> is a good starting number >> // smooth is smoothing factor of the error feedback signal --0.8 is a good >> starting number >> // gain is a number (or array for additional adaptive inputs) that sets the >> base filtering --1 is a good number >> // Periods is an array of periods for the filter that is translated to a >> gain array. >> //================================================================ >> >> function ALF( array, decay, smooth, gain ) >> { >> global g_FirstBar, g_LastBar; // global bar range to apply all loops due to >> lack of full control over SBR >> lastResult = lastL0 = lastL1 = lastL2 = lastL3 = array[g_FirstBar]; >> lastErrorFactor = 0.5; >> HH = 0.1; >> LL = 0; >> >> for ( i = g_FirstBar; i <= g_LastBar; i++ ) >> { >> //following error >> error = abs( array[i] - lastResult ); >> //recent highest error (decays over time) >> if ( error > HH ) { HH = error; } >> else { HH *= decay; } >> //recent lowest error (decays over time) >> if ( error < LL ) { LL = error; } >> else { LL *= decay; } >> //get ema of error position in range of error >> if ( HH != LL ) { errorFactor = smooth * lastErrorFactor + (1 - smooth) >> * ((error - LL) / (HH - LL)); } >> else { errorFactor = 1; } // for x/0 case >> lastErrorFactor = errorFactor ; >> // LaGuerre Filter >> G = errorFactor * gain[i]; >> L0 = G * array[i] + (1 - G) * lastL0; >> L1 = -(1 - G) * L0 + lastL0 + (1 - G) * lastL1; >> lastL0 = L0; >> L2 = -(1 - G) * L1 + lastL1 + (1 - G) * lastL2; >> lastL1 = L1; >> L3 = -(1 - G) * L2 + lastL2 + (1 - G) * lastL3; >> lastL2 = L2; >> lastL3 = L3; >> result[i] = lastResult = (L0 + 2 * L1 + 2 * L2 + L3) / 6; >> } >> return result; >> } >> >> function ALFilter( PriceArray, Periods ) >> { >> gain = (1 / ((Periods / 2) ^.6666) + 2 / (Periods / 2)) / 2; // translate >> Periods to the non-linear gain term >> decay = 0.99; // error decay factor >> smooth = 0.8; // error smoothing factor >> return ALF( PriceArray, decay, smooth, gain ); >> } >> > > > > > ------------------------------------ > > **** IMPORTANT PLEASE READ **** > This group is for the discussion between users only. > This is *NOT* technical support channel. > > TO GET TECHNICAL SUPPORT send an e-mail directly to > SUPPORT {at} amibroker.com > > TO SUBMIT SUGGESTIONS please use FEEDBACK CENTER at > http://www.amibroker.com/feedback/ > (submissions sent via other channels won't be considered) > > For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG: > http://www.amibroker.com/devlog/ > > Yahoo! Groups Links > > >
