Overall Statistics
from collections import deque

### <summary>
### This project presents a python alternative to the C# RollingWindow method 
### It takes advantage of the python collections.deque method to maintain the 
### history of an indicator
### </summary>
class BasicTemplateAlgorithm(QCAlgorithm):
    '''Simple algo to demonstrate the deque() method to store the history of an indicator'''
    
    class MacdState:
        ''' This class is used to save the state of the MACD values with each bar'''
        def __init__(self, macd):
            if not macd.IsReady:
                self.Macd = 0.0
                self.Fast = 0.0
                self.Slow = 0.0
                self.Signal = 0.0
            else:
                self.Macd = macd.Current.Value
                self.Fast = macd.Fast.Current.Value
                self.Slow = macd.Slow.Current.Value
                self.Signal = macd.Signal.Current.Value


    def Initialize(self):

        self.SetStartDate(2014,01,01)  #Set Start Date
        self.SetEndDate(2018,01,01)    #Set End Date
        self.SetCash(20000)            #Set Strategy Cash
        
        self.security = "FB"        # specify the desired security
        self.Hist = 10              # set the amount of history to retain for the indicator
        
        self.AddEquity(self.security, Resolution.Daily)
        
        # Specify the parameters for the macd indicator and the corresponding event handler 
        self.macd = self.MACD(self.security, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
        self.macd.Updated += self.macdUpdated
        
        # Intitialize the collections.deque (https://docs.python.org/3/library/collections.html#collections.deque)
        #  - the deque will maintain a list containing objects of the MacdState class
        #  - a new object will be prepended to the list each time the macd is updated
        # If desired, also specify the length of the list 
        self.macdHist = deque([self.MacdState(self.macd)], self.Hist)

        # Plot the indicator
        self.PlotIndicator("MACD", True, self.macd, self.macd.Signal)
        
    def macdUpdated(self, sender, updated):
        # Save the current state of the macd values by instantiating a new MacdState
        #  object and adding it to the deque
        self.macdHist.appendleft(self.MacdState(self.macd))

    def OnData(self, data):
        '''
        Arguments:
            data: Slice object keyed by symbol containing the stock data
        '''
        if not (self.macd.IsReady): return

        if not self.Portfolio.Invested:
            # enter a long position if macd crosses above zero.
            # In the code below, an index of 0 refers to the most recent value 
            #  of the macd properties in the deque. An index of 1 retrieves the 
            #  macd values of the previous bar 
            if self.macdHist[1].Macd < 0 and self.macdHist[0].Macd > 0:
                self.SetHoldings(self.security, 1)
        else:
            # exit the position if the macd drops back below zero
            if self.macdHist[0].Macd < 0:
                self.Liquidate(self.security)