optPricing 2.3.4__tar.gz → 2.5.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 (460) hide show
  1. optpricing-2.5.0/CHANGELOG.md +50 -0
  2. optpricing-2.5.0/MANIFEST.in +11 -0
  3. {optpricing-2.3.4/src/optpricing.egg-info → optpricing-2.5.0}/PKG-INFO +37 -45
  4. {optpricing-2.3.4 → optpricing-2.5.0}/README.md +8 -7
  5. optpricing-2.5.0/benchmarks/run_benchmarks.py +164 -0
  6. optpricing-2.5.0/pyproject.toml +148 -0
  7. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/iv_surface.py +2 -2
  8. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/commands/dashboard.py +4 -2
  9. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/commands/price.py +1 -1
  10. optpricing-2.5.0/src/optpricing/config.py +66 -0
  11. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/data/historical_manager.py +1 -0
  12. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/data/market_data_manager.py +2 -2
  13. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/base/__init__.py +2 -0
  14. optpricing-2.5.0/src/optpricing/models/base/cf_sampler.py +110 -0
  15. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/bates.py +11 -4
  16. optpricing-2.5.0/src/optpricing/models/cev.py +145 -0
  17. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/cgmy.py +54 -31
  18. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/cir.py +6 -1
  19. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/heston.py +17 -7
  20. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/hyperbolic.py +51 -19
  21. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/kou.py +7 -0
  22. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/nig.py +15 -2
  23. optpricing-2.5.0/src/optpricing/models/sabr.py +290 -0
  24. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/sabr_jump.py +36 -3
  25. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/vg.py +7 -0
  26. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/american_monte_carlo.py +14 -4
  27. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/kernels/american_mc_kernels.py +16 -15
  28. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/kernels/mc_kernels.py +35 -27
  29. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/kernels/path_kernels.py +34 -24
  30. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/monte_carlo.py +22 -14
  31. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/pde.py +68 -23
  32. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/backtest_workflow.py +1 -0
  33. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/sabr_config.py +1 -0
  34. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/sabr_jump_config.py +2 -1
  35. {optpricing-2.3.4 → optpricing-2.5.0/src/optpricing.egg-info}/PKG-INFO +37 -45
  36. optpricing-2.5.0/src/optpricing.egg-info/SOURCES.txt +186 -0
  37. optpricing-2.5.0/src/optpricing.egg-info/requires.txt +11 -0
  38. optpricing-2.5.0/src/optpricing.egg-info/scm_file_list.json +448 -0
  39. optpricing-2.5.0/src/optpricing.egg-info/scm_version.json +8 -0
  40. {optpricing-2.3.4 → optpricing-2.5.0}/tests/cli/commands/test_price.py +5 -1
  41. optpricing-2.5.0/tests/correctness/__init__.py +0 -0
  42. optpricing-2.5.0/tests/correctness/_helpers.py +17 -0
  43. optpricing-2.5.0/tests/correctness/conftest.py +128 -0
  44. optpricing-2.5.0/tests/correctness/test_invariants.py +285 -0
  45. optpricing-2.5.0/tests/correctness/test_mc_regressions.py +344 -0
  46. optpricing-2.5.0/tests/correctness/test_reference_values.py +427 -0
  47. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_cgmy.py +35 -21
  48. optpricing-2.5.0/tests/models/test_sabr.py +138 -0
  49. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_sabr_jump.py +17 -5
  50. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/kernels/test_mc_kernels.py +12 -17
  51. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/kernels/test_path_kernels.py +7 -5
  52. optpricing-2.5.0/tests/test_config.py +70 -0
  53. optpricing-2.3.4/.coveragerc +0 -4
  54. optpricing-2.3.4/.github/ISSUE_TEMPLATE/bug_report.md +0 -34
  55. optpricing-2.3.4/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  56. optpricing-2.3.4/.github/workflows/ci.yml +0 -45
  57. optpricing-2.3.4/.github/workflows/pages.yml +0 -54
  58. optpricing-2.3.4/.github/workflows/publish.yml +0 -43
  59. optpricing-2.3.4/.gitignore +0 -31
  60. optpricing-2.3.4/.pre-commit-config.yaml +0 -17
  61. optpricing-2.3.4/CHANGELOG.md +0 -7
  62. optpricing-2.3.4/CODE_OF_CONDUCT.md +0 -128
  63. optpricing-2.3.4/CONTRIBUTING.md +0 -58
  64. optpricing-2.3.4/MANIFEST.in +0 -6
  65. optpricing-2.3.4/PULL_REQUEST_TEMPLATE.md +0 -23
  66. optpricing-2.3.4/SECURITY.md +0 -15
  67. optpricing-2.3.4/artifacts/backtest_logs/SPY_backtest_2025-06-17.csv +0 -3
  68. optpricing-2.3.4/artifacts/backtest_logs/SPY_backtest_2025-07-07.csv +0 -6
  69. optpricing-2.3.4/artifacts/backtest_logs/SPY_backtest_2025-07-09.csv +0 -8
  70. optpricing-2.3.4/artifacts/calibrated_params/SPY_BSM_2023-01-01.json +0 -8
  71. optpricing-2.3.4/artifacts/calibrated_params/SPY_BSM_2025-06-17.json +0 -3
  72. optpricing-2.3.4/artifacts/calibrated_params/SPY_BSM_2025-07-03.json +0 -8
  73. optpricing-2.3.4/artifacts/calibrated_params/SPY_BSM_2025-07-07.json +0 -8
  74. optpricing-2.3.4/artifacts/calibrated_params/SPY_BSM_2025-07-08.json +0 -8
  75. optpricing-2.3.4/artifacts/calibrated_params/SPY_BSM_2025-07-09.json +0 -8
  76. optpricing-2.3.4/artifacts/calibrated_params/SPY_Black-Scholes_2025-06-17.json +0 -3
  77. optpricing-2.3.4/artifacts/calibrated_params/SPY_Merton_2025-06-17.json +0 -7
  78. optpricing-2.3.4/artifacts/calibrated_params/SPY_Merton_2025-07-03.json +0 -11
  79. optpricing-2.3.4/artifacts/calibrated_params/SPY_Merton_2025-07-07.json +0 -11
  80. optpricing-2.3.4/artifacts/calibrated_params/SPY_Merton_2025-07-08.json +0 -11
  81. optpricing-2.3.4/artifacts/calibrated_params/SPY_Merton_2025-07-09.json +0 -11
  82. optpricing-2.3.4/artifacts/calibration_logs/SPY_evaluation_2025-06-16.csv +0 -3
  83. optpricing-2.3.4/codecov.yml +0 -7
  84. optpricing-2.3.4/config.yaml +0 -34
  85. optpricing-2.3.4/data/historical_data/AAPL_10y_returns.parquet +0 -0
  86. optpricing-2.3.4/data/historical_data/AMC_10y_returns.parquet +0 -0
  87. optpricing-2.3.4/data/historical_data/AMD_10y_returns.parquet +0 -0
  88. optpricing-2.3.4/data/historical_data/AMZN_10y_returns.parquet +0 -0
  89. optpricing-2.3.4/data/historical_data/BAC_10y_returns.parquet +0 -0
  90. optpricing-2.3.4/data/historical_data/BA_10y_returns.parquet +0 -0
  91. optpricing-2.3.4/data/historical_data/CAT_10y_returns.parquet +0 -0
  92. optpricing-2.3.4/data/historical_data/CVX_10y_returns.parquet +0 -0
  93. optpricing-2.3.4/data/historical_data/GME_10y_returns.parquet +0 -0
  94. optpricing-2.3.4/data/historical_data/GOOGL_10y_returns.parquet +0 -0
  95. optpricing-2.3.4/data/historical_data/GS_10y_returns.parquet +0 -0
  96. optpricing-2.3.4/data/historical_data/HD_10y_returns.parquet +0 -0
  97. optpricing-2.3.4/data/historical_data/JNJ_10y_returns.parquet +0 -0
  98. optpricing-2.3.4/data/historical_data/JPM_10y_returns.parquet +0 -0
  99. optpricing-2.3.4/data/historical_data/META_10y_returns.parquet +0 -0
  100. optpricing-2.3.4/data/historical_data/MSFT_10y_returns.parquet +0 -0
  101. optpricing-2.3.4/data/historical_data/NKE_10y_returns.parquet +0 -0
  102. optpricing-2.3.4/data/historical_data/NVDA_10y_returns.parquet +0 -0
  103. optpricing-2.3.4/data/historical_data/PFE_10y_returns.parquet +0 -0
  104. optpricing-2.3.4/data/historical_data/QQQ_10y_returns.parquet +0 -0
  105. optpricing-2.3.4/data/historical_data/SPY_10y_returns.parquet +0 -0
  106. optpricing-2.3.4/data/historical_data/SPY_5y_returns.parquet +0 -0
  107. optpricing-2.3.4/data/historical_data/TSLA_10y_returns.parquet +0 -0
  108. optpricing-2.3.4/data/historical_data/UNH_10y_returns.parquet +0 -0
  109. optpricing-2.3.4/data/historical_data/WMT_10y_returns.parquet +0 -0
  110. optpricing-2.3.4/data/historical_data/XOM_10y_returns.parquet +0 -0
  111. optpricing-2.3.4/data/market_data_snapshots/AAPL_2025-06-16.parquet +0 -0
  112. optpricing-2.3.4/data/market_data_snapshots/AAPL_2025-06-17.parquet +0 -0
  113. optpricing-2.3.4/data/market_data_snapshots/AAPL_2025-06-26.parquet +0 -0
  114. optpricing-2.3.4/data/market_data_snapshots/AAPL_2025-07-02.parquet +0 -0
  115. optpricing-2.3.4/data/market_data_snapshots/AAPL_2025-07-03.parquet +0 -0
  116. optpricing-2.3.4/data/market_data_snapshots/AAPL_2025-07-07.parquet +0 -0
  117. optpricing-2.3.4/data/market_data_snapshots/AAPL_2025-07-08.parquet +0 -0
  118. optpricing-2.3.4/data/market_data_snapshots/AAPL_2025-07-09.parquet +0 -0
  119. optpricing-2.3.4/data/market_data_snapshots/AMC_2025-06-17.parquet +0 -0
  120. optpricing-2.3.4/data/market_data_snapshots/AMC_2025-06-26.parquet +0 -0
  121. optpricing-2.3.4/data/market_data_snapshots/AMC_2025-07-02.parquet +0 -0
  122. optpricing-2.3.4/data/market_data_snapshots/AMC_2025-07-03.parquet +0 -0
  123. optpricing-2.3.4/data/market_data_snapshots/AMC_2025-07-07.parquet +0 -0
  124. optpricing-2.3.4/data/market_data_snapshots/AMC_2025-07-08.parquet +0 -0
  125. optpricing-2.3.4/data/market_data_snapshots/AMC_2025-07-09.parquet +0 -0
  126. optpricing-2.3.4/data/market_data_snapshots/AMD_2025-06-17.parquet +0 -0
  127. optpricing-2.3.4/data/market_data_snapshots/AMD_2025-06-26.parquet +0 -0
  128. optpricing-2.3.4/data/market_data_snapshots/AMD_2025-07-02.parquet +0 -0
  129. optpricing-2.3.4/data/market_data_snapshots/AMD_2025-07-03.parquet +0 -0
  130. optpricing-2.3.4/data/market_data_snapshots/AMD_2025-07-07.parquet +0 -0
  131. optpricing-2.3.4/data/market_data_snapshots/AMD_2025-07-08.parquet +0 -0
  132. optpricing-2.3.4/data/market_data_snapshots/AMD_2025-07-09.parquet +0 -0
  133. optpricing-2.3.4/data/market_data_snapshots/AMZN_2025-06-17.parquet +0 -0
  134. optpricing-2.3.4/data/market_data_snapshots/AMZN_2025-06-26.parquet +0 -0
  135. optpricing-2.3.4/data/market_data_snapshots/AMZN_2025-07-02.parquet +0 -0
  136. optpricing-2.3.4/data/market_data_snapshots/AMZN_2025-07-03.parquet +0 -0
  137. optpricing-2.3.4/data/market_data_snapshots/AMZN_2025-07-07.parquet +0 -0
  138. optpricing-2.3.4/data/market_data_snapshots/AMZN_2025-07-08.parquet +0 -0
  139. optpricing-2.3.4/data/market_data_snapshots/AMZN_2025-07-09.parquet +0 -0
  140. optpricing-2.3.4/data/market_data_snapshots/BAC_2025-06-17.parquet +0 -0
  141. optpricing-2.3.4/data/market_data_snapshots/BAC_2025-06-26.parquet +0 -0
  142. optpricing-2.3.4/data/market_data_snapshots/BAC_2025-07-02.parquet +0 -0
  143. optpricing-2.3.4/data/market_data_snapshots/BAC_2025-07-03.parquet +0 -0
  144. optpricing-2.3.4/data/market_data_snapshots/BAC_2025-07-07.parquet +0 -0
  145. optpricing-2.3.4/data/market_data_snapshots/BAC_2025-07-08.parquet +0 -0
  146. optpricing-2.3.4/data/market_data_snapshots/BAC_2025-07-09.parquet +0 -0
  147. optpricing-2.3.4/data/market_data_snapshots/BA_2025-06-17.parquet +0 -0
  148. optpricing-2.3.4/data/market_data_snapshots/BA_2025-06-26.parquet +0 -0
  149. optpricing-2.3.4/data/market_data_snapshots/BA_2025-07-02.parquet +0 -0
  150. optpricing-2.3.4/data/market_data_snapshots/BA_2025-07-03.parquet +0 -0
  151. optpricing-2.3.4/data/market_data_snapshots/BA_2025-07-07.parquet +0 -0
  152. optpricing-2.3.4/data/market_data_snapshots/BA_2025-07-08.parquet +0 -0
  153. optpricing-2.3.4/data/market_data_snapshots/BA_2025-07-09.parquet +0 -0
  154. optpricing-2.3.4/data/market_data_snapshots/CAT_2025-06-17.parquet +0 -0
  155. optpricing-2.3.4/data/market_data_snapshots/CAT_2025-06-26.parquet +0 -0
  156. optpricing-2.3.4/data/market_data_snapshots/CAT_2025-07-02.parquet +0 -0
  157. optpricing-2.3.4/data/market_data_snapshots/CAT_2025-07-03.parquet +0 -0
  158. optpricing-2.3.4/data/market_data_snapshots/CAT_2025-07-07.parquet +0 -0
  159. optpricing-2.3.4/data/market_data_snapshots/CAT_2025-07-08.parquet +0 -0
  160. optpricing-2.3.4/data/market_data_snapshots/CAT_2025-07-09.parquet +0 -0
  161. optpricing-2.3.4/data/market_data_snapshots/CVX_2025-06-17.parquet +0 -0
  162. optpricing-2.3.4/data/market_data_snapshots/CVX_2025-06-26.parquet +0 -0
  163. optpricing-2.3.4/data/market_data_snapshots/CVX_2025-07-02.parquet +0 -0
  164. optpricing-2.3.4/data/market_data_snapshots/CVX_2025-07-03.parquet +0 -0
  165. optpricing-2.3.4/data/market_data_snapshots/CVX_2025-07-07.parquet +0 -0
  166. optpricing-2.3.4/data/market_data_snapshots/CVX_2025-07-08.parquet +0 -0
  167. optpricing-2.3.4/data/market_data_snapshots/CVX_2025-07-09.parquet +0 -0
  168. optpricing-2.3.4/data/market_data_snapshots/GME_2025-06-17.parquet +0 -0
  169. optpricing-2.3.4/data/market_data_snapshots/GME_2025-06-26.parquet +0 -0
  170. optpricing-2.3.4/data/market_data_snapshots/GME_2025-07-02.parquet +0 -0
  171. optpricing-2.3.4/data/market_data_snapshots/GME_2025-07-03.parquet +0 -0
  172. optpricing-2.3.4/data/market_data_snapshots/GME_2025-07-07.parquet +0 -0
  173. optpricing-2.3.4/data/market_data_snapshots/GME_2025-07-08.parquet +0 -0
  174. optpricing-2.3.4/data/market_data_snapshots/GME_2025-07-09.parquet +0 -0
  175. optpricing-2.3.4/data/market_data_snapshots/GOOGL_2025-06-16.parquet +0 -0
  176. optpricing-2.3.4/data/market_data_snapshots/GOOGL_2025-06-17.parquet +0 -0
  177. optpricing-2.3.4/data/market_data_snapshots/GOOGL_2025-06-26.parquet +0 -0
  178. optpricing-2.3.4/data/market_data_snapshots/GOOGL_2025-07-02.parquet +0 -0
  179. optpricing-2.3.4/data/market_data_snapshots/GOOGL_2025-07-03.parquet +0 -0
  180. optpricing-2.3.4/data/market_data_snapshots/GOOGL_2025-07-07.parquet +0 -0
  181. optpricing-2.3.4/data/market_data_snapshots/GOOGL_2025-07-08.parquet +0 -0
  182. optpricing-2.3.4/data/market_data_snapshots/GOOGL_2025-07-09.parquet +0 -0
  183. optpricing-2.3.4/data/market_data_snapshots/GS_2025-06-17.parquet +0 -0
  184. optpricing-2.3.4/data/market_data_snapshots/GS_2025-06-26.parquet +0 -0
  185. optpricing-2.3.4/data/market_data_snapshots/GS_2025-07-02.parquet +0 -0
  186. optpricing-2.3.4/data/market_data_snapshots/GS_2025-07-03.parquet +0 -0
  187. optpricing-2.3.4/data/market_data_snapshots/GS_2025-07-07.parquet +0 -0
  188. optpricing-2.3.4/data/market_data_snapshots/GS_2025-07-08.parquet +0 -0
  189. optpricing-2.3.4/data/market_data_snapshots/GS_2025-07-09.parquet +0 -0
  190. optpricing-2.3.4/data/market_data_snapshots/HD_2025-06-17.parquet +0 -0
  191. optpricing-2.3.4/data/market_data_snapshots/HD_2025-06-26.parquet +0 -0
  192. optpricing-2.3.4/data/market_data_snapshots/HD_2025-07-02.parquet +0 -0
  193. optpricing-2.3.4/data/market_data_snapshots/HD_2025-07-03.parquet +0 -0
  194. optpricing-2.3.4/data/market_data_snapshots/HD_2025-07-07.parquet +0 -0
  195. optpricing-2.3.4/data/market_data_snapshots/HD_2025-07-08.parquet +0 -0
  196. optpricing-2.3.4/data/market_data_snapshots/HD_2025-07-09.parquet +0 -0
  197. optpricing-2.3.4/data/market_data_snapshots/JNJ_2025-06-17.parquet +0 -0
  198. optpricing-2.3.4/data/market_data_snapshots/JNJ_2025-06-26.parquet +0 -0
  199. optpricing-2.3.4/data/market_data_snapshots/JNJ_2025-07-02.parquet +0 -0
  200. optpricing-2.3.4/data/market_data_snapshots/JNJ_2025-07-03.parquet +0 -0
  201. optpricing-2.3.4/data/market_data_snapshots/JNJ_2025-07-07.parquet +0 -0
  202. optpricing-2.3.4/data/market_data_snapshots/JNJ_2025-07-08.parquet +0 -0
  203. optpricing-2.3.4/data/market_data_snapshots/JNJ_2025-07-09.parquet +0 -0
  204. optpricing-2.3.4/data/market_data_snapshots/JPM_2025-06-17.parquet +0 -0
  205. optpricing-2.3.4/data/market_data_snapshots/JPM_2025-06-26.parquet +0 -0
  206. optpricing-2.3.4/data/market_data_snapshots/JPM_2025-07-02.parquet +0 -0
  207. optpricing-2.3.4/data/market_data_snapshots/JPM_2025-07-03.parquet +0 -0
  208. optpricing-2.3.4/data/market_data_snapshots/JPM_2025-07-07.parquet +0 -0
  209. optpricing-2.3.4/data/market_data_snapshots/JPM_2025-07-08.parquet +0 -0
  210. optpricing-2.3.4/data/market_data_snapshots/JPM_2025-07-09.parquet +0 -0
  211. optpricing-2.3.4/data/market_data_snapshots/META_2025-06-16.parquet +0 -0
  212. optpricing-2.3.4/data/market_data_snapshots/META_2025-06-17.parquet +0 -0
  213. optpricing-2.3.4/data/market_data_snapshots/META_2025-06-26.parquet +0 -0
  214. optpricing-2.3.4/data/market_data_snapshots/META_2025-07-02.parquet +0 -0
  215. optpricing-2.3.4/data/market_data_snapshots/META_2025-07-03.parquet +0 -0
  216. optpricing-2.3.4/data/market_data_snapshots/META_2025-07-07.parquet +0 -0
  217. optpricing-2.3.4/data/market_data_snapshots/META_2025-07-08.parquet +0 -0
  218. optpricing-2.3.4/data/market_data_snapshots/META_2025-07-09.parquet +0 -0
  219. optpricing-2.3.4/data/market_data_snapshots/MSFT_2025-06-17.parquet +0 -0
  220. optpricing-2.3.4/data/market_data_snapshots/MSFT_2025-06-26.parquet +0 -0
  221. optpricing-2.3.4/data/market_data_snapshots/MSFT_2025-07-02.parquet +0 -0
  222. optpricing-2.3.4/data/market_data_snapshots/MSFT_2025-07-03.parquet +0 -0
  223. optpricing-2.3.4/data/market_data_snapshots/MSFT_2025-07-07.parquet +0 -0
  224. optpricing-2.3.4/data/market_data_snapshots/MSFT_2025-07-08.parquet +0 -0
  225. optpricing-2.3.4/data/market_data_snapshots/MSFT_2025-07-09.parquet +0 -0
  226. optpricing-2.3.4/data/market_data_snapshots/NKE_2025-06-17.parquet +0 -0
  227. optpricing-2.3.4/data/market_data_snapshots/NKE_2025-06-26.parquet +0 -0
  228. optpricing-2.3.4/data/market_data_snapshots/NKE_2025-07-02.parquet +0 -0
  229. optpricing-2.3.4/data/market_data_snapshots/NKE_2025-07-03.parquet +0 -0
  230. optpricing-2.3.4/data/market_data_snapshots/NKE_2025-07-07.parquet +0 -0
  231. optpricing-2.3.4/data/market_data_snapshots/NKE_2025-07-08.parquet +0 -0
  232. optpricing-2.3.4/data/market_data_snapshots/NKE_2025-07-09.parquet +0 -0
  233. optpricing-2.3.4/data/market_data_snapshots/NVDA_2025-06-17.parquet +0 -0
  234. optpricing-2.3.4/data/market_data_snapshots/NVDA_2025-06-26.parquet +0 -0
  235. optpricing-2.3.4/data/market_data_snapshots/NVDA_2025-07-02.parquet +0 -0
  236. optpricing-2.3.4/data/market_data_snapshots/NVDA_2025-07-03.parquet +0 -0
  237. optpricing-2.3.4/data/market_data_snapshots/NVDA_2025-07-07.parquet +0 -0
  238. optpricing-2.3.4/data/market_data_snapshots/NVDA_2025-07-08.parquet +0 -0
  239. optpricing-2.3.4/data/market_data_snapshots/NVDA_2025-07-09.parquet +0 -0
  240. optpricing-2.3.4/data/market_data_snapshots/PFE_2025-06-17.parquet +0 -0
  241. optpricing-2.3.4/data/market_data_snapshots/PFE_2025-06-26.parquet +0 -0
  242. optpricing-2.3.4/data/market_data_snapshots/PFE_2025-07-02.parquet +0 -0
  243. optpricing-2.3.4/data/market_data_snapshots/PFE_2025-07-03.parquet +0 -0
  244. optpricing-2.3.4/data/market_data_snapshots/PFE_2025-07-07.parquet +0 -0
  245. optpricing-2.3.4/data/market_data_snapshots/PFE_2025-07-08.parquet +0 -0
  246. optpricing-2.3.4/data/market_data_snapshots/PFE_2025-07-09.parquet +0 -0
  247. optpricing-2.3.4/data/market_data_snapshots/QQQ_2025-06-17.parquet +0 -0
  248. optpricing-2.3.4/data/market_data_snapshots/QQQ_2025-06-26.parquet +0 -0
  249. optpricing-2.3.4/data/market_data_snapshots/QQQ_2025-07-02.parquet +0 -0
  250. optpricing-2.3.4/data/market_data_snapshots/QQQ_2025-07-03.parquet +0 -0
  251. optpricing-2.3.4/data/market_data_snapshots/QQQ_2025-07-07.parquet +0 -0
  252. optpricing-2.3.4/data/market_data_snapshots/QQQ_2025-07-08.parquet +0 -0
  253. optpricing-2.3.4/data/market_data_snapshots/QQQ_2025-07-09.parquet +0 -0
  254. optpricing-2.3.4/data/market_data_snapshots/SPY_2025-06-16.parquet +0 -0
  255. optpricing-2.3.4/data/market_data_snapshots/SPY_2025-06-17.parquet +0 -0
  256. optpricing-2.3.4/data/market_data_snapshots/SPY_2025-06-26.parquet +0 -0
  257. optpricing-2.3.4/data/market_data_snapshots/SPY_2025-07-02.parquet +0 -0
  258. optpricing-2.3.4/data/market_data_snapshots/SPY_2025-07-03.parquet +0 -0
  259. optpricing-2.3.4/data/market_data_snapshots/SPY_2025-07-07.parquet +0 -0
  260. optpricing-2.3.4/data/market_data_snapshots/SPY_2025-07-08.parquet +0 -0
  261. optpricing-2.3.4/data/market_data_snapshots/SPY_2025-07-09.parquet +0 -0
  262. optpricing-2.3.4/data/market_data_snapshots/TSLA_2025-06-16.parquet +0 -0
  263. optpricing-2.3.4/data/market_data_snapshots/TSLA_2025-06-17.parquet +0 -0
  264. optpricing-2.3.4/data/market_data_snapshots/TSLA_2025-06-26.parquet +0 -0
  265. optpricing-2.3.4/data/market_data_snapshots/TSLA_2025-07-02.parquet +0 -0
  266. optpricing-2.3.4/data/market_data_snapshots/TSLA_2025-07-03.parquet +0 -0
  267. optpricing-2.3.4/data/market_data_snapshots/TSLA_2025-07-07.parquet +0 -0
  268. optpricing-2.3.4/data/market_data_snapshots/TSLA_2025-07-08.parquet +0 -0
  269. optpricing-2.3.4/data/market_data_snapshots/TSLA_2025-07-09.parquet +0 -0
  270. optpricing-2.3.4/data/market_data_snapshots/UNH_2025-06-17.parquet +0 -0
  271. optpricing-2.3.4/data/market_data_snapshots/UNH_2025-06-26.parquet +0 -0
  272. optpricing-2.3.4/data/market_data_snapshots/UNH_2025-07-02.parquet +0 -0
  273. optpricing-2.3.4/data/market_data_snapshots/UNH_2025-07-03.parquet +0 -0
  274. optpricing-2.3.4/data/market_data_snapshots/UNH_2025-07-07.parquet +0 -0
  275. optpricing-2.3.4/data/market_data_snapshots/UNH_2025-07-08.parquet +0 -0
  276. optpricing-2.3.4/data/market_data_snapshots/UNH_2025-07-09.parquet +0 -0
  277. optpricing-2.3.4/data/market_data_snapshots/WMT_2025-06-17.parquet +0 -0
  278. optpricing-2.3.4/data/market_data_snapshots/WMT_2025-06-26.parquet +0 -0
  279. optpricing-2.3.4/data/market_data_snapshots/WMT_2025-07-02.parquet +0 -0
  280. optpricing-2.3.4/data/market_data_snapshots/WMT_2025-07-03.parquet +0 -0
  281. optpricing-2.3.4/data/market_data_snapshots/WMT_2025-07-07.parquet +0 -0
  282. optpricing-2.3.4/data/market_data_snapshots/WMT_2025-07-08.parquet +0 -0
  283. optpricing-2.3.4/data/market_data_snapshots/WMT_2025-07-09.parquet +0 -0
  284. optpricing-2.3.4/data/market_data_snapshots/XOM_2025-06-17.parquet +0 -0
  285. optpricing-2.3.4/data/market_data_snapshots/XOM_2025-06-26.parquet +0 -0
  286. optpricing-2.3.4/data/market_data_snapshots/XOM_2025-07-02.parquet +0 -0
  287. optpricing-2.3.4/data/market_data_snapshots/XOM_2025-07-03.parquet +0 -0
  288. optpricing-2.3.4/data/market_data_snapshots/XOM_2025-07-07.parquet +0 -0
  289. optpricing-2.3.4/data/market_data_snapshots/XOM_2025-07-08.parquet +0 -0
  290. optpricing-2.3.4/data/market_data_snapshots/XOM_2025-07-09.parquet +0 -0
  291. optpricing-2.3.4/docs/guide/API.md +0 -127
  292. optpricing-2.3.4/docs/guide/CLI.md +0 -150
  293. optpricing-2.3.4/docs/guide/dashboard.md +0 -53
  294. optpricing-2.3.4/docs/guide/examples.md +0 -66
  295. optpricing-2.3.4/docs/guide/getting_started.md +0 -133
  296. optpricing-2.3.4/docs/guide/installation.md +0 -61
  297. optpricing-2.3.4/docs/guide/introduction.md +0 -23
  298. optpricing-2.3.4/docs/images/bates.png +0 -0
  299. optpricing-2.3.4/docs/images/calibration.png +0 -0
  300. optpricing-2.3.4/docs/images/fit_jump.png +0 -0
  301. optpricing-2.3.4/docs/images/zcb.png +0 -0
  302. optpricing-2.3.4/docs/index.md +0 -45
  303. optpricing-2.3.4/docs/reference/atoms/index.md +0 -7
  304. optpricing-2.3.4/docs/reference/calibration/index.md +0 -7
  305. optpricing-2.3.4/docs/reference/cli/index.md +0 -12
  306. optpricing-2.3.4/docs/reference/dashboard/index.md +0 -9
  307. optpricing-2.3.4/docs/reference/data/index.md +0 -6
  308. optpricing-2.3.4/docs/reference/index.md +0 -77
  309. optpricing-2.3.4/docs/reference/models/index.md +0 -9
  310. optpricing-2.3.4/docs/reference/parity/index.md +0 -5
  311. optpricing-2.3.4/docs/reference/techniques/index.md +0 -6
  312. optpricing-2.3.4/docs/reference/workflows/index.md +0 -6
  313. optpricing-2.3.4/examples/american_options_benchmark.py +0 -208
  314. optpricing-2.3.4/examples/european_options_benchmark.py +0 -453
  315. optpricing-2.3.4/examples/getting_started.py +0 -47
  316. optpricing-2.3.4/examples/rate_models_benchmark.py +0 -55
  317. optpricing-2.3.4/mkdocs.yml +0 -87
  318. optpricing-2.3.4/pyproject.toml +0 -97
  319. optpricing-2.3.4/src/optpricing/config.py +0 -57
  320. optpricing-2.3.4/src/optpricing/models/cev.py +0 -109
  321. optpricing-2.3.4/src/optpricing/models/sabr.py +0 -64
  322. optpricing-2.3.4/src/optpricing.egg-info/SOURCES.txt +0 -438
  323. optpricing-2.3.4/src/optpricing.egg-info/requires.txt +0 -24
  324. optpricing-2.3.4/tests/models/test_sabr.py +0 -40
  325. {optpricing-2.3.4 → optpricing-2.5.0}/LICENSE +0 -0
  326. {optpricing-2.3.4 → optpricing-2.5.0}/setup.cfg +0 -0
  327. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/__init__.py +0 -0
  328. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/atoms/__init__.py +0 -0
  329. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/atoms/bond.py +0 -0
  330. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/atoms/option.py +0 -0
  331. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/atoms/rate.py +0 -0
  332. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/atoms/stock.py +0 -0
  333. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/__init__.py +0 -0
  334. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/calibrator.py +0 -0
  335. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/fit_jump_parameters.py +0 -0
  336. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/fit_market_params.py +0 -0
  337. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/technique_selector.py +0 -0
  338. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/vectorized_bsm_iv.py +0 -0
  339. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/vectorized_integration_iv.py +0 -0
  340. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/calibration/vectorized_pricer.py +0 -0
  341. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/__init__.py +0 -0
  342. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/commands/__init__.py +0 -0
  343. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/commands/backtest.py +0 -0
  344. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/commands/calibrate.py +0 -0
  345. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/commands/data.py +0 -0
  346. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/commands/demo.py +0 -0
  347. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/commands/tools.py +0 -0
  348. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/cli/main.py +0 -0
  349. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/Home.py +0 -0
  350. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/__init__.py +0 -0
  351. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/pages/1_Pricer_and_Greeks.py +0 -0
  352. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/pages/2_Calibration_and_IV.py +0 -0
  353. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/pages/3_Market_Analytics.py +0 -0
  354. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/pages/4_Model_Fitting.py +0 -0
  355. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/pages/5_Term_Structure.py +0 -0
  356. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/pages/__init__.py +0 -0
  357. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/plots.py +0 -0
  358. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/service.py +0 -0
  359. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/dashboard/widgets.py +0 -0
  360. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/data/__init__.py +0 -0
  361. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/__init__.py +0 -0
  362. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/base/base_model.py +0 -0
  363. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/base/validators.py +0 -0
  364. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/blacks_approx.py +0 -0
  365. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/bsm.py +0 -0
  366. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/dupire_local.py +0 -0
  367. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/merton_jump.py +0 -0
  368. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/perpetual_put.py +0 -0
  369. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/models/vasicek.py +0 -0
  370. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/parity/__init__.py +0 -0
  371. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/parity/implied_rate.py +0 -0
  372. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/parity/parity_model.py +0 -0
  373. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/__init__.py +0 -0
  374. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/base/__init__.py +0 -0
  375. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/base/base_technique.py +0 -0
  376. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/base/greek_mixin.py +0 -0
  377. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/base/iv_mixin.py +0 -0
  378. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/base/lattice_technique.py +0 -0
  379. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/base/pricing_result.py +0 -0
  380. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/base/random_utils.py +0 -0
  381. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/closed_form.py +0 -0
  382. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/crr.py +0 -0
  383. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/fft.py +0 -0
  384. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/integration.py +0 -0
  385. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/kernels/__init__.py +0 -0
  386. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/kernels/lattice_kernels.py +0 -0
  387. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/leisen_reimer.py +0 -0
  388. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/techniques/topm.py +0 -0
  389. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/__init__.py +0 -0
  390. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/__init__.py +0 -0
  391. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/bates_config.py +0 -0
  392. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/bsm_config.py +0 -0
  393. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/cev_config.py +0 -0
  394. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/cgmy_config.py +0 -0
  395. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/heston_config.py +0 -0
  396. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/hyperbolic_config.py +0 -0
  397. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/kou_config.py +0 -0
  398. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/merton_config.py +0 -0
  399. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/nig_config.py +0 -0
  400. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/configs/vg_config.py +0 -0
  401. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing/workflows/daily_workflow.py +0 -0
  402. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing.egg-info/dependency_links.txt +0 -0
  403. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing.egg-info/entry_points.txt +0 -0
  404. {optpricing-2.3.4 → optpricing-2.5.0}/src/optpricing.egg-info/top_level.txt +0 -0
  405. {optpricing-2.3.4 → optpricing-2.5.0}/tests/atoms/test_bond.py +0 -0
  406. {optpricing-2.3.4 → optpricing-2.5.0}/tests/atoms/test_option.py +0 -0
  407. {optpricing-2.3.4 → optpricing-2.5.0}/tests/atoms/test_rate.py +0 -0
  408. {optpricing-2.3.4 → optpricing-2.5.0}/tests/atoms/test_stock.py +0 -0
  409. {optpricing-2.3.4 → optpricing-2.5.0}/tests/calibration/test_calibrator.py +0 -0
  410. {optpricing-2.3.4 → optpricing-2.5.0}/tests/calibration/test_fit_jump_parameters.py +0 -0
  411. {optpricing-2.3.4 → optpricing-2.5.0}/tests/calibration/test_fit_market_params.py +0 -0
  412. {optpricing-2.3.4 → optpricing-2.5.0}/tests/calibration/test_iv_surface.py +0 -0
  413. {optpricing-2.3.4 → optpricing-2.5.0}/tests/calibration/test_technique_selector.py +0 -0
  414. {optpricing-2.3.4 → optpricing-2.5.0}/tests/calibration/test_vectorized_bsm_iv.py +0 -0
  415. {optpricing-2.3.4 → optpricing-2.5.0}/tests/calibration/test_vectorized_integration_iv.py +0 -0
  416. {optpricing-2.3.4 → optpricing-2.5.0}/tests/calibration/test_vectorized_pricer.py +0 -0
  417. {optpricing-2.3.4 → optpricing-2.5.0}/tests/cli/commands/test_backtest.py +0 -0
  418. {optpricing-2.3.4 → optpricing-2.5.0}/tests/cli/commands/test_calibrate.py +0 -0
  419. {optpricing-2.3.4 → optpricing-2.5.0}/tests/cli/commands/test_data.py +0 -0
  420. {optpricing-2.3.4 → optpricing-2.5.0}/tests/cli/commands/test_tools.py +0 -0
  421. {optpricing-2.3.4 → optpricing-2.5.0}/tests/cli/test_main.py +0 -0
  422. {optpricing-2.3.4 → optpricing-2.5.0}/tests/dashboard/test_plots.py +0 -0
  423. {optpricing-2.3.4 → optpricing-2.5.0}/tests/dashboard/test_service.py +0 -0
  424. {optpricing-2.3.4 → optpricing-2.5.0}/tests/dashboard/test_widgets.py +0 -0
  425. {optpricing-2.3.4 → optpricing-2.5.0}/tests/data/test_historical_manager.py +0 -0
  426. {optpricing-2.3.4 → optpricing-2.5.0}/tests/data/test_market_data_manager.py +0 -0
  427. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/base/test_base_model.py +0 -0
  428. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/base/test_validators.py +0 -0
  429. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_bates.py +0 -0
  430. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_blacks_approx.py +0 -0
  431. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_bsm.py +0 -0
  432. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_cev.py +0 -0
  433. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_cir.py +0 -0
  434. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_dupire_local.py +0 -0
  435. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_heston.py +0 -0
  436. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_hyperbolic.py +0 -0
  437. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_kou.py +0 -0
  438. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_merton_jump.py +0 -0
  439. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_nig.py +0 -0
  440. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_perpetual_put.py +0 -0
  441. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_vasicek.py +0 -0
  442. {optpricing-2.3.4 → optpricing-2.5.0}/tests/models/test_vg.py +0 -0
  443. {optpricing-2.3.4 → optpricing-2.5.0}/tests/parity/test_implied_rate.py +0 -0
  444. {optpricing-2.3.4 → optpricing-2.5.0}/tests/parity/test_parity_model.py +0 -0
  445. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/base/test_greek_mixin.py +0 -0
  446. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/base/test_iv_mixin.py +0 -0
  447. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/base/test_pricing_result.py +0 -0
  448. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/base/test_random_utils.py +0 -0
  449. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/kernels/test_lattice_kernels.py +0 -0
  450. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_american_monte_carlo.py +0 -0
  451. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_closed_form.py +0 -0
  452. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_crr.py +0 -0
  453. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_fft.py +0 -0
  454. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_integration.py +0 -0
  455. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_leisen_reimer.py +0 -0
  456. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_monte_carlo.py +0 -0
  457. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_pde.py +0 -0
  458. {optpricing-2.3.4 → optpricing-2.5.0}/tests/techniques/test_topm.py +0 -0
  459. {optpricing-2.3.4 → optpricing-2.5.0}/tests/workflows/test_backtest_workflow.py +0 -0
  460. {optpricing-2.3.4 → optpricing-2.5.0}/tests/workflows/test_daily_workflow.py +0 -0
