Overall Statistics
# # FullRSI algorithm according to alpha framework
# class SelectionData(object):
#     def __init__(self, symbol, period):
#         self.symbol = symbol
#         self.indicator = RelativeStrengthIndex(self.symbol, self.period)
#         self.volume = 0

#     def update(self, time, price, volume):
#         self.volume = volume
#         if self.ema.Update(time, price):
#             self.is_above_ema = price > ema


# class FullRSI(QCAlgorithm):

#     def Initialize(self):
        
#         # Likely Don't Change
#         self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
#         self.SetCash(100000)  # Set Strategy Cash
#         self.SetLeverage(1.0)
        
#         # Maybe Change
#         self.SetStartDate(2000, 1, 1)  # Set Start Date
#         self.SetWarmUp(20)
#         self.SetBenchmark("SPY")

#         # self.AddEquity(self.equity_str, Resolution.Daily)
#         self.rsi = self.RSI(self.equity_str, 14)
        
       
#         # Personal additions
#         self.equity_list = ["SPY"]
#         self.manual_equity_universe()
#         self.PorfolioPercentages = self.portfolio_percentages()
                
#     @property
#     def portfolio_percentages(self):
#         """
#         Keeps a record of portfolio percentages in portfolio
#         """
#         percentages = {}
#         for keys in self.Securities:
#             percentages[key] = 0.0
#         return percentages
        
#     def manual_equity_universe(self):
#         self.UniverseSettings.Resolution = resolution.Daily
#         self.UniverseSettings.Leverage = 1
#         symbols = [Symbol.Create(e, SecurityType.Equity, Market.USA) for e in self.equity_list]
#         self.AddUniverseSelection(ManualUniverseSelectionModel(symbols))
        
#     def OnData(self, data):
#         if not self.rsi.IsReady: 
#             return
        
#         order_proportion = 0.1
        
#         if self.rsi.Current.Value < 30:
#             self.SetHoldings(self.PortfolioPercentages[])
#             self.Debug(f"RSI is at {self.rsi}")
#             marketTicket = self.MarketOrder("SPY", quantity)
            
#         elif self.rsi.Current.Value > 70:
#             self.Debug(f"RSI is at {self.rsi}")
#             marketTicket = self.MarketOrder("SPY", -100)
    
                
#     def OnEndOfDay(self):
#         self.Plot("Indicators","RSI", self.rsi.Current.Value)
        
#     def OnOrderEvent(self, OrderEvent):
        
#         # On Order Fill
#         order = self.Transactions.GetOrderById(OrderEvent.OrderId)
#         self.Debug("OrderT {} . Symbol: {}, Direction: {}, Fee: {}, Quantity: {}, Fill_Price: {}".format(
#             order.Id,
#             order.Symbol,
#             OrderEvent.Direction,
#             OrderEvent.Fee,
#             OrderEvent.FillQuantity,
#             OrderEvent.FillPrice
#         ))
#         self.Plot('')
from System.Drawing import Color

