-
Notifications
You must be signed in to change notification settings - Fork 679
/
Copy pathfred.py
71 lines (61 loc) · 2 KB
/
fred.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from pandas import concat, read_csv
from pandas_datareader.base import _BaseReader
from pandas_datareader.compat import is_list_like
class FredReader(_BaseReader):
"""
Get data for the given name from the St. Louis FED (FRED).
"""
@property
def url(self):
"""API URL"""
return "https://fred.stlouisfed.org/graph/fredgraph.csv"
def read(self):
"""Read data
Returns
-------
data : DataFrame
If multiple names are passed for "series" then the index of the
DataFrame is the outer join of the indices of each series.
"""
try:
return self._read()
finally:
self.close()
def _read(self):
if not is_list_like(self.symbols):
names = [self.symbols]
else:
names = self.symbols
urls = [f"{self.url}?id={n}" for n in names]
def fetch_data(url, name):
"""Utility to fetch data"""
resp = self._read_url_as_StringIO(url)
data = read_csv(
resp,
index_col=0,
parse_dates=True,
header=None,
skiprows=1,
names=["DATE", name],
na_values=".",
)
try:
return data.truncate(self.start, self.end)
except KeyError as exc: # pragma: no cover
if data.iloc[3].name[7:12] == "Error":
raise OSError(
"Failed to get the data. Check that "
"{!r} is a valid FRED series.".format(name)
) from exc
raise
try:
data = [fetch_data(url, n) for url, n in zip(urls, names, strict=True)]
except TypeError:
# Python 3.9 only
data = [fetch_data(url, n) for url, n in zip(urls, names)] # noqa: B905
df = concat(
data,
axis=1,
join="outer",
)
return df