Skip to content

Commit 43e270c

Browse files
TST/CLN: Refactor io.data.options class to improve testing
Removed most references to month and year (passing expiry date around instead). Also protected with RemoteDataError checking for the expiry month links.
1 parent 03bbed5 commit 43e270c

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

pandas/io/data.py

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -661,31 +661,35 @@ def get_options_data(self, month=None, year=None, expiry=None):
661661

662662
_OPTIONS_BASE_URL = 'http://finance.yahoo.com/q/op?s={sym}'
663663

664-
def _get_option_tables(self, month, year, expiry):
664+
def _get_option_tables(self, expiry):
665+
root = self._get_option_page_from_yahoo(expiry)
666+
tables = self._parse_option_page_from_yahoo(root)
667+
m1 = _two_char_month(expiry.month)
668+
table_name = '_tables' + m1 + str(expiry.year)[-2:]
669+
setattr(self, table_name, tables)
670+
return tables
665671

666-
year, month, expiry = self._try_parse_dates(year, month, expiry)
672+
def _get_option_page_from_yahoo(self, expiry):
667673

668674
url = self._OPTIONS_BASE_URL.format(sym=self.symbol)
669675

670-
if month and year: # try to get specified month from yahoo finance
671-
m1 = _two_char_month(month)
676+
m1 = _two_char_month(expiry.month)
672677

673-
# if this month use other url
674-
if month == CUR_MONTH and year == CUR_YEAR:
675-
url += '+Options'
676-
else:
677-
url += '&m={year}-{m1}'.format(year=year, m1=m1)
678-
else: # Default to current month
678+
# if this month use other url
679+
if expiry.month == CUR_MONTH and expiry.year == CUR_YEAR:
679680
url += '+Options'
681+
else:
682+
url += '&m={year}-{m1}'.format(year=expiry.year, m1=m1)
680683

681684
root = self._parse_url(url)
685+
return root
686+
687+
def _parse_option_page_from_yahoo(self, root):
688+
682689
tables = root.xpath('.//table')
683690
ntables = len(tables)
684691
if ntables == 0:
685-
raise RemoteDataError("No tables found at {0!r}".format(url))
686-
687-
table_name = '_tables' + m1 + str(year)[-2:]
688-
setattr(self, table_name, tables)
692+
raise RemoteDataError("No tables found")
689693

690694
try:
691695
self.underlying_price, self.quote_time = self._get_underlying_price(root)
@@ -723,7 +727,7 @@ def _get_option_data(self, month, year, expiry, name):
723727
try:
724728
tables = getattr(self, table_name)
725729
except AttributeError:
726-
tables = self._get_option_tables(month, year, expiry)
730+
tables = self._get_option_tables(expiry)
727731

728732
ntables = len(tables)
729733
table_loc = self._TABLE_LOC[name]
@@ -948,6 +952,8 @@ def _try_parse_dates(year, month, expiry):
948952
year = CUR_YEAR
949953
month = CUR_MONTH
950954
expiry = dt.date(year, month, 1)
955+
else:
956+
expiry = dt.date(year, month, 1)
951957

952958
return year, month, expiry
953959

@@ -1127,7 +1133,11 @@ def _get_expiry_months(self):
11271133
url = 'http://finance.yahoo.com/q/op?s={sym}'.format(sym=self.symbol)
11281134
root = self._parse_url(url)
11291135

1130-
links = root.xpath('.//*[@id="yfncsumtab"]')[0].xpath('.//a')
1136+
try:
1137+
links = root.xpath('.//*[@id="yfncsumtab"]')[0].xpath('.//a')
1138+
except IndexError:
1139+
return RemoteDataError('Expiry months not available')
1140+
11311141
month_gen = (element.attrib['href'].split('=')[-1]
11321142
for element in links
11331143
if '/q/op?s=' in element.attrib['href']

pandas/io/tests/test_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ def test_sample_page_price_quote_time2(self):
334334
@network
335335
def test_sample_page_chg_float(self):
336336
#Tests that numeric columns with comma's are appropriately dealt with
337-
tables = self.root1.xpath('.//table')
337+
tables = self.aapl._parse_option_page_from_yahoo(self.root1)
338338
data = web._parse_options_data(tables[self.aapl._TABLE_LOC['puts']])
339339
option_data = self.aapl._process_data(data)
340340
self.assertEqual(option_data['Chg'].dtype, 'float64')

0 commit comments

Comments
 (0)