Hi All,
I've been reading through the forums and documentation, and am at a loss. I've tried using timedelta, and the self.consolidate method as well, but in each case I get the error:
ArgumentException : Invalid third argument, should be either a valid consolidator or timedelta object.
I'd like to use consolidators for the registration, just to make sure that everything is pumped through the event handlers I have.
I tried attaching the backtests, but none were found. I'll attach my code below:
'''Notes:'''
import numpy as np
from datetime import datetime, timedelta
from Alphas.MacdAlphaModel import MacdAlphaModel
from Risk.MaximumDrawdownPercentPerSecurity import MaximumDrawdownPercentPerSecurity
class DataConsolidationAlgorithm(QCAlgorithm):
def Initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
self.SetStartDate(DateTime(2020, 1, 1, 0, 0, 0)) #Set Start Date
self.SetEndDate(self.StartDate + timedelta(1)) #Set End Date
self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.03))
# Find more symbols here: http://quantconnect.com/data
self.symbol = "BTCUSD"
self.AddCrypto(self.symbol, Resolution.Minute)
'''Data Consolidator Initialization and Indicator Subscription Registration'''
# We do not need to register 1 minute indicators because they come in at our global resolution.
# All indicators need to be defined here (with timescaled names), and then subscribed to their various timescales.
# 1 Minute Indicators
self.price = self.SMA(self.symbol, 1, Resolution.Minute)
self.oneBB = self.BB(self.symbol, 20, MovingAverageType.Simple, Resolution.Minute)
self.oneBBTop = self.oneBB.UpperBand
self.oneBBMiddle = self.oneBB.MiddleBand
self.oneBBBottom = self.oneBB.LowerBand
# 5 Minute Indicators
self.fiveBB = self.BB(self.symbol, 20, MovingAverageType.Simple)
self.fiveBBTop = self.fiveBB.UpperBand
self.fiveBBMiddle = self.fiveBB.MiddleBand
self.fiveBBBottom = self.fiveBB.LowerBand
self.fiveCCI = self.CCI(self.symbol, 20, MovingAverageType.Simple)
self.fiveRSI = self.RSI(self.symbol, 14, MovingAverageType.Simple)
# 30 Minute Indicators
self.thirtyBB = self.BB(self.symbol, 20, MovingAverageType.Simple)
self.thirtyBBW = self.thirtyBB.BandWidth
self.thirtyCCI = self.CCI(self.symbol, 20, MovingAverageType.Simple)
self.thirtyRSI = self.RSI(self.symbol, 14, MovingAverageType.Simple)
# 1 Hour Indicators
self.sixtyCCI = self.CCI(self.symbol, 20, MovingAverageType.Simple)
self.sixtyRSI = self.RSI(self.symbol, 14, MovingAverageType.Simple)
# 4 Hour Indicators
self.fourCCI = self.CCI(self.symbol, 20, MovingAverageType.Simple)
self.fourRSI = self.RSI(self.symbol, 14, MovingAverageType.Simple)
self.fourMACD = self.MACD(self.symbol, 12, 26, MovingAverageType.Simple)
# 1 Day Indicators
self.dayCCI = self.CCI(self.symbol, 20, MovingAverageType.Simple)
self.dayRSI = self.RSI(self.symbol, 14, MovingAverageType.Simple)
self.dayMACD = self.MACD(self.symbol, 12, 26, MovingAverageType.Simple)
# 1 Week Indicators
self.weekBB = self.BB(self.symbol, 20, MovingAverageType.Simple)
self.weekBBBottom = self.weekBB.LowerBand
# define our 5 minute trade bar consolidator. we can
# access the 5 minute bar from the DataConsolidated events
fiveMinuteConsolidator = TradeBarConsolidator(timedelta(minutes=5))
# attach our event handler. the event handler is a function that will
# be called each time we produce a new consolidated piece of data.
fiveMinuteConsolidator.DataConsolidated += self.fiveMinuteBarHandler
# this call adds our 5 minute consolidator to
# the manager to receive updates from the engine
self.SubscriptionManager.AddConsolidator(self.symbol, fiveMinuteConsolidator)
self.fiveMinuteIndicators = [self.fiveBB, self.fiveBBTop, self.fiveBBMiddle, self.fiveBBBottom, self.fiveCCI, self.fiveRSI]
for indicator in self.fiveMinuteIndicators:
self.RegisterIndicator(self.symbol, indicator, fiveMinuteConsolidator)
self.Log(str(indicator) + str(" is registered"))
# define our 30 minute trade bar consolidator. we can
# access the 30 minute bar from the DataConsolidated events
thirtyMinuteConsolidator = TradeBarConsolidator(timedelta(minutes=30))
# attach our event handler. the event handler is a function that will
# be called each time we produce a new consolidated piece of data.
thirtyMinuteConsolidator.DataConsolidated += self.thirtyMinuteBarHandler
# this call adds our 30 minute consolidator to
# the manager to receive updates from the engine
self.SubscriptionManager.AddConsolidator(self.symbol, thirtyMinuteConsolidator)
self.thirtyMinuteIndicators = [self.thirtyBB, self.thirtyyBBW, self.thirtyCCI, self.thirtyRSI]
for indicator in self.thirtyMinuteIndicators:
self.RegisterIndicator(self.symbol, indicator, thirtyMinuteConsolidator)
self.Log(str(indicator) + str(" is registered"))
# define our 60 minute trade bar consolidator. we can
# access the 60 minute bar from the DataConsolidated events
sixtyMinuteConsolidator = TradeBarConsolidator(timedelta(minutes=60))
# attach our event handler. the event handler is a function that will
# be called each time we produce a new consolidated piece of data.
sixtyMinuteConsolidator.DataConsolidated += self.sixtyMinuteBarHandler
# this call adds our 60 minute consolidator to
# the manager to receive updates from the engine
self.SubscriptionManager.AddConsolidator(self.symbol, sixtyMinuteConsolidator)
self.sixtyMinuteIndicators = [self.sixtyCCI, self.sixtyRSI]
for indicator in self.sixtyMinuteIndicators:
self.RegisterIndicator(self.symbol, indicator, sixtyMinuteConsolidator)
self.Log(str(indicator) + str(" is registered"))
# define our 4 hour trade bar consolidator. we can
# access the 4 hour bar from the DataConsolidated events
fourHourConsolidator = TradeBarConsolidator(timedelta(minutes=240))
# attach our event handler. the event handler is a function that will
# be called each time we produce a new consolidated piece of data.
fourHourConsolidator.DataConsolidated += self.fourHourBarHandler
# this call adds our 4 hour consolidator to
# the manager to receive updates from the engine
self.SubscriptionManager.AddConsolidator(self.symbol, fourHourConsolidator)
self.fourHourIndicators = [self.fourCCI, self.fourRSI, self.fourMACD]
for indicator in self.fourHourIndicators:
self.RegisterIndicator(self.symbol, indicator, fourHourConsolidator)
self.Log(str(indicator) + str(" is registered"))
# first define a one day trade bar -- this produces a consolidated piece of data after a day has passed
oneDayConsolidator = TradeBarConsolidator(timedelta(1))
# attach our event handler. the event handler is a function that will
# be called each time we produce a new consolidated piece of data.
oneDayConsolidator.DataConsolidated += self.oneDayBarHandler
# this call adds our 1 Day consolidator to
# the manager to receive updates from the engine
self.SubscriptionManager.AddConsolidator(self.symbol, oneDayConsolidator)
self.oneDayIndicators = [self.dayCCI, self.dayRSI, self.dayMACD]
for indicator in self.oneDayIndicators:
self.RegisterIndicator(self.symbol, indicator, oneDayConsolidator)
self.Log(str(indicator) + str(" is registered"))
# first define a one week trade bar -- this produces a consolidated piece of data after a week has passed
oneWeekConsolidator = TradeBarConsolidator(timedelta(7))
# attach our event handler. the event handler is a function that will
# be called each time we produce a new consolidated piece of data.
oneWeekConsolidator.DataConsolidated += self.oneWeekBarHandler
# this call adds our 1 Week consolidator to
# the manager to receive updates from the engine
self.SubscriptionManager.AddConsolidator(self.symbol, oneWeekConsolidator)
self.oneWeekIndicators = [self.weekBB, self.weekBBBottom]
for indicator in self.oneWeekIndicators:
self.RegisterIndicator(self.symbol, indicator, oneWeekConsolidator)
self.Log(str(indicator) + str(" is registered"))
'''Argument Initialization'''
# Time
self.consolidatedFiveMinute = False
self.consolidatedFifteenMinute = False
self.consolidatedThirtyMinute = False
self.consolidatedSixtyMinute = False
self.consolidatedFourHour = False
self.consolidatedDay = False
self.consolidatedWeek = False
self.__last = None
# Warm Up of our longest timeframe (1 week) defined in minutes.
self.SetWarmUp(10080, Resolution.Minute)
def OnData(self, data):
# 1 minute bar
self.Debug("1 Minute")
self.Log("1 Minute")
pass
def fiveMinuteBarHandler(self, sender, consolidated):
self.Debug("5 Minutes")
self.Log("5 Minutes")
self.consolidatedFiveMinute = True
def thirtyMinuteBarHandler(self, sender, consolidated):
self.Debug("30 Minutes")
self.Log("30 Minutes")
self.consolidatedThirtyMinute = True
def sixtyMinuteBarHandler(self, sender, consolidated):
self.Debug("60 Minutes")
self.Log("60 Minutes")
self.consolidatedHour = True
def fourHourBarHandler(self, sender, consolidated):
self.Debug("4 Hours")
self.Log("4 Hours")
self.consolidatedFourHour = True
def oneDayBarHandler(self, sender, consolidated):
self.Debug("1 Day")
self.Log("1 Day")
self.consolidatedDay = True
def oneWeekBarHandler(self, sender, consolidated):
self.Debug("1 Week")
self.Log("1 Week")
self.consolidatedWeek = True
def OnEndOfAlgorithm(self):
if not self.consolidatedWeek:
raise Exception("Expected weekly consolidator to be fired.")
Def returns
It looks like it was an issue with how I was calling the Bollinger Band Top, Middle and Bottom band. Potentially as well with the For Loop, but I haven't tested that yet.
Def returns
SOLVED: Issue was caused by trying to register .UpperBand, .MiddleBand, .LowerBand, and .BandWidth, which I guess was unnecessary!
Louis Szeto
Hi Tomes
The error message indicates that the problem was resulted by the third argument of the indicator method is not in the correct type. The Bollinger Band indicator requires inputs in the following:
In the provided code snippets, the 3rd attribute is missing. It is most commonly using the value of 2.
Also, for custom periods (5 minutes, 30 minutes, 4 hours, 1 week). We should use manual-updating indicators like BollingerBand(period, standard_deviation_level, moving_average_type) instead of self.BB and register the manual-updating indicator by self.RegisterIndicator. Please check this doc for example. While 1 minute, 1 hour and 1 day can keep using self.BB with stated resolution at the last argument.
Best
Louis Szeto
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.
Def returns
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!