Overall Statistics
Total Trades
9
Average Win
18.08%
Average Loss
0%
Compounding Annual Return
50.642%
Drawdown
9.400%
Expectancy
0
Net Profit
111.737%
Sharpe Ratio
3.007
Probabilistic Sharpe Ratio
96.366%
Loss Rate
0%
Win Rate
100%
Profit-Loss Ratio
0
Alpha
0.341
Beta
0.372
Annual Standard Deviation
0.176
Annual Variance
0.031
Information Ratio
0.092
Tracking Error
0.229
Treynor Ratio
1.426
Total Fees
$26.26
Estimated Strategy Capacity
$49000000.00
Lowest Capacity Asset
QQQ RIWIV7K5Z9LX
class AJ_LowRisk1(QCAlgorithm):
    
   

    def Initialize(self):
        self.SetStartDate(2019, 10, 1)
        self.SetEndDate(2021,7,30)
        self.SetCash(100000)
        
        self.SetTimeZone("America/New_York")
        
        equity = self.AddEquity("QQQ", Resolution.Minute)
        
        self._qqq = equity.Symbol
        
        self.Consolidate(self._qqq, Resolution.Daily, self.DailyBarHandler)
        
        self.window = RollingWindow[TradeBar](2) 
        
        self._holdings = equity.Holdings
        
        #equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
        #equity.SetLeverage(1.0)
        
        self.SetBenchmark("QQQ")
        
        self._rc = self.RC("QQQ", 15, 3.0, Resolution.Daily)
        
        self._rc.Updated += self.RcUpdated
        self._rcwindow = RollingWindow[IndicatorDataPoint](2)
        
        
        self._momp = self.MOMP("QQQ", 2, Resolution.Daily)
        self._momp_values = []
        self._momp_stddev = StandardDeviation(510)
        self._momp.Updated += self.OnAdUpdated
        
        self._ema8 = self.EMA("QQQ", 8, Resolution.Daily)
        self._ema21 = self.EMA("QQQ", 21, Resolution.Daily)
        
        self.SetWarmUp(510, Resolution.Daily)
        
        stockPlot = Chart("Trade Plot")
        stockPlot.AddSeries(Series("Buy", SeriesType.Scatter, 0))
        stockPlot.AddSeries(Series("Sell", SeriesType.Scatter, 0))
        stockPlot.AddSeries(Series("UpperChannel", SeriesType.Line, 0))
        stockPlot.AddSeries(Series("LowerChannel", SeriesType.Line, 0))
        stockPlot.AddSeries(Series("Regression", SeriesType.Line, 0))
        stockPlot.AddSeries(Series("Value", SeriesType.Line, 0))
        self.AddChart(stockPlot)
        
        self.initial = 0
     
        #self._time = datetime.strptime("2019-10-01 00:00:00", "%Y-%m-%d %H:%M:%S")
        self._time = self.Time
        
    def RcUpdated(self, sender, updated):
        '''Adds updated values to rolling window'''
        self._rcwindow.Add(updated)

    def OnData(self, data):
        
        
        if (not self._rc.IsReady) or (not data.ContainsKey(self._qqq)) or (not self._momp_stddev.IsReady): return
        if data[self._qqq] is None: return
        value = data[self._qqq].Value
        
        self.window.Add(data["QQQ"])
    
        if not self.window.IsReady or not self._rcwindow.IsReady: return
        
        pastBar = self.window[0]
        pastRc = self._rcwindow[1]
        nowRc = self._rcwindow[0]
        
        #self.Debug(str(self.initial))
        
        #if (self.Time.hour > 12) and (not self.Portfolio.Invested) and (self.initial == 0):
        if (not self.Portfolio.Invested) and (self.initial == 0):
            self.SetHoldings(self._qqq, 1)
            #self.Debug("Price of QQQ Shares: " + str(self.Portfolio["QQQ"].AveragePrice))
            #self.Debug("Number of QQQ Shares: " + str(self.Portfolio["QQQ"].Quantity))
            #self.Debug(str(self.Time))
            self.initial = 1
         

        if (not (self.Time - self._time).days < 1) and (self._holdings.Quantity > 0) and (pastBar.Close < self._rc.LinearRegression.Current.Value * (100 - 2.5 * self._momp_stddev.Current.Value)/100):
            self.Liquidate(self._qqq)
            self._time = self.Time 
            
            
        if (not (self.Time - self._time).days < 1) and (self._holdings.Quantity <= 0) and (pastBar.Close > self._rc.LinearRegression.Current.Value * (100 - 2.5 * self._momp_stddev.Current.Value)/100) and (self._ema8.Current.Value > self._ema21.Current.Value) and (nowRc > pastRc):
            self.SetHoldings(self._qqq, 1)
           
            #self.Debug("Price of QQQ Shares: " + str(self.Portfolio["QQQ"].AveragePrice))
            #self.Debug("Number of QQQ Shares: " + str(self.Portfolio["QQQ"].Quantity))
            #self.Debug(str(self.Time))
        
        #self.Debug("RC: " + str(self._rc.LinearRegression.Current.Value))
        
       
    """    
        self.Plot('Trade Plot', 'Price', pastBar.Open)
        self.Plot("Trade Plot", "UpperChannel", self._rc.LinearRegression.Current.Value * (100 + 1 * self._momp_stddev.Current.Value)/100)
        self.Plot("Trade Plot", "LowerChannel", self._rc.LinearRegression.Current.Value * (100 - 1 * self._momp_stddev.Current.Value)/100)
        self.Plot("Trade Plot", "Regression", self._rc.LinearRegression.Current.Value)
    """
    
    """    
    def OnEndOfDay(self, symbol):
        self.Plot("Trade Plot", "UpperChannel", self._rc.LinearRegression.Current.Value * (100 + 1 * self._momp_stddev.Current.Value)/100)
        self.Plot("Trade Plot", "LowerChannel", self._rc.LinearRegression.Current.Value * (100 - 1 * self._momp_stddev.Current.Value)/100)
        self.Plot("Trade Plot", "Regression", self._rc.LinearRegression.Current.Value)
    """
    
    def OnAdUpdated(self, _momp, current):
        if _momp.IsReady:
            self._momp_stddev.Update(current.EndTime, current.Value)
            self._momp_values.append(self._momp.Current.Value) 
      
    def DailyBarHandler(self, consolidated):
        if self.Time > datetime.strptime("2019-10-01 00:00:00", "%Y-%m-%d %H:%M:%S"):
            self.Plot("Trade Plot", "Price", consolidated.Close)
            self.Plot("Trade Plot", "UpperChannel", self._rc.LinearRegression.Current.Value * (100 + 2.5 * self._momp_stddev.Current.Value)/100)
            self.Plot("Trade Plot", "LowerChannel", self._rc.LinearRegression.Current.Value * (100 - 2.5 * self._momp_stddev.Current.Value)/100)
            self.Plot("Trade Plot", "Regression", self._rc.LinearRegression.Current.Value)