In quantitative finance, understanding how an option’s value changes over time is critical for risk management and trading. This is where Theta, the Greek that measures time decay, plays a central role. In this article, you’ll learn how to calculate Theta for options in C++ with a simple yet powerful approach to estimate how much an option’s price erodes as it approaches expiration. Whether you’re building a pricing engine or just deepening your understanding of the Greeks, this guide will walk you through a practical C++ implementation step-by-step.
1. What is Theta?
Theta is one of the most important Greeks in options trading. It measures the rate at which an option loses value as time passes, assuming all other factors remain constant. This phenomenon is known as time decay.
Mathematically, Theta is defined as the partial derivative of the option price V with respect to time t:
[math]\large \Theta = \frac{\partial V}{\partial t}[/math]
In most practical cases, Theta is negative for long option positions meaning the value of the option decreases as time progresses. This reflects the diminishing probability that the option will end up in-the-money as expiration nears.
Imagine you hold a European call option on a stock priced at $100, with a strike at $100 and 30 days to expiry. If the option is worth $4.00 today, and $3.95 tomorrow (with no change in volatility or the stock price), then Theta is approximately:
[math]\large \Theta \approx \frac{3.95 – 4.00}{1} = -0.05[/math]
This means the option loses 5 cents per day due to the passage of time alone.
Key Characteristics of Theta:
- Short-term options have higher Theta (faster decay).
- At-the-money options typically experience the highest Theta.
- Theta increases as expiration approaches, especially in the final weeks.
- Call and put options both exhibit Theta decay, but not symmetrically.
2. The Black-Scholes Formula
Under the Black-Scholes model, we can calculate Theta analytically for both European call and put options. These closed-form expressions are widely used for pricing, calibration, and risk reporting.
Black-Scholes Theta Formulas
European Call Option Theta:
[math]\large \Theta_{\text{call}} = -\frac{S \cdot \sigma \cdot N'(d_1)}{2\sqrt{T}} – rK e^{-rT} N(d_2)[/math]
European Put Option Theta:
[math]\large \Theta_{\text{put}} = -\frac{S \cdot \sigma \cdot N'(d_1)}{2\sqrt{T}} + rK e^{-rT} N(-d_2)[/math]
Where:
- [math]S[/math] = spot price of the underlying
- [math]K[/math] = strike price
- [math]T[/math] = time to maturity (in years)
- [math]r[/math] = risk-free interest rate
- [math]\sigma[/math] = volatility
- [math]N(d)[/math] = cumulative normal distribution
- [math]N'(d)[/math] = standard normal density (i.e., PDF)
- [math]d_1 = \frac{\ln(S/K) + (r + \sigma^2/2)T}{\sigma \sqrt{T}}[/math]
3. An Implementation in C++
Here’s a minimal, self-contained example that calculates Theta using QuantLib:
#include <ql/quantlib.hpp>
#include <iostream>
using namespace QuantLib;
int main() {
// Set evaluation date
Calendar calendar = TARGET();
Date today(19, July, 2025);
Settings::instance().evaluationDate() = today;
// Option parameters
Option::Type optionType = Option::Call;
Real underlying = 100.0;
Real strike = 100.0;
Rate riskFreeRate = 0.01; // 1%
Volatility volatility = 0.20; // 20%
Date maturity = calendar.advance(today, 90, Days); // 3 months
DayCounter dayCounter = Actual365Fixed();
// Construct option
ext::shared_ptr<Exercise> europeanExercise(new EuropeanExercise(maturity));
ext::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(optionType, strike));
VanillaOption europeanOption(payoff, europeanExercise);
// Market data (handle wrappers)
Handle<Quote> spot(ext::shared_ptr<Quote>(new SimpleQuote(underlying)));
Handle<YieldTermStructure> flatRate(ext::shared_ptr<YieldTermStructure>(
new FlatForward(today, riskFreeRate, dayCounter)));
Handle<BlackVolTermStructure> flatVol(ext::shared_ptr<BlackVolTermStructure>(
new BlackConstantVol(today, calendar, volatility, dayCounter)));
// Black-Scholes-Merton process
ext::shared_ptr<BlackScholesMertonProcess> bsmProcess(
new BlackScholesMertonProcess(spot, flatRate, flatRate, flatVol));
// Set pricing engine
europeanOption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new AnalyticEuropeanEngine(bsmProcess)));
// Output results
std::cout << "Option price: " << europeanOption.NPV() << std::endl;
std::cout << "Theta (per year): " << europeanOption.theta() << std::endl;
std::cout << "Theta (per day): " << europeanOption.theta() / 365.0 << std::endl;
return 0;
}
This example prices a European call option using QuantLib’s AnalyticEuropeanEngine
, which leverages the Black-Scholes formula to compute both the option’s price and its Greeks, including Theta. The method theta()
returns the annualized Theta value, representing the rate of time decay per year; dividing it by 365 gives the daily Theta, which is more intuitive for short-term trading and hedging. You can easily experiment with other scenarios by changing the option type to Option::Put
or adjusting the maturity date to observe how Theta behaves under different conditions.
4. Compile and Run
You will need to install Quantlib first, on a mac:
brew install quantlib
and then prepare your CMakeList.txt:
cmake_minimum_required(VERSION 3.10)
project(theta)
set(CMAKE_CXX_STANDARD 17)
find_package(PkgConfig REQUIRED)
pkg_check_modules(QUANTLIB REQUIRED QuantLib)
include_directories(${QUANTLIB_INCLUDE_DIRS})
link_directories(${QUANTLIB_LIBRARY_DIRS})
add_executable(theta ../theta.cpp)
target_link_libraries(theta ${QUANTLIB_LIBRARIES})
Where theta.cpp contains the code from the former section.
Then:
mkdir build
cd build
cmake..
make
Once compiled, you can run the executable:
➜ build git:(main) ✗ ./theta
Option price: 4.65065
Theta (per year): -6.73569
Which gives you the value of theta.
You can clone the project here on Github to calculate Theta for options in C++: