2

I am trying to add a holiday to my calendar in QuantLib such that my option pricing model considers this in pricing where I would expect that the time to expiry should decrease with the inclusion of a holiday, and my option reduce in price. However, when I use the .addHoliday method it successfully adds the holiday to the Calendar, but the option price doesn't change. It seems as if the option time to expiry is used from the DayCounter object and doesn't use the Calendar. Would my interpretation here be correct and if so, how would I add a holiday such that it affects my option pricing? My expectation is that the option price decreases by the same amount as if I reduced the expiry date by a day. Example below

import QuantLib as ql

def get_option_price(add_holiday): calculation_date = ql.Date(18, 1, 2023) ql.Settings.instance().evaluationDate = calculation_date

expiry = ql.Date(30, 1, 2023)
spot_price = 100.
strike_price = 105.
volatility = 0.50
dividend_rate = 0
option_type = ql.Option.Call

risk_free_rate = 0.001
day_count = ql.Actual365Fixed()
calendar = ql.UnitedStates(0)

if add_holiday:
    calendar.addHoliday(ql.Date(24, 1, 2023))
print(add_holiday, ql.Calendar.holidayList(calendar, calculation_date, expiry))

payoff = ql.PlainVanillaPayoff(option_type, strike_price)
exercise = ql.EuropeanExercise(expiry)
european_option = ql.VanillaOption(payoff, exercise)

spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_price))
flat_ts = ql.YieldTermStructureHandle(ql.FlatForward(calculation_date, risk_free_rate, day_count))
dividend_yield = ql.YieldTermStructureHandle(ql.FlatForward(calculation_date, dividend_rate, day_count))
flat_vol_ts = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(calculation_date, calendar, volatility, day_count))
bsm_process = ql.BlackScholesMertonProcess(spot_handle, dividend_yield, flat_ts, flat_vol_ts)

european_option.setPricingEngine(ql.AnalyticEuropeanEngine(bsm_process))
print(european_option.NPV(), european_option.delta())

get_option_price(False) get_option_price(True)

False ()
1.7305073013860064 0.3111915181849204
True (Date(24,1,2023),)
1.7305073013860064 0.3111915181849204
  • Most tools use expiry as a fraction of 365 or 365.25 days and a holiday has no impact on that (unless the expiry date itself would be a holiday and you shift to the next or prior business day). After all, the actual days to expiry are still the same, if there are holidays in between or not. You also specify actual/365 which means it counts every day und uses 365 days for computing the year fraction – AKdemy Jan 20 '23 at 10:53
  • I'm a little surprised of the implementation of a calendar and then not using it to calculate time to expiry. After all, time to expiry should be in trading time. For example, if it were Monday morning and I had an expiry on Friday evening, and Christmas Day was Wednesday, I would only want to use the equivalent of 4 days till expiry. Otherwise QuantLib is forcing me to change my expiry date or my volatility to get a realistic option price. Using this example, in QuantLib, is there any way for me to have a holiday reduce the time to expiry of an option keeping all the other properties as is? – pinkusfloyd Jan 20 '23 at 12:27
  • 1
    That's not how it works, but it's an interesting concept. In some markets (notbaly, Brazil), the interest on some debts only accrues during working days - doesn't accrue during holidays. But in most of the world, interest accrues daily. Can you please articulate why you want your option to be priced this way? – Dimitri Vulis Jan 20 '23 at 12:48
  • 1
    @Dimitri Vulis' comment about Brazil is important. Howver, your term sheet (or the exchange) will determine the specifications. For example, if you have ACT/365FIXED, you will count all days (if holiday or weekend), and FIXED means you also do not care about a leap year. In order to get a realistic option price, you need to follow the convention. I doubt the convention will be to only count working days. This answer shows how a realistic option price is computed given details about expiry and delivery date etc. – AKdemy Jan 20 '23 at 13:19
  • Sorry but I believe this is how professional options traders price their options because it allows them to compare volatilities equally. For a theoretical example, let's say the whole year is made up of holidays except the last minute of the year which is expiration. No one would buy an option with 365 days of volatility because it only has 1 minute to realize that volatility. The price would have to be significantly lower to reflect this, and if the time to expiry isn't changed then the volatility must be lower. This means the option cannot be compared like for like with other options. – pinkusfloyd Jan 20 '23 at 13:24
  • In a more practical example, you can refer to the hkex exchange website for their volatility prices. https://www.hkex.com.hk/Products/Listed-Derivatives/Equity-Index/Hang-Seng-Index-(HSI)/Hang-Seng-Index-Options?sc_lang=en#&product=HSI . You can see that the January term, which has many holidays coming up, is significantly lower volatility than the February, March etc. terms. That is because they haven't priced the time to expiry correctly, and have compensated with lower volatility. – pinkusfloyd Jan 20 '23 at 13:25
  • Please note that the example of interest is irrelevant as that is dictated by the exchange and clearing houses. Implied volatility is dictated by model. – pinkusfloyd Jan 20 '23 at 13:28
  • @AKdemy right, so for many Brazil instruments, the daycount is "Brazil business days / 252". I can't think of any other market that does this. Anyway, sorry, it's very tangentially relevant to this question. – Dimitri Vulis Jan 20 '23 at 13:39
  • 1
    @pinkusfloyd "I believe this is how professional options traders price their options" I'm not even going to comment on whether this believe is correct, but if it were the case, it wouldn't imply that "professional options traders" are right. Appeals to authority don't work in quantitative finance :) I do urge you to read this article https://doi.org/10.1002/wilm.10871 by Espeg Haug. – Dimitri Vulis Jan 20 '23 at 13:45
  • When it comes to implied volatility, no one is right. However, if this is how I want to view my options then I have the right to view them this way, and I have articulated my reasoning for doing so. My only question is: does QuantLib support this functionality in some way? – pinkusfloyd Jan 20 '23 at 13:48
  • I agree, a flexible library ought to let you perform calculations that you want, even if they don't make sense (because one can trade on weekends and holidays) - at least to reproduce what one believes to be one's counterparties' pricing logic, even if doesn't make sense. – Dimitri Vulis Jan 20 '23 at 13:54

1 Answers1

3

Replace

    day_count = ql.Actual365Fixed()
    calendar = ql.UnitedStates(0)

with

    calendar = ql.UnitedStates(0)
    day_count = ql.Business252(calendar)

to get the behavior you expect. If you want only the volatility to be affected, use business/252 for the vol curve and act/365F for the rate curves.

Luigi Ballabio
  • 7,123
  • 22
  • 37
  • This is perfect, thank you! – pinkusfloyd Jan 22 '23 at 01:03
  • A follow up question: it seems like doing it this way slows down the options calculation significantly (around 4x slower). Not sure if it's relevant but I also have the enable intraday/high resolution date enabled. Is this expected? @luigi-ballabio – pinkusfloyd Feb 15 '23 at 05:19
  • That's expected. The other day count conventions are simple calculations, e.g., (expiry date - valuation date)/365; the business/252 convention needs to look at each day between the two dates to see if it's a business day or a holiday. – Luigi Ballabio Feb 15 '23 at 09:07