Follow us on Twitter ![]()
Question, remark ? Contact us at contact@myengineeringtools.com
One of the basics in using Python for finance is to download stock data, the following tutorial explains step by step how to do that with the Python financial ecosystem, utilizing pandas-datareader and modern data access workflows.
Before attempting to download stock data, the Python installation you are running must have the following libraries installed :
If you don't have those libraries installed, please run pip install to install them :
pip install numpypip install pandaspip install pandas-datareaderpip install yfinance1st of all, start by importing the libraries that you will need :
import numpy as np
import pandas as pd
import pandas_datareader as web
The simplest synthax is the following :
web.DataReader(ticker, 'yahoo', start, end)
With :
ticker : the ticker symbol of the stock you want to download, as a string
'yahoo' : it is the datasource, Yahoo finance is very common but there are other datasources managed by Pandas-Datareader
start : it is the start date of the period to download, format MM-DD-YYYY (but the library can also parse other date formats)
end : it is the end date of the period to download, format MM-DD-YYYY (but the library can also parse other date formats)
Example : we download chevron stock data from 15/02/2015 to 01/11/2021 and we assign to a dataframe named df
df = web.DataReader('CVX', 'yahoo', '02-15-2015', '11-01-2021')
You can print the dataframe with print(df) afterwards, the listing is the following :
The data downloaded are, for each date, High, Low, Open, Close, Volume, Adj Close in this typical format :
| Date (index) | High | Low | Open | Close | Volume | Adj Close |
|---|---|---|---|---|---|---|
| 2015-02-17 | 112.45 | 109.80 | 111.00 | 110.25 | 8,920,400 | 84.50 |
Running the function and entering manually the parameters is of course not very practical, the function below helps to automatize the download of the data and also records the data downloaded in csv files for later use.
def save_stock_data_csv(portfolio, start_date, end_date, path):
'''Download the stock price data of all tickers in a portfolio
portfolio is a list of strings'''
for ticker in portfolio:
df = web.DataReader(ticker, 'yahoo', start_date, end_date)
df.to_csv(path + ticker + '.csv')
The function can be tested, for example using the code below :
path = 'Data/'
portfolio = ['AMZN', 'AAPL']
start_date = '2016-01-01'
end_date = '2020-01-01'
save_stock_data_csv(portfolio, start_date, end_date, path)
This allows to download all the stock data in csv files in the Data/ folder.
It is of course possible to download from Yahoo at each execution but this might not be efficient for a high number of stocks. In this case, downloading one time the data with the function described at step 3 allows to have csv file that can be reused later. The following code allows to read the data from the csv file :
portfolio = ['AMZN', 'AAPL']
df = pd.read_csv(path + portfolio[0] + '.csv')
print(df)
This allows to affect the data downloaded for Amazon to the dataframe df, which gives the following result :
You can download the file with the code here : get_stock_data.py
Once raw stock data is acquired via Python, quantitative engineers and analysts evaluate price trends using standard thermodynamic-like discrete statistical equations:
1. Simple Arithmetic Return:
\[ R_t = \frac{P_t - P_{t-1}}{P_{t-1}} = \frac{P_t}{P_{t-1}} - 1 \]2. Continuously Compounded (Logarithmic) Return:
\[ r_t = \ln\left(\frac{P_t}{P_{t-1}}\right) \]3. Compound Annual Growth Rate (CAGR):
\[ \text{CAGR} = \left(\frac{P_{\text{end}}}{P_{\text{start}}}\right)^{\frac{1}{N_{\text{years}}}} - 1 \]4. Annualized Volatility (\(\sigma_{\text{ann}}\)):
\[ \sigma_{\text{ann}} = \sigma_{\text{daily}} \times \sqrt{252} \]5. Sharpe Ratio (\(S\)):
\[ S = \frac{R_{\text{CAGR}} - R_f}{\sigma_{\text{ann}}} \]6. Parametric Value at Risk (\(\text{VaR}_{95\%}\)):
\[ \text{VaR}_{95\%} = 1.645 \times \sigma_{\text{daily}} \times \text{Position Value} \]pandas-datareader direct Yahoo scraping frequently throws HTTP 404/403 errors due to rotating crumbs. In production, utilize yfinance.pdr_override() or direct REST calls to maintain uninterrupted automated pipelines.Close prices. Always use Adj Close to prevent artificial 50% drops from 2-for-1 splits.time.sleep(0.5) or batch requests to avoid IP blacklisting.