You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: TECHNICAL_README.md
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -73,11 +73,15 @@ ModelParams(
73
73
pricing_engine="black76"|"bs", # default forward-based Black-76. Use Black-Scholes only when puts data are unavailable
74
74
price_method="last"|"mid", # defaults to 'mid'; mid-price calculated as `(bid + ask) / 2`
75
75
max_staleness_days=3, # filter options older than N calendar days from valuation_date. Defaults to 3 to accomodate weekends. Set to None to disable filtering
76
+
surface_method="svi", # "svi" (default) or "bspline"
77
+
surface_options= {"max_iter": 400}, # optional dict of method-specific kwargs
76
78
)
77
79
```
78
80
79
81
Note that mid prices are preferred over last, due to lower noise from stale quotes. However, Yahoo Finance often doesn't have bid/ask data, so the from_ticker() method for yfinance uses last prices by default.
80
82
83
+
`surface_method` selects between the arbitrage-aware SVI fitter and the legacy cubic B-spline smoother. Supply `surface_options` as a plain dictionary (for example via `oipd.core.svi.svi_options(max_iter=800, tol=1e-9)`) to override calibration defaults. If calibration fails (e.g., too few strikes or a hard butterfly violation) the code raises `CalculationError("Failed to smooth implied volatility data: ...")`. In those cases either clean the input quotes or retry with the legacy cubic spline via `ModelParams(surface_method="bspline")`.
84
+
81
85
### 2.4 RND estimator
82
86
83
87
Main class that fits risk-neutral density models from options data and provides probability distribution results.
@@ -152,7 +156,7 @@ The process of generating the PDFs and CDFs is as follows:
152
156
2. Apply put–call parity preprocessing: estimate the forward from near‑ATM call–put pairs
153
157
3. Based on the forward price, restrict to OTM options. Keep calls above the forward and replace in‑the‑money calls with synthetic calls constructed from OTM puts via parity, to reduce noise from illiquid ITM quotes[^2].
154
158
4. Using the chosen pricing model (Black‑76 as it works with forward prices[^3]) we convert strike prices into implied volatilities (IV)[^4]. IV are solved using either Newton's Method or Brent's root‑finding algorithm, as specified by the `solver_method` argument
155
-
5.Using B‑spline, we fit a curve‑of‑best‑fit onto the resulting IVs over the full range of strike prices[^5]. Thus, we have extracted a continuous model from discrete IV observations — this is called the volatility smile
159
+
5.Fit the implied-volatility smile using the configured surface model. By default we calibrate a raw SVI slice. During optimisation we constrain the raw parameters (`b ≥ 0`, `|ρ| ≤ ρ_bound < 1`, `σ ≥ σ_min`) and enforce the Gatheral–Jacquier minimum-variance condition `a + b σ √(1 − ρ²) ≥ 0`. After calibration we evaluate the butterfly diagnostic `g(k)` on an extended log-moneyness grid; if `min_g < 0` a `CalculationError`is raised. Users can opt into the historical cubic B-spline smoother with `surface_method="bspline"`.
156
160
6. From the volatility smile, we use the same pricing model to convert IVs back to prices. Thus, we arrive at a continuous curve of options prices along the full range of strike prices
157
161
7. From the continuous price curve, we use numerical differentiation to get the first derivative of prices. Then we numerically differentiate again to get the second derivative of prices. The second derivative of prices multiplied by a discount factor $\exp^{r*\uptau}$, results in the probability density function [^6]
158
162
8. Once we have the PDF, we can calculate the CDF
@@ -161,7 +165,7 @@ The process of generating the PDFs and CDFs is as follows:
161
165
[^2]: Parity-based OTM‑only preprocessing follows Aït‑Sahalia and Lo, ["Nonparametric Estimation of State‑Price Densities Implicit in Financial Asset Prices"](https://www.princeton.edu/~yacine/aslo.pdf)
162
166
[^3]: Derivation of Black-76 is explained well by [this article](https://benjaminwhiteside.com/2021/01/15/black-76/)
163
167
[^4]: We convert from price-space to IV-space, and then back to price-space in step 6. See this [blog post](https://reasonabledeviations.com/2020/10/10/option-implied-pdfs-2/) for a breakdown of why we do this double conversion
164
-
[^5]: See [this paper](https://edoc.hu-berlin.de/bitstream/handle/18452/14708/zeng.pdf?sequence=1&isAllowed=y) for more details. In summary, options markets contains noise. Therefore, generating a volatility smile through simple interpolation will result in a noisy smile function. Then converting back to price-space will result in a noisy price curve. And finally when we numerically twice differentiate the price curve, noise will be amplified and the resulting PDF will be meaningless. Thus, we need either a parametric or non-parametric model to try to extract the true relationship between IV and strike price from the noisy observations. The paper suggests a 3rd order B-spline as a possible model choice
168
+
[^5]: Options markets contain noise. Simple interpolation would yield erratic smiles, which in turn produce unstable price curves and PDFs. We therefore fit a model to the smile: by default the raw SVI parametrisation of Gatheral & Jacquier (see ["Arbitrage-Free SVI Volatility Surfaces"](https://arxiv.org/abs/1204.0646)), with a legacy cubic B-spline fallback available for diagnostics. The original B-spline motivation is discussed in [Zeng (2014)](https://edoc.hu-berlin.de/bitstream/handle/18452/14708/zeng.pdf?sequence=1&isAllowed=y)
165
169
[^6]: For a proof of this derivation, see this [blog post](https://reasonabledeviations.com/2020/10/10/option-implied-pdfs-2/)
0 commit comments