| Overall Statistics |
|
Total Orders 1199 Average Win 3.18% Average Loss -1.36% Compounding Annual Return 55.505% Drawdown 29.200% Expectancy 0.836 Start Equity 5000 End Equity 2608036.70 Net Profit 52060.734% Sharpe Ratio 1.529 Sortino Ratio 2.068 Probabilistic Sharpe Ratio 97.515% Loss Rate 45% Win Rate 55% Profit-Loss Ratio 2.35 Alpha 0.315 Beta 0.73 Annual Standard Deviation 0.247 Annual Variance 0.061 Information Ratio 1.285 Tracking Error 0.227 Treynor Ratio 0.516 Total Fees $28588.95 Estimated Strategy Capacity $93000000.00 Lowest Capacity Asset XLU RGRPZX100F39 Portfolio Turnover 22.54% |
from AlgorithmImports import *
class RSIRebalanceStrategy(QCAlgorithm):
def Initialize(self):
self.set_start_date(2011, 1, 1)
self.set_cash(5000)
self.settings.free_portfolio_value_percentage = 0.01
self.set_warmup(timedelta(days=250))
self.qqq = self.add_equity("QQQ", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW).Symbol
self.qld = self.add_equity("TQQQ", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW).Symbol
self.spy = self.add_equity("SPY", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW).Symbol
self.itot = self.add_equity("VT", Resolution.DAILY, data_normalization_mode=DataNormalizationMode.RAW).Symbol
self.xlp = self.add_equity("XLP", Resolution.DAILY).Symbol
self.xlu = self.add_equity("XLU", Resolution.DAILY).Symbol
self.bil = self.add_equity("BIL", Resolution.DAILY).Symbol
self.vixy = self.add_equity("UVXY", Resolution.DAILY).Symbol
self.qqq_rsi = self.rsi(self.qqq, 10)
self.spy_sma_200 = self.sma(self.spy, 200)
self.spy_sma_30 = self.sma(self.spy, 30)
self.schedule.on(self.date_rules.every_day(), self.time_rules.before_market_close(self.spy, 10), self.Rebalance)
# self.schedule.on(self.date_rules.week_end(), self.time_rules.after_market_close(self.spy, 0), self.add_cash)
def add_cash(self):
self.portfolio.cash_book["USD"].add_amount(100)
def RSI2(self,equity,period):
extension = min(period*5,250)
r_w = RollingWindow[float](extension)
history = self.history(equity,extension - 1,Resolution.DAILY)
for historical_bar in history:
r_w.add(historical_bar.close)
while r_w.count < extension:
current_price = self.securities[equity].price
r_w.add(current_price)
if r_w.is_ready:
average_gain = 0
average_loss = 0
gain = 0
loss = 0
for i in range(extension - 1,extension - period -1,-1):
gain += max(r_w[i-1] - r_w[i],0)
loss += abs(min(r_w[i-1] - r_w[i],0))
average_gain = gain/period
average_loss = loss/period
for i in range(extension - period - 1,0,-1):
average_gain = (average_gain*(period-1) + max(r_w[i-1] - r_w[i],0))/period
average_loss = (average_loss*(period-1) + abs(min(r_w[i-1] - r_w[i],0)))/period
if average_loss == 0:
return 100
else:
rsi = 100 - (100/(1 + average_gain / average_loss))
return rsi
else:
return None
def SMA2(self,equity,period):
r_w = RollingWindow[float](period)
history = self.history(equity,period - 1,Resolution.DAILY)
for historical_bar in history:
r_w.add(historical_bar.close)
while r_w.count < period:
current_price = self.securities[equity].price
r_w.add(current_price)
if r_w.is_ready:
sma = sum(r_w) / period
return sma
else:
return 0
def Rebalance(self):
if not self.qqq_rsi.IsReady or not self.spy_sma_200.IsReady or not self.spy_sma_30.IsReady:
return
rsi_value = self.RSI2("QQQ", 10)
spy_price = self.securities[self.spy].Price
spy_sma_200 = self.SMA2("SPY", 200)
spy_sma_30 = self.SMA2("SPY", 30)
if rsi_value > 79:
liquidate = not self.portfolio[self.vixy].invested
self.set_holdings(self.vixy, 1, liquidate)
elif rsi_value < 31:
liquidate = not self.portfolio[self.qld].invested
self.set_holdings(self.qld, 1, liquidate)
elif spy_price > spy_sma_200:
if spy_price > spy_sma_30:
liquidate = not self.portfolio[self.qqq].invested
self.set_holdings(self.qqq, 1, liquidate)
else:
# self.set_holdings([PortfolioTarget(self.xlp, 0.5), PortfolioTarget(self.xlu, 0.5)], True)
liquidate = not self.portfolio[self.xlu].invested
self.set_holdings(self.xlu, 1, liquidate)
else:
if spy_price > spy_sma_30:
# self.set_holdings([PortfolioTarget(self.xlp, 0.5), PortfolioTarget(self.xlu, 0.5)], True)
liquidate = not self.portfolio[self.xlu].invested
self.set_holdings(self.xlu, 1, liquidate)
else:
liquidate = not self.portfolio[self.bil].invested
self.set_holdings(self.bil, 1, liquidate)