quantflow 0.7.0__tar.gz → 0.9.0__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 (398) hide show
  1. {quantflow-0.7.0 → quantflow-0.9.0}/.github/copilot-instructions.md +10 -1
  2. quantflow-0.9.0/.github/instructions/makefile.instructions.md +5 -0
  3. quantflow-0.9.0/.github/instructions/release.instructions.md +48 -0
  4. quantflow-0.9.0/.github/instructions/tutorial.instructions.md +96 -0
  5. {quantflow-0.7.0 → quantflow-0.9.0}/.github/workflows/build.yml +2 -3
  6. {quantflow-0.7.0 → quantflow-0.9.0}/.github/workflows/docker-multiarch.yml +6 -0
  7. quantflow-0.9.0/.github/workflows/release.yml +78 -0
  8. {quantflow-0.7.0 → quantflow-0.9.0}/.gitignore +3 -1
  9. quantflow-0.9.0/CLAUDE.md +5 -0
  10. {quantflow-0.7.0 → quantflow-0.9.0}/Makefile +35 -24
  11. {quantflow-0.7.0 → quantflow-0.9.0}/PKG-INFO +27 -58
  12. {quantflow-0.7.0 → quantflow-0.9.0}/app/__main__.py +6 -3
  13. {quantflow-0.7.0 → quantflow-0.9.0}/app/hurst.py +23 -23
  14. quantflow-0.9.0/app/utils/paths.py +13 -0
  15. quantflow-0.9.0/dev/build-examples +10 -0
  16. {quantflow-0.7.0 → quantflow-0.9.0}/dev/lint +5 -6
  17. {quantflow-0.7.0 → quantflow-0.9.0}/dev/quantflow.dockerfile +10 -7
  18. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/index.md +1 -1
  19. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/options/black.md +4 -5
  20. quantflow-0.9.0/docs/api/options/calibration.md +17 -0
  21. quantflow-0.9.0/docs/api/sp/bns.md +6 -0
  22. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/sp/heston.md +6 -0
  23. quantflow-0.9.0/docs/api/sp/index.md +63 -0
  24. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/sp/ou.md +2 -0
  25. quantflow-0.9.0/docs/api/sp/wiener.md +3 -0
  26. quantflow-0.9.0/docs/api/utils/index.md +15 -0
  27. quantflow-0.9.0/docs/api/utils/marginal1d.md +9 -0
  28. quantflow-0.9.0/docs/assets/logos/README.md +30 -0
  29. quantflow-0.9.0/docs/assets/logos/favicon.ico +0 -0
  30. quantflow-0.9.0/docs/assets/logos/head-snippet.html +12 -0
  31. quantflow-0.9.0/docs/assets/logos/manifest.json +42 -0
  32. quantflow-0.9.0/docs/assets/logos/png/quantflow-app-icon-1024.png +0 -0
  33. quantflow-0.9.0/docs/assets/logos/png/quantflow-app-icon-128.png +0 -0
  34. quantflow-0.9.0/docs/assets/logos/png/quantflow-app-icon-256.png +0 -0
  35. quantflow-0.9.0/docs/assets/logos/png/quantflow-app-icon-512.png +0 -0
  36. quantflow-0.9.0/docs/assets/logos/png/quantflow-github-social-1280x640.png +0 -0
  37. quantflow-0.9.0/docs/assets/logos/png/quantflow-linkedin-banner.png +0 -0
  38. quantflow-0.9.0/docs/assets/logos/png/quantflow-lockup-1200.png +0 -0
  39. quantflow-0.9.0/docs/assets/logos/png/quantflow-lockup-dark-1200.png +0 -0
  40. quantflow-0.9.0/docs/assets/logos/png/quantflow-lockup-dark-2400.png +0 -0
  41. quantflow-0.9.0/docs/assets/logos/png/quantflow-lockup-tagline-dark-1600.png +0 -0
  42. quantflow-0.9.0/docs/assets/logos/png/quantflow-lockup-tagline-light-1600.png +0 -0
  43. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-1024.png +0 -0
  44. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-128.png +0 -0
  45. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-16.png +0 -0
  46. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-256.png +0 -0
  47. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-32.png +0 -0
  48. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-48.png +0 -0
  49. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-512.png +0 -0
  50. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-64.png +0 -0
  51. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-dark-1024.png +0 -0
  52. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-dark-128.png +0 -0
  53. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-dark-16.png +0 -0
  54. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-dark-256.png +0 -0
  55. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-dark-32.png +0 -0
  56. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-dark-48.png +0 -0
  57. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-dark-512.png +0 -0
  58. quantflow-0.9.0/docs/assets/logos/png/quantflow-mark-dark-64.png +0 -0
  59. quantflow-0.9.0/docs/assets/logos/quantflow-app-icon.svg +16 -0
  60. quantflow-0.9.0/docs/assets/logos/quantflow-favicon.svg +13 -0
  61. quantflow-0.9.0/docs/assets/logos/quantflow-linkedin-banner.svg +18 -0
  62. quantflow-0.9.0/docs/assets/logos/quantflow-lockup-dark.svg +15 -0
  63. quantflow-0.9.0/docs/assets/logos/quantflow-lockup-tagline-dark.svg +16 -0
  64. quantflow-0.9.0/docs/assets/logos/quantflow-lockup-tagline-light.svg +15 -0
  65. quantflow-0.9.0/docs/assets/logos/quantflow-lockup.svg +14 -0
  66. quantflow-0.9.0/docs/assets/logos/quantflow-mark-dark.svg +14 -0
  67. quantflow-0.9.0/docs/assets/logos/quantflow-mark.svg +13 -0
  68. quantflow-0.9.0/docs/bib2md.py +195 -0
  69. quantflow-0.9.0/docs/bibliography.md +73 -0
  70. quantflow-0.9.0/docs/examples/_utils.py +43 -0
  71. quantflow-0.9.0/docs/examples/cir_pdf_comparison.py +100 -0
  72. quantflow-0.9.0/docs/examples/fft.py +22 -0
  73. quantflow-0.9.0/docs/examples/pricing_method_comparison.py +178 -0
  74. quantflow-0.9.0/docs/examples/vol_surface_bns2_calibration.py +45 -0
  75. quantflow-0.9.0/docs/examples/vol_surface_bns_calibration.py +35 -0
  76. quantflow-0.9.0/docs/examples/vol_surface_heston_calibration.py +36 -0
  77. {quantflow-0.7.0 → quantflow-0.9.0}/docs/examples/vol_surface_hestonj_calibration.py +16 -15
  78. {quantflow-0.7.0 → quantflow-0.9.0}/docs/examples/vol_surface_inputs.py +6 -1
  79. quantflow-0.9.0/docs/examples/volsurface.json +5348 -0
  80. quantflow-0.7.0/docs/examples/weiner_volatility_pricer.py → quantflow-0.9.0/docs/examples/wiener_volatility_pricer.py +3 -6
  81. quantflow-0.9.0/docs/favicon.ico +0 -0
  82. {quantflow-0.7.0 → quantflow-0.9.0}/docs/glossary.md +47 -8
  83. {quantflow-0.7.0 → quantflow-0.9.0}/docs/index.md +10 -56
  84. quantflow-0.9.0/docs/javascripts/mathjax.js +26 -0
  85. quantflow-0.9.0/docs/mcp.md +63 -0
  86. quantflow-0.9.0/docs/references.bib +152 -0
  87. quantflow-0.9.0/docs/release-notes.md +165 -0
  88. quantflow-0.9.0/docs/robots.txt +2 -0
  89. {quantflow-0.7.0 → quantflow-0.9.0}/docs/theory/characteristic.md +6 -0
  90. quantflow-0.9.0/docs/theory/convexity_correction.md +119 -0
  91. {quantflow-0.7.0 → quantflow-0.9.0}/docs/theory/inversion.md +9 -25
  92. {quantflow-0.7.0 → quantflow-0.9.0}/docs/theory/levy.md +4 -2
  93. quantflow-0.9.0/docs/theory/option_pricing.md +232 -0
  94. quantflow-0.9.0/docs/tutorials/bns_calibration.md +143 -0
  95. quantflow-0.9.0/docs/tutorials/cir.md +95 -0
  96. {quantflow-0.7.0 → quantflow-0.9.0}/docs/tutorials/index.md +1 -0
  97. {quantflow-0.7.0 → quantflow-0.9.0}/docs/tutorials/option_pricing.md +3 -3
  98. quantflow-0.9.0/docs/tutorials/pricing_method_comparison.md +62 -0
  99. quantflow-0.9.0/docs/tutorials/volatility_surface.md +251 -0
  100. {quantflow-0.7.0 → quantflow-0.9.0}/mkdocs.yml +15 -5
  101. {quantflow-0.7.0 → quantflow-0.9.0}/pyproject.toml +26 -2
  102. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ai/tools/crypto.py +21 -6
  103. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/bs.py +9 -6
  104. quantflow-0.9.0/quantflow/options/calibration/__init__.py +24 -0
  105. quantflow-0.9.0/quantflow/options/calibration/base.py +336 -0
  106. quantflow-0.9.0/quantflow/options/calibration/bns.py +144 -0
  107. quantflow-0.9.0/quantflow/options/calibration/heston.py +305 -0
  108. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/divfm/network.py +1 -1
  109. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/divfm/pricer.py +48 -33
  110. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/pricer.py +83 -133
  111. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/surface.py +15 -14
  112. quantflow-0.9.0/quantflow/sp/__init__.py +0 -0
  113. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/sp/base.py +25 -7
  114. quantflow-0.9.0/quantflow/sp/bns.py +246 -0
  115. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/sp/cir.py +88 -31
  116. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/sp/copula.py +6 -10
  117. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/sp/dsp.py +4 -2
  118. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/sp/heston.py +165 -7
  119. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/sp/jump_diffusion.py +5 -5
  120. quantflow-0.9.0/quantflow/sp/ou.py +333 -0
  121. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/sp/poisson.py +1 -1
  122. quantflow-0.7.0/quantflow/sp/weiner.py → quantflow-0.9.0/quantflow/sp/wiener.py +1 -1
  123. quantflow-0.9.0/quantflow/utils/__init__.py +0 -0
  124. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/utils/distributions.py +2 -2
  125. quantflow-0.9.0/quantflow/utils/marginal.py +833 -0
  126. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/utils/plot.py +8 -6
  127. quantflow-0.9.0/quantflow_tests/__init__.py +0 -0
  128. quantflow-0.9.0/quantflow_tests/test_bns.py +107 -0
  129. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_cir.py +21 -2
  130. quantflow-0.9.0/quantflow_tests/test_copula.py +58 -0
  131. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_divfm.py +13 -10
  132. quantflow-0.9.0/quantflow_tests/test_heston.py +104 -0
  133. quantflow-0.9.0/quantflow_tests/test_jump_diffusion.py +56 -0
  134. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_ohlc.py +2 -2
  135. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_options.py +172 -12
  136. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_options_pricer.py +3 -3
  137. quantflow-0.9.0/quantflow_tests/test_ou.py +110 -0
  138. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_poisson.py +17 -0
  139. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_strategies.py +2 -2
  140. quantflow-0.7.0/quantflow_tests/test_weiner.py → quantflow-0.9.0/quantflow_tests/test_wiener.py +13 -13
  141. {quantflow-0.7.0 → quantflow-0.9.0}/readme.md +10 -56
  142. {quantflow-0.7.0 → quantflow-0.9.0}/uv.lock +94 -107
  143. quantflow-0.7.0/.hypothesis/.gitignore +0 -9
  144. quantflow-0.7.0/.hypothesis/constants/0254a8e6686c0188 +0 -4
  145. quantflow-0.7.0/.hypothesis/constants/0301065152d9ab0f +0 -4
  146. quantflow-0.7.0/.hypothesis/constants/08a9483e67e42715 +0 -4
  147. quantflow-0.7.0/.hypothesis/constants/12661bda99c599a0 +0 -4
  148. quantflow-0.7.0/.hypothesis/constants/178c27013672fc03 +0 -4
  149. quantflow-0.7.0/.hypothesis/constants/179cb27b16ec61cb +0 -4
  150. quantflow-0.7.0/.hypothesis/constants/1d76d579f73cb78a +0 -4
  151. quantflow-0.7.0/.hypothesis/constants/1fb1e289086a6515 +0 -4
  152. quantflow-0.7.0/.hypothesis/constants/22c995d873e6fc5e +0 -4
  153. quantflow-0.7.0/.hypothesis/constants/28ee0759c42ef0dc +0 -4
  154. quantflow-0.7.0/.hypothesis/constants/359bfc81440230bd +0 -4
  155. quantflow-0.7.0/.hypothesis/constants/38eb4b8a22a4e143 +0 -4
  156. quantflow-0.7.0/.hypothesis/constants/3b743a167ba8a00d +0 -4
  157. quantflow-0.7.0/.hypothesis/constants/3d1ea6cd5c0dd805 +0 -4
  158. quantflow-0.7.0/.hypothesis/constants/3f69026b057c9ea4 +0 -4
  159. quantflow-0.7.0/.hypothesis/constants/43429b7066040416 +0 -4
  160. quantflow-0.7.0/.hypothesis/constants/48eded684f2df5ff +0 -4
  161. quantflow-0.7.0/.hypothesis/constants/48f9e94e06874f1f +0 -4
  162. quantflow-0.7.0/.hypothesis/constants/4a0084c87b2db2c3 +0 -4
  163. quantflow-0.7.0/.hypothesis/constants/559123e9ab320ac4 +0 -4
  164. quantflow-0.7.0/.hypothesis/constants/56b8b5b1f444ca20 +0 -4
  165. quantflow-0.7.0/.hypothesis/constants/57aada3b0484db35 +0 -4
  166. quantflow-0.7.0/.hypothesis/constants/57d925bf614c980e +0 -4
  167. quantflow-0.7.0/.hypothesis/constants/586b6c6bec39754b +0 -4
  168. quantflow-0.7.0/.hypothesis/constants/5db8650c1259a5be +0 -4
  169. quantflow-0.7.0/.hypothesis/constants/5e91d8ab779e1b7f +0 -4
  170. quantflow-0.7.0/.hypothesis/constants/5e9b34ae43a63455 +0 -4
  171. quantflow-0.7.0/.hypothesis/constants/60fd378f4cdd9e2b +0 -4
  172. quantflow-0.7.0/.hypothesis/constants/62b16e163f3080b1 +0 -4
  173. quantflow-0.7.0/.hypothesis/constants/65be84333a21ee0e +0 -4
  174. quantflow-0.7.0/.hypothesis/constants/6c21b394c1448f8f +0 -4
  175. quantflow-0.7.0/.hypothesis/constants/6f23e19523671fa0 +0 -4
  176. quantflow-0.7.0/.hypothesis/constants/7447925d1ef6c39e +0 -4
  177. quantflow-0.7.0/.hypothesis/constants/746b49e5b68d35ad +0 -4
  178. quantflow-0.7.0/.hypothesis/constants/8077ddf6166a85cc +0 -4
  179. quantflow-0.7.0/.hypothesis/constants/81385a74f6fe21d1 +0 -4
  180. quantflow-0.7.0/.hypothesis/constants/8e946ad29fdc078f +0 -4
  181. quantflow-0.7.0/.hypothesis/constants/92a3edfcfc1aea4b +0 -4
  182. quantflow-0.7.0/.hypothesis/constants/93bfbd91994ac4c8 +0 -4
  183. quantflow-0.7.0/.hypothesis/constants/9be9011eed1003b0 +0 -4
  184. quantflow-0.7.0/.hypothesis/constants/9f39c6a9e378f874 +0 -4
  185. quantflow-0.7.0/.hypothesis/constants/a4e02d335ce302fe +0 -4
  186. quantflow-0.7.0/.hypothesis/constants/a5942183658b1820 +0 -4
  187. quantflow-0.7.0/.hypothesis/constants/abe86acdb72d5329 +0 -4
  188. quantflow-0.7.0/.hypothesis/constants/b2bc2ff1a9dc1ebd +0 -4
  189. quantflow-0.7.0/.hypothesis/constants/b43b9a034a123011 +0 -4
  190. quantflow-0.7.0/.hypothesis/constants/bc2ede502ce77baa +0 -4
  191. quantflow-0.7.0/.hypothesis/constants/be48829d39927abc +0 -4
  192. quantflow-0.7.0/.hypothesis/constants/c05e0bd6fe504415 +0 -4
  193. quantflow-0.7.0/.hypothesis/constants/c198e8c7d980ebd0 +0 -4
  194. quantflow-0.7.0/.hypothesis/constants/c42c0c1705a53e64 +0 -4
  195. quantflow-0.7.0/.hypothesis/constants/cc15223c7c9326cd +0 -4
  196. quantflow-0.7.0/.hypothesis/constants/ce1f53f3613afe56 +0 -4
  197. quantflow-0.7.0/.hypothesis/constants/ced58ab73e655e68 +0 -4
  198. quantflow-0.7.0/.hypothesis/constants/cf8267391ea821cf +0 -4
  199. quantflow-0.7.0/.hypothesis/constants/d1c239339de85cf1 +0 -4
  200. quantflow-0.7.0/.hypothesis/constants/da39a3ee5e6b4b0d +0 -4
  201. quantflow-0.7.0/.hypothesis/constants/dfdb158bb5ee458f +0 -4
  202. quantflow-0.7.0/.hypothesis/constants/e0a9a30d56186ce4 +0 -4
  203. quantflow-0.7.0/.hypothesis/constants/e238343dcf50c80f +0 -4
  204. quantflow-0.7.0/.hypothesis/constants/ed5fae84fef8d28d +0 -4
  205. quantflow-0.7.0/.hypothesis/constants/f33893fdc851717e +0 -4
  206. quantflow-0.7.0/.hypothesis/constants/f5861549f7f1821b +0 -4
  207. quantflow-0.7.0/.hypothesis/constants/fc9042c4e0183418 +0 -4
  208. quantflow-0.7.0/.hypothesis/constants/fe8b643a6cddd723 +0 -4
  209. quantflow-0.7.0/CLAUDE.md +0 -2
  210. quantflow-0.7.0/dev/build-examples +0 -28
  211. quantflow-0.7.0/docs/api/options/calibration.md +0 -5
  212. quantflow-0.7.0/docs/api/sp/index.md +0 -9
  213. quantflow-0.7.0/docs/api/sp/weiner.md +0 -3
  214. quantflow-0.7.0/docs/api/utils/index.md +0 -3
  215. quantflow-0.7.0/docs/api/utils/marginal1d.md +0 -3
  216. quantflow-0.7.0/docs/assets/heston_calibrated_smile.png +0 -0
  217. quantflow-0.7.0/docs/assets/hestonj_calibrated_smile.png +0 -0
  218. quantflow-0.7.0/docs/assets/linkedin-banner.png +0 -0
  219. quantflow-0.7.0/docs/assets/quantflow-light.svg +0 -110
  220. quantflow-0.7.0/docs/assets/quantflow-logo.png +0 -0
  221. quantflow-0.7.0/docs/assets/quantflow-repo.png +0 -0
  222. quantflow-0.7.0/docs/assets/quantflow-repo.svg +0 -203
  223. quantflow-0.7.0/docs/assets/quantflow.svg +0 -252
  224. quantflow-0.7.0/docs/bibliography.md +0 -51
  225. quantflow-0.7.0/docs/examples/vol_surface_heston_calibration.py +0 -33
  226. quantflow-0.7.0/docs/examples_png/vol_surface_heston_plot.py +0 -35
  227. quantflow-0.7.0/docs/examples_png/vol_surface_hestonj_plot.py +0 -46
  228. quantflow-0.7.0/docs/javascripts/mathjax.js +0 -12
  229. quantflow-0.7.0/docs/references.bib +0 -139
  230. quantflow-0.7.0/docs/theory/option_pricing.md +0 -114
  231. quantflow-0.7.0/docs/tutorials/volatility_surface.md +0 -185
  232. quantflow-0.7.0/notebooks/applications/calibration.md +0 -204
  233. quantflow-0.7.0/notebooks/applications/calibration.py +0 -189
  234. quantflow-0.7.0/notebooks/applications/volatility_surface.md +0 -144
  235. quantflow-0.7.0/notebooks/data/fed.md +0 -40
  236. quantflow-0.7.0/notebooks/data/fiscal_data.md +0 -31
  237. quantflow-0.7.0/notebooks/data/fmp.md +0 -80
  238. quantflow-0.7.0/notebooks/data/timeseries.md +0 -39
  239. quantflow-0.7.0/notebooks/models/bns.md +0 -111
  240. quantflow-0.7.0/notebooks/models/cir.md +0 -186
  241. quantflow-0.7.0/notebooks/models/gousv.md +0 -48
  242. quantflow-0.7.0/notebooks/models/heston.md +0 -133
  243. quantflow-0.7.0/notebooks/models/heston_jumps.md +0 -78
  244. quantflow-0.7.0/notebooks/models/jump_diffusion.md +0 -101
  245. quantflow-0.7.0/notebooks/models/ou.md +0 -203
  246. quantflow-0.7.0/notebooks/models/overview.md +0 -19
  247. quantflow-0.7.0/notebooks/models/poisson.md +0 -269
  248. quantflow-0.7.0/notebooks/models/weiner.md +0 -73
  249. quantflow-0.7.0/quantflow/options/calibration.py +0 -357
  250. quantflow-0.7.0/quantflow/sp/bns.py +0 -66
  251. quantflow-0.7.0/quantflow/sp/ou.py +0 -182
  252. quantflow-0.7.0/quantflow/utils/marginal.py +0 -321
  253. quantflow-0.7.0/quantflow_tests/fixtures/volsurface.json +0 -4359
  254. quantflow-0.7.0/quantflow_tests/test_copula.py +0 -30
  255. quantflow-0.7.0/quantflow_tests/test_heston.py +0 -39
  256. quantflow-0.7.0/quantflow_tests/test_jump_diffusion.py +0 -27
  257. quantflow-0.7.0/quantflow_tests/test_ou.py +0 -48
  258. {quantflow-0.7.0 → quantflow-0.9.0}/.coveragerc +0 -0
  259. {quantflow-0.7.0 → quantflow-0.9.0}/.dockerignore +0 -0
  260. {quantflow-0.7.0 → quantflow-0.9.0}/.github/workflows/deploy.yml +0 -0
  261. {quantflow-0.7.0 → quantflow-0.9.0}/.vscode/launch.json +0 -0
  262. {quantflow-0.7.0 → quantflow-0.9.0}/.vscode/settings.json +0 -0
  263. {quantflow-0.7.0 → quantflow-0.9.0}/.vscode/tasks.json +0 -0
  264. {quantflow-0.7.0 → quantflow-0.9.0}/CITATION.cff +0 -0
  265. {quantflow-0.7.0 → quantflow-0.9.0}/LICENSE +0 -0
  266. {quantflow-0.7.0 → quantflow-0.9.0}/app/cointegration.py +0 -0
  267. {quantflow-0.7.0 → quantflow-0.9.0}/app/double_exponential_sampling.py +0 -0
  268. {quantflow-0.7.0 → quantflow-0.9.0}/app/gaussian_sampling.py +0 -0
  269. {quantflow-0.7.0 → quantflow-0.9.0}/app/heston_divfm_fit.py +0 -0
  270. {quantflow-0.7.0 → quantflow-0.9.0}/app/heston_vol_surface.py +0 -0
  271. {quantflow-0.7.0 → quantflow-0.9.0}/app/poisson_sampling.py +0 -0
  272. {quantflow-0.7.0 → quantflow-0.9.0}/app/scripts/__init__.py +0 -0
  273. {quantflow-0.7.0 → quantflow-0.9.0}/app/scripts/heston_divfm_fit.py +0 -0
  274. {quantflow-0.7.0 → quantflow-0.9.0/app/scripts}/test_comparison.py +0 -0
  275. {quantflow-0.7.0 → quantflow-0.9.0}/app/supersmoother.py +0 -0
  276. {quantflow-0.7.0 → quantflow-0.9.0}/app/utils/__init__.py +0 -0
  277. {quantflow-0.7.0 → quantflow-0.9.0}/app/volatility_surface.py +0 -0
  278. {quantflow-0.7.0 → quantflow-0.9.0}/dev/blocks/quantflow.yaml +0 -0
  279. {quantflow-0.7.0 → quantflow-0.9.0}/dev/charts.yaml +0 -0
  280. {quantflow-0.7.0 → quantflow-0.9.0}/dev/helm/.helmignore +0 -0
  281. {quantflow-0.7.0 → quantflow-0.9.0}/dev/helm/Chart.yaml +0 -0
  282. {quantflow-0.7.0 → quantflow-0.9.0}/dev/helm/templates/_helpers.tpl +0 -0
  283. {quantflow-0.7.0 → quantflow-0.9.0}/dev/helm/templates/_service.tpl +0 -0
  284. {quantflow-0.7.0 → quantflow-0.9.0}/dev/helm/templates/app.yaml +0 -0
  285. {quantflow-0.7.0 → quantflow-0.9.0}/dev/helm/templates/configmap.yaml +0 -0
  286. {quantflow-0.7.0 → quantflow-0.9.0}/dev/helm/templates/secret.yaml +0 -0
  287. {quantflow-0.7.0 → quantflow-0.9.0}/dev/helm/values.yaml +0 -0
  288. {quantflow-0.7.0 → quantflow-0.9.0}/dev/install +0 -0
  289. {quantflow-0.7.0 → quantflow-0.9.0}/dev/marimo +0 -0
  290. {quantflow-0.7.0 → quantflow-0.9.0}/dev/test +0 -0
  291. {quantflow-0.7.0/quantflow/ai/tools → quantflow-0.9.0/docs}/__init__.py +0 -0
  292. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/data/deribit.md +0 -0
  293. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/data/fed.md +0 -0
  294. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/data/fmp.md +0 -0
  295. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/data/fred.md +0 -0
  296. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/data/index.md +0 -0
  297. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/options/divfm.md +0 -0
  298. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/options/index.md +0 -0
  299. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/options/pricer.md +0 -0
  300. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/options/svi.md +0 -0
  301. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/options/vol_surface.md +0 -0
  302. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/rates/index.md +0 -0
  303. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/rates/interest_rate.md +0 -0
  304. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/rates/yield_curve.md +0 -0
  305. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/sp/cir.md +0 -0
  306. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/sp/compound_poisson.md +0 -0
  307. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/sp/copula.md +0 -0
  308. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/sp/dsp.md +0 -0
  309. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/sp/jump_diffusion.md +0 -0
  310. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/sp/poisson.md +0 -0
  311. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/ta/ewma.md +0 -0
  312. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/ta/index.md +0 -0
  313. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/ta/kalman.md +0 -0
  314. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/ta/ohlc.md +0 -0
  315. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/ta/paths.md +0 -0
  316. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/ta/supersmoother.md +0 -0
  317. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/utils/bins.md +0 -0
  318. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/utils/distributions.md +0 -0
  319. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/utils/numbers.md +0 -0
  320. {quantflow-0.7.0 → quantflow-0.9.0}/docs/api/utils/types.md +0 -0
  321. {quantflow-0.7.0 → quantflow-0.9.0}/docs/assets/heston.gif +0 -0
  322. {quantflow-0.7.0 → quantflow-0.9.0}/docs/contributing.md +0 -0
  323. {quantflow-0.7.0/quantflow/data → quantflow-0.9.0/docs/examples}/__init__.py +0 -0
  324. {quantflow-0.7.0 → quantflow-0.9.0}/docs/examples/heston_volatility_pricer.py +0 -0
  325. {quantflow-0.7.0 → quantflow-0.9.0}/docs/theory/index.md +0 -0
  326. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/__init__.py +0 -0
  327. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ai/__init__.py +0 -0
  328. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ai/server.py +0 -0
  329. {quantflow-0.7.0/quantflow/options → quantflow-0.9.0/quantflow/ai/tools}/__init__.py +0 -0
  330. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ai/tools/base.py +0 -0
  331. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ai/tools/charts.py +0 -0
  332. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ai/tools/fred.py +0 -0
  333. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ai/tools/stocks.py +0 -0
  334. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ai/tools/vault.py +0 -0
  335. {quantflow-0.7.0/quantflow/rates → quantflow-0.9.0/quantflow/data}/__init__.py +0 -0
  336. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/data/deribit.py +0 -0
  337. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/data/fed.py +0 -0
  338. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/data/fiscal_data.py +0 -0
  339. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/data/fmp.py +0 -0
  340. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/data/fred.py +0 -0
  341. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/data/vault.py +0 -0
  342. {quantflow-0.7.0/quantflow/sp → quantflow-0.9.0/quantflow/options}/__init__.py +0 -0
  343. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/divfm/__init__.py +0 -0
  344. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/divfm/trainer.py +0 -0
  345. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/divfm/weights.py +0 -0
  346. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/docs/butterfly.md +0 -0
  347. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/docs/calendar_spread.md +0 -0
  348. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/docs/spread.md +0 -0
  349. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/docs/straddle.md +0 -0
  350. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/docs/strangle.md +0 -0
  351. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/docs/terminology.md +0 -0
  352. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/inputs.py +0 -0
  353. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/strategies/__init__.py +0 -0
  354. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/strategies/base.py +0 -0
  355. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/strategies/butterfly.py +0 -0
  356. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/strategies/calendar_spread.py +0 -0
  357. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/strategies/spread.py +0 -0
  358. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/strategies/straddle.py +0 -0
  359. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/strategies/strangle.py +0 -0
  360. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/options/svi.py +0 -0
  361. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/py.typed +0 -0
  362. {quantflow-0.7.0/quantflow/utils → quantflow-0.9.0/quantflow/rates}/__init__.py +0 -0
  363. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/rates/interest_rate.py +0 -0
  364. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/rates/nelson_siegel.py +0 -0
  365. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/rates/yield_curve.py +0 -0
  366. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ta/__init__.py +0 -0
  367. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ta/base.py +0 -0
  368. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ta/ewma.py +0 -0
  369. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ta/kalman.py +0 -0
  370. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ta/ohlc.py +0 -0
  371. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ta/paths.py +0 -0
  372. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/ta/supersmoother.py +0 -0
  373. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/utils/bins.py +0 -0
  374. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/utils/dates.py +0 -0
  375. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/utils/functions.py +0 -0
  376. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/utils/numbers.py +0 -0
  377. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/utils/transforms.py +0 -0
  378. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow/utils/types.py +0 -0
  379. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/conftest.py +0 -0
  380. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/fixtures/deribit_futures.json +0 -0
  381. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/fixtures/deribit_instruments.json +0 -0
  382. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/fixtures/deribit_options.json +0 -0
  383. {quantflow-0.7.0/docs/examples → quantflow-0.9.0/quantflow_tests/fixtures}/volsurface.json +0 -0
  384. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_ai.py +0 -0
  385. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_data.py +0 -0
  386. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_data_deribit.py +0 -0
  387. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_disable_outliers.py +0 -0
  388. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_distributions.py +0 -0
  389. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_frft.py +0 -0
  390. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_implied_fwd.py +0 -0
  391. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_rates.py +0 -0
  392. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_surface_methods.py +0 -0
  393. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_svi.py +0 -0
  394. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_utils.py +0 -0
  395. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/test_vault.py +0 -0
  396. {quantflow-0.7.0 → quantflow-0.9.0}/quantflow_tests/utils.py +0 -0
  397. {quantflow-0.7.0 → quantflow-0.9.0}/rops.toml +0 -0
  398. {quantflow-0.7.0 → quantflow-0.9.0}/taplo.toml +0 -0
