Skip to content
All library documents

Updating QuantLib Inputs to Reprice an American Dividend Option

Article Quant Q&A · Author: fan

Summary

The document explains why changing a QuantLib option’s spot input or evaluation date may appear not to change its net present value. The example prices an American call with scheduled dividends, then attempts to alter the quote and reprice the existing instrument. The issue is that the code assigns to a method rather than calling it, and the quote handle itself is not the object whose value should be updated.

The answer shows that a quote handle points to an underlying quote object, whose value can be changed so dependent pricing objects observe the update. It demonstrates a changed option value after changing the underlying spot quote. This is a narrow implementation example rather than a general guide to repricing: the discussion does not explore all QuantLib object lifetimes, evaluation-date dependencies, or instrument and engine configurations.

Key ideas

  • A QuantLib quote handle refers to an underlying quote object whose value can be updated.
  • Call the quote’s value-setting method instead of assigning a value to the method.
  • Changing the underlying quote allows linked pricing objects to recalculate the option value.
  • The example concerns one American dividend option setup and does not cover every repricing dependency.

Tags

Full text
# Why Quantlib Option NPV does not change when repricing?


# Why Quantlib Option NPV does not change when repricing?












Trying to learn Quantlib with Python, please have a look at below code:

```
# option data
# AAPL US
maturity_date = ql.Date(26, 1, 2019)
spot_price = 180
strike_price = 180
volatility = 0.2198 # the historical vols or implied vols
option_type = ql.Option.Call
risk_free_rate = 0.025
day_count = ql.Actual365Fixed()
calendar = ql.UnitedStates()
calculation_date = ql.Date(1, 8, 2018)
ql.Settings.instance().evaluationDate = calculation_date
dividenddates = [ql.Date(10,8,2018), ql.Date(8, 11, 2018)]
dividends = [0.73,0.73]
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))
bs_process = ql.BlackScholesProcess(spot_handle,flat_ts, flat_vol_ts)
payoff = ql.PlainVanillaPayoff(option_type, strike_price)
settlement = calculation_date
am_exercise = ql.AmericanExercise(settlement, maturity_date)
american_option = ql.DividendVanillaOption(payoff, am_exercise, dividenddates, dividends)
engine = ql.FDDividendAmericanEngine(bs_process)
# engine = ql.FDDividendAmericanEngine(bs_process, timeSteps=500, gridPoints=500)
american_option.setPricingEngine(engine)

print(american_option.NPV())
```

I got 11.273456 as option value. However, when I try to change the spot price, or calculation_date and reprice the option, the NPV doesn't seem to change.

I tried:

```
spot_handle.setValue = 179
print(american_option.NPV())
```

or

```
ql.Settings.instance().evaluationDate = calculation_date + 1
print(american_option.NPV())
```

NPV still gives same value, unless I re-run through the first section code to re-create instrument with new inputs. I thought Quantlib is designed to allow us use the existing instrument to reprice with simply changing one or more inputs, anything I miss here?

Thanks for your help.

## Answer by byouness (score 3)

https://quant.stackexchange.com/a/43640

Hello fan and welcome to SE! You were very close, there are two small issues with your code:

#### setValue()

This is a method and not an attribute which value you can updated, so you have to call `object.setValue(new_value)` instead of `object.setValue = new_value`

#### Handles and quotes

The handle is roughly a smart pointer on a pointer, it points on a quote that can change.

As a result, it's not the handle's value that you need to change (and by the way, it doesn't have a `setValue()` method, you can see it if you call `spot_handle.setValue(179)`).

What you can change instead is the value of the underlying quote, in this way:

```
(...)
spot = ql.SimpleQuote(spot_price)
spot_handle = ql.QuoteHandle(spot)
(...)
print(american_option.NPV())
# Returns 11.273456139007127

spot.setValue(179.)
print(american_option.NPV())
# Returns 10.747540028959339
```

For more on handles:

- https://stackoverflow.com/a/42907325/2699660

- https://www.implementingquantlib.com/2013/07/odds-and-ends-smart-pointers-and-handles.html

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.