Getting Options Data from Yahoo Finance with Pandas

by John | December 07, 2020


If the code displayed in this article doesn't work for any reason, please email me.


In this article we will show how to get stock options data from Yahoo Finance. In order to do this we will use the Pandas Datareader package. You can find installation steps here.


It is also worth noting that options data bid/ ask prices will only be available during trading hours 9.30am ET - 4pm ET and also bear in mind that the data is on a short delay of approximately 15 minutes. 


With that said let's begin and take a look at some options data. Import the following packages and execute the script to get options data for Facebook (FB). 


import pandas as pd
import as web
import numpy as np

FB = web.YahooOptions('FB')


Now that we have an options object we can use some of the built in methods to get data. 


Show Available Expiries


The options object has a nice built in property that allows us to view the expiries available for the given stock option. It is also worth nothing here that the larger stocks will have more expiries since they are more widely traded. 


for exp in FB.expiry_dates:




Getting Call & Put Option Data.


We can get data for call options that expiry on a certain date, along with filtering by the month of expiry. Let's first check out the default call for this function.


calls = FB.get_call_data()


So viewing the expiries it seems that the default is for this function call is to return the nearest expiration. 


                                            Last  ...                                               JSON
Strike Expiry     Type Symbol                     ...                                                   
135.0  2020-12-11 call FB201211C00135000  150.08  ...  {'contractSymbol': 'FB201211C00135000', 'strik...
185.0  2020-12-11 call FB201211C00185000   92.95  ...  {'contractSymbol': 'FB201211C00185000', 'strik...
190.0  2020-12-11 call FB201211C00190000   93.75  ...  {'contractSymbol': 'FB201211C00190000', 'strik...
195.0  2020-12-11 call FB201211C00195000   89.00  ...  {'contractSymbol': 'FB201211C00195000', 'strik...
200.0  2020-12-11 call FB201211C00200000   79.65  ...  {'contractSymbol': 'FB201211C00200000', 'strik...
                                         ...  ...                                                ...
395.0  2020-12-11 call FB201211C00395000    0.08  ...  {'contractSymbol': 'FB201211C00395000', 'strik...
400.0  2020-12-11 call FB201211C00400000    0.23  ...  {'contractSymbol': 'FB201211C00400000', 'strik...
405.0  2020-12-11 call FB201211C00405000    0.32  ...  {'contractSymbol': 'FB201211C00405000', 'strik...
410.0  2020-12-11 call FB201211C00410000    0.07  ...  {'contractSymbol': 'FB201211C00410000', 'strik...
425.0  2020-12-11 call FB201211C00425000    0.06  ...  {'contractSymbol': 'FB201211C00425000', 'strik...

[62 rows x 15 columns]


We can also pass in arguments to the get_call_data method to get call options that expire on a certain month. To do this all we need to do is pass in a month and year argument. 


FB.get_call_data(month =2 , year = 2021)

#Strike Expiry     Type Symbol                     ...                                                   
#125.0  2021-02-19 call FB210219C00125000  152.35  ...  {'contractSymbol': 'FB210219C00125000', 'strik...
#130.0  2021-02-19 call FB210219C00130000  156.25  ...  {'contractSymbol': 'FB210219C00130000', 'strik...
#135.0  2021-02-19 call FB210219C00135000  140.00  ...  {'contractSymbol': 'FB210219C00135000', 'strik...
#140.0  2021-02-19 call FB210219C00140000  121.68  ...  {'contractSymbol': 'FB210219C00140000', 'strik...
#145.0  2021-02-19 call FB210219C00145000  130.65  ...  {'contractSymbol': 'FB210219C00145000', 'strik...


Alternatively we can pass in an expiry argument or list of expiries. Below we show how to download every call option at all expiries, we make use of the property we mentioned at the beginning of the document. Notice that this returns a MultiIndex dataframe. To change it to a regular index we can use the reset index command.


allcalls = FB.get_call_data(expiry= FB.expiry_dates)


#MultiIndex([(  5.0, '2021-01-15', 'call', 'FB210115C00005000'),
#            (  5.0, '2021-03-19', 'call', 'FB210319C00005000'),
#            (  5.0, '2021-06-18', 'call', 'FB210618C00005000'),
#            (  5.0, '2022-01-21', 'call', 'FB220121C00005000'),
#            ( 10.0, '2021-01-15', 'call', 'FB210115C00010000'),
#            ( 10.0, '2021-03-19', 'call', 'FB210319C00010000'),
#            ( 10.0, '2021-06-18', 'call', 'FB210618C00010000'),
#            ( 10.0, '2022-01-21', 'call', 'FB220121C00010000'),
#            ( 15.0, '2021-01-15', 'call', 'FB210115C00015000'),
#            ( 15.0, '2021-03-19', 'call', 'FB210319C00015000'),



We can use the exact same command for getting put options, get replace get_call_data with get_put_data and everything else is exactlly the same. 



Get all Options Data

It is very easy to get all options data from the Yahoo Finance api, in this seciton we will also show how to create a the mid-price for an option, which we will use in future articles on pricing and volatility. Again this returns a MultiIndex dataframe, here we reset the index as it is easier to work with in the regular format. 


alloptions = FB.get_all_data()


alloptions['mid_price'] = (alloptions.Ask + alloptions.Bid) / 2


This dataframe will have the following columns. Below we give a short description of each column along with the datatype.


options terms from yahoo finance explained



Full Python Code


import pandas as pd
import as web
import numpy as np

FB = web.YahooOptions('FB')

#showing available expiries
for exp in FB.expiry_dates:

# get call data
calls = FB.get_call_data()

#get put data
puts  = FB.get_put_data()

#get call data based on specific expiry
FB.get_call_data(month =2 , year = 2021)

# getting all call data, can also pass in a datetime to the expiry below
allcalls = FB.get_call_data(expiry= FB.expiry_dates)

#notice index is in multiindex

#changing to regular index

#get all available data for puts and calls at every expiration
alloptions = FB.get_all_data()


# perform calculate on the data.
alloptions['mid_price'] = (alloptions.Ask - alloptions.Bid) / 2




Join the discussion

Share this post with your friends!