Overall Statistics
Total Trades
33
Average Win
7.69%
Average Loss
-0.81%
Compounding Annual Return
142.308%
Drawdown
13.400%
Expectancy
6.835
Net Profit
142.897%
Sharpe Ratio
5.23
Probabilistic Sharpe Ratio
98.771%
Loss Rate
25%
Win Rate
75%
Profit-Loss Ratio
9.45
Alpha
1.338
Beta
0.306
Annual Standard Deviation
0.289
Annual Variance
0.084
Information Ratio
2.578
Tracking Error
0.365
Treynor Ratio
4.954
Total Fees
$144.13
class OnQQQ(QCAlgorithm):

    def Initialize(self):
        
        
        #self.MarketMinutes = int(self.GetParameter("mins"))
        self.RsiLowGap = int(self.GetParameter("rsiLow"))
        self.RsiHighGap = int(self.GetParameter("rsiHigh"))
        self.PpoGap = float(self.GetParameter("ppo"))
        self.SlopeGap = float(self.GetParameter("slope"))
        self.RsiGap = float(self.GetParameter("rsi"))
        
        self.RsiDays = int(self.GetParameter("rsiDays"))
        #self.SmaDays = int(self.GetParameter("smaDays"))
        self.SmaLongDays = int(self.GetParameter("smaLongDays"))
        self.SmaShortDays = int(self.GetParameter("smaShortDays"))
        self.PpoSlowDays = int(self.GetParameter("ppoSlowDays"))
        self.PpoFastDays = int(self.GetParameter("ppoFastDays"))
        
        self.StartYear = int(self.GetParameter("startYear"))
        self.EndYear = int(self.GetParameter("endYear"))
        self.Out= str(self.GetParameter("out"))
        self.MinDaysOut = int(self.GetParameter("daysOut"))
        
        self.Out="TLT"
        
        self.SetStartDate(self.StartYear, 1, 1)
        self.SetEndDate(self.EndYear,12,31)
        self.SetCash(100000)
        
        
        self.Debug(f"After Market Open. rsiLow:{self.RsiLowGap} rsiHigh:{self.RsiHighGap} ppo:{self.PpoGap} rsiDays:{self.RsiDays} smaLongDays:{self.SmaLongDays} smaShortDays:{self.SmaShortDays} ppoFastDays:{self.PpoFastDays} ppoSlowDays:{self.PpoSlowDays}")
 
 # ------------------------------------------- Defining Tickers and collection Indicators -----------------------------
        self.tickers = ["QQQ","TLT"]  # , "SQQQ","GLD","PSQ","SH","EMTY", "XLU","XLP","TBT","IEF"]
       
       
        self.TickerTable = {}
        
        for ticker in self.tickers:
            
            # --------- Add Equity
            self.AddEquity(ticker, Resolution.Hour)
            
            # --------- Add Equity indicators
            rsi = self.RSI(ticker, self.RsiDays, Resolution.Daily)
            smaLong = self.SMA(ticker, self.SmaLongDays, Resolution.Daily)
            smaShort = self.SMA(ticker, self.SmaShortDays, Resolution.Daily)
            rcShort = self.RC(ticker,self.SmaShortDays, Resolution.Daily)
            ppo = self.PPO(ticker, self.PpoFastDays, self.PpoSlowDays, MovingAverageType.Simple, Resolution.Daily)
            
            symbolData = SymbolData(ticker, rsi, smaLong, smaShort, rcShort, ppo)
            
            # --------- Update TickerTable
            self.TickerTable[ticker] = symbolData
            

        self.Schedule.On(self.DateRules.EveryDay("QQQ"),self.TimeRules.AfterMarketOpen("QQQ",0), self.Trade)
        self.Schedule.On(self.DateRules.EveryDay("QQQ"),self.TimeRules.AfterMarketOpen("QQQ",0), self.PlotIt)

 # ---------------------------------------------- New Benchmark plot ------------------------------------------------
        self.SetBenchmark("QQQ")
        # Variable to hold the last calculated benchmark value
        self.lastBenchmarkValue = None
        # Our inital benchmark value scaled to match our portfolio
        self.BenchmarkPerformance = self.Portfolio.TotalPortfolioValue
        
        self.QQQ_RSI = None 
        self.QQQ_PPO = None
        self.QQQ_SLOPE = None
        self.QQQ_BIG_SMA_WINDOW = None
        self.QQQ_SMALL_SMA_WINDOW = None

        self.MyQQQIndicator = 1 # Default Enter the Market
        self.DaysOut = 0        # Cooldown days after exiting the Market
        self.TotalDays =0       # Counter for total days
        self.TotalDaysIn = 0    # Counter for days in the MArket
        
        self.SetWarmUp(timedelta(days=45))

    # ------------------------------------------------- On Data -----------------------------------------------------
    def OnData(self, data):
        pass
        
        
    # ---------------------------------------------- Trade Function --------------------------------------------------
    def Trade(self):
        
        self.TotalDays +=1
        
        self.QQQ_RSI = self.TickerTable["QQQ"].Rsi.Current.Value
        self.QQQ_PPO = self.TickerTable["QQQ"].Ppo.Current.Value
        self.QQQ_BIG_SMA_WINDOW = self.TickerTable["QQQ"].SmaLong.Current.Value
        self.QQQ_SMALL_SMA_WINDOW = self.TickerTable["QQQ"].SmaShort.Current.Value
        self.QQQ_SLOPE = self.TickerTable["QQQ"].RcShort.Slope.Current.Value
        
        #self.Debug(f"{round(self.Time,2)}  QQQ RSI:{round(self.QQQ_RSI,2)}  PPO:{round(self.QQQ_PPO,2)}  QQQ_BIG_SMA_WINDOW:{round(QQQ_BIG_SMA_WINDOW,2)}  QQQ_SMALL_SMA_WINDOW:{round(QQQ_SMALL_SMA_WINDOW,2)}  Slope:{round(self.QQQ_SLOPE,2)}")
     
        #if self.QQQ_PPO >= self.PpoGap and self.QQQ_PPO <= 0.8:
        #if self.QQQ_SLOPE > self.SlopeGap:
        #if self.QQQ_RSI>20:
        
        if self.QQQ_PPO >= self.PpoGap and self.QQQ_SLOPE > self.SlopeGap and self.QQQ_RSI > self.RsiGap:  # ---- Be in the Market 
      
                if self.DaysOut >= self.MinDaysOut:
                    self.MyQQQIndicator = 1
                    self.DaysOut = 0
                else:
                    self.DaysOut +=1                                        # ---- Unless in Market out Cooldown
        else:                                                               
            self.MyQQQIndicator = 0
            self.DaysOut = 0                                            # Zero the DaysOut counter
        
            
        if self.MyQQQIndicator == 1:
            self.TotalDaysIn +=1
            if not self.Securities["QQQ"].Invested:
                self.SetHoldings("QQQ", 1.0, True)
                self.Notify.Sms("+972542224488", "QQQ In:" + str(self.Securities["QQQ"].Price))
        else:
             if not self.Securities[self.Out].Invested:
                self.SetHoldings(self.Out, 1.0, True)
                self.Notify.Sms("+972542224488", "QQQ Out:" + str(self.Securities["QQQ"].Price))
                
        
    
    def OnEndOfAlgorithm(self):
        self.Liquidate()
        if self.TotalDays>0:
            self.Debug(f"TPV:{round(self.Portfolio.TotalPortfolioValue,2)} Total Days:{self.TotalDays}  Total Days In:{self.TotalDaysIn} {round(self.TotalDaysIn/self.TotalDays*100,2)}%")
    
    # ---------------------------------------------- Plot Function --------------------------------------------------
    def PlotIt(self):    
        self.Plot("QQQ Indicator","InOut",self.MyQQQIndicator)
        bench = self.Securities["QQQ"].Close 
        if self.lastBenchmarkValue is not  None:
           self.BenchmarkPerformance = self.BenchmarkPerformance * (bench/self.lastBenchmarkValue)
        # store today's benchmark close price for use tomorrow
        self.lastBenchmarkValue = bench
        # make our plots
        self.Plot(" vs Benchmark", "Portfolio", self.Portfolio.TotalPortfolioValue)
        self.Plot(" vs Benchmark", "QQQ", self.BenchmarkPerformance)
        
        self.Plot("RSI","RSI",self.QQQ_RSI)
        self.Plot("PPO","PPO",self.QQQ_PPO)
        self.Plot("Slope","Slope",self.QQQ_SLOPE)

# ---------------------------------------------- SymbolData --------------------------------------------------
         
# symbolData = SymbolData(ticker, rsi, smaLong, smaShort, rcShort, ppo)
class SymbolData:
    def __init__(self, symbol, rsi, smaLong, smaShort, rcShort, ppo):
        self.Symbol = symbol
        self.Rsi = rsi
        #self.Sma = sma
        self.SmaLong = smaLong
        self.SmaShort = smaShort
        self.RcShort = rcShort
        self.Ppo = ppo