@@ -0,0 +1,50 @@
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
+ ### Changed
10
+
11
+ - Python 3.10 support dropped (end of life); supported versions are 3.11–3.14, with 3.15 tested as experimental.
12
+ - 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.
13
+ - Streamlit and Plotly moved to the optional `ui` extra: `pip install "optpricing[ui]"` for the dashboard.
14
+ - Development tooling moved from the `dev` extra to PEP 735 dependency groups (`uv sync`; `pip install -e . --group dev`).
15
+ - Package metadata uses a PEP 639 license expression; the source distribution no longer bundles `data/`, `artifacts/` or docs (24 MB → ~0.1 MB).
16
+ - 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.
17
+
18
+ ### Removed
19
+
20
+ - Unused runtime dependencies `matplotlib`, `tabulate` and the explicit `click` pin (Click arrives via Typer).
21
+
22
+ ### Fixed
23
+
24
+ - `test_price_command` relied on a hard-coded maturity date that is now in the past.
25
+ - **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.
26
+ - NIG exact sampler drew the inverse-Gaussian subordinator with shape 1 instead of (δT)²; prices were ~3 % low.
27
+ - 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.
28
+ - 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.
29
+ - 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.
30
+ - 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.
31
+ - 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.
32
+ - SABR kernels could leave the spot negative after a large down-move (puts paid more than the strike); zero is absorbing for 0 < β < 1.
33
+ - Parameter validation now rejects parameter sets without a risk-neutral measure: Kou η₁ ≤ 1, VG θν + σ²ν/2 ≥ 1, NIG/Hyperbolic |β+1| ≥ α, CGMY M ≤ 1.
34
+ - `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.
35
+ - Heston and Bates read `v0` from the model parameters when it is not passed as a pricing kwarg.
36
+ - 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).
37
+
38
+ - 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`.
39
+ - Heston and Bates default parameters now satisfy the Feller condition (`vol_of_vol` 0.5 → 0.3).
40
+
41
+ ### Added
42
+
43
+ - `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.
44
+ - `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.
45
+
46
+ ## [2.0.0] - 2025-06-26
47
+
48
+ ### Added
49
+
50
+ - Shipped to PyPI `pyproject.toml`
@@ -0,0 +1,11 @@
1
+ # setuptools_scm seeds the sdist with every git-tracked file. Keep the archive to
2
+ # what a source build and the test suite need; data, artifacts, docs and CI config
3
+ # live in the repository only.
4
+ prune data
5
+ prune artifacts
6
+ prune docs
7
+ prune examples
8
+ prune .github
9
+ exclude .gitignore .pre-commit-config.yaml .python-version
10
+ exclude codecov.yml config.yaml mkdocs.yml uv.lock
11
+ exclude CODE_OF_CONDUCT.md CONTRIBUTING.md PULL_REQUEST_TEMPLATE.md SECURITY.md
@@ -1,59 +1,50 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: optpricing
3
- Version: 2.3.4
3
+ Version: 2.5.0
4
4
  Summary: A financial options pricing and analysis library.
