| 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)