| 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 riskAdjustedTargetsfrom 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