Skip to content

Instantly share code, notes, and snippets.

@mmport80
Created December 1, 2016 19:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mmport80/0982308e0f8e631e221a2f39b12b2067 to your computer and use it in GitHub Desktop.
Save mmport80/0982308e0f8e631e221a2f39b12b2067 to your computer and use it in GitHub Desktop.
import token
import tokenize
from six.moves import cStringIO as StringIO
import json
from pandas.io.json import json_normalize
import requests
import pandas as pd
def __fix_lazy_json(in_text):
"""
Handle lazy JSON - to fix expecting property name
this function fixes the json output from google
http://stackoverflow.com/questions/4033633/handling-lazy-json-in-python-expecting-property-name
"""
tokengen = tokenize.generate_tokens(StringIO(in_text).readline)
result = []
for tokid, tokval, _, _, _ in tokengen:
# fix unquoted strings
if (tokid == token.NAME):
if tokval not in ['true', 'false', 'null', '-Infinity', 'Infinity', 'NaN']:
tokid = token.STRING
tokval = u'"%s"' % tokval
# fix single-quoted strings
elif (tokid == token.STRING):
if tokval.startswith("'"):
tokval = u'"%s"' % tokval[1:-1].replace('"', '\\"')
# remove invalid commas
elif (tokid == token.OP) and ((tokval == '}') or (tokval == ']')):
if (len(result) > 0) and (result[-1][1] == ','):
result.pop()
# fix single-quoted strings
elif (tokid == token.STRING):
if tokval.startswith("'"):
tokval = u'"%s"' % tokval[1:-1].replace('"', '\\"')
result.append((tokid, tokval))
return tokenize.untokenize(result)
def Options(symbol):
url = "https://www.google.com/finance/option_chain"
r = requests.get(url, params={"q": symbol, "output": "json"})
content_json = r.text
dat = json.loads(__fix_lazy_json(content_json))
puts = json_normalize(dat['puts'])
calls = json_normalize(dat['calls'])
np = len(puts)
nc = len(calls)
for i in dat['expirations'][1:]:
r = requests.get(url, params={"q": symbol, "expd": i['d'], "expm": i[
'm'], "expy": i['y'], "output": "json"})
content_json = r.text
idat = json.loads(__fix_lazy_json(content_json))
puts1 = json_normalize(idat['puts'])
calls1 = json_normalize(idat['calls'])
puts1.index = [np + i for i in puts1.index]
calls1.index = [nc + i for i in calls1.index]
np += len(puts1)
nc += len(calls1)
puts = puts.append(puts1)
calls = calls.append(calls1)
calls.columns = ['Ask', 'Bid', 'Chg', 'cid', 'PctChg', 'cs', 'IsNonstandard',
'Expiry', 'Underlying', 'Open_Int', 'Last', 'Symbol', 'Strike', 'Vol']
puts.columns = ['Ask', 'Bid', 'Chg', 'cid', 'PctChg', 'cs', 'IsNonstandard',
'Expiry', 'Underlying', 'Open_Int', 'Last', 'Symbol', 'Strike', 'Vol']
calls['Type'] = ['call' for i in range(len(calls))]
puts['Type'] = ['put' for i in range(len(puts))]
puts.index = [i + len(calls) for i in puts.index]
opt = pd.concat([calls, puts])
opt['Underlying'] = [symbol for i in range(len(opt))]
opt['Underlying_Price'] = [dat['underlying_price']
for i in range(len(opt))]
opt['Root'] = opt['Underlying']
for j in ['Vol', 'Strike', 'Last', 'Bid', 'Ask', 'Chg']:
opt[j] = pd.to_numeric(opt[j], errors='coerce')
opt['IsNonstandard'] = opt['IsNonstandard'].apply(lambda x: x != 'OPRA')
opt = opt.sort_values(by=['Strike', 'Type'])
opt.index = range(len(opt))
col = ['Strike', 'Expiry', 'Type', 'Symbol', 'Last', 'Bid', 'Ask', 'Chg', 'PctChg', 'Vol',
'Open_Int', 'Root', 'IsNonstandard', 'Underlying', 'Underlying_Price', 'cid', 'cs']
opt = opt[col]
return opt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment