Skip to content

Commit de0197e

Browse files
author
David Stephens
committed
Clean up Yahoo daily to use DailyBaseReader methods
1 parent 12d8477 commit de0197e

File tree

2 files changed

+23
-65
lines changed

2 files changed

+23
-65
lines changed

pandas_datareader/yahoo/actions.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pandas import (Panel, concat, DataFrame)
1+
from pandas import (concat, DataFrame, MultiIndex)
22
from pandas_datareader.yahoo.daily import YahooDailyReader
33

44

@@ -11,12 +11,12 @@ class YahooActionReader(YahooDailyReader):
1111

1212
def read(self):
1313
data = super(YahooActionReader, self).read()
14-
if isinstance(data, Panel):
15-
data = data.swapaxes('minor', 'items')
16-
actions = {}
17-
for s in data:
14+
actions = {}
15+
if isinstance(data.columns, MultiIndex):
16+
data = data.swaplevel(0, 1, axis=1)
17+
for s in data.columns.levels[0]:
1818
actions[s] = _get_one_action(data[s])
19-
return Panel(actions).swapaxes('items', 'minor')
19+
return actions
2020
else:
2121
return _get_one_action(data)
2222

pandas_datareader/yahoo/daily.py

Lines changed: 17 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,15 @@
33
import json
44
import re
55
import time
6-
import warnings
7-
8-
import numpy as np
9-
import pandas.compat as compat
10-
from pandas import (Panel, DataFrame, to_datetime, notnull, isnull)
11-
from pandas_datareader._utils import (RemoteDataError, SymbolWarning)
12-
from pandas_datareader.base import (_DailyBaseReader, _in_chunks)
6+
from pandas import (DataFrame, to_datetime, notnull, isnull)
7+
from pandas_datareader._utils import RemoteDataError
8+
from pandas_datareader.base import _DailyBaseReader
139

1410

1511
class YahooDailyReader(_DailyBaseReader):
1612
"""
17-
Returns DataFrame/Panel of with historical over date range, start to end.
13+
Returns DataFrame of with historical over date range,
14+
start to end.
1815
To avoid being penalized by Yahoo! Finance servers, pauses between
1916
downloading 'chunks' of symbols can be specified.
2017
@@ -96,6 +93,10 @@ def __init__(self, symbols=None, start=None, end=None, retry_count=3,
9693
def get_actions(self):
9794
return self._get_actions
9895

96+
@property
97+
def url(self):
98+
return 'https://finance.yahoo.com/quote/{}/history'
99+
99100
def _get_params(self, symbol):
100101
unix_start = int(time.mktime(self.start.timetuple()))
101102
day_end = self.end.replace(hour=23, minute=59, second=59)
@@ -106,31 +107,17 @@ def _get_params(self, symbol):
106107
'period2': unix_end,
107108
'interval': self.interval,
108109
'frequency': self.interval,
109-
'filter': 'history'
110+
'filter': 'history',
111+
'symbol': symbol
110112
}
111113
return params
112114

113-
def read(self):
114-
"""Read data"""
115-
try:
116-
# If a single symbol, (e.g., 'GOOG')
117-
if isinstance(self.symbols, (compat.string_types, int)):
118-
dfs = self._read_one_data(self.symbols)
119-
120-
# Or multiple symbols, (e.g., ['GOOG', 'AAPL', 'MSFT'])
121-
elif isinstance(self.symbols, DataFrame):
122-
dfs = self._dl_mult_symbols(self.symbols.index)
123-
else:
124-
dfs = self._dl_mult_symbols(self.symbols)
125-
126-
return dfs
127-
finally:
128-
self.close()
129-
130-
def _read_one_data(self, symbol):
115+
def _read_one_data(self, url, params):
131116
""" read one data from specified symbol """
132-
url = 'https://finance.yahoo.com/quote/{}/history'.format(symbol)
133-
params = self._get_params(symbol)
117+
118+
symbol = params['symbol']
119+
del params['symbol']
120+
url = url.format(symbol)
134121

135122
resp = self._get_response(url, params=params)
136123
ptrn = r'root\.App\.main = (.*?);\n}\(this\)\);'
@@ -195,39 +182,10 @@ def _read_one_data(self, symbol):
195182

196183
return prices
197184

198-
def _dl_mult_symbols(self, symbols):
199-
stocks = {}
200-
failed = []
201-
passed = []
202-
for sym_group in _in_chunks(symbols, 1): # ignoring chunksize
203-
for sym in sym_group:
204-
try:
205-
stocks[sym] = self._read_one_data(sym)
206-
passed.append(sym)
207-
except IOError:
208-
msg = 'Failed to read symbol: {0!r}, replacing with NaN.'
209-
warnings.warn(msg.format(sym), SymbolWarning)
210-
failed.append(sym)
211-
212-
if len(passed) == 0:
213-
msg = "No data fetched using {0!r}"
214-
raise RemoteDataError(msg.format(self.__class__.__name__))
215-
try:
216-
if len(stocks) > 0 and len(failed) > 0 and len(passed) > 0:
217-
df_na = stocks[passed[0]].copy()
218-
df_na[:] = np.nan
219-
for sym in failed:
220-
stocks[sym] = df_na
221-
return Panel(stocks).swapaxes('items', 'minor')
222-
except AttributeError:
223-
# cannot construct a panel with just 1D nans indicating no data
224-
msg = "No data fetched using {0!r}"
225-
raise RemoteDataError(msg.format(self.__class__.__name__))
226-
227185

228186
def _adjust_prices(hist_data, price_list=None):
229187
"""
230-
Return modifed DataFrame or Panel with adjusted prices based on
188+
Return modifed DataFrame with adjusted prices based on
231189
'Adj Close' price. Adds 'Adj_Ratio' column.
232190
"""
233191
if price_list is None:

0 commit comments

Comments
 (0)