I’d like to calculate the implied volatility (IV) of a table t
containing an option chain.
The function to calculate the IV is:
// Newton-Raphson method to find implied volatility
impliedVol:{[S;K;T;r;isCall;marketPrice]
sigma:0.5; // Initial guess
tolerance:1e-6;
i:0;
diff:1;
while[abs[diff]>tolerance and i<100;
result:.deriv.bsm[S;K;r;T;isCall;sigma];
diff:result[`price]-marketPrice;
sigma:sigma-diff%result[`vega];
i+:1;
];
sigma:$[i=100; 0N; sigma]
};
The above function works OK for scalar inputs, however for using it inside a select statement it fails since it makes the variable diff
a list (instead of scalar) presumed by the function. As a workaround I could do:
ivFunc:{[rate;row] impliedVol[row`S; row`K; row[`daysLeft]%365; rate; row`isCall; row`close]};
t:update IV:100*ivFunc[rate] peach t from t
which despite peach
is excrutiatingly slow.
How can i modify impliedVol
so that I can write the following and thus expect vectorization to speed things through?
r:0.04;
t:update IV:100 * impliedVol[S;K;daysLeft%365;(count)#r;isCall;close];
1