Files
strategy-lab/to_explore/pyquantnews/106_ThetaDecay.ipynb
David Brazda e3da60c647 daily update
2024-10-21 20:57:56 +02:00

6.9 KiB

No description has been provided for this image

This code calculates and visualizes the theta of a European call option over time until expiration. It sets up the necessary financial instruments using QuantLib, including the option, interest rate curve, dividend yield curve, and volatility surface. The theta is calculated for each day leading up to expiration and stored in a list. Finally, the theta values are plotted against the days to expiration, providing insight into the option's time decay.

In [ ]:
import QuantLib as ql
import matplotlib.pyplot as plt

Define option parameters

In [ ]:
expiry_date = ql.Date(15, 6, 2023)
strike_price = 100
spot_price = 105
volatility = 0.2
risk_free_rate = 0.01
dividend_yield = 0.02

Set up the QuantLib calendar and day count convention

In [ ]:
calendar = ql.UnitedStates(ql.UnitedStates.NYSE)
day_count = ql.Actual365Fixed()

Create the QuantLib objects for the option

In [ ]:
exercise = ql.EuropeanExercise(expiry_date)
payoff = ql.PlainVanillaPayoff(ql.Option.Call, strike_price)
option = ql.VanillaOption(payoff, exercise)

Create the interest rate curve

In [ ]:
risk_free_rate_handle = ql.YieldTermStructureHandle(
    ql.FlatForward(0, calendar, ql.QuoteHandle(ql.SimpleQuote(risk_free_rate)), day_count)
)

Create the dividend yield curve

In [ ]:
dividend_yield_handle = ql.YieldTermStructureHandle(
    ql.FlatForward(0, calendar, ql.QuoteHandle(ql.SimpleQuote(dividend_yield)), day_count)
)

Create the volatility surface

In [ ]:
volatility_handle = ql.BlackVolTermStructureHandle(
    ql.BlackConstantVol(0, calendar, ql.QuoteHandle(ql.SimpleQuote(volatility)), day_count)
)

Create the Black-Scholes process

In [ ]:
spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_price))
bs_process = ql.BlackScholesMertonProcess(
    spot_handle, 
    dividend_yield_handle, 
    risk_free_rate_handle, 
    volatility_handle
)

Define the range of days to expiration

In [ ]:
days_to_expiry = range(365, 15, -1)
In [ ]:
theta_values = []

Calculate theta for each day

In [ ]:
for days in days_to_expiry:
    expiry_date = calendar.advance(ql.Date().todaysDate(), ql.Period(int(days), ql.Days))
    exercise = ql.EuropeanExercise(expiry_date)
    option = ql.VanillaOption(payoff, exercise)
    
    # Set up the pricing engine
    engine = ql.AnalyticEuropeanEngine(bs_process)
    option.setPricingEngine(engine)
    
    # Calculate theta
    theta = option.theta() / 365
    theta_values.append(theta)

Plot the theta values

In [ ]:
plt.figure(figsize=(10, 6))
plt.plot(days_to_expiry, theta_values, label='Theta')
plt.xlabel('Days to Expiration')
plt.ylabel('Theta')
plt.title('Option Theta over Time to Expiration')
plt.gca().invert_xaxis()
ticks = range(365, 15, -50)
plt.xticks(ticks)
plt.show()

PyQuant News is where finance practitioners level up with Python for quant finance, algorithmic trading, and market data analysis. Looking to get started? Check out the fastest growing, top-selling course to get started with Python for quant finance. For educational purposes. Not investment advise. Use at your own risk.