# simple RSI trading SPY 
class SimpleRSI(QCAlgorithm):

    def Initialize(self):
        
        # Likely Don't Change
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
        self.SetCash(100000)  # Set Strategy Cash

        # Maybe Change
        self.SetStartDate(2009, 1, 1)  # Set Start Date
        self.SetEndDate(2012, 1, 1)
        self.SetWarmUp(20)
        self.equity_str = "AAPL"
        self.SetBenchmark(self.equity_str)
        
        # Personal additions
        self.AddEquity(self.equity_str,Resolution.Hour)
        self.portfolio_percentages = {self.equity_str: 0.0}
             
        # self.AddEquity(self.equity_str, Resolution.Daily)
        self.rsi = self.RSI(self.equity_str, 14)
        
        # Charting
        rsi_plot = Chart('Indicators')
        # On the Trade Plotter Chart we want 3 series: trades and price:
        rsi_plot.AddSeries(Series('RSI', SeriesType.Line, "",  Color.DeepSkyBlue))
        rsi_plot.AddSeries(Series('Upper', SeriesType.Line, "", Color.LightGray))
        rsi_plot.AddSeries(Series('Lower', SeriesType.Line, "",  Color.LightGray))
        self.AddChart(rsi_plot)
        
        order_plot = Chart('Orders')
        order_plot.AddSeries(Series('Buy', SeriesType.Scatter, "", Color.Blue, ScatterMarkerSymbol.Triangle))
        order_plot.AddSeries(Series('Sell', SeriesType.Scatter, "", Color.Black, ScatterMarkerSymbol.TriangleDown))
        self.candles = Series('Equity', SeriesType.Candle, "$",  Color.DeepSkyBlue)
        order_plot.AddSeries(self.candles)
        self.AddChart(order_plot)
        
        
        # self.candles = Series('Daily', SeriesType.Candle)
        # self.chart = Chart('Candles')
        # self.chart.AddSeries(self.candles)
        # self.AddChart(self.chart)
        
    def OnData(self, data):
        if not self.rsi.IsReady: 
            return
        
        self.Debug("Symbol: {}, Quantity: {}, AvgPrice: {:.2F}, MktPrice: {:.2F}, Holding P/L {:.2F}, Holding P/L % {:.2F}, RSI: {:.2F}, portfolio percentage: {}".format(
            self.Portfolio[self.equity_str].Symbol,
            self.Portfolio[self.equity_str].Quantity,
            self.Portfolio[self.equity_str].AveragePrice,
            self.Portfolio[self.equity_str].Price,
            self.Portfolio[self.equity_str].UnrealizedProfit,
            self.Portfolio[self.equity_str].UnrealizedProfitPercent * 100,
            self.rsi.Current.Value,
            self.portfolio_percentages[self.equity_str]
            )
        )
        time = self.UtcTime
        
        if data[self.equity_str] is not None:
            
            # NOTE: order is important and each point has to be one minute apart because reasons.
            self.candles.AddPoint(time + timedelta(minutes=1), data[self.equity_str].Open)
            self.candles.AddPoint(time + timedelta(minutes=2), data[self.equity_str].High)
            self.candles.AddPoint(time + timedelta(minutes=3), data[self.equity_str].Low)
            self.candles.AddPoint(time + timedelta(minutes=4), data[self.equity_str].Close)
        else: 
            print(f'Candlestick was not plotted for {time}')
        order_proportion = 0.05
        
        if self.rsi.Current.Value < 30:
            if self.portfolio_percentages[self.equity_str] < 0.91:
                self.portfolio_percentages[self.equity_str] += order_proportion
                self.SetHoldings(self.equity_str, self.portfolio_percentages[self.equity_str])
            else:
                self.Debug('Maximum Leverage reached')
                
        elif self.rsi.Current.Value > 70:
            if self.portfolio_percentages[self.equity_str] > -0.91:
                self.portfolio_percentages[self.equity_str] -= order_proportion
                self.SetHoldings(self.equity_str, self.portfolio_percentages[self.equity_str])
            else:
                self.Debug('Maximum Leverage reached')
            
                
    def OnEndOfDay(self):
        # Plot RSI chart
        self.Plot("Indicators", "RSI", self.rsi.Current.Value)
        self.Plot("Indicators","Upper", 70)
        self.Plot("Indicators","Lower", 30)
        
        # Plot Orders chart
        # self.Plot("Orders", self.equity_str, self.Portfolio[self.equity_str].Price)
        
    def OnOrderEvent(self, OrderEvent):
        # On Order Fill
        if OrderEvent.Status == OrderStatus.Filled:
            order = self.Transactions.GetOrderById(OrderEvent.OrderId)
            self.Debug("Order {} . Symbol: {}, Direction: {}, Fee: {}, Quantity: {}, Fill_Price: {}".format(
                order.Id,
                order.Symbol,
                OrderEvent.Direction,
                OrderEvent.OrderFee,
                OrderEvent.FillQuantity,
                OrderEvent.FillPrice
                )
            )
            
            if OrderEvent.Direction == 1:
                self.Plot("Orders", "Sell", OrderEvent.FillPrice)
            elif OrderEvent.Direction == 0:
                self.Plot("Orders", "Buy", OrderEvent.FillPrice)
# # simple RSI trading SPY 
# class SimpleRSI(QCAlgorithm):

#     def Initialize(self):
        
#         # Likely Don't Change
#         self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
#         self.SetCash(100000)  # Set Strategy Cash
        
#         # Maybe Change
#         self.SetStartDate(2000, 1, 1)  # Set Start Date
#         self.SetWarmUp(20)
#         self.SetBenchmark("SPY")

#         # self.AddEquity(self.equity_str, Resolution.Daily)
#         self.rsi = self.RSI("SPY", 14)
       
#         # Personal additions
#         self.equity_list = ["SPY"]
#         self.AddEquity("SPY",Resolution.Daily)
#         self.PorfolioPercentages = self.portfolio_percentages()
                
#     @property
#     def portfolio_percentages(self):
#         """
#         Keeps a record of portfolio percentages in portfolio
#         """
#         percentages = {}
#         for keys in self.Securities:
#             percentages[key] = 0.0
#         return percentages
        
#     def OnData(self, data):
#         if not self.rsi.IsReady: 
#             return
        
#         order_proportion = 0.1
        
#         if self.rsi.Current.Value < 30:
#             if self.PortfolioPercentages < 0.91:
#                 self.PortfolioPercentages["SPY"] + 0.1
#                 self.SetHoldings(self.PortfolioPercentages["SPY"])
#                 self.Debug(f"RSI is at {self.rsi}")
            
#             else:
#                 self.Debug('Maximum Leverage reached')
                
#         elif self.rsi.Current.Value > 70:
#             if self.PortfolioPercentages > -0.91:
#                 self.PortfolioPercentages["SPY"] - 0.1
#                 self.SetHoldings(self.PortfolioPercentages["SPY"])
#                 self.Debug(f"RSI is at {self.rsi}")
        
#             else:
#                 self.Debug('Maximum Leverage reached')
                
                
#     def OnEndOfDay(self):
#         self.Plot("Indicators","RSI", self.rsi.Current.Value)
        
#     def OnOrderEvent(self, OrderEvent):
        
#         # On Order Fill
#         order = self.Transactions.GetOrderById(OrderEvent.OrderId)
#         self.Debug("OrderT {} . Symbol: {}, Direction: {}, Fee: {}, Quantity: {}, Fill_Price: {}".format(
#             order.Id,
#             order.Symbol,
#             OrderEvent.Direction,
#             OrderEvent.Fee,
#             OrderEvent.FillQuantity,
#             OrderEvent.FillPrice
#         ))
#         self.Plot('')