5
- Author-email: Diljit Singh <first_last22@google.com>
6
- License: # MIT LICENSE
7
-
8
- Copyright 2025 Diljit Singh
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
-
5
+ Author: Diljit Singh
6
+ License-Expression: MIT
16
7
  Project-URL: Homepage, https://diljit22.github.io/optpricing/
17
- Classifier: Programming Language :: Python :: 3
18
- Classifier: License :: OSI Approved :: MIT License
8
+ Project-URL: Documentation, https://diljit22.github.io/optpricing/
9
+ Project-URL: Repository, https://github.com/Diljit22/optpricing
10
+ Project-URL: Issues, https://github.com/Diljit22/optpricing/issues
11
+ Project-URL: Changelog, https://github.com/Diljit22/optpricing/blob/main/CHANGELOG.md
12
+ Keywords: options,derivatives,quantitative-finance,option-pricing,heston,monte-carlo,fft,calibration
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Financial and Insurance Industry
15
+ Classifier: Intended Audience :: Science/Research
19
16
  Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3 :: Only
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
20
23
  Classifier: Topic :: Office/Business :: Financial :: Investment
21
- Requires-Python: >=3.10
24
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
25
+ Requires-Python: >=3.11
22
26
  Description-Content-Type: text/markdown
23
27
  License-File: LICENSE
