Overall Statistics |
Total Trades 2167 Average Win 0.72% Average Loss -0.73% Compounding Annual Return 10.620% Drawdown 25.500% Expectancy 0.238 Net Profit 550.864% Sharpe Ratio 0.899 Probabilistic Sharpe Ratio 26.258% Loss Rate 38% Win Rate 62% Profit-Loss Ratio 0.99 Alpha 0 Beta 0 Annual Standard Deviation 0.129 Annual Variance 0.017 Information Ratio 0.899 Tracking Error 0.129 Treynor Ratio 0 Total Fees $9614.23 |
# Pick 5 ETFs with strongest 3 month momentum into your portfolio and weight them equally. # Hold for 1 month and then rebalance at the satrt of a month # Why invalid orders in backtest # https://www.quantconnect.com/forum/discussion/10611/why-invalid-orders-in-backtest/p1 import pandas as pd from datetime import datetime class AssetClassMomentumAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2002, 7, 28) self.SetEndDate(datetime.now()) self.InitCash = 100000 self.SetCash(self.InitCash) self.MKT = self.AddEquity("SPY", Resolution.Hour).Symbol self.mkt = [] self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) # create a dictionary to store momentum indicators for all symbols self.data = {} period = int(3*21) # period of the momentum indicator is 3 months, average 21 business day for each month and 6.5 hours trading session self.symbols = ["SPY", "IWF", "QQQ", "IBB", "XLV", "EEM", "IWD", "TLT", "IEF", "IGOV", "GLD", "IYR", "DBC"] # warm up the MOM indicator self.SetWarmUp(period) for symbol in self.symbols: self.AddEquity(symbol, Resolution.Minute) if self.Securities[symbol].IsTradable == True: self.data[symbol] = self.MOM(symbol, period, Resolution.Daily) else: continue self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), self.Rebalance) def Rebalance(self): if self.IsWarmingUp: return for sec in self.data: if self.Securities[sec].IsTradable == False: self.data.remove(sec) top5 = pd.Series(self.data).sort_values(ascending = False)[:5] for sec in self.Portfolio.Keys: if sec not in top5.index: self.Liquidate(sec) for sec in top5.index: self.SetHoldings(sec, 1.0 / len(top5)) def OnEndOfDay(self): mkt_price = self.Securities[self.MKT].Close self.mkt.append(mkt_price) mkt_perf = self.InitCash * self.mkt[-1] / self.mkt[0] self.Plot('Strategy Equity', self.MKT, mkt_perf) account_leverage = self.Portfolio.TotalHoldingsValue / self.Portfolio.TotalPortfolioValue self.Plot('Holdings', 'leverage', round(account_leverage, 2)) self.Plot('Holdings', 'Target Leverage', 1)