Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
TypeError: unhashable type: 'list'

Hi all! First time poster, long time lurker.

First off, I am so thankful I stumbled upon this site. Thank you for providing us little guys with the means to research strategies, Quantopian!

I am having some issues with an algo I cannibalized from here:
https://www.quantopian.com/posts/etf-rotation-strategy

when trying to marry it with a trailing stop loss idea found here:
https://www.quantopian.com/posts/trailing-stop-loss

The error I am getting is in line 143 of the "set_trailing_stop" funciton. The error is as follows:

TypeError: unhashable type: 'list'  
...
USER ALGORITHM:143, in set_trailing_stop  
if context.portfolio.positions[context.stock].amount:  

Any help would be greatly appreciated.

8 responses

The ETF code is using context.stock (singular) but storing a list in it, and the trailing stoploss code expected just one security object in that variable.

Since you already added the needed loop, in set_trailing_stop() you can just replace context.stock with simply stock.
Next will be an error about the older data[stock].price method, replace with data.current(stock, 'price'). Looking up the price one time is more efficient:

    for stock in context.portfolio.positions:  
        price = data.current(stock, 'price')  
        if context.portfolio.positions[stock].amount:  
            context.stop_price = max(context.stop_price, context.stop_pct * price)

        if price < context.stop_price:  
            order_target(stock, 0)  
            context.stop_price = 0  
            log.info("Stop Loss'd " + str(stock.symbol))  

In the trailing stoploss code, many of the examples are manually handling a stop threshold while one example on the page uses the built-in StopOrder. Others can be found here:

https://www.google.com/search?q="style=+StopOrder"+site%3Aquantopian.com

Well its running, but the stop loss isn't selling appropriately. It appears that last bit of code prefers to sell everything but one stock, which leads me to believe its calculating a stop loss price for one stock, stock A, then judging the stocks B and C off their price relationship to stop loss price A. For example, RING and SLVP sell nearly immediately upon purchase, but in April of 2016, they were well on their way up! The sale took place while the stock was up from their original purchase price.

I've tried to play around with the code, move some code around, etc. but the problem still persists. Any thoughts?

Low volume stocks. Trade Info

You think so?

I could just not be understanding, but that doesn't explain to me why I buy a stock at 8am, and then two hours later on the same day (when the stop loss code operates) it starts selling the stock, when the stock itself is on its way up? (I'm looking at RING in April of 2016)

Edit: My first reply was unclear. I'm not so worried that when the stop loss order is activated, it takes a while to sell the full position, I'm concerned that it's selling prematurely. I will buy a stock at 8:30am, then it sells at 10am the same day, for no reason. The stock is on the way up, but the stop loss code is selling anyways.

You think so?

I'm just going by the output. Please take a look at the content in link I provided. If you increment a counter each time any stock's order fills zero shares, it reaches nearly 10,000.

The problem of selling unexpectedly would be because RING stopped out on a stored price from another stock.

Here's a way you can store them individually, could just be a dictionary, however I'm using a pandas series.

Also added logging of those, looks like this:

2016-09-01 06:31 rebalance:99 INFO      Prc       %        Stp     Symbol  
2016-09-01 06:31 rebalance:107 INFO   121.54     121.0    100.41   IVW  
2016-09-01 06:31 rebalance:107 INFO    42.51      60.4     70.36   IUSG  
2016-09-01 06:31 rebalance:107 INFO   136.93     124.6    109.88   IJT  
2016-09-01 06:31 rebalance:107 INFO    84.90     117.2     72.46   SHY  
2016-09-01 06:31 rebalance:107 INFO    45.96     114.9     39.98   USMV  
2016-09-01 06:31 rebalance:107 INFO    10.52      93.6     11.24   RING  
2016-09-01 06:31 rebalance:107 INFO    13.47      93.4     14.42   SLVP  
2016-09-01 06:31 rebalance:107 INFO    28.06     129.0     21.75   ILF  
2016-09-01 06:31 rebalance:128 INFO ETF Month  
2016-09-02 08:30 set_trailing_stop:164 INFO Stop Loss'd RING at prc 11.21, 99.7% of stp prc 11.24  
2016-09-02 08:30 set_trailing_stop:164 INFO Stop Loss'd SLVP at prc 14.40, 99.9% of stp prc 14.42  

There's far more than enough power to handle stops every minute if you want to:

    for i in range(1, 391, 1):  # start, end + 1, every i (currently 1)  
        schedule_function(set_trailing_stop,  
                          date_rules.every_day(), time_rules.market_open(minutes=i))  

Blue Seahawk that worked like a charm. Thanks a ton!

The hash() is a built-in python method, used to return a unique number . This can be applied to any user-defined object which won’t get changed once initialized. This property is used mainly in dictionary keys .

TypeError: unhashable type: 'list' usually means that you are trying to use a list as an hash argument. This means that when you try to hash an unhashable object it will result an error. For ex. when you use a list as a key in the dictionary , this cannot be done because lists can't be hashed. The standard way to solve this issue is to cast a list to a tuple .