The Variance Day Model

[ quant ]

In a previous post, we’ve established that

Colloquially, one could say that:

Variance Schedule

Before we begin, I want to emphasize that problems in finance don’t always have a unique and objectively best solution. There aren’t theories of everything that can predict events with a 100% accuracy like in physics and mathematics. So there is plenty of room for creativity within this template.

In this simple model, we assign:

We start by creating a pandas DataFrame containing all the dates of the calendar year.

import pandas as pd

# Generate date range
date_range = pd.date_range(start='2023-01-01', end='2023-12-31')

# Create a DataFrame with the date range
df = pd.DataFrame({'Date': date_range})

We can then assign the variance weights to each day in 2023 like so:

# US holidays in 2023
holidays = [
    date(2023, 1, 2),  # New Year's Day observed
    date(2023, 1, 16),  # Martin Luther King Jr. Day
    date(2023, 2, 20),  # Washington's Birthday
    date(2023, 4, 7),  # Good Friday
    date(2023, 5, 29),  # Memorial Day
    date(2023, 6, 19),  # Juneteenth National Independence Day
    date(2023, 7, 3),  # Independence Day observed
    date(2023, 7, 4),  # Independence Day
    date(2023, 9, 4),  # Labor Day
    date(2023, 11, 23),  # Thanksgiving Day
    date(2023, 11, 24),  # Day after Thanksgiving
    date(2023, 12, 25),  # Christmas Day
]

# Assign weights based on whether the date corresponds to a weekday or weekend
df['Weight'] = df['Date'].apply(lambda x: 1 if x.weekday() < 5 else 0.25)

# Update the 'Weight' column to include holidays
df.loc[df['Date'].isin(holidays), 'Weight'] = 0.25

After determining the assigned weights, the next step involves calculating the duration of a year (how much time is a year?). This calculation is essential as it provides the necessary input, the time to expiration in years, for any standard option pricing model. We will call this the tenor. In a calendar day model, the tenor is 365. In our case, the number should hang around 280.

# Calculate the time between every calendar date and December 31st. 
df['DTE'] = df['Weight'][::-1].cumsum()[::-1]

# Time between Jan1st and Dec31st is the tenor
tenor = df['DTE'].iloc[0] # ~= 280

Try and see what you get for the year 2024. Anyway, save this dataframe as a csv file because you will need it everytime you want to price an option.

Finally, to determine the time to expiration in years, you only have to find the difference in the ‘DTE’ value between the expiration date and the current date. You can open the csv file and manually calculate that difference or, if you have thousands of options to price, you do it programmatically:

def calculate_time_until_expiration(variance_weights_df, current_date, event_date, tenor):
    # Normalize dates 
    event_date = pd.to_datetime(event_date).normalize()
    current_date = pd.to_datetime(current_date).normalize()

    days_to_event = variance_weights_df[
        variance_weights_df['Date'] == event_date
    ]['DTE'].iloc[0]

    days_to_current = variance_weights_df[
        variance_weights_df['Date'] == current_date
    ]['DTE'].iloc[0]

    
    # Ensure that the current date's DTE is greater than 
    # the event date's DTE
    return (days_to_current - days_to_event + 0.5) / tenor

As we know, time doesn’t pass uniformly across the calendar. Since the regular trading hours start at 9:30am ET and end at 4:00pm ET, the time you plug into your model could be VERY sensitive to the time left before the close. In our simple model, I chose to add an increment of 0.5 to make sure that the time that the function returns isn’t 0. Roughly, that 0.5 equates to half a trading day left.

Finally, we obtain the elusive variance time by normalizing that time with the tenor. I leave it to the reader as an exercise to write a vectorized function capable of taking in an entire options chain instead of one option at a time.

Conclusion

So now that we got a more accurate representation of time, the next step is to think about how we can use it to our advantage. In a following post, we will explore how one can use variance time to calibrate the volatilities as implied by the prices of the options.