Ahrens Moving Average Java Example


//========================================================================
// Ahrens Moving Average                                                //
//                                                                      //
// The Ahrens Moving Average is an IIR (Infinite Impulse Response),     //
// front-weighted moving average which can be used to filter time       //
// series data using a window as short as 2 periods. It provides        //
// superior smoothing and is less likely to be perturbed by transient   //
// spikes than either a simple moving average or a exponential moving   //
// average with the same smoothing period.                              //
//                                                                      //
// This program is free software: you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation, either version 3 of the License, or    //
// (at your option) any later version.                                  //
//                                                                      //
// This program is distributed in the hope that it will be useful,      //
// but WITHOUT ANY WARRANTY; without even the implied warranty of       //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        //
// GNU General Public License for more details.                         //
//                                                                      //
// You should have received a copy of the GNU General Public License    //
// along with this program.  If not, the full text of it can be found   //
// at http://www.gnu.org/licenses/gpl.html                              //
//========================================================================

//------------------------------------------------------------------------
//    This implementation was graciously provided by Java authority     //
//    Michael Ernest. (Books by Michael are available on Amazon.COM)    //
//------------------------------------------------------------------------

package doc;

import java.util.ArrayList;

public class AhrensMovingAverage {

    public ArrayList ama(double[] icol, int period, int x_end) {
        ArrayList avg = new ArrayList<>();
        int x_start = 0;
        
        //-------------------------------------------------------
        // the AMA may be used to smooth raw data or the output
        // of other calculations. since other calculations may
        // introduce significant phase lag there is no guarantee
        // that the input data will really start at the beginning
        // of the array passed to this function. this loop locates
        // the first actual datapoint in the input series. leading
        // zeros are assumed to be empty cells

        for (int a = 1; a < x_end; a++) {
             if (icol[a] != 0) {
                 x_start = a;
             }
        }
        
        //-------------------------------------------------------
        // the first data point in a series may be (significantly)
        // divergent from the data that follows. this loop creates
        // a reasonably representative set of initial values to
        // seed the average.  it uses an "expanding period" simple
        // moving average over the first N samples (where N equals
        // the period of the average)

        int count = 0;
        double total = 0;
        
        for (int a = x_start; a < x_start + period && a < x_end; a++) {
            count++;
            total += (double)icol[a];
            avg.add(total / count);
        }
        
        //-------------------------------------------------------
        // once the seed values have been calculated, shift gears
        // and calculate the AMA for $x_start + $period through
        // $x_end

        for (int a = x_start + period; a <= x_end; a++) {
            double numerator = (double)icol[a] - 
                               (avg.get(a-1) + avg.get(a-period)/2);
            avg.set(a, avg.get(a-1) + numerator / period);
        }

        return avg;
    }    
}





Click link to download the above JAVA source code.