这是我的另一个问题的后续问题,Efficiently fitting cubic splines in SAS to specific grid of objects - 以前的解决方案有效,但效果不如我想象的那么高。
此代码的目的是按组对特定范围的对象变量IV
插入图像MNES
的值,并对结果值执行操作。
我的数据集如下:
MEMBID DATE MNES IV
1 13152 0.84 0.40
1 13152 0.89 0.34
1 13152 0.91 0.31
1 13152 0.93 0.29
1 13152 0.95 0.26
1 13152 0.98 0.23
1 13152 0.99 0.22
1 13152 1.00 0.22
1 13152 1.02 0.20
1 13152 1.04 0.18
1 13152 1.07 0.18
...
4 13172 0.89 0.24
4 13172 0.94 0.20
4 13172 0.97 0.19
4 13172 1.01 0.19
4 13172 1.04 0.20
4 13172 1.07 0.21
4 13172 1.15 0.23
4 13172 1.17 0.24
...
每个MEMBID
和DATE
组合都是按组的。从视角来看,我应该有大约两百万个小组。
通过将三次样条拟合到现有的IV
- MNES
对,应使用每个分组来估算100 IV
网格的MNES
。这个网格从1/3变为3并且不是线性的,而是估计如下(这与我正在应用的方法有关 - graphically):
%let m = 500;
%let k = 2;
%let u = (1+&k) ** (1/&m);
data splined(keep=mnes);
do grid=-500 to 500;
mnes = (&u) ** grid;
end;
run;
然后通过计算每行的选项价格并按组分别对该特定函数求和,将每个分组合成为单个数字。考虑到结果数据集的体积(即1001个网格对象×2百万个组= 20亿行),我不知道是否一次性完成所有这一切 - 但循环似乎并不聪明。
我一次又一次地研究过,从我收集的内容中,有几种内置工具可用于估算SAS中的三次样条:
MNES
和IV
变量,通过使用逗号分隔列表。在循环中进行200万次迭代远非一个好主意 - 在我当前的实现中花了太长时间; 如果你不知道三次样条曲线是如何工作的,那么paper就会用非常简单的术语来解释它。
我已经彻底研究过这个问题,但我没有答案。我很欣赏有关如何有效地自动化此过程的任何建议。谢谢。
在@Joe的评论之后,这里有5个小组的数据集。我已经简化了网格参数,只有m = 5,因此每组11个点。 (请注意,我在have
和want
中删除了一些小数位以改进演示。)
have
membid date days iv mnes
-1 04JAN1996 365 0.15 0.91
-1 04JAN1996 365 0.14 0.94
-1 04JAN1996 365 0.14 0.96
-1 04JAN1996 365 0.13 0.98
-1 04JAN1996 365 0.13 1.00
-1 04JAN1996 365 0.13 1.02
-1 04JAN1996 365 0.12 1.04
-1 04JAN1996 365 0.12 1.06
-1 04JAN1996 365 0.12 1.08
-1 04JAN1996 365 0.11 1.09
-1 04JAN1996 365 0.11 1.11
-1 04JAN1996 365 0.11 1.13
-1 05JAN1996 365 0.15 0.91
-1 05JAN1996 365 0.14 0.94
-1 05JAN1996 365 0.14 0.96
-1 05JAN1996 365 0.13 0.98
-1 05JAN1996 365 0.13 1.00
-1 05JAN1996 365 0.13 1.02
-1 05JAN1996 365 0.12 1.04
-1 05JAN1996 365 0.12 1.06
-1 05JAN1996 365 0.12 1.08
-1 05JAN1996 365 0.11 1.09
-1 05JAN1996 365 0.11 1.11
-1 05JAN1996 365 0.11 1.13
-1 08JAN1996 365 0.14 0.91
-1 08JAN1996 365 0.14 0.94
-1 08JAN1996 365 0.13 0.96
-1 08JAN1996 365 0.13 0.98
-1 08JAN1996 365 0.12 1.00
-1 08JAN1996 365 0.12 1.02
-1 08JAN1996 365 0.13 1.04
-1 08JAN1996 365 0.12 1.06
-1 08JAN1996 365 0.12 1.08
-1 08JAN1996 365 0.12 1.10
-1 08JAN1996 365 0.11 1.11
-1 08JAN1996 365 0.11 1.13
-1 09JAN1996 365 0.15 0.91
-1 09JAN1996 365 0.14 0.94
-1 09JAN1996 365 0.14 0.96
-1 09JAN1996 365 0.14 0.98
-1 09JAN1996 365 0.13 1.00
-1 09JAN1996 365 0.13 1.02
-1 09JAN1996 365 0.12 1.04
-1 09JAN1996 365 0.12 1.06
-1 09JAN1996 365 0.12 1.08
-1 09JAN1996 365 0.11 1.09
-1 09JAN1996 365 0.11 1.11
-1 09JAN1996 365 0.11 1.13
-1 10JAN1996 365 0.15 0.91
-1 10JAN1996 365 0.15 0.94
-1 10JAN1996 365 0.14 0.96
-1 10JAN1996 365 0.14 0.98
-1 10JAN1996 365 0.13 1.00
-1 10JAN1996 365 0.13 1.02
-1 10JAN1996 365 0.13 1.05
-1 10JAN1996 365 0.12 1.06
-1 10JAN1996 365 0.12 1.08
-1 10JAN1996 365 0.12 1.10
-1 10JAN1996 365 0.12 1.12
-1 10JAN1996 365 0.11 1.14
want
grid membid date days mnes iv
-5 -1 13152 365 0.3333 0.15207
-4 -1 13152 365 0.4152 0.15207
-3 -1 13152 365 0.5172 0.15207
-2 -1 13152 365 0.6443 0.15207
-1 -1 13152 365 0.8027 0.15207
0 -1 13152 365 1 0.13631
1 -1 13152 365 1.2457 0.11354
2 -1 13152 365 1.5518 0.11354
3 -1 13152 365 1.9331 0.11354
4 -1 13152 365 2.4082 0.11354
5 -1 13152 365 3 0.11354
-5 -1 13153 365 0.3333 0.15217
-4 -1 13153 365 0.4152 0.15217
-3 -1 13153 365 0.5172 0.15217
-2 -1 13153 365 0.6443 0.15217
-1 -1 13153 365 0.8027 0.15217
0 -1 13153 365 1 0.135057
1 -1 13153 365 1.2457 0.115
2 -1 13153 365 1.5518 0.115
3 -1 13153 365 1.9331 0.115
4 -1 13153 365 2.4082 0.115
5 -1 13153 365 3 0.115
-5 -1 13156 365 0.3333 0.14731
-4 -1 13156 365 0.4152 0.14731
-3 -1 13156 365 0.5172 0.14731
-2 -1 13156 365 0.6443 0.14731
-1 -1 13156 365 0.8027 0.14731
0 -1 13156 365 1 0.131243
1 -1 13156 365 1.2457 0.11656
2 -1 13156 365 1.5518 0.11656
3 -1 13156 365 1.9331 0.11656
4 -1 13156 365 2.4082 0.11656
5 -1 13156 365 3 0.11656
-5 -1 13157 365 0.3333 0.15556
-4 -1 13157 365 0.4152 0.15556
-3 -1 13157 365 0.5172 0.15556
-2 -1 13157 365 0.6443 0.15556
-1 -1 13157 365 0.8027 0.15556
0 -1 13157 365 1 0.13881
1 -1 13157 365 1.2457 0.11447
2 -1 13157 365 1.5518 0.11447
3 -1 13157 365 1.9331 0.11447
4 -1 13157 365 2.4082 0.11447
5 -1 13157 365 3 0.11447
-5 -1 13158 365 0.3333 0.15920
-4 -1 13158 365 0.4152 0.15920
-3 -1 13158 365 0.5172 0.15920
-2 -1 13158 365 0.6443 0.15920
-1 -1 13158 365 0.8027 0.15920
0 -1 13158 365 1 0.14023
1 -1 13158 365 1.2457 0.11923
2 -1 13158 365 1.5518 0.11923
3 -1 13158 365 1.9331 0.11923
4 -1 13158 365 2.4082 0.11923
5 -1 13158 365 3 0.11923
使用以下代码生成want
数据集。 optday
是一个只有have
数据集的一个副组的数据集(我使用proc sql和宏循环到#34;到达那里")。 contribution
和option price
是我需要的其他字段。
data _null_;
set optday end=last;
if _n_ = 1 then do;
call symput("first1",mnes);
call symput("first1_v",iv);
end;
if last then do;
call symput("last1",mnes);
call symput("last1_v",iv);
end;
run;
proc sql noprint;
select mnes into:mneslist
separated by ','
from optday;
select iv into:IVlist
separated by ','
from optday;
select count(*) into:countlist
from optday;
quit;
data want;
do grid=-500 to 500;
membid = &currmembid;
date = "&currdate"d;
days = &currdays;
mnes = (&u) ** grid;
if mnes < &first1 then IV = &first1_v;
if mnes > &last1 then IV = &last1_v;
if mnes >= &first1 and mnes <= &last1 then IV = msplint(mnes, &countlist, &mneslist, &IVlist);
if mnes < 1 then optionprice = BLKSHPTPRC(mnes,&currdays/365,1,&currrate/100,iv);
else optionprice = BLKSHCLPRC(mnes,&currdays/365,1,&currrate/100,iv);
contrib = (1-(log(1+&k)/(&m))*grid)*optionprice/(&u)**grid;
output;
end;
run;
请注意,本文中使用的网格机制取自Buss和Vilkov在Vilkov网站上公开提供的MATLAB代码,其中包含选项数据的免模型隐含度量:http://www.vilkov.net/www/content/code-and-useful-stuff
答案 0 :(得分:0)
我能够解决这个问题,因此我正在分享我的解决方案。我相信它非常有效 - 它可以在3到4个小时内运行我需要的所有过程。我以前的估计是10天。
我按照以下步骤操作:
have
; mnes
范围之外的常量值,并为剩余的遗漏值进行插值。缺点:我无法动态指定我想在每个观察值处有一个样条线结。因此,我必须给出一定数量的结,并且它将在观察值之间平均分配它们。这使得已知mnes范围之外的值不是网格中的最终iv,而是另一个值。
以下是我使用的代码,包含示例信息:
data have;
input membid date days iv mnes;
datalines;
1 1 365 0.15 0.91
1 1 365 0.14 0.94
1 1 365 0.14 0.96
1 1 365 0.13 0.98
1 1 365 0.13 1.00
1 1 365 0.13 1.02
1 1 365 0.12 1.04
1 1 365 0.12 1.06
1 1 365 0.12 1.08
1 1 365 0.11 1.09
1 1 365 0.11 1.11
1 1 365 0.11 1.13
2 2 365 0.15 0.91
2 2 365 0.14 0.94
2 2 365 0.14 0.96
2 2 365 0.13 0.98
2 2 365 0.13 1.00
2 2 365 0.13 1.02
2 2 365 0.12 1.04
2 2 365 0.12 1.06
2 2 365 0.12 1.08
2 2 365 0.11 1.09
2 2 365 0.11 1.11
2 2 365 0.11 1.13
;
run;
* Set model inputs;
%let m = 500;
%let k = 2;
%let u = (1+&k) ** (1/&m);
%let a = 2 * (&u-1);
* Needed to sort data by groups;
proc sort data=have;
by membid date days mnes;
run;
* Create moneyness grid for each by group;
data _splined;
set have;
by membid date days;
if first.days then do grid=(-&m) to &m;
mnes = (&u) ** grid;
iv = .;
output;
end;
run;
* Append observations to generated moneyness grid;
proc datasets nolist;
append base=_splined
data=have;
quit;
* Sort these, because first come the moneyness grids and then all the observations;
proc sort data=_splined;
by membid date days mnes;
run;
* Apply cubic splines with 10 equally spaced knots;
proc transreg data=_splined short noprint;
model identity(iv)=spline(mnes / nknots=10);
output out=output1 p;
by membid date days;
run;
* Delete initial observations - these are marked by proc transreg with _type_ = 'SCORE';
data splined(keep=membid date days piv mnes);
set output1(keep=membid date days _type_ piv mnes);
if _type_ NE 'SCORE';
run;
如果您有任何疑问,请发表评论,我会尽力帮助您!
请注意,本文中使用的网格机制取自Buss和Vilkov在Vilkov网站上公开提供的MATLAB代码,其中包含选项数据的免模型隐含度量:http://www.vilkov.net/www/content/code-and-useful-stuff