From b26534264f6c456711719f42ea13cfdee713b792 Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Mon, 13 Apr 2020 14:29:27 +0100 Subject: [PATCH 1/5] Add av-forex-daily endpoint for historical currency exchange rates from AlphaVantange. --- pandas_datareader/av/time_series.py | 11 ++++++++++- pandas_datareader/data.py | 13 +++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pandas_datareader/av/time_series.py b/pandas_datareader/av/time_series.py index 22d09d9d..ace052e1 100644 --- a/pandas_datareader/av/time_series.py +++ b/pandas_datareader/av/time_series.py @@ -39,6 +39,7 @@ class AVTimeSeriesReader(AlphaVantage): "TIME_SERIES_MONTHLY": "Monthly Time Series", "TIME_SERIES_MONTHLY_ADJUSTED": "Monthly Adjusted Time Series", "TIME_SERIES_INTRADAY": "Time Series (1min)", + "FX_DAILY": "Time Series FX (Daily)", } def __init__( @@ -77,6 +78,10 @@ def function(self): def intraday(self): return True if self.function == "TIME_SERIES_INTRADAY" else False + @property + def forex(self): + return True if self.function == "FX_DAILY" else False + @property def output_size(self): """ Used to limit the size of the Alpha Vantage query when @@ -92,13 +97,17 @@ def data_key(self): @property def params(self): p = { - "symbol": self.symbols, "function": self.function, "apikey": self.api_key, "outputsize": self.output_size, } if self.intraday: p.update({"interval": "1min"}) + if self.forex: + p.update({"from_symbol": self.symbols.split("/")[0]}) + p.update({"to_symbol": self.symbols.split("/")[1]}) + else: + p.update({"symbol": self.symbols}) return p def _read_lines(self, out): diff --git a/pandas_datareader/data.py b/pandas_datareader/data.py index b78884f4..64cc8a5e 100644 --- a/pandas_datareader/data.py +++ b/pandas_datareader/data.py @@ -361,6 +361,7 @@ def DataReader( "yahoo-actions", "yahoo-dividends", "av-forex", + "av-forex-daily", "av-daily", "av-daily-adjusted", "av-weekly", @@ -567,6 +568,18 @@ def DataReader( api_key=api_key, ).read() + elif data_source == "av-forex-daily": + return AVTimeSeriesReader( + symbols=name, + function="FX_DAILY", + start=start, + end=end, + retry_count=retry_count, + pause=pause, + session=session, + api_key=api_key, + ).read() + elif data_source == "av-daily": return AVTimeSeriesReader( symbols=name, From bc94308b801d358ac1e8b0f4ce2b91c619113dce Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Mon, 13 Apr 2020 14:39:44 +0100 Subject: [PATCH 2/5] Add av-forex-daily to documentation. --- docs/source/remote_data.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/source/remote_data.rst b/docs/source/remote_data.rst index b463e978..daeac873 100644 --- a/docs/source/remote_data.rst +++ b/docs/source/remote_data.rst @@ -139,7 +139,7 @@ Historical Time Series Data Through the `Alpha Vantage `__ Time Series -endpoints, it is possible to obtain historical equities data for individual +endpoints, it is possible to obtain historical equities and currency rate data for individual symbols. For daily, weekly, and monthly frequencies, 20+ years of historical data is available. The past 3-5 days of intraday data is also available. The following endpoints are available: @@ -151,6 +151,7 @@ The following endpoints are available: * ``av-weekly-adjusted`` - Weekly Time Series (Adjusted) * ``av-monthly`` - Monthly Time Series * ``av-monthly-adjusted`` - Monthly Time Series (Adjusted) +* ``av-forex-daily`` - Daily Time Series .. code-block:: ipython @@ -173,6 +174,8 @@ The following endpoints are available: volume 2.834990e+07 Name: 2017-02-09, dtype: float64 +To request the historical exchange rate of physical or digital currencies, use +``av-forex-daily`` and format the symbol as "FROM/TO", for example "USD/JPY". The top-level function ``get_data_alphavantage`` is also provided. This function will From 29063c693a9185ed3c64e0cef18b0d34795b4742 Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Mon, 13 Apr 2020 14:45:38 +0100 Subject: [PATCH 3/5] Updated whatsnew. --- docs/source/whatsnew/v0.9.0.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/whatsnew/v0.9.0.txt b/docs/source/whatsnew/v0.9.0.txt index 5a9e2b83..c6642666 100644 --- a/docs/source/whatsnew/v0.9.0.txt +++ b/docs/source/whatsnew/v0.9.0.txt @@ -16,6 +16,7 @@ Highlights include: Enhancements ~~~~~~~~~~~~ +- Added AlphaVantage endpoint to get historical currency exchange rates. .. _whatsnew_090.api_breaking: @@ -33,3 +34,4 @@ Bug Fixes Contributors ~~~~~~~~~~~~ - David Stephens +- Matthew Hall From 6f85da9695fc03775d00ae9e87f5a24057fb3159 Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Tue, 14 Apr 2020 13:48:46 +0100 Subject: [PATCH 4/5] Add test for av-forex-daily. --- pandas_datareader/tests/av/test_av_time_series.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pandas_datareader/tests/av/test_av_time_series.py b/pandas_datareader/tests/av/test_av_time_series.py index 08caa944..95f8a0be 100644 --- a/pandas_datareader/tests/av/test_av_time_series.py +++ b/pandas_datareader/tests/av/test_av_time_series.py @@ -194,3 +194,17 @@ def test_av_intraday(self): assert len(df) > 1000 assert "open" in df.columns assert "close" in df.columns + + def test_av_forex_daily(self): + df = web.DataReader( + "USD/JPY", + "av-forex-daily", + start=self.start, + end=self.end, + retry_count=6, + pause=20.5, + ) + assert df.columns.equals(self.col_index[:4]) # No volume col for forex + assert len(df) == 718 + assert df.loc["2015-02-09"]["close"] == 118.6390 + assert df.loc["2017-05-24"]["high"] == 112.1290 From c61f394c15bda9280d8796dab474ca92f3324558 Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Tue, 14 Apr 2020 14:01:50 +0100 Subject: [PATCH 5/5] Black formatting fixes. --- pandas_datareader/tests/av/test_av_time_series.py | 2 +- pandas_datareader/yahoo/daily.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas_datareader/tests/av/test_av_time_series.py b/pandas_datareader/tests/av/test_av_time_series.py index 95f8a0be..0dedf65c 100644 --- a/pandas_datareader/tests/av/test_av_time_series.py +++ b/pandas_datareader/tests/av/test_av_time_series.py @@ -204,7 +204,7 @@ def test_av_forex_daily(self): retry_count=6, pause=20.5, ) - assert df.columns.equals(self.col_index[:4]) # No volume col for forex + assert df.columns.equals(self.col_index[:4]) # No volume col for forex assert len(df) == 718 assert df.loc["2015-02-09"]["close"] == 118.6390 assert df.loc["2017-05-24"]["high"] == 112.1290 diff --git a/pandas_datareader/yahoo/daily.py b/pandas_datareader/yahoo/daily.py index c6ec5e85..e1578b09 100644 --- a/pandas_datareader/yahoo/daily.py +++ b/pandas_datareader/yahoo/daily.py @@ -199,7 +199,7 @@ def _read_one_data(self, url, params): def split_ratio(row): if float(row["Numerator"]) > 0: if ":" in row["Splitratio"]: - n, m = row["Splitratio"].split(':') + n, m = row["Splitratio"].split(":") return float(m) / float(n) else: return eval(row["Splitratio"])