This report shows a few free ways to get prices and other financial information for a stock or index. There are plenty of other APIs, like Alpha Vantage, and many paid services.

Pandas Datareader


You can import stock and other financial data directly into a Pandas dataframe with pandas_datareader.data. The following sources are available:

  • Yahoo Finance
  • Enigma
  • St.Louis FED (FRED)
  • Kenneth French’s data library
  • World Bank
  • OECD
  • Eurostat
  • Thrift Savings Plan
  • Oanda currency historical rate
  • Nasdaq Trader symbol definitions (remote_data.nasdaq_symbols)

FACEBOOK

> import pandas_datareader.data as web
+ import datetime
+ 
+ start = datetime.datetime(2015, 1, 1)
+ end = datetime.datetime(2017, 1, 1)
+ 
+ facebook = web.DataReader("FB", 'yahoo', start, end)
+ facebook.head()
                 High        Low       Open      Close    Volume  Adj Close
Date                                                                       
2015-01-02  78.930000  77.699997  78.580002  78.449997  18177500  78.449997
2015-01-05  79.250000  76.860001  77.980003  77.190002  26452200  77.190002
2015-01-06  77.589996  75.360001  77.230003  76.150002  27399300  76.150002
2015-01-07  77.360001  75.820000  76.760002  76.150002  22045300  76.150002
2015-01-08  78.230003  76.080002  76.739998  78.180000  23961000  78.180000

ST. LOUIS FED

> start = datetime.datetime(2010, 1, 1)
+ end = datetime.datetime(2017, 1, 1)
+ 
+ gdp = web.DataReader("GDP", "fred", start, end)
+ gdp.head()
                  GDP
DATE                 
2010-01-01  14721.350
2010-04-01  14926.098
2010-07-01  15079.917
2010-10-01  15240.843
2011-01-01  15285.828

Quandl


Quandl is a source of financial, economic, and alternative datasets. Many are free.

> import numpy as np
+ import pandas as pd
+ import matplotlib.pyplot as plt
+ import seaborn as sns
+ import quandl

WTI Crude Oil price from the US Department of Energy:

> mydata = quandl.get("EIA/PET_RWTC_D")
+ mydata.head()
            Value
Date             
1986-01-02  25.56
1986-01-03  26.00
1986-01-06  26.53
1986-01-07  25.85
1986-01-08  25.87
> sns.set_style('darkgrid')
+ mydata.plot(figsize=(12,6));
+ plt.show()

You can get the same data in a NumPy array:

> mydata = quandl.get("EIA/PET_RWTC_D", returns="numpy")
+ mydata
rec.array([('1986-01-02T00:00:00.000000000', 25.56),
           ('1986-01-03T00:00:00.000000000', 26.  ),
           ('1986-01-06T00:00:00.000000000', 26.53), ...,
           ('2020-11-24T00:00:00.000000000', 44.71),
           ('2020-11-25T00:00:00.000000000', 45.58),
           ('2020-11-30T00:00:00.000000000', 45.2 )],
          dtype=[('Date', '<M8[ns]'), ('Value', '<f8')])

ST. LOUIS FED

> mydata = quandl.get("FRED/GDP", start_date="2001-12-31", 
+ end_date="2005-12-31")
+ 
+ mydata.head()
                Value
Date                 
2002-01-01  10788.952
2002-04-01  10893.207
2002-07-01  10992.051
2002-10-01  11071.463
2003-01-01  11183.507

OIL AND APPLE

> mydata = quandl.get(["NSE/OIL.1", "WIKI/AAPL.4"],
+                     start_date="2001-12-31",   
+                     end_date="2017-12-31")
+                     
+ mydata.tail()
            NSE/OIL - Open  WIKI/AAPL - Close
Date                                         
2017-12-22           360.0             175.01
2017-12-26           360.0             170.57
2017-12-27           361.0             170.60
2017-12-28           361.5             171.08
2017-12-29           375.5             169.23

FOR STOCKS

Unfortunately the free WIKI stock database is no longer active (ended in 2018), but it can be used to retrieve historical information. There are still some paid sources on Quandl.

> mydata = quandl.get('WIKI/FB',
+                     start_date='2015-01-01',
+                     end_date='2017-01-01')
+                     
+ mydata.iloc[0:5:,7:12]
            Adj. Open  Adj. High  Adj. Low  Adj. Close  Adj. Volume
Date                                                               
2015-01-02      78.58    78.9300    77.700      78.450   18177475.0
2015-01-05      77.98    79.2455    76.860      77.190   26452191.0
2015-01-06      77.23    77.5900    75.365      76.150   27399288.0
2015-01-07      76.76    77.3600    75.820      76.150   22045333.0
2015-01-08      76.74    78.2300    76.080      78.175   23960953.0

You can also specify the column index.

> mydata = quandl.get('WIKI/FB.1',
+                     start_date='2015-01-01',
+                     end_date='2017-01-01')
+ mydata.head()
             Open
Date             
2015-01-02  78.58
2015-01-05  77.98
2015-01-06  77.23
2015-01-07  76.76
2015-01-08  76.74

HOUSING PRICES

Zillow Home Value Index (Metro): Zillow Rental Index - All Homes - San Francisco, CA

