diff --git a/.claude/skills/update-doc-indexes/SKILL.md b/.claude/skills/update-doc-indexes/SKILL.md new file mode 100644 index 00000000..e422079e --- /dev/null +++ b/.claude/skills/update-doc-indexes/SKILL.md @@ -0,0 +1,49 @@ +--- +name: update-doc-indexes +description: Update top level API index pages with missing documented pages and classes +--- + +# Update API index pages + +Update every top level API index page so it references all the relevant +documented pages and classes of its section. + +## Scope + +The top level index pages are `docs/api/
/index.md`, one per section +listed under `API Reference` in the `nav` of `mkdocs.yml` +(currently: data, dists, options, rates, sp, ta, utils). +If arguments name one or more sections, restrict the update to those. + +## Procedure + +For each section: + +1. Read the section entry in the `nav` of `mkdocs.yml` and list its pages. +2. For each page, collect what it documents: the H1 title and the + mkdocstrings entries (`::: fully.qualified.path` lines). +3. Read the section `index.md` and identify pages or classes that are not + mentioned anywhere on it. +4. Add the missing entries to the index page: + * Follow the existing layout of that index page. If it uses tables with + `| Class | Description |` columns, extend or add tables in the same + format. Only introduce a new H2 section when the missing entries do not + fit an existing one, and match the style of the sections already there. + * Ask the developer where to place a new section if the page layout does + not make the placement obvious. + * Link classes and functions with mkdocstrings cross-references + (`[ClassName][fully.qualified.path]`) and pages with relative markdown + links (e.g. `[SVI Volatility Smile](svi.md)`). + * Write a one line description for each entry, based on the docstring or + the page introduction. Link concepts to `docs/glossary.md` instead of + redefining them. +5. Do not remove or rewrite existing content: this skill only adds what is + missing and fixes references that are broken. + +## Conventions + +* Follow the documentation rules in `.github/copilot-instructions.md` + (no dashes as punctuation, short paragraphs, relative links). +* Do not edit generated files (`docs/bibliography.md`, `readme.md`). +* After the update, list for the developer which entries were added to which + index page. diff --git a/Makefile b/Makefile index 7c78bb20..b75360c0 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ help: @echo ================================================================================ .PHONY: app-serve -app-serve: ## serve app +app-serve: ## serve python api app only @MICRO_SERVICE_HOST=127.0.0.1 uv run python -m app .PHONY: docs @@ -25,7 +25,7 @@ docs-examples: ## Regenerate docs examples .PHONY: docs-serve docs-serve: ## serve docs, examples, and API with auto-reload - @bash ./dev/docs-serve + @bash ./dev/serve/all .PHONY: frontend-build frontend-build: ## build Observable frontend examples @@ -34,7 +34,7 @@ frontend-build: ## build Observable frontend examples .PHONY: frontend-serve frontend-serve: ## serve Observable frontend with auto-reload - @bash ./dev/frontend-serve + @bash ./dev/serve/observable .PHONY: install-dev install-dev: ## Install development dependencies diff --git a/app/api/volatility.py b/app/api/volatility.py index c2c94e4b..8394dc4a 100644 --- a/app/api/volatility.py +++ b/app/api/volatility.py @@ -38,7 +38,7 @@ class ForwardCurveResponse(BaseModel): class VolSurfaceResponse(BaseModel): - ssvi: SSVI = Field(description="SSVI model fitted to the volatility surface") + ssvi: SSVI = Field(description="eSSVI model fitted to the volatility surface") inputs: VolSurfaceInputs = Field(description="Volatility surface inputs") options: list[OptionInfo] = Field( description="List of option info with implied volatilities" diff --git a/dev/docs-serve b/dev/docs-serve deleted file mode 100755 index e3fd7572..00000000 --- a/dev/docs-serve +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -set -e - -OBSERVABLE_PORT=${OBSERVABLE_PORT:-3001} -DOCS_PORT=${DOCS_PORT:-8000} -API_PORT=${API_PORT:-8001} -FRONTEND_ORIGIN=${FRONTEND_ORIGIN:-http://127.0.0.1:${OBSERVABLE_PORT}} -QUANTFLOW_API_ORIGIN=${QUANTFLOW_API_ORIGIN:-http://127.0.0.1:${API_PORT}} - -npm --prefix frontend exec concurrently -- \ - --kill-others \ - --names docs,examples,api \ - --prefix "[{name}]" \ - "DOCS_PORT=${DOCS_PORT} bash ./dev/mkdocs-serve" \ - "OBSERVABLE_PORT=${OBSERVABLE_PORT} QUANTFLOW_API_ORIGIN=${QUANTFLOW_API_ORIGIN} bash ./dev/frontend-serve" \ - "API_PORT=${API_PORT} QUANTFLOW_CORS_ORIGINS=${FRONTEND_ORIGIN} bash ./dev/api-serve" diff --git a/dev/frontend-serve b/dev/frontend-serve deleted file mode 100755 index fb70afad..00000000 --- a/dev/frontend-serve +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -set -e - -OBSERVABLE_PORT=${OBSERVABLE_PORT:-3001} - -echo "Examples: http://127.0.0.1:${OBSERVABLE_PORT}" - -npm --prefix frontend run dev -- --host 127.0.0.1 --port ${OBSERVABLE_PORT} diff --git a/dev/mkdocs-serve b/dev/mkdocs-serve deleted file mode 100755 index a6209383..00000000 --- a/dev/mkdocs-serve +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -set -e - -DOCS_PORT=${DOCS_PORT:-8000} - -echo "Documentation: http://127.0.0.1:${DOCS_PORT}" - -uv run mkdocs serve \ - --dev-addr 127.0.0.1:${DOCS_PORT} \ - --livereload \ - --watch quantflow \ - --watch docs diff --git a/dev/serve-info b/dev/serve-info deleted file mode 100644 index 82461c8c..00000000 --- a/dev/serve-info +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -set -e - -OBSERVABLE_PORT=${OBSERVABLE_PORT:-3001} -DOCS_PORT=${DOCS_PORT:-8000} -API_PORT=${API_PORT:-8001} - -echo "Documentation: http://127.0.0.1:${DOCS_PORT}" -echo "Examples: http://127.0.0.1:${OBSERVABLE_PORT}" -echo "API: http://127.0.0.1:${API_PORT}" diff --git a/dev/serve/all b/dev/serve/all new file mode 100755 index 00000000..97c970f1 --- /dev/null +++ b/dev/serve/all @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -e + +QUANTFLOW_OBSERVABLE_PORT=${QUANTFLOW_OBSERVABLE_PORT:-8006} +QUANTFLOW_MKDOCS_PORT=${QUANTFLOW_MKDOCS_PORT:-8000} +QUANTFLOW_API_PORT=${QUANTFLOW_API_PORT:-8001} + +QUANTFLOW_OBSERVABLE_URL=${QUANTFLOW_OBSERVABLE_URL:-http://127.0.0.1:${QUANTFLOW_OBSERVABLE_PORT}} +QUANTFLOW_MKDOCS_ORIGIN=${QUANTFLOW_MKDOCS_ORIGIN:-http://127.0.0.1:${QUANTFLOW_MKDOCS_PORT}} +QUANTFLOW_API_ORIGIN=${QUANTFLOW_API_ORIGIN:-http://127.0.0.1:${QUANTFLOW_API_PORT}} + +npm --prefix frontend exec concurrently -- \ + --kill-others \ + --names mkdocs,observable,api \ + --prefix "[{name}]" \ + "QUANTFLOW_MKDOCS_PORT=${QUANTFLOW_MKDOCS_PORT} QUANTFLOW_OBSERVABLE_URL=${QUANTFLOW_OBSERVABLE_URL} bash ./dev/serve/mkdocs" \ + "QUANTFLOW_OBSERVABLE_PORT=${QUANTFLOW_OBSERVABLE_PORT} QUANTFLOW_API_ORIGIN=${QUANTFLOW_API_ORIGIN} QUANTFLOW_MKDOCS_ORIGIN=${QUANTFLOW_MKDOCS_ORIGIN} bash ./dev/serve/observable" \ + "QUANTFLOW_API_PORT=${QUANTFLOW_API_PORT} QUANTFLOW_CORS_ORIGINS=${QUANTFLOW_OBSERVABLE_URL} bash ./dev/serve/api" diff --git a/dev/api-serve b/dev/serve/api similarity index 57% rename from dev/api-serve rename to dev/serve/api index c14a5586..cf947083 100755 --- a/dev/api-serve +++ b/dev/serve/api @@ -1,15 +1,15 @@ #!/usr/bin/env bash set -e -API_PORT=${API_PORT:-8001} +QUANTFLOW_API_PORT=${QUANTFLOW_API_PORT:-8001} -echo "API: http://127.0.0.1:${API_PORT}" +echo "API: http://127.0.0.1:${QUANTFLOW_API_PORT}" uv run uvicorn \ app.__main__:crate_app \ --factory \ --host 127.0.0.1 \ - --port ${API_PORT} \ + --port ${QUANTFLOW_API_PORT} \ --reload \ --reload-dir app \ --reload-dir quantflow diff --git a/dev/serve/mkdocs b/dev/serve/mkdocs new file mode 100755 index 00000000..f38d1dd6 --- /dev/null +++ b/dev/serve/mkdocs @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e + +QUANTFLOW_MKDOCS_PORT=${QUANTFLOW_MKDOCS_PORT:-8000} + +echo "Documentation: http://127.0.0.1:${QUANTFLOW_MKDOCS_PORT}" + +uv run mkdocs serve \ + --dev-addr 127.0.0.1:${QUANTFLOW_MKDOCS_PORT} \ + --livereload \ + --watch quantflow \ + --watch docs diff --git a/dev/serve/observable b/dev/serve/observable new file mode 100755 index 00000000..eb200235 --- /dev/null +++ b/dev/serve/observable @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e + +QUANTFLOW_OBSERVABLE_PORT=${QUANTFLOW_OBSERVABLE_PORT:-8006} + +echo "Examples: http://127.0.0.1:${QUANTFLOW_OBSERVABLE_PORT}" + +npm --prefix frontend \ + run dev \ + -- \ + --host 127.0.0.1 \ + --port ${QUANTFLOW_OBSERVABLE_PORT} diff --git a/docs/api/dists/index.md b/docs/api/dists/index.md index 04a2df9f..b8efa2c5 100644 --- a/docs/api/dists/index.md +++ b/docs/api/dists/index.md @@ -7,3 +7,21 @@ stochastic process at a fixed time horizon. Every distribution derives from [Distribution][quantflow.dists.Distribution], which exposes a common [sample][quantflow.dists.Distribution.sample] method for drawing random variates. + +The [1D Distributions](distributions1d.md) page documents +[Distribution1D][quantflow.dists.Distribution1D] and its concrete laws +[Normal][quantflow.dists.Normal], [Exponential][quantflow.dists.Exponential] +and [DoubleExponential][quantflow.dists.DoubleExponential], used as jump size +distributions in compound Poisson processes. + +Multivariate laws derive from [MvDistribution][quantflow.dists.MvDistribution], +which exposes its [MeanAndCov][quantflow.dists.MeanAndCov] statistics; +[MvNormal][quantflow.dists.MvNormal] is the multivariate normal implementation, +documented on the [Distributions](distributions.md) page. + +[Marginal1D][quantflow.dists.Marginal1D], on the [Marginal 1D](marginal1d.md) +page, is the abstract 1D distribution with Fourier based option pricing. +The pricing method is selected via +[OptionPricingMethod][quantflow.dists.OptionPricingMethod] and results are +returned as [OptionPricingResult][quantflow.dists.OptionPricingResult] or +[OptionPricingCosResult][quantflow.dists.OptionPricingCosResult]. diff --git a/docs/api/options/black.md b/docs/api/options/black.md index 9da130af..399d3166 100644 --- a/docs/api/options/black.md +++ b/docs/api/options/black.md @@ -6,7 +6,7 @@ Here we define the [log strike](../../glossary.md#log-strike) `k` as k = \log{\frac{K}{F_\tau}} \end{equation} -where $K$ is the strike price and $F_\tau$ is the forward price of the underlying asset at time to maturity $\tau$. +where $K$ is the strike price and $F_\tau$ is the [forward price](../../glossary.md#forwards) of the underlying asset at time to maturity $\tau$. ::: quantflow.options.bs.black_price diff --git a/docs/api/options/divfm.md b/docs/api/options/divfm.md index 96a9b3b9..b2b7ddbe 100644 --- a/docs/api/options/divfm.md +++ b/docs/api/options/divfm.md @@ -1,13 +1,16 @@ # Deep IV Factor Model The DIVFM module implements the Deep Implied Volatility Factor Model from -Gauthier, Godin & Legros (2025). The IV surface on a given day is modelled as +[Gauthier, Godin & Legros (2025)](../../bibliography.md#gauthier). +The IV surface on a given day is modelled as a linear combination of $p$ fixed latent functions learned by a neural network: -$$\sigma_t(M, \tau; \theta) = \mathbf{f}(M, \tau, X; \theta)\,\boldsymbol{\beta}_t = \sum_{i=1}^{p} \beta_{t,i}\,f_i(M, \tau, X; \theta)$$ +\begin{equation} +\sigma_t(M, \tau; \theta) = \mathbf{f}(M, \tau, X; \theta)\,\boldsymbol{\beta}_t = \sum_{i=1}^{p} \beta_{t,i}\,f_i(M, \tau, X; \theta) +\end{equation} -where $M = \frac{1}{\sqrt{\tau}}\log\!\left(\frac{K}{F_{t,\tau}}\right)$ is the -time-scaled moneyness, $\mathbf{f}$ is a feedforward neural network with fixed +where $M$ is the time-scaled [moneyness](../../glossary.md#moneyness), +$\mathbf{f}$ is a feedforward neural network with fixed weights $\theta$ shared across all days, and $\boldsymbol{\beta}_t$ are daily coefficients fitted in closed form via OLS. diff --git a/docs/api/options/index.md b/docs/api/options/index.md index c3e78964..010f139f 100644 --- a/docs/api/options/index.md +++ b/docs/api/options/index.md @@ -21,11 +21,26 @@ which accepts price inputs incrementally and builds the surface through its `sur The lower-level [GenericVolSurfaceLoader][quantflow.options.surface.GenericVolSurfaceLoader] provides the same functionality with a user-defined security type. +## Pricing + +| Class | Description | +|---|---| +| [black_price][quantflow.options.bs.black_price] | Undiscounted Black call/put prices in [forward space](../../glossary.md#forward-space) | +| [BlackSensitivities][quantflow.options.bs.BlackSensitivities] | Black model sensitivities (Greeks) in forward space | +| [implied_black_volatility][quantflow.options.bs.implied_black_volatility] | Implied Black volatility via Newton's method | +| [SVI][quantflow.options.svi.SVI] | SVI parameterisation of a single-maturity volatility smile | +| [SSVI][quantflow.options.ssvi.SSVI] | SSVI parameterisation of the full volatility surface | +| [DIVFMPricer][quantflow.options.divfm.DIVFMPricer] | Deep Implied Volatility Factor Model pricer | +| [OptionPricer][quantflow.options.pricer.OptionPricer] | Option pricing with stochastic process models | +| [VolModelCalibration][quantflow.options.calibration.base.VolModelCalibration] | Base class for calibrating vol models (Heston and BNS variants) to a surface | +| [PutCallParity][quantflow.options.parity.PutCallParity] | [Put-call parity](../../glossary.md#put-call-parity) relationships between calls, puts and forwards | +| [moneyness][quantflow.options.moneyness] | Conversions between strike, log-strike and [moneyness](../../glossary.md#moneyness) | + ## Price Classes | Class | Description | |---|---| -| [Price][quantflow.options.surface.Price] | Base bid/ask price for any security | +| [Price][quantflow.utils.price.Price] | Base bid/ask price for any security | | [SpotPrice][quantflow.options.surface.SpotPrice] | Spot bid/ask price of an underlying asset | | [FwdPrice][quantflow.options.surface.FwdPrice] | Forward bid/ask price at a specific maturity | | [OptionPrice][quantflow.options.surface.OptionPrice] | Single-sided option price with implied volatility and convergence flag | diff --git a/docs/api/options/ssvi.md b/docs/api/options/ssvi.md index bb0ecbaa..3651d1cd 100644 --- a/docs/api/options/ssvi.md +++ b/docs/api/options/ssvi.md @@ -1,5 +1,3 @@ # SSVI Volatility Surface -::: quantflow.options.ssvi.VarianceCurve - ::: quantflow.options.ssvi.SSVI diff --git a/docs/api/rates/index.md b/docs/api/rates/index.md index d23c874d..066d920a 100644 --- a/docs/api/rates/index.md +++ b/docs/api/rates/index.md @@ -12,6 +12,8 @@ The central concept is the [discount factor](../../glossary.md#discount-factor) f(\tau) = -\frac{\partial \ln D_\tau}{\partial \tau} \end{equation} +The trivial [NoDiscountCurve][quantflow.rates.no_discount.NoDiscountCurve] implementation has zero rates, so its discount factor is always one. + **[Interpolated Curves](interpolated.md)** build the term structure directly from observed zero rates at a set of anchor dates. [InterpolatedLinearCurve][quantflow.rates.interpolated.InterpolatedLinearCurve] interpolates the zero rate piecewise linearly, while [InterpolatedMonotonicCubicCurve][quantflow.rates.interpolated.InterpolatedMonotonicCubicCurve] uses a shape-preserving cubic spline. **[CIRCurve](cir.md)** is a short-rate term-structure model derived from the Cox-Ingersoll-Ross process, with positive-rate dynamics and closed-form discount factors. @@ -21,3 +23,5 @@ The central concept is the [discount factor](../../glossary.md#discount-factor) **[VasicekCurve](vasicek.md)** is a Gaussian mean-reverting short-rate model with analytical formulas for discount factors and instantaneous forward rates. **[Calibration](calibration.md)** provides [YieldCurveCalibration][quantflow.rates.calibration.YieldCurveCalibration], the base class for fitting a yield curve to discount factors, and [OptionsDiscountingCalibration][quantflow.rates.calibration.OptionsDiscountingCalibration], which bootstraps asset and quote curves from put-call parity observations. + +Each curve model provides its own calibration wrapper: [InterpolatedYieldCurveCalibration][quantflow.rates.interpolated.InterpolatedYieldCurveCalibration], [CIRCurveCalibration][quantflow.rates.cir.CIRCurveCalibration], [NelsonSiegelCalibration][quantflow.rates.nelson_siegel.NelsonSiegelCalibration] and [VasicekCurveCalibration][quantflow.rates.vasicek.VasicekCurveCalibration]. diff --git a/docs/api/sp/index.md b/docs/api/sp/index.md index a4e5223c..f1096b07 100644 --- a/docs/api/sp/index.md +++ b/docs/api/sp/index.md @@ -23,6 +23,7 @@ This page gives an overview of all stochastic processes available in the library | Process | Description | |---|---| +| [PoissonBase][quantflow.sp.poisson.PoissonBase] | Abstract base for Poisson-style jump processes | | [PoissonProcess][quantflow.sp.poisson.PoissonProcess] | Homogeneous Poisson process | | [CompoundPoissonProcess][quantflow.sp.poisson.CompoundPoissonProcess] | Poisson process with random jump sizes | | [DSP][quantflow.sp.dsp.DSP] | Doubly stochastic (Cox) Poisson process | diff --git a/docs/api/ta/index.md b/docs/api/ta/index.md index b168fb6c..21bc3571 100644 --- a/docs/api/ta/index.md +++ b/docs/api/ta/index.md @@ -1,3 +1,7 @@ # Timeseries Analysis -- [Kalman Filter & UKF](kalman.md) — linear-Gaussian and unscented filtering +- [EWMA](ewma.md): exponentially weighted moving average filter for time series +- [Kalman Filter & UKF](kalman.md): linear-Gaussian and unscented filtering +- [OHLC](ohlc.md): OHLC bar aggregation with range-based variance estimators +- [Paths](paths.md): paths produced by stochastic process simulations +- [Supersmoother](supersmoother.md): two-pole Butterworth filter with adaptive smoothing diff --git a/docs/api/utils/index.md b/docs/api/utils/index.md index 339685a0..14cc2324 100644 --- a/docs/api/utils/index.md +++ b/docs/api/utils/index.md @@ -10,4 +10,5 @@ users who want to extend the library or understand its inner workings. |---|---| | [Bins](bins.md) | Histogram and event-density utilities | | [Numbers](numbers.md) | Decimal number helpers | +| [Price](price.md) | Bid/ask price and price/volume containers | | [Types](types.md) | Shared type aliases (FloatArray, etc.) | diff --git a/docs/bibliography.md b/docs/bibliography.md index 462a0f4d..234d0d8d 100644 --- a/docs/bibliography.md +++ b/docs/bibliography.md @@ -110,6 +110,22 @@ Jim Gatheral. (2004) [A parsimonious arbitrage-free implied volatility parameter
+#### gauthier + +Geneviève Gauthier, Frédéric Godin, Sebastien Legros. (2025) [Deep Implied Volatility Factor Models for Stock Options](https://dx.doi.org/10.2139/ssrn.5283770){target="_blank" rel="noopener"} + +
+ +
+ +#### hendriks_martini + +Sebas Hendriks, Claude Martini. (2019) [The extended SSVI volatility surface](https://dx.doi.org/10.2139/ssrn.2971502){target="_blank" rel="noopener"}, Journal of Computational Finance, 22(5):25-39 + +
+ +
+ #### heston-calibration Milan Mrázek, Jan Pospíšil. (2017) [Calibration and simulation of Heston model](https://doi.org/10.1515/math-2017-0058){target="_blank" rel="noopener"}, Open Mathematics, 15(1):679-704 @@ -174,6 +190,14 @@ G. K. G. Saez. (2014) [Fourier Transform Methods for Option Pricing: An Applicat
+#### ssvi_calibration + +Pierre Cohort, Jacopo Corbetta, Claude Martini, Ismail Laachir. (2019) [Robust calibration and arbitrage-free interpolation of SSVI slices](https://doi.org/10.48550/arXiv.1804.04924){target="_blank" rel="noopener"}, Decisions in Economics and Finance, 42(2) + +
+ +
+ #### ukf Merwe. (2014) [The Unscented Kalman Filter for Nonlinear Estimation](https://groups.seas.harvard.edu/courses/cs281/papers/unscented.pdf){target="_blank" rel="noopener"}, internet diff --git a/docs/glossary.md b/docs/glossary.md index 443584bb..6155f76f 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -169,15 +169,27 @@ Moneyness is used in the context of option pricing in order to compare options w where $K$ is the strike, $F$ is the Forward price, and $\tau$ is the time to maturity. It is used to compare options with different maturities by scaling the [log-strike](#log-strike) by the square root of time to maturity. This is because the price of the underlying asset is subject to random fluctuations, if these fluctuations follow a Brownian motion than the standard deviation of the price movement will increase with the square root of time. +## Moneyness Convexity Adjusted + +The convexity-adjusted moneyness, often called standardized moneyness in the literature, extends the [vol-adjusted moneyness](#moneyness-vol-adjusted) with the convexity correction of the lognormal distribution. It is defined as + +\begin{equation} + m_c = \frac{1}{\sigma\sqrt{\tau}}\ln\frac{K}{F} + \frac{\sigma\sqrt{\tau}}{2} = m_\sigma + \frac{\sigma\sqrt{\tau}}{2} = -d_2 +\end{equation} + +where $K$ is the strike, $F$ is the Forward price, $\tau$ is the time to maturity, $\sigma$ is the implied Black volatility and $d_2$ is the standard argument of the [Black formula](api/options/black.md#quantflow.options.bs.black_price). + +Unlike the [vol-adjusted moneyness](#moneyness-vol-adjusted), which is centered at the forward, this measure is zero at the median of the risk-neutral distribution, $K = F e^{-\sigma^2\tau/2}$. + ## Moneyness Vol Adjusted The vol-adjusted moneyness is used in the context of option pricing in order to compare options with different maturities and different levels of volatility. It is defined as \begin{equation} - m_\sigma = \frac{1}{\sigma\sqrt{\tau}}\ln\frac{K}{F} + m_\sigma = \frac{1}{\sigma\sqrt{\tau}}\ln\frac{K}{F} = \frac{m}{\sigma} \end{equation} -where $K$ is the strike, $F$ is the Forward price, $\tau$ is the time to maturity and $\sigma$ is the implied Black volatility. +where $K$ is the strike, $F$ is the Forward price, $\tau$ is the time to maturity, $\sigma$ is the implied Black volatility and $m$ is the [moneyness](#moneyness). ## Parseval's Theorem @@ -244,6 +256,22 @@ identity $h^2 I$ and the observation matrix is a column vector $c$. The innovation covariance $S = h^2 I + P\,c c^\top$ is then a rank-1 update to a scaled identity, avoiding a full $O(n_y^3)$ solve. +## Standard Normal Distribution + +The normal distribution with zero mean and unit variance. +Throughout the documentation, $N$ denotes its +[CDF](#cumulative-distribution-function-cdf) and $n$ its +[PDF](#probability-density-function-pdf): + +\begin{equation} +\begin{aligned} + n(x) &= \frac{1}{\sqrt{2\pi}} e^{-\frac{x^2}{2}} \\ + N(x) &= \int_{-\infty}^x n(s)\ ds +\end{aligned} +\end{equation} + +This notation is used by the [Black Pricing](api/options/black.md) formulas. + ## State-Space Model A mathematical framework describing the joint evolution of an unobserved diff --git a/docs/references.bib b/docs/references.bib index 1afe76f1..f3d2fb5f 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -120,6 +120,25 @@ @misc{gatheral_svi url={https://faculty.baruch.cuny.edu/jgatheral/madrid2004.pdf}, } +@misc{gauthier, + title={Deep Implied Volatility Factor Models for Stock Options}, + author={Gauthier, Geneviève and Godin, Frédéric and Legros, Sebastien}, + howpublished={SSRN working paper}, + year={2025}, + url={https://dx.doi.org/10.2139/ssrn.5283770}, +} + +@article{hendriks_martini, + title={The extended SSVI volatility surface}, + author={Sebas Hendriks and Claude Martini}, + journal={Journal of Computational Finance}, + year={2019}, + volume={22}, + number={5}, + pages={25--39}, + url={https://dx.doi.org/10.2139/ssrn.2971502}, +} + @article{heston-calibration, title={Calibration and simulation of Heston model}, author={Milan Mrázek and Jan Pospíšil}, @@ -193,6 +212,16 @@ @mastersthesis{saez url={https://www.uv.es/bfc/TFM2014/008-014.pdf}, } +@article{ssvi_calibration, + title={Robust calibration and arbitrage-free interpolation of SSVI slices}, + author={Pierre Cohort and Jacopo Corbetta and Claude Martini and Ismail Laachir}, + journal={Decisions in Economics and Finance}, + year={2019}, + volume={42}, + number={2}, + url={https://doi.org/10.48550/arXiv.1804.04924}, +} + @article{ukf, title={The Unscented Kalman Filter for Nonlinear Estimation}, author={Merwe}, diff --git a/frontend/observablehq.config.js b/frontend/observablehq.config.js index 7be60b04..e3ec3fe1 100644 --- a/frontend/observablehq.config.js +++ b/frontend/observablehq.config.js @@ -4,6 +4,7 @@ import {fileURLToPath} from "node:url"; const __dirname = dirname(fileURLToPath(import.meta.url)); const apiOrigin = process.env.QUANTFLOW_API_ORIGIN || ""; +const mkdocsOrigin = process.env.QUANTFLOW_MKDOCS_ORIGIN || "https://quantflow.quantmind.com"; const headSnippet = readFileSync(resolve(__dirname, "../docs/assets/logos/head-snippet.html"), "utf-8") .trim() .replace(/href="\//g, 'href="https://quantflow.quantmind.com/'); @@ -14,6 +15,7 @@ export default { output: "../app/examples", base: "/examples", head: ` + ${headSnippet}`, @@ -21,8 +23,8 @@ ${headSnippet}`, pages: [{name: "Volatility Surface", path: "/volatility-surface"}, {name: "Yield Curve", path: "/yield-curve"}, {name: "Sampling", path: "/sampling"}, {name: "SuperSmoother", path: "/supersmoother"}, {name: "Cointegration", path: "/cointegration"}, {name: "Hurst Exponent", path: "/hurst"}, {name: "Heston Vol Surface", path: "/heston-vol-surface"}], header: `