@@ -27,11 +27,20 @@ applyTo: '/**'
27
27
 
28
28
  * The documentation for quantflow is available at `https://quantflow.quantmid.com`
29
29
  * Documentation is built using [mkdocs](https://www.mkdocs.org/) and stored in the `docs/` directory. The documentation source files are written in markdown format.
30
- * Do not use em dashes () in documentation files or docstrings. Use colons, parentheses, or restructure the sentence instead.
30
+ * Split prose into short paragraphs (one idea per paragraph) separated by blank lines. Never write a wall-of-text paragraph that strings together mechanism, rationale, caveats and usage advice. This applies to mkdocs tutorials, theory pages and long docstrings.
31
+ * Do not use dashes (em dashes, en dashes, or hyphens used as dashes) in documentation files or docstrings. Use colons, parentheses, or restructure the sentence instead.
31
32
  * Math in documentation and docstrings: always use `\begin{equation}...\end{equation}` for any formula or equation. Use `$...$` only for brief inline references to variables (e.g. $F$, $K$). Do not use `$$...$$`, `` `...` ``, or RST syntax (`.. math::`, `:math:`).
33
+ * Math notation convention: use $\Phi$ for the characteristic function and $\phi$ for the characteristic exponent, where $\Phi = e^{-\phi}$.
32
34
  * Glossary entries in `docs/glossary.md` must be kept in alphabetical order.
35
+ * Do not repeat concept definitions inline in tutorials or docstrings — link to the glossary instead using a relative markdown link (e.g. `[moneyness](../glossary.md#moneyness)`).
33
36
  * To rebuild doc examples run `uv run ./dev/build-examples` — runs all scripts in `docs/examples/` and writes their output to `docs/examples_output/`
34
37
 
38
+ ## Pydantic models
39
+
40
+ * Always document Pydantic fields with `Field(description=...)` — never use a docstring below a field assignment
41
+ * Split long description strings across lines using implicit string concatenation rather than shortening the text
42
+ * When a docstring line exceeds the line length limit, split it across multiple lines rather than shortening the text
43
+
35
44
  ## Package structure
36
45
 
37
46
  * Strategy runtime markdown descriptions (read by `load_description()` at runtime) live inside the package at `quantflow/options/strategies/docs/` — they must be inside the package to be accessible when the library is installed
@@ -0,0 +1,5 @@
1
+ # Makefile Conventions
2
+
3
+ - Keep all targets sorted alphabetically.
4
+ - targets should be separated by a one blank line only.
5
+ - Each target should have a one-line description, starting with `##`, that describes what the target does. This description is used by the `help` target to generate documentation for all targets.
@@ -0,0 +1,48 @@
1
+ # Release Instructions
2
+
3
+ Releases are driven by `v*` git tags. Pushing a tag triggers
4
+ `.github/workflows/release.yml`, which runs lint and the test suite, publishes
5
+ the package to PyPI (`make publish`), then extracts the matching `## vX.Y.Z`
6
+ section from `docs/release-notes.md` and publishes it as the GitHub Release
7
+ body.
8
+
9
+ ## Cutting a release
10
+
11
+ 1. Bump `version` in `pyproject.toml` to the new release version.
12
+ 2. Add a `## vX.Y.Z` section at the top of `docs/release-notes.md` with the
13
+ notes for the release. The header text is matched verbatim by the
14
+ workflow's `awk` extractor, so it must be `## vX.Y.Z` exactly (no trailing
15
+ dash, no title after the version). The release workflow fails if this
16
+ section is missing.
17
+ 3. Commit and merge to `main`; let the `build` workflow pass.
18
+ 4. From `main`, run `make release` — it reads the version from
19
+ `pyproject.toml`, asks for confirmation, then creates an annotated `vX.Y.Z`
20
+ tag and pushes it. The `release` workflow takes it from there.
21
+
22
+ Do not publish to PyPI manually, and do not revive the old
23
+ `head_commit.message == 'release'` flow — the tag-triggered workflow is the
24
+ only supported path.
25
+
26
+ ## Release-notes conventions
27
+
28
+ The `## vX.Y.Z` section in `docs/release-notes.md` is rendered both on the
29
+ docs site and as the GitHub Release body, so it must follow these conventions:
30
+
31
+ - Open with a one-paragraph summary describing the theme of the release. If
32
+ the release contains breaking changes, point readers to the **Breaking
33
+ changes** section in that paragraph.
34
+ - Group entries under H3 subsections in this order: `### Breaking changes`,
35
+ `### New features`, `### Improvements and fixes`,
36
+ `### Documentation and assets`. Omit any subsection that has no entries.
37
+ - Every PR reference must be a markdown link of the form
38
+ `[#NN](https://github.com/quantmind/quantflow/pull/NN)` — never a bare
39
+ `(#NN)`. GitHub's auto-linking only works in some contexts, and the explicit
40
+ URL works everywhere. When one entry references multiple PRs, list them
41
+ comma-separated inside one set of parentheses, each as its own link.
42
+ - Build the PR list by running `git log vPREV..HEAD --oneline` against the
43
+ previous release tag and following each squashed-merge commit back to its
44
+ PR. Cross-check with `gh pr list --state merged --base main` for any PRs
45
+ merged since the previous tag.
46
+ - End the section with a
47
+ `[Full changelog](https://github.com/quantmind/quantflow/compare/vPREV...vX.Y.Z)`
48
+ link comparing the new tag against the previous one.
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: quantflow-tutorial-instructions
3
+ description: 'Instructions for tutorial in quantflow'
4
+ applyTo: '/docs/tutorials/**,/docs/examples/**'
5
+ ---
6
+
7
+
8
+
9
+ # Tutorial Instructions
10
+
11
+ ## File locations
12
+
13
+ - Tutorial pages: `docs/tutorials/<name>.md`
14
+ - Example scripts: `docs/examples/<name>.py`
15
+ - Generated images: `docs/assets/examples/<name>.png`
16
+ - Script stdout captured to: `docs/examples/output/<name>.out`
17
+ - Every new tutorial must be added to the `nav` section of `mkdocs.yml` under `Tutorials`.
18
+ - Update `docs/tutorials/index.md` with a row in the summary table.
19
+
20
+ ## Building
21
+
22
+ - Build a single example: `uv run python docs/examples/<name>.py`
23
+ - Build all examples and capture output: `make docs-examples`
24
+ - Preview the docs locally: `uv run mkdocs serve`
25
+
26
+ ## Tutorial page structure
27
+
28
+ Each tutorial markdown file should follow this order:
29
+
30
+ 1. **H1 title** — the subject, not "Tutorial on X".
31
+ 2. **One-paragraph introduction** — what the tutorial demonstrates and why it is useful.
32
+ Link to the relevant API classes using `[ClassName][fully.qualified.path]`.
33
+ 3. **Sections** (H2) — cover the concept first, then show usage, then show results.
34
+ Use H3 subsections for variants (different parameter regimes, maturities, etc.).
35
+ 4. **Code section** — always the last H2. Embed the full example script with:
36
+ ````
37
+ ```python
38
+ --8<-- "docs/examples/<name>.py"
39
+ ```
40
+ ````
41
+ If the script prints structured output, embed it too:
42
+ ````
43
+ ```
44
+ --8<-- "docs/examples/output/<name>.out"
45
+ ```
46
+ ````
47
+
48
+ ## Example scripts
49
+
50
+ - Each script must be self-contained and runnable with `uv run python docs/examples/<name>.py`.
51
+ - Place shared helpers in `docs/examples/_utils.py` — do not duplicate utility code.
52
+ - Use `assets_path(filename)` from `_utils.py` to get the correct path when saving images.
53
+ - Use `plotly` for all charts. Save to PNG with `fig.write_image(assets_path(...), width=900, height=500)`.
54
+ Use `width=1600, height=800` for side-by-side subplot layouts.
55
+ - When overlaying an analytical curve with a numerical result (e.g. PDF from characteristic
56
+ function), plot the analytical result as a solid line and the numerical result as circle
57
+ markers (`mode="markers", marker=dict(symbol="circle")`). This makes the discretization
58
+ points visible and the two series easy to distinguish.
59
+ - Do not `print` raw numbers — emit only what belongs in the captured `.out` file.
60
+ - Scripts must produce no warnings when run cleanly (fix the root cause, e.g. avoid `x=0`
61
+ in domains where the PDF is singular).
62
+ - The `build_examples` helper in `_utils.py` runs every non-underscore script and captures
63
+ stdout; keep scripts idempotent and deterministic.
64
+
65
+ ## Charts
66
+
67
+ - Embed images with a clickable link that opens full-size in a new tab:
68
+ ```markdown
69
+ [![Alt text](../assets/examples/<name>.png)](../assets/examples/<name>.png){target="_blank"}
70
+ ```
71
+ - Write a one-sentence caption above each image explaining what the reader should observe.
72
+
73
+ ## Math
74
+
75
+ Follow the math conventions in `copilot-instructions.md`:
76
+
77
+ - Use `\begin{equation}...\end{equation}` for standalone formulas.
78
+ - Use `\begin{equation}\begin{aligned}...\end{aligned}\end{equation}` for multi-line systems.
79
+ - Use `$...$` only for brief inline variable references.
80
+ - Use `\Phi` for the characteristic function and `\phi` for the characteristic exponent.
81
+
82
+ ## Cross-references
83
+
84
+ - Link API symbols with `[ClassName][fully.qualified.module.ClassName]`.
85
+ - Link to theory pages with relative markdown links: `[Option Pricing](../theory/option_pricing.md)`.
86
+ - Link to the glossary for concept definitions rather than re-defining them inline.
87
+ - Link to the bibliography for external references: `[Carr-Madan](../bibliography.md#carr_madan)`.
88
+
89
+ ## What not to include
90
+
91
+ - Do not explain implementation details that belong in docstrings.
92
+ - Do not reproduce equations already in the API reference — link to them instead.
93
+ - Do not add a summary or "next steps" section unless the tutorial is part of a series.
94
+ - Do not use math notation (`$...$`, `\begin{equation}`, etc.) in any heading (H1–H4).
95
+ Math does not render in the table of contents — write headings in plain English instead
96
+ (e.g. "Short horizon" not "Short horizon ($t = 0.5$)").
@@ -23,6 +23,8 @@ jobs:
23
23
  - uses: actions/checkout@v4
