1
- """ The Cox-Ross-Rubinstein binomial tree pricing method.
1
+ # Cox-Ross-Rubinstein Binomial Tree Pricing Implementation
2
2
3
- This struct represents the Cox-Ross-Rubinstein binomial pricing model for option pricing.
3
+ """
4
+ The Cox-Ross-Rubinstein binomial tree pricing method.
5
+
6
+ This struct represents the Cox-Ross-Rubinstein (CRR) binomial pricing model for option pricing.
7
+
8
+ # Fields
9
+ - `steps`: The number of time steps in the binomial tree.
10
+
11
+ # Notes
12
+ - This implementation supports options written on either the **forward price** or the **spot price**.
13
+ - When pricing an option on the forward price, discounting is already embedded in the forward.
14
+ - When pricing an option on the spot price, discounting must be explicitly applied at each step.
15
+ - The up probability is defined as:
16
+
17
+ ```
18
+ p = 1 / (1 + u)
19
+ ```
20
+ where:
21
+ - `u = exp(σ√ΔT)` is the up-move factor,
22
+ - `ΔT` is the time step duration in years.
4
23
"""
5
24
struct CoxRossRubinsteinMethod <: AbstractPricingMethod
6
- steps
25
+ steps:: Int
7
26
end
8
27
9
- function binomial_tree_value (step, discounted_continuation, underlying_at_i, payoff, :: European )
10
- return discounted_continuation
28
+ """
29
+ Returns the value at a given node in the binomial tree for a European option.
30
+
31
+ # Arguments
32
+ - `discounted_continuation`: Discounted expected future values from the next step.
33
+ - `::European`: Marker type for European exercise style.
34
+
35
+ # Returns
36
+ - The continuation value, as European options do not allow early exercise.
37
+ """
38
+ function binomial_tree_value (_, discounted_continuation, _, _, :: European )
39
+ return discounted_continuation
11
40
end
12
41
42
+ """
43
+ Returns the value at a given node in the binomial tree for an American option.
44
+
45
+ # Arguments
46
+ - `step`: Current time step in the binomial tree.
47
+ - `discounted_continuation`: Discounted expected future values from the next step.
48
+ - `underlying_at_i`: Function to compute the underlying price at a given step.
49
+ - `payoff`: Payoff function of the option.
50
+ - `::American`: Marker type for American exercise style.
51
+
52
+ # Returns
53
+ - The maximum between the continuation value and the intrinsic value of the option (early exercise is considered).
54
+ """
13
55
function binomial_tree_value (step, discounted_continuation, underlying_at_i, payoff, :: American )
14
- return max .(discounted_continuation, payoff (underlying_at_i (step)))
56
+ return max .(discounted_continuation, payoff (underlying_at_i (step)))
15
57
end
16
58
59
+ """
60
+ Computes the underlying asset price at a given step when pricing an option on the **spot price**.
61
+
62
+ # Arguments
63
+ - `time_step`: Current time step in the binomial tree.
64
+ - `forward`: Forward price of the underlying asset.
65
+ - `rate`: Risk-free rate.
66
+ - `delta_time`: Time step size in years.
67
+ - `::Spot`: Marker type indicating the option is written on the spot price.
68
+
69
+ # Returns
70
+ - The estimated spot price, derived by discounting the forward price.
71
+ """
17
72
function binomial_tree_underlying (time_step, forward, rate, delta_time, :: Spot )
18
- return exp (- rate* time_step* delta_time) * forward
73
+ return exp (- rate * time_step * delta_time) * forward
19
74
end
20
75
76
+ """
77
+ Computes the underlying asset price at a given step when pricing an option on the **forward price**.
78
+
79
+ # Arguments
80
+ - `forward`: Forward price of the underlying asset.
81
+ - `::Forward`: Marker type indicating the option is written on the forward price.
82
+
83
+ # Returns
84
+ - The forward price (unchanged, as forward prices already embed discounting).
85
+ """
21
86
function binomial_tree_underlying (_, forward, _, _, :: Forward )
22
- return forward
87
+ return forward
23
88
end
24
89
25
- function compute_price (payoff:: P , market_inputs:: BlackScholesInputs , method:: CoxRossRubinsteinMethod ) where P <: AbstractPayoff
26
- ΔT = Dates. value .(payoff. expiry .- market_inputs. referenceDate) ./ 365 / method. steps # we might want to specify daycount conventions to ensure consistency
27
- up_step = exp (market_inputs. sigma * sqrt (ΔT))
28
- forward_at_i (i) = market_inputs. forward * up_step .^ (- i: 2 : i)
29
- underlying_at_i (i) = binomial_tree_underlying (i, forward_at_i (i), market_inputs. rate, ΔT, payoff. underlying)
30
- up_probability = 1 / (1 + up_step)
31
- value = payoff (forward_at_i (method. steps))
32
-
33
- for step in (method. steps- 1 ): - 1 : 0
34
- continuation = up_probability * value[2 : end ] + (1 - up_probability) * value[1 : end - 1 ]
35
- df = exp (- market_inputs. rate * ΔT)
36
- value = binomial_tree_value (step, df * continuation, underlying_at_i, payoff, payoff. exercise_style)
37
- end
38
-
39
- return value[1 ]
40
- end
90
+ """
91
+ Computes the price of a vanilla option using the Cox-Ross-Rubinstein binomial tree model.
92
+
93
+ # Arguments
94
+ - `payoff`: The option payoff function, which determines intrinsic value.
95
+ - `market_inputs`: Market data including forward price, risk-free rate, and volatility.
96
+ - `method`: The CRR pricing method with a defined number of steps.
97
+
98
+ # Returns
99
+ - The computed option price using backward induction.
100
+
101
+ # Notes
102
+ - This implementation supports **options on either forward prices or spot prices**.
103
+ - If the option is written on a forward price, discounting is embedded.
104
+ - If the option is written on a spot price, discounting is applied explicitly.
105
+ - The up-move factor is computed as `u = exp(σ√ΔT)`, and the up probability is given by `p = 1 / (1 + u)`.
106
+ """
107
+ function compute_price (payoff, market_inputs, method:: CoxRossRubinsteinMethod )
108
+ steps = method. steps
109
+ ΔT = Dates. value .(payoff. expiry - market_inputs. referenceDate) / 365 / steps # Assuming ACT/365 day count
110
+ u = exp (market_inputs. sigma * sqrt (ΔT)) # Up-move factor
111
+ forward_at_i (i) = market_inputs. forward * u .^ (- i: 2 : i)
112
+ underlying_at_i (i) = binomial_tree_underlying (i, forward_at_i (i), market_inputs. rate, ΔT, payoff. underlying)
113
+
114
+ # Up probability in forward measure
115
+ p = 1 / (1 + u)
116
+
117
+ # Initialize terminal payoffs
118
+ value = payoff .(forward_at_i (steps))
119
+
120
+ # Backward induction
121
+ for step in (steps- 1 ): - 1 : 0
122
+ continuation = p * value[2 : end ] + (1 - p) * value[1 : end - 1 ]
123
+ df = exp (- market_inputs. rate * ΔT) # Discounting
124
+ value = binomial_tree_value (step, df * continuation, underlying_at_i, payoff, payoff. exercise_style)
125
+ end
126
+
127
+ return value[1 ]
128
+ end
0 commit comments