> houses = quandl.get('ZILLOW/M11_ZRIAH')
+ houses.head()
             Value
Date              
2010-11-30  2454.0
2010-12-31  2461.0
2011-01-31  2484.0
2011-02-28  2506.0
2011-03-31  2526.0
> houses.plot();
+ plt.show()

yfinance


The yfinance package makes it easy to download many items from Yahoo.

MSFT

> import yfinance as yf
+ df = yf.download('MSFT', start='2019-01-01', end='2020-05-30')

[*********************100%***********************]  1 of 1 completed
> df.head()
                  Open        High  ...   Adj Close    Volume
Date                                ...                      
2019-01-02   99.550003  101.750000  ...   98.602066  35329300
2019-01-03  100.099998  100.190002  ...   94.974693  42579100
2019-01-04   99.720001  102.510002  ...   99.391899  44060600
2019-01-07  101.639999  103.269997  ...   99.518669  35656100
2019-01-08  103.040001  103.970001  ...  100.240234  31514400

[5 rows x 6 columns]
> msft = yf.Ticker("MSFT")

Data other than price:

  • msft.info
  • hist = msft.history(period=“max”)
  • msft.actions
  • msft.dividends
  • msft.splits
  • msft.financials
  • msft.quarterly_financials
  • msft.major_holders
  • msft.institutional_holders
  • msft.balance_sheet
  • msft.quarterly_balance_sheet
  • msft.cashflow
  • msft.quarterly_cashflow
  • msft.earnings
  • msft.quarterly_earnings
  • msft.sustainability
  • msft.recommendations
  • msft.calendar
> msft.recommendations
                               Firm       To Grade From Grade Action
Date                                                                
2012-03-16 08:19:00  Argus Research            Buy                up
2012-03-19 14:00:00  Hilliard Lyons  Long-Term Buy              main
2012-03-22 07:03:00  Morgan Stanley     Overweight              main
2012-04-03 11:53:00             UBS            Buy              main
2012-04-20 06:18:00   Deutsche Bank            Buy              main
...                             ...            ...        ...    ...
2020-10-28 12:00:17  Morgan Stanley     Overweight              main
2020-10-28 13:22:56   Credit Suisse     Outperform              main
2020-10-29 16:00:20   Deutsche Bank            Buy              main
2020-11-05 10:48:37     Oppenheimer     Outperform    Perform     up
2020-11-24 11:17:51         KeyBanc     Overweight              init

[299 rows x 4 columns]

MULTIPLE TICKERS

> data = yf.download(tickers = "SPY AAPL MSFT", period = "ytd")

[                       0%                       ]
[**********************67%*******                ]  2 of 3 completed
[*********************100%***********************]  3 of 3 completed
> data['Adj Close'].head()
                 AAPL        MSFT         SPY
Date                                         
2020-01-02  73.840042  158.936279  320.273743
2020-01-03  73.122154  156.957260  317.848572
2020-01-06  73.704819  157.362961  319.061188
2020-01-07  73.358185  155.928177  318.164032
2020-01-08  74.538239  158.411835  319.859741
> ticker = yf.Ticker('TSLA')
+ tsla_df = ticker.history(period="max")
+ sns.set_style('darkgrid')
+ tsla_df['Close'].plot(title="TSLA's stock price");
+ plt.show()

yahoofinancials


Yahoo data can also be captured from yahoofinancials, although it is more difficult.

> from yahoofinancials import YahooFinancials
+ 
+ yahoo_financials = YahooFinancials('TSLA')
+ data = yahoo_financials.get_historical_price_data(start_date='2000-01-01', 
+                                                   end_date='2019-12-31', 
+                                                   time_interval='weekly')
+ 
+ tsla_df = pd.DataFrame(data['TSLA']['prices'])
+ 
+ tsla_df = tsla_df.drop('date', axis=1).set_index('formatted_date')
+ tsla_df.head()
                 high    low   open  close     volume  adjclose
formatted_date                                                 
2010-06-28      6.084  3.508  3.800  3.840  246560000     3.840
2010-07-05      4.000  2.996  4.000  3.480  127753000     3.480
2010-07-12      4.300  3.380  3.590  4.128   77194500     4.128
2010-07-19      4.450  3.900  4.274  4.258   35878500     4.258
2010-07-26      4.300  3.910  4.300  3.988   15260000     3.988
> assets = ['TSLA', 'MSFT', 'FB']
+ 
+ yahoo_financials = YahooFinancials(assets)
+ 
+ data = yahoo_financials.get_historical_price_data(start_date='2019-01-01', 
+                                                   end_date='2019-12-31', 
+                                                   time_interval='weekly')
+ 
+ prices_df = pd.DataFrame({
+     a: {x['formatted_date']: x['adjclose'] for x in data[a]['prices']} for a in assets
+ })
+ 
+ prices_df.head()
                 TSLA        MSFT          FB
2019-01-01  66.991997   99.518669  138.050003
2019-01-08  66.879997   99.508911  145.389999
2019-01-15  60.452000  105.027977  150.039993
2019-01-22  59.276001  102.463470  147.470001
2019-01-29  62.577999  103.107025  169.250000