使用Matlab下载googlefinance上面的option数据版本2012a-getoption.m
本帖最后由 1989111 于 2014-3-31 12:00 编辑
之前一直潜水,但是后来写了点程序回馈大家,献丑了!大家都知道下载yahoo 或者google的的股票数据API,但是option他们没有提供API。 所以,一般的entry level的数据拿daily的就好了. 所以今天鄙人讲讲怎么在google finance 拿option的数据. 一下方法,也是鄙人自创的,用的是matlab,code也很原始,但是用来抛砖引玉,也是极好的. 大家在matlab里面自创一个function,复制粘贴一下就好了,用法很简单, ticker用string的名字输入就好,例如[call,put]=getoption;,就可以得到当天option,call 和put的数据了.
下面是程序源代码:
function [calls,puts]=getoption
QQ截图20140330224814.png
请注意源代码里面没有这一句。因为我木有权限发url!
sourcefile=urlread;目的有三:1. 我不读取网页数据,以上的修改过的link是以下下载链接, output是JSON 文件,属于google API的范畴. 显得高端大气上档次一些. 用正则表达式读网页拖慢网络速度,于是改用,这个人家网站自己提供的下载链接,或者用code: A=urlwrite; B=importdata; 然后对B做后面的正则表达式处理,这样可以减少对网站的资源占用.2. 读取网页不可靠,网页上很多冗余信息,对扒数据没啥用处, JSON由于有API提供的接口,写作方式比较固定,几乎没有冗余信息,读取工作顺利,出错概率小.3. JSON 文件在java里面可以直接读取,如果用matlab在java里面写得话会很方便,但是哥还是坚持用低调而奢华的用正则表达式读取JSON文件, 大家可以用word打开JSON文件,看看里面的格式,写得挺整齐的.
下面的code照旧,写得不好不要见怪,多谢各种给我的代码提供意见的热心码农,另外在一位热心网友的留言下我找到了如何下载全部option的办法, 感谢那位网友提供的帮助,他给我的指点实质上告诉了我:其实google整个网页的数据呈现就是以JSON文件的读取做基础的! 这也是我作此修改的最大原因,以期达到更大可靠性.但是人家是做有偿服务的,所以我不能贴出来抢别人生意,请大家见谅
callstart=regexpi;
[locations,datefile]= regexp;
strike= regexp;
bid= regexp;
ask= regexp;
volume=regexp;
price=regexp;
OpenInterest=regexp;
Expiration=regexp;
for i=1:length
strike{i}= regexp;
bid{i}= regexp;
ask{i}= regexp;
volume{i}= regexp;
price{i}= regexp;
OpenInterest{i}= regexp;
Expiration{i}= regexp\w.*', 'match');
end
index1=find ;
index2=find ;
A={price{index1};strike{index1};bid{index1};ask{index1};volume{index1};OpenInterest{index1};Expiration{index1}};
B={price{index2};strike{index2};bid{index2};ask{index2};volume{index2};OpenInterest{index2};Expiration{index2}};
A=A';
B=B';
for i=1:length
calldata.price{i}= str2double;
calldata.strike{i}=str2double;
calldata.bid{i}=str2double;
calldata.ask{i}=str2double;
calldata.Volume{i}=str2double;
calldata.OpenInterest{i}=str2double;
calldata.Expiration{i}= cell2mat;
end
for i=1:length
putdata.price{i}=str2double;
putdata.strike{i}=str2double;
putdata.bid{i}=str2double;
putdata.ask{i}=str2double;
putdata.Volume{i}=str2double;
putdata.OpenInterest{i}=str2double;
putdata.Expiration{i}= cell2mat;
end
calls=dataset({calldata.strike','Strike'},{calldata.price','Price'},{calldata.bid','Bid'},{calldata.ask','ask'},...
{calldata.Volume','Volume'},{calldata.OpenInterest','Open Interest'},{calldata.Expiration','Expiration'});
puts=dataset({putdata.strike','Strike'},{putdata.price','Price'},{putdata.bid','Bid'},{putdata.ask','ask'},...
{putdata.Volume','Volume'},{putdata.OpenInterest','Open Interest'},{putdata.Expiration','Expiration'});
end
下面鄙人就来讲解一下里面的代码是干啥的.
第一行当然是输入一个ticker,输入的形式必须是string的,用matlab的话说就是'XXXX', XXXX代表ticker;
第二行,是吧一个网址和ticker串起来,因为google finance上的网址都有规律,所以如果你要搜索google的option今天的报价,
有图为证:
所以在执行当中,已经有了一个string 变量url,它指向goog finance网址:
然后我们看看是不是:
仔细一看,真的是,
然后第二句就是读取这个网页的源文件, 简单说来就是我们打开了这个网页,然后read source file就会出来各种字母的那个页面
然后再看看后面的code
callstart=regexpi;
[locations,datefile]= regexp;
这个东西是叫做matlab正则表达式的应用,想系统学的同学可以上网搜,比我讲的要好, 我只是要用的时候拿出来看,
上图:
大家看到strike的规律没有?
都是strike 后面跟着一个价格, 所以,下面这个code就是讲得是匹配含有{xxx strike.xxx}的最小长度的字符.*? 的意思就是尽可能短的字符
[locations,datefile]= regexp; 然后大家可以打开datefile去看看
找到的匹配字符 大概是这个模样:
{cid:"216439834517106",name:"",s:"GOOG130830P00710000",e:"OPRA",p:"-",c:"-",b:"-",a:"0.45",oi:"0",vol:"-",strike:"710.00",expiry:"Aug 30, 2013"}
这个算是一个元素,datefile里面有好多个这样的元素....
再看下面的语句,明白了上面的,下面的也就不难理解了
strike= regexp;
bid= regexp;
ask= regexp;
volume=regexp;
price=regexp;
OpenInterest=regexp;
Expiration=regexp;
这几个就是在{cid:"216439834517106",name:"",s:"GOOG130830P00710000",e:"OPRA",p:"-",c:"-",b:"-",a:"0.45",oi:"0",vol:"-",strike:"710.00",expiry:"Aug 30, 2013"}里面找含有strike:".*?",b:".*?"等等的字符,于是乎我们又进了一步,把响应的字符都找出来了.
得到了price大概像这个东西
',p:"-"' ',p:"-"' ',p:"-"' ',p:"-"' ',p:"-"' ',p:"-"' ',p:"-"' ',p:"0.40"' ',p:"0.45"' ',p:"0.10"' ',p:"0.10"'
其他的例如expiration啥的大概都差不多. 到这里为止,我们要的数据都已经扒下来了,但是这样的数据存在的形式是在让人蛋疼,于是乎我们做一下的工作
for i=1:length
strike{i}= regexp;
bid{i}= regexp;
ask{i}= regexp;
volume{i}= regexp;
price{i}= regexp;
OpenInterest{i}= regexp;
Expiration{i}= regexp\w.*', 'match');
end
这个讲的是既然我们找到了那些数据,数据总是跟着p:"0.10",这样子多难看啊, 拿price的例子来说,price{i}= regexp; 想要做的意思就是,遍历price这个向量里面每一个元素, 只留下xxx.xxx的数据,[0-9]{1,}表示至少出现一次,[0-9]{1,}.[0-9]{1,}则表示把一个含有小数的数字读取出来, 于是p:"0.10"就会变成0.10啦,同理跟其他的也是一样的. 然后就是
index1=find ;
index2=find ;
A={price{index1};strike{index1};bid{index1};ask{index1};volume{index1};OpenInterest{index1};Expiration{index1}};
B={price{index2};strike{index2};bid{index2};ask{index2};volume{index2};OpenInterest{index2};Expiration{index2}};
当时我留了call start这个变量没讲,是因为这个相当于一个路标,表示着call 和put的分界线, find这个函数只不过是找到大于call start和小于它的相对位置而已. index1 和index2都含有了put 和 call的相对位置.
后面的没啥好说了,就是data转换输出的东西,A是call,B是put的数据
这里没啥好说的,就是为了输出方便,好看, 需要说明的是这里用了matlab的dataset和cell函数,因此,获得的数据不能够直接拿来做向量运算,如果要用到,要需要做一下转换,dataset2cell,然后cell2double的转换,这样的话就可以变成一般的double型的变量来运算啦. 有图为证:
然后再说一下这个函数的缺点,第一,变成dataset和cell要转换,这是一个缺点.第二, 不能拿历史数据,这个我知道啊,option 的历史数据都是要钱的,屌丝只能能够每天跑这个程序一次,自己建立一个自己需要的option pricec的数据库了. 需要指出的是google finance有15min的延迟,因此,intraday的数据只要你跑程序多,是可以拿到的.
这是程序代码[/align][align=left][align=left]function [calls,puts]=getoption[/align]
[align=left]sourcefile=urlread;[/align]
[align=left]callstart=regexpi;[/align][align=left][locations,datefile]= regexp;[/align][align=left]strike= regexp;[/align][align=left]bid= regexp;[/align][align=left]ask= regexp;[/align][align=left]volume=regexp;[/align]
[align=left]price=regexp;[/align][align=left]OpenInterest=regexp;[/align][align=left]Expiration=regexp;[/align][align=left]for i=1:length[/align][align=left] strike{i}= regexp;[/align][align=left] bid{i}= regexp;[/align][align=left] ask{i}= regexp;[/align][align=left] volume{i}= regexp;[/align][align=left] price{i}= regexp;[/align][align=left] OpenInterest{i}= regexp;[/align][align=left] Expiration{i}= regexp;[/align][align=left]end[/align]
[align=left]index1=find ;[/align][align=left]index2=find ;[/align][align=left]A={price{index1};strike{index1};bid{index1};ask{index1};volume{index1};OpenInterest{index1};Expiration{index1}};[/align][align=left]B={price{index2};strike{index2};bid{index2};ask{index2};volume{index2};OpenInterest{index2};Expiration{index2}};[/align][align=left]A=A';[/align][align=left]B=B';[/align]
[align=left]for i=1:length[/align]
[align=left] calldata.price{i}= str2double;[/align][align=left] calldata.strike{i}=str2double;[/align][align=left] calldata.bid{i}=str2double;[/align][align=left] calldata.ask{i}=str2double;[/align][align=left] calldata.Volume{i}=str2double;[/align][align=left] calldata.OpenInterest{i}=str2double;[/align][align=left] calldata.Expiration{i}= cell2mat;[/align][align=left]end[/align][align=left]for i=1:length[/align][align=left]putdata.price{i}=str2double;[/align][align=left]putdata.strike{i}=str2double;[/align][align=left]putdata.bid{i}=str2double;[/align][align=left]putdata.ask{i}=str2double;[/align][align=left]putdata.Volume{i}=str2double;[/align][align=left]putdata.OpenInterest{i}=str2double;[/align][align=left]putdata.Expiration{i}= cell2mat;[/align][align=left]end[/align]
[align=left] calls=dataset;[/align][align=left] puts=dataset;[/align][align=left]end[/align]
[/align]
[align=left]复制代码 复制代码