Overall Statistics
from collections import deque
from datetime import datetime, timedelta
from numpy import sum, std
from QuantConnect.Data.Market import QuoteBar

class PriceOverreactionsForex(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2017, 12, 11)  # Set Start Date
        self.SetEndDate(2018, 12, 31) # Set End Date
        self.SetCash(100000)  # Set Strategy Cash
        self.syls = ["USDCAD","AUDUSD","EURJPY", "EURUSD", "USDCAD"] # Define Symbols for Trading
        self.days = 20 # Paramater to calculate reference
        self.open = {}
        self.averageDay = {}
        self.intraDay = {}

        for symbol in self.syls:
            self.AddForex(symbol, Resolution.Hour, Market.Oanda)
            self.averageDay[symbol] = AverageDay(symbol, self.days)
            self.RegisterIndicator(symbol, self.averageDay[symbol], Resolution.Daily)
            self.intraDay[symbol] = 0.0
            self.open[symbol] = 0.0
            
        self.SetWarmup(self.days)

    def OnData(self, data):
        
        if self.IsWarmingUp: return
    
    #     for symbol in self.syls:
    #         if self.open[symbol] == 0.0:
    #             self.open[symbol] = data[symbol].Open
                
    #         self.intraDay[symbol] = self.UpdateIntraday(symbol, data[symbol].Close)

    # def UpdateIntraday(self, symbol, lastClose):
    #     r = 0.0
    #     r = ((lastClose / self.open[symbol])- 1 ) * 100
    #     return r
    
class AverageDay(PythonIndicator):
    def __init__(self, name, period):
        self.Name = name
        self.Time = datetime.min
        self.Value = 0
        self.queue = deque(maxlen=period)
        self.Positive = 0
        self.Negative = 0

    def __repr__(self):
        return "{0} -> IsReady: {1}. Time: {2}. Value: {3}".format(self.Name, self.IsReady, self.Time, self.Value)

    # Update method is mandatory
    def Update(self, input):
        r = ((input.Close / input.Open) - 1 ) * 100
        self.queue.appendleft(r)
        count = len(self.queue)
        self.Time = input.EndTime
        average = sum(self.queue) / count
        deviation = std(self.queue)
        self.Positive = average + (2 * deviation)
        self.Negative = average - (2 * deviation)
        return count == self.queue.maxlen