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