Skip to content

Commit

Permalink
Merge 9a9971d into f50e5cc
Browse files Browse the repository at this point in the history
  • Loading branch information
bashtage committed Jan 11, 2018
2 parents f50e5cc + 9a9971d commit 0f7111d
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 15 deletions.
31 changes: 31 additions & 0 deletions pandas_datareader/bankofcanada.py
@@ -0,0 +1,31 @@
from __future__ import unicode_literals

import pandas.compat as compat

from pandas_datareader.base import _BaseReader


class BankOfCanadaReader(_BaseReader):
"""Get data for the given name from Bank of Canada."""

_URL = 'http://www.bankofcanada.ca/valet/observations'

@property
def url(self):
if not isinstance(self.symbols, compat.string_types):
raise ValueError('data name must be string')

return '{0}/{1}/csv'.format(self._URL, self.symbols)

@property
def params(self):
return {'start_date': self.start.strftime('%Y-%m-%d'),
'end_date': self.end.strftime('%Y-%m-%d')}

@staticmethod
def _sanitize_response(response):
"""
Clean up the response string
"""
data = response.text.split('OBSERVATIONS')[1]
return data.split('ERRORS')[0].strip()
1 change: 0 additions & 1 deletion pandas_datareader/base.py
Expand Up @@ -17,7 +17,6 @@
class _BaseReader(object):

"""
Parameters
----------
sym : string with a single Single stock symbol (ticker).
Expand Down
38 changes: 24 additions & 14 deletions pandas_datareader/data.py
Expand Up @@ -4,25 +4,30 @@

import warnings

from pandas_datareader.bankofcanada import BankOfCanadaReader
from pandas_datareader.edgar import EdgarIndexReader
from pandas_datareader.enigma import EnigmaReader
from pandas_datareader.eurostat import EurostatReader
from pandas_datareader.famafrench import FamaFrenchReader
from pandas_datareader.fred import FredReader
from pandas_datareader.google.daily import GoogleDailyReader
from pandas_datareader.google.quotes import GoogleQuotesReader
from pandas_datareader.google.options import Options as GoogleOptions

from pandas_datareader.yahoo.daily import YahooDailyReader
from pandas_datareader.yahoo.quotes import YahooQuotesReader
from pandas_datareader.google.quotes import GoogleQuotesReader
from pandas_datareader.moex import MoexReader
from pandas_datareader.nasdaq_trader import get_nasdaq_symbols
from pandas_datareader.oecd import OECDReader
from pandas_datareader.quandl import QuandlReader
from pandas_datareader.yahoo.actions import (YahooActionReader, YahooDivReader)
from pandas_datareader.yahoo.components import _get_data as get_components_yahoo # noqa
from pandas_datareader.yahoo.components import _get_data as \
get_components_yahoo
from pandas_datareader.yahoo.daily import YahooDailyReader
from pandas_datareader.yahoo.options import Options as YahooOptions
from pandas_datareader.yahoo.quotes import YahooQuotesReader

from pandas_datareader.eurostat import EurostatReader
from pandas_datareader.fred import FredReader
from pandas_datareader.famafrench import FamaFrenchReader
from pandas_datareader.oecd import OECDReader
from pandas_datareader.edgar import EdgarIndexReader
from pandas_datareader.enigma import EnigmaReader
from pandas_datareader.nasdaq_trader import get_nasdaq_symbols
from pandas_datareader.quandl import QuandlReader
from pandas_datareader.moex import MoexReader
__all__ = ['get_components_yahoo', 'get_data_enigma', 'get_data_famafrench',
'get_data_fred', 'get_data_google', 'get_data_moex',
'get_data_quandl', 'get_data_yahoo', 'get_data_yahoo_actions',
'get_nasdaq_symbols', 'get_quote_google', 'get_quote_yahoo']


def get_data_fred(*args, **kwargs):
Expand Down Expand Up @@ -141,6 +146,11 @@ def DataReader(name, data_source=None, start=None, end=None,
retry_count=retry_count, pause=pause,
session=session).read()

elif data_source == "bankofcanada":
return BankOfCanadaReader(symbols=name, start=start, end=end,
retry_count=retry_count, pause=pause,
session=session).read()

elif data_source == "enigma":
return EnigmaReader(dataset_id=name, api_key=access_key).read()

Expand Down
67 changes: 67 additions & 0 deletions pandas_datareader/tests/test_bankofcanada.py
@@ -0,0 +1,67 @@
from datetime import date, timedelta

import pytest

import pandas_datareader.data as web
from pandas_datareader._utils import RemoteDataError


class TestBankOfCanada(object):

@staticmethod
def get_symbol(currency_code, inverted=False):
if inverted:
return 'FXCAD{}'.format(currency_code)
else:
return 'FX{}CAD'.format(currency_code)

def check_bankofcanada_count(self, code):
df = web.DataReader(self.get_symbol(code), 'bankofcanada',
date.today() - timedelta(days=30), date.today())
assert df.size > 15

def check_bankofcanada_valid(self, code):
symbol = self.get_symbol(code)
df = web.DataReader(symbol, 'bankofcanada',
date.today() - timedelta(days=30), date.today())
assert symbol in df.columns

def check_bankofcanada_inverted(self, code):
symbol = self.get_symbol(code)
symbol_inverted = self.get_symbol(code, inverted=True)

df = web.DataReader(symbol, 'bankofcanada',
date.today() - timedelta(days=30), date.today())
df_i = web.DataReader(symbol_inverted, 'bankofcanada',
date.today() - timedelta(days=30), date.today())

pairs = zip((1 / df)[symbol].tolist(), df_i[symbol_inverted].tolist())
assert all(a - b < 0.01 for a, b in pairs)

def test_bankofcanada_usd_count(self):
self.check_bankofcanada_count('USD')

def test_bankofcanada_eur_count(self):
self.check_bankofcanada_count('EUR')

def test_bankofcanada_usd_valid(self):
self.check_bankofcanada_valid('USD')

def test_bankofcanada_eur_valid(self):
self.check_bankofcanada_valid('EUR')

def test_bankofcanada_usd_inverted(self):
self.check_bankofcanada_inverted('USD')

def test_bankofcanada_eur_inverted(self):
self.check_bankofcanada_inverted('EUR')

def test_bankofcanada_bad_range(self):
with pytest.raises(RemoteDataError):
web.DataReader('FXCADUSD', 'bankofcanada',
date.today(), date.today() - timedelta(days=30))

def test_bankofcanada_bad_url(self):
with pytest.raises(RemoteDataError):
web.DataReader('abcdefgh', 'bankofcanada',
date.today() - timedelta(days=30), date.today())

0 comments on commit 0f7111d

Please sign in to comment.