goldb.org home

AS OF MAY 2008, THIS BLOG IS NO LONGER BEING UPDATED.
Visit the new blog at: http://coreygoldberg.blogspot.com



 Monday, September 17, 2007

Python - Yahoo Stock Quote Module

Last week I wrote a small Python module for retrieving stock prices.

It used screen scraping to get data from Google Finance.  Yahoo offers stock data in a much more digestible form which allowed me to get values without screen scraping and regular expressions.  So, I wrote a module based around this.

This new module is much more comprehensive and exposes a Python API for retrieving all sorts of stock data from Yahoo Finance.

My ystockquote module provides a Python API for retrieving stock data from Yahoo Finance.  This module contains the following functions:

  • get_all(symbol)
  • get_price(symbol)
  • get_change(symbol)
  • get_volume(symbol)
  • get_avg_daily_volume(symbol)
  • get_stock_exchange(symbol)
  • get_market_cap(symbol)
  • get_book_value(symbol)
  • get_ebitda(symbol)
  • get_dividend_per_share(symbol)
  • get_dividend_yield(symbol)
  • get_earnings_per_share(symbol)
  • get_52_week_high(symbol)
  • get_52_week_low(symbol)
  • get_50day_moving_avg(symbol)
  • get_200day_moving_avg(symbol)
  • get_price_earnings_ratio(symbol)
  • get_price_earnings_growth_ratio(symbol)
  • get_price_sales_ratio(symbol)
  • get_price_book_ratio(symbol)
  • get_short_ratio(symbol)

Sample Usage:


>>> import ystockquote
>>> print ystockquote.get_price('GOOG')
529.46
>>> print ystockquote.get_all('MSFT')
{'stock_exchange': '"NasdaqNM"', 'market_cap': '268.6B', 
'200day_moving_avg': '29.2879', '52_week_high': '31.84', 
'price_earnings_growth_ratio': '1.45', 'price_sales_ratio': '5.33',
'price': '28.65', 'earnings_per_share': '1.423', 
'50day_moving_avg': '28.7981', 'avg_daily_volume': '55579700',
'volume': '25330856', '52_week_low': '26.48', 'short_ratio': '1.60', 
'price_earnings_ratio': '28.65', 'dividend_yield': '1.38', 
'dividend_per_share': '0.40', 'price_book_ratio': '8.76', 
'ebitda': '20.441B', 'change': '-0.39', 'book_value': '3.315'}

The module is available here:  http://www.goldb.org/ystockquote.html

#    Comments [11] |
Monday, September 17, 2007 2:44:09 PM (Eastern Standard Time, UTC-05:00)
Code like that makes me wish more services used CSV for data. The module does so much, but the code is so clean.
K
Monday, September 17, 2007 4:26:39 PM (Eastern Standard Time, UTC-05:00)
you might think about adding get_price_history(symbol, start_date, end_date). i know their price history interface offers csv output. i use a bash script to retrieve price history right now, but python is so much nicer :)
Monday, September 17, 2007 4:29:02 PM (Eastern Standard Time, UTC-05:00)
also, putting all of these functions into a class would be more pythonic ;)
Monday, September 17, 2007 6:05:53 PM (Eastern Standard Time, UTC-05:00)
Nicely done. Code has been added to my lib dir.
Tuesday, September 18, 2007 6:26:08 AM (Eastern Standard Time, UTC-05:00)
That's neat !
I second JMC on putting all the functions into a class ...
Tuesday, September 18, 2007 8:45:35 AM (Eastern Standard Time, UTC-05:00)
@JMC
@Tim

I wasn't sure if I should create a class and use all of the functions as methods. If this is how most Python modules work (do they?), then perhaps I should. However, I guess I don't see why this would need to be OO. Since each function is called individually, and no state is stored, I didn't see a reason to use OO. anyone have thoughts on this, or a good reason why they should be in a class?

-Corey
Tuesday, September 18, 2007 9:52:01 AM (Eastern Standard Time, UTC-05:00)
Nice! The Finance::YahooQuote module is one thing (the only thing?) I missed from Perl! I've condensed your code down into an even shorter version that auto-generates its own functions. All you have to do to add a new field is just update the dictionary that maps long names to short field names. Here you go:

<pre>
#!/usr/bin/env python
#
# Copyright (c) 2007, 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.

# Copyright (c) 2007, Dan Lenski (lenski@umd.edu)
# Made it shorter and more pythonic, I think :)


import urllib
from functools import partial

"""
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('"')

_fields = {
'price': 'l1', 'change': 'c1', 'volume': 'v', 'avg_daily_volume': 'a2',
'stock_exchange': 'x', 'market_cap': 'j1', 'book_value': 'b4',
'ebitda': 'j4', 'dividend_per_share': 'd', 'dividend_yield': 'y',
'earnings_per_share': 'e', '52_week_high': 'k', '52_week_low': 'j',
'50day_moving_avg': 'm3', '200day_moving_avg': 'm4',
'price_earnings_ratio': 'l1', 'price_earnings_growth_ratio': 'r5',
'price_sales_ratio': 'p5', 'price_book_ratio': 'p6', 'short_ratio': 's7'
}

def get_all(symbol):
"""
Get all available quote data for the given ticker symbol.

Returns a dictionary.
"""
longnames, fieldnames = _fields.keys(), _fields.values()
fieldvalues = _request(symbol, ''.join(fieldnames)).split(',')
return dict(zip(longnames, fieldvalues))

_globals = globals()
for _f in _fields:
_globals['get_' + _f] = partial(_request, stat=_fields[_f])
</pre>
Friday, September 21, 2007 12:45:55 PM (Eastern Standard Time, UTC-05:00)
I would like recommend a feature where you can request multiple quotes in one HTTP request. Yahoo supports a comma-separated list of tickers in the URL.
Monday, September 24, 2007 10:37:46 PM (Eastern Standard Time, UTC-05:00)
A such nice and useful program. However, if I want to retrieve historical data, how can I do it? Thanks a lot.

I sent to an email, Corey. Please check it.
Tuesday, October 09, 2007 7:34:02 AM (Eastern Standard Time, UTC-05:00)
When processing HTML data in python you probably should use Beautiful Soup to get more robust results.
As far as I know it is best library for that purpose.
http://www.crummy.com/software/BeautifulSoup/
Mika
Tuesday, October 09, 2007 10:21:25 AM (Eastern Standard Time, UTC-05:00)
> When processing HTML data in python you probably should
> use Beautiful Soup to get more robust results.

Keep it simple.. I don't actually process any HTML. I make an HTTP request that returns a CSV file of data, which I split and parse.
Comments are closed.