Reputation: 31
I'm migrating some Yahoo Finance CSV/screen-scraping interfaces to use YQL, and struggling with the yahoo.finance.options table. If I query for all options for a given symbol, I don't find the expiration dates associated with the options. If I query for symbol and expiration, then I find the expiration date associated with the chain, but not the options therein. While I'm familiar with the cycle of options expiration and can bootstrap it from a given date, that's a poor solution; for one thing, it will generate more queries. I'd much prefer to introspect it from the data, since it should be available (it can be screen-scraped). Anybody know how to get at this in YQL, or am I out of luck?
Here's some python code I'm using:
from xml.etree.ElementTree import ElementTree
import urllib, urllib2
class YQL(object):
url = 'http://query.yahooapis.com/v1/public/yql'
env = 'store://datatables.org/alltableswithkeys'
format = 'xml'
@classmethod
def query(cls, string):
q = urllib.quote(string)
url = cls.url + '&'.join(('?q=%s' % q, 'env=%s' % cls.env,
'format=%s' % cls.format))
resp = urllib2.urlopen(url)
return ElementTree(file=resp).getroot().find('results')[:]
chain = YQL.query('select * from yahoo.finance.options where symbol="WFC"')[0]
chain.attrib
option = chain[0]
option.attrib
for attr in option:
print attr.tag, attr.text
Upvotes: 3
Views: 2979
Reputation: 667
If you don't set the expiration date in the YQL query, then I think the data set will be returned for the contracts expiring soonest this month (but later than today). Those are not necessarily the monthly options, expiring on third Friday. The returned dataset could be for weeklies or quartelies options expiring this month (if your underlying has ones). Even if you issue the query a few days after expiration of the monthlies (3-rd Friday) there is a chance that you'll get data for something expiring this month rather than next month monthlies.
So, as unutbu suggested, it makes sense always issuing queries with expiration month specified to receive expiration date in the returned data set, and know exactly what you are getting. Or even better, with expiration date specified.
Too bad that querying the yahoo.finance.option_contracts table does not return expiration date, just the month. And it does not help finding out if your underlying has options other than monthlies, and their expiration dates.
Upvotes: 1
Reputation: 43
You can further take advantage of YQL's ability to chain queries with
SELECT * FROM yahoo.finance.options WHERE symbol="%s" AND expiration in (SELECT contract FROM yahoo.finance.option_contracts WHERE symbol="%s")
Where %s is the symbol you're seeking, obviously. This will pull all option chains from all available expiration dates, and save you several queries.
Upvotes: 4
Reputation: 11
In order to get the list of available contract dates use the yahoo.finance.option_contracts. To continue your code (which I appreciated) you could print all possible put options like this:
xml_dates = YQL.query('select * from yahoo.finance.option_contracts where ' +
'symbol="HYG"')[0]
dates = []
for attr in xml_dates:
print attr.tag, attr.text
dates.append(attr.text)
for expiration in dates:
xml_contracts = YQL.query('select * from yahoo.finance.options where '
+'symbol="HYG" AND expiration="' + expiration +'"')
for option in xml_contracts[0]:
if (option.attrib['type']=='P'):
print 'Put: strike=' + option.findtext('strikePrice')+ ', lowball '
+ 'ask=' + option.findtext('ask') + ', date='+ expiration
Upvotes: 1
Reputation: 879073
If you don't set the expiration date in the YQL query, then I think the expiration date of the data set will be the upcoming third Friday of the month. Using dateutil, you could define this date in Python with:
import dateutil.relativedelta as relativedelta
import dateutil.rrule as rrule
import datetime as dt
expiration=rrule.rrule(
rrule.MONTHLY,
byweekday=(relativedelta.FR(3)), dtstart=dt.datetime.now())[0]
(Note: the above code ignores holidays, in which case the expiration date would be the third Thursday.... If you use this code, be sure to also check what Yahoo decides to return when the current day is the third Friday of the month -- I'm not sure if expiration date will be the current date, or the third Friday of the next month.)
To see the option chain for a particular expiration year/month (other than the upcoming third Friday), you might use a YQL query such as:
chain = YQL.query('''
select * from yahoo.finance.options
where symbol="WFC" and expiration="2011-08"''')[0]
It is possible to obtain data on multiple expirations all in one YQL query:
chains = YQL.query('''
select * from yahoo.finance.options
where symbol="WFC" and (
expiration="2011-08" or
expiration="2011-10" or
expiration="2012-01"
)
''')
Interestingly, when data on multiple expirations is requested, the chain.attrib
does include an expiration
key:
for chain in chains:
print(chain.attrib)
# for option in chain:
# print(option.attrib)
# for attr in option:
# print attr.tag, attr.text
# print('-'*80)
yields
{'symbol': 'WFC', 'expiration': '2011-08-19'}
{'symbol': 'WFC', 'expiration': '2011-10-21'}
{'symbol': 'WFC', 'expiration': '2012-01-20'}
Upvotes: 1