[R-SIG-Finance] American option sensitivities
J Toll
jctoll at gmail.com
Fri Feb 10 15:24:51 CET 2012
On Fri, Feb 10, 2012 at 3:18 AM, Enrico Schumann
<enricoschumann at yahoo.de> wrote:
>
> Hi all,
>
> (comments below)
>
> Am 10.02.2012 01:02, schrieb J Toll:
>
>> On Thu, Feb 9, 2012 at 5:17 PM, Dirk Eddelbuettel<edd at debian.org> wrote:
>>>
>>>
>>> On 9 February 2012 at 17:06, J Toll wrote:
>>> | Hi,
>>> |
>>> | I'd like to calculate sensitivities on American options. I was hoping
>>> | somebody might be able to summarize of the current state of that
>>> | functionality within the various R packages. It's my understanding
>>> | that the fOptions package can calculate greeks for European options
>>> | but not American. RQuantLib appears to have had the ability to
>>> | calculate greeks for American options at one point, but it appears
>>> | that functionality was removed in Release 0.1.8 sometime around
>>> | 2003-11-28.
>>>
>>> ... because that functionality was removed upstream by QuantLib.
>>>
>>> |
>>> |
>>> http://lists.r-forge.r-project.org/pipermail/rquantlib-commits/2010-August/000117.html
>>> |
>>> | Additionally, from RQuantLib ?AmericanOptions says,
>>> |
>>> | "Note that under the new pricing framework used in QuantLib, binary
>>> | pricers do not provide analytics for 'Greeks'. This is expected to be
>>> | addressed in future releases of QuantLib."
>>> |
>>> | I haven't found any other packages for calculating option
>>> | sensitivities. Are there any other packages?
>>> |
>>> | Regarding RQuantLib, is the issue that that functionality hasn't been
>>> | implemented in R yet, or is it QuantLib that's broken?
>>>
>>> There is a third door behind which you find the price: "numerical
>>> shocks".
>>>
>>> Evaluate your american option, then shift the various parameters (spot,
>>> vol,
>>> int.rate, time to mat, ...) each by a small amount and calculate the
>>> change
>>> in option price -- voila for the approximate change in option value for
>>> change input. You can also compute twice at 'x - eps' and 'x + eps'
>>> etc.
>>>
>>> Dirk
>>
>>
>> Dirk,
>>
>> Thank you for your response. I was hoping you might reply.
>>
>> I understand the concept of your suggestion, although I don't have any
>> practical experience implementing it. I'm guessing this is what's
>> generally referred to as finite difference methods. In theory, the
>> first order greeks should be simple enough, although my impression is
>> the second or third order greeks may be a bit more challenging.
>>
>> I hate to trouble you for more information, but I'm curious why? Is
>> this the "standard" method of calculating greeks for American options?
>> Has QuantLib decided not to implement this calculation? Just curious.
>>
>> Thanks again,
>>
>
> A simple forward difference is
>
> [f(x + h) - f(x)] / h
>
> 'f' is the option pricing formula; 'x' are the arguments to the formula, and
> 'h' is a small offset.
>
> Numerically, 'h' should not be made too small:
>
> (1) Even for smooth functions, we trade off truncation error (which is large
> when 'h' is large) against roundoff-error (in the extreme, 'x + h' may still
> be 'x' for a very small 'h').
>
> (2) American options are typically valued via finite-difference or tree
> methods, and hence 'f' is not smooth and any 'bumps' in the function will be
> magnified by dividing by a very small 'h'. So when 'h' is too small, the
> results will become nonsensical.
>
> Here is an example. As a first test, I use a European option.
>
> require("RQuantLib")
> h <- 1e-4
> S <- 100
> K <- 100
> tau <- 0.5
> vol <- 0.3
> C0 <- EuropeanOption(type = "call",
> underlying = S, strike = K,
> dividendYield = 0.0,
> riskFreeRate = 0.03, maturity = tau,
> volatility = 0.3)
> Cplus <- EuropeanOption(type="call",
> underlying = S + h, strike = K,
> dividendYield = 0.0,
> riskFreeRate=0.03, maturity=tau,
> volatility=0.3)
> Cminus <- EuropeanOption(type="call",
> underlying = S - h, strike=K,
> dividendYield=0.0,
> riskFreeRate=0.03, maturity=tau,
> volatility=0.3)
>
> ## a first-order difference: delta
> (Cplus$value-C0$value)/h
> ## [1] 0.570159
> C0$delta
> ## [1] 0.5701581
>
>
> ## a second-order difference
> (Cplus$delta-C0$delta)/h
> ## [1] 0.01851474
> C0$gamma
> ## [1] 0.01851475
>
>
>
>
> Now for an American option. Here we don't have the delta, so we first need
> to compute it as well.
>
> C0 <- AmericanOption(type="put",
> underlying = S, strike=K,
> dividendYield=0.0,
> riskFreeRate=0.03, maturity=tau,
> volatility=vol)
> Cplus <- AmericanOption(type="put",
> underlying = S + h, strike=K,
> dividendYield=0.0,
> riskFreeRate=0.03, maturity=tau,
> volatility=vol)
> Cminus <- AmericanOption(type="put",
> underlying = S - h, strike=K,
> dividendYield=0.0,
> riskFreeRate=0.03, maturity=tau,
> volatility=vol)
>
> ## a first-order difference: delta
> (dplus <- (Cplus$value - C0$value)/h)
> (dminus <-(C0$value - Cminus$value)/h)
>
> ## a second-order difference
> (dplus - dminus)/h
> ## [1] 0.01905605
>
> I ran a little a experiment with different levels of 'h', where you can
> clearly see when the gamma diverges.
>
> | h | gamma |
> | 1 | 0.01905385 |
> | 0.01 | 0.01905612 |
> | 1e-4 | 0.01905605 |
> | 1e-5 | 0.01915801 |
> | 1e-6 | 0.03463896 |
> | 1e-8 | 8.881784 |
>
>
> In the literatur, you find a number of tricks to smooth the function, but in
> my experience, you are fine if you make 'h' small with respect to 'x' --
> small, not tiny. So if the stock price is 100, a change of 1 or 0.1 is
> small. (And think of it: even if we found that a change of one-thousandth of
> a cent led to a meaningful numerical difference; if the stock price never
> moves by such an amount, such a computation would not be empirically
> meaningful.)
>
>
> Regards,
> Enrico
>
Enrico,
Thank you so much for such a detailed and helpful example. I had
found an article on Wikipedia mentioning many of the issues you write
about regarding selection of h. In that article, the author/s
suggest:
"A choice for h which is small without producing a large rounding
error is sqrt(ε x) where the machine epsilon ε is typically of the
order 2.2×10-16."
http://en.wikipedia.org/wiki/Numerical_differentiation
So for R, I suppose that would equate to:
h <- sqrt(.Machine$double.eps * x)
Thanks again for your really helpful example.
Best,
James
>
>
>>
>> James
>>
>>
>>
>>>
>>> |
>>> | Thanks for any clarification.
>>> |
>>> | Best,
>>> |
>>> |
>>> | James
>>> |
>>> | _______________________________________________
>>> | R-SIG-Finance at r-project.org mailing list
>>> | https://stat.ethz.ch/mailman/listinfo/r-sig-finance
>>> | -- Subscriber-posting only. If you want to post, subscribe first.
>>> | -- Also note that this is not the r-help list where general R questions
>>> should go.
>>>
>>> --
>>> "Outside of a dog, a book is a man's best friend. Inside of a dog, it is
>>> too
>>> dark to read." -- Groucho Marx
>>
>>
>> _______________________________________________
>> R-SIG-Finance at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
>> -- Subscriber-posting only. If you want to post, subscribe first.
>> -- Also note that this is not the r-help list where general R questions
>> should go.
>
>
> --
> Enrico Schumann
> Lucerne, Switzerland
> http://nmof.net/
More information about the R-SIG-Finance
mailing list