Estimating Rates and Volatility from CME American Gold Options
Summary
The document describes an attempt to infer a risk-free rate and volatility from traded American gold options expiring in November 2020. It uses a snapshot of call and put prices across strikes, a futures price, and a chosen settlement date as inputs to a QuantLib pricing setup. The proposed method prices each option with a binomial engine and adjusts the rate and volatility parameters to minimize squared differences between model and observed prices.
The author reports an estimated rate and volatility, then questions whether the rate is plausible. The example is useful for understanding joint calibration from option prices, but it does not resolve whether the setup is financially consistent. In particular, the implementation assigns the same parameter to both the risk-free and dividend yield inputs, while using a futures price as the underlying in a Black-Scholes-Merton process; American exercise and futures-style option conventions may require a different model. The document supplies no independent calibration, market-data validation, or assessment of parameter identifiability.
Key ideas
- The example fits a rate and volatility to call and put prices across several strikes.
- It minimizes the sum of squared differences between observed and model option values.
- The model uses American exercise and a binomial pricing engine.
- The author questions the plausibility of the fitted rate, and the setup has modeling choices that need validation.
Tags
Full text
# Option implied data from CME
# Option implied data from CME
I am trying to extract the `risk free rate and volatility` from the traded American options with expiry Nov-2020 from CME. https://www.cmegroup.com/trading/metals/precious/gold_quotes_globex_options.html#optionProductId=192&strikeRange=ATM
I took prior settlement price and date as the calculation date. A snapshot of data that I used is as follows -
I used `Python-quantlib` library to do all calculations -
```
import QuantLib as ql
import pandas as pd
import scipy
calculationday = ql.Date(18, 8, 2020)
ql.Settings.instance().evaluationDate = calculationday
calendar = ql.UnitedStates()
future = 2013.1
optiondata = pd.concat([
pd.DataFrame({'optiontype' : ['P']*10,
'strike' : [1950.0, 1955.0, 1960.0, 1965.0, 1970.0, 1975.0, 1980.0, 1985.0, 1990.0, 1995.0],
'expiry' : [ql.Date(27, 10, 2020)]*10,
'price' : [45.70, 47.70, 49.70, 51.90, 54.10, 56.40, 58.70, 61.10, 63.60, 66.10]
}),
pd.DataFrame({'optiontype' : ['C']*10,
'strike' : [1950.0, 1955.0, 1960.0, 1965.0, 1970.0, 1975.0, 1980.0, 1985.0, 1990.0, 1995.0],
'expiry' : [ql.Date(27, 10, 2020)]*10,
'price' : [108.80, 105.80, 102.80, 100.00, 97.20, 94.50, 91.80, 89.20, 86.70, 84.20]
})
], ignore_index = True, sort = False)
def loss(parameters, data = optiondata):
riskfree = parameters[0]/100
div = parameters[0]/100
vol = parameters[1]/100
optionprice = np.zeros(data.shape[0])
for i in np.arange(data.shape[0]):
optionparam = ql.VanillaOption(ql.PlainVanillaPayoff(1 if data['optiontype'][i] == 'C' else -1, data['strike'][i]),
ql.AmericanExercise(calculationday, data['expiry'][i]))
priceprocess = ql.BlackScholesMertonProcess(ql.QuoteHandle(ql.SimpleQuote(future)),
ql.YieldTermStructureHandle(ql.FlatForward(calculationday, div, ql.Actual360())),
ql.YieldTermStructureHandle(ql.FlatForward(calculationday, riskfree, ql.Actual360())),
ql.BlackVolTermStructureHandle(ql.BlackConstantVol(calculationday, calendar, vol, ql.Actual360())))
binomial_engine = ql.BinomialVanillaEngine(priceprocess, "crr", 1300)
optionparam.setPricingEngine(binomial_engine)
optionprice[i] = optionparam.NPV()
return np.sum(np.square(data['price'] - optionprice))
minimize(loss, [0, 10], method = 'trust-constr', constraints = NonlinearConstraint(lambda x: np.array( [ x[0], x[1] ] ), 0., np.inf))
```
With above implementation, I got `risk free rate` as 1.03418556% (continuously compounding) and `volatility` as 21.10113888%
However I have doubt if above calculation is really right because the implied risk-free rate is still looking quite large.
Could you please point if above calculation makes sense?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.