Overall Statistics |
Total Orders
616
Average Win
1.27%
Average Loss
-1.51%
Compounding Annual Return
8.038%
Drawdown
46.300%
Expectancy
0.382
Start Equity
100000
End Equity
687590.10
Net Profit
587.590%
Sharpe Ratio
0.308
Sortino Ratio
0.295
Probabilistic Sharpe Ratio
0.053%
Loss Rate
25%
Win Rate
75%
Profit-Loss Ratio
0.84
Alpha
0.013
Beta
0.681
Annual Standard Deviation
0.139
Annual Variance
0.019
Information Ratio
-0.011
Tracking Error
0.102
Treynor Ratio
0.063
Total Fees
$3287.61
Estimated Strategy Capacity
$100000000.00
Lowest Capacity Asset
XLI RGRPZX100F39
Portfolio Turnover
1.15%
|
# https://quantpedia.com/strategies/sector-momentum-rotational-system/ # # Use ten sector ETFs. Pick 3 ETFs with the strongest 12-month momentum into your portfolio and weight them equally. Hold them for one month and then rebalance. #region imports from AlgorithmImports import * #endregion class SectorMomentumAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2000, 1, 1) self.SetCash(100000) # daily ROC data self.data:Dict[str, RateOfChange] = {} self.roc_period:int = 12 * 21 self.SetWarmUp(self.roc_period, Resolution.Daily) self.selected_symbol_count:int = 3 # long symbol count self.long_universe:List[str] = [ "VNQ", # Vanguard Real Estate Index Fund "XLK", # Technology Select Sector SPDR Fund "XLE", # Energy Select Sector SPDR Fund "XLV", # Health Care Select Sector SPDR Fund "XLF", # Financial Select Sector SPDR Fund "XLI", # Industrials Select Sector SPDR Fund "XLB", # Materials Select Sector SPDR Fund "XLY", # Consumer Discretionary Select Sector SPDR Fund "XLP", # Consumer Staples Select Sector SPDR Fund "XLU" # Utilities Select Sector SPDR Fund ] for ticker in self.long_universe: data = self.AddEquity(ticker, Resolution.Daily) data.SetLeverage(5) self.data[ticker] = self.ROC(ticker, self.roc_period, Resolution.Daily) self.data[self.long_universe[0]].Updated += self.OnROCUpdated self.recent_month:int = -1 self.rebalance_flag:bool = False def OnROCUpdated(self, sender, updated) -> None: # set rebalance flag if self.recent_month != self.Time.month: self.recent_month = self.Time.month self.rebalance_flag = True def OnData(self, data: Slice) -> None: if self.IsWarmingUp: return # rebalance once a month if self.rebalance_flag: self.rebalance_flag = False # sort long universe by momentum sorted_by_momentum:List = sorted([x for x in self.data.items() if x[1].IsReady and \ x[0] in self.long_universe and \ x[0] in data and data[x[0]]], \ key = lambda x: x[1].Current.Value, reverse = True) if len(sorted_by_momentum) < self.selected_symbol_count: self.Liquidate() return long:List[str] = [x[0] for x in sorted_by_momentum[:self.selected_symbol_count]] # trade execution invested:List[str] = [x.Key.Value for x in self.Portfolio if x.Value.Invested] for symbol in invested: if symbol not in long: self.Liquidate(symbol) for ticker in long: self.SetHoldings(ticker, 1 / len(long)) # Custom fee model class CustomFeeModel(FeeModel): def GetOrderFee(self, parameters): fee = parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.0 return OrderFee(CashAmount(fee, "USD"))