optPricing 2.5.0__tar.gz → 2.7.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 (243) hide show
  1. optpricing-2.7.0/CHANGELOG.md +133 -0
  2. {optpricing-2.5.0/src/optpricing.egg-info → optpricing-2.7.0}/PKG-INFO +3 -2
  3. {optpricing-2.5.0 → optpricing-2.7.0}/benchmarks/run_benchmarks.py +20 -0
  4. {optpricing-2.5.0 → optpricing-2.7.0}/pyproject.toml +3 -1
  5. optpricing-2.7.0/src/optpricing/calibration/__init__.py +54 -0
  6. optpricing-2.7.0/src/optpricing/calibration/calibrator.py +480 -0
  7. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/calibration/fit_jump_parameters.py +11 -7
  8. optpricing-2.7.0/src/optpricing/calibration/fit_market_params.py +271 -0
  9. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/calibration/iv_surface.py +17 -5
  10. optpricing-2.7.0/src/optpricing/calibration/market_filters.py +307 -0
  11. optpricing-2.7.0/src/optpricing/calibration/metrics.py +181 -0
  12. optpricing-2.7.0/src/optpricing/calibration/vectorized_bsm_iv.py +170 -0
  13. optpricing-2.7.0/src/optpricing/calibration/vectorized_pricer.py +313 -0
  14. optpricing-2.7.0/src/optpricing/cli/commands/backtest.py +133 -0
  15. optpricing-2.7.0/src/optpricing/cli/commands/calibrate.py +265 -0
  16. optpricing-2.7.0/src/optpricing/cli/commands/data.py +243 -0
  17. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/cli/commands/price.py +10 -16
  18. optpricing-2.7.0/src/optpricing/cli/commands/tune.py +129 -0
  19. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/cli/main.py +8 -2
  20. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/config.py +4 -0
  21. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/pages/2_Calibration_and_IV.py +63 -12
  22. optpricing-2.7.0/src/optpricing/dashboard/service.py +192 -0
  23. optpricing-2.7.0/src/optpricing/data/__init__.py +53 -0
  24. optpricing-2.7.0/src/optpricing/data/historical_manager.py +301 -0
  25. optpricing-2.7.0/src/optpricing/data/market_data_manager.py +636 -0
  26. optpricing-2.7.0/src/optpricing/data/stream.py +314 -0
  27. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/base/base_model.py +4 -0
  28. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/bates.py +7 -1
  29. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/bsm.py +34 -21
  30. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/cev.py +121 -4
  31. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/merton_jump.py +55 -30
  32. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/sabr.py +25 -15
  33. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/american_monte_carlo.py +73 -51
  34. optpricing-2.7.0/src/optpricing/techniques/base/random_utils.py +149 -0
  35. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/fft.py +25 -4
  36. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/integration.py +76 -27
  37. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/kernels/__init__.py +8 -0
  38. optpricing-2.7.0/src/optpricing/techniques/kernels/american_mc_kernels.py +143 -0
  39. optpricing-2.7.0/src/optpricing/techniques/kernels/mc_kernels.py +470 -0
  40. optpricing-2.7.0/src/optpricing/techniques/kernels/path_kernels.py +425 -0
  41. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/monte_carlo.py +75 -63
  42. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/pde.py +82 -27
  43. optpricing-2.7.0/src/optpricing/workflows/__init__.py +29 -0
  44. optpricing-2.7.0/src/optpricing/workflows/backtest_workflow.py +299 -0
  45. optpricing-2.7.0/src/optpricing/workflows/configs/__init__.py +127 -0
  46. optpricing-2.7.0/src/optpricing/workflows/configs/bsm_config.py +13 -0
  47. optpricing-2.7.0/src/optpricing/workflows/configs/cev_config.py +23 -0
  48. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/workflows/configs/cgmy_config.py +2 -2
  49. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/workflows/configs/heston_config.py +7 -3
  50. optpricing-2.7.0/src/optpricing/workflows/configs/kou_config.py +29 -0
  51. optpricing-2.7.0/src/optpricing/workflows/configs/merton_config.py +29 -0
  52. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/workflows/configs/sabr_jump_config.py +4 -2
  53. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/workflows/configs/vg_config.py +1 -1
  54. optpricing-2.7.0/src/optpricing/workflows/daily_workflow.py +330 -0
  55. optpricing-2.7.0/src/optpricing/workflows/tuning.py +269 -0
  56. {optpricing-2.5.0 → optpricing-2.7.0/src/optpricing.egg-info}/PKG-INFO +3 -2
  57. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing.egg-info/SOURCES.txt +15 -1
  58. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing.egg-info/requires.txt +2 -1
  59. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing.egg-info/scm_file_list.json +26 -0
  60. optpricing-2.7.0/src/optpricing.egg-info/scm_version.json +8 -0
  61. optpricing-2.7.0/tests/calibration/test_calibrator.py +191 -0
  62. optpricing-2.7.0/tests/calibration/test_fit_market_params.py +134 -0
  63. optpricing-2.7.0/tests/calibration/test_market_filters.py +132 -0
  64. optpricing-2.7.0/tests/calibration/test_metrics.py +68 -0
  65. optpricing-2.7.0/tests/calibration/test_vectorized_bsm_iv.py +116 -0
  66. optpricing-2.7.0/tests/calibration/test_vectorized_pricer.py +186 -0
  67. optpricing-2.7.0/tests/cli/commands/test_backtest.py +57 -0
  68. optpricing-2.7.0/tests/cli/commands/test_calibrate.py +120 -0
  69. optpricing-2.7.0/tests/cli/commands/test_data.py +129 -0
  70. optpricing-2.7.0/tests/cli/commands/test_price.py +103 -0
  71. optpricing-2.7.0/tests/cli/commands/test_tune.py +49 -0
  72. optpricing-2.7.0/tests/conftest.py +101 -0
  73. {optpricing-2.5.0 → optpricing-2.7.0}/tests/correctness/test_mc_regressions.py +74 -34
  74. optpricing-2.7.0/tests/dashboard/test_pages.py +78 -0
  75. optpricing-2.7.0/tests/dashboard/test_service.py +166 -0
  76. optpricing-2.7.0/tests/data/test_historical_manager.py +120 -0
  77. optpricing-2.7.0/tests/data/test_market_data_manager.py +368 -0
  78. optpricing-2.7.0/tests/data/test_stream.py +155 -0
  79. optpricing-2.7.0/tests/models/test_vectorized_closed_forms.py +101 -0
  80. optpricing-2.7.0/tests/techniques/kernels/test_mc_kernels.py +178 -0
  81. optpricing-2.7.0/tests/techniques/kernels/test_path_kernels.py +93 -0
  82. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_american_monte_carlo.py +5 -2
  83. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_monte_carlo.py +14 -4
  84. optpricing-2.7.0/tests/workflows/test_backtest_workflow.py +125 -0
  85. optpricing-2.7.0/tests/workflows/test_configs.py +74 -0
  86. optpricing-2.7.0/tests/workflows/test_daily_workflow.py +179 -0
  87. optpricing-2.7.0/tests/workflows/test_tuning.py +104 -0
  88. optpricing-2.5.0/CHANGELOG.md +0 -50
  89. optpricing-2.5.0/src/optpricing/calibration/__init__.py +0 -28
  90. optpricing-2.5.0/src/optpricing/calibration/calibrator.py +0 -149
  91. optpricing-2.5.0/src/optpricing/calibration/fit_market_params.py +0 -120
  92. optpricing-2.5.0/src/optpricing/calibration/vectorized_bsm_iv.py +0 -93
  93. optpricing-2.5.0/src/optpricing/calibration/vectorized_pricer.py +0 -88
  94. optpricing-2.5.0/src/optpricing/cli/commands/backtest.py +0 -46
  95. optpricing-2.5.0/src/optpricing/cli/commands/calibrate.py +0 -145
  96. optpricing-2.5.0/src/optpricing/cli/commands/data.py +0 -165
  97. optpricing-2.5.0/src/optpricing/dashboard/service.py +0 -103
  98. optpricing-2.5.0/src/optpricing/data/__init__.py +0 -28
  99. optpricing-2.5.0/src/optpricing/data/historical_manager.py +0 -91
  100. optpricing-2.5.0/src/optpricing/data/market_data_manager.py +0 -200
  101. optpricing-2.5.0/src/optpricing/techniques/base/random_utils.py +0 -31
  102. optpricing-2.5.0/src/optpricing/techniques/kernels/american_mc_kernels.py +0 -85
  103. optpricing-2.5.0/src/optpricing/techniques/kernels/mc_kernels.py +0 -367
  104. optpricing-2.5.0/src/optpricing/techniques/kernels/path_kernels.py +0 -334
  105. optpricing-2.5.0/src/optpricing/workflows/__init__.py +0 -14
  106. optpricing-2.5.0/src/optpricing/workflows/backtest_workflow.py +0 -128
  107. optpricing-2.5.0/src/optpricing/workflows/configs/__init__.py +0 -53
  108. optpricing-2.5.0/src/optpricing/workflows/configs/bsm_config.py +0 -10
  109. optpricing-2.5.0/src/optpricing/workflows/configs/cev_config.py +0 -16
  110. optpricing-2.5.0/src/optpricing/workflows/configs/kou_config.py +0 -20
  111. optpricing-2.5.0/src/optpricing/workflows/configs/merton_config.py +0 -12
  112. optpricing-2.5.0/src/optpricing/workflows/daily_workflow.py +0 -217
  113. optpricing-2.5.0/src/optpricing.egg-info/scm_version.json +0 -8
  114. optpricing-2.5.0/tests/calibration/test_calibrator.py +0 -99
  115. optpricing-2.5.0/tests/calibration/test_fit_market_params.py +0 -79
  116. optpricing-2.5.0/tests/calibration/test_vectorized_bsm_iv.py +0 -47
  117. optpricing-2.5.0/tests/calibration/test_vectorized_pricer.py +0 -75
  118. optpricing-2.5.0/tests/cli/commands/test_backtest.py +0 -20
  119. optpricing-2.5.0/tests/cli/commands/test_calibrate.py +0 -39
  120. optpricing-2.5.0/tests/cli/commands/test_data.py +0 -53
  121. optpricing-2.5.0/tests/cli/commands/test_price.py +0 -60
  122. optpricing-2.5.0/tests/dashboard/test_service.py +0 -114
  123. optpricing-2.5.0/tests/data/test_historical_manager.py +0 -58
  124. optpricing-2.5.0/tests/data/test_market_data_manager.py +0 -193
  125. optpricing-2.5.0/tests/techniques/kernels/test_mc_kernels.py +0 -479
  126. optpricing-2.5.0/tests/techniques/kernels/test_path_kernels.py +0 -289
  127. optpricing-2.5.0/tests/workflows/test_backtest_workflow.py +0 -73
  128. optpricing-2.5.0/tests/workflows/test_daily_workflow.py +0 -76
  129. {optpricing-2.5.0 → optpricing-2.7.0}/LICENSE +0 -0
  130. {optpricing-2.5.0 → optpricing-2.7.0}/MANIFEST.in +0 -0
  131. {optpricing-2.5.0 → optpricing-2.7.0}/README.md +0 -0
  132. {optpricing-2.5.0 → optpricing-2.7.0}/setup.cfg +0 -0
  133. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/__init__.py +0 -0
  134. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/atoms/__init__.py +0 -0
  135. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/atoms/bond.py +0 -0
  136. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/atoms/option.py +0 -0
  137. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/atoms/rate.py +0 -0
  138. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/atoms/stock.py +0 -0
  139. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/calibration/technique_selector.py +0 -0
  140. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/calibration/vectorized_integration_iv.py +0 -0
  141. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/cli/__init__.py +0 -0
  142. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/cli/commands/__init__.py +0 -0
  143. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/cli/commands/dashboard.py +0 -0
  144. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/cli/commands/demo.py +0 -0
  145. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/cli/commands/tools.py +0 -0
  146. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/Home.py +0 -0
  147. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/__init__.py +0 -0
  148. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/pages/1_Pricer_and_Greeks.py +0 -0
  149. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/pages/3_Market_Analytics.py +0 -0
  150. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/pages/4_Model_Fitting.py +0 -0
  151. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/pages/5_Term_Structure.py +0 -0
  152. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/pages/__init__.py +0 -0
  153. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/plots.py +0 -0
  154. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/dashboard/widgets.py +0 -0
  155. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/__init__.py +0 -0
  156. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/base/__init__.py +0 -0
  157. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/base/cf_sampler.py +0 -0
  158. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/base/validators.py +0 -0
  159. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/blacks_approx.py +0 -0
  160. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/cgmy.py +0 -0
  161. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/cir.py +0 -0
  162. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/dupire_local.py +0 -0
  163. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/heston.py +0 -0
  164. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/hyperbolic.py +0 -0
  165. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/kou.py +0 -0
  166. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/nig.py +0 -0
  167. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/perpetual_put.py +0 -0
  168. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/sabr_jump.py +0 -0
  169. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/vasicek.py +0 -0
  170. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/models/vg.py +0 -0
  171. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/parity/__init__.py +0 -0
  172. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/parity/implied_rate.py +0 -0
  173. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/parity/parity_model.py +0 -0
  174. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/__init__.py +0 -0
  175. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/base/__init__.py +0 -0
  176. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/base/base_technique.py +0 -0
  177. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/base/greek_mixin.py +0 -0
  178. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/base/iv_mixin.py +0 -0
  179. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/base/lattice_technique.py +0 -0
  180. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/base/pricing_result.py +0 -0
  181. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/closed_form.py +0 -0
  182. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/crr.py +0 -0
  183. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/kernels/lattice_kernels.py +0 -0
  184. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/leisen_reimer.py +0 -0
  185. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/techniques/topm.py +0 -0
  186. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/workflows/configs/bates_config.py +0 -0
  187. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/workflows/configs/hyperbolic_config.py +0 -0
  188. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/workflows/configs/nig_config.py +0 -0
  189. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing/workflows/configs/sabr_config.py +0 -0
  190. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing.egg-info/dependency_links.txt +0 -0
  191. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing.egg-info/entry_points.txt +0 -0
  192. {optpricing-2.5.0 → optpricing-2.7.0}/src/optpricing.egg-info/top_level.txt +0 -0
  193. {optpricing-2.5.0 → optpricing-2.7.0}/tests/atoms/test_bond.py +0 -0
  194. {optpricing-2.5.0 → optpricing-2.7.0}/tests/atoms/test_option.py +0 -0
  195. {optpricing-2.5.0 → optpricing-2.7.0}/tests/atoms/test_rate.py +0 -0
  196. {optpricing-2.5.0 → optpricing-2.7.0}/tests/atoms/test_stock.py +0 -0
  197. {optpricing-2.5.0 → optpricing-2.7.0}/tests/calibration/test_fit_jump_parameters.py +0 -0
  198. {optpricing-2.5.0 → optpricing-2.7.0}/tests/calibration/test_iv_surface.py +0 -0
  199. {optpricing-2.5.0 → optpricing-2.7.0}/tests/calibration/test_technique_selector.py +0 -0
  200. {optpricing-2.5.0 → optpricing-2.7.0}/tests/calibration/test_vectorized_integration_iv.py +0 -0
  201. {optpricing-2.5.0 → optpricing-2.7.0}/tests/cli/commands/test_tools.py +0 -0
  202. {optpricing-2.5.0 → optpricing-2.7.0}/tests/cli/test_main.py +0 -0
  203. {optpricing-2.5.0 → optpricing-2.7.0}/tests/correctness/__init__.py +0 -0
  204. {optpricing-2.5.0 → optpricing-2.7.0}/tests/correctness/_helpers.py +0 -0
  205. {optpricing-2.5.0 → optpricing-2.7.0}/tests/correctness/conftest.py +0 -0
  206. {optpricing-2.5.0 → optpricing-2.7.0}/tests/correctness/test_invariants.py +0 -0
  207. {optpricing-2.5.0 → optpricing-2.7.0}/tests/correctness/test_reference_values.py +0 -0
  208. {optpricing-2.5.0 → optpricing-2.7.0}/tests/dashboard/test_plots.py +0 -0
  209. {optpricing-2.5.0 → optpricing-2.7.0}/tests/dashboard/test_widgets.py +0 -0
  210. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/base/test_base_model.py +0 -0
  211. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/base/test_validators.py +0 -0
  212. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_bates.py +0 -0
  213. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_blacks_approx.py +0 -0
  214. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_bsm.py +0 -0
  215. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_cev.py +0 -0
  216. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_cgmy.py +0 -0
  217. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_cir.py +0 -0
  218. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_dupire_local.py +0 -0
  219. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_heston.py +0 -0
  220. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_hyperbolic.py +0 -0
  221. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_kou.py +0 -0
  222. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_merton_jump.py +0 -0
  223. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_nig.py +0 -0
  224. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_perpetual_put.py +0 -0
  225. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_sabr.py +0 -0
  226. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_sabr_jump.py +0 -0
  227. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_vasicek.py +0 -0
  228. {optpricing-2.5.0 → optpricing-2.7.0}/tests/models/test_vg.py +0 -0
  229. {optpricing-2.5.0 → optpricing-2.7.0}/tests/parity/test_implied_rate.py +0 -0
  230. {optpricing-2.5.0 → optpricing-2.7.0}/tests/parity/test_parity_model.py +0 -0
  231. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/base/test_greek_mixin.py +0 -0
  232. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/base/test_iv_mixin.py +0 -0
  233. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/base/test_pricing_result.py +0 -0
  234. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/base/test_random_utils.py +0 -0
  235. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/kernels/test_lattice_kernels.py +0 -0
  236. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_closed_form.py +0 -0
  237. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_crr.py +0 -0
  238. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_fft.py +0 -0
  239. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_integration.py +0 -0
  240. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_leisen_reimer.py +0 -0
  241. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_pde.py +0 -0
  242. {optpricing-2.5.0 → optpricing-2.7.0}/tests/techniques/test_topm.py +0 -0
  243. {optpricing-2.5.0 → optpricing-2.7.0}/tests/test_config.py +0 -0
