Dennis,
You have done some good work here. Would it be possible to explain exactly how 
you use for trading.  Also, there is no PLOT so one could see a chart of the 
adaptive MA.

Dick 

--- 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 ); 
> }
>


Reply via email to