Skip to content

Commit 3592458

Browse files
committed
Working on CRR
1 parent 37ff127 commit 3592458

File tree

6 files changed

+76
-19
lines changed

6 files changed

+76
-19
lines changed

examples/example.jl

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,28 @@ using BenchmarkTools
33

44
"""Example code with benchmarks"""
55
# Define market data and payoff
6-
market_inputs = h.BlackScholesInputs(0.01, 1, 0.4)
6+
market_inputs = h.BlackScholesInputs(0, 0.4, 1, 0.4)
77
payoff = h.VanillaEuropeanCall(1, 1)
8-
pricer = h.Pricer(market_inputs, payoff, h.BlackScholesMethod())
9-
println(pricer())
8+
analytical_pricer = h.Pricer(payoff, market_inputs, h.BlackScholesMethod())
9+
price = h.price(payoff, market_inputs, h.BlackScholesMethod())
10+
11+
crr = h.CoxRossRubinsteinMethod(2000)
12+
crr_pricer = h.Pricer(payoff, market_inputs, crr)
13+
println("Cox Ross Rubinstein:")
14+
println(crr_pricer())
15+
16+
println("Analytical price:")
17+
println(analytical_pricer())
1018
# Analytical Delta
11-
analytical_delta_calc = h.DeltaCalculator(pricer, h.BlackScholesAnalyticalDelta())
19+
analytical_delta_calc = h.DeltaCalculator(analytical_pricer, h.BlackScholesAnalyticalDelta())
1220
println(analytical_delta_calc())
1321

1422
# AD Delta
15-
ad_delta_calc = h.DeltaCalculator(pricer, h.ADDelta())
23+
ad_delta_calc = h.DeltaCalculator(analytical_pricer, h.ADDelta())
1624
println(ad_delta_calc())
1725

1826
println("Benchmarking pricer:")
19-
@btime pricer()
27+
@btime analytical_pricer()
2028

2129
# Run benchmarks
2230
println("Benchmarking Analytical Delta:")

src/Hedgehog2.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module Hedgehog2
22

33
using BenchmarkTools, ForwardDiff, Distributions, Accessors
44

5+
if false
6+
include("../examples/example.jl")
7+
end
8+
59
include("payoffs.jl")
610
include("market_inputs.jl")
711
include("pricing_methods.jl")

