@@ -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 ]
@@ -903,13 +907,14 @@ def get_near_stock_price(self, above_below=2, call=True, put=False,
903907 meth_name = 'get_{0}_data' .format (nam [:- 1 ])
904908 df = getattr (self , meth_name )(expiry = expiry )
905909
906- start_index = np .where (df .index .get_level_values ('Strike' )
910+ if self .underlying_price :
911+ start_index = np .where (df .index .get_level_values ('Strike' )
907912 > self .underlying_price )[0 ][0 ]
908913
909- get_range = slice (start_index - above_below ,
914+ get_range = slice (start_index - above_below ,
910915 start_index + above_below + 1 )
911- chop = df [get_range ].dropna (how = 'all' )
912- data [nam ] = chop
916+ chop = df [get_range ].dropna (how = 'all' )
917+ data [nam ] = chop
913918
914919 return concat ([data [nam ] for nam in to_ret ]).sortlevel ()
915920
@@ -948,6 +953,8 @@ def _try_parse_dates(year, month, expiry):
948953 year = CUR_YEAR
949954 month = CUR_MONTH
950955 expiry = dt .date (year , month , 1 )
956+ else :
957+ expiry = dt .date (year , month , 1 )
951958
952959 return year , month , expiry
953960
@@ -1127,7 +1134,11 @@ def _get_expiry_months(self):
11271134 url = 'http://finance.yahoo.com/q/op?s={sym}' .format (sym = self .symbol )
11281135 root = self ._parse_url (url )
11291136
1130- links = root .xpath ('.//*[@id="yfncsumtab"]' )[0 ].xpath ('.//a' )
1137+ try :
1138+ links = root .xpath ('.//*[@id="yfncsumtab"]' )[0 ].xpath ('.//a' )
1139+ except IndexError :
1140+ return RemoteDataError ('Expiry months not available' )
1141+
11311142 month_gen = (element .attrib ['href' ].split ('=' )[- 1 ]
11321143 for element in links
11331144 if '/q/op?s=' in element .attrib ['href' ]
0 commit comments