@@ -0,0 +1,133 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions come from git tags
5
+ (`vX.Y.Z`) via setuptools_scm.
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Workflows (calibration, backtesting, data)
10
+
11
+ - **Calibration rebuilt** (`Calibrator.fit` keeps its signature). Residuals are taken in Black-Scholes
12
+ implied-volatility space (`objective="iv"`, price space optional) with inverse bid-ask-spread weights
13
+ (`"vega"`/`"none"` optional); parameters are optimised in a unit cube (`log_scale` for wide ranges) with
14
+ L-BFGS-B from several starting points (recipe guess, warm start from the previous day, Latin-hypercube
15
+ samples); invalid parameter sets are penalised instead of raising; optional soft Feller penalty; `logging`
16
+ replaces the per-evaluation prints; `Calibrator.result` (`CalibrationResult`) carries loss, IV/price RMSE,
17
+ evaluation counts and per-start records.
18
+ - New `LiquidityFilter` / `filter_options` (OTM options with a bid, spread ≤ 25 %, open interest, 7 days–2 years,
19
+ forward moneyness 0.7–1.3, solvable implied vol) and `CalibrationSettings`; fit metrics (`evaluate_model`,
20
+ `residual_table`, `bucket_metrics`) by maturity and moneyness bucket.
21
+ - **Every model with a closed form or characteristic function is calibratable** (BSM, Merton, Heston, Bates,
22
+ SABR, CEV, Kou, NIG, VG, CGMY, Hyperbolic); SABR-with-jumps via Monte Carlo behind `--allow-mc`.
23
+ `price_options_vectorized` dispatches to vectorised closed forms (BSM, Merton, SABR, **CEV**), the
24
+ Gauss-Legendre characteristic-function route or Monte Carlo with common random numbers; `ChainLayout` caches
25
+ the strike groups and Fourier kernels for repeated pricing (Heston objective 13 → 4 ms on a 2,700-option chain).
26
+ - `CEVModel.price_closed_form`: Cox (1975)/Schroder (1989) noncentral-χ² formula, matching the Hull reference
27
+ values and QuantLib's `AnalyticCEVEngine` to 1e-9 (CEV previously had no closed form).
28
+ - `BSMIVSolver`: safeguarded Newton with bracket tracking and bisection fallback, NaN for prices outside the
29
+ no-arbitrage band (deep ITM/OTM and short maturities used to return garbage), optional initial guess.
30
+ - **Snapshot schema v2**: `ticker`, `snapshot_date`, `as_of`, `risk_free_rate` (13-week T-bill `^IRX`,
31
+ continuously compounded) and `dividend_yield` (implied from put-call parity near the money, given the rate)
32
+ are stored with every chain; v1 files are upgraded on load from the stored `^IRX` history
33
+ (`optpricing data download --rates`). Workflows no longer call the network.
34
+ - Historical files (v2) store adjusted close, dividends and log returns; `trailing_dividend_yield`,
35
+ `load_risk_free_rate`, `get_live_risk_free_rate` added.
36
+ - `BacktestWorkflow` is a proper walk-forward test: ascending dates, calibrate on *t*, evaluate on *t+1* with
37
+ that day's market parameters, out-of-sample IV/price RMSE, bucket metrics, `BSM-ATM` and stale-parameter
38
+ baselines, warm starts; CSV + bucket CSV + JSON summary.
39
+ - New per-ticker auto-tuning (`optpricing tune`, `workflows.tune_ticker`): walk-forward cross-validation over
40
+ candidate settings, model leaderboard, cache in `artifacts/tuning/{TICKER}.json` used by `calibrate --auto`,
41
+ `backtest --auto` and the dashboard.
42
+ - CLI: `calibrate --model all|<names> [--auto] [--allow-mc] [--objective] [--n-starts]` with a leaderboard
43
+ table and CSV, `backtest --model all`, new `tune`, `data download --rates`, `data snapshot --compact
44
+ --only-fresh`, new `data stream` (free `yfinance.WebSocket` quotes → parquet, option contracts included).
45
+ Model names are case-insensitive with aliases (`Variance Gamma` → `VG`).
46
+ - Scheduled GitHub Action (`snapshot.yml`) captures compact liquid-only chains for `snapshot_tickers` every
47
+ trading day (~25 KB per ticker) and commits them.
48
+ - Dashboard: calibration page offers every calibratable model, tuned settings, objective/start controls, a
49
+ leaderboard sorted by IV RMSE and error-by-bucket tables; `DashboardService` runs on the offline workflow.
50
+ Headless `AppTest` smoke tests cover every page.
51
+
52
+ ### Fixed (workflows)
53
+
54
+ - Backtest paired dates newest-first, calibrating on *t+1* and evaluating on *t* (look-ahead bias).
55
+ - Calibration workflows fetched today's dividend yield from yfinance for historical snapshots (and failed offline).
56
+ - Recipes were ignored when a model had `param_defs`; Bates fitted a non-existent `sigma`; Kou's `frozen` was a
57
+ list and crashed; Merton froze all four parameters from history and fitted nothing; Heston started from a
58
+ Feller-violating guess; the VG recipe key (`"Variance Gamma"`) did not match the dashboard's `"VG"`.
59
+ - Implied dividend yields: inferring both `r` and `q` from the strike slope of `C − P` is biased by the early
60
+ exercise premium of American puts (real SPY chains implied r ≈ 0 and q ≈ −3 %); the rate now comes from the
61
+ T-bill quote and only near-the-money pairs are used for `q`.
62
+ - yfinance 1.x: `fast_info["last_price"]` → `lastPrice` (every live fetch triggered a second `history()` call);
63
+ `dividendYield` is reported in percent since 0.2.5x (unit detection added); duplicate contracts dropped.
64
+ - Heston characteristic function at `u = −i` is degenerate when ρξ > κ; the chain pricer falls back to the
65
+ analytic forward there and silences the resulting warnings during calibration.
66
+ - `calibrate` printed the parameters at every objective evaluation.
67
+ - `pyarrow` (the parquet engine every snapshot needs) was only installed through the `ui` extra; it is now a
68
+ runtime dependency (`pyarrow>=22`, the first release with Python 3.14 wheels).
69
+
70
+ ### Performance
71
+
72
+ - Monte Carlo engine rebuilt: the numba kernels draw their own random numbers from per-chunk
73
+ `numpy.random.Generator`s (spawned from one seed, fixed chunk size) and run concurrently on a thread pool
74
+ (`n_jobs`, `chunk_size` options; `OPTPRICING_MC_THREADS`). Results depend only on the seed and chunk size,
75
+ common-random-number Greeks are preserved, and jump sizes now come from the seeded stream. 100k-path
76
+ BSM 27.7 → 3.4 ms, Heston (Euler) 88.7 → 7.5 ms on 10 cores.
77
+ - Heston/Bates Monte Carlo defaults to Andersen's Quadratic-Exponential variance scheme with martingale
78
+ correction (`variance_scheme="qe"`; `"euler"` keeps full truncation). 20 QE steps are more accurate than
79
+ 252 Euler steps; on long-dated, high vol-of-vol parameters Euler was off by several price units.
80
+ - Closed forms use `scipy.special.ndtr` (BSM price 28 → 2 µs); the Merton series is vectorised with log-space
81
+ Poisson weights (2.7 ms → 14 µs, no overflow past 170 terms).
82
+ - `IntegrationTechnique` evaluates the Gil–Pelaez integrals on a cached composite Gauss–Legendre rule
83
+ (`method="gauss"`, 0.69 → 0.07 ms; `method="quad"` keeps the adaptive rule); the calibration chain pricer
84
+ uses the same rule (400 options 19.5 → 1.7 ms). `FFTTechnique` interpolates cubically and defaults to
85
+ `eta=0.125` (ATM error 5e-4 → 1e-6 at the same cost).
86
+ - Longstaff–Schwartz: parallel power-sum regression on moneyness, time-major path matrices
87
+ (20k paths 32 → 13 ms); Crank–Nicolson PDE marches in numba with the two constant matrices factorised once
88
+ (200×200 grid 2.3 → 0.3 ms).
89
+ - Kernel signatures changed: SDE kernels take `(gen, n_paths, n_steps, antithetic, ...)`, path kernels return
90
+ `(n_steps + 1, n_paths)` arrays, and `longstaff_schwartz_pricer` takes `n_threads`.
91
+
92
+ ### Changed
93
+
94
+ - Python 3.10 support dropped (end of life); supported versions are 3.11–3.14, with 3.15 tested as experimental.
95
+ - Dependency pins relaxed from `~=` to verified minimum versions (`numpy>=2.3.2`, `scipy>=1.16.1`, `pandas>=2.3.3`, `numba>=0.63`, `pyyaml>=6.0.3`, `typer>=0.15.3`, `yfinance>=0.2.63`). Current releases (numpy 2.5, pandas 3.1, numba 0.68, yfinance 1.x) are supported.
96
+ - Streamlit and Plotly moved to the optional `ui` extra: `pip install "optpricing[ui]"` for the dashboard.
97
+ - Development tooling moved from the `dev` extra to PEP 735 dependency groups (`uv sync`; `pip install -e . --group dev`).
98
+ - Package metadata uses a PEP 639 license expression; the source distribution no longer bundles `data/`, `artifacts/` or docs (24 MB → ~0.1 MB).
99
+ - CI rebuilt on uv: lint, Python 3.11–3.15 matrix, minimum-dependency-versions job, build/twine checks; docs and publish workflows split into build and deploy jobs with hash-pinned actions.
100
+
101
+ ### Removed
102
+
103
+ - Unused runtime dependencies `matplotlib`, `tabulate` and the explicit `click` pin (Click arrives via Typer).
104
+
105
+ ### Fixed
106
+
107
+ - `test_price_command` relied on a hard-coded maturity date that is now in the past.
108
+ - **European Monte Carlo for Heston, Bates, SABR and SABR-jump applied the spot/variance correlation twice** (once in `MonteCarloTechnique`, once in the kernels), biasing prices by up to 2 % at ρ = −0.7. Heston MC now agrees with QuantLib's analytic engine within Monte Carlo error.
109
+ - NIG exact sampler drew the inverse-Gaussian subordinator with shape 1 instead of (δT)²; prices were ~3 % low.
110
+ - CEV exact sampler used an incorrect noncentral-χ² parametrisation (terminal mean 100.6 for a forward of 105.1), ignored the dividend yield and the seeded generator, and divided by zero at r = 0. It now samples the absorbed squared-Bessel law exactly (Makarov & Glew 2010) and matches the Cox/Schroder closed form.
111
+ - CGMY: the Lévy exponent was singular at Y = 0 and Y = 1 (Γ(−Y) poles) and the only Monte Carlo path was guarded on Y = 1 while implementing the Y = 0 law. Both limits are closed-form now; other Y sample by characteristic-function inversion.
112
+ - Hyperbolic model: characteristic function was neither the Lévy-process law nor the horizon-T hyperbolic law (so the drift was not a martingale correction for T ≠ 1), and the sampler passed α, β where scipy expects αδ, βδ. It is now the hyperbolic Lévy motion (φₜ = φ₁ᵗ) with exact sampling at T = 1 and CF inversion otherwise.
113
+ - PDE (Crank–Nicolson) Greeks were read at the grid node below the spot (delta off by ≈ 0.02); the spot now sits on a node, boundary values track the time level (with the dividend discount), and a Rannacher start-up is used.
114
+ - Longstaff–Schwartz regressed on raw powers of S through an explicit inverse of XᵀX (ill-conditioned beyond degree 2) and swallowed failures with a bare `except`; it now uses moneyness-scaled regressors and least squares.
115
+ - SABR kernels could leave the spot negative after a large down-move (puts paid more than the strike); zero is absorbing for 0 < β < 1.
116
+ - Parameter validation now rejects parameter sets without a risk-neutral measure: Kou η₁ ≤ 1, VG θν + σ²ν/2 ≥ 1, NIG/Hyperbolic |β+1| ≥ α, CGMY M ≤ 1.
117
+ - `optpricing.config` no longer writes `config.yaml` and data directories at import time (previously into `site-packages/lib` for installed packages); the root is `$OPTPRICING_HOME` or the working directory and folders are created when first written to.
118
+ - Heston and Bates read `v0` from the model parameters when it is not passed as a pricing kwarg.
119
+ - Feller-condition messages are `UserWarning`s instead of prints; pandas 3 (`inplace`, `Timestamp.utcnow`) and `importlib.resources.path` deprecations removed; `fastmath` dropped from the numba kernels (≤ 5 % measured cost, bit-identical results).
120
+
121
+ - SABR is now the four-parameter model of Hagan et al. (2002) on the forward: `alpha` is the initial volatility and the new `nu` the volatility of volatility (previously `alpha` played both roles). The old three-parameter form is still accepted with a `DeprecationWarning` (`nu = alpha`). Monte Carlo simulates the forward dynamics (prices move by O((r−q)T(1−β)) relative to the old spot-with-drift kernel) and the SABR kernels' `alpha` argument is renamed `nu`.
122
+ - Heston and Bates default parameters now satisfy the Feller condition (`vol_of_vol` 0.5 → 0.3).
123
+
124
+ ### Added
125
+
126
+ - `SABRModel.implied_volatility` (Hagan's lognormal expansion, bit-identical to QuantLib's `sabrVolatility`), an optional `shift` parameter for shifted SABR, and a Black-76 closed form so `ClosedFormTechnique`, the CLI and calibration price SABR analytically.
127
+ - `benchmarks/run_benchmarks.py` with recorded before/after results, and a reference-value test suite (`tests/correctness/`) pinned to QuantLib 1.44 and textbook closed forms.
128
+
129
+ ## [2.0.0] - 2025-06-26
130
+
131
+ ### Added
132
+
133
+ - Shipped to PyPI `pyproject.toml`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: optpricing
3
- Version: 2.5.0
3
+ Version: 2.7.0
4
4
  Summary: A financial options pricing and analysis library.
