Hi, I dont understand why I am getting a KeyError: -1 ?
Any help appreciated.
#
# QuantConnect Basic Template:
# Fundamentals to using a QuantConnect algorithm.
#
# You can view the QCAlgorithm base class on Github:
# https://github.com/QuantConnect/Lean/tree/master/Algorithm
#
from datetime import date
import numpy as np
import pandas as pd
class BasicTemplateAlgorithm(QCAlgorithm):
def Initialize(self):
# Set the cash we'd like to use for our backtest
# This is ignored in live trading
self.SetCash(10000)
# Start and end dates for the backtest.
# These are ignored in live trading.
self.SetStartDate(2015,1,1)
self.SetEndDate(2015,6,1)
# Add assets you'd like to see
self.safe = self.AddEquity("AGG", Resolution.Daily).Symbol
self.tlt = self.AddEquity("TLT", Resolution.Daily).Symbol
self.Log("Safe is: {}".format(type(self.safe)))
self.Log("Safe value: {}".format(self.safe))
self.Log("tlt is: {}".format(type(self.tlt)))
self.Log("tlt value: {}".format(self.tlt))
self._symbols = []
self._symbols.append("SPY"), self._symbols.append("EFA"), self._symbols.append("EEM"), self._symbols.append("GLD")
for stock in self._symbols:
self.AddSecurity(SecurityType.Equity, stock, Resolution.Daily)
def OnData(self, slice):
# Assign the day on the date
today = self.Time
if not (today.month == 12 or today.month == 3 or today.month == 6 or today.month == 9):
return
mom_period = 22
# Find historical price and calculate momentum
histmom = self.History(self._symbols, 22, Resolution.Daily)["close"].unstack(level=0)
# mom = (histmom[-1]/histmom[0]) - 1.0
mom = (histmom.iloc[-1]/histmom.iloc[0]) - 1.0
# mom = mom.dropna()
top_assets = mom.sort_values().index[-4:]
top_assets_values = mom.sort_values()[-4:]
self.Log("History is: {}".format(type(histmom)))
self.Log("mom is: {}".format(type(mom)))
safe_percent = 0
tlt_percent = 0
# Create list to manage Portfolio
currently_holding = []
# Rebalance Securities
for x in range(len(top_assets)):
if top_assets_values[x] > 0:
self.SetHoldings(top_assets[x], 0.45)
currently_holding.append(top_assets[x])
else:
hist = self.History(self.safe, 22, Resolution.Daily)["close"].unstack(level=0)
mom = (hist[-1]/hist[0]) - 1.0
if mom > 0:
safe_percent += 0.45
if self.safe not in currently_holding:
currently_holding.append(self.safe)
else:
tlt_percent +=0.45
if self.tlt not in currently_holding:
currently_holding.append(self.tlt)
top_up = 4 - len(top_assets)
if top_up > 0:
for x in range(top_up):
hist = self.History(self.safe, 22, Resolution.Daily)["close"].unstack(level=0)
mom = (hist[-1]/hist[0]) - 1.0
if mom > 0:
safe_percent += 0.25
if self.safe not in currently_holding:
currently_holding.append(self.safe)
else:
tlt_percent += 0.25
if self.tlt not in currently_holding:
currently_holding.append(self.tlt)
print(safe_percent, tlt_percent)
if safe_percent > 0:
self.SetHoldings(self.safe, safe_percent)
if tlt_percent > 0:
self.SetHoldings(self.tlt, tlt_percent)
print ("2" + str(currently_holding))
def clear(self, data):
today = self.Time
if not (today.month == 12 or today.month == 3 or today.month == 6 or today.month == 9):
return
print("1" + str(currently_holding))
for s in Portfolio:
self.SetHoldings(s, 0)
currently_holding = []
Lexx7
Here's the error:
Runtime Error: Python.Runtime.PythonException: KeyError : -1
at Python.Runtime.PyObject.Invoke (Python.Runtime.PyTuple args, Python.Runtime.PyDict kw) [0x00033] in <69d4fd635645431aa1e955e701040fd1>:0
at Python.Runtime.PyObject.InvokeMethod (System.String name, Python.Runtime.PyTuple args, Python.Runtime.PyDict kw) [0x00007] in <69d4fd635645431aa1e955e701040fd1>:0
at Python.Runtime.PyObject.TryInvokeMember (System.Dynamic.InvokeMemberBinder binder, System.Object[] args, System.Object& result) [0x0003e] in <69d4fd635645431aa1e955e701040fd1>:0
Dan Whitnable
The error stems from the code
mom = (hist[-1]/hist[0]) - 1.0
'hist' is a Pandas dataframe and con't (generally) be indexed like that. You can use the 'iloc' method to get the last row (which you did earlier in your code). Somethong like this:
mom = (hist.iloc[-1]/hist.iloc[0]) - 1.0
Change this in lines 80 and 94 and see if it works.
Lexx7
Thanks Dan. Good to see you over here from Quantopian. The code I posted previously actually worked fine on Quantopian but I cant see to access the research environment here so its very difficult to debug.
This is the error I have now:
ValueError : The truth value of a Series is ambiguous.
Seems to do with the data frame I think? I did a type on the log, seems fine to me?
2015-03-02 00:00:00 History is: <class 'pandas.core.frame.DataFrame'>
2015-03-02 00:00:00 mom is: <class 'pandas.core.series.Series'>
2015-03-02 00:00:00 topassets is: <class 'pandas.core.indexes.base.Index'>
2015-03-02 00:00:00 topassetsvalues is: <class 'pandas.core.series.Series'>
2015-03-02 00:00:00 topassets value: Index([u'GLD', u'EEM', u'SPY', u'EFA'], dtype='object', name=u'symbol')
2015-03-02 00:00:00 top_assets_values value: symbol
GLD -0.058824
EEM 0.015454
SPY 0.052563
EFA 0.060952
dtype: float64
Dan Whitnable
The problem is in the two 'if' statements
if mom > 0:
on lines 81 and 95 above. 'mom' is a pandas series (though it only has single row). That is why you are getting the error 'The truth value of a Series is ambiguous'. Python doesn't know how to compare a series > 0. What you really want is a single scaler value. It's a bit clugy but this works
if mom.values[0] > 0:
That will look at the values (which is actually potentially a list of values since 'mom' is a series) and then take the first value. That's the scaler number you are looking for and which can then be compared > 0.
Instead, as an alternative, you could do something like that a few lines earlier when you assign 'mom'.
Aleksey, good seeing you too over here. Keep posting. I'm learning too but always willing to help out.
Lexx7
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!