24
- Requires-Dist: numpy~=2.2.5
25
- Requires-Dist: scipy~=1.15.2
26
- Requires-Dist: pandas~=2.2.3
27
- Requires-Dist: numba~=0.61.2
28
- Requires-Dist: pyyaml~=6.0.2
29
- Requires-Dist: click~=8.1
30
- Requires-Dist: typer~=0.15.2
31
- Requires-Dist: streamlit~=1.45.1
32
- Requires-Dist: matplotlib~=3.10.1
33
- Requires-Dist: plotly~=6.1.2
34
- Requires-Dist: yfinance~=0.2.63
35
- Requires-Dist: tabulate~=0.9.0
36
- Provides-Extra: dev
37
- Requires-Dist: pytest; extra == "dev"
38
- Requires-Dist: pytest-cov; extra == "dev"
39
- Requires-Dist: ruff==0.11.6; extra == "dev"
40
- Requires-Dist: mkdocs; extra == "dev"
41
- Requires-Dist: mkdocs-material; extra == "dev"
42
- Requires-Dist: mkdocstrings[python]; extra == "dev"
43
- Requires-Dist: mkdocs-section-index; extra == "dev"
44
- Requires-Dist: line_profiler; extra == "dev"
45
- Requires-Dist: pre-commit; extra == "dev"
46
- Requires-Dist: codecov; extra == "dev"
28
+ Requires-Dist: numpy>=2.3.2
29
+ Requires-Dist: scipy>=1.16.1
30
+ Requires-Dist: pandas>=2.3.3
31
+ Requires-Dist: numba>=0.63
32
+ Requires-Dist: pyyaml>=6.0.3
33
+ Requires-Dist: typer>=0.15.3
34
+ Requires-Dist: yfinance>=0.2.63
35
+ Provides-Extra: ui
36
+ Requires-Dist: streamlit>=1.45.1; extra == "ui"
37
+ Requires-Dist: plotly>=6.1.2; extra == "ui"
47
38
  Dynamic: license-file