5
5
  Author: Diljit Singh
6
6
  License-Expression: MIT
@@ -30,8 +30,9 @@ Requires-Dist: scipy>=1.16.1
30
30
  Requires-Dist: pandas>=2.3.3
31
31
  Requires-Dist: numba>=0.63
32
32
  Requires-Dist: pyyaml>=6.0.3
33
- Requires-Dist: typer>=0.15.3
33
+ Requires-Dist: typer>=0.16.0
34
34
  Requires-Dist: yfinance>=0.2.63
35
+ Requires-Dist: pyarrow>=22
35
36
  Provides-Extra: ui
36
37
  Requires-Dist: streamlit>=1.45.1; extra == "ui"
37
38
  Requires-Dist: plotly>=6.1.2; extra == "ui"
@@ -83,6 +83,22 @@ def _lsmc_bsm_20k() -> float:
83
83
  return amc.price(PUT, STOCK, BSM, RATE).price
84
84
 
85
85
 
86
+ def _heston_chain_400() -> float:
87
+ import pandas as pd
88
+
89
+ from optpricing.calibration.vectorized_pricer import price_options_vectorized
90
+
91
+ chain = pd.DataFrame(
92
+ [
93
+ {"strike": k, "maturity": t, "optionType": typ}
94
+ for t in (0.1, 0.25, 0.5, 1.0, 2.0)
95
+ for k in np.linspace(60, 150, 40)
96
+ for typ in ("call", "put")
97
+ ]
98
+ )
99
+ return float(price_options_vectorized(chain, STOCK, HESTON, RATE, v0=0.04).sum())
100
+
101
+
86
102
  CASES: dict[str, tuple[Callable[[], float], str]] = {
87
103
  "bsm_closed_form_x1000": (_bsm_closed_form, "1000 closed-form BSM prices"),
88
104
  "heston_fft": (_heston_fft, "Carr-Madan FFT, N=4096"),
@@ -91,6 +107,10 @@ CASES: dict[str, tuple[Callable[[], float], str]] = {
91
107
  "mc_bsm_100k": (_mc_bsm_100k, "100k paths x 100 steps, antithetic"),
92
108
  "mc_heston_100k": (_mc_heston_100k, "100k paths x 100 steps, antithetic"),
93
109
  "lsmc_bsm_20k": (_lsmc_bsm_20k, "Longstaff-Schwartz, 20k paths x 50 steps"),
110
+ "heston_chain_400": (
111
+ _heston_chain_400,
112
+ "vectorised chain pricer, 400 options x 5 maturities",
113
+ ),
94
114
  }
95
115
 
96
116
 
@@ -45,8 +45,10 @@ dependencies = [
45
45
  "pandas>=2.3.3",
46
46
  "numba>=0.63",
47
47
  "pyyaml>=6.0.3",
48
- "typer>=0.15.3",
48
+ "typer>=0.16.0",
49
49
  "yfinance>=0.2.63",
50
+ # Parquet engine for snapshots and recordings; 22.0.0 is the first release with cp314 wheels.
51
+ "pyarrow>=22",
50
52
  ]
51
53
 
52
54
  [project.optional-dependencies]
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ __doc__ = """
4
+ The `calibration` package provides tools for fitting financial models to
5
+ market data, estimating parameters from historical data, and calculating
6
+ implied volatility surfaces.
7
+ """
8
+
9
+ from .calibrator import CalibrationResult, Calibrator
10
+ from .fit_jump_parameters import fit_jump_params_from_history
11
+ from .fit_market_params import (
12
+ find_atm_options,
13
+ fit_rate_and_dividend,
14
+ implied_dividend_yield,
15
+ implied_forward_curve,
16
+ )
17
+ from .iv_surface import VolatilitySurface
18
+ from .market_filters import (
19
+ DEFAULT_SETTINGS,
20
+ CalibrationSettings,
21
+ LiquidityFilter,
22
+ annotate_chain,
23
+ filter_options,
24
+ )
25
+ from .metrics import bucket_metrics, evaluate_model, residual_table, summarize_residuals
26
+ from .technique_selector import select_fastest_technique
27
+ from .vectorized_bsm_iv import BSMIVSolver
28
+ from .vectorized_integration_iv import VectorizedIntegrationIVSolver
29
+ from .vectorized_pricer import price_options_vectorized, supports_vectorized_pricing
30
+
31
+ __all__ = [
32
+ "BSMIVSolver",
33
+ "CalibrationResult",
34
+ "CalibrationSettings",
35
+ "Calibrator",
36
+ "DEFAULT_SETTINGS",
37
+ "LiquidityFilter",
38
+ "VectorizedIntegrationIVSolver",
39
+ "VolatilitySurface",
40
+ "annotate_chain",
41
+ "bucket_metrics",
42
+ "evaluate_model",
43
+ "filter_options",
44
+ "fit_jump_params_from_history",
45
+ "fit_rate_and_dividend",
46
+ "find_atm_options",
47
+ "implied_dividend_yield",
48
+ "implied_forward_curve",
49
+ "price_options_vectorized",
50
+ "residual_table",
51
+ "select_fastest_technique",
52
+ "summarize_residuals",
53
+ "supports_vectorized_pricing",
54
+ ]