Overall Statistics |
Total Trades 461 Average Win 1.68% Average Loss -0.51% Compounding Annual Return 8.031% Drawdown 19.100% Expectancy 1.238 Net Profit 416.897% Sharpe Ratio 0.724 Probabilistic Sharpe Ratio 6.423% Loss Rate 48% Win Rate 52% Profit-Loss Ratio 3.31 Alpha 0.07 Beta 0.01 Annual Standard Deviation 0.098 Annual Variance 0.01 Information Ratio -0.008 Tracking Error 0.201 Treynor Ratio 6.77 Total Fees $461.37 Estimated Strategy Capacity $29000000.00 |
class SectorAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2000, 1, 1) self.SetCash(10000) self.Settings.FreePortfolioValuePercentage = 0.05 # Daily indicator data. self.s_indicators = {} self.b_indicators = {} self.period = 200 self.sectors_in = 0 self.SetWarmUp(self.period) self.sectors = [ "XRLE", # Real Estate SPDR 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 #"XLC", # Communication Services SPDR Fund ] self.bonds = ["TLT", # iShares 20 Plus Year Treasury Bond ETF ] self.SetBenchmark('SPY') self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) for sector in self.sectors: symbol = self.AddEquity(sector, Resolution.Daily).Symbol self.s_indicators[symbol] = SymbolData(self, symbol, self.period) for bond in self.bonds: symbol = self.AddEquity(bond, Resolution.Daily).Symbol self.b_indicators[symbol] = SymbolData(self, symbol, self.period) self.plot_allocation = Chart('Allocation') self.Schedule.On(self.DateRules.MonthStart(self.sectors[0]), self.TimeRules.AfterMarketOpen(self.sectors[0]), self.Rebalance) #self.Schedule.On(self.DateRules.WeekStart(self.sectors[0]), self.TimeRules.AfterMarketOpen(self.sectors[0]), self.Rebalance) self.Schedule.On(self.DateRules.EveryDay(self.sectors[0]), self.TimeRules.BeforeMarketClose(self.sectors[0], 1), self.PlotData) def Rebalance(self): n_sectors = len(self.sectors) n_bonds = len(self.bonds) in_out_sectors = 0 # Sectors ETF for sector in self.s_indicators: if self.s_indicators[sector].sell: if self.Portfolio[sector].Invested: in_out_sectors -= 1 # Sell sector ETF self.Liquidate(sector) if self.s_indicators[sector].buy: if not self.Portfolio[sector].Invested: in_out_sectors += 1 # Buy sector ETF self.SetHoldings(sector, 1 / n_sectors) # Update number of long ETF self.sectors_in = self.sectors_in + in_out_sectors # Bonds for bond in self.b_indicators: # Sell bonds if self.b_indicators[bond].sell and self.Portfolio[bond].Invested: # Sell bonds self.Liquidate(bond) # if bond pct must change, adjust the size of position if in_out_sectors: if self.b_indicators[bond].buy: # New size bond_pct = ((n_sectors - self.sectors_in) / n_sectors) / n_bonds self.SetHoldings(bond, bond_pct) def PlotData(self): cash = self.Portfolio.Cash + self.Portfolio.UnsettledCash sectors_allocation = 0 for sector in self.s_indicators: sectors_allocation += self.Portfolio[sector].Price * self.Portfolio[sector].Quantity bonds_allocation = 0 for bond in self.b_indicators: bonds_allocation += self.Portfolio[sector].Price * self.Portfolio[sector].Quantity self.Plot("Allocation", "Cash", cash/self.Portfolio.TotalPortfolioValue * 100) self.Plot("Allocation", "Sectors", sectors_allocation/self.Portfolio.TotalPortfolioValue * 100) self.Plot("Allocation", "Bonds", bonds_allocation/self.Portfolio.TotalPortfolioValue * 100) self.Plot("Sectors", "IN", self.sectors_in) class SymbolData(object): def __init__(self, algo, symbol, period): self.algo = algo self.symbol = symbol self.slow_ema = ExponentialMovingAverage(period) self.fast_ema = ExponentialMovingAverage(int(period/10)) algo.RegisterIndicator(symbol.Value, self.slow_ema, Resolution.Daily) algo.RegisterIndicator(symbol.Value, self.fast_ema, Resolution.Daily) @property def buy2(self): if self.slow_ema.IsReady: price = self.algo.Securities[self.symbol].Close indicator = self.slow_ema.Current.Value if price > indicator: return True else: return False else: None @property def buy(self): if self.slow_ema.IsReady and self.fast_ema.IsReady: slow = self.slow_ema.Current.Value #fast = self.fast_ema.Current.Value fast = self.algo.Securities[self.symbol].Close if fast > slow: return True else: return False else: None @property def sell(self): return not self.buy