# Black Scholes Theta Finite difference

I am trying to obtain the Theta from Closed Formula by using Finite Difference methods and I observe some discrepancies. For instance, here with the following parameters:

Spot:50, Strike:50, Rate: 0.12 Time To maturity: 0.25, Volatility: 0.3

BS Closed Form: -8.528247797676

BS Forward FD: -5.8503941392455516

I applied a change of -1/365 in T to compute the BS Forward FD.

Please note that I am perfectly able to match Delta, Gamma and Vega. I don’t know what is wrong with Theta. Any idea?

First and foremost I do not agree with you Closed Form value. I get $\Theta=-8.963$. There are various of BS calculator you can use the check your results and in general you should do that. Here is one: https://goodcalculators.com/black-scholes-calculator/

Have in mind that maturity T is fixed then your forward FD problem should look like this: $$\Theta(T-t_0) \approx \frac{C(....,T-t_0+h)-C(....,T-t_0)}{h}$$ $C(...,T-t)$ denotes the BS call price for time To maturity $T-t$. Choose a small value of $h$ say $h=1/100000$ and let the other parameters be those your mentioned in your post then at time 0 and maturity $T=1/4$ your FD problem will return: $$\Theta(T-0)=\Theta(T) \approx \frac{C(....,T+h)-C(....,T)}{h}=-8.963$$ Even for a much bigger value of $h$ namely $h=1/365$ the result is $\Theta(T)=-8.946$

@Sanjay's answer is correct but there is an important consideration from a practical perspective.

Closed form theta in BS is the change per unit time (the change after one year). In other words, mathematically the result of the formula for theta is expressed in value per year. Many professional pricing engines actually display it as 1 day theta (computed as BS_Theta / 365).

More often though, finite difference (FD) theta is actually computed as a true 1 day bump and reprice theta (shifting the evaluation date one day forward and repricing). A complete replication of Bloomberg's OVML and Quantlib can be found in this answer. Using FD theta has at least two advantages:

• BS theta can exceed actual market value of an option if the time to expiry is short (see below for an example)
• Holidays and weekends can easily be included in the computation (Friday will be a 3 day theta, provided Monday is a working day)

In any case, the value from the calculator that Sanjay provided is a 1 year theta, which is easy to show with the following Julia code:

using Distributions, DataFrames

N(x) = cdf(Normal(0,1),x)
n(x) = pdf(Normal(0,1),x)
"""
https://en.wikipedia.org/wiki/Greeks_(finance)#Formulas_for_European_option_Greeks
"""
function BSM(S,K,t,r,d,σ, cp)
d1 = ( log(S/K) + (r - d + 1/2*σ^2)*t ) / (σ*sqrt(t))
d2 = d1 - σ*sqrt(t)
opt  = cp*exp(-d*t)S*N(cp*d1) - cp*exp(-r*t)*K*N(cp*d2)
theta_c = (-(S * exp(-d*t)*n(d1)* σ )/ (2 * sqrt(t)) - r * K * exp(-r*t) * N(d2) + d * S * exp(-d*t)*N(d1))
theta_p = (-(S * exp(-d*t)*n(d1)* σ )/ (2 * sqrt(t)) + r * K * exp(-r*t) * N(-d2) - d * S * exp(-d*t)*N(-d1))
return opt, theta_c, theta_p
end

S, K, r, t, σ = 50, 50, 0.12, 0.25, 0.3
res = BSM(S, K, t, r, 0, σ, 1)
DataFrame(Call = res, Theta = res ) This theta value is in line with the calculator used by Sanjay (this is assuming rates are continuous). However, it is rather useless from a practical perspective. What one would usually do is to look at what happens to the option price with one less day to expiry. You get this value by dividing BS theta by 365. FD theta is the result of repricing the model with one less day to expiry, keeping all else equal and simply looking at the price difference between the two option values.

res2 = BSM(S, K, t - 1/365, r, 0, σ, 1)
day_theta = res/365
fd_theta = res2- res
DataFrame(Symbol("Call") => res, Symbol("Call -1 day") => res2, Symbol("Theta") => res, Symbol("1 Day Theta") => day_theta, Symbol("FD Theta") => fd_theta) We can use the below example, which prices a OTM option with 5 days to expiry and 1 million notional, to show why FD theta is often preferred. BS theta would actually result in a negative option value in this case.

r1 = BSM(45, 50, 5/365, r, 0, σ, 1) .* 1000000
r2 = BSM(45, 50, 4/365, r, 0, σ, 1) .* 1000000
DataFrame(Symbol("Call") => r1, Symbol("Call -1 day") => r2, Symbol("1 Day Theta") => r1/365, Symbol("FD Theta") => r2 - r1) 