pythonpython-2.7pyalgotrade

KeyError importing yahoo bars with Pyalgotrade


I have run into a problem where python is throwing a KeyError when trying to reference stock prices in pyalgotrade's onBars function. The interesting thing is that it depends which stocks you are trying to access. The following code does not work and throws the error:

from pyalgotrade import strategy
from pyalgotrade.tools import yahoofinance
from pyalgotrade.technical import ma
from pyalgotrade.stratanalyzer import returns
from pyalgotrade.stratanalyzer import sharpe
from pyalgotrade.utils import stats
from pyalgotrade.barfeed import yahoofeed
import os
import sys

class MyStrategy(strategy.BacktestingStrategy):
    def __init__(self, feed, instruments):

        strategy.BacktestingStrategy.__init__(self, feed, 1000)
        self.__position = {}
        self.__instruments = instruments
        self.__sma20 = {}
        self.__sma200 = {}

        for inst in instruments:
            price = feed[inst].getCloseDataSeries()
            self.__sma20[inst] = ma.SMA(price, 20)
            self.__sma200[inst] = ma.SMA(price, 200)

        # We'll use adjusted close values instead of regular close values.
        self.setUseAdjustedValues(True)

    def onEnterOk(self, position):
        execInfo = position.getEntryOrder().getExecutionInfo()
        self.info("BUY " + str(position.getEntryOrder().getInstrument()) +" at " +str((execInfo.getPrice())) )

    def onEnterCanceled(self, position):
        execInfo = position.getEntryOrder().getExecutionInfo()
        self.info("onEnterCanceled " + str(position.getEntryOrder().getInstrument()) +" at " +str((execInfo.getPrice())) )

    def onBars(self, bars):
        #print bars['AAD'].getClose()
        for key in bars.keys():
            print key
        #sys.exit()
        for inst in self.__instruments:
            print inst

            self.info(bars[inst].getClose())
            print self.__sma20[inst][-1]
            if self.__sma20[inst][-1]  > self.__sma200[inst][-1] :
              print "go long"


def run_strategy():
        # Load the yahoo feed from the CSV file
        stocks = ["ABP.AX","AGL.AX","ALL.AX","ALQ.AX","AMC.AX","AMP.AX","ANN.AX","ANZ.AX","APA.AX","APN.AX"]
        #stocks = ['AAPL', 'IBM', 'MSFT', 'DOW', 'AXP','BA','CSCO','CVX','DD','DIS','GE','GS','HD','INTC','JNJ']
        feed = yahoofinance.build_feed(stocks, 2003, 2014, "./DailyStockPrices")

        # Evaluate the strategy with the feed.
        myStrategy = MyStrategy(feed, stocks)
        myStrategy.run()
        print "Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity()

run_strategy()

The stocks are Australian stocks and all valid. The yahoofeed module downloads them. If I comment out the line beginning with stocks = and uncomment the line below to use US stocks it works perfectly.

My first thought was full stops in the stock codes but if you run it, it prints out the contents of bars.keys() and this keeps changing which appears to be the cause of the issue. It eventually errors on one that doesn't exist but why the contents change on every bar is beyond me.

Can anyone explain or help fix this phenomena? I very much like Pyalgotrade and have been looking at Zipline as an alternative but it's too slow.


Solution

  • I think that the problem is that you're assuming that for each date (on each call to onBars) you have prices for all instruments, and that may not be the case. Try printing the datetime (bars.getDateTime()) and then take a look at the file with the prices for that instrument.