Overall Statistics
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data.Consolidators import *
from datetime import timedelta
import decimal

### <Summary>
### Example algorithm giving an introduction into using IDataConsolidators.
### This is an advanced QC concept and requires a certain level of comfort using C# and its event system.
###
### What is an IDataConsolidator?
### IDataConsolidator is a plugin point that can be used to transform your data more easily.
### In this example we show one of the simplest consolidators, the TradeBarConsolidator.
### This type is capable of taking a timespan to indicate how long each bar should be, or an
### integer to indicate how many bars should be aggregated into one.
###
### When a new 'consolidated' piece of data is produced by the IDataConsolidator, an event is fired
### with the argument of the new data.
### </summary>
### <meta name="tag" content="using data" />
### <meta name="tag" content="consolidating data" />
class SPY5minAlgorithm(QCAlgorithm):

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(DateTime(2018, 9, 6, 9, 30, 0))  #Set Start Date/Time
        #self.SetEndDate(self.StartDate + timedelta(1))           #Set End Date
        self.SetEndDate(DateTime(2018, 9, 6, 16, 0, 0))           #Set End Date
        self.SetCash(100000) #Set Strategy Cash
        self.__mx = decimal.Decimal('0.001') #threshold to trigger
        #Find more symbols here: http://quantconnect.com/data
        self.AddEquity("SPY")
        
        # define our 5 minute trade bar consolidator. we can
        # access the 5 minute bar from the DataConsolidated events
        fiveMinuteConsolidator = TradeBarConsolidator(timedelta(minutes=5))

        # attach our event handler. the event handler is a function that will
        # be called each time we produce a new consolidated piece of data.
        fiveMinuteConsolidator.DataConsolidated += self.FiveMinuteBarHandler

        # this call adds our 5 minute consolidator to
        # the manager to receive updates from the engine
        self.SubscriptionManager.AddConsolidator("SPY", fiveMinuteConsolidator)

        self.__last = None #save the last bar

    def OnData(self, data):
        '''We need to declare this method'''
        pass


    def OnEndOfDay(self):
        # close up shop each day and reset our 'last' value so we start tomorrow fresh
        self.Liquidate("SPY")
        self.__last = None


    def FiveMinuteBarHandler(self, sender, consolidated):
        '''This is our event handler for our 5 minute trade bar defined above in Initialize(). So each time the
        consolidator produces a new 30 minute bar, this function will be called automatically. The 'sender' parameter
         will be the instance of the IDataConsolidator that invoked the event, but you'll almost never need that!'''
        
        self.Log(consolidated.Close)
        if self.__last is not None and consolidated.Close > self.__last.Close*(1+self.__mx) and self.Portfolio['SPY'].Quantity <=0 :
            self.Log(f"{consolidated.Time} >> SPY >> LONG  >> 100 >> {self.Portfolio['SPY'].Quantity}")
            self.Order("SPY", 100)

        elif self.__last is not None and consolidated.Close < self.__last.Close*(1-self.__mx) and self.Portfolio['SPY'].Quantity >=0 :
            self.Log(f"{consolidated.Time} >> SPY >> SHORT  >> 100 >> {self.Portfolio['SPY'].Quantity}")
            self.Order("SPY", -100)

        self.__last = consolidated