quantflow 0.6.0__tar.gz → 0.6.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. {quantflow-0.6.0 → quantflow-0.6.2}/.github/copilot-instructions.md +5 -1
  2. {quantflow-0.6.0 → quantflow-0.6.2}/.gitignore +1 -0
  3. {quantflow-0.6.0 → quantflow-0.6.2}/.vscode/launch.json +1 -1
  4. {quantflow-0.6.0 → quantflow-0.6.2}/Makefile +5 -0
  5. {quantflow-0.6.0 → quantflow-0.6.2}/PKG-INFO +3 -3
  6. quantflow-0.6.2/app/volatility_surface.py +106 -0
  7. quantflow-0.6.2/dev/build-examples +28 -0
  8. {quantflow-0.6.0 → quantflow-0.6.2}/dev/quantflow.dockerfile +2 -0
  9. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/data/deribit.md +1 -0
  10. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/data/index.md +1 -1
  11. quantflow-0.6.2/docs/api/options/black.md +25 -0
  12. quantflow-0.6.2/docs/api/options/index.md +52 -0
  13. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/options/pricer.md +2 -0
  14. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/options/vol_surface.md +22 -0
  15. quantflow-0.6.2/docs/api/sp/dsp.md +3 -0
  16. quantflow-0.6.2/docs/api/utils/index.md +3 -0
  17. quantflow-0.6.2/docs/api/utils/numbers.md +4 -0
  18. quantflow-0.6.2/docs/api/utils/types.md +6 -0
  19. quantflow-0.6.2/docs/bibliography.md +43 -0
  20. quantflow-0.6.2/docs/examples/heston_volatility_pricer.py +25 -0
  21. quantflow-0.6.2/docs/examples/weiner_volatility_pricer.py +19 -0
  22. {quantflow-0.6.0/notebooks → quantflow-0.6.2/docs}/theory/characteristic.md +8 -25
  23. quantflow-0.6.2/docs/theory/index.md +51 -0
  24. {quantflow-0.6.0/notebooks → quantflow-0.6.2/docs}/theory/inversion.md +20 -45
  25. {quantflow-0.6.0/notebooks → quantflow-0.6.2/docs}/theory/levy.md +18 -38
  26. {quantflow-0.6.0/notebooks → quantflow-0.6.2/docs}/theory/option_pricing.md +19 -42
  27. quantflow-0.6.2/docs/tutorials/option_pricing.md +36 -0
  28. {quantflow-0.6.0 → quantflow-0.6.2}/mkdocs.yml +22 -6
  29. {quantflow-0.6.0 → quantflow-0.6.2}/pyproject.toml +3 -3
  30. quantflow-0.6.2/quantflow/__init__.py +5 -0
  31. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/data/deribit.py +48 -10
  32. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/options/bs.py +95 -38
  33. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/options/calibration.py +9 -8
  34. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/options/inputs.py +11 -0
  35. quantflow-0.6.2/quantflow/options/pricer.py +335 -0
  36. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/options/surface.py +538 -175
  37. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/base.py +3 -2
  38. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/dsp.py +0 -2
  39. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/heston.py +49 -28
  40. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/poisson.py +21 -14
  41. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/bins.py +29 -15
  42. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/distributions.py +27 -25
  43. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/marginal.py +47 -22
  44. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/types.py +10 -3
  45. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_options.py +2 -2
  46. quantflow-0.6.2/quantflow_tests/test_options_pricer.py +53 -0
  47. {quantflow-0.6.0 → quantflow-0.6.2}/uv.lock +1021 -860
  48. quantflow-0.6.0/docs/api/options/black.md +0 -23
  49. quantflow-0.6.0/docs/api/options/index.md +0 -5
  50. quantflow-0.6.0/docs/api/utils/index.md +0 -1
  51. quantflow-0.6.0/docs/bibliography.md +0 -13
  52. quantflow-0.6.0/notebooks/theory/overview.md +0 -17
  53. quantflow-0.6.0/quantflow/__init__.py +0 -3
  54. quantflow-0.6.0/quantflow/options/pricer.py +0 -196
  55. quantflow-0.6.0/quantflow_tests/test_options_pricer.py +0 -22
  56. {quantflow-0.6.0 → quantflow-0.6.2}/.coveragerc +0 -0
  57. {quantflow-0.6.0 → quantflow-0.6.2}/.dockerignore +0 -0
  58. {quantflow-0.6.0 → quantflow-0.6.2}/.github/workflows/build.yml +0 -0
  59. {quantflow-0.6.0 → quantflow-0.6.2}/.github/workflows/deploy.yml +0 -0
  60. {quantflow-0.6.0 → quantflow-0.6.2}/.github/workflows/docker-multiarch.yml +0 -0
  61. {quantflow-0.6.0 → quantflow-0.6.2}/.vscode/settings.json +0 -0
  62. {quantflow-0.6.0 → quantflow-0.6.2}/.vscode/tasks.json +0 -0
  63. {quantflow-0.6.0 → quantflow-0.6.2}/CITATION.cff +0 -0
  64. {quantflow-0.6.0 → quantflow-0.6.2}/CLAUDE.md +0 -0
  65. {quantflow-0.6.0 → quantflow-0.6.2}/LICENSE +0 -0
  66. {quantflow-0.6.0 → quantflow-0.6.2}/app/__main__.py +0 -0
  67. {quantflow-0.6.0 → quantflow-0.6.2}/app/cointegration.py +0 -0
  68. {quantflow-0.6.0 → quantflow-0.6.2}/app/double_exponential_sampling.py +0 -0
  69. {quantflow-0.6.0 → quantflow-0.6.2}/app/gaussian_sampling.py +0 -0
  70. {quantflow-0.6.0 → quantflow-0.6.2}/app/hurst.py +0 -0
  71. {quantflow-0.6.0 → quantflow-0.6.2}/app/poisson_sampling.py +0 -0
  72. {quantflow-0.6.0 → quantflow-0.6.2}/app/supersmoother.py +0 -0
  73. {quantflow-0.6.0 → quantflow-0.6.2}/app/utils/__init__.py +0 -0
  74. {quantflow-0.6.0 → quantflow-0.6.2}/dev/blocks/quantflow.yaml +0 -0
  75. {quantflow-0.6.0 → quantflow-0.6.2}/dev/charts.yaml +0 -0
  76. {quantflow-0.6.0 → quantflow-0.6.2}/dev/helm/.helmignore +0 -0
  77. {quantflow-0.6.0 → quantflow-0.6.2}/dev/helm/Chart.yaml +0 -0
  78. {quantflow-0.6.0 → quantflow-0.6.2}/dev/helm/templates/_helpers.tpl +0 -0
  79. {quantflow-0.6.0 → quantflow-0.6.2}/dev/helm/templates/_service.tpl +0 -0
  80. {quantflow-0.6.0 → quantflow-0.6.2}/dev/helm/templates/app.yaml +0 -0
  81. {quantflow-0.6.0 → quantflow-0.6.2}/dev/helm/templates/configmap.yaml +0 -0
  82. {quantflow-0.6.0 → quantflow-0.6.2}/dev/helm/templates/secret.yaml +0 -0
  83. {quantflow-0.6.0 → quantflow-0.6.2}/dev/helm/values.yaml +0 -0
  84. {quantflow-0.6.0 → quantflow-0.6.2}/dev/install +0 -0
  85. {quantflow-0.6.0 → quantflow-0.6.2}/dev/lint +0 -0
  86. {quantflow-0.6.0 → quantflow-0.6.2}/dev/marimo +0 -0
  87. {quantflow-0.6.0 → quantflow-0.6.2}/dev/test +0 -0
  88. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/data/fed.md +0 -0
  89. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/data/fmp.md +0 -0
  90. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/data/fred.md +0 -0
  91. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/index.md +0 -0
  92. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/options/calibration.md +0 -0
  93. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/sp/cir.md +0 -0
  94. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/sp/compound_poisson.md +0 -0
  95. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/sp/heston.md +0 -0
  96. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/sp/index.md +0 -0
  97. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/sp/jump_diffusion.md +0 -0
  98. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/sp/ou.md +0 -0
  99. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/sp/poisson.md +0 -0
  100. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/sp/weiner.md +0 -0
  101. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/ta/ewma.md +0 -0
  102. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/ta/index.md +0 -0
  103. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/ta/kalman.md +0 -0
  104. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/ta/ohlc.md +0 -0
  105. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/ta/paths.md +0 -0
  106. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/ta/supersmoother.md +0 -0
  107. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/utils/bins.md +0 -0
  108. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/utils/distributions.md +0 -0
  109. {quantflow-0.6.0 → quantflow-0.6.2}/docs/api/utils/marginal1d.md +0 -0
  110. {quantflow-0.6.0 → quantflow-0.6.2}/docs/assets/heston.gif +0 -0
  111. {quantflow-0.6.0 → quantflow-0.6.2}/docs/assets/linkedin-banner.png +0 -0
  112. {quantflow-0.6.0 → quantflow-0.6.2}/docs/assets/quantflow-light.svg +0 -0
  113. {quantflow-0.6.0 → quantflow-0.6.2}/docs/assets/quantflow-logo.png +0 -0
  114. {quantflow-0.6.0 → quantflow-0.6.2}/docs/assets/quantflow-repo.png +0 -0
  115. {quantflow-0.6.0 → quantflow-0.6.2}/docs/assets/quantflow-repo.svg +0 -0
  116. {quantflow-0.6.0 → quantflow-0.6.2}/docs/assets/quantflow.svg +0 -0
  117. {quantflow-0.6.0 → quantflow-0.6.2}/docs/contributing.md +0 -0
  118. {quantflow-0.6.0 → quantflow-0.6.2}/docs/index.md +0 -0
  119. {quantflow-0.6.0 → quantflow-0.6.2}/docs/javascripts/mathjax.js +0 -0
  120. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/CNAME +0 -0
  121. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/_config.yml +0 -0
  122. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/_toc.yml +0 -0
  123. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/applications/calibration.md +0 -0
  124. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/applications/calibration.py +0 -0
  125. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/applications/hurst.md +0 -0
  126. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/applications/overview.md +0 -0
  127. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/applications/sampling.md +0 -0
  128. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/applications/volatility_surface.md +0 -0
  129. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/conf.py +0 -0
  130. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/data/fed.md +0 -0
  131. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/data/fiscal_data.md +0 -0
  132. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/data/fmp.md +0 -0
  133. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/data/timeseries.md +0 -0
  134. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/examples/heston_vol_surface.md +0 -0
  135. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/index.md +0 -0
  136. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/bns.md +0 -0
  137. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/cir.md +0 -0
  138. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/gousv.md +0 -0
  139. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/heston.md +0 -0
  140. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/heston_jumps.md +0 -0
  141. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/jump_diffusion.md +0 -0
  142. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/ou.md +0 -0
  143. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/overview.md +0 -0
  144. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/poisson.md +0 -0
  145. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/models/weiner.md +0 -0
  146. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/reference/biblio.md +0 -0
  147. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/reference/contributing.md +0 -0
  148. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/reference/glossary.md +0 -0
  149. {quantflow-0.6.0 → quantflow-0.6.2}/notebooks/reference/references.bib +0 -0
  150. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/__init__.py +0 -0
  151. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/server.py +0 -0
  152. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/tools/__init__.py +0 -0
  153. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/tools/base.py +0 -0
  154. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/tools/charts.py +0 -0
  155. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/tools/crypto.py +0 -0
  156. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/tools/fred.py +0 -0
  157. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/tools/stocks.py +0 -0
  158. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ai/tools/vault.py +0 -0
  159. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/data/__init__.py +0 -0
  160. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/data/fed.py +0 -0
  161. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/data/fiscal_data.py +0 -0
  162. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/data/fmp.py +0 -0
  163. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/data/fred.py +0 -0
  164. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/data/vault.py +0 -0
  165. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/options/__init__.py +0 -0
  166. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/py.typed +0 -0
  167. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/__init__.py +0 -0
  168. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/bns.py +0 -0
  169. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/cir.py +0 -0
  170. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/copula.py +0 -0
  171. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/jump_diffusion.py +0 -0
  172. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/ou.py +0 -0
  173. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/sp/weiner.py +0 -0
  174. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ta/__init__.py +0 -0
  175. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ta/base.py +0 -0
  176. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ta/ewma.py +0 -0
  177. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ta/kalman.py +0 -0
  178. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ta/ohlc.py +0 -0
  179. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ta/paths.py +0 -0
  180. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/ta/supersmoother.py +0 -0
  181. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/__init__.py +0 -0
  182. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/dates.py +0 -0
  183. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/functions.py +0 -0
  184. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/interest_rates.py +0 -0
  185. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/numbers.py +0 -0
  186. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/plot.py +0 -0
  187. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow/utils/transforms.py +0 -0
  188. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/conftest.py +0 -0
  189. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_ai.py +0 -0
  190. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_cir.py +0 -0
  191. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_copula.py +0 -0
  192. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_data.py +0 -0
  193. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_distributions.py +0 -0
  194. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_frft.py +0 -0
  195. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_heston.py +0 -0
  196. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_jump_diffusion.py +0 -0
  197. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_ohlc.py +0 -0
  198. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_ou.py +0 -0
  199. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_poisson.py +0 -0
  200. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_utils.py +0 -0
  201. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_vault.py +0 -0
  202. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/test_weiner.py +0 -0
  203. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/utils.py +0 -0
  204. {quantflow-0.6.0 → quantflow-0.6.2}/quantflow_tests/volsurface.json +0 -0
  205. {quantflow-0.6.0 → quantflow-0.6.2}/readme.md +0 -0
  206. {quantflow-0.6.0 → quantflow-0.6.2}/rops.toml +0 -0
  207. {quantflow-0.6.0 → quantflow-0.6.2}/taplo.toml +0 -0
  208. {quantflow-0.6.0 → quantflow-0.6.2}/test_comparison.py +0 -0
