Overall Statistics
namespace QuantConnect {

	// Loosely based on https://github.com/QuantConnect/Lean/blob/master/Indicators/SimpleMovingAverage.cs
    public class AverageMomentum : WindowIndicator<IndicatorDataPoint>
    {
        public IndicatorBase<IndicatorDataPoint> Mom { get; private set; }
        public IndicatorBase<IndicatorDataPoint> RollingSum { get; private set; }

        public AverageMomentum(int momentumPeriod, int averagePeriod)
            : this(String.Format($"AVGMOM{momentumPeriod}_{averagePeriod}"), momentumPeriod, averagePeriod)
        {
        }

        public AverageMomentum(string name, int momentumPeriod, int averagePeriod)
            : base(name, averagePeriod)
        {
        	Mom = new Momentum(name+"_MOM", momentumPeriod);
        	RollingSum = new Sum(name + "_Sum", averagePeriod);
        }

        /// <summary>
        /// Gets a flag indicating when this indicator is ready and fully initialized
        /// </summary>
        public override bool IsReady
        {
            get { return Mom.IsReady && RollingSum.IsReady; }
        }

        /// <summary>
        /// Computes the next value of this indicator from the given state
        /// </summary>
        /// <param name="input">The input given to the indicator</param>
        /// <param name="window">The window for the input history</param>
        /// <returns>A new value for this indicator</returns>
        protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input)
        {
            Mom.Update(input);
            
			if(Mom.IsReady) RollingSum.Update(input.Time, Mom);
            return RollingSum.Current.Value / window.Count;
         }

        /// <summary>
        /// Resets this indicator and its sub-indicator Mean to their initial state
        /// </summary>
        public override void Reset()
        {
            Mom.Reset();
            RollingSum.Reset();
            base.Reset();
        }
    }
}
namespace QuantConnect 
{   
    public class BasicTemplateAlgorithm : QCAlgorithm
    {
        //Initialize the data and resolution you require for your strategy:
        public override void Initialize() 
        {
			
            SetStartDate(2016, 1, 1);         
            SetEndDate(DateTime.Now.Date.AddDays(-1));
            SetCash(25000);
            SetWarmup(TimeSpan.FromDays(20));
            AddSecurity(SecurityType.Equity, "SPY", Resolution.Daily);

			// UNCOMMENT THIS LINE AND IT WILL BREAK.
            //var avgMom = AVGMOM("SPY", 20, 7, Resolution.Daily);
        }

        public void OnData(TradeBars data) 
        {   
            if (!Portfolio.HoldStock) 
            {
                int quantity = (int)Math.Floor(Portfolio.Cash / data["SPY"].Close);
                Order("SPY",  quantity);
                Debug("Purchased SPY on " + Time.ToShortDateString());
            }
        }
        
        // Based on https://www.quantconnect.com/lean/documentation/topic15.html
		public AverageMomentum AVGMOM(string symbol, int momentumPeriod, int averagePeriod, Resolution? resolution = null)  {
		      var name = CreateIndicatorName(symbol, string.Format("AVGMOM{0}_{1}", momentumPeriod, averagePeriod), resolution);
		      var avgMom = new AverageMomentum(name, momentumPeriod, averagePeriod);
		      RegisterIndicator(symbol, avgMom, resolution);
		      return avgMom;
		}
    }
}