Source » Moving Average function - source code


        /// <summary>
        /// Calculates a Moving Average
        /// </summary>
        /// <param name="iPeriod">Period</param>
        /// <param name="iShift">Shift</param>
        /// <param name="maMethod">Method of calculation</param>
        /// <param name="afSource">The array of source data</param>
        /// <returns>the Moving Average</returns>
        protected static float[] MovingAverage(int iPeriod, int iShift, MAMethod maMethod, float[] afSource)
        {
            int     iBar;
            float   sum;
            float[] afTarget = new float[Bars];

            if (iPeriod <= 1 && iShift == 0)
            {   // There is no smoothing
                return afSource;
            }

            if (iPeriod > Bars || iPeriod + iShift <= 0 || iPeriod + iShift > Bars)
            {   // Error in the parameters
                return null;
            }

            for (iBar = 0; iBar < iPeriod + iShift - 1; iBar++)
            {
                afTarget[iBar] = 0;
            }

            for (iBar = 0, sum = 0; iBar < iPeriod; iBar++)
            {
                sum += afSource[iBar];
            }

            afTarget[iPeriod + iShift - 1] = sum / iPeriod;

            // Simple Moving Average
            if (maMethod == MAMethod.Simple)
            {   
                for (iBar = iPeriod; iBar < Math.Min(Bars, Bars - iShift); iBar++)
                {
                    afTarget[iBar + iShift] = afTarget[iBar + iShift - 1] + afSource[iBar] / iPeriod - afSource[iBar - iPeriod] / iPeriod;
                }
            }

            // Exponential Moving Average
            else if (maMethod == MAMethod.Exponential)
            {   
                float pr = 2f / (iPeriod + 1);

                for (iBar = iPeriod; iBar < Math.Min(Bars, Bars - iShift); iBar++)
                {
                    afTarget[iBar + iShift] = afSource[iBar] * pr + afTarget[iBar + iShift - 1] * (1 - pr);
                }
            }

            // Weighted Moving Average
            else if (maMethod == MAMethod.Weighted)
            {
                float fWeight = iPeriod * (iPeriod + 1) / 2f;

                for (iBar = iPeriod; iBar < Math.Min(Bars, Bars - iShift); iBar++)
                {
                    sum = 0f;
                    for (int i = 0; i < iPeriod; i++)
                    {
                        sum += afSource[iBar - i] * (iPeriod - i);
                    }

                    afTarget[iBar + iShift] = sum / fWeight;
                }
            }

            // Smoothed Moving Average
            else if (maMethod == MAMethod.Smoothed)
            {
                for (iBar = iPeriod; iBar < Math.Min(Bars, Bars - iShift); iBar++)
                {
                    afTarget[iBar + iShift] = (afTarget[iBar + iShift - 1] * (iPeriod - 1) + afSource[iBar]) / iPeriod;
                }
            }

            for (iBar = Bars + iShift; iBar < Bars; iBar++)
            {
                afTarget[iBar] = 0;
            }

            return afTarget;
        }

Top