@@ -12,6 +12,8 @@ applyTo: '/**'
12
12
 
13
13
  * Always run `make lint` after code changes — runs taplo, isort, black, ruff, and mypy
14
14
  * Never edit `readme.md` directly — it is generated from `docs/index.md` via `make docs`
15
+ * To run all tests use `make test` — runs all tests in the `tests/` directory using pytest
16
+ * To run a specific test file, use `uv run pytest tests/path/to/test_file.py`
15
17
 
16
18
  ## Docker
17
19
 
@@ -24,4 +26,6 @@ applyTo: '/**'
24
26
 
25
27
  * The documentation for quantflow is available at `https://quantflow.quantmid.com`
26
28
  * Documentation is built using [mkdocs](https://www.mkdocs.org/) and stored in the `docs/` directory. The documentation source files are written in markdown format.
27
-
29
+ * Do not use em dashes (—) in documentation files or docstrings. Use colons, parentheses, or restructure the sentence instead.
30
+ * Math in documentation and docstrings uses `$...$` for inline and `$$...$$` or `\begin{equation}...\end{equation}` for block equations. Do not use `.. math::` or `:math:` (RST syntax).
31
+ * To rebuild doc examples run `uv run ./dev/build-examples` — runs all scripts in `docs/examples/` and writes their output to `docs/examples_output/`
@@ -37,3 +37,4 @@ _build
37
37
 
38
38
  # builds
39
39
  app/docs
40
+ docs/examples_output
@@ -14,7 +14,7 @@
14
14
  "args": [
15
15
  "-x",
16
16
  "-vvv",
17
- "quantflow_tests/test_options.py",
17
+ "quantflow_tests/test_options_pricer.py",
18
18
  ]
19
19
  },