src/delta_methods.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function (delta_calc::DeltaCalculator{BlackScholesAnalyticalDelta, VanillaEurope
4444
K = delta_calc.pricer.payoff.strike
4545
r = delta_calc.pricer.marketInputs.rate
4646
σ = delta_calc.pricer.marketInputs.sigma
47-
T = delta_calc.pricer.payoff.time
47+
T = delta_calc.pricer.payoff.expiry
4848
d1 = (log(S / K) + (r + 0.5 * σ^2) * T) /* sqrt(T))
4949
return cdf(Normal(), d1) # Black-Scholes delta for calls
5050
end

src/market_inputs.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ abstract type AbstractMarketInputs end
99
- `sigma`: The volatility of the underlying asset.
1010
1111
This struct encapsulates the necessary inputs for pricing derivatives under the Black-Scholes model.
12+
It is assumed that the volatility is annual.
1213
"""
1314
struct BlackScholesInputs <: AbstractMarketInputs
15+
today
1416
rate
1517
spot
1618
sigma

src/payoffs.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ abstract type AbstractPayoff end
55
66
# Fields
77
- `strike`: The strike price of the option.
8-
- `time`: The time to maturity of the option.
8+
- `expiry`: The time to maturity of the option.
99
1010
This struct represents a European call option, which provides a payoff of `max(spot - strike, 0.0)`.
1111
"""
1212
struct VanillaEuropeanCall <: AbstractPayoff
1313
strike
14-
time
14+
expiry
1515
end
1616

1717
"""Computes the payoff of a vanilla European call option given a spot price.
@@ -24,5 +24,5 @@ end
2424
- The payoff value, calculated as `max(spot - payoff.strike, 0.0)`.
2525
"""
2626
function (payoff::VanillaEuropeanCall)(spot)
27-
return max(spot - payoff.strike, 0.0)
27+
return max.(spot .- payoff.strike, 0.0)
2828
end

src/pricing_methods.jl

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,24 @@ struct BlackScholesMethod <: AbstractPricingMethod end
2222
A `Pricer` is a callable struct that computes the price of the derivative using the specified pricing method.
2323
"""
2424
struct Pricer{P <: AbstractPayoff, M <: AbstractMarketInputs, S <: AbstractPricingMethod}
25-
marketInputs::M
26-
payoff::P
27-
pricingMethod::S
25+
payoff::P
26+
marketInputs::M
27+
pricingMethod::S
28+
end
29+
30+
"""
31+
Computes the price based on a Pricer input object.
32+
33+
# Arguments
34+
- `pricer::Pricer{A, B, C}`:
35+
A `Pricer`, specifying a payoff, a market inputs and a method.
36+
37+
# Returns
38+
- The computed price of the derivative.
39+
40+
"""
41+
function (pricer::Pricer{A,B,C})() where {A<:AbstractPayoff,B<:AbstractMarketInputs,C<:AbstractPricingMethod}
42+
return price(pricer.payoff, pricer.marketInputs, pricer.pricingMethod)
2843
end
2944

3045
"""Computes the price of a vanilla European call option using the Black-Scholes model.
@@ -44,13 +59,41 @@ price = S * Φ(d1) - K * exp(-r * T) * Φ(d2)
4459
```
4560
where `Φ` is the CDF of the standard normal distribution.
4661
"""
47-
function (pricer::Pricer{VanillaEuropeanCall, BlackScholesInputs, BlackScholesMethod})()
48-
S = pricer.marketInputs.spot
49-
K = pricer.payoff.strike
50-
r = pricer.marketInputs.rate
51-
σ = pricer.marketInputs.sigma
52-
T = pricer.payoff.time
62+
function price(payoff::VanillaEuropeanCall, marketInputs::BlackScholesInputs, method::BlackScholesMethod)
63+
S = marketInputs.spot
64+
K = payoff.strike
65+
r = marketInputs.rate
66+
σ = marketInputs.sigma
67+
T = payoff.expiry
5368
d1 = (log(S / K) + (r + 0.5 * σ^2) * T) /* sqrt(T))
5469
d2 = d1 - σ * sqrt(T)
5570
return S * cdf(Normal(), d1) - K * exp(-r * T) * cdf(Normal(), d2)
5671
end
72+
73+
"""The Cox-Ross-Rubinstein binomial tree pricing method.
74+
75+
This struct represents the Cox-Ross-Rubinstein binomial pricing model for option pricing.
76+
"""
77+
struct CoxRossRubinsteinMethod <: AbstractPricingMethod
78+
steps
79+
end
80+
81+
function price(payoff::P, market_inputs::BlackScholesInputs, method::CoxRossRubinsteinMethod) where P <: AbstractPayoff
82+
ΔT = (payoff.expiry - market_inputs.today) / method.steps
83+
step_size = exp(market_inputs.sigma * sqrt(ΔT))
84+
up_probability = 1 / (1 + step_size) # this should be specified by the tree choices, configurations of the
85+
spots_at_i = i -> step_size .^ (-i:2:i)
86+
87+
p = up_probability
88+
value = payoff(spots_at_i(method.steps))
89+
90+
for step in method.steps-1:-1:0
91+
continuation = p * value[2:end] + (1 - p) * value[1:end-1]
92+
df = exp(-market_inputs.rate * ΔT)
93+
value = df * continuation
94+
95+
end
96+
97+
return value
98+
99+
end

0 commit comments

Comments
 (0)