(SAS)期权使用proc模型或任何程序计算隐含波动率

时间:2017-05-04 11:34:47

标签: sas

我是初学者使用SAS。 我想计算隐含波动率。

我的数据集如下所示

Option_code / put_call_idx / underlying_price / dividend_yield / maturity / option_premium / strike_price / etc.

A / "PUT" / 1000 / 0.5 / 13 / 5 / 980 / .......
B / "CALL" / 1000 / 0.5 / 13 / 10 / 990 / .......

每一行都有不同的选项信息,所以我希望得到我的决赛 解决隐含波动率后的数据集,其形式如下:

A / "PUT" / 1000 / 0.5 / 13 / ...... / **0.15 (IV for option A)**
B / "CALL" / 1000 / 0.5 / 13 / ...... / **0.18 (IV for option B)**

我的凌乱代码看起来像这样

proc model data = INPUT noprint;

exogenous ksp200 ksp200_div ttm strike_prc rf;

endogenous iv;

n_1 = log(ksp200 * exp((rf - ksp200_div) * (ttm/250)) / strke_price

.... other Black-Scholes Formula input  .......

0 = abs(model price - market price)

solve iv / maxiter = 100 converge = 0.1 out = iv_root;
by option_code;

run;

执行某些行后,有正确的解决方案但有错误消息 意思是一些观察在牛顿方法迭代之后没有解决方案。

我认为来自实际交换的数据引用了错误消息对我没有意义。所以我的杂乱的代码或方法定义错了?还是有其他计算隐含波动率的方法?

让我知道一些引用或参考页面。

1 个答案:

答案 0 :(得分:0)

我经常处理这个问题。通常时间选项报价是陈旧的,没有意义。当您尝试求解隐含波动率时,解决方案会在IV = 0时达到界限。例如,一个简单的电话报价为5美元,但这笔钱是6美元。您应该检查没有意义的值并找到处理它们的方法。

我喜欢你的PROC MODEL方法我个人会使用PROC FCMP将它们放入我自己的函数中并使用数据步骤。 SOLVE中有一个FCMP函数可以为您找到根。

proc fcmp outlib=work.fns.options;

/*Taken from Wikipedia - BS with a continous dividend*/
function optPrc(type $, K,S,q,r,ttm,vol);
    d1 = (1/(vol*sqrt(ttm)))*(log(S/K)+(r-q+.5*vol**2)*ttm);
    d2 = d1-(vol*sqrt(ttm));
    F=S*exp((r-q)*ttm);
    ert = exp(-r*ttm);
    prc = .;
    if upcase(substr(type,1,1)) = "C" then 
        prc = ert*(F*cdf('NORMAL',d1,0,1)-K*cdf('NORMAL',d2,0,1));
    else if upcase(substr(type,1,1)) = "P" then
        prc = ert*(K*cdf('NORMAL',-d2,0,1)-F*cdf('NORMAL',-d1,0,1));

    return(prc);

endsub;

/*IV Solver*/
function opt_iv(type $, K,S,q,r,ttm,opt_prc);

    iv = .;
    prc = optPrc(type , K,S,q,r,ttm,1e-8);
    if opt_prc < prc then do;
        PUT "ERROR: Option Price out of bounds" opt_prc= prc= "at 0 vol";
    end;
    else do;
        array opts[5] initial abconv relconv maxiter status
                        (.5   .001   1.0e-6  100     -1);

        iv = solve("optPrc",opts, opt_prc, type , K, S, q, r, ttm, .);
        if status ^= 0 then 
            PUT "ERROR: Problem Solving." STATUS=;
    end;

    return (iv);
endsub;

run;
quit;

options cmplib=(work.fns);

data test;
Type = "PUT";
Underlying = 1000;
Div_Yield = 0.5;
Maturity = 13;
Opt_Prc=5;
Strike=980;
output;
Type = "CALL";
Underlying = 1000;
Div_Yield = 0.5;
Maturity = 13;
Opt_Prc=10;
Strike=990;
output;

/*This obviously is bad - call is $10 in the money, but quoted at 5*/
Type = "CALL";
Underlying = 1000;
Div_Yield = 0;
Maturity = 13;
Opt_Prc=5;
Strike=990;
output;


/*This obviously is put - put is $10 in the money, but quoted at 5*/
Type = "PUT";
Underlying = 1000;
Div_Yield = 0;
Maturity = 13;
Opt_Prc=5;
Strike=1010;
output;
run;


data test2;
set test;

iv= opt_iv(type, Strike,Underlying,Div_Yield/100,0.005,Maturity/250,Opt_Prc);
run;