20
20
  ]
@@ -27,6 +27,7 @@ marimo: ## Run marimo for editing notebooks
27
27
  .PHONY: docs
28
28
  docs: ## build documentation
29
29
  @cp docs/index.md readme.md
30
+ @uv run ./dev/build-examples
30
31
  @uv run mkdocs build
31
32
 
32
33
  .PHONY: docs-serve
@@ -46,3 +47,7 @@ tests: ## Unit tests
46
47
  .PHONY: outdated
47
48
  outdated: ## Show outdated packages
48
49
  uv tree --outdated
50
+
51
+ .PHONY: upgrade
52
+ upgrade: ## Upgrade dependencies
53
+ uv lock --upgrade
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quantflow
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: quantitative analysis
5
5
  Project-URL: Homepage, https://github.com/quantmind/quantflow
6
6
  Project-URL: Repository, https://github.com/quantmind/quantflow
@@ -9,7 +9,7 @@ Author-email: Luca Sbardella <luca@quantmind.com>
9
9
  License-Expression: BSD-3-Clause
10
10
  License-File: LICENSE
11
11
  Requires-Python: <3.15,>=3.11
12
- Requires-Dist: ccy>=1.7.1
12
+ Requires-Dist: ccy>=2.0.0
13
13
  Requires-Dist: polars[pandas,pyarrow]>=1.11.0
