I'm getting runtime errors on the basic futures template.
Runtime Error: AttributeError : 'datetime.datetime' object has no attribute 'Date' at OnData
def OnData(self, slice):
if not self.Portfolio.Invested:
for chain in slice.FutureChains:
# find the front contract expiring no earlier than in 90 days
contracts = [ i for i in chain.Value if i.Expiry > self.Time.Date.AddDays(180) ]
# if thre is more than one contract, trade the one woth the closes expire date
if len(contracts) > 0:
contract = sorted(contracts, key=lambda x: x.Volume, reverse=False)[0]
self.MarketOrder(contract.Symbol, 1);
Then, if I modify the line to remedy the error (simply putting contracts = chain.Values.Contracts), I get the following TypeError:
Runtime Error: TypeError : object of type 'FuturesContracts' has no len()
def OnData(self, slice):
if not self.Portfolio.Invested:
for chain in slice.FutureChains:
contracts = chain.Values.Contracts
if len(contracts) > 0:
contract = sorted(contracts, key=lambda x: x.Volume, reverse=False)[0]
self.MarketOrder(contract.Symbol, 1);
else:
self.Liquidate();
I'm just trying to change the code from sorting by expiry to sorting by volume. Seems like it should be simple but I'm running into some difficulties, obviously.
Sebastien Winsor
No way to edit??
Jing Wu
Hi Sebastien, self.Time is a python datetime object, you should use the python syntax
self.Time.date() + timedelta(days=2)
chain.Values.Contracts is not a list, you should use the following statement to get a list of future contracts
for chain in slice.FutureChains: contracts = [i for i in chain.Value]
Please see the basic futures algorithm
Volume property is not available for the futures contract, you could find properties of FuturesContract in the doc
https://www.quantconnect.com/lean/documentation/topic24129.html
Sebastien Winsor
Thanks Jing. I did manage to solve the datetime object attribute error. For the type error, the documentation appears misleading somewhat, and lists volume as a property of the contract; is there a mistake with the documentation?
# Explore the future contract chain def OnData(self, slice): for chain in slice.FutureChains.Values: contracts = chain.Contracts for contract in contracts: pass class FuturesContract: self.Symbol # (Symbol) Symbol for contract needed to trade. self.UnderlyingSymbol # (Symbol) Underlying futures asset. self.Expiry # (datetime) When the future expires self.OpenInterest # (decimal) Number of open interest. self.LastPrice # (decimal) Last sale price. self.Volume # (long) reported volume. self.BidPrice # (decimal) bid quote price. self.BidSize # (long) bid quote size. self.AskPrice # (decimal) ask quote price. self.AskSize # (long) ask quote size.
In any case, we should be able to use open interest to identify the active contract. Ideally we'd use volume, but OI should work too. The following code will select the contract in the futurechain with the highest OI, correct?
def OnData(self,slice): if not self.Portfolio.Invested: for chain in slice.FutureChains: contracts = [i for i in chain.Value] active = sorted(contracts, key = lambda x: x.OpenInterest, reverse=False)[0]
Sebastien Winsor
I have one other issue with orders specifically. For some reason at the moment I'm unable to post a reply with a backtest attached so I posted the code below. It's the same logic used in several templates, however my algorithm constantly buys/liquidates holdings, almost as if futures were not recognized by self.Portfolio.Invested. I fill up the 10k order limit in a matter of hours. Can you see what the issue is here?
Many thanks for all your help.
from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Securities import * from datetime import timedelta class BasicTemplateFuturesAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2013, 10, 7) self.SetEndDate(2013, 10, 11) self.SetCash(1000000) # Subscribe and set our expiry filter for the futures chain futureES = self.AddFuture(Futures.Indices.SP500EMini) futureES.SetFilter(timedelta(0), timedelta(182)) futureGC = self.AddFuture(Futures.Metals.Gold) futureGC.SetFilter(timedelta(0), timedelta(182)) def OnData(self,slice): if not self.Portfolio.Invested: for chain in slice.FutureChains: contracts = [i for i in chain.Value] if len(contracts) > 0: active = sorted(contracts, key=lambda x: x.OpenInterest, reverse=False)[0] self.MarketOrder(active.Symbol, 1); else: self.Liquidate()
Sebastien Winsor
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!