Overall Statistics |
Total Trades 343 Average Win 2.96% Average Loss -0.76% Compounding Annual Return 34.822% Drawdown 14.500% Expectancy 2.519 Net Profit 2055.308% Sharpe Ratio 1.683 Probabilistic Sharpe Ratio 97.225% Loss Rate 28% Win Rate 72% Profit-Loss Ratio 3.89 Alpha 0.213 Beta 0.255 Annual Standard Deviation 0.144 Annual Variance 0.021 Information Ratio 0.744 Tracking Error 0.172 Treynor Ratio 0.95 Total Fees $1715.00 Estimated Strategy Capacity $0 Lowest Capacity Asset SPDN.SPDN 2S |
class AccelDualMomentum(QCAlgorithm): def Initialize(self): self.SetStartDate(2012, 1, 1) # Set Start Date #self.SetEndDate(2022,2,28) # Set End Date self.SetCash(10000) # Set Strategy Cash res = Resolution.Minute #self.QQQ = self.AddEquity('QQQ', res).Symbol #self.EEM = self.AddEquity('EEM', res).Symbol #self.TLT = self.AddEquity('TLT', res).Symbol #self.SPDN = self.AddEquity('SPDN', res).Symbol #self.IEF = self.AddEquity('IEF', res).Symbol self.QQQ = self.AddData(QQQ, "QQQ", Resolution.Daily).Symbol self.VEU = self.AddData(VEU, "VEU", Resolution.Daily).Symbol self.TLT = self.AddData(TLT, "TLT", Resolution.Daily).Symbol self.SPDN = self.AddData(SPDN, "SPDN", Resolution.Daily).Symbol self.IEF = self.AddData(IEF, "IEF", Resolution.Daily).Symbol self.indicator = self.AddData(MOMENTUM, "MOMENTUM", Resolution.Daily).Symbol self.leverage = 1 # Set leverage | A value of 1 indicates no leverage | A value of 2 indicates 100% leverage self.Securities["QQQ"].SetLeverage(self.leverage) self.Securities["VEU"].SetLeverage(self.leverage) self.Securities["TLT"].SetLeverage(self.leverage) self.Securities["SPDN"].SetLeverage(self.leverage) self.Securities["IEF"].SetLeverage(self.leverage) # Set trading frequency self.monthly = 0 self.annual = 0 self.daily = 1 self.trading_fee = 5 # Fee per trade self.trading_day = 21 # Set trading day | Value = 21 is last trading day of month self.GetParameter("trading_day") self.SetWarmUp(timedelta(126)) def shiftAssets(self, target): if not (self.Portfolio[target].Invested): for symbol in self.Portfolio.Keys: self.Liquidate(symbol) if not self.Portfolio.Invested: self.SetHoldings(target, 1*self.leverage) def getMonthTradingDay(self): month_last_day = DateTime(self.Time.year, self.Time.month, DateTime.DaysInMonth(self.Time.year, self.Time.month)) tradingDays = self.TradingCalendar.GetDaysByType(TradingDayType.BusinessDay, DateTime(self.Time.year, self.Time.month, 1), month_last_day) tradingDays = [day.Date.date() for day in tradingDays] return tradingDays[-22 + self.trading_day] def getYearLastTradingDay(self): year_last_day = DateTime(self.Time.year, 12, DateTime.DaysInMonth(self.Time.year, 12)) tradingDays = self.TradingCalendar.GetDaysByType(TradingDayType.BusinessDay, DateTime(self.Time.year, 12, 1), year_last_day) tradingDays = [day.Date.date() for day in tradingDays] return tradingDays [-1] def OnData(self, data): if self.IsWarmingUp: return if (self.daily ==1): if data.ContainsKey(self.indicator): ticker = data[self.indicator].GetProperty('Indicator') if (ticker =="VEU"): self.Securities["VEU"].SetFeeModel(MonthlyCustomFeeModel()) #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen('QQQ', 120), self.shiftAssets(self.EEM)) self.shiftAssets(self.VEU) elif (ticker =="QQQ"): self.Securities["QQQ"].SetFeeModel(MonthlyCustomFeeModel()) #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen('QQQ', 120), self.shiftAssets(self.QQQ)) self.shiftAssets(self.QQQ) elif (ticker =="TLT"): self.Securities["TLT"].SetFeeModel(MonthlyCustomFeeModel()) #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen('QQQ', 120), self.shiftAssets(self.TLT)) self.shiftAssets(self.TLT) elif (ticker =="IEF"): self.Securities["IEF"].SetFeeModel(MonthlyCustomFeeModel()) #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen('QQQ', 120), self.shiftAssets(self.IEF)) self.shiftAssets(self.IEF) elif (ticker =="SPDN"): self.Securities["SPDN"].SetFeeModel(MonthlyCustomFeeModel()) #self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen('QQQ', 120), self.shiftAssets(self.SPDN)) self.shiftAssets(self.SPDN) # Charts self.Plot("Margin", "Remaining", self.Portfolio.MarginRemaining) self.Plot("Margin", "Used", self.Portfolio.TotalMarginUsed) self.Plot("Cash", "Remaining", self.Portfolio.Cash) self.Plot("Cash", "Remaining", self.Portfolio.TotalHoldingsValue) self.Plot("QQQ", "Held", self.Portfolio["QQQ"].Quantity) self.Plot("VEU", "Held", self.Portfolio["VEU"].Quantity) self.Plot("TLT", "Held", self.Portfolio["TLT"].Quantity) self.Plot("IEF", "Held", self.Portfolio["IEF"].Quantity) self.Plot("SPDN", "Held", self.Portfolio["SPDN"].Quantity) class QQQ(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("https://www.dropbox.com/s/vdn8trsn76505lz/QQQ.csv?dl=1", SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLive): if not (line.strip() and line[0].isdigit()): return None index = QQQ() index.Symbol = config.Symbol data = line.split(',') index.Time = datetime.strptime(data[0], "%Y-%m-%d") index.EndTime = index.Time + timedelta(days=1) index.Value = data[4] index["Open"] = float(data[1]) index["High"] = float(data[2]) index["Low"] = float(data[3]) index["Close"] = float(data[4]) index["Adj Close"] = float(data[5]) return index class EEM(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("https://www.dropbox.com/s/afucxcoaejhk0fu/EEM.csv?dl=1", SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLive): if not (line.strip() and line[0].isdigit()): return None index = EEM() index.Symbol = config.Symbol data = line.split(',') index.Time = datetime.strptime(data[0], "%Y-%m-%d") index.EndTime = index.Time + timedelta(days=1) index.Value = data[4] index["Open"] = float(data[1]) index["High"] = float(data[2]) index["Low"] = float(data[3]) index["Close"] = float(data[4]) index["Adj Close"] = float(data[5]) return index class TLT(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("https://www.dropbox.com/s/9zhb9ec9s9pqulc/TLT.csv?dl=1", SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLive): if not (line.strip() and line[0].isdigit()): return None index = TLT() index.Symbol = config.Symbol data = line.split(',') index.Time = datetime.strptime(data[0], "%Y-%m-%d") index.EndTime = index.Time + timedelta(days=1) index.Value = data[4] index["Open"] = float(data[1]) index["High"] = float(data[2]) index["Low"] = float(data[3]) index["Close"] = float(data[4]) index["Adj Close"] = float(data[5]) return index class SPDN(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("https://www.dropbox.com/s/slxq8xtarpq50rq/SPDN.csv?dl=1", SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLive): if not (line.strip() and line[0].isdigit()): return None index = SPDN() index.Symbol = config.Symbol data = line.split(',') index.Time = datetime.strptime(data[0], "%Y-%m-%d") index.EndTime = index.Time + timedelta(days=1) index.Value = data[4] index["Open"] = float(data[1]) index["High"] = float(data[2]) index["Low"] = float(data[3]) index["Close"] = float(data[4]) index["Adj Close"] = float(data[5]) return index class IEF(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("https://www.dropbox.com/s/fvnu9zai31g5plg/IEF.csv?dl=1", SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLive): if not (line.strip() and line[0].isdigit()): return None index = IEF() index.Symbol = config.Symbol data = line.split(',') index.Time = datetime.strptime(data[0], "%Y-%m-%d") index.EndTime = index.Time + timedelta(days=1) index.Value = data[4] index["Open"] = float(data[1]) index["High"] = float(data[2]) index["Low"] = float(data[3]) index["Close"] = float(data[4]) index["Adj Close"] = float(data[5]) return index class VINEX(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("https://www.dropbox.com/s/3otgob32pyl0hz8/VINEX.csv?dl=1", SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLive): if not (line.strip() and line[0].isdigit()): return None index = VINEX() index.Symbol = config.Symbol data = line.split(',') index.Time = datetime.strptime(data[0], "%d/%m/%Y") index.EndTime = index.Time + timedelta(days=1) index.Value = data[4] index["Open"] = float(data[1]) index["High"] = float(data[2]) index["Low"] = float(data[3]) index["Close"] = float(data[4]) return index class VEU(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("https://www.dropbox.com/s/b0ywadvwclo2xyd/VEU.csv?dl=1", SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLive): if not (line.strip() and line[0].isdigit()): return None index = VEU() index.Symbol = config.Symbol data = line.split(',') index.Time = datetime.strptime(data[0], "%Y-%m-%d") index.EndTime = index.Time + timedelta(days=1) index.Value = data[4] index["Open"] = float(data[1]) index["High"] = float(data[2]) index["Low"] = float(data[3]) index["Close"] = float(data[4]) return index class MOMENTUM(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("https://www.dropbox.com/s/c7dh6xdc55i9mmq/Indicator_SHY_XLI_with%20VEU.csv?dl=1", SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLive): if not (line.strip() and line[0].isdigit()): return None index = MOMENTUM() index.Symbol = config.Symbol data = line.split(',') index.Time = datetime.strptime(data[0], "%Y-%m-%d") index.EndTime = index.Time + timedelta(days=1) index.SetProperty("Indicator", str(data[1])) return index class MonthlyCustomFeeModel: def GetOrderFee(self, parameters): self.margin_rate = 0.0 #Set Margin Fee self.trading_fee = 5 #Set fee per trade fee = self.trading_fee + (parameters.Security.Leverage-1)*parameters.Security.Price*parameters.Order.AbsoluteQuantity*(self.margin_rate/12) return OrderFee(CashAmount(fee, 'USD'))