@@ -661,31 +661,35 @@ def get_options_data(self, month=None, year=None, expiry=None):
661
661
662
662
_OPTIONS_BASE_URL = 'http://finance.yahoo.com/q/op?s={sym}'
663
663
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
665
671
666
- year , month , expiry = self . _try_parse_dates ( year , month , expiry )
672
+ def _get_option_page_from_yahoo ( self , expiry ):
667
673
668
674
url = self ._OPTIONS_BASE_URL .format (sym = self .symbol )
669
675
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 )
672
677
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 :
679
680
url += '+Options'
681
+ else :
682
+ url += '&m={year}-{m1}' .format (year = expiry .year , m1 = m1 )
680
683
681
684
root = self ._parse_url (url )
685
+ return root
686
+
687
+ def _parse_option_page_from_yahoo (self , root ):
688
+
682
689
tables = root .xpath ('.//table' )
683
690
ntables = len (tables )
684
691
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" )
689
693
690
694
try :
691
695
self .underlying_price , self .quote_time = self ._get_underlying_price (root )
@@ -723,7 +727,7 @@ def _get_option_data(self, month, year, expiry, name):
723
727
try :
724
728
tables = getattr (self , table_name )
725
729
except AttributeError :
726
- tables = self ._get_option_tables (month , year , expiry )
730
+ tables = self ._get_option_tables (expiry )
727
731
728
732
ntables = len (tables )
729
733
table_loc = self ._TABLE_LOC [name ]
@@ -903,13 +907,14 @@ def get_near_stock_price(self, above_below=2, call=True, put=False,
903
907
meth_name = 'get_{0}_data' .format (nam [:- 1 ])
904
908
df = getattr (self , meth_name )(expiry = expiry )
905
909
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' )
907
912
> self .underlying_price )[0 ][0 ]
908
913
909
- get_range = slice (start_index - above_below ,
914
+ get_range = slice (start_index - above_below ,
910
915
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
913
918
914
919
return concat ([data [nam ] for nam in to_ret ]).sortlevel ()
915
920
@@ -948,6 +953,8 @@ def _try_parse_dates(year, month, expiry):
948
953
year = CUR_YEAR
949
954
month = CUR_MONTH
950
955
expiry = dt .date (year , month , 1 )
956
+ else :
957
+ expiry = dt .date (year , month , 1 )
951
958
952
959
return year , month , expiry
953
960
@@ -1127,7 +1134,11 @@ def _get_expiry_months(self):
1127
1134
url = 'http://finance.yahoo.com/q/op?s={sym}' .format (sym = self .symbol )
1128
1135
root = self ._parse_url (url )
1129
1136
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
+
1131
1142
month_gen = (element .attrib ['href' ].split ('=' )[- 1 ]
1132
1143
for element in links
1133
1144
if '/q/op?s=' in element .attrib ['href' ]
0 commit comments