10
10
import urllib
11
11
import urllib2
12
12
import time
13
+ import warnings
13
14
14
15
from zipfile import ZipFile
15
16
from pandas .util .py3compat import StringIO , BytesIO , bytes_to_str
@@ -111,12 +112,7 @@ def get_quote_yahoo(symbols):
111
112
urlStr = 'http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s' % (
112
113
sym_list , request )
113
114
114
- try :
115
- lines = urllib2 .urlopen (urlStr ).readlines ()
116
- except Exception , e :
117
- s = "Failed to download:\n {0}" .format (e )
118
- print (s )
119
- return None
115
+ lines = urllib2 .urlopen (urlStr ).readlines ()
120
116
121
117
for line in lines :
122
118
fields = line .decode ('utf-8' ).strip ().split (',' )
@@ -539,7 +535,7 @@ def _parse_options_data(table):
539
535
540
536
class Options (object ):
541
537
"""
542
- This class fetches call/put data for a given stock/exipry month.
538
+ This class fetches call/put data for a given stock/expiry month.
543
539
544
540
It is instantiated with a string representing the ticker symbol.
545
541
@@ -553,7 +549,7 @@ class Options(object):
553
549
Examples
554
550
--------
555
551
# Instantiate object with ticker
556
- >>> aapl = Options('aapl')
552
+ >>> aapl = Options('aapl', 'yahoo' )
557
553
558
554
# Fetch September 2012 call data
559
555
>>> calls = aapl.get_call_data(9, 2012)
@@ -576,24 +572,25 @@ class Options(object):
576
572
577
573
"""
578
574
579
- def __init__ (self , symbol ):
575
+ def __init__ (self , symbol , data_source = None ):
580
576
""" Instantiates options_data with a ticker saved as symbol """
581
577
self .symbol = str (symbol ).upper ()
578
+ if (data_source is None ):
579
+ warnings .warn ("Options(symbol) is deprecated, use Options(symbol, data_source) instead" ,
580
+ FutureWarning )
581
+ data_source = "yahoo"
582
+ if (data_source != "yahoo" ):
583
+ raise NotImplementedError ("currently only yahoo supported" )
582
584
583
- def get_options_data (self , month = None , year = None ):
585
+ def get_options_data (self , month = None , year = None , expiry = None ):
584
586
"""
585
587
Gets call/put data for the stock with the expiration data in the
586
588
given month and year
587
589
588
590
Parameters
589
591
----------
590
- month: number, int, optional(default=None)
591
- The month the options expire. This should be either 1 or 2
592
- digits.
593
-
594
- year: number, int, optional(default=None)
595
- The year the options expire. This sould be a 4 digit int.
596
-
592
+ expiry: datetime.date, optional(default=None)
593
+ The date when options expire (defaults to current month)
597
594
598
595
Returns
599
596
-------
@@ -609,7 +606,7 @@ def get_options_data(self, month=None, year=None):
609
606
When called, this function will add instance variables named
610
607
calls and puts. See the following example:
611
608
612
- >>> aapl = Options('aapl') # Create object
609
+ >>> aapl = Options('aapl', 'yahoo' ) # Create object
613
610
>>> aapl.calls # will give an AttributeError
614
611
>>> aapl.get_options_data() # Get data and set ivars
615
612
>>> aapl.calls # Doesn't throw AttributeError
@@ -621,6 +618,8 @@ def get_options_data(self, month=None, year=None):
621
618
representations of the month and year for the expiry of the
622
619
options.
623
620
"""
621
+ year , month = self ._try_parse_dates (year ,month ,expiry )
622
+
624
623
from lxml .html import parse
625
624
626
625
if month and year : # try to get specified month from yahoo finance
@@ -659,19 +658,15 @@ def get_options_data(self, month=None, year=None):
659
658
660
659
return [call_data , put_data ]
661
660
662
- def get_call_data (self , month = None , year = None ):
661
+ def get_call_data (self , month = None , year = None , expiry = None ):
663
662
"""
664
663
Gets call/put data for the stock with the expiration data in the
665
664
given month and year
666
665
667
666
Parameters
668
667
----------
669
- month: number, int, optional(default=None)
670
- The month the options expire. This should be either 1 or 2
671
- digits.
672
-
673
- year: number, int, optional(default=None)
674
- The year the options expire. This sould be a 4 digit int.
668
+ expiry: datetime.date, optional(default=None)
669
+ The date when options expire (defaults to current month)
675
670
676
671
Returns
677
672
-------
@@ -683,7 +678,7 @@ def get_call_data(self, month=None, year=None):
683
678
When called, this function will add instance variables named
684
679
calls and puts. See the following example:
685
680
686
- >>> aapl = Options('aapl') # Create object
681
+ >>> aapl = Options('aapl', 'yahoo' ) # Create object
687
682
>>> aapl.calls # will give an AttributeError
688
683
>>> aapl.get_call_data() # Get data and set ivars
689
684
>>> aapl.calls # Doesn't throw AttributeError
@@ -694,6 +689,8 @@ def get_call_data(self, month=None, year=None):
694
689
repsectively, two digit representations of the month and year
695
690
for the expiry of the options.
696
691
"""
692
+ year , month = self ._try_parse_dates (year ,month ,expiry )
693
+
697
694
from lxml .html import parse
698
695
699
696
if month and year : # try to get specified month from yahoo finance
@@ -727,19 +724,15 @@ def get_call_data(self, month=None, year=None):
727
724
728
725
return call_data
729
726
730
- def get_put_data (self , month = None , year = None ):
727
+ def get_put_data (self , month = None , year = None , expiry = None ):
731
728
"""
732
729
Gets put data for the stock with the expiration data in the
733
730
given month and year
734
731
735
732
Parameters
736
733
----------
737
- month: number, int, optional(default=None)
738
- The month the options expire. This should be either 1 or 2
739
- digits.
740
-
741
- year: number, int, optional(default=None)
742
- The year the options expire. This sould be a 4 digit int.
734
+ expiry: datetime.date, optional(default=None)
735
+ The date when options expire (defaults to current month)
743
736
744
737
Returns
745
738
-------
@@ -764,6 +757,8 @@ def get_put_data(self, month=None, year=None):
764
757
repsectively, two digit representations of the month and year
765
758
for the expiry of the options.
766
759
"""
760
+ year , month = self ._try_parse_dates (year ,month ,expiry )
761
+
767
762
from lxml .html import parse
768
763
769
764
if month and year : # try to get specified month from yahoo finance
@@ -798,7 +793,7 @@ def get_put_data(self, month=None, year=None):
798
793
return put_data
799
794
800
795
def get_near_stock_price (self , above_below = 2 , call = True , put = False ,
801
- month = None , year = None ):
796
+ month = None , year = None , expiry = None ):
802
797
"""
803
798
Cuts the data frame opt_df that is passed in to only take
804
799
options that are near the current stock price.
@@ -810,19 +805,15 @@ def get_near_stock_price(self, above_below=2, call=True, put=False,
810
805
should be taken
811
806
812
807
call: bool
813
- Tells the function weather or not it should be using
808
+ Tells the function whether or not it should be using
814
809
self.calls
815
810
816
811
put: bool
817
812
Tells the function weather or not it should be using
818
813
self.puts
819
814
820
- month: number, int, optional(default=None)
821
- The month the options expire. This should be either 1 or 2
822
- digits.
823
-
824
- year: number, int, optional(default=None)
825
- The year the options expire. This sould be a 4 digit int.
815
+ expiry: datetime.date, optional(default=None)
816
+ The date when options expire (defaults to current month)
826
817
827
818
Returns
828
819
-------
@@ -831,6 +822,8 @@ def get_near_stock_price(self, above_below=2, call=True, put=False,
831
822
desired. If there isn't data as far out as the user has asked for
832
823
then
833
824
"""
825
+ year , month = self ._try_parse_dates (year ,month ,expiry )
826
+
834
827
price = float (get_quote_yahoo ([self .symbol ])['last' ])
835
828
836
829
if call :
@@ -844,13 +837,6 @@ def get_near_stock_price(self, above_below=2, call=True, put=False,
844
837
except AttributeError :
845
838
df_c = self .get_call_data (month , year )
846
839
847
- # NOTE: For some reason the put commas in all values >1000. We remove
848
- # them here
849
- df_c .Strike = df_c .Strike .astype (str ).apply (lambda x : \
850
- x .replace (',' , '' ))
851
- # Now make sure Strike column has dtype float
852
- df_c .Strike = df_c .Strike .astype (float )
853
-
854
840
start_index = np .where (df_c ['Strike' ] > price )[0 ][0 ]
855
841
856
842
get_range = range (start_index - above_below ,
@@ -872,13 +858,6 @@ def get_near_stock_price(self, above_below=2, call=True, put=False,
872
858
except AttributeError :
873
859
df_p = self .get_put_data (month , year )
874
860
875
- # NOTE: For some reason the put commas in all values >1000. We remove
876
- # them here
877
- df_p .Strike = df_p .Strike .astype (str ).apply (lambda x : \
878
- x .replace (',' , '' ))
879
- # Now make sure Strike column has dtype float
880
- df_p .Strike = df_p .Strike .astype (float )
881
-
882
861
start_index = np .where (df_p .Strike > price )[0 ][0 ]
883
862
884
863
get_range = range (start_index - above_below ,
@@ -897,11 +876,21 @@ def get_near_stock_price(self, above_below=2, call=True, put=False,
897
876
else :
898
877
return chop_put
899
878
879
+ def _try_parse_dates (self , year , month , expiry ):
880
+ if year is not None or month is not None :
881
+ warnings .warn ("month, year arguments are deprecated, use expiry instead" ,
882
+ FutureWarning )
883
+
884
+ if expiry is not None :
885
+ year = expiry .year
886
+ month = expiry .month
887
+ return year , month
888
+
900
889
def get_forward_data (self , months , call = True , put = False , near = False ,
901
890
above_below = 2 ):
902
891
"""
903
892
Gets either call, put, or both data for months starting in the current
904
- month and going out in the future a spcified amount of time.
893
+ month and going out in the future a specified amount of time.
905
894
906
895
Parameters
907
896
----------
@@ -933,6 +922,7 @@ def get_forward_data(self, months, call=True, put=False, near=False,
933
922
If asked for, a DataFrame containing put data from the current
934
923
month to the current month plus months.
935
924
"""
925
+ warnings .warn ("get_forward_data() is deprecated" , FutureWarning )
936
926
in_months = range (cur_month , cur_month + months + 1 )
937
927
in_years = [cur_year ] * (months + 1 )
938
928
0 commit comments