24
24
  - name: install rops
25
25
  uses: quantmind/rops/.github/actions/setup-rops@main
26
+ env:
27
+ GITHUB_TOKEN: ${{ secrets.TOKEN_DEPLOYMENT }}
26
28
  - name: install taplo
27
29
  run: rops tools update taplo
28
30
  - name: Set up Python ${{ matrix.python-version }}
@@ -47,9 +49,6 @@ jobs:
47
49
  with:
48
50
  token: ${{ secrets.CODECOV_TOKEN }}
49
51
  files: ./build/coverage.xml
50
- - name: publish
51
- if: ${{ matrix.python-version == '3.14' && github.event.head_commit.message == 'release' }}
52
- run: make publish
53
52
 
54
53
  image:
55
54
  if: github.ref == 'refs/heads/main'
@@ -23,6 +23,8 @@ jobs:
23
23
  password: ${{ github.token }}
24
24
  - name: install rops
25
25
  uses: quantmind/rops/.github/actions/setup-rops@main
26
+ env:
27
+ GITHUB_TOKEN: ${{ secrets.TOKEN_DEPLOYMENT }}
26
28
  - name: build amd64
27
29
  run: rops docker build ${{ inputs.image-name }}
28
30
  - name: push amd64
@@ -44,6 +46,8 @@ jobs:
44
46
  password: ${{ github.token }}
