|
1 |
| -using QuadGK, Dates |
| 1 | +using QuadGK, Dates, Distributions |
2 | 2 |
|
3 | 3 | # at the moment, only for black scholes. The dynamics should be use to get more generality.
|
4 |
| -struct CarrMadanBS <: AbstractPricingMethod |
| 4 | +struct CarrMadan <: AbstractPricingMethod |
5 | 5 | α
|
6 | 6 | bound
|
| 7 | + log_distribution |
7 | 8 | end
|
8 | 9 |
|
9 |
| -function characteristic_function(t, market_inputs::BlackScholesInputs, method::CarrMadanBS) |
10 |
| - r = market_inputs.rate |
11 |
| - σ = market_inputs.sigma |
12 |
| - return u -> exp(im * (r - σ^2 / 2) * u * t - u^2 * t * σ^2 / 2) |
| 10 | +function CarrMadan(α, bound; market_inputs::BlackScholesInputs) |
| 11 | + distribution(t) = Normal((market_inputs.rate - market_inputs.sigma^2 / 2) * t, market_inputs.sigma * sqrt(t)) |
| 12 | + return CarrMadan(α, bound, distribution) |
13 | 13 | end
|
14 | 14 |
|
15 |
| -function compute_price(payoff::VanillaOption{European, Call, Spot}, market_inputs::BlackScholesInputs, method::CarrMadanBS) |
| 15 | +# in distribution.jl t is Real, hence we need to redefine it. |
| 16 | +cf(d::Normal, t) = exp(im * t * d.μ - d.σ^2 / 2 * t^2) |
| 17 | + |
| 18 | +function compute_price(payoff::VanillaOption{European, Call, Spot}, market_inputs::BlackScholesInputs, method::CarrMadan) |
16 | 19 | damp = exp(- method.α * log(payoff.strike)) / 2π
|
17 | 20 | T = Dates.value(payoff.expiry - market_inputs.referenceDate) / 365
|
18 |
| - ϕ = characteristic_function(T, market_inputs, method) |
| 21 | + ϕ(u) = cf(method.log_distribution(T), u) |
19 | 22 | integrand(v) = call_transform(market_inputs.rate, T, ϕ, v, method) * exp(- im * v * log(payoff.strike))
|
20 | 23 | integral, error = quadgk(integrand, -method.bound, method.bound)
|
21 | 24 | return real(damp * integral)
|
22 | 25 | end
|
23 | 26 |
|
24 |
| -function call_transform(rate, time, ϕ, v, method::CarrMadanBS) |
| 27 | +function call_transform(rate, time, ϕ, v, method::CarrMadan) |
25 | 28 | numerator = exp(- rate * time) * ϕ(v - (method.α + 1)im)
|
26 | 29 | denominator = method.α^2 + method.α - v^2 + v * (2 * method.α + 1)im
|
27 | 30 | return numerator / denominator
|
|
0 commit comments