R Optimizing problems
I wrote a function bs.pp
that calculates the Black Scholes value of a Put option.
bs.pp <- function (Price, Strike, sigma, texp, int) {
d1=(1 / (sigma*sqrt(texp)))*(log(Price/Strike)+(int+(sigma^2)/2)*texp)
d2=d1-sigma*sqrt(texp)
Strike*pnorm(-d2)*exp(-int*texp)-Price*pnorm(-d1)}
Which seems to work well
> bs.pp(1000,1000,.2,1,.02)
[1] 69.35905
> bs.pp(1000,900,.25,1,.02)
[1] 46.15609
Now I'm trying to use the R function optimize
to calculate the inverse function, we know ( Price
, Strike
, texp
, int
), and the result of the function, but do not sigma
.
I tried to do it like this
gg <- function(Price, Strike, sigma, texp, int, PutPrice){(bs.pp(Price, Strike, sigma, texp, int) - PutPrice)^2}
xmin <- optimize(gg, c(0,1), tol = 0.0001, Price = 1000, Strike = 1000, texp = 1, int = 0.02, PutPrice = 69.4)
xmin$minimum
What the error returns
Error in optimize(gg, c(0, 1), tol = 1e-04, Price = 1000, Strike = 1000, :
'xmin' not less than 'xmax'
I wonder if I ran the following (note "int = 0.02" replaced with "0.02" in the optimization line)
gg <- function(Price, Strike, sigma, texp, int, PutPrice){(bs.pp(Price, Strike, sigma, texp, int) - PutPrice)^2}
xmin <- optimize(gg, c(0,1), tol = 0.0001, Price = 1000, Strike = 900, texp = 1, 0.02, PutPrice = 46.2)
xmin$minimum
I am getting the correct answer
[1] 0.2501474
And prove it wasn't just an accident
gg <- function(Price, Strike, sigma, texp, int, PutPrice){(bs.pp(Price, Strike, sigma, texp, int) - PutPrice)^2}
xmin <- optimize(gg, c(0,1), tol = 0.0001, Price = 1000, Strike = 1000, texp = 1, 0.02, PutPrice = 69.4)
xmin$minimum
returns the correct answer also
[1] 0.2001055
Any ideas? I tried to move the function arguments around to sigma
be the first, but that doesn't seem to make any difference.
Just FYI my final function would be the following, which I am sure could be written more elegantly
bs.piv <- function(Price, Strike, texp, intr, PutPrice){
optfunc <- function(P, S, sigma, t, i, PP){(bs.pp(Price, Strike, sigma, texp, intr) - PutPrice)^2}
xmin <- optimize(optfunc, c(0,1), tol = 0.0001, P=Price, S=Strike, t=texp, i=intr, PP=PutPrice)
xmin$minimum}
source to share
Naming all of your arguments is usually a good idea, especially when dealing with an argument ...
. In this case, the problem is fixed:
xmin <- optimize(f = gg, interval = c(0,1), tol = 0.0001, Price = 1000, Strike = 1000, texp = 1, int = 0.02, PutPrice = 69.4)
EDIT: as explained by @Roland, interval
corresponds int
, however is one example of the danger of partial matching arguments R.
source to share
In addition to @David H's answer, which provides a solution for naming an argument interval
, here's an explanation:
This is due to the partial agreement of the arguments. For details, see the definition of the language in section 4.3.2. In short, matching works in three steps:
1.) Exact name matches are searched between the supplied arguments and optimize the "arguments". For example interval
will match interval
here.
2.) Searches for partial name matches between supplied arguments and argument optimization. For example int
will match interval
here.
3.) Position matching is performed. "If there is an argument" ... ", it will accept the remaining arguments, whether marked or not." And it is ...
used optimize
to pass arguments to the function specified in f
.
So step 2 takes away your argument int
, because the partial match happens before the positions are matched.
source to share