45
47
  - name: install rops
46
48
  uses: quantmind/rops/.github/actions/setup-rops@main
49
+ env:
50
+ GITHUB_TOKEN: ${{ secrets.TOKEN_DEPLOYMENT }}
47
51
  - name: build arm64
48
52
  run: rops docker build ${{ inputs.image-name }}
49
53
  - name: push arm64
@@ -64,5 +68,7 @@ jobs:
64
68
  password: ${{ github.token }}
65
69
  - name: install rops
66
70
  uses: quantmind/rops/.github/actions/setup-rops@main
71
+ env:
72
+ GITHUB_TOKEN: ${{ secrets.TOKEN_DEPLOYMENT }}
67
73
  - name: create manifest
68
74
  run: rops docker manifest ${{ inputs.image-name }}
@@ -0,0 +1,78 @@
1
+ name: release
2
+
3
+ # Triggered by `v*` tags. Builds and publishes the package to PyPI, then
4
+ # extracts the matching section from docs/release-notes.md and publishes it
5
+ # as the GitHub Release body. Re-runs idempotently update an existing
6
+ # release rather than failing.
7
+
8
+ on:
9
+ push:
10
+ tags:
11
+ - "v*"
12
+
13
+ permissions:
14
+ contents: write
15
+
16
+ jobs:
17
+ release:
18
+ runs-on: ubuntu-latest
19
+ env:
20
+ PYTHON_ENV: ci
21
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23
+ PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
24
+ FMP_API_KEY: ${{ secrets.FMP_API_KEY }}
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+
28
+ - name: install rops
29
+ uses: quantmind/rops/.github/actions/setup-rops@main
30
+ env:
31
+ GITHUB_TOKEN: ${{ secrets.TOKEN_DEPLOYMENT }}
32
+
33
+ - name: install taplo
34
+ run: rops tools update taplo
35
+
36
+ - name: Set up Python
37
+ uses: actions/setup-python@v5
38
+ with:
39
+ python-version: "3.14"
40
+
41
+ - name: Install uv
42
+ run: pip install -U pip uv
43
+
44
+ - name: Install dependencies
45
+ run: make install-dev
46
+
47
+ - name: run lint
48
+ run: make lint-check
49
+
50
+ - name: run tests
51
+ run: make tests
52
+
53
+ - name: publish to PyPI
54
+ run: make publish
55
+
56
+ - name: Extract release notes
57
+ run: |
58
+ TAG="${GITHUB_REF_NAME}"
59
+ awk -v tag="## ${TAG}" '
60
+ $0 == tag { in_section = 1; next }
61
+ /^## / && in_section { exit }
62
+ in_section { print }
63
+ ' docs/release-notes.md > /tmp/notes.md
64
+ if [ ! -s /tmp/notes.md ]; then
65
+ echo "No section '## ${TAG}' found in docs/release-notes.md" >&2
66
+ exit 1
67
+ fi
68
+ echo "--- extracted notes for ${TAG} ---"
69
+ cat /tmp/notes.md
70
+
71
+ - name: Publish GitHub Release
72
+ run: |
73
+ TAG="${GITHUB_REF_NAME}"
74
+ if gh release view "$TAG" >/dev/null 2>&1; then
75
+ gh release edit "$TAG" --notes-file /tmp/notes.md
76
+ else
77
+ gh release create "$TAG" --title "$TAG" --notes-file /tmp/notes.md
78
+ fi
@@ -26,6 +26,7 @@ build
26
26
  dist