48
39
 
49
40
  # OptPricing: A Quantitative Finance Library for Derivative Pricing and Analysis
50
41
 
51
- [![Tests](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/ci.yml?branch=main&label=tests)](https://github.com/diljit22/optpricing/actions/workflows/ci.yml)
42
+ [![CI](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/ci.yml?branch=main&label=ci)](https://github.com/diljit22/optpricing/actions/workflows/ci.yml)
52
43
  [![Coverage](https://codecov.io/gh/diljit22/optpricing/branch/main/graph/badge.svg)](https://codecov.io/gh/diljit22/optpricing)
53
- [![Ruff](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/ci.yml?branch=main&label=ruff)](https://github.com/diljit22/optpricing/actions/workflows/ci.yml)
54
- [![Docs](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/ci.yml?branch=main&label=docs)](https://github.com/diljit22/optpricing/actions/workflows/ci.yml)
44
+ [![Docs](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/pages.yml?branch=main&label=docs)](https://github.com/diljit22/optpricing/actions/workflows/pages.yml)
55
45
  [![PyPI version](https://img.shields.io/pypi/v/optpricing.svg)](https://pypi.org/project/optpricing/)
56
- [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
46
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
47
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
57
48
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
58
49
 
59
50
  `optpricing` is a Python library for pricing, calibrating, and analyzing financial derivatives. It is built with a focus on architectural clarity, model breadth, and practical usability through a robust API, command-line interface, and an interactive dashboard.
@@ -90,12 +81,13 @@ Diljit Singh
90
81
 
91
82
  ## Quick Start
92
83
 
93
- `optpricing` is designed for a straightforward installation using `pip` and is compatible with Python 3.10 and higher.
84
+ `optpricing` installs with `pip` (or `uv`) and supports Python 3.11 through 3.14.
94
85
 
95
86
  ### 1. Install the Library
96
87
 
97
88
  ```bash
98
- pip install optpricing
89
+ pip install optpricing # library + CLI
90
+ pip install "optpricing[ui]" # also the Streamlit dashboard
99
91
  ```
100
92
 
101
93
  ### 2. Download Historical Data
@@ -126,7 +118,7 @@ For more details, see the [CLI Guide](https://diljit22.github.io/optpricing/guid
126
118
 
127
119
  ### 4. Launch the Dashboard
128
120
 
129
- Visualize option chains and model outputs, interact with a pricing calculator featuring 15 models and 10 techniques.
121
+ Visualize option chains and model outputs, and interact with a pricing calculator covering 12 models and 8 techniques (the full library exposes 17 pricing models plus parity/implied-rate models, and 9 techniques). Requires the `ui` extra.
130
122
 
131
123
  ```bash
132
124
  optpricing dashboard
@@ -1,11 +1,11 @@
1
1
  # OptPricing: A Quantitative Finance Library for Derivative Pricing and Analysis
2
2
 
3
- [![Tests](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/ci.yml?branch=main&label=tests)](https://github.com/diljit22/optpricing/actions/workflows/ci.yml)
3
+ [![CI](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/ci.yml?branch=main&label=ci)](https://github.com/diljit22/optpricing/actions/workflows/ci.yml)
4
4
  [![Coverage](https://codecov.io/gh/diljit22/optpricing/branch/main/graph/badge.svg)](https://codecov.io/gh/diljit22/optpricing)
5
- [![Ruff](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/ci.yml?branch=main&label=ruff)](https://github.com/diljit22/optpricing/actions/workflows/ci.yml)
6
- [![Docs](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/ci.yml?branch=main&label=docs)](https://github.com/diljit22/optpricing/actions/workflows/ci.yml)
5
+ [![Docs](https://img.shields.io/github/actions/workflow/status/diljit22/optpricing/pages.yml?branch=main&label=docs)](https://github.com/diljit22/optpricing/actions/workflows/pages.yml)
7
6
  [![PyPI version](https://img.shields.io/pypi/v/optpricing.svg)](https://pypi.org/project/optpricing/)
8
- [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
7
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
8
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
9
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
10
 
11
11
  `optpricing` is a Python library for pricing, calibrating, and analyzing financial derivatives. It is built with a focus on architectural clarity, model breadth, and practical usability through a robust API, command-line interface, and an interactive dashboard.
@@ -42,12 +42,13 @@ Diljit Singh
42
42
 
43
43
  ## Quick Start
44
44
 
45
- `optpricing` is designed for a straightforward installation using `pip` and is compatible with Python 3.10 and higher.
45
+ `optpricing` installs with `pip` (or `uv`) and supports Python 3.11 through 3.14.
46
46
 
47
47
  ### 1. Install the Library
48
48
 
49
49
  ```bash
50
- pip install optpricing
50
+ pip install optpricing # library + CLI
51
+ pip install "optpricing[ui]" # also the Streamlit dashboard
51
52
  ```
52
53
 
53
54
  ### 2. Download Historical Data
@@ -78,7 +79,7 @@ For more details, see the [CLI Guide](https://diljit22.github.io/optpricing/guid
78
79
 
79
80
  ### 4. Launch the Dashboard
80
81
 
81
- Visualize option chains and model outputs, interact with a pricing calculator featuring 15 models and 10 techniques.
82
+ Visualize option chains and model outputs, and interact with a pricing calculator covering 12 models and 8 techniques (the full library exposes 17 pricing models plus parity/implied-rate models, and 9 techniques). Requires the `ui` extra.
82
83
 
83
84
  ```bash
84
85
  optpricing dashboard
@@ -0,0 +1,164 @@
1
+ """Micro-benchmarks for the core pricing paths.
2
+
3
+ Usage (from the repository root)::
4
+
5
+ uv run python benchmarks/run_benchmarks.py # print table
6
+ uv run python benchmarks/run_benchmarks.py --out results/x.json
7
+ uv run python benchmarks/run_benchmarks.py --repeats 9 --only mc_heston_100k
8
+
9
+ Each case is warmed up once (numba compilation, caches) and then timed
10
+ ``repeats`` times; the median and minimum wall-clock times are reported.
11
+ Numbers are only comparable on the same machine, so results files record the
12
+ platform, interpreter and library versions alongside the git revision.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import argparse
18
+ import json
19
+ import platform
20
+ import statistics
21
+ import subprocess
22
+ import sys
23
+ import time
24
+ from collections.abc import Callable
25
+ from datetime import UTC, datetime
26
+ from pathlib import Path
27
+
28
+ import numba
29
+ import numpy as np
30
+ import scipy
31
+
32
+ from optpricing import BSMModel, HestonModel, Option, OptionType, Rate, Stock
33
+ from optpricing.techniques import (
34
+ AmericanMonteCarloTechnique,
35
+ ClosedFormTechnique,
36
+ FFTTechnique,
37
+ IntegrationTechnique,
38
+ MonteCarloTechnique,
39
+ PDETechnique,
40
+ )
41
+
42
+ OPTION = Option(strike=100.0, maturity=1.0, option_type=OptionType.CALL)
43
+ PUT = Option(strike=100.0, maturity=1.0, option_type=OptionType.PUT)
44
+ STOCK = Stock(spot=100.0, dividend=0.01)
45
+ RATE = Rate(rate=0.05)
46
+ BSM = BSMModel(params={"sigma": 0.2})
47
+ HESTON = HestonModel(
48
+ params={"v0": 0.04, "kappa": 2.0, "theta": 0.05, "rho": -0.7, "vol_of_vol": 0.5}
49
+ )
50
+
51
+
52
+ def _bsm_closed_form() -> float:
53
+ tech = ClosedFormTechnique()
54
+ for _ in range(1000):
55
+ p = tech.price(OPTION, STOCK, BSM, RATE).price
56
+ return p
57
+
58
+
59
+ def _heston_fft() -> float:
60
+ return FFTTechnique().price(OPTION, STOCK, HESTON, RATE, v0=0.04).price
61
+
62
+
63
+ def _heston_integration() -> float:
64
+ return IntegrationTechnique().price(OPTION, STOCK, HESTON, RATE, v0=0.04).price
65
+
66
+
67
+ def _cn_pde() -> float:
68
+ return PDETechnique(M=200, N=200).price(OPTION, STOCK, BSM, RATE).price
69
+
70
+
71
+ def _mc_bsm_100k() -> float:
72
+ mc = MonteCarloTechnique(n_paths=100_000, n_steps=100, seed=1)
73
+ return mc.price(OPTION, STOCK, BSM, RATE).price
74
+
75
+
76
+ def _mc_heston_100k() -> float:
77
+ mc = MonteCarloTechnique(n_paths=100_000, n_steps=100, seed=1)
78
+ return mc.price(OPTION, STOCK, HESTON, RATE, v0=0.04).price
79
+
80
+
81
+ def _lsmc_bsm_20k() -> float:
82
+ amc = AmericanMonteCarloTechnique(n_paths=20_000, n_steps=50, seed=1)
83
+ return amc.price(PUT, STOCK, BSM, RATE).price
84
+
85
+
86
+ CASES: dict[str, tuple[Callable[[], float], str]] = {
87
+ "bsm_closed_form_x1000": (_bsm_closed_form, "1000 closed-form BSM prices"),
88
+ "heston_fft": (_heston_fft, "Carr-Madan FFT, N=4096"),
89
+ "heston_integration": (_heston_integration, "Gil-Pelaez quadrature"),
90
+ "cn_pde_200x200": (_cn_pde, "Crank-Nicolson, 200 x 200 grid"),
91
+ "mc_bsm_100k": (_mc_bsm_100k, "100k paths x 100 steps, antithetic"),
92
+ "mc_heston_100k": (_mc_heston_100k, "100k paths x 100 steps, antithetic"),
93
+ "lsmc_bsm_20k": (_lsmc_bsm_20k, "Longstaff-Schwartz, 20k paths x 50 steps"),
94
+ }
95
+
96
+
97
+ def _git_rev() -> str:
98
+ try:
99
+ rev = subprocess.run(
100
+ ["git", "rev-parse", "--short", "HEAD"],
101
+ capture_output=True,
102
+ text=True,
103
+ check=True,
104
+ ).stdout.strip()
105
+ dirty = subprocess.run(
106
+ ["git", "status", "--porcelain"], capture_output=True, text=True, check=True
107
+ ).stdout.strip()
108
+ return rev + ("-dirty" if dirty else "")
109
+ except Exception: # pragma: no cover - git may be unavailable
110
+ return "unknown"
111
+
112
+
113
+ def run(repeats: int, only: list[str] | None) -> dict:
114
+ results = {}
115
+ for name, (fn, desc) in CASES.items():
116
+ if only and name not in only:
117
+ continue
118
+ value = fn() # warm-up: numba compile, lazy imports
119
+ times = []
120
+ for _ in range(repeats):
121
+ t0 = time.perf_counter()
122
+ fn()
123
+ times.append(time.perf_counter() - t0)
124
+ results[name] = {
125
+ "description": desc,
126
+ "median_ms": 1e3 * statistics.median(times),
127
+ "min_ms": 1e3 * min(times),
128
+ "repeats": repeats,
129
+ "value": float(value),
130
+ }
131
+ return results
132
+
133
+
134
+ def main() -> None:
135
+ parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0])
136
+ parser.add_argument("--repeats", type=int, default=5)
137
+ parser.add_argument("--only", nargs="*", help="subset of case names")
138
+ parser.add_argument("--out", type=Path, help="write JSON results to this path")
139
+ args = parser.parse_args()
140
+
141
+ results = run(args.repeats, args.only)
142
+ payload = {
143
+ "timestamp": datetime.now(UTC).isoformat(timespec="seconds"),
144
+ "git": _git_rev(),
145
+ "platform": platform.platform(),
146
+ "machine": platform.machine(),
147
+ "python": sys.version.split()[0],
148
+ "numpy": np.__version__,
149
+ "scipy": scipy.__version__,
150
+ "numba": numba.__version__,
151
+ "results": results,
152
+ }
153
+
154
+ print(f"{'case':26s}{'median ms':>12s}{'min ms':>10s} value")
155
+ for name, r in results.items():
156
+ print(f"{name:26s}{r['median_ms']:12.3f}{r['min_ms']:10.3f} {r['value']:.6f}")
157
+ if args.out:
158
+ args.out.parent.mkdir(parents=True, exist_ok=True)
159
+ args.out.write_text(json.dumps(payload, indent=2) + "\n")
160
+ print(f"\nwrote {args.out}")
161
+
162
+
163
+ if __name__ == "__main__":
164
+ main()
@@ -0,0 +1,148 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "setuptools-scm>=8"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "optpricing"
7
+ dynamic = ["version"]
8
+ description = "A financial options pricing and analysis library."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Diljit Singh" }]
14
+ keywords = [
15
+ "options",
16
+ "derivatives",
17
+ "quantitative-finance",
18
+ "option-pricing",
19
+ "heston",
20
+ "monte-carlo",
21
+ "fft",
22
+ "calibration",
23
+ ]
24
+ classifiers = [
25
+ "Development Status :: 4 - Beta",
26
+ "Intended Audience :: Financial and Insurance Industry",
27
+ "Intended Audience :: Science/Research",
28
+ "Operating System :: OS Independent",
29
+ "Programming Language :: Python :: 3",
30
+ "Programming Language :: Python :: 3 :: Only",
31
+ "Programming Language :: Python :: 3.11",
32
+ "Programming Language :: Python :: 3.12",
33
+ "Programming Language :: Python :: 3.13",
34
+ "Programming Language :: Python :: 3.14",
35
+ "Topic :: Office/Business :: Financial :: Investment",
36
+ "Topic :: Scientific/Engineering :: Mathematics",
37
+ ]
38
+
39
+ # Floors are the oldest releases with wheels for every supported CPython (3.11-3.14)
40
+ # and were verified with `uv pip install --resolution lowest-direct` + the full test
41
+ # suite on each interpreter. Do not raise a floor without re-running that check.
42
+ dependencies = [
43
+ "numpy>=2.3.2",
44
+ "scipy>=1.16.1",
45
+ "pandas>=2.3.3",
46
+ "numba>=0.63",
47
+ "pyyaml>=6.0.3",
48
+ "typer>=0.15.3",
49
+ "yfinance>=0.2.63",
50
+ ]
51
+
52
+ [project.optional-dependencies]
53
+ # Streamlit dashboard (`optpricing dashboard`).
54
+ ui = [
55
+ "streamlit>=1.45.1",
56
+ "plotly>=6.1.2",
57
+ ]
58
+
59
+ [project.urls]
60
+ Homepage = "https://diljit22.github.io/optpricing/"
61
+ Documentation = "https://diljit22.github.io/optpricing/"
62
+ Repository = "https://github.com/Diljit22/optpricing"
63
+ Issues = "https://github.com/Diljit22/optpricing/issues"
64
+ Changelog = "https://github.com/Diljit22/optpricing/blob/main/CHANGELOG.md"
65
+
66
+ [project.scripts]
67
+ optpricing = "optpricing.cli.main:app"
68
+
69
+ # Development tooling (PEP 735). Not published with the package.
70
+ # uv sync -> default `dev` group (test + lint + docs + pre-commit)
71
+ # uv sync --group test -> just what the test suite needs
72
+ # pip install -e . --group dev -> pip >= 25.1
73
+ [dependency-groups]
74
+ test = [
75
+ "optpricing[ui]",
76
+ "pytest>=8.3",
77
+ "pytest-cov>=5",
78
+ ]
79
+ lint = [
80
+ "ruff==0.17.3",
81
+ ]
82
+ docs = [
83
+ "mkdocs>=1.6.1",
84
+ "mkdocs-material>=9.6",
85
+ "mkdocstrings[python]>=0.29",
86
+ "mkdocs-section-index>=0.3.9",
87
+ ]
88
+ profile = [
89
+ "line-profiler>=4.2",
90
+ "py-spy>=0.4",
91
+ ]
92
+ dev = [
93
+ { include-group = "test" },
94
+ { include-group = "lint" },
95
+ { include-group = "docs" },
96
+ "pre-commit>=4.0",
97
+ ]
98
+
99
+ [tool.uv]
100
+ default-groups = ["dev"]
101
+
102
+ [tool.setuptools]
103
+ package-dir = { "" = "src" }
104
+
105
+ [tool.setuptools.packages.find]
106
+ where = ["src"]
107
+
108
+ [tool.setuptools_scm]
109
+ version_scheme = "post-release"
110
+ local_scheme = "no-local-version"
111
+
112
+ [tool.ruff]
113
+ line-length = 88
114
+
115
+ [tool.ruff.lint]
116
+ select = ["E", "W", "F", "I", "N", "UP", "NPY"]
117
+ ignore = ["N803", "N806"]
118
+
119
+ [tool.ruff.lint.per-file-ignores]
120
+ # streamlit page files are named for the sidebar, not for PEP 8
121
+ "src/optpricing/dashboard/pages/*.py" = ["N999"]
122
+ "src/optpricing/dashboard/Home.py" = ["N999"]
123
+ # numba kernels use the legacy np.random API on purpose
124
+ "src/optpricing/techniques/kernels/mc_kernels.py" = ["NPY002"]
125
+ "src/optpricing/techniques/kernels/american_mc_kernels.py" = ["NPY002", "E722"]
126
+ "src/optpricing/techniques/kernels/path_kernels.py" = ["NPY002"]
127
+
128
+ [tool.ruff.format]
129
+ quote-style = "double"
130
+ skip-magic-trailing-comma = false
131
+
132
+ [tool.pytest.ini_options]
133
+ minversion = "8.0"
134
+ testpaths = ["tests"]
135
+ # Coverage is opt-in: `pytest --cov` (CI does this); plain `pytest` stays fast and debuggable.
136
+ addopts = "-ra --strict-markers --strict-config"
137
+ xfail_strict = true
138
+ filterwarnings = [
139
+ # Several fixtures deliberately use Feller-violating Heston/CIR parameters.
140
+ "ignore:.*do not satisfy the Feller condition.*:UserWarning",
141
+ ]
142
+
143
+ [tool.coverage.run]
144
+ source = ["optpricing"]
145
+ omit = ["*/dashboard/pages/*"]
146
+
147
+ [tool.coverage.report]
148
+ show_missing = true
@@ -95,7 +95,7 @@ class VolatilitySurface:
95
95
  market_ivs = self._calculate_ivs(stock, rate, self.data["marketPrice"])
96
96
  self.surface = self.data.copy()
97
97
  self.surface["iv"] = market_ivs
98
- self.surface.dropna(inplace=True)
98
+ self.surface = self.surface.dropna()
99
99
  self.surface = self.surface[
100
100
  (self.surface["iv"] > 1e-4) & (self.surface["iv"] < 2.0)
101
101
  ]
@@ -146,5 +146,5 @@ class VolatilitySurface:
146
146
  )
147
147
  self.surface = self.data.copy()
148
148
  self.surface["iv"] = model_ivs
149
- self.surface.dropna(inplace=True)
149
+ self.surface = self.surface.dropna()
150
150
  return self
@@ -15,12 +15,14 @@ def dashboard():
15
15
  Launches the Streamlit dashboard application.
16
16
  """
17
17
  try:
18
- with resources.path("optpricing.dashboard", "Home.py") as app_path:
18
+ home = resources.files("optpricing.dashboard").joinpath("Home.py")
19
+ with resources.as_file(home) as app_path:
19
20
  typer.echo(f"Launching Streamlit dashboard from: {app_path}")
20
21
  subprocess.run(["streamlit", "run", str(app_path)], check=True)
21
22
  except FileNotFoundError:
22
23
  typer.secho(
23
- "Error: 'streamlit' command not found. Hint: `pip install optpricing[app]`",
24
+ "Error: 'streamlit' command not found. "
25
+ "Hint: `pip install 'optpricing[ui]'`",
24
26
  fg=typer.colors.RED,
25
27
  )
26
28
  raise typer.Exit(code=1)
@@ -172,7 +172,7 @@ def price(
172
172
  stock = Stock(spot=spot, dividend=q_div)
173
173
  rate = Rate(rate=r_rate)
174
174
  maturity_years = (
175
- pd.to_datetime(maturity) - pd.Timestamp.utcnow().tz_localize(None)
175
+ pd.to_datetime(maturity) - pd.Timestamp.now(tz="UTC").tz_localize(None)
176
176
  ).days / 365.25
177
177
  if maturity_years <= 0:
178
178
  _err("Maturity date must be in the future.")
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from pathlib import Path
5
+
6
+ import yaml
7
+
8
+ __doc__ = """
9
+ Resolve the project root, read the optional ``config.yaml`` and expose the data
10
+ and artifact directories.
11
+
12
+ The root is ``$OPTPRICING_HOME`` if set, otherwise the current working directory.
13
+ Running from a source checkout therefore behaves as before, while an installed
14
+ package no longer writes ``config.yaml`` or data folders next to its own modules
15
+ in ``site-packages``. Nothing is created at import time; writers create the
16
+ directory they need (see :func:`ensure_directories`).
17
+ """
18
+
19
+ DEFAULT_CONFIG: dict[str, object] = {
20
+ "live_data_provider": "yfinance",
21
+ "data_directory": "data",
22
+ "artifacts_directory": "artifacts",
23
+ }
24
+
25
+ PROJECT_ROOT = Path(os.environ.get("OPTPRICING_HOME", Path.cwd())).resolve()
26
+ CONFIG_FILE_PATH = PROJECT_ROOT / "config.yaml"
27
+
28
+
29
+ def _load_config(path: Path) -> dict:
30
+ if not path.exists():
31
+ return dict(DEFAULT_CONFIG)
32
+ with open(path) as f:
33
+ loaded = yaml.safe_load(f) or {}
34
+ return {**DEFAULT_CONFIG, **loaded}
35
+
36
+
37
+ _config = _load_config(CONFIG_FILE_PATH)
38
+
39
+ # Directory Management
40
+ DATA_DIR = PROJECT_ROOT / str(_config.get("data_directory", "data"))
41
+ ARTIFACTS_DIR = PROJECT_ROOT / str(_config.get("artifacts_directory", "artifacts"))
42
+
43
+ # Input Data Directories
44
+ MARKET_SNAPSHOT_DIR = DATA_DIR / "market_data_snapshots"
45
+ HISTORICAL_DIR = DATA_DIR / "historical_data"
46
+
47
+ # Output Artifact Directories
48
+ BACKTEST_LOGS_DIR = ARTIFACTS_DIR / "backtest_logs"
49
+ CALIBRATED_PARAMS_DIR = ARTIFACTS_DIR / "calibrated_params"
50
+ CALIBRATION_LOGS_DIR = ARTIFACTS_DIR / "calibration_logs"
51
+
52
+ ALL_DIRS = [
53
+ DATA_DIR,
54
+ ARTIFACTS_DIR,
55
+ MARKET_SNAPSHOT_DIR,
56
+ HISTORICAL_DIR,
57
+ BACKTEST_LOGS_DIR,
58
+ CALIBRATED_PARAMS_DIR,
59
+ CALIBRATION_LOGS_DIR,
60
+ ]
61
+
62
+
63
+ def ensure_directories() -> None:
64
+ """Create all data and artifact directories (idempotent)."""
65
+ for path in ALL_DIRS:
66
+ path.mkdir(parents=True, exist_ok=True)
@@ -42,6 +42,7 @@ def save_historical_returns(
42
42
 
43
43
  log_returns = np.log(data["Close"] / data["Close"].shift(1)).dropna()
44
44
  filename = HISTORICAL_DIR / f"{ticker}_{period}_returns.parquet"
45
+ filename.parent.mkdir(parents=True, exist_ok=True)
45
46
  log_returns.to_frame(name="log_return").to_parquet(filename)
46
47
 
47
48
  print(f" -> Saved to {filename}")