Overall Statistics |
Total Trades 36 Average Win 0.92% Average Loss -0.02% Compounding Annual Return 95.694% Drawdown 13.500% Expectancy 35.256 Net Profit 15.560% Sharpe Ratio 2.695 Probabilistic Sharpe Ratio 73.168% Loss Rate 8% Win Rate 92% Profit-Loss Ratio 38.28 Alpha 0.506 Beta 1.513 Annual Standard Deviation 0.238 Annual Variance 0.056 Information Ratio 4.189 Tracking Error 0.132 Treynor Ratio 0.423 Total Fees $36.08 Estimated Strategy Capacity $2000.00 Lowest Capacity Asset EDOC XGLILOJXRUJP Portfolio Turnover 4.34% |
#region imports from AlgorithmImports import * #endregion import numpy as np from datetime import datetime import talib class NadionResistanceShield(QCAlgorithm): def Initialize(self): self.SetStartDate(2023, 1, 1) # Set Start Date #self.SetEndDate(2021, 1, 1) self.SetCash(25000) # Set Strategy Cash self.tickers = ['SOXX','CIBR','ROBO','CLOU','BLOK', #Tech 'IHI', 'VHT', 'IHE', 'EDOC', #Healthcare 'VDE', 'OIH', 'ICLN', 'XOP','TAN', #Energy 'XLF', 'IAT', 'FINX', 'IAI', #Financial 'GDX', 'LIT', 'COPX', 'VAW', 'URNM',"WOOD", #Materials 'XLY', 'XLC','XRT', 'ESPO', 'CARZ', #Consumer Discretionary 'VIS', 'PHO', 'ITA', 'IYT', 'JETS', #Industrials 'XLU', 'PAVE', 'RYU', 'GIL' #Utilities 'VNQ', 'XLRE' #RealEstate 'VIXM', 'VXX', 'UVXY','BITS' #Volatility 'QQQ', 'IWM', 'MDY', 'IEMG', 'DBC', 'IWF', 'IWD' ] #self.ROC = {} self.num_fine = 5 self.symbolDataBySymbol = {} self.marketDataBySymbol = {} self.vwaps = {} self.stds = {} self.Marketvwaps = {} self.Marketstds = {} self.trade = True self.atr=[] self.MarketCaps = ["SPY","QQQ"]#, "MDY","IWM"] self.spy = "SPY" self.iwm = "IWM" self.mdy = "MDY" self.qqq = "QQQ" self.momentum_periods = [30, 90, 180] self.consolidation_periods = [10, 20, 50] # trade only once per day self.next_trade_time = self.Time #self.AddRiskManagement(TrailingStopRiskManagementModel(0.05)) for symbolmark in self.MarketCaps: symbol = self.AddEquity(symbolmark, Resolution.Daily).Symbol sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close) sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close) self.marketDataBySymbol[symbol] = symbolMarkData(symbol, sma50, sma200) for symbol in self.tickers: self.AddEquity(symbol, Resolution.Hour) '''For the below 3 EMA's, you can convert them to 4H bars using the colidator method''' close = self.MIN(symbol, 1, Resolution.Daily, Field.Low) ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close) sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close) sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close) sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close) self.sma = self.SMA(symbol, 20, Resolution.Hour, Field.Close) sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close) sma100 = self.SMA(symbol, 100, Resolution.Daily, Field.Close) ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close) ema50 = self.EMA(symbol, 50, Resolution.Hour, Field.Close) rsi = self.RSI(symbol, 14, Resolution.Daily) wilr = self.WILR(symbol, 14, Resolution.Daily) wilr_fast = self.WILR(symbol, 10, Resolution.Daily) self.vwaps[symbol] = self.VWAP(symbol, 14, Resolution.Daily) self.stds[symbol] = self.STD(symbol, 14, Resolution.Daily) atr = self.ATR(symbol, 7, Resolution.Daily) self.atr.append(self.ATR(symbol, 7, Resolution.Daily)) self.high = self.MAX(symbol, 7, Resolution.Daily, Field.High) self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low) self.sma.Updated += self.OnSMA '''Consolidator method''' smaConsolidate = ExponentialMovingAverage(20, MovingAverageType.Simple) # create the 4 hour data consolidator fourHourConsolidator = TradeBarConsolidator(timedelta(hours=4)) self.SubscriptionManager.AddConsolidator(symbol, fourHourConsolidator) # register the 4 hour consolidated bar data to automatically update the indicator self.RegisterIndicator(symbol, smaConsolidate, fourHourConsolidator) self.vwaps[symbol] = self.VWAP(symbol, 14, Resolution.Daily) self.stds[symbol] = self.STD(symbol, 14, Resolution.Daily) self.Marketvwaps[symbol] = self.VWAP(symbol, 14, Resolution.Daily) self.Marketstds[symbol] = self.STD(symbol, 14, Resolution.Daily) symbolData = SymbolData(symbol, ema10, sma20, sma100, sma200, sma7, sma50, ema20, ema50, rsi, wilr, wilr_fast, atr, smaConsolidate, close) self.symbolDataBySymbol[symbol] = symbolData self.spy = self.AddEquity("SPY", Resolution.Daily) # Before the open self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", -5), Action(self.beforeTheOpen)) #set the following between 1 - 4 hours depending on buy frequency self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Every(timedelta(hours=6.5)), self.buySignals) #self.TimeRules.EveryDay, #self.buySignals) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Every(timedelta(hours=3.2)), self.sellSignals) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY"), self.tradeStart) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY"), self.tradeEnd) self.SetWarmUp(timedelta(days=90)) def beforeTheOpen(self): self.Log("SPY: {0}".format(self.spy.Close)) #for i in range(len(self.tickers)): # self.Log("ATR: {0}".format(self.atr[i].Current.Value)) def OnData(self, data): if self.IsWarmingUp:# or not all(std.IsReady for std in self.stds.values()): return for symbol in self.tickers: price = self.Securities[symbol].Price vwap = self.vwaps[symbol].Current.Value std = self.stds[symbol].Current.Value ub1 = vwap + std ub2 = vwap + 2*std lb1 = vwap - std lb2 = vwap - 2*std self.Plot(symbol, 'price', price) self.Plot(symbol, 'vwap', vwap) self.Plot(symbol, 'ub2', ub2) self.Plot(symbol, 'ub1', ub1) self.Plot(symbol, 'lb1', lb1) self.Plot(symbol, 'lb2', lb2) #Take Profit if price > ub2: self.Liquidate(symbol) return def tradeStart(self): self.trade = True def tradeEnd(self): self.trade = False def OnOrderEvent(self, OrderEvent): '''Event when the order is filled. Debug log the order fill. :OrderEvent:''' if OrderEvent.FillQuantity == 0: return # Get the filled order Order = self.Transactions.GetOrderById(OrderEvent.OrderId) # Log the filled order details self.Log("ORDER NOTIFICATION >> {} >> Status: {} Symbol: {}. Quantity: " "{}. Direction: {}. Fill Price {}".format(str(Order.Tag), str(OrderEvent.Status), str(OrderEvent.Symbol), str(OrderEvent.FillQuantity), str(OrderEvent.Direction), str(OrderEvent.FillPrice))) def buySignals(self): if self.trade == False: return # Return if benchmark is below SMA for symbolmark, symbolmarkData in self.marketDataBySymbol.items(): if (self.Securities[symbolmark].Close > symbolmarkData.sma200.Current.Value): return for symbol, symbolData in self.symbolDataBySymbol.items(): if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close < self.low.Current.Value) and (symbolData.sma100.Current.Value > symbolData.sma200.Current.Value):# and (self.Securities[symbol].Close > symbolData.sma200.Current.Value): self.SetHoldings(symbol, .1, False, "Buy Signal") elif not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close < symbolData.sma20.Current.Value) and (symbolData.ema20.Current.Value > symbolData.ema50.Current.Value): self.SetHoldings(symbol, .1, False, "Buy Signal") def sellSignals(self): if self.trade == False: return for symbol, symbolData in self.symbolDataBySymbol.items(): if self.Portfolio[symbol].Invested and (symbolData.rsi.Current.Value > 90): self.StopMarketOrder(symbol, .05, self.Securities[symbol].Close, "Some Profit Signal") #if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (symbolData.sma20.Current.Value < symbolData.atr.Current.Value): # self.Liquidate(symbol, "Sell Signal") if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > self.high.Current.Value): self.Liquidate(symbol, "Sell New High Signal") def OnSMA(self, sender, updated): if self.sma.IsReady: #self.Debug(f"SMA Updated on {self.Time} with value: {self.sma.Current.Value}") return class symbolMarkData: def __init__(self, symbol, sma50, sma200): self.Symbol = symbol self.sma50 = sma50 self.sma200 = sma200 class SymbolData: def __init__(self, symbol, ema10, sma20, sma50, sma100, sma200, sma7, ema20, ema50, rsi, wilr, wilr_fast, atr, smaConsolidate, close): self.Symbol = symbol self.ema10 = ema10 self.sma20 = sma20 self.sma50 = sma50 self.sma200 = sma200 self.sma100 = sma100 self.sma7 = sma7 self.ema20 = ema20 self.ema50 = ema50 self.close = close self.rsi = rsi self.wilr = wilr self.wilr_fast = wilr_fast self.atr = atr #self.emaConsolidate = emaConsolidate self.smaConsolidate = smaConsolidate