def testDownloadAndParseWeekly(self): with common.TmpDir() as tmpPath: instrument = "AAPL" path = os.path.join(tmpPath, "quandl-aapl-weekly-2010.csv") quandl.download_weekly_bars("WIKI", instrument, 2010, path, auth_token) bf = quandlfeed.Feed(frequency=bar.Frequency.WEEK) bf.addBarsFromCSV(instrument, path) bf.loadAll() # Quandl used to report 2010-1-3 as the first week of 2010. self.assertTrue(bf[instrument][0].getDateTime() in [ datetime.datetime(2010, 1, 3), datetime.datetime(2010, 1, 10) ]) self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2010, 12, 26)) self.assertEquals(bf[instrument][-1].getOpen(), 325.0) self.assertEquals(bf[instrument][-1].getHigh(), 325.15) self.assertEquals(bf[instrument][-1].getLow(), 323.17) self.assertEquals(bf[instrument][-1].getClose(), 323.6) self.assertEquals(bf[instrument][-1].getVolume(), 7969900) self.assertEquals(bf[instrument][-1].getPrice(), 323.6) # Not checking against a specific value since this is going to change # as time passes by. self.assertNotEquals(bf[instrument][-1].getAdjClose(), None)
def testDownloadAndParseDailyNoAdjClose(self): with common.TmpDir() as tmpPath: instrument = "ORCL" path = os.path.join(tmpPath, "quandl-daily-orcl-2013.csv") quandl.download_daily_bars("GOOG", "NASDAQ_ORCL", 2013, path, auth_token) bf = quandlfeed.Feed() bf.setNoAdjClose() bf.addBarsFromCSV(instrument, path) bf.loadAll() self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2013, 12, 31)) self.assertEquals(bf[instrument][-1].getOpen(), 37.94) self.assertEquals(bf[instrument][-1].getHigh(), 38.34) self.assertEquals(bf[instrument][-1].getLow(), 37.88) self.assertEquals(bf[instrument][-1].getClose(), 38.26) self.assertEquals(bf[instrument][-1].getVolume(), 11747517) self.assertEquals(bf[instrument][-1].getAdjClose(), None) self.assertEquals(bf[instrument][-1].getPrice(), 38.26)
def testDownloadAndParseDaily(self): with common.TmpDir() as tmpPath: instrument = "ORCL" path = os.path.join(tmpPath, "quandl-daily-orcl-2010.csv") quandl.download_daily_bars("WIKI", instrument, 2010, path, auth_token) bf = quandlfeed.Feed() bf.addBarsFromCSV(instrument, path) bf.loadAll() self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2010, 12, 31)) self.assertEquals(bf[instrument][-1].getOpen(), 31.22) self.assertEquals(bf[instrument][-1].getHigh(), 31.33) self.assertEquals(bf[instrument][-1].getLow(), 30.93) self.assertEquals(bf[instrument][-1].getClose(), 31.3) self.assertEquals(bf[instrument][-1].getVolume(), 11716300) self.assertEquals(bf[instrument][-1].getPrice(), 31.3) # Not checking against a specific value since this is going to change # as time passes by. self.assertNotEquals(bf[instrument][-1].getAdjClose(), None)
def testDownloadAndParseDaily_UseAdjClose(self): with common.TmpDir() as tmpPath: instrument = "ORCL" path = os.path.join(tmpPath, "quandl-daily-orcl-2010.csv") quandl.download_daily_bars("WIKI", instrument, 2010, path, auth_token) bf = quandlfeed.Feed() bf.addBarsFromCSV(instrument, path) # Need to setUseAdjustedValues(True) after loading the file because we # can't tell in advance if adjusted values are there or not. bf.setUseAdjustedValues(True) bf.loadAll() self.assertEquals(bf[instrument][-1].getDateTime(), datetime.datetime(2010, 12, 31)) self.assertEquals(bf[instrument][-1].getOpen(), 31.22) self.assertEquals(bf[instrument][-1].getHigh(), 31.33) self.assertEquals(bf[instrument][-1].getLow(), 30.93) self.assertEquals(bf[instrument][-1].getClose(), 31.3) self.assertEquals(bf[instrument][-1].getVolume(), 11716300) self.assertEquals(bf[instrument][-1].getPrice(), bf[instrument][-1].getAdjClose()) # Not checking against a specific value since this is going to change # as time passes by. self.assertNotEquals(bf[instrument][-1].getAdjClose(), None)
def build_feed(sourceCode, tableCodes, fromYear, toYear, storage, frequency=bar.Frequency.DAY, timezone=None, skipErrors=False, noAdjClose=False, authToken=None, columnNames={}, forceDownload=False): """Build and load a :class:`engine.barfeed.quandlfeed.Feed` using CSV files downloaded from Quandl. CSV files are downloaded if they haven't been downloaded before. :param sourceCode: The dataset source code. :type sourceCode: string. :param tableCodes: The dataset table codes. :type tableCodes: list. :param fromYear: The first year. :type fromYear: int. :param toYear: The last year. :type toYear: int. :param storage: The path were the files will be loaded from, or downloaded to. :type storage: string. :param frequency: The frequency of the bars. Only **engine.bar.Frequency.DAY** or **engine.bar.Frequency.WEEK** are supported. :param timezone: The default timezone to use to localize bars. Check :mod:`engine.marketsession`. :type timezone: A pytz timezone. :param skipErrors: True to keep on loading/downloading files in case of errors. :type skipErrors: boolean. :param noAdjClose: True if the instruments don't have adjusted close values. :type noAdjClose: boolean. :param authToken: Optional. An authentication token needed if you're doing more than 50 calls per day. :type authToken: string. :param columnNames: Optional. A dictionary to map column names. Valid key values are: * datetime * open * high * low * close * volume * adj_close :type columnNames: dict. :rtype: :class:`engine.barfeed.quandlfeed.Feed`. """ logger = engine.logger.getLogger("quandl") ret = quandlfeed.Feed(frequency, timezone) if noAdjClose: ret.setNoAdjClose() # Additional column names. for col, name in columnNames.iteritems(): ret.setColumnName(col, name) if not os.path.exists(storage): logger.info("Creating %s directory" % (storage)) os.mkdir(storage) for year in range(fromYear, toYear + 1): for tableCode in tableCodes: fileName = os.path.join( storage, "%s-%s-%d-quandl.csv" % (sourceCode, tableCode, year)) if not os.path.exists(fileName) or forceDownload: logger.info("Downloading %s %d to %s" % (tableCode, year, fileName)) try: if frequency == bar.Frequency.DAY: download_daily_bars(sourceCode, tableCode, year, fileName, authToken) elif frequency == bar.Frequency.WEEK: download_weekly_bars(sourceCode, tableCode, year, fileName, authToken) else: raise Exception("Invalid frequency") except Exception, e: if skipErrors: logger.error(str(e)) continue else: raise e ret.addBarsFromCSV(tableCode, fileName)
def testInvalidFrequency(self): with self.assertRaisesRegexp(Exception, "Invalid frequency.*"): quandlfeed.Feed(frequency=bar.Frequency.MINUTE)