14
14
  Requires-Dist: pydantic>=2.0.2
15
15
  Requires-Dist: python-dotenv>=1.0.1
@@ -17,7 +17,7 @@ Requires-Dist: scipy>=1.14.1
17
17
  Requires-Dist: statsmodels<0.15.0,>=0.14.6
18
18
  Provides-Extra: ai
19
19
  Requires-Dist: asciichartpy>=1.5.25; extra == 'ai'
20
- Requires-Dist: ccy[holidays]>=1.7.1; extra == 'ai'
20
+ Requires-Dist: ccy[holidays]>=2.0.0; extra == 'ai'
21
21
  Requires-Dist: google-genai>=1.61.0; extra == 'ai'
22
22
  Requires-Dist: mcp>=1.26.0; extra == 'ai'
23
23
  Requires-Dist: openai>=2.16.0; extra == 'ai'
@@ -0,0 +1,106 @@
1
+ import marimo
2
+
3
+ __generated_with = "0.20.4"
4
+ app = marimo.App(width="medium")
5
+
6
+
7
+ @app.cell
8
+ def _():
9
+ import marimo as mo
10
+ from app.utils import nav_menu
11
+ nav_menu()
12
+ return (mo,)
13
+
14
+
15
+ @app.cell(hide_code=True)
16
+ def _(mo):
17
+ mo.md(r"""
18
+ # Volatility Surface
19
+
20
+ In this notebook we illustrate the use of the Volatility Surface tool in the library. We use [deribit](https://docs.deribit.com/) options on ETHUSD as example.
21
+
22
+ The library provide a [VolSurfaceLoader](api/options/vol_surface/#quantflow.options.surface.VolSurfaceLoader) for Deribit:
23
+
24
+ ```python
25
+ import pandas as pd
26
+ from quantflow.data.deribit import Deribit
27
+
28
+ async with Deribit() as cli:
29
+ loader = await cli.volatility_surface_loader("eth", exclude_open_interest=0)
30
+
31
+ # build the volatility surface
32
+ surface = loader.surface()
33
+ # calculate black implied volatilities
34
+ surface.bs()
35
+ # disable outliers
36
+ surface.disable_outliers()
37
+ # display inputs - only options with converged implied volatility
38
+ surface_inputs = surface.inputs(converged=True)
39
+ pd.DataFrame([i.model_dump() for i in surface_inputs.inputs])
40
+ ```
41
+ """)
42
+ return
43
+
44
+
45
+ @app.cell
46
+ def _(mo):
47
+ inverse = mo.ui.checkbox(value=True, label="Inverse options")
48
+ inverse
49
+ return (inverse,)
50
+
51
+
52
+ @app.cell
53
+ async def _(inverse):
54
+ import pandas as pd
55
+ from quantflow.data.deribit import Deribit
56
+
57
+ async with Deribit() as cli:
58
+ loader = await cli.volatility_surface_loader("eth", exclude_open_interest=0, inverse=inverse.value)
59
+
60
+ # build the volatility surface
61
+ surface = loader.surface()
62
+ # calculate black implied volatilities
63
+ surface.bs()
64
+ # disable outliers
65
+ surface.disable_outliers()
66
+ # display inputs - only options with converged implied volatility
67
+ surface_inputs = surface.inputs(converged=True)
68
+ pd.DataFrame([i.model_dump() for i in surface_inputs.inputs])
69
+ return (surface,)
70
+
71
+
72
+ @app.cell(hide_code=True)
73
+ def _(mo):
74
+ mo.md(r"""
75
+ ##Volatility Surface
76
+ """)
77
+ return
78
+
79
+
80
+ @app.cell
81
+ def _(surface):
82
+ surface.plot3d()
83
+ return
84
+
85
+
86
+ @app.cell(hide_code=True)
87
+ def _(mo):
88
+ mo.md(r"""
89
+ ## Term Structure
90
+ """)
91
+ return
92
+
93
+
94
+ @app.cell
95
+ def _(surface):
96
+ surface.term_structure()
97
+ return
98
+
99
+
100
+ @app.cell
101
+ def _():
102
+ return
103
+
104
+
105
+ if __name__ == "__main__":
106
+ app.run()
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env python
2
+ """Run all example scripts in docs/examples/ and capture their stdout to .out files."""
3
+ import subprocess
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ out_dir = Path("docs/examples_output")
8
+ out_dir.mkdir(exist_ok=True)
9
+
10
+ examples = sorted(Path("docs/examples").glob("*.py"))
11
+ failed = []
12
+
13
+ for script in examples:
14
+ out_file = out_dir / script.with_suffix(".out").name
15
+ print(f"running {script} -> {out_file}")
16
+ result = subprocess.run(
17
+ [sys.executable, str(script)],
18
+ capture_output=True,
19
+ text=True,
20
+ )
21
+ if result.returncode != 0:
22
+ print(f"FAILED: {script}\n{result.stderr}", file=sys.stderr)
23
+ failed.append(script)
24
+ else:
25
+ out_file.write_text(result.stdout)
26
+
27
+ if failed:
28
+ sys.exit(1)
@@ -14,6 +14,8 @@ RUN uv sync --frozen --no-install-project --extra ai --extra book --extra docs -
14
14
  COPY mkdocs.yml ./
