Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -2.224 Tracking Error 0.122 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
from clr import AddReference AddReference("System") AddReference("QuantConnect.Common") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Algorithm.Framework") from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Algorithm.Framework import * from QuantConnect.Algorithm.Framework.Portfolio import PortfolioTarget from QuantConnect.Algorithm.Framework.Risk import RiskManagementModel class TrailingStopRiskManagementModel(RiskManagementModel): '''Provides an implementation of IRiskManagementModel that limits the maximum possible loss measured from the highest unrealized profit''' def __init__(self, maximumDrawdownPercent = 0.05): '''Initializes a new instance of the TrailingStopRiskManagementModel class Args: maximumDrawdownPercent: The maximum percentage drawdown allowed for algorithm portfolio compared with the highest unrealized profit, defaults to 5% drawdown''' self.maximumDrawdownPercent = -abs(maximumDrawdownPercent) self.trailingHighs = dict() self.lastDay = -1 self.percentGain = 0.005 def ManageRisk(self, algorithm, targets): '''Manages the algorithm's risk at each time step Args: algorithm: The algorithm instance targets: The current portfolio targets to be assessed for risk''' if algorithm.Time.day == self.lastDay: return [] self.lastDay = algorithm.Time.day riskAdjustedTargets = list() for kvp in algorithm.Securities: symbol = kvp.Key security = kvp.Value percentChange = algorithm.Securities[symbol].Holdings.UnrealizedProfitPercent / 0.005 # Add newly invested securities if symbol not in self.trailingHighs: self.trailingHighs[symbol] = security.Close # Set to average holding cost continue # Remove if not invested if not security.Invested and symbol in self.trailingHighs: try: self.trailingHighs.pop(symbol, None) except: continue continue if percentChange.is_integer() and percentChange > 0: self.trailingHighs[symbol] = security.Close # Check for new highs and update - set to tradebar high # if self.trailingHighs[symbol] < security.High: # self.trailingHighs[symbol] = security.High # continue # Check for securities past the drawdown limit securityHigh = self.trailingHighs[symbol] if securityHigh == 0: riskAdjustedTargets.append(PortfolioTarget(symbol, 0)) continue drawdown = (security.Low / securityHigh) - 1 if drawdown < self.maximumDrawdownPercent: # liquidate riskAdjustedTargets.append(PortfolioTarget(symbol, 0)) return riskAdjustedTargets
from itertools import groupby class NadionResistanceShield(QCAlgorithm): #class DataConsolidationAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 1, 1) # Set Start Date #self.SetEndDate(2019, 1, 1) self.SetCash(25000) # Set Strategy Cash self.manually_selected = [self.AddEquity(symbol).Symbol for symbol in ["QQQ"]] self.tickers = self.ActiveSecurities # self.assets = filteredSymbols + self.manually_selected self.symbolDataBySymbol = {} self.MarketCaps = ["SPY", "TLT", "GLD", "VNQ"]# "QQQ"]#,"MDY","IWM"] self.marketDataBySymbol = {} self.volatilityDataBySymbol = {} self.vix = ["VIX"] self.trade = True self.atr=[] self.spy = "SPY" self.iwm = "IWM" self.mdy = "MDY" self.qqq = "QQQ" self.vix = "VIX" # Before the open # Trailing distance in $ self.trail_dist = 10 # Declare an attribute that we shall use for storing our # stop loss ticket. self.sl_order = None # Declare an attribute that we will use to store the last trail level # used. We will use this to decide whether to move the stop self.last_trail_level = None # Stock Selector self.AddUniverse(self.Coarse, self.Fine) self.activelyTrading = [] self.weight = 0 self.numberOfSymbolsCoarse = 500 self.exposureToSector = 2 self.lastMonth = -1 for symbolmark in self.MarketCaps: symbol = self.AddEquity(symbolmark, Resolution.Hour).Symbol sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close) sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close) rsi = self.RSI(symbol, 14, Resolution.Daily) self.marketDataBySymbol[symbol] = symbolMarkData(symbol, sma50, sma200, rsi) for symbolvol in self.vix: symbol = self.AddEquity(symbolmark, Resolution.Hour).Symbol rsi = self.RSI(symbol, 14, Resolution.Daily) wilr = self.WILR(symbol, 14, Resolution.Daily) self.volatilityDataBySymbol[symbol] = symbolvolData(symbol, rsi, wilr) 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''' 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) 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) atr = self.ATR(symbol, 20, Resolution.Daily) self.atr.append(self.ATR(symbol, 7, Resolution.Daily)) self.high = self.MAX(symbol, 5, Resolution.Daily, Field.High) self.midhigh = self.MAX(symbol, 3, Resolution.Daily, Field.High) self.low = self.MIN(symbol, 5, Resolution.Daily, Field.Low) self.stoplow = self.MIN(symbol, 20, 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) symbolData = SymbolData(symbol, ema10, sma20, sma200, sma7, sma50, ema20, ema50, rsi, wilr, wilr_fast, atr, smaConsolidate) 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)) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), self.buySignals) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), self.sellSignals) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 10), self.buySignals) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 10), self.sellSignals) #self.AddRiskManagement(TrailingStopRiskManagementModel(0.04)) self.SetWarmUp(timedelta(days=180)) def Coarse(self, coarse): if self.Time.month == self.lastMonth: return Universe.Unchanged self.lastMonth = self.Time.month allCoarse = [x for x in coarse if x.HasFundamentalData and x.Price > 1 and x.Volume > 1] finalCoarse = sorted(allCoarse, key = lambda x: x.DollarVolume, reverse = True) return [x.Symbol for x in finalCoarse][:self.numberOfSymbolsCoarse] return self.tickers def Fine(self, fine): filteredSymbols = [] sortedBySector = [x for x in fine] for code, g in groupby(sortedBySector, lambda x: x.AssetClassification.MorningstarSectorCode): for x in sorted(g, key = lambda x: x.ValuationRatios.PERatio, reverse = False)[:self.exposureToSector]: filteredSymbols.append(x.Symbol) #self.tickers = filteredSymbols + self.manually_selected return filteredSymbols[:5] self.Log("tickers: {0}".format(self.tickers)) def OnSecuritiesChanged(self, changes): return self.tickers 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): 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))) #self.Log(OrderEvent.FillPrice - symbolData.atr.Current.Value)) 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.rsi.Current.Value > 50): return for symbolvol, symbolvolData in self.volatilityDataBySymbol.items(): if (self.Securities[symbolvol].Close > symbolvolData.wilr.Current.Value < -20): return for symbol, symbolData in self.symbolDataBySymbol.items(): if not self.Portfolio[symbol].Invested:# and (self.Securities[symbol].Close < self.low.Current.Value):# and (self.midhigh.Current.Value < self.high.Current.Value): self.SetHoldings(symbol, .2, False, "Buy Signal") def sellSignals(self): if self.trade == False: return for symbol, symbolData in self.symbolDataBySymbol.items(): if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > self.high.Current.Value): self.Liquidate(symbol, "Sell Signal") # Update our trailing stop loss as necessary def stopLoss(self): if self.trade == False: return for symbol, symbolData in self.symbolDataBySymbol.items(): if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close < (symbolData.atr.Current.Value *2)): self.Liquidate(symbol, "Sell 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, rsi): self.Symbol = symbol self.sma50 = sma50 self.sma200 = sma200 self.rsi = rsi class symbolvolData: def __init__(self, symbol, rsi, wilr): self.Symbol = symbol self.rsi = rsi self.wilr = wilr class SymbolData: def __init__(self, symbol, ema10, sma20, sma50, sma200, sma7, ema20, ema50, rsi, wilr, wilr_fast, atr, smaConsolidate): self.Symbol = symbol self.ema10 = ema10 self.sma20 = sma20 self.sma50 = sma50 self.sma200 = sma200 self.sma7 = sma7 self.ema20 = ema20 self.ema50 = ema50 self.rsi = rsi self.wilr = wilr self.wilr_fast = wilr_fast self.atr = atr #self.emaConsolidate = emaConsolidate self.smaConsolidate = smaConsolidate