I want to look into stock data.

Yahoo Finance API

According to stackoverflow ("alternative to google finance api"), financial information can be obtained through the Yahoo Finance API.

For instance, you can generate a CSV by a simple API call

# generate and save a CSV for AAPL, GOOG and MSFT
http://finance.yahoo.com/d/quotes.csv?s=AAPL+GOOG+MSFT&f=sb2b3jk

or by using the webservice to return XML or JSON.

# All stock quotes in XML
http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote

# All stock quotes in JSON
http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json

In [1]:
url = "http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json"

Making a webservice request


In [2]:
import requests
import json  

response = requests.get(url)

# Load as JSON object
j = json.loads(response.content)

# Make tidy and print the first 3 entries
stock = [i['resource']['fields'] for i in j['list']['resources']]
stock[:3]


Out[2]:
[{'name': 'USD/KRW',
  'price': '1116.109985',
  'symbol': 'KRW=X',
  'ts': '1495284995',
  'type': 'currency',
  'utctime': '2017-05-20T12:56:35+0000',
  'volume': '0'},
 {'name': 'SILVER 1 OZ 999 NY',
  'price': '0.059382',
  'symbol': 'XAG=X',
  'ts': '1495351368',
  'type': 'currency',
  'utctime': '2017-05-21T07:22:48+0000',
  'volume': '36'},
 {'name': 'USD/VND',
  'price': '22599.000000',
  'symbol': 'VND=X',
  'ts': '1495284996',
  'type': 'currency',
  'utctime': '2017-05-20T12:56:36+0000',
  'volume': '0'}]

Yahoo-finance Python package

In addition to making requests by a url, there is a python package (yahoo-finance) which provides functions to get stock data from Yahoo! Finance.


In [3]:
import yahoo_finance

yahoo = yahoo_finance.Share('YHOO')

print(yahoo.get_open())
print(yahoo.get_price())
print(yahoo.get_trade_datetime())


50.03
50.18
2017-05-19 20:00:00 UTC+0000

In [4]:
# Refresh
yahoo.refresh()

print(yahoo.get_price())
print(yahoo.get_trade_datetime())


50.18
2017-05-19 20:00:00 UTC+0000

Small issues

From the examples, there is a function to get_historical() data. However, when I actually do run it, I get a YQLResponseMalformedError: Response malformed. error. Googling the error message, The Financial Hacker (2017) comments:

The Yahoo Finance API is dead. Without prior announcement, Yahoo has abandoned their only remaining service that was clearly ahead of the competition.

The link to this issue is found here.


In [5]:
yahoo.get_historical('2014-04-25', '2014-04-29')


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/Users/csiu/software/anaconda/anaconda2-4.0.0/envs/kaggle/lib/python3.6/site-packages/yahoo_finance/__init__.py in _request(self, query)
    119         try:
--> 120             _, results = response['query']['results'].popitem()
    121         except (KeyError, StopIteration, AttributeError):

AttributeError: 'NoneType' object has no attribute 'popitem'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
/Users/csiu/software/anaconda/anaconda2-4.0.0/envs/kaggle/lib/python3.6/site-packages/yahoo_finance/__init__.py in _request(self, query)
    122             try:
--> 123                 raise YQLQueryError(response['error']['description'])
    124             except KeyError:

KeyError: 'error'

During handling of the above exception, another exception occurred:

YQLResponseMalformedError                 Traceback (most recent call last)
<ipython-input-5-cb09be2f58a1> in <module>()
----> 1 yahoo.get_historical('2014-04-25', '2014-04-29')

/Users/csiu/software/anaconda/anaconda2-4.0.0/envs/kaggle/lib/python3.6/site-packages/yahoo_finance/__init__.py in get_historical(self, start_date, end_date)
    340             try:
    341                 query = self._prepare_query(table='historicaldata', startDate=s, endDate=e)
--> 342                 result = self._request(query)
    343                 if isinstance(result, dict):
    344                     result = [result]

/Users/csiu/software/anaconda/anaconda2-4.0.0/envs/kaggle/lib/python3.6/site-packages/yahoo_finance/__init__.py in _request(self, query)
    123                 raise YQLQueryError(response['error']['description'])
    124             except KeyError:
--> 125                 raise YQLResponseMalformedError()
    126         else:
    127             if self._is_error_in_results(results):

YQLResponseMalformedError: Response malformed.

For now, not all functionality is lost.