15
15
  COPY docs/ ./docs/
16
16
  COPY quantflow/ ./quantflow/
17
+ COPY dev/build-examples ./dev/build-examples
18
+ RUN uv run ./dev/build-examples
17
19
  RUN uv run mkdocs build
18
20
 
19
21
  # Stage 2: Runtime stage
@@ -9,3 +9,4 @@ from quantflow.data.deribit import Deribit
9
9
  ```
10
10
 
11
11
  ::: quantflow.data.deribit.Deribit
12
+
@@ -1,7 +1,7 @@
1
1
  # Data fetching
2
2
 
3
3
 
4
- The :mod:`quantflow.data` module provides classes and functions for fetching data from various sources.
4
+ The `quantflow.data` module provides classes and functions for fetching data from various sources.
5
5
  To use the module the package must be installed with the optional `data` extra.
6
6
  ```
7
7
  pip install quantflow[data]
@@ -0,0 +1,25 @@
1
+ # Black Pricing
2
+
3
+ Here we define the log strike `k` as
4
+ $$
5
+ k = \log{\frac{K}{F}}
6
+ $$
7
+
8
+ where $K$ is the strike price and $F$ is the forward price of the underlying asset.
9
+ We also refers to this log-strike as `moneyness`, since it is zero for at-the-money (ATM) options,
10
+ negative for in-the-money (ITM) call options, and positive for out-of-the-money (OTM) call options.
11
+
12
+
13
+ ::: quantflow.options.bs.black_price
14
+
15
+ ::: quantflow.options.bs.black_call
16
+
17
+ ::: quantflow.options.bs.black_vega
18
+
19
+ ::: quantflow.options.bs.BlackSensitivities
20
+
21
+ ::: quantflow.options.bs.implied_black_volatility
22
+
23
+ ::: quantflow.options.bs.ImpliedVols
24
+
25
+ ::: quantflow.options.bs.ImpliedVol
@@ -0,0 +1,52 @@
1
+ # Options
2
+
3
+ The `options` module provides classes and functions for pricing and calibrating options.
4
+
5
+ ## Volatility Surface
6
+
7
+ The central class is [VolSurface][quantflow.options.surface.VolSurface], which represents
8
+ the implied volatility surface for an asset across all strikes and maturities. It holds:
9
+
10
+ - a [SpotPrice][quantflow.options.surface.SpotPrice] for the underlying asset
11
+ - a sorted tuple of [VolCrossSection][quantflow.options.surface.VolCrossSection] objects, one per maturity
12
+
13
+ Each [VolCrossSection][quantflow.options.surface.VolCrossSection] contains the forward price
14
+ at that maturity and a tuple of [Strike][quantflow.options.surface.Strike] objects.
15
+ Each [Strike][quantflow.options.surface.Strike] holds a call and/or put as an
16
+ [OptionPrices][quantflow.options.surface.OptionPrices], which in turn pairs a bid and ask
17
+ [OptionPrice][quantflow.options.surface.OptionPrice].
18
+
19
+ A surface is typically constructed via [VolSurfaceLoader][quantflow.options.surface.VolSurfaceLoader],
20
+ which accepts price inputs incrementally and builds the surface through its `surface()` method.
21
+ The lower-level [GenericVolSurfaceLoader][quantflow.options.surface.GenericVolSurfaceLoader]
22
+ provides the same functionality with a user-defined security type.
23
+
24
+ ## Price Classes
25
+
26
+ | Class | Description |
27
+ |---|---|
28
+ | [Price][quantflow.options.surface.Price] | Base bid/ask price for any security |
29
+ | [SpotPrice][quantflow.options.surface.SpotPrice] | Spot bid/ask price of an underlying asset |
30
+ | [FwdPrice][quantflow.options.surface.FwdPrice] | Forward bid/ask price at a specific maturity |
31
+ | [OptionPrice][quantflow.options.surface.OptionPrice] | Single-sided option price with implied volatility and convergence flag |
32
+ | [OptionPrices][quantflow.options.surface.OptionPrices] | Paired bid and ask [OptionPrice][quantflow.options.surface.OptionPrice] for a given strike and option type |
33
+
34
+ ## Input Classes
35
+
36
+ The input classes are plain data containers used to serialize and deserialize volatility surface data,
37
+ for example when storing or transmitting a snapshot of the surface.
38
+
39
+ | Class | Description |
40
+ |---|---|
41
+ | [VolSurfaceInputs][quantflow.options.inputs.VolSurfaceInputs] | Top-level container: asset name, reference date, and a list of inputs |
42
+ | [VolSurfaceInput][quantflow.options.inputs.VolSurfaceInput] | Base input with bid, ask, open interest and volume |
43
+ | [SpotInput][quantflow.options.inputs.SpotInput] | Input for a spot price |
44
+ | [ForwardInput][quantflow.options.inputs.ForwardInput] | Input for a forward price with maturity |
45
+ | [OptionInput][quantflow.options.inputs.OptionInput] | Input for an option with strike, maturity, type, and optional implied vols |
46
+
47
+ A [VolSurface][quantflow.options.surface.VolSurface] can be round-tripped via:
48
+
49
+ ```python
50
+ inputs = surface.inputs() # VolSurface -> VolSurfaceInputs
51
+ surface = surface_from_inputs(inputs) # VolSurfaceInputs -> VolSurface
52
+ ```
@@ -7,3 +7,5 @@ different stochastic volatility models.
7
7
  ::: quantflow.options.pricer.OptionPricer
