Hi Everyone,
I've been struggling with trying to get my crude oil and gasoline futures Indicator Extensions to work. I copy pasted this from my S&P/Nasdaq futures algorithm and just changed the symbols but i'm getting this error. Can someone take a look please?
Runtime Error: AttributeError : 'BasicTemplateFuturesAlgorithm' object has no attribute 'rbsma'
at OnData in main.py:line 39
AttributeError : 'BasicTemplateFuturesAlgorithm' object has no attribute 'rbsma'
Douglas Stridsberg
Your error implies you're trying to access a property which does not exist.
You're initialising the rbsma field in a function which may or may not be run before your twoforty() function where you're calling that field.
Initialise rbsma in your Initialize() function instead (as you've done with frontCL and frontRB), as it's guaranteed it will run before anything else.
Apollos Hill
HI Douglas,
Thanks for your help. When i do that i get:
Object reference not set to an instance of an object
Here is my backtest.
How do you think i should put it in the initialize function? I have tried
self.rbsma = self.SMA("RB", 60, Resolution.Minute)
and
self.rbsma = self.SMA(self.frontRB.Symbol 60, Resolution.Minute) (which i know doesn't work because there is no symbol property yet)
Douglas Stridsberg
It's possible that your new error stems from something else in your code. It's hard to see with all the comments and general fluff. Can you remove all but the strictly necessary pieces of code and send that? This is a good guide on how to create a minimal working example.
Also, the code attached is identical to the previous one you sent. Can you send the code you tried with the changes you made?
Apollos Hill
That's weird. I see all the fluff you are talking about. that backtest doesn't look that way in my portal. only in the forums here. I'm just baffled that the RB specifically can't load an SMA when i copy pasted this verbatim from my NQ/ES algo that Jack Simonson helped me with.
from datetime import timedelta
import decimal
class BasicTemplateFuturesAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2019, 1, 1)
self.SetEndDate(2019, 5, 20)
self.SetCash(1000000)
# Subscribe and set our expiry filter for the futures chain
futureCL = self.AddFuture(Futures.Energies.CrudeOilWTI)
futureCL.SetFilter(timedelta(30), timedelta(180))
futureRB = self.AddFuture(Futures.Energies.Gasoline)
futureRB.SetFilter(timedelta(30), timedelta(180))
self.frontCL = None
self.frontRB = None
self.rbsma = self.SMA(self.frontRB, 60, Resolution.Minute)
def OnData(self,slice):
for chain in slice.FutureChains:
contracts = list(filter(lambda x: x.Expiry > self.Time + timedelta(45), chain.Value))
for contract in contracts:
if ('RB ' in str(contract.Symbol)) and (self.frontRB is None):
self.frontRB = sorted(contracts, key = lambda x: x.Expiry, reverse=True)[0]
self.Consolidate(contract.Symbol, timedelta(minutes=120), self.twoforty)
if ('CL ' in str(contract.Symbol)) and (self.frontCL is None):
self.frontCL = sorted(contracts, key = lambda x: x.Expiry, reverse=True)[0]
self.clsma = self.SMA(self.frontCL.Symbol, 60, Resolution.Minute)
self.clrbsma = IndicatorExtensions.Minus(self.clsma, self.rbsma)
def OnOrderEvent(self, orderEvent):
pass
def twoforty(self, consolidated):
self.consolidated45Minute = True
if not self.Portfolio.Invested:
self.MarketOrder(self.frontRB.Symbol , -1)
self.MarketOrder(self.frontCL.Symbol , 1)
self.Debug("clrbsma!!!: " + str(self.clrbsma.Current.Value))
self.Log("front rb cont symbol: " + str(self.frontRB.Symbol))
Douglas Stridsberg
There's still fluff - your Debug and Log statements should go in order to produce a proper minimal working example.
As it happens, I think your error is in your last two debug and log statements. You're trying to use a variable that may not yet have been initialised.
Also, you're creating a new SMA each time you get data arriving, as you've decided to put your indicator initialiser inside your OnData, which means that variable will be reset each time you get new data.
I think it might be worth going over some of the example algorithms and seeing how things should be done correctly. The GitHub repo contains a lot of them.
If that doesn't help, I think you might need to think over the structure of your strategy. You should never put code in your OnData that initialises or otherwise "starts" something afresh. Your OnData should simply be doing calculations on pre-existing variables that should have been initialsied earlier. You should never register a new Consolidator inside OnData. The list goes on.
Apollos Hill
Hi I have said before that i am copying this word for word the way the employee showed me. If you could get a working example going for me that proves exactly what you are talking about then i can take a look. Or if you could just write out a snippet of code of exactly what you are saying. I know what you mean but i'm telling you there is no way to do it. i have tried many ways.
Link Liang
Hi Apollos,
The reason is those futures are expired after about three months. Therefore we have to put an expiry check as following:
if (self.frontES is not None) and (self.Time > self.frontES.Expiry):
self.frontES = None
if (self.frontNQ is not None) and (self.Time > self.frontNQ.Expiry):
self.frontNQ = None
Hope it helps.
Apollos Hill
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!