|
From: Al C. <aca...@al...> - 2026-02-17 17:02:26
|
Hi Dirk,
This is our code:
def calc_option_implied_vol(self, instrument_model: BaseModel, parameter_model: BaseModel = None,
market_data_model: BaseModel = None):
equity_option_instrument = self.get_equity_option_instrument(instrument_model)
evaluationDate = Utils.extract_input_model("evaluationDate", parameter_model)
optionPrice = Utils.extract_input_model("optionPrice", parameter_model)
spotPrice = Utils.extract_input_model("spotPrice", parameter_model)
dayCounter = Utils.extract_input_model("dayCounter", parameter_model)
calendar = Utils.extract_input_model("calendar", market_data_model)
irCurveTenors = Utils.extract_input_model("irCurveTenors", market_data_model)
irCurveZeroRates = Utils.extract_input_model("irCurveZeroRates", market_data_model)
dividendYield = Utils.extract_input_model("dividendYield", market_data_model)
exerciseType = Utils.extract_input_model("exerciseType", instrument_model)
dummyVolatility = 0.2
volQuote = ql.SimpleQuote(dummyVolatility)
dividendCurve = self._buildDividendCurve(evaluationDate, dividendYield, dayCounter)
irCurve = self._buildInterestCurve(evaluationDate, calendar, dayCounter, irCurveTenors, irCurveZeroRates)
volTS = self._buildVol(evaluationDate, calendar, dayCounter, volQuote)
bsmProcess = ql.BlackScholesMertonProcess(
ql.QuoteHandle(ql.SimpleQuote(spotPrice)),
ql.YieldTermStructureHandle(dividendCurve),
ql.YieldTermStructureHandle(irCurve),
ql.BlackVolTermStructureHandle(volTS))
ql.Settings.instance().evaluationDate = evaluationDate
if exerciseType == "European":
equity_option_instrument.setPricingEngine(ql.AnalyticEuropeanEngine(bsmProcess))
elif exerciseType == "American":
if self.americanEngine == "FdBlackScholesVanillaEngine":
aEngine = ql.FdBlackScholesVanillaEngine(bsmProcess, 100, 100)
elif self.americanEngine == "BinomialVanillaEngine":
aEngine = ql.BinomialVanillaEngine(bsmProcess, "crr", 400)
else:
raise MMException(f"Unsupported americanEngine {self.americanEngine}")
equity_option_instrument.setPricingEngine(aEngine)
else:
raise MMException(f"Unsupported exercise type {exerciseType}")
impliedVol = equity_option_instrument.impliedVolatility(optionPrice, bsmProcess, 1e-6, 1000, 0.001, 4.0)
return impliedVol
My Best
-Al
Cell # 917-603-8000
www.AlphaAnalitica.com
This e-mail is intended only for the person or entity to which it is addressed and may contain information that is privileged, confidential or otherwise protected from disclosure. Dissemination, distribution or copying of this e-mail or the information herein by anyone other than the intended recipient, or an employee or agent responsible for delivering the message to the intended recipient, is prohibited. If you have received this e-mail in error, please notify us immediately (646-205-3213 or in...@Al...) and destroy the original message and all copies.
-----Original Message-----
From: Dirk Eddelbuettel <ed...@de...>
Sent: Monday, February 16, 2026 6:13 PM
To: Dirk Eddelbuettel <ed...@de...>
Cc: Al Cabrini <aca...@al...>; qua...@li...
Subject: RE: [Quantlib-dev] FW: Welcome to the "QuantLib-dev" mailing list
On 16 February 2026 at 16:11, Dirk Eddelbuettel wrote:
|
| On 16 February 2026 at 22:02, Al Cabrini wrote:
| | Thank you Dirk,
| |
| | I added comment below
| |
| | Ticker = BE 03/06/26 C155 Equity
| | OPT_PUT_CALL = Call
| | OPT_STRIKE_PX = 155
| | OPT_EXER_TYP = American
| | OPT_EXERCISE_DT = Mar-20-2026
| | OPT_UNDL_PX = 138.75
| | Option Price MID = 9.475
| | evaluation date = Feb-13-2026
| |
| | Here is the Bloomberg value for implied Vol is 116.124 but my
| | Quantlib calculatin is 141.3
|
| Show as your call to quantlib, please. The issue will likely be that
| you transcribed parameters the wrong way. Sometimes it is
| daysdifference/365 instead of over 252 or vice versa. It all depends.
| And it is good practice to calibrate so I would start with spot =
| strike = 100, t_to_mat = 1 year, vol = 25%, r = 0.04 etc and see if I can start aligning call or put prices.
|
| This library is well known, and had a million eyes on it. It is not
| likely that the code is off. That leaves ... the invocation.
|
| So show us what you did.
FWIW I cannot make heads or tails of that example. I came up with implied vol below either 116 or 141%.
To reset, consider a posted example for a European call option posted here:
https://en.wikipedia.org/wiki/Implied_volatility
This recomputes for me (using RQuantLib)
> EuropeanOptionImpliedVolatility(type="call", value=2, underlying=51.25, strike=50, dividendYield=0.00, riskFreeRate=0.05, maturity=32/365, volatility=0.4)
[1] 0.186925
attr(,"class")
[1] "EuropeanOptionImpliedVolatility" "ImpliedVolatility"
>
matching the stipulated 18.7% on the wikipedia page.
Dirk
--
dirk.eddelbuettel.com | @eddelbuettel | ed...@de...
|