27
27
  .venv
28
28
  .mypy_cache
29
+ .hypothesis
29
30
  .pytest_cache
30
31
  .ruff_cache
31
32
  .python-version
@@ -37,4 +38,5 @@ _build
37
38
 
38
39
  # builds
39
40
  app/docs
40
- docs/examples_output
41
+ docs/assets/examples
42
+ docs/examples/output
@@ -0,0 +1,5 @@
1
+ @readme.md
2
+ @.github/copilot-instructions.md
3
+ @.github/instructions/makefile.instructions.md
4
+ @.github/instructions/release.instructions.md
5
+ @.github/instructions/tutorial.instructions.md
@@ -5,53 +5,64 @@ help:
5
5
  @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'
6
6
  @echo ================================================================================
7
7
 
8
+ .PHONY: docs
9
+ docs: ## build documentation
10
+ @cp docs/index.md readme.md
11
+ @uv run ./dev/build-examples
12
+ @uv run mkdocs build
13
+
14
+ .PHONY: docs-bib
15
+ docs-bib: ## Regenerate docs bibliography
16
+ @uv run ./docs/bib2md.py
17
+
18
+ .PHONY: docs-examples
19
+ docs-examples: ## Regenerate docs examples
20
+ @uv run ./dev/build-examples
21
+
22
+ .PHONY: docs-serve
23
+ docs-serve: ## serve documentation
24
+ @uv run mkdocs serve --livereload --watch quantflow --watch docs
25
+
26
+ .PHONY: install-dev
27
+ install-dev: ## Install development dependencies
28
+ @./dev/install
8
29
 
