class TemplateA(QCAlgorithm):
def Initialize(self):
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) # Defaults to margin account. Ready to be used on IBKR
self.SetStartDate(2020, 3, 3) # Set Start Date
self.initialcash = 10000 # Set Strategy Cash
self.SetCash(self.initialcash)
self.Resolution = Resolution.Minute
self.NFLX=self.AddEquity("NFLX", self.Resolution)
self.ROKU=self.AddEquity("ROKU", self.Resolution)
self.SetWarmup(10, self.Resolution)
self.Schedule.On(self.DateRules.EveryDay(self.ROKU.Symbol),self.TimeRules.Every(timedelta(minutes=60)),self.trade)
## Risk Management
self.numberOfOrdersPerDay= 6
self.numberOfSharesPerTrade= -2 #short shares need the minus sign
self.MaxNumberOfSharesLong= 20
self.MaxNumberOfSharesShort= -20 #short shares need the minus sign
self.takeProfit = 1.10 # means a 10% take profit
self.stopLoss = 0.95 # means a 5% stop loss
def OnData(self, slice):
#Take profit logic
if self.Portfolio.Invested:
if self.Portfolio.TotalPortfolioValue > self.initialcash * self.takeProfit:# means a 5% take profit target, if the initial portfolio value is 100000 with 1.05 you will take profit when the value of portfolio is greater than 105 000 $.
self.Liquidate()
self.Debug("Take profit triggered")
#Stop loss logic
if self.Portfolio.Invested:
if self.Portfolio.TotalPortfolioValue < self.initialcash * self.stopLoss: # means a 10% stop loss. In this case 0.9 means that the portfolio is valued a 90% of the original value, so if the initial value is 100 000 $ it means 90 000$, a 10% stop loss. if you set self.initialcash*0.5 means a 50% stop loss and so on.
self.Liquidate()
self.Debug("Stop Loss triggered")
def trade(self):
NFLX = self.History(self.NFLX.Symbol, timedelta(7), Resolution.Daily)["close"].unstack(level=0)
NFLX_latest_close = NFLX['NFLX'][-1]
NFLX_first_close = NFLX['NFLX'][-5]
NFLX_percentage_move = (NFLX_latest_close - NFLX_first_close)/NFLX_first_close*100
ROKU = self.History(self.ROKU.Symbol, timedelta(7), Resolution.Daily)["close"].unstack(level=0)
ROKU_latest_close = ROKU['ROKU'][-1]
ROKU_first_close = ROKU['ROKU'][-5]
ROKU_percentage_move = (ROKU_latest_close - ROKU_first_close)/ROKU_first_close*100
exchange = self.Securities["ROKU"].Exchange
if exchange.ExchangeOpen and self.MaxNumberOfSharesShort<self.Portfolio["ROKU"].Quantity<self.MaxNumberOfSharesLong:
marketTicket = self.MarketOrder("ROKU", self.numberOfSharesPerTrade)
self.Debug("Market Order Fill Price: {0}".format(marketTicket.AverageFillPrice))
self.Debug("ROKU shares held "+str(self.Portfolio["ROKU"].Quantity))
Hi everybody!
I'm developing a simple strategy which should trade ROKU and NFLX according to some returns criteria (still haven't developed that part).
For now, with the code above, I get:
BacktestingRealTimeHandler.Run(): There was an error in a scheduled event ROKU: EveryDay: Every 60 min. The error was IndexError : index out of bounds
I don't have this error if I choose different backtesting periods...
I think it's related to the hourly scheduling function...can anyone help?
Thanks!
Emiliano Fraticelli
I've gone further with the development of the strategy, but unfortunately the problem still persists,
As you can see I've changed the logic of trading every hour for a logic of trading at specific time, but the problem is still there
class TemplateA(QCAlgorithm):
def Initialize(self):
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) # Defaults to margin account. Ready to be used on IBKR
self.SetStartDate(2020, 3, 3) # Set Start Date
self.initialcash = 10000 # Set Strategy Cash
self.SetCash(self.initialcash)
self.Resolution = Resolution.Minute
self.NFLX=self.AddEquity("NFLX", self.Resolution)
self.ROKU=self.AddEquity("ROKU", self.Resolution)
self.SetWarmup(100000, self.Resolution)
self.previous = None
self.Schedule.On(self.DateRules.EveryDay(self.ROKU.Symbol),self.TimeRules.At(9, 30),self.trade)
self.Schedule.On(self.DateRules.EveryDay(self.ROKU.Symbol),self.TimeRules.At(10, 30),self.trade)
self.Schedule.On(self.DateRules.EveryDay(self.ROKU.Symbol),self.TimeRules.At(11, 30),self.trade)
self.Schedule.On(self.DateRules.EveryDay(self.ROKU.Symbol),self.TimeRules.At(12, 30),self.trade)
self.Schedule.On(self.DateRules.EveryDay(self.ROKU.Symbol),self.TimeRules.At(13, 30),self.trade)
self.Schedule.On(self.DateRules.EveryDay(self.ROKU.Symbol),self.TimeRules.At(14, 30),self.trade)
## Risk Management
self.numberOfOrdersPerDay= 2
self.numberOfSharesPerTrade= 2
self.MaxNumberOfSharesLong= 20
self.MaxNumberOfSharesShort= -20 #short shares need the minus sign
self.takeProfit = 1.10 # means a 10% take profit
self.stopLoss = 0.80 # means a 5% stop loss
def OnData(self, slice):
#Take profit logic
if self.Portfolio.Invested:
if self.Portfolio.TotalPortfolioValue > self.initialcash * self.takeProfit:
self.Liquidate()
self.Debug("Take profit triggered")
#Stop loss logic
if self.Portfolio.Invested:
if self.Portfolio.TotalPortfolioValue < self.initialcash * self.stopLoss:
self.Liquidate()
self.Debug("Stop Loss triggered")
def trade(self):
if self.IsWarmingUp:
return
# only once per day
if self.previous is not None and self.previous.Date == self.Time.Date:
self.numberOfOrdersPerDay=self.numberOfOrdersPerDay-1
if self.numberOfOrdersPerDay==0:
self.Debug("Too much trades today "+self.Time)
return
if self.previous is not None and self.previous.Date != self.Time.Date:
self.numberOfOrdersPerDay=2
NFLX = self.History(self.NFLX.Symbol, timedelta(7), Resolution.Daily)["close"].unstack(level=0)
NFLX_latest_close = NFLX['NFLX'][-1]
NFLX_first_close = NFLX['NFLX'][-5]
NFLX_percentage_move = (NFLX_latest_close - NFLX_first_close)/NFLX_first_close*100
ROKU = self.History(self.ROKU.Symbol, timedelta(7), Resolution.Daily)["close"].unstack(level=0)
ROKU_latest_close = ROKU['ROKU'][-1]
ROKU_first_close = ROKU['ROKU'][-5]
ROKU_percentage_move = (ROKU_latest_close - ROKU_first_close)/ROKU_first_close*100
exchange = self.Securities["ROKU"].Exchange
if exchange.ExchangeOpen and self.MaxNumberOfSharesShort<self.Portfolio["ROKU"].Quantity<self.MaxNumberOfSharesLong and self.ROKU.IsTradable and (NFLX_percentage_move-ROKU_percentage_move)>0.05:
marketTicket = self.MarketOrder("ROKU", self.numberOfSharesPerTrade)
self.Debug("############################################")
self.Debug("NFLX % move "+str(NFLX_percentage_move))
self.Debug("ROKU % move "+str(ROKU_percentage_move))
self.Debug("Long ROKU")
self.Debug("Market Order Fill Price: {0}".format(marketTicket.AverageFillPrice))
self.Debug("ROKU shares held "+str(self.Portfolio["ROKU"].Quantity))
if exchange.ExchangeOpen and self.MaxNumberOfSharesShort<self.Portfolio["ROKU"].Quantity<self.MaxNumberOfSharesLong and self.ROKU.IsTradable and (NFLX_percentage_move-ROKU_percentage_move)<-0.05:
marketTicket = self.MarketOrder("ROKU", -self.numberOfSharesPerTrade)
self.Debug("############################################")
self.Debug("NFLX % move "+str(NFLX_percentage_move))
self.Debug("ROKU % move "+str(ROKU_percentage_move))
self.Debug("Short ROKU")
self.Debug("Market Order Fill Price: {0}".format(marketTicket.AverageFillPrice))
self.Debug("ROKU shares held "+str(self.Portfolio["ROKU"].Quantity))
Emiliano Fraticelli
Fixed by myself by looking at :
https://www.quantconnect.com/forum/discussion/4941/problems-with-a-scheduled-function/p1Emiliano Fraticelli
Finally, "index is out of bounds" because the historical data has only returned one data point. I would advise you to ask for more data point (5 instead of 2) and use the last two.
Emiliano Fraticelli
I don't know why I need to take more datapoints, but anyway...
Emiliano Fraticelli
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!