-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathstockretriever.py
133 lines (100 loc) · 4.1 KB
/
stockretriever.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#! /usr/bin/env python
#
# Download from https://github.com/gurch101/StockScraper
#
# See http://www.gurchet-rai.net/dev/yahoo-finance-yql for details
#
"""A wrapper for the Yahoo! Finance YQL api."""
import sys
import httplib
import urllib
import json
PUBLIC_API_URL = 'http://query.yahooapis.com/v1/public/yql'
DATATABLES_URL = 'store://datatables.org/alltableswithkeys'
HISTORICAL_URL = 'http://ichart.finance.yahoo.com/table.csv?s='
RSS_URL = 'http://finance.yahoo.com/rss/headline?s='
FINANCE_TABLES = {'quotes': 'yahoo.finance.quotes',
'options': 'yahoo.finance.options',
'quoteslist': 'yahoo.finance.quoteslist',
'sectors': 'yahoo.finance.sectors',
'industry': 'yahoo.finance.industry'}
def execute_yql_query(yql):
"""Returns the JSON response of the given YQL query. """
conn = httplib.HTTPConnection('query.yahooapis.com')
query_string = urllib.urlencode({
'q': yql,
'format': 'json',
'env': DATATABLES_URL
})
conn.request('GET', PUBLIC_API_URL + '?' + query_string)
return json.loads(conn.getresponse().read())
class QueryError(Exception):
"""Exception that's raised when YQL query execution fails. """
pass
class NoResultsError(Exception):
"""Exception that's raised when the YQL response contains an empty
resultset."""
pass
def __format_symbol_list(symbols):
return ",".join(["\"" + symbol + "\"" for symbol in symbols])
def __is_valid_response(response):
return ('query' in response
and 'results' in response['query']
and 'error' not in response)
def __validate_response(response, tag):
if not __is_valid_response(response):
if 'error' in response:
raise QueryError('YQL query failed with error: "%s".'
% response['error']['description'])
raise QueryError('YQL response malformed.')
elif (response['query']['results'] is None
or tag not in response['query']['results']):
raise NoResultsError('No results found.')
return response['query']['results'][tag]
def get_current_info(symbol_list, columns='*'):
"""Retrieves the latest data (15 minute delay) for the
provided symbols."""
columns = ','.join(columns)
symbols = __format_symbol_list(symbol_list)
yql = ('select %s from %s where symbol in (%s)'
% (columns, FINANCE_TABLES['quotes'], symbols))
response = execute_yql_query(yql)
return __validate_response(response, 'quote')
def get_historical_info(symbol, from_dt=None, to_dt=None):
"""Retrieves historical stock data for the provided symbol.
Historical data includes date, open, close, high, low, volume,
and adjusted close."""
if from_dt is None or to_dt is None:
date_string = ''
else:
date_string = ('&a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&g=d&ignore=.csv' %
(from_dt.month-1, from_dt.day, from_dt.year,
to_dt.month-1, to_dt.day, to_dt.year))
yql = ('select * from csv where url="%s"'
' and columns="Date,Open,High,Low,Close,Volume,AdjClose"' %
(HISTORICAL_URL + symbol + date_string))
response = execute_yql_query(yql)
results = __validate_response(response, 'row')
# delete first row which contains column names
del results[0]
return results
def get_news_feed(symbol):
"""Retrieves the rss feed for the provided symbol."""
feed_url = RSS_URL + symbol
yql = ('select title, link, description, pubDate '
'from rss where url="%s"' % feed_url)
response = execute_yql_query(yql)
return __validate_response(response, 'item')
def get_industry_index(industry_id):
"""retrieves all symbols that belong to an industry."""
yql = ('select * from %s where id =\'%s\'' %
(FINANCE_TABLES['industry'], industry_id))
response = execute_yql_query(yql)
return __validate_response(response, 'industry')
if __name__ == "__main__":
try:
print get_current_info(sys.argv[1:])
# print get_news_feed('yhoo')
except QueryError, err:
print err
sys.exit(2)