| Overall Statistics |
|
Total Orders 733 Average Win 1.25% Average Loss -1.52% Compounding Annual Return 11.723% Drawdown 53.900% Expectancy 0.330 Start Equity 100000 End Equity 680832.00 Net Profit 580.832% Sharpe Ratio 0.45 Sortino Ratio 0.475 Probabilistic Sharpe Ratio 0.917% Loss Rate 27% Win Rate 73% Profit-Loss Ratio 0.83 Alpha 0.017 Beta 0.977 Annual Standard Deviation 0.174 Annual Variance 0.03 Information Ratio 0.227 Tracking Error 0.069 Treynor Ratio 0.08 Total Fees $3562.82 Estimated Strategy Capacity $670000.00 Lowest Capacity Asset VAW SVS2QA8SPHET Portfolio Turnover 2.37% |
#region imports
from AlgorithmImports import *
#endregion
# https://quantpedia.com/Screener/Details/3
# Use 10 sector ETFs. Pick 3 ETFs with strongest 12 month momentum into your portfolio
# and weigh them equally. Hold for 1 month and then rebalance.
class SectorMomentumAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2007, 1, 1)
self.set_cash(100000)
# create a dictionary to store momentum indicators for all symbols
self._data = {}
period = 3*21
# choose ten sector ETFs
symbols = ["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
"KBE", # SPDR S&P Bank ETF
"VAW", # Vanguard Materials ETF
"XLY", # Consumer Discretionary Select Sector SPDR Fund
"XLP", # Consumer Staples Select Sector SPDR Fund
"VGT"] # Vanguard Information Technology ETF
# warm up the MOM indicator
self.set_warm_up(period)
for symbol in symbols:
self.add_equity(symbol, Resolution.DAILY)
self._data[symbol] = self.mom(symbol, period, Resolution.DAILY)
# shcedule the function to fire at the month start
self.schedule.on(self.date_rules.month_start("VNQ"), self.time_rules.after_market_open("VNQ"), self._rebalance)
def _rebalance(self):
if self.is_warming_up:
return
top3 = pd.Series(self._data).sort_values(ascending=False)[:3]
for symbol, security_hold in self.portfolio.items():
# liquidate the security which is no longer in the top3 momentum list
if security_hold.invested and (symbol.value not in top3.index):
self.liquidate(symbol)
for symbol in top3.index:
self.set_holdings(symbol, 1/len(top3))