9
30
  .PHONY: lint
10
31
  lint: ## Lint and fix
11
32
  @uv run ./dev/lint fix
12
33
 
13
-
14
34
  .PHONY: lint-check
15
35
  lint-check: ## Lint check only
16
36
  @uv run ./dev/lint
17
37
 
18
-
19
- .PHONY: install-dev
20
- install-dev: ## Install development dependencies
21
- @./dev/install
22
-
23
38
  .PHONY: marimo
24
39
  marimo: ## Run marimo for editing notebooks
25
40
  @./dev/marimo edit
26
41
 
27
- .PHONY: docs-png
28
- docs-png: ## Regenerate PNG assets in docs/assets/ (requires Chrome via kaleido)
29
- @for f in docs/examples_png/*.py; do uv run python $$f; done
30
-
31
- .PHONY: docs
32
- docs: ## build documentation
33
- @cp docs/index.md readme.md
34
- @uv run ./dev/build-examples
35
- @uv run mkdocs build
36
-
37
- .PHONY: docs-serve
38
- docs-serve: ## serve documentation
39
- @uv run mkdocs serve --livereload --watch quantflow --watch docs
42
+ .PHONY: outdated
43
+ outdated: ## Show outdated packages
44
+ uv tree --outdated
40
45
 
41
46
  .PHONY: publish
42
47
  publish: ## Release to pypi
43
48
  @uv build
44
49
  @uv publish --token $(PYPI_TOKEN)
45
50
 
51
+ .PHONY: release
52
+ release: ## Tag current version (from pyproject.toml) and push
53
+ $(eval VERSION := $(shell grep '^version' pyproject.toml | head -1 | sed 's/version = "\(.*\)"/\1/'))
54
+ @read -p "Tagging with v$(VERSION), are you sure? [Y/n] " ans; \
55
+ ans=$${ans:-Y}; \
56
+ if [ "$$ans" = "Y" ] || [ "$$ans" = "y" ]; then \
57
+ git tag -a v$(VERSION) -m "v$(VERSION)" && git push origin v$(VERSION); \
58
+ else \
59
+ echo "Aborted."; \
60
+ fi
61
+
46
62
  .PHONY: tests
47
63
  tests: ## Unit tests
48
64
  @./dev/test
49
65
 
50
-
51
- .PHONY: outdated
52
- outdated: ## Show outdated packages
53
- uv tree --outdated
54
-
55
66
  .PHONY: upgrade
56
67
  upgrade: ## Upgrade dependencies
57
68
  uv lock --upgrade
@@ -1,13 +1,28 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quantflow
3
- Version: 0.7.0
3
+ Version: 0.9.0
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
7
- Project-URL: Documentation, https://quantmind.github.io/quantflow/
7
+ Project-URL: Documentation, https://quantflow.quantmind.com
8
+ Project-URL: Issues, https://github.com/quantmind/quantflow/issues
8
9
  Author-email: Luca Sbardella <luca@quantmind.com>
9
10
  License-Expression: BSD-3-Clause
10
11
  License-File: LICENSE
12
+ Keywords: finance,options,pricing,quantitative,stochastic,volatility
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Financial and Insurance Industry
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: BSD License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Office/Business :: Financial
24
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
25
+ Classifier: Typing :: Typed
11
26
  Requires-Python: <3.15,>=3.11
12
27
  Requires-Dist: ccy>=2.0.0
13
28
  Requires-Dist: polars[pandas,pyarrow]>=1.11.0
@@ -54,7 +69,7 @@ Provides-Extra: ml
54
69
  Requires-Dist: torch>=2.10.0; extra == 'ml'
55
70
  Description-Content-Type: text/markdown
56
71
 
57
- # <a href="https://quantmind.github.io/quantflow"><img src="https://raw.githubusercontent.com/quantmind/quantflow/main/docs/assets/quantflow-light.svg" width=300 /></a>
72
+ # <a href="https://quantmind.github.io/quantflow"><img src="https://raw.githubusercontent.com/quantmind/quantflow/main/docs/assets/logos/quantflow-lockup.svg" width=300 /></a>
58
73
 
59
74
  [![PyPI version](https://badge.fury.io/py/quantflow.svg)](https://badge.fury.io/py/quantflow)
60
75
  [![Python versions](https://img.shields.io/pypi/pyversions/quantflow.svg)](https://pypi.org/project/quantflow)
@@ -85,67 +100,21 @@ pip install quantflow
85
100
 
86
101
  * `data` — data retrieval: `pip install quantflow[data]`
87
102
  * `ai` — MCP server for AI clients: `pip install quantflow[ai,data]`
103
+ * `ml` — training the Deep Implied Volatility model: `pip install quantflow[ml]`
88
104
 
89
105
  ## MCP Server
90
106
 
91
- Quantflow exposes its data tools as an [MCP](https://modelcontextprotocol.io) server, allowing AI clients such as Claude to query market data, crypto volatility surfaces, and economic indicators directly.
107
+ Quantflow exposes its data tools as an [MCP](https://modelcontextprotocol.io) server for AI clients.
108
+ See [MCP Server](https://quantflow.quantmind.com/mcp/) for setup and available tools.
92
109
 
93
- Install with the `ai` and `data` extras:
110
+ ## License
94
111
 
95
- ```bash
96
- pip install quantflow[ai,data]
97
- ```
98
-
99
- ### API keys
100
-
101
- Store your API keys in `~/.quantflow/.vault`:
102
-
103
- ```
104
- fmp=your-fmp-key
105
- fred=your-fred-key
106
- ```
112
+ Released under the [BSD 3-Clause License](https://github.com/quantmind/quantflow/blob/main/LICENSE).
107
113
 
108
- Or let the AI manage them for you via the `vault_add` tool once connected.
114
+ ## Citation
109
115
 
110
- ### Claude Code
116
+ If you use Quantflow in your research, please cite it using the metadata in [CITATION.cff](https://github.com/quantmind/quantflow/blob/main/CITATION.cff).
111
117
 
112
- ```bash
113
- claude mcp add quantflow -- uv run qf-mcp
114
- ```
115
-
116
- ### Claude Desktop
117
-
118
- Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
119
-
120
- ```json
121
- {
122
- "mcpServers": {
123
- "quantflow": {
124
- "command": "uv",
125
- "args": ["run", "qf-mcp"]
126
- }
127
- }
128
- }
129
- ```
118
+ ## License
130
119
 
131
- ### Available tools
132
-
133
- | Tool | Description |
134
- |---|---|
135
- | `vault_keys` | List stored API keys |
136
- | `vault_add` | Add or update an API key |
137
- | `vault_delete` | Delete an API key |
138
- | `stock_indices` | List stock market indices |
139
- | `stock_search` | Search companies by name or symbol |
140
- | `stock_profile` | Get company profile |
141
- | `stock_prices` | Get OHLC price history |
142
- | `sector_performance` | Sector performance and PE ratios |
143
- | `crypto_instruments` | List Deribit instruments |
144
- | `crypto_historical_volatility` | Historical volatility from Deribit |
145
- | `crypto_term_structure` | Volatility term structure |
146
- | `crypto_implied_volatility` | Implied volatility surface |
147
- | `crypto_prices` | Crypto OHLC price history |
148
- | `ascii_chart` | ASCII chart for any stock or crypto symbol |
149
- | `fred_subcategories` | Browse FRED categories |
150
- | `fred_series` | List series in a FRED category |
151
- | `fred_data` | Fetch FRED observations |
120
+ Released under the [BSD 3-Clause License](https://github.com/quantmind/quantflow/blob/main/LICENSE).
@@ -2,17 +2,19 @@ import os
2
2
  from pathlib import Path
3
3
 
4
4
  import marimo
5
- from fastapi import FastAPI, APIRouter
5
+ from fastapi import APIRouter, FastAPI
6
6
  from fastapi.staticfiles import StaticFiles
7
7
 
8
- APP_PATH = Path(__file__).parent
8
+ from app.utils.paths import APP_PATH, head_snippet
9
+
9
10
  PORT = int(os.environ.get("MICRO_SERVICE_PORT", "8001"))
10
11
  status_router = APIRouter()
11
12
 
12
13
 
13
14
  def crate_app() -> FastAPI:
14
15
  # Create a marimo asgi app
15
- server = marimo.create_asgi_app(include_code=True)
16
+ html_head = head_snippet(APP_PATH / "docs")
17
+ server = marimo.create_asgi_app(include_code=True, html_head=html_head)
16
18
  for path in APP_PATH.glob("*.py"):
17
19
  if path.name.startswith("_"):
18
20
  continue
@@ -25,6 +27,7 @@ def crate_app() -> FastAPI:
25
27
  app.mount("/", StaticFiles(directory=APP_PATH / "docs", html=True), name="static")
26
28
  return app
27
29
 
30
+
28
31
  @status_router.get("/status")
29
32
  async def service_status() -> dict:
30
33
  return {"status": "ok"}