8
8
 
9
9
  ::: quantflow.options.pricer.MaturityPricer
10
+
11
+ ::: quantflow.options.pricer.ModelOptionPrice
@@ -9,10 +9,32 @@
9
9
 
10
10
  ::: quantflow.options.surface.VolSurfaceLoader
11
11
 
12
+ ::: quantflow.options.surface.VolCrossSectionLoader
13
+
14
+ ## Bid/Ask Prices
15
+
16
+ ::: quantflow.options.surface.Price
17
+
18
+ ::: quantflow.options.surface.SpotPrice
19
+
20
+ ::: quantflow.options.surface.FwdPrice
21
+
22
+ ::: quantflow.options.surface.Strike
23
+
24
+ ::: quantflow.options.surface.OptionArrays
25
+
26
+ ::: quantflow.options.surface.OptionMetadata
27
+
12
28
  ::: quantflow.options.surface.OptionPrice
13
29
 
30
+ ::: quantflow.options.surface.OptionPrices
31
+
14
32
  ::: quantflow.options.surface.OptionSelection
15
33
 
34
+ ::: quantflow.options.inputs.OptionType
35
+
36
+ ## Vol Surface Inputs
37
+
16
38
  ::: quantflow.options.inputs.VolSurfaceInputs
17
39
 
18
40
  ::: quantflow.options.inputs.VolSurfaceInput
