This is what I am getting. Can anyone please point me in the right direction?
Below is the script. Backtest still hasnt completed, but will update:
class NadionResistanceShield(QCAlgorithm):
#class DataConsolidationAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 1) # Set Start Date
self.SetEndDate(2021, 2, 1)
self.SetCash(50000) # Set Strategy Cash
self.tickers = ["SPY"]
self.symbolDataBySymbol = {}
self.trade = True
# Before the open
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'''
macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily, Field.Close)
ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
#sma7 = self.SMA(symbol, 7, Resolution.Minute, Field.Close)
ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
ema7 = self.EMA(symbol, 7, Resolution.Hour, Field.Close)
#ema7 = self.EMA(symbol, 7, Resolution.Minute, Field.Close)
ema9 = self.EMA(symbol, 9, Resolution.Hour, Field.Close)
rsi = self.RSI(symbol, 14, Resolution.Daily)
wilr_up = self.WILR(symbol, 10, Resolution.Daily)
wilr = self.WILR(symbol, 14, Resolution.Daily)
atr = self.ATR(symbol, 14, Resolution.Daily)
self.atr=[]
for i in self.tickers:
self.atr.append(self.ATR(i, 14))
'''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.Schedule.On(self.DateRules.EveryDay(self.tickers),
#self.TimeRules.AfterMarketOpen(self.tickers, -5),
# Action(self.beforeTheOpen))
symbolData = SymbolData(symbol, ema10, sma200, sma20, sma50, sma7, ema20, ema7, ema9, rsi, wilr, wilr_up, atr, smaConsolidate)
self.symbolDataBySymbol[symbol] = symbolData
def beforeTheOpen(self):
for i in range(len(self.tickers)):
self.Log("ATR: {0}".format(self.atr[i].Current.Value))
self.spy = self.AddEquity("SPY", Resolution.Daily)
# Before the open
#self.Schedule.On(self.DateRules.EveryDay(self.tickers),
# self.TimeRules.AfterMarketOpen(self.tickers, -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=2)),
self.buySignals)
self.Schedule.On(self.DateRules.EveryDay("SPY"),
self.TimeRules.Every(timedelta(hours=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.AddRiskManagement(TrailingStopRiskManagementModel(0.03))
self.SetWarmUp(timedelta(days=50))
def tradeStart(self):
self.trade = True
def tradeEnd(self):
self.trade = False
def buySignals(self):
if self.trade == False:
self.stopBuyPrice = data["SPY"].Close + 3
self.stopLossPrice = self.stopBuyPrice - 10
self.profitTarget1 = self.stopBuyPrice + 10
self.profitTarget2 = self.stopBuyPrice + 20
return
for symbol, symbolData in self.symbolDataBySymbol.items():
#if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.ema7.Current.Value) and (symbolData.ema7.Current.Value > symbolData.atr.Current.Value) and (symbolData.sma20.Current.Value > symbolData.sma50.Current.Value):
# self.SetHoldings(symbol, .1, False, "Buy Signal")
if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) (symbolData.wilr.Current.Value < symbolData.wilr_up.Current.Value) and (symbolData.rsi < 30):
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 (self.Securities[symbol].Close < symbolData.sma7.Current.Value):
self.Liquidate(symbol, "Sell Signal")
def OnData(self, slice):
pass
class SymbolData:
def __init__(self, symbol, ema10, sma200, sma20, sma50, sma7, ema20, ema7, ema9, rsi, wilr, wilr_up, atr, smaConsolidate):
self.Symbol = symbol
self.ema10 = ema10
self.sma200 = sma200
self.sma20 = sma20
self.sma50 = sma50
self.sma7 = sma7
self.ema20 = ema20
self.ema7 = ema7
self.ema9 = ema9
self.rsi = rsi
self.wilr = wilr
self.wilr_up = wilr_up
self.atr = atr
#self.emaConsolidate = emaConsolidate
self.smaConsolidate = smaConsolidate
Derek Melchin
Hi Axist,
The error above is thrown because we are missing an `and` operator. To resolve the issue, we should replace
if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) (symbolData.wilr.Current.Value < symbolData.wilr_up.Current.Value) and (symbolData.rsi < 30):
with
if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (symbolData.wilr.Current.Value < symbolData.wilr_up.Current.Value) and (symbolData.rsi.Current.Value < 30):
See the attached backtest for reference.
Continuing with the development of this algorithm, we should be sure to warm up the indicators. We can add
self.EnableAutomaticIndicatorWarmUp = True
to warm up the indicators created with the short-cut methods (`self.EMA`). For the `ExponentialMovingAverage` indicator, we recommend adding a manual warm up.
Best,
Derek Melchin
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Axist
Thank you for this! This helped a lot.
So I tried adding in the stop loss and Profit taking to be set after a sell condition is met. I took what was found here, and tried to incoperate it, though I am not certain I needed everything. Does the OnData function break everything?
I'd like to get this working before I eventually figure out how to have the stop loss be set as a trailing stop loss. Much like what this does, but only set after the SellSignal condition is met
self.AddRiskManagement(TrailingStopRiskManagementModel(0.03))
Heres the code so far:
class NadionResistanceShield(QCAlgorithm): #class DataConsolidationAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 1, 1) # Set Start Date self.SetEndDate(2021, 2, 1) self.SetCash(50000) # Set Strategy Cash self.tickers = ["SPY"] self.symbolDataBySymbol = {} self.trade = True # SL / TP self.entryTicket = None self.stoplossTicket = None self.profit1Ticket = None self.profit2Ticket = None # Before the open self.EnableAutomaticIndicatorWarmUp = True 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''' macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily, Field.Close) ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close) sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close) sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close) sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close) sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close) #sma7 = self.SMA(symbol, 7, Resolution.Minute, Field.Close) ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close) ema7 = self.EMA(symbol, 7, Resolution.Hour, Field.Close) #ema7 = self.EMA(symbol, 7, Resolution.Minute, Field.Close) ema9 = self.EMA(symbol, 9, Resolution.Hour, Field.Close) rsi = self.RSI(symbol, 14, Resolution.Daily) wilr_up = self.WILR(symbol, 10, Resolution.Daily) wilr = self.WILR(symbol, 14, Resolution.Daily) atr = self.ATR(symbol, 14, Resolution.Daily) self.atr=[] for i in self.tickers: self.atr.append(self.ATR(i, 14)) '''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.Schedule.On(self.DateRules.EveryDay(self.tickers), #self.TimeRules.AfterMarketOpen(self.tickers, -5), # Action(self.beforeTheOpen)) symbolData = SymbolData(symbol, ema10, sma200, sma20, sma50, sma7, ema20, ema7, ema9, rsi, wilr, wilr_up, atr, smaConsolidate) self.symbolDataBySymbol[symbol] = symbolData def beforeTheOpen(self): for i in range(len(self.tickers)): continue self.Log("ATR: {0}".format(self.atr[i].Current.Value)) self.spy = self.AddEquity("SPY", Resolution.Daily) # Before the open #self.Schedule.On(self.DateRules.EveryDay(self.tickers), # self.TimeRules.AfterMarketOpen(self.tickers, -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=2)), self.buySignals) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Every(timedelta(hours=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.AddRiskManagement(TrailingStopRiskManagementModel(0.03)) self.SetWarmUp(timedelta(days=50)) def tradeStart(self): self.trade = True def tradeEnd(self): self.trade = False def OnOrderEvent(self, orderevent): if orderevent.Status != OrderStatus.Filled: return self.stoplossTicket = self.StopMarketOrder(symbol,-100,self.stopLossPrice) # Enter limit order 1 self.profit1Ticket = self.LimitOrder(symbol,-50,self.profitTarget1) # Enter limit order 2 self.profit2Ticket = self.LimitOrder(symbol,-50,self.profitTarget2) def OnData(self, data): if self.entryTicket == None: self.stopBuyPrice = data[symbol].Close + 3 self.stopLossPrice = self.stopBuyPrice - 10 self.profitTarget1 = self.stopBuyPrice + 10 self.profitTarget2 = self.stopBuyPrice + 20 self.entryTicket = self.StopMarketOrder("SPY", 100, self.stopBuyPrice) return def buySignals(self): if self.trade == False: self.stopBuyPrice = self.symbol.Close + 3 self.stopLossPrice = self.stopBuyPrice - 10 self.profitTarget1 = self.stopBuyPrice + 10 self.profitTarget2 = self.stopBuyPrice + 20 return for symbol, symbolData in self.symbolDataBySymbol.items(): #if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.ema7.Current.Value) and (symbolData.ema7.Current.Value > symbolData.atr.Current.Value) and (symbolData.sma20.Current.Value > symbolData.sma50.Current.Value): # self.SetHoldings(symbol, .1, False, "Buy Signal") if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.sma200.Current.Value) and (symbolData.wilr.Current.Value < symbolData.wilr_up.Current.Value) and (symbolData.rsi.Current.Value < 30) and (symbolData.wilr.Current.Value < -85): self.SetHoldings(symbol, .5, 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 < symbolData.sma7.Current.Value): #self.Liquidate(symbol, "Sell Signal") self.stoplossTicket = self.StopMarketOrder(symbol,-.5,self.stopLossPrice) # Enter limit order 1 self.profit1Ticket = self.LimitOrder("SPY",-.25,self.profitTarget1) # Enter limit order 2 self.profit2Ticket = self.LimitOrder("SPY",-.25,self.profitTarget2) if self.profit1Ticket != None and self.profit1Ticket.OrderId == orderevent.OrderId: self.stoplossTicket.UpdateQuantity(-.25) if self.stoplossTicket != None and self.stoplossTicket.OrderId == orderevent.OrderId: self.profit1Ticket.Cancel() self.profit2Ticket.Cancel() self.entryTicket = None if self.profit2Ticket != None and self.profit2Ticket.OrderId == orderevent.OrderId: self.stoplossTicket.Cancel() self.entryTicket = None # def OnOrderEvent(self, orderevent): # if orderevent.Status != OrderStatus.Filled: # return # self.stoplossTicket = self.StopMarketOrder("SPY",-100,self.stopLossPrice) # Enter limit order 1 # self.profit1Ticket = self.LimitOrder("SPY",-50,self.profitTarget1) # Enter limit order 2 # self.profit2Ticket = self.LimitOrder("SPY",-50,self.profitTarget2) class SymbolData: def __init__(self, symbol, ema10, sma200, sma20, sma50, sma7, ema20, ema7, ema9, rsi, wilr, wilr_up, atr, smaConsolidate): self.Symbol = symbol self.ema10 = ema10 self.sma200 = sma200 self.sma20 = sma20 self.sma50 = sma50 self.sma7 = sma7 self.ema20 = ema20 self.ema7 = ema7 self.ema9 = ema9 self.rsi = rsi self.wilr = wilr self.wilr_up = wilr_up self.atr = atr #self.emaConsolidate = emaConsolidate self.smaConsolidate = smaConsolidate
Axist
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!