Overall Statistics
# Imports
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Algorithm")

from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data import *
from QuantConnect.Data.Custom import *
from QuantConnect.Data.Market import TradeBar, QuoteBar
from QuantConnect.Data.Consolidators import *
from QuantConnect.Indicators import *
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np


class BasicTemplateAlgorithm(QCAlgorithm):
    
    def Initialize(self):
        self.symbol = "USDZAR"
        self.highprice = None
        self.lowprice = None
        self.tidetrend = None
        self.wavetrend = None
        
        self.closeWindow = RollingWindow[float](4)
        
        self.SetStartDate(2018,9,1) #Set Start Date
        self.SetEndDate(datetime.now()) #Set End Date to Now
        self.SetCash(1122) #Set Strategy Cash
        
        self.AddForex(self.symbol, Resolution.Minute).SetLeverage(50.0)
        
        # Create the rolling windows
        # Creates MACDOH indicator and add to a rolling window when it is updated
        self.macd1 = self.MACD(self.symbol, 12, 26, 9, MovingAverageType.Exponential)
        self.macd1.Updated += self.MACDOHUpdated
        self.macdoh = RollingWindow[MovingAverageConvergenceDivergence](5)
        
        # Creates MACDTM indicator and add to a rolling window when it is updated
        self.macd2 = self.MACD(self.symbol, 12, 26, 9, MovingAverageType.Exponential)
        self.macd2.Updated += self.MACDTMUpdated
        self.macdtm = RollingWindow[MovingAverageConvergenceDivergence](5)
        
        # Creates BB indicator and add to a rolling window when it is updated
        self.boll = self.BB(self.symbol, 20, 1, MovingAverageType.Exponential, Resolution.Minute)
        self.boll.Updated += self.BBUpdated
        self.bb = RollingWindow[BollingerBands](5)
        
        # Creates RSI indicator and add to a rolling window when it is updated
        self.strength = self.RSI(self.symbol, 14, MovingAverageType.Simple, Resolution.Minute)
        self.strength.Updated += self.RSIUpdated
        self.rsi = RollingWindow[RelativeStrengthIndex](5)
        
        oneHourConsolidator = QuoteBarConsolidator(timedelta(minutes=60))
        oneHourConsolidator.DataConsolidated += self.OneHourBarHandler
        self.RegisterIndicator(self.symbol, self.macd1, oneHourConsolidator)
        self.SubscriptionManager.AddConsolidator(self.symbol, oneHourConsolidator)
        
        tenMinuteConsolidator = QuoteBarConsolidator(timedelta(minutes=10))
        tenMinuteConsolidator.DataConsolidated += self.TenMinuteBarHandler
        self.RegisterIndicator(self.symbol, self.macd2, tenMinuteConsolidator)
        self.RegisterIndicator(self.symbol, self.boll, tenMinuteConsolidator)
        self.RegisterIndicator(self.symbol, self.strength, tenMinuteConsolidator)
        self.SubscriptionManager.AddConsolidator(self.symbol, tenMinuteConsolidator)
        
#        twoMinuteConsolidator = QuoteBarConsolidator(timedelta(minutes=2))
#        twoMinuteConsolidator.DataConsolidated += self.TwoMinuteBarHandler
#        self.SubscriptionManager.AddConsolidator(self.symbol, twoMinuteConsolidator)
        
        self.SetWarmUp(120, Resolution.Minute)
    
    #Pass (cause this is only for minute data)
    def OnData(self, data):
        pass
    
    # Adds updated values to MACDOH rolling window
    def MACDOHUpdated(self, sender, updated):
        self.macdoh.Add(updated)
        
    # Adds updated values to MACDTM rolling window
    def MACDTMUpdated(self, sender, updated):
        self.macdtm.Add(updated)
    
    # Adds updated values to BB rolling window
    def BBUpdated(self, sender, updated):
        self.bb.Add(updated)
    
    # Adds updated values to RSI rolling window
    def RSIUpdated(self, sender, updated):
        self.rsi.Add(updated)
    
    def OneHourBarHandler(self, sender, consolidated):
        if not (self.macdoh.IsReady): return
        macd_hist_0 = self.macdoh[0].Current.Value - self.macdoh[0].Signal.Current.Value
        macd_hist_1 = self.macdoh[1].Current.Value - self.macdoh[1].Signal.Current.Value
        macd_hist_2 = self.macdoh[2].Current.Value - self.macdoh[2].Signal.Current.Value
        macd_hist_3 = self.macdoh[3].Current.Value - self.macdoh[3].Signal.Current.Value
        
    def TenMinuteBarHandler(self, sender, consolidated):
        self.closeWindow.Add(self.Securities[self.symbol].Close)
        
        if not (self.closeWindow.IsReady and self.macdoh.IsReady and self.macdtm.IsReady and self.bb.IsReady and self.rsi.IsReady): return
    
        price_0 = self.closeWindow[0]
        price_1 = self.closeWindow[1]
        price_2 = self.closeWindow[2]
        
        self.highprice = max(price_0, price_1, price_2)
        self.lowprice = min(price_0, price_1, price_2)
        
        currrsi = self.rsi[0].Current.Value
        currbbub = self.bb[0].UpperBand.Current.Value
        currbblb = self.bb[0].LowerBand.Current.Value
        
        macd_hist_0 = self.macdtm[0].Current.Value - self.macdtm[0].Signal.Current.Value
        macd_hist_1 = self.macdtm[1].Current.Value - self.macdtm[1].Signal.Current.Value
        macd_hist_2 = self.macdtm[2].Current.Value - self.macdtm[2].Signal.Current.Value
        macd_hist_3 = self.macdtm[3].Current.Value - self.macdtm[3].Signal.Current.Value