Overall Statistics
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data import *
from datetime import timedelta
import pandas as pd
from io import StringIO
import datetime

 
class main(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020,7,27)  # Set Start Date
        self.SetEndDate(2020,12,31)# Set End Date
        self.SetCash(100000)  # Set Strategy Cash
        
        # If using dropbox remember to add the &dl=1 to trigger a download
        csv = self.Download("https://www.dropbox.com/s/2hlxb85lo7y10i3/test.csv?dl=1")

        # read file (which needs to be a csv) to a pandas DataFrame. include following imports above
    
        self.df = pd.read_csv(StringIO(csv))
        
        self.SetExecution(ImmediateExecutionModel())
        self.AveragePrice = None
        #self.security= None
        #self.quantity= None
        
        
        for i in range(len(self.df)) :
            self.security=str(self.df.iloc[i,0]).replace(" ", "")
            #self.quantity=self.df.iloc[i,1]
            self.AddEquity(self.security,Resolution.Minute).SetDataNormalizationMode(DataNormalizationMode.Raw)
            self.Debug(i)

            # DAY'S START BUY ACTION
            ################################################################################################################################  
            self.Schedule.On(self.DateRules.EveryDay(self.security), self.TimeRules.At(self.df.iloc[i,4], self.df.iloc[i,5]),Action(self.EveryDayAfterMarketOpen))
            
            # the problem is in the line of code above, I can't schedule the day's start buying action FOR THE SPECIFIC INSTRUMENT. Can't do something like
            
            # self.Schedule.On(self.DateRules.EveryDay("AAPL"), self.TimeRules.At(10, 30 ),Action(self.EveryDayAfterMarketOpen("AAPL"))
            # self.Schedule.On(self.DateRules.EveryDay("IBM"), self.TimeRules.At(9, 30 ),Action(self.EveryDayAfterMarketOpen("IBM"))
            
            # where I "reuse" EveryDayAfterMarketOpen every time passing a different financial instrument and making the buy action happen for the specific
            # intrument
        
            #DAY'S END LIQUIDATE SELL ACTION
            ##################################################################################################################################   
            self.Schedule.On(self.DateRules.EveryDay(self.security), self.TimeRules.At(self.df.iloc[i,6], self.df.iloc[i,7]),Action(self.SpecificTime))

        
        ############## SLIPPAGE & FEE MODEL####################################################################
            self.Securities[self.security].FeeModel = ConstantFeeModel(0)
            self.Securities[self.security].SlippageModel = ConstantSlippageModel(0)
        
    def EveryDayAfterMarketOpen(self):

        now = datetime.datetime.now()
        self.Debug(str(now.hour))# now.minute
        for i in range(len(self.df)) :
                if now.hour==self.df.iloc[i,4] and now.minute==self.df.iloc[i,5] :
                    self.MarketOrder(str(self.df.iloc[i,0]).replace(" ", ""),self.df.iloc[i,1])
                    self.AveragePrice = self.Portfolio[str(self.df.iloc[i,0]).replace(" ", "")].AveragePrice

    def SpecificTime(self):
        for i in range(len(self.df)) : # this for here would be useless if I had a method like self.Schedule.On(self.DateRules.EveryDay("IBM"), self.TimeRules.At(9, 30 ),Action(self.SpecificTime("IBM")) where I can link the execution time (in hours and minutes ) to the SPECIFIC STOCK
            self.Liquidate(str(self.df.iloc[i,0]).replace(" ", ""))

        
    
            
    ''' let's first solve the problem above of linking the buy and liquidate action to the proper financial instrument
    
        ## CODE TO TRIGGER STOP LOSSES AND TAKE PROFITS    
    def OnData(self, slice):
            if not slice.Bars.ContainsKey(self.security): return
        
            if self.AveragePrice != None :
                    if (slice[self.security].Price > self.AveragePrice * self.df.iloc[0,2]):
                        self.Liquidate(self.security," TAKE PROFIT @ " + str(slice[self.security].Price) +" AverageFillPrice " +str(self.AveragePrice))
                    if (slice[self.security].Price < self.AveragePrice * self.df.iloc[0,3]):
                        self.Liquidate(self.security," STOP LOSS @ " + str(slice[self.security].Price) +" AverageFillPrice " +str(self.AveragePrice))
    '''
    
    def OnData(self, slice):
        now = datetime.datetime.now()
        self.Debug(str(now.hour))# now.minute
        for i in range(len(self.df)) :
                if now.hour==self.df.iloc[i,4] and now.minute==self.df.iloc[i,5] :
                    self.MarketOrder(str(self.df.iloc[i,0]).replace(" ", ""),self.df.iloc[i,1])
                    self.AveragePrice = self.Portfolio[str(self.df.iloc[i,0]).replace(" ", "")].AveragePrice