1
1
# Exports
2
- export ForwardAD, FiniteDifference, GreekProblem, SecondOrderGreekProblem
2
+ export ForwardAD, FiniteDifference, GreekProblem, SecondOrderGreekProblem, AnalyticGreek
3
3
4
4
# Method types
5
5
abstract type GreekMethod end
@@ -10,13 +10,16 @@ struct FDForward <: FDScheme end
10
10
struct FDBackward <: FDScheme end
11
11
struct FDCentral <: FDScheme end
12
12
13
+ struct AnalyticGreek <: GreekMethod end
14
+
13
15
struct ForwardAD <: GreekMethod end
16
+
14
17
struct FiniteDifference{S<: FDScheme } <: GreekMethod
15
18
bump
16
19
scheme:: S
17
20
end
18
21
19
- FiniteDifference (bump) = FiniteDifference (bump, CentralFiniteDifference ())
22
+ FiniteDifference (bump) = FiniteDifference (bump, FDCentral ())
20
23
21
24
# First-order GreekProblem
22
25
struct GreekProblem{P, L}
@@ -60,7 +63,7 @@ function compute_fd_derivative(::FDCentral, prob, lens, ε, pricing_method)
60
63
return (v_up - v_down) / (2 ε)
61
64
end
62
65
63
- function solve (gprob:: GreekProblem , method:: FiniteDifference{S} , pricing_method:: P ) where {S<: FiniteDifferenceScheme , P<: AbstractPricingMethod }
66
+ function solve (gprob:: GreekProblem , method:: FiniteDifference{S} , pricing_method:: P ) where {S<: FDScheme , P<: AbstractPricingMethod }
64
67
prob = gprob. pricing_problem
65
68
lens = gprob. wrt
66
69
ε = method. bump
@@ -119,3 +122,76 @@ function solve(gprob::SecondOrderGreekProblem, method::FiniteDifference, pricing
119
122
120
123
return (greek = deriv,)
121
124
end
125
+
126
+ function solve (gprob:: GreekProblem , :: AnalyticGreek , :: BlackScholesAnalytic )
127
+ prob = gprob. pricing_problem
128
+ lens = gprob. wrt
129
+ inputs = prob. market
130
+
131
+ S = inputs. spot
132
+ σ = inputs. sigma
133
+ T = yearfrac (prob. market. referenceDate, prob. payoff. expiry)
134
+ K = prob. payoff. strike
135
+
136
+ D = df (prob. market. rate, T)
137
+ F = prob. market. spot / D
138
+ √ T = sqrt (T)
139
+ d1 = (log (F / K) + 0.5 * σ^ 2 * T) / (σ * √ T)
140
+ d2 = d1 - σ * √ T
141
+
142
+ Φ = x -> cdf (Normal (), x)
143
+ ϕ = x -> pdf (Normal (), x)
144
+
145
+ greek = if lens === @optic _. market. spot
146
+ # Delta = ∂V/∂S = ∂V/∂F * ∂F/∂S = (cp * N(cp·d1)) * (1/D)
147
+ cp * Φ (cp * d1)
148
+
149
+ elseif lens === @optic _. market. sigma
150
+ # Vega = ∂V/∂σ = D · F · φ(d1) · √T
151
+ D * F * ϕ (d1) * √ T
152
+
153
+ else
154
+ error (" Unsupported lens for analytic Greek" )
155
+ end
156
+
157
+ return (greek = greek,)
158
+ end
159
+
160
+ function solve (
161
+ gprob:: SecondOrderGreekProblem ,
162
+ :: AnalyticGreek ,
163
+ :: BlackScholesAnalytic
164
+ )
165
+ prob = gprob. pricing_problem
166
+ lens1 = gprob. wrt1
167
+ lens2 = gprob. wrt2
168
+ inputs = prob. market
169
+
170
+ S = inputs. spot
171
+ σ = inputs. sigma
172
+ T = yearfrac (inputs. referenceDate, prob. payoff. expiry)
173
+ K = prob. payoff. strike
174
+
175
+ D = df (inputs. rate, T)
176
+ F = S / D
177
+ √ T = sqrt (T)
178
+ d1 = (log (F / K) + 0.5 * σ^ 2 * T) / (σ * √ T)
179
+ d2 = d1 - σ * √ T
180
+
181
+ ϕ = x -> pdf (Normal (), x)
182
+
183
+ greek = if (lens1 === @optic _. market. spot) && (lens2 === @optic _. market. spot)
184
+ # Gamma = ∂²V/∂S² = φ(d1) / (Sσ√T)
185
+ ϕ (d1) / (S * σ * √ T)
186
+
187
+ elseif (lens1 === @optic _. market. sigma) && (lens2 === @optic _. market. sigma)
188
+ # Volga = Vega * d1 * d2 / σ
189
+ vega = D * F * ϕ (d1) * √ T
190
+ vega * d1 * d2 / σ
191
+
192
+ else
193
+ error (" Unsupported second-order analytic Greek" )
194
+ end
195
+
196
+ return (greek = greek,)
197
+ end
0 commit comments