As I discussed in my previous post I have started to explore the possibilities of using python for quant fiance applications. To be honest I have only spent about 2 hours working on this project. In that short amount of time I have been able to:
- Connect to Interactive Brokers via IbPy.
- Connect and download free stock data from Yahoo finance via ystockquote.
- Visualise stock data using matplotlib.
I wont go through connecting to Interactive Broker here as max has written an excellent tutorial on his site. Max provides some excellent resources on quant trading.
Getting Stock Quotes From Yahoo via Python
Corey Goldberg has written a simple module that is a good starting point for getting stock data. I am yet to modify the code but when I do I will post the modified source code. You can download the source code for ystockquote.py below:
#!/usr/bin/env python
#
# Copyright (c) 2007-2008, Corey Goldberg (corey@goldb.org)
#
# license: GNU LGPL
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
import urllib
"""
This is the "ystockquote" module.
This module provides a Python API for retrieving stock data from Yahoo Finance.
sample usage:
>>> import ystockquote
>>> print ystockquote.get_price('GOOG')
529.46
"""
def __request(symbol, stat):
url = 'http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s' % (symbol, stat)
return urllib.urlopen(url).read().strip().strip('"')
def get_all(symbol):
"""
Get all available quote data for the given ticker symbol.
Returns a dictionary.
"""
values = __request(symbol, 'l1c1va2xj1b4j4dyekjm3m4rr5p5p6s7').split(',')
data = {}
data['price'] = values[0]
data['change'] = values[1]
data['volume'] = values[2]
data['avg_daily_volume'] = values[3]
data['stock_exchange'] = values[4]
data['market_cap'] = values[5]
data['book_value'] = values[6]
data['ebitda'] = values[7]
data['dividend_per_share'] = values[8]
data['dividend_yield'] = values[9]
data['earnings_per_share'] = values[10]
data['52_week_high'] = values[11]
data['52_week_low'] = values[12]
data['50day_moving_avg'] = values[13]
data['200day_moving_avg'] = values[14]
data['price_earnings_ratio'] = values[15]
data['price_earnings_growth_ratio'] = values[16]
data['price_sales_ratio'] = values[17]
data['price_book_ratio'] = values[18]
data['short_ratio'] = values[19]
return data
def get_price(symbol):
return __request(symbol, 'l1')
def get_change(symbol):
return __request(symbol, 'c1')
def get_volume(symbol):
return __request(symbol, 'v')
def get_avg_daily_volume(symbol):
return __request(symbol, 'a2')
def get_stock_exchange(symbol):
return __request(symbol, 'x')
def get_market_cap(symbol):
return __request(symbol, 'j1')
def get_book_value(symbol):
return __request(symbol, 'b4')
def get_ebitda(symbol):
return __request(symbol, 'j4')
def get_dividend_per_share(symbol):
return __request(symbol, 'd')
def get_dividend_yield(symbol):
return __request(symbol, 'y')
def get_earnings_per_share(symbol):
return __request(symbol, 'e')
def get_52_week_high(symbol):
return __request(symbol, 'k')
def get_52_week_low(symbol):
return __request(symbol, 'j')
def get_50day_moving_avg(symbol):
return __request(symbol, 'm3')
def get_200day_moving_avg(symbol):
return __request(symbol, 'm4')
def get_price_earnings_ratio(symbol):
return __request(symbol, 'r')
def get_price_earnings_growth_ratio(symbol):
return __request(symbol, 'r5')
def get_price_sales_ratio(symbol):
return __request(symbol, 'p5')
def get_price_book_ratio(symbol):
return __request(symbol, 'p6')
def get_short_ratio(symbol):
return __request(symbol, 's7')
def get_historical_prices(symbol, start_date, end_date):
"""
Get historical prices for the given ticker symbol.
Date format is 'YYYYMMDD'
Returns a nested list.
"""
url = 'http://ichart.yahoo.com/table.csv?s=%s&' % symbol + \
'd=%s&' % str(int(end_date[4:6]) - 1) + \
'e=%s&' % str(int(end_date[6:8])) + \
'f=%s&' % str(int(end_date[0:4])) + \
'g=d&' + \
'a=%s&' % str(int(start_date[4:6]) - 1) + \
'b=%s&' % str(int(start_date[6:8])) + \
'c=%s&' % str(int(start_date[0:4])) + \
'ignore=.csv'
days = urllib.urlopen(url).readlines()
data = [day[:-2].split(',') for day in days]
return data
As you can see python is a very simple easy to read and understand language.
A Very Simple Example
In this simple example we will work in the interactive ipython environment with matplotlib. We will download the data separate the data and store it in separate list data structures. This is a very inefficient way of doing things and is not optimal. This example is for demonstration purposes.
import ystockquote
# Get Quotes 01/01/2006 - 01/01/2009
GOOG = ystockquote.get_historical_prices('GOOG', '20060101', '20090101')
# Create empty lists, quick and dirty
GOOGOpen = [ ]
GOOGClose = [ ]
GOOGDate = [ ]
GOOGHigh = [ ]
GOOGLow = [ ]
GOOGAdj = [ ]
GOOGVolume = [ ]
# Populate lists from downloaded data
for i in range(1, 755):
GOOGDate.append(GOOG[i][0])
GOOGOpen.append(GOOG[i][1])
GOOGHigh.append(GOOG[i][2])
GOOGLow.append(GOOG[i][3])
GOOGClose.append(GOOG[i][4])
GOOGVolume.append(GOOG[i][5])
GOOGAdj.append(GOOG[i][6])
plot(GOOGAdj)
title("Google Adjusted Close")
ylabel(r"GOOG Closing Price ($USD)", fontsize = 12)
xlabel(r"Date", fontsize = 12)
grid(True)
The image below shows the output we get when we save the plot as a .png file.
As you can see we need to adjust the x category labels. We will do this in an upcoming tutorial.
Creating a simple linked chart in Python
In Matlab it is very easy to create linked graphs, it is also possible to create linked graphs using matplotlib. The example below shows how we can link volume and adjusted close for Google.
import ystockquote
# Get Quotes 01/01/2006 - 01/01/2009
GOOG = ystockquote.get_historical_prices('GOOG', '20060101', '20090101')
# Create empty lists, quick and dirty
GOOGOpen = [ ]
GOOGClose = [ ]
GOOGDate = [ ]
GOOGHigh = [ ]
GOOGLow = [ ]
GOOGAdj = [ ]
GOOGVolume = [ ]
# Populate lists from downloaded data
for i in range(1, 755):
GOOGDate.append(GOOG[i][0])
GOOGOpen.append(GOOG[i][1])
GOOGHigh.append(GOOG[i][2])
GOOGLow.append(GOOG[i][3])
GOOGClose.append(GOOG[i][4])
GOOGVolume.append(GOOG[i][5])
GOOGAdj.append(GOOG[i][6])
#create canvas add two plots linked via x-axis
fig = figure()
ax = fig.add_subplot(311)
ax2 = fig.add_subplot(312, sharex=ax)
ax.plot(GOOGAdj)
ax2.plot(GOOGVolume)
Below you can see the output, you can scroll and zoom these graphs and they remain aligned.
Below shows what happens when you zoom in on a chart.
As you can see from the above examples python is easy to use and is very flexible. In my next post I will go through some more advanced charting and drawing functions.



Thanks for writing such a simple article. I have been wanting to automate some of my trading strategies however I didn’t want to learn C or C++ as they seem much mor complex languages. Python seems like it is easy to use yet powerful.
Great article. I agree python is a good choice. Easy and lots of library support. I wrote a piece on how to download historical data from yahoo in python. It is available at : http://blog.kilotrader.com/2010/11/adjusting-yahoo-data.html
Thanks