Back

Help with Algo Issue : KeyError : -1

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 = []
Update Backtest








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

0

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.

0

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

0

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.

0

Update Backtest





0

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.


Loading...

This discussion is closed