@@ -0,0 +1,3 @@
1
+ # Doubly Stochastic Poisson process
2
+
3
+ ::: quantflow.sp.dsp.DSP
@@ -0,0 +1,3 @@
1
+ # Utilities
2
+
3
+ This section contains utility functions and classes that are used throughout the library. They are not meant to be used directly by the user, but they can be useful for advanced users who want to extend the library or understand its inner workings.
@@ -0,0 +1,4 @@
1
+ # Numbers
2
+
3
+
4
+ ::: quantflow.utils.numbers.DecimalNumber
@@ -0,0 +1,6 @@
1
+ # Types
2
+
3
+
4
+ ::: quantflow.utils.types.FloatArray
5
+
6
+ ::: quantflow.utils.types.FloatArrayLike
@@ -0,0 +1,43 @@
1
+ # Bibliography
2
+
3
+ ---
4
+
5
+ ### carr_madan
6
+
7
+ Peter Carr, Dilip Madan
8
+
9
+ [Option Valuation Using the Fast Fourier Transform](https://doi.org/10.1002/(SICI)1097-0261(199904)2:1<61::AID-FUT4>3.0.CO;2-4)
10
+
11
+ Journal of Computational Finance, 2(4):61-73, 1999
12
+
13
+ ---
14
+
15
+ ### carr_wu
16
+
17
+ Peter Carr, Liuren Wu
18
+
19
+ [Time-Changed Lévy Processes and Option Pricing](https://doi.org/10.1016/S0304-405X(03)00171-5)
20
+
21
+ Journal of Financial Economics, 71(1):113-141, 2004
22
+
23
+ ---
24
+
25
+ ### chourdakis
26
+
27
+ Kyriakos Chourdakis
28
+
29
+ [Option Pricing Using the Fractional FFT](https://doi.org/10.21314/JCF.2005.102)
30
+
31
+ Journal of Computational Finance, 8(2):1-18, 2005
32
+
33
+ ---
34
+
35
+ ### molnar
36
+
37
+ Peter Molnar
38
+
39
+ [Volatility modeling and forecasting: utilization of realized volatility, implied volatility and the highest and lowest price of the day](https://drive.google.com/file/d/1zCU1OZyrKQLpxaypPv9U5UPbReBDXcMf/view)
40
+
41
+ Master's thesis, University of Economics in Prague, 2020
42
+
43
+ ---
@@ -0,0 +1,25 @@
1
+ from quantflow.options.inputs import OptionType
2
+ from quantflow.options.pricer import OptionPricer
3
+ from quantflow.sp.heston import HestonJ
4
+ from quantflow.utils.distributions import DoubleExponential
5
+
6
+ pricer = OptionPricer(
7
+ model=HestonJ.create(
8
+ DoubleExponential,
9
+ vol=0.5,
10
+ kappa=2,
11
+ rho=-0.2,
12
+ sigma=0.8,
13
+ jump_fraction=0.5,
14
+ jump_asymmetry=0.2,
15
+ )
16
+ )
17
+
18
+ # Price an ATM call option at time to maturity 1.0
19
+ price = pricer.price(
20
+ option_type=OptionType.call,
21
+ strike=100.0,
22
+ forward=100.0,
23
+ ttm=1.0,
24
+ )
25
+ print(price.model_dump_json(indent=2))
@@ -0,0 +1,19 @@
1
+ from quantflow.options.inputs import OptionType
2
+ from quantflow.options.pricer import OptionPricer
3
+ from quantflow.sp.weiner import WeinerProcess
4
+ from quantflow.utils.distributions import DoubleExponential
5
+
6
+ # Weiner process with constant volatility
7
+ # This produces the same sensitivities as the Black-Scholes model
8
+ pricer = OptionPricer(
9
+ model=WeinerProcess(sigma=0.3)
10
+ )
11
+
12
+ # Price an ATM call option at time to maturity 1.0
13
+ price = pricer.price(
14
+ option_type=OptionType.call,
15
+ strike=100.0,
16
+ forward=100.0,
17
+ ttm=1.0,
18
+ )
19
+ print(price.model_dump_json(indent=2))
@@ -1,24 +1,12 @@
1
- ---
2
- jupytext:
3
- text_representation:
4
- extension: .md
5
- format_name: myst
6
- format_version: 0.13
7
- jupytext_version: 1.16.6
8
- kernelspec:
9
- display_name: Python 3 (ipykernel)
10
- language: python
11
- name: python3
12
- ---
13
-
14
1
  # Characteristic Function
15
2
 
16
- The library makes heavy use of [characteristic function](https://en.wikipedia.org/wiki/Characteristic_function_(probability_theory))
3
+ The library makes heavy use of the [characteristic function](https://en.wikipedia.org/wiki/Characteristic_function_(probability_theory))
17
4
  concept and therefore, it is useful to familiarize with it.
18
5
 
19
6
  ## Definition
20
7
 
21
- The characteristic function of a random variable $x$ is the Fourier (inverse) transform of ${\mathbb P}_x$, where ${\mathbb P}_x$ is the distrubution measure of $x$
8
+ The characteristic function of a random variable $x$ is the Fourier (inverse) transform of ${\mathbb P}_x$, where ${\mathbb P}_x$ is the distribution measure of $x$
9
+
22
10
  \begin{equation}
23
11
  \Phi_{x,u} = {\mathbb E}\left[e^{i u x}\right] = \int e^{i u s} {\mathbb P}_x\left(ds\right)
24
12
  \end{equation}
@@ -33,23 +21,23 @@ The characteristic function of a random variable $x$ is the Fourier (inverse) tr
33
21
  * moments of $x$ are given by
34
22
 
35
23
  \begin{equation}
36
- {\mathbb E}\left[x^n\right] = i^{-n} \left.\frac{\Phi_{x, u}}{d u}\right|_{u=0}
24
+ {\mathbb E}\left[x^n\right] = i^{-n} \left.\frac{d\Phi_{x, u}}{d u}\right|_{u=0}
37
25
  \end{equation}
38
26
 
39
- ## Covolution
27
+ ## Convolution
40
28
 
41
- The characteristic function is a great tool for working with linear combination of random variables.
29
+ The characteristic function is a great tool for working with linear combinations of random variables.
42
30
 
43
31
  * if $x$ and $y$ are independent random variables then the characteristic function of the linear combination $a x + b y$ ($a$ and $b$ are constants) is
44
32
 
45
33
  \begin{equation}
46
- \Phi_{ax+bx,u} = \Phi_{x,a u}\Phi_{y,b u}
34
+ \Phi_{ax+by,u} = \Phi_{x,a u}\Phi_{y,b u}
47
35
  \end{equation}
48
36
 
49
37
  * which means, if $x$ and $y$ are independent, the characteristic function of $x+y$ is the product
50
38
 
51
39
  \begin{equation}
52
- \Phi_{x+x,u} = \Phi_{x,u}\Phi_{y,u}
40
+ \Phi_{x+y,u} = \Phi_{x,u}\Phi_{y,u}
53
41
  \end{equation}
54
42
 
55
43
  * The characteristic function of $ax+b$ is
@@ -79,11 +67,6 @@ The inversion formula for these distributions is given by
79
67
  {\mathbb P}_x\left(x=k\right) = \frac{1}{2\pi}\int_{-\pi}^\pi e^{-iuk}\Phi_{k, u} du
80
68
  \end{equation}
81
69
 
82
- ```{code-cell}
83
-
84
- ```
85
-
86
- (characteristic-exponent)=
87
70
  ## Characteristic Exponent
88
71
 
89
72
  The characteristic exponent $\phi_{x,u}$ is defined as
@@ -0,0 +1,51 @@
1
+ # Theory
2
+
3
+ QuantFlow is built around a unified mathematical framework based on **characteristic functions** and **Lévy processes**. This section introduces the core ideas that underpin the library's stochastic process models, Fourier inversion methods, and option pricing routines.
4
+
5
+ ## Characteristic Functions
6
+
7
+ The [characteristic function](./characteristic.md) of a random variable $x$ is its Fourier transform under the probability measure:
8
+
9
+ $$
10
+ \Phi_{x,u} = \mathbb{E}\left[e^{iux}\right]
11
+ $$
12
+
13
+ It is the central computational object throughout the library. Unlike the probability density function, the characteristic function is always well-defined, bounded, and closed under convolution of independent random variables. This makes it the natural tool for working with Lévy processes, where densities are often unavailable in closed form.
14
+
15
+ ## Lévy Processes
16
+
17
+ A [Lévy process](./levy.md) $x_t$ has independent and stationary increments, and its characteristic function factors cleanly over time:
18
+
19
+ $$
20
+ \Phi_{x_t, u} = e^{-t\,\phi_{x_1, u}}
21
+ $$
22
+
23
+ where $\phi_{x_1,u}$ is the **characteristic exponent** at unit time, given by the Lévy-Khintchine formula.
24
+
25
+ The library extends this to **time-changed Lévy processes** $y_t = x_{\tau_t}$, where $\tau_t$ is a stochastic clock driven by an intensity process $\lambda_t$. When $\tau_t$ and $x_t$ are independent, the characteristic function of $y_t$ reduces to the Laplace transform of the integrated intensity:
26
+
27
+ $$
28
+ \Phi_{y_t, u} = \mathcal{L}_{\tau_t}\!\left(\phi_{x_1, u}\right)
29
+ $$
30
+
31
+ This structure includes the Heston stochastic volatility model and its jump extensions as special cases, where the intensity process follows a CIR (Cox-Ingersoll-Ross) dynamics.
32
+
33
+ ## Fourier Inversion
34
+
35
+ Given the characteristic function, the [probability density function](./inversion.md) is recovered via inverse Fourier transform. The library implements two numerical schemes:
36
+
37
+ - **Trapezoidal / Simpson integration** (default) using the Fractional FFT (FRFT), which allows the frequency and space domains to be discretized independently.
38
+ - **Standard FFT**, available as an alternative, with the constraint that $\delta_u \cdot \delta_x = 2\pi / N$.
39
+
40
+ The FRFT is preferred in practice as it achieves higher accuracy with fewer points.
41
+
42
+ ## Option Pricing
43
+
44
+ [European call options](./option_pricing.md) are priced by applying the Fourier inversion machinery to the damped call payoff. For an underlying $S_t = S_0 e^{s_t}$ with log-price process $s_t = x_t - c_t$ (where $c_t$ is the convexity correction ensuring the forward is a martingale), the call price in log-moneyness $k = \ln(K/S_0)$ is:
45
+
46
+ $$
47
+ c_k = \frac{e^{-\alpha k}}{\pi} \int_0^\infty e^{-ivk}\, \Psi(v - i\alpha)\, dv, \qquad
48
+ \Psi_u = \frac{\Phi_{s_t}(u-i)}{iu(iu+1)}
49
+ $$
50
+
51
+ The same numerical transforms used for PDF inversion are reused here, making option pricing computationally efficient across all supported models.