Overall Statistics |
Total Trades 1875 Average Win 2.18% Average Loss -2.01% Compounding Annual Return 31.632% Drawdown 55.400% Expectancy 0.218 Net Profit 3057.588% Sharpe Ratio 0.781 Probabilistic Sharpe Ratio 8.569% Loss Rate 42% Win Rate 58% Profit-Loss Ratio 1.09 Alpha 0.215 Beta 0.883 Annual Standard Deviation 0.387 Annual Variance 0.15 Information Ratio 0.558 Tracking Error 0.365 Treynor Ratio 0.342 Total Fees $22371.17 Estimated Strategy Capacity $3400000.00 Lowest Capacity Asset UPRO UDQRQQYTO12D Portfolio Turnover 16.25% |
#region imports from AlgorithmImports import * class ParticleQuantumChamber(QCAlgorithm): def Initialize(self): self.SetStartDate(2011, 1, 1) # self.SetEndDate(2020, 6, 15) self.SetCash(10000) self.upro = self.AddEquity('UPRO', Resolution.Daily).Symbol # UPRO = 3x levered SPX self.shy = self.AddEquity('SHY', Resolution.Daily).Symbol # SHY = short term Treasury ETF self.spy = self.AddEquity('SPY', Resolution.Daily).Symbol # SPY = S&P 500 ETF self.uvxy = self.AddEquity('UVXY', Resolution.Daily).Symbol # self.tmf = self.AddEquity('TMF', Resolution.Daily).Symbol # self.vix = self.AddEquity('VIX', Resolution.Daily).Symbol # self.tecl = self.AddEquity('TECL', Resolution.Daily).Symbol # self.sh = self.AddEquity('SH', Resolution.Daily).Symbol # self.tlt = self.AddEquity('TLT', Resolution.Daily).Symbol # self.spxu = self.AddEquity('SPXU', Resolution.Daily).Symbol # self.sphb = self.AddEquity('SPHB', Resolution.Daily).Symbol self.bsv = self.AddEquity('BSV', Resolution.Daily).Symbol self.qqq = self.AddEquity('QQQ', Resolution.Daily).Symbol # self.iei = self.AddEquity('IEI', Resolution.Daily).Symbol # # Register to receive data for the 'SPY' symbol # self.AddEquity('SPY', Resolution.Daily) self.SetWarmup(200) self.investpercent = 1 self.SetBenchmark(self.spy) self.UniverseSettings.Resolution = Resolution.Daily # self.SetAlpha(EtfSmaAlphaModel(self.spy, self.upro, self.shy)) # self.SetUniverseSelection(ManualUniverseSelectionModel([self.upro, self.shy, self.spy])) self.SetExecution(ImmediateExecutionModel()) # self.SetBrokerageModel(AlphaStreamsBrokerageModel()) # Setting the account type in the brokerage model # self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Cash) # 3 days for portfolio to receive cash from sale of a stock self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) # avoids simulating order settlement with margin (or simply don't use a brokerage model but may have inaccurate fees) # self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) # all insights are equal weight self.SetPortfolioConstruction(InsightWeightingPortfolioConstructionModel()) # insights' weighting determines portfolio allocation # Investigate backing out and resetting after 2 weeks? # self.SetRiskManagement(MaximumDrawdownPercentPortfolio(0.1)) # Run to cash at 10% drawdown # self.riskedSecurities = set() # self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.1)) # 10% drawdown # self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Friday), self.TimeRules.At(9, 30), self.riskedSecurities.clear()) # Create a custom chart stockPlot = Chart("Stock Plot") stockPlot.AddSeries(Series("SPY", SeriesType.Line)) stockPlot.AddSeries(Series("UPRO", SeriesType.Line)) stockPlot.AddSeries(Series("SHY", SeriesType.Line)) stockPlot.AddSeries(Series("200d EMA", SeriesType.Line)) # Add 200d EMA series stockPlot.AddSeries(Series("10d RSI", SeriesType.Line)) stockPlot.AddSeries(Series("60d RSI", SeriesType.Line)) stockPlot.AddSeries(Series("Cash", SeriesType.Line)) stockPlot.AddSeries(Series("Unsettled Cash", SeriesType.Line)) self.AddChart(stockPlot) # Initialize EMA self.ema30spy = self.EMA(self.spy, 30, Resolution.Daily) self.ema200spy = self.EMA(self.spy, 200, Resolution.Daily) self.rsi10spy = self.RSI(self.spy, 10, MovingAverageType.Simple, Resolution.Daily) self.rsi10qqq = self.RSI(self.qqq, 10, MovingAverageType.Simple, Resolution.Daily) self.rsi10tlt = self.RSI(self.tlt, 10, MovingAverageType.Simple, Resolution.Daily) self.rsi10sh = self.RSI(self.sh, 10, MovingAverageType.Simple, Resolution.Daily) self.rsi10spxu = self.RSI(self.spxu, 10, MovingAverageType.Simple, Resolution.Daily) self.rsi60spy = self.RSI(self.spy, 60, MovingAverageType.Simple, Resolution.Daily) self.rsi60tlt = self.RSI(self.tlt, 60, MovingAverageType.Simple, Resolution.Daily) self.rsi14iei = self.RSI(self.iei, 14, MovingAverageType.Simple, Resolution.Daily) self.rsi14sphb = self.RSI(self.sphb, 14, MovingAverageType.Simple, Resolution.Daily) self.rsi7bsv = self.RSI(self.bsv, 7, MovingAverageType.Simple, Resolution.Daily) self.rsi7sphb = self.RSI(self.sphb, 7, MovingAverageType.Simple, Resolution.Daily) def liquidate_all_positions_except(self, symbol_to_keep): for holding in self.Portfolio.Values: if holding.Symbol != symbol_to_keep and holding.Invested: self.Liquidate(holding.Symbol) def OnData(self, data): if self.IsWarmingUp: return # if no spy data, skip if not data.ContainsKey(self.spy): return if not data.ContainsKey(self.uvxy): return if self.spy in data and data[self.spy] is not None: self.Plot("Stock Plot", "SPY", data[self.spy].Close) self.Plot("Stock Plot", "200d EMA", self.ema200spy.Current.Value) # Plot 200d EMA self.Plot("Stock Plot", "10d RSI", self.rsi10spy.Current.Value) self.Plot("Stock Plot", "60d RSI", self.rsi60spy.Current.Value) if self.upro in data and data[self.upro] is not None: self.Plot("Stock Plot", "UPRO", data[self.upro].Close) if self.shy in data and data[self.shy] is not None: self.Plot("Stock Plot", "SHY", data[self.shy].Close) self.Plot("Stock Plot", "Cash", self.Portfolio.Cash) self.Plot("Stock Plot", "Unsettled Cash", self.Portfolio.UnsettledCash) self.invested_value = sum([x.HoldingsValue for x in self.Portfolio.Values]) # Calculate the currently invested value self.percent_invested = (self.invested_value / self.Portfolio.TotalPortfolioValue) * 100 # Calculate the percentage invested # allocation = self.Portfolio[stock_symbol].Percentage # self.Log(f"{stock_symbol} allocation: {allocation * 100:.2f}%") # Plotting Cash Amounts self.Plot("Portfolio Info", "Cash", self.Portfolio.Cash) self.Plot("Portfolio Info", "Unsettled Cash", self.Portfolio.UnsettledCash) self.Plot("Portfolio Info", "Percent Invested", self.percent_invested) # Set timedelta as an instance variable self.timedelta = timedelta(days=1) insights = [] if data[self.spy].Close > self.ema200spy.Current.Value: if self.rsi10spy.Current.Value > 80: # # invest in uxvy insights.append(Insight.Price(self.uvxy, self.timedelta, InsightDirection.Up, weight=self.investpercent)) self.Log(f"Insight allocation: {self.investpercent * 100:.2f}% in {self.uvxy}") else: if self.rsi60spy.Current.Value > 60: # # invest in tmf or vixy (add inv volatility here later) ########## ADD VOLATILITY LATER ########### #### TMF VS VIXY HERE insights.append(Insight.Price(self.tmf, self.timedelta, InsightDirection.Up, weight=self.investpercent)) self.Log(f"Insight allocation: {self.investpercent * 100:.2f}% in {self.tmf}") else: # invest in upro insights.append(Insight.Price(self.upro, self.timedelta, InsightDirection.Up, weight=self.investpercent)) self.Log(f"Insight allocation: {self.investpercent * 100:.2f}% in {self.upro}") else: # spy close <= ema if self.rsi10qqq.Current.Value < 30: # set to tecl insights.append(Insight.Price(self.tecl, self.timedelta, InsightDirection.Up, weight=self.investpercent)) self.Log(f"Insight allocation: {self.investpercent * 100:.2f}% in {self.tecl}") else: if self.rsi60tlt.Current.Value < 45: #### HALF IN THIS BLOCK #### if data[self.spy].Close > self.ema30spy.Current.Value: if self.rsi10spy.Current.Value > 70: # set to SH insights.append(Insight.Price(self.sh, self.timedelta, InsightDirection.Up, weight=self.investpercent/2)) self.Log(f"Insight allocation: {self.investpercent/2 * 100:.2f}% in {self.sh}") else: # set to upro insights.append(Insight.Price(self.upro, self.timedelta, InsightDirection.Up, weight=self.investpercent/2)) self.Log(f"Insight allocation: {self.investpercent/2 * 100:.2f}% in {self.upro}") else: # between tlt and sh 10drsi select top1 if self.rsi10tlt.Current.Value > self.rsi10sh.Current.Value: #invest in tlt insights.append(Insight.Price(self.tlt, self.timedelta, InsightDirection.Up, weight=self.investpercent/2)) self.Log(f"Insight allocation: {self.investpercent/2 * 100:.2f}% in {self.tlt}") else: insights.append(Insight.Price(self.sh, self.timedelta, InsightDirection.Up, weight=self.investpercent/2)) self.Log(f"Insight allocation: {self.investpercent/2 * 100:.2f}% in {self.sh}") #### END HALF IN THIS BLOCK #### #### HALF IN THIS BLOCK #### if self.rsi14iei.Current.Value < self.rsi14sphb.Current.Value: if self.rsi7bsv.Current.Value < self.rsi7sphb.Current.Value: # invest in sh insights.append(Insight.Price(self.sh, self.timedelta, InsightDirection.Up, weight=self.investpercent/2)) self.Log(f"Insight allocation: {self.investpercent/2 * 100:.2f}% in {self.sh}") else: #invest in upro insights.append(Insight.Price(self.upro, self.timedelta, InsightDirection.Up, weight=self.investpercent/2)) self.Log(f"Insight allocation: {self.investpercent/2 * 100:.2f}% in {self.upro}") else: #invest in upro insights.append(Insight.Price(self.upro, self.timedelta, InsightDirection.Up, weight=self.investpercent/2)) self.Log(f"Insight allocation: {self.investpercent/2 * 100:.2f}% in {self.upro}") #### END HALF IN THIS BLOCK #### else: # if data[self.spy].Close > self.ema30spy.Current.Value: if self.rsi10spy.Current.Value > 70: # invest in sh insights.append(Insight.Price(self.sh, self.timedelta, InsightDirection.Up, weight=self.investpercent)) self.Log(f"Insight allocation: {self.investpercent * 100:.2f}% in {self.sh}") else: # invest in upro insights.append(Insight.Price(self.upro, self.timedelta, InsightDirection.Up, weight=self.investpercent)) self.Log(f"Insight allocation: {self.investpercent * 100:.2f}% in {self.upro}") else: # between tlt and spxu 10drsi select top1 if self.rsi10tlt.Current.Value > self.rsi10spxu.Current.Value: #invest in tlt insights.append(Insight.Price(self.tlt, self.timedelta, InsightDirection.Up, weight=self.investpercent)) self.Log(f"Insight allocation: {self.investpercent * 100:.2f}% in {self.tlt}") else: insights.append(Insight.Price(self.spxu, self.timedelta, InsightDirection.Up, weight=self.investpercent)) self.Log(f"Insight allocation: {self.investpercent * 100:.2f}% in {self.spxu}") # Group insights and return if insights: self.EmitInsights(Insight.Group(insights))