quantark 0.1.0__py3-none-any.whl

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 (399) hide show
  1. quantark/__init__.py +3 -0
  2. quantark/_compat.py +150 -0
  3. quantark/asset/__init__.py +8 -0
  4. quantark/asset/bond/__init__.py +2 -0
  5. quantark/asset/bond/engine/__init__.py +44 -0
  6. quantark/asset/bond/engine/analytical/__init__.py +12 -0
  7. quantark/asset/bond/engine/analytical/black_engine.py +583 -0
  8. quantark/asset/bond/engine/analytical/bond_forward_engine.py +390 -0
  9. quantark/asset/bond/engine/analytical/bond_futures_engine.py +569 -0
  10. quantark/asset/bond/engine/convertible/__init__.py +12 -0
  11. quantark/asset/bond/engine/convertible/convertible_bond_engine.py +800 -0
  12. quantark/asset/bond/engine/discount/__init__.py +10 -0
  13. quantark/asset/bond/engine/discount/bond_discount_engine.py +517 -0
  14. quantark/asset/bond/engine/discount/frn_engine.py +913 -0
  15. quantark/asset/bond/engine/pde/__init__.py +14 -0
  16. quantark/asset/bond/engine/pde/convertible/__init__.py +21 -0
  17. quantark/asset/bond/engine/pde/convertible/jump_diffusion_engine.py +603 -0
  18. quantark/asset/bond/engine/pde/convertible/pde_params.py +59 -0
  19. quantark/asset/bond/engine/pde/convertible/tf_engine.py +546 -0
  20. quantark/asset/bond/engine/tree/__init__.py +14 -0
  21. quantark/asset/bond/engine/tree/convertible/__init__.py +21 -0
  22. quantark/asset/bond/engine/tree/convertible/binomial_engine.py +488 -0
  23. quantark/asset/bond/engine/tree/convertible/tree_params.py +72 -0
  24. quantark/asset/bond/engine/tree/convertible/trinomial_engine.py +1341 -0
  25. quantark/asset/bond/product/__init__.py +37 -0
  26. quantark/asset/bond/product/base_bond_product.py +114 -0
  27. quantark/asset/bond/product/convertible/__init__.py +16 -0
  28. quantark/asset/bond/product/convertible/convertible_bond.py +595 -0
  29. quantark/asset/bond/product/couponbond/__init__.py +12 -0
  30. quantark/asset/bond/product/couponbond/fixed_bond.py +285 -0
  31. quantark/asset/bond/product/couponbond/frn.py +538 -0
  32. quantark/asset/bond/product/forward/__init__.py +9 -0
  33. quantark/asset/bond/product/forward/base_bond_forward.py +92 -0
  34. quantark/asset/bond/product/forward/bond_forward.py +335 -0
  35. quantark/asset/bond/product/futures/__init__.py +8 -0
  36. quantark/asset/bond/product/futures/bond_futures.py +532 -0
  37. quantark/asset/bond/product/option/__init__.py +9 -0
  38. quantark/asset/bond/product/option/euro_short_term_bond_option.py +231 -0
  39. quantark/asset/bond/riskmeasures/__init__.py +13 -0
  40. quantark/asset/bond/riskmeasures/bond_greeks_calculator.py +484 -0
  41. quantark/asset/bond/schedule/__init__.py +21 -0
  42. quantark/asset/bond/schedule/cashflow.py +595 -0
  43. quantark/asset/equity/__init__.py +11 -0
  44. quantark/asset/equity/analysis/__init__.py +4 -0
  45. quantark/asset/equity/analysis/autocallable_path_analyzer.py +257 -0
  46. quantark/asset/equity/engine/__init__.py +84 -0
  47. quantark/asset/equity/engine/analytical/__init__.py +37 -0
  48. quantark/asset/equity/engine/analytical/american_option_engine.py +682 -0
  49. quantark/asset/equity/engine/analytical/asian_option_analytical_engine.py +1102 -0
  50. quantark/asset/equity/engine/analytical/barrier_analytical_engine.py +455 -0
  51. quantark/asset/equity/engine/analytical/black_scholes_engine.py +322 -0
  52. quantark/asset/equity/engine/analytical/deltaone_engine.py +340 -0
  53. quantark/asset/equity/engine/analytical/digital_option_engine.py +168 -0
  54. quantark/asset/equity/engine/analytical/double_barrier_option_engine.py +481 -0
  55. quantark/asset/equity/engine/analytical/double_sharkfin_option_analytical_engine.py +508 -0
  56. quantark/asset/equity/engine/analytical/one_touch_analytical_engine.py +302 -0
  57. quantark/asset/equity/engine/analytical/range_accrual_analytical_engine.py +396 -0
  58. quantark/asset/equity/engine/analytical/single_sharkfin_option_analytical_engine.py +229 -0
  59. quantark/asset/equity/engine/base_engine.py +137 -0
  60. quantark/asset/equity/engine/event_stats.py +85 -0
  61. quantark/asset/equity/engine/mc/__init__.py +31 -0
  62. quantark/asset/equity/engine/mc/american_option_mc_engine.py +485 -0
  63. quantark/asset/equity/engine/mc/asian_option_mc_engine.py +678 -0
  64. quantark/asset/equity/engine/mc/barrier_option_mc_engine.py +726 -0
  65. quantark/asset/equity/engine/mc/digital_option_mc_engine.py +419 -0
  66. quantark/asset/equity/engine/mc/double_sharkfin_option_mc_engine.py +676 -0
  67. quantark/asset/equity/engine/mc/euro_mc_engine.py +423 -0
  68. quantark/asset/equity/engine/mc/phoenix_mc_engine.py +1206 -0
  69. quantark/asset/equity/engine/mc/range_accrual_mc_engine.py +738 -0
  70. quantark/asset/equity/engine/mc/single_sharkfin_option_mc_engine.py +549 -0
  71. quantark/asset/equity/engine/mc/snowball_mc_engine.py +2250 -0
  72. quantark/asset/equity/engine/pde/__init__.py +36 -0
  73. quantark/asset/equity/engine/pde/american_pde_solver.py +211 -0
  74. quantark/asset/equity/engine/pde/barrier_pde_solver.py +692 -0
  75. quantark/asset/equity/engine/pde/base_pde_solver.py +994 -0
  76. quantark/asset/equity/engine/pde/double_barrier_pde_solver.py +510 -0
  77. quantark/asset/equity/engine/pde/double_one_touch_pde_solver.py +435 -0
  78. quantark/asset/equity/engine/pde/european_pde_solver.py +170 -0
  79. quantark/asset/equity/engine/pde/ko_reset_snowball_pde_solver.py +477 -0
  80. quantark/asset/equity/engine/pde/one_touch_pde_solver.py +439 -0
  81. quantark/asset/equity/engine/pde/phoenix_pde_solver.py +613 -0
  82. quantark/asset/equity/engine/pde/snowball_pde_solver.py +1810 -0
  83. quantark/asset/equity/engine/pde/spatial_grid.py +750 -0
  84. quantark/asset/equity/engine/pde/time_grid.py +308 -0
  85. quantark/asset/equity/engine/pde_engine.py +238 -0
  86. quantark/asset/equity/engine/quad/__init__.py +23 -0
  87. quantark/asset/equity/engine/quad/discrete_quad_engine.py +106 -0
  88. quantark/asset/equity/engine/quad/european_quad_engine.py +325 -0
  89. quantark/asset/equity/engine/quad/ko_reset_snowball_quad_engine.py +362 -0
  90. quantark/asset/equity/engine/quad/phoenix_quad_engine.py +614 -0
  91. quantark/asset/equity/engine/quad/quad_adapters.py +1260 -0
  92. quantark/asset/equity/engine/quad/quad_core.py +513 -0
  93. quantark/asset/equity/engine/quad/quad_math.py +219 -0
  94. quantark/asset/equity/engine/quad/snowball_quad_engine.py +1137 -0
  95. quantark/asset/equity/engine/validation/script/benchmark_check_american_analytical.py +117 -0
  96. quantark/asset/equity/engine/validation/script/benchmark_check_american_pde.py +114 -0
  97. quantark/asset/equity/engine/validation/script/benchmark_check_asian_analytical.py +440 -0
  98. quantark/asset/equity/engine/validation/script/benchmark_check_barrier_analytical.py +269 -0
  99. quantark/asset/equity/engine/validation/script/benchmark_check_barrier_pde_solver.py +636 -0
  100. quantark/asset/equity/engine/validation/script/benchmark_check_digital_option.py +256 -0
  101. quantark/asset/equity/engine/validation/script/benchmark_check_snowball_pde_solver.py +807 -0
  102. quantark/asset/equity/engine/validation/script/boundary_check_american_analytical.py +290 -0
  103. quantark/asset/equity/engine/validation/script/boundary_check_american_pde.py +242 -0
  104. quantark/asset/equity/engine/validation/script/boundary_check_asian_analytical.py +612 -0
  105. quantark/asset/equity/engine/validation/script/boundary_check_barrier_analytical.py +434 -0
  106. quantark/asset/equity/engine/validation/script/boundary_check_barrier_pde_solver.py +748 -0
  107. quantark/asset/equity/engine/validation/script/boundary_check_digital_option.py +575 -0
  108. quantark/asset/equity/engine/validation/script/boundary_check_snowball_pde_solver.py +1101 -0
  109. quantark/asset/equity/engine/validation/script/greeks_check_digital_option.py +349 -0
  110. quantark/asset/equity/engine/validation/script/mc_comparison_barrier_pde.py +270 -0
  111. quantark/asset/equity/engine/validation/script/quick_mc_compare.py +51 -0
  112. quantark/asset/equity/engine/validation/script/validation_stepdown_improved.py +97 -0
  113. quantark/asset/equity/param/__init__.py +24 -0
  114. quantark/asset/equity/param/engine_param_profiles.py +325 -0
  115. quantark/asset/equity/param/engine_params.py +728 -0
  116. quantark/asset/equity/process/__init__.py +7 -0
  117. quantark/asset/equity/process/bsm/__init__.py +7 -0
  118. quantark/asset/equity/process/bsm/bsm_process.py +108 -0
  119. quantark/asset/equity/process/bsm/qmc_brownian_bridge.py +401 -0
  120. quantark/asset/equity/process/bsm/qmc_path_generator.py +694 -0
  121. quantark/asset/equity/process/bsm/qmc_rqmc_driver.py +163 -0
  122. quantark/asset/equity/process/bsm/qmc_sobol.py +195 -0
  123. quantark/asset/equity/process/bsm/qmc_variance_reduction.py +292 -0
  124. quantark/asset/equity/product/__init__.py +8 -0
  125. quantark/asset/equity/product/base_equity_product.py +72 -0
  126. quantark/asset/equity/product/deltaone/__init__.py +22 -0
  127. quantark/asset/equity/product/deltaone/base_deltaone_product.py +147 -0
  128. quantark/asset/equity/product/deltaone/futures.py +485 -0
  129. quantark/asset/equity/product/deltaone/spot_instrument.py +118 -0
  130. quantark/asset/equity/product/option/__init__.py +104 -0
  131. quantark/asset/equity/product/option/american_option.py +114 -0
  132. quantark/asset/equity/product/option/asian_option.py +531 -0
  133. quantark/asset/equity/product/option/barrier_option.py +289 -0
  134. quantark/asset/equity/product/option/base_equity_option.py +659 -0
  135. quantark/asset/equity/product/option/digital_option.py +102 -0
  136. quantark/asset/equity/product/option/double_barrier_option.py +286 -0
  137. quantark/asset/equity/product/option/double_one_touch_option.py +310 -0
  138. quantark/asset/equity/product/option/double_sharkfin_option.py +466 -0
  139. quantark/asset/equity/product/option/european_vanilla_option.py +103 -0
  140. quantark/asset/equity/product/option/ko_reset_snowball_option.py +563 -0
  141. quantark/asset/equity/product/option/observation_schedule.py +530 -0
  142. quantark/asset/equity/product/option/one_touch_option.py +287 -0
  143. quantark/asset/equity/product/option/phoenix_config.py +116 -0
  144. quantark/asset/equity/product/option/phoenix_helpers.py +576 -0
  145. quantark/asset/equity/product/option/phoenix_option.py +1167 -0
  146. quantark/asset/equity/product/option/range_accrual_config.py +288 -0
  147. quantark/asset/equity/product/option/range_accrual_helpers.py +608 -0
  148. quantark/asset/equity/product/option/range_accrual_option.py +526 -0
  149. quantark/asset/equity/product/option/single_sharkfin_option.py +420 -0
  150. quantark/asset/equity/product/option/snowball_config.py +261 -0
  151. quantark/asset/equity/product/option/snowball_helpers.py +977 -0
  152. quantark/asset/equity/product/option/snowball_option.py +1242 -0
  153. quantark/asset/equity/report/__init__.py +15 -0
  154. quantark/asset/equity/report/autocallable_risk_report.py +2118 -0
  155. quantark/asset/equity/report/plotting.py +87 -0
  156. quantark/asset/equity/report/snowball_risk_comparison_report.py +2230 -0
  157. quantark/asset/equity/report/surfaces.py +123 -0
  158. quantark/asset/equity/report/term_structure.py +126 -0
  159. quantark/asset/equity/riskmeasures/__init__.py +7 -0
  160. quantark/asset/equity/riskmeasures/greeks_calculator.py +1204 -0
  161. quantark/asset/rate/__init__.py +58 -0
  162. quantark/asset/rate/engine/__init__.py +25 -0
  163. quantark/asset/rate/engine/cap_floor_engine.py +514 -0
  164. quantark/asset/rate/engine/fra_engine.py +286 -0
  165. quantark/asset/rate/engine/irs_discount_engine.py +891 -0
  166. quantark/asset/rate/engine/swaption_engine.py +587 -0
  167. quantark/asset/rate/product/__init__.py +67 -0
  168. quantark/asset/rate/product/cap_floor.py +550 -0
  169. quantark/asset/rate/product/fra.py +219 -0
  170. quantark/asset/rate/product/irs.py +1223 -0
  171. quantark/asset/rate/product/swaption.py +372 -0
  172. quantark/backtest/__init__.py +153 -0
  173. quantark/backtest/base.py +263 -0
  174. quantark/backtest/dashboard.py +874 -0
  175. quantark/backtest/equity/__init__.py +35 -0
  176. quantark/backtest/equity/config.py +118 -0
  177. quantark/backtest/equity/engine.py +408 -0
  178. quantark/backtest/equity/hedge_executor.py +374 -0
  179. quantark/backtest/equity/metrics.py +396 -0
  180. quantark/backtest/equity/results.py +232 -0
  181. quantark/backtest/equity/state.py +252 -0
  182. quantark/backtest/examples/__init__.py +4 -0
  183. quantark/backtest/examples/advanced_backtest.py +345 -0
  184. quantark/backtest/examples/basic_delta_hedge.py +246 -0
  185. quantark/backtest/examples/fi_dv01_hedge.py +267 -0
  186. quantark/backtest/fi/__init__.py +30 -0
  187. quantark/backtest/fi/config.py +114 -0
  188. quantark/backtest/fi/engine.py +378 -0
  189. quantark/backtest/fi/hedge_executor.py +254 -0
  190. quantark/backtest/fi/metrics.py +308 -0
  191. quantark/backtest/fi/results.py +193 -0
  192. quantark/backtest/fi/state.py +212 -0
  193. quantark/backtest/logger.py +393 -0
  194. quantark/backtest/otc/__init__.py +74 -0
  195. quantark/backtest/otc/_replay.py +637 -0
  196. quantark/backtest/otc/book_engine.py +587 -0
  197. quantark/backtest/otc/config.py +175 -0
  198. quantark/backtest/otc/dashboard.py +1006 -0
  199. quantark/backtest/otc/engine.py +420 -0
  200. quantark/backtest/otc/engine_factory.py +138 -0
  201. quantark/backtest/otc/market.py +216 -0
  202. quantark/backtest/otc/results.py +107 -0
  203. quantark/backtest/otc/state.py +166 -0
  204. quantark/backtest/report_generator.py +608 -0
  205. quantark/backtest/strategy/__init__.py +28 -0
  206. quantark/backtest/strategy/base_strategy.py +235 -0
  207. quantark/backtest/strategy/convexity_neutral_strategy.py +247 -0
  208. quantark/backtest/strategy/delta_neutral_strategy.py +283 -0
  209. quantark/backtest/strategy/dv01_neutral_strategy.py +283 -0
  210. quantark/backtest/transaction_costs.py +485 -0
  211. quantark/backtest/visualizer.py +1019 -0
  212. quantark/cashleg/__init__.py +31 -0
  213. quantark/cashleg/accrual_leg.py +120 -0
  214. quantark/cashleg/base.py +48 -0
  215. quantark/cashleg/base_amount.py +60 -0
  216. quantark/cashleg/deterministic_leg.py +39 -0
  217. quantark/cashleg/event_distribution.py +262 -0
  218. quantark/cashleg/fixed_payoff_leg.py +92 -0
  219. quantark/cashleg/leg_schedule.py +95 -0
  220. quantark/cashleg/leg_valuator.py +40 -0
  221. quantark/dynamicscenario/__init__.py +97 -0
  222. quantark/dynamicscenario/base.py +297 -0
  223. quantark/dynamicscenario/config.py +122 -0
  224. quantark/dynamicscenario/engine.py +703 -0
  225. quantark/dynamicscenario/equity/__init__.py +14 -0
  226. quantark/dynamicscenario/fi/__init__.py +24 -0
  227. quantark/dynamicscenario/fi/config.py +149 -0
  228. quantark/dynamicscenario/fi/engine.py +500 -0
  229. quantark/dynamicscenario/fi/results.py +503 -0
  230. quantark/dynamicscenario/path/__init__.py +17 -0
  231. quantark/dynamicscenario/path/day_path.py +397 -0
  232. quantark/dynamicscenario/path/fi_path_library.py +488 -0
  233. quantark/dynamicscenario/path/path_builder.py +726 -0
  234. quantark/dynamicscenario/path/path_library.py +620 -0
  235. quantark/dynamicscenario/report/__init__.py +12 -0
  236. quantark/dynamicscenario/report/dynamic_report.py +1175 -0
  237. quantark/dynamicscenario/report/visualizer.py +1586 -0
  238. quantark/dynamicscenario/results/__init__.py +19 -0
  239. quantark/dynamicscenario/results/dynamic_results.py +579 -0
  240. quantark/dynamicscenario/results/result_exporter.py +438 -0
  241. quantark/param/__init__.py +75 -0
  242. quantark/param/basis/__init__.py +19 -0
  243. quantark/param/basis/basis_yield.py +301 -0
  244. quantark/param/div/__init__.py +16 -0
  245. quantark/param/div/dividend_yield.py +123 -0
  246. quantark/param/index/__init__.py +52 -0
  247. quantark/param/index/rate_index.py +568 -0
  248. quantark/param/quote/__init__.py +7 -0
  249. quantark/param/quote/spot_quote.py +35 -0
  250. quantark/param/rrf/__init__.py +22 -0
  251. quantark/param/rrf/rate_curve.py +436 -0
  252. quantark/param/vol/__init__.py +6 -0
  253. quantark/param/vol/vol_surface.py +118 -0
  254. quantark/portfolio/__init__.py +61 -0
  255. quantark/portfolio/base.py +203 -0
  256. quantark/portfolio/equity/__init__.py +17 -0
  257. quantark/portfolio/equity/portfolio.py +391 -0
  258. quantark/portfolio/equity/position.py +368 -0
  259. quantark/portfolio/fi/__init__.py +14 -0
  260. quantark/portfolio/fi/portfolio.py +424 -0
  261. quantark/portfolio/fi/position.py +272 -0
  262. quantark/portfolio/portfolio_snapshot.py +221 -0
  263. quantark/portfolio/portfolio_storage.py +414 -0
  264. quantark/priceenv/__init__.py +7 -0
  265. quantark/priceenv/pricing_environment.py +196 -0
  266. quantark/rfq/__init__.py +32 -0
  267. quantark/rfq/builders.py +102 -0
  268. quantark/rfq/models.py +214 -0
  269. quantark/rfq/registry.py +611 -0
  270. quantark/rfq/service.py +237 -0
  271. quantark/simm/__init__.py +155 -0
  272. quantark/simm/calibration/__init__.py +206 -0
  273. quantark/simm/calibration/accessors.py +439 -0
  274. quantark/simm/calibration/commodity.py +156 -0
  275. quantark/simm/calibration/credit_non_qualifying.py +79 -0
  276. quantark/simm/calibration/credit_qualifying.py +130 -0
  277. quantark/simm/calibration/cross_risk.py +39 -0
  278. quantark/simm/calibration/equity.py +125 -0
  279. quantark/simm/calibration/fx.py +92 -0
  280. quantark/simm/calibration/ir.py +152 -0
  281. quantark/simm/calibration/version.py +33 -0
  282. quantark/simm/config.py +186 -0
  283. quantark/simm/crif/__init__.py +35 -0
  284. quantark/simm/crif/models.py +230 -0
  285. quantark/simm/crif/parser.py +585 -0
  286. quantark/simm/engines/__init__.py +62 -0
  287. quantark/simm/engines/aggregation/__init__.py +67 -0
  288. quantark/simm/engines/aggregation/addon.py +141 -0
  289. quantark/simm/engines/aggregation/bucket_aggregator.py +298 -0
  290. quantark/simm/engines/aggregation/concentration.py +349 -0
  291. quantark/simm/engines/aggregation/product_class_aggregator.py +183 -0
  292. quantark/simm/engines/aggregation/risk_class_aggregator.py +403 -0
  293. quantark/simm/engines/aggregation/simm_calculator.py +430 -0
  294. quantark/simm/engines/aggregation/weighted_sensitivity.py +272 -0
  295. quantark/simm/engines/base.py +231 -0
  296. quantark/simm/engines/classification/__init__.py +10 -0
  297. quantark/simm/engines/classification/bucket_mapper.py +347 -0
  298. quantark/simm/engines/factory.py +137 -0
  299. quantark/simm/engines/portfolio_adapter.py +336 -0
  300. quantark/simm/engines/result.py +176 -0
  301. quantark/simm/engines/risk_class/__init__.py +18 -0
  302. quantark/simm/engines/risk_class/equity_engine.py +263 -0
  303. quantark/simm/engines/risk_class/ir_engine.py +264 -0
  304. quantark/simm/report/__init__.py +17 -0
  305. quantark/simm/report/crif_export.py +284 -0
  306. quantark/simm/report/excel_generator.py +401 -0
  307. quantark/simm/report/html_generator.py +840 -0
  308. quantark/simm/results/__init__.py +38 -0
  309. quantark/simm/results/attribution.py +313 -0
  310. quantark/simm/results/simm_result.py +339 -0
  311. quantark/simm/results/whatif.py +268 -0
  312. quantark/simm/sensitivity.py +533 -0
  313. quantark/simm/taxonomy.py +416 -0
  314. quantark/stresstest/__init__.py +67 -0
  315. quantark/stresstest/base.py +116 -0
  316. quantark/stresstest/config.py +5 -0
  317. quantark/stresstest/engine.py +5 -0
  318. quantark/stresstest/equity/__init__.py +17 -0
  319. quantark/stresstest/equity/config.py +69 -0
  320. quantark/stresstest/equity/engine.py +272 -0
  321. quantark/stresstest/equity/report/__init__.py +7 -0
  322. quantark/stresstest/equity/report/report_generator.py +423 -0
  323. quantark/stresstest/equity/report/visualizer.py +328 -0
  324. quantark/stresstest/equity/results.py +145 -0
  325. quantark/stresstest/fi/__init__.py +15 -0
  326. quantark/stresstest/fi/config.py +59 -0
  327. quantark/stresstest/fi/engine.py +213 -0
  328. quantark/stresstest/fi/metrics.py +60 -0
  329. quantark/stresstest/fi/results.py +64 -0
  330. quantark/stresstest/report/__init__.py +12 -0
  331. quantark/stresstest/report/report_generator.py +5 -0
  332. quantark/stresstest/report/visualizer.py +5 -0
  333. quantark/stresstest/results/__init__.py +16 -0
  334. quantark/stresstest/results/result_aggregator.py +325 -0
  335. quantark/stresstest/results/result_exporter.py +286 -0
  336. quantark/stresstest/results/stress_results.py +5 -0
  337. quantark/stresstest/scenario/__init__.py +13 -0
  338. quantark/stresstest/scenario/scenario.py +242 -0
  339. quantark/stresstest/scenario/scenario_builder.py +376 -0
  340. quantark/stresstest/scenario/scenario_library.py +435 -0
  341. quantark/stresstest/scenario/scenario_storage.py +224 -0
  342. quantark/stresstest/stress/__init__.py +13 -0
  343. quantark/stresstest/stress/stress_applicator.py +590 -0
  344. quantark/stresstest/stress/stress_types.py +142 -0
  345. quantark/util/__init__.py +23 -0
  346. quantark/util/barrier_shift.py +44 -0
  347. quantark/util/calendar/__init__.py +27 -0
  348. quantark/util/calendar/business_calendar.py +584 -0
  349. quantark/util/calendar/day_counter.py +517 -0
  350. quantark/util/calendar/holidayfile/china.csv +1920 -0
  351. quantark/util/calendar/holidayfile/china_sse.csv +1462 -0
  352. quantark/util/enum/__init__.py +81 -0
  353. quantark/util/enum/bond_enums.py +112 -0
  354. quantark/util/enum/deltaone_enums.py +16 -0
  355. quantark/util/enum/engine_enums.py +137 -0
  356. quantark/util/enum/greeks_enums.py +29 -0
  357. quantark/util/enum/option_enums.py +221 -0
  358. quantark/util/exceptions.py +66 -0
  359. quantark/util/marketdata/__init__.py +39 -0
  360. quantark/util/marketdata/adapter/base_adapter.py +203 -0
  361. quantark/util/marketdata/adapter/mock_adapter.py +265 -0
  362. quantark/util/marketdata/converter.py +289 -0
  363. quantark/util/marketdata/example_usage.py +314 -0
  364. quantark/util/marketdata/generator/__init__.py +7 -0
  365. quantark/util/marketdata/generator/mock_generator.py +466 -0
  366. quantark/util/marketdata/models.py +358 -0
  367. quantark/util/marketdata/storage/__init__.py +7 -0
  368. quantark/util/marketdata/storage/parquet_storage.py +340 -0
  369. quantark/util/numerical/__init__.py +98 -0
  370. quantark/util/numerical/comparison.py +219 -0
  371. quantark/util/numerical/constants.py +98 -0
  372. quantark/util/numerical/formatting.py +380 -0
  373. quantark/util/numerical/pnl.py +17 -0
  374. quantark/util/numerical/safe_math.py +238 -0
  375. quantark/util/numerical/validation.py +315 -0
  376. quantark/var/__init__.py +39 -0
  377. quantark/var/attribution.py +398 -0
  378. quantark/var/backtest/__init__.py +7 -0
  379. quantark/var/backtest/var_backtester.py +309 -0
  380. quantark/var/base.py +63 -0
  381. quantark/var/config.py +219 -0
  382. quantark/var/engines/__init__.py +13 -0
  383. quantark/var/engines/historical.py +925 -0
  384. quantark/var/engines/monte_carlo.py +870 -0
  385. quantark/var/engines/parametric.py +1199 -0
  386. quantark/var/results/__init__.py +16 -0
  387. quantark/var/results/incremental_var_result.py +131 -0
  388. quantark/var/results/var_report.py +346 -0
  389. quantark/var/results/var_result.py +134 -0
  390. quantark/var/risk_factors/__init__.py +22 -0
  391. quantark/var/risk_factors/base.py +41 -0
  392. quantark/var/risk_factors/equity_factors.py +158 -0
  393. quantark/var/risk_factors/fi_factors.py +99 -0
  394. quantark-0.1.0.dist-info/METADATA +351 -0
  395. quantark-0.1.0.dist-info/RECORD +399 -0
  396. quantark-0.1.0.dist-info/WHEEL +4 -0
  397. quantark-0.1.0.dist-info/licenses/LICENSE +202 -0
  398. quantark-0.1.0.dist-info/licenses/NOTICE +2 -0
  399. quantark_compat.pth +1 -0
@@ -0,0 +1,485 @@
1
+ """
2
+ Monte Carlo pricing engine for American vanilla options using LSM.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Optional, Tuple, Union
7
+
8
+ import numpy as np
9
+
10
+ from quantark.asset.equity.engine.base_engine import BaseEngine
11
+ from quantark.asset.equity.product.option import AmericanOption
12
+ from quantark.asset.equity.product.base_equity_product import BaseEquityProduct
13
+ from quantark.asset.equity.param import MCParams
14
+ from quantark.priceenv import PricingEnvironment
15
+ from quantark.util.enum.engine_enums import MonteCarloMethod, EngineType
16
+ from quantark.util.exceptions import ValidationError, PricingError
17
+ from quantark.util.numerical import (
18
+ Tolerance,
19
+ is_zero,
20
+ is_finite,
21
+ safe_divide,
22
+ safe_exp,
23
+ safe_power,
24
+ safe_sqrt,
25
+ validate_positive,
26
+ validate_non_negative,
27
+ )
28
+
29
+ from quantark.asset.equity.process.bsm.qmc_path_generator import GBMPathGenerator
30
+ from quantark.asset.equity.process.bsm.qmc_sobol import (
31
+ PseudoRandomNormalGenerator,
32
+ SobolNormalGenerator,
33
+ )
34
+ from quantark.asset.equity.process.bsm.qmc_rqmc_driver import RQMCResult, run_rqmc
35
+ from quantark.asset.equity.process.bsm.qmc_variance_reduction import VarianceReductionConfig
36
+
37
+
38
+ @dataclass
39
+ class AmericanMCResult:
40
+ """Result container for American option MC pricing."""
41
+
42
+ price: float
43
+ std_error: float
44
+ num_paths: int
45
+ early_exercise_ratio: Optional[float] = None
46
+ avg_exercise_time: Optional[float] = None
47
+ batches_used: Optional[int] = None
48
+
49
+
50
+ class AmericanOptionMCEngine(BaseEngine):
51
+ """
52
+ Monte Carlo pricing engine for American vanilla options using LSM.
53
+
54
+ Supports three Monte Carlo methods:
55
+ - PSEUDO: Standard Monte Carlo with pseudorandom numbers
56
+ - QUASI: Quasi-Monte Carlo with Sobol sequences
57
+ - RANDOMIZED_QUASI: Randomized QMC with adaptive batching
58
+
59
+ Usage:
60
+ # Preferred: Two-level enum pattern
61
+ engine = AmericanOptionMCEngine(
62
+ params=MCParams(num_paths=100000, time_steps=252),
63
+ method=EngineType.MONTE_CARLO(MonteCarloMethod.QUASI)
64
+ )
65
+
66
+ # Alternative: Direct method enum
67
+ engine = AmericanOptionMCEngine(
68
+ params=MCParams(num_paths=100000),
69
+ method=MonteCarloMethod.QUASI
70
+ )
71
+
72
+ # Backward compatibility: String
73
+ engine = AmericanOptionMCEngine(method="quasi")
74
+ """
75
+
76
+ engine_type = EngineType.MONTE_CARLO
77
+
78
+ DEFAULT_METHOD = MonteCarloMethod.PSEUDO
79
+
80
+ def __init__(
81
+ self,
82
+ params: Optional[MCParams] = None,
83
+ method: Union[str, MonteCarloMethod, tuple, None] = None,
84
+ regression_degree: int = 2,
85
+ min_regression_points: int = 25,
86
+ ):
87
+ """
88
+ Initialize American option Monte Carlo engine.
89
+
90
+ Args:
91
+ params: Monte Carlo configuration parameters (MCParams)
92
+ method: Monte Carlo method selection, one of:
93
+ - EngineType.MONTE_CARLO(MonteCarloMethod.XXX) (preferred)
94
+ - MonteCarloMethod.XXX
95
+ - String: "pseudo", "quasi", "randomized_quasi"
96
+ - None: defaults to MonteCarloMethod.PSEUDO
97
+ regression_degree: Polynomial degree for LSM regression basis
98
+ min_regression_points: Minimum in-the-money paths for regression
99
+
100
+ Raises:
101
+ ValidationError: If method or regression settings are invalid
102
+ """
103
+ if params is None:
104
+ params = MCParams()
105
+
106
+ if not isinstance(params, MCParams):
107
+ raise ValidationError(
108
+ f"params must be MCParams instance, got {type(params).__name__}"
109
+ )
110
+
111
+ if regression_degree < 1:
112
+ raise ValidationError(
113
+ f"regression_degree must be >= 1, got {regression_degree}"
114
+ )
115
+ if min_regression_points < 1:
116
+ raise ValidationError(
117
+ "min_regression_points must be positive, "
118
+ f"got {min_regression_points}"
119
+ )
120
+ if min_regression_points < regression_degree + 1:
121
+ raise ValidationError(
122
+ "min_regression_points must be at least regression_degree + 1, "
123
+ f"got {min_regression_points}"
124
+ )
125
+
126
+ super().__init__(params)
127
+
128
+ if method is None:
129
+ self.method = self.DEFAULT_METHOD
130
+ elif isinstance(method, tuple):
131
+ engine_type, mc_method = method
132
+ if engine_type != EngineType.MONTE_CARLO:
133
+ raise ValidationError(
134
+ f"Expected EngineType.MONTE_CARLO, got {engine_type}"
135
+ )
136
+ if not isinstance(mc_method, MonteCarloMethod):
137
+ raise ValidationError(
138
+ f"Expected MonteCarloMethod, got {type(mc_method).__name__}"
139
+ )
140
+ self.method = mc_method
141
+ elif isinstance(method, MonteCarloMethod):
142
+ self.method = method
143
+ elif isinstance(method, str):
144
+ try:
145
+ self.method = MonteCarloMethod[method.upper()]
146
+ except KeyError:
147
+ valid_methods = [m.name for m in MonteCarloMethod]
148
+ raise ValidationError(
149
+ f"Invalid method string '{method}'. Valid methods: {valid_methods}"
150
+ )
151
+ else:
152
+ raise ValidationError(
153
+ f"Invalid method type {type(method).__name__}. "
154
+ "Expected MonteCarloMethod, tuple, str, or None"
155
+ )
156
+
157
+ self.regression_degree = regression_degree
158
+ self.min_regression_points = min_regression_points
159
+ self._last_result: Optional[AmericanMCResult] = None
160
+ self._last_rqmc_result: Optional[RQMCResult] = None
161
+
162
+ def price(
163
+ self, product: BaseEquityProduct, pricing_env: PricingEnvironment
164
+ ) -> float:
165
+ """
166
+ Price an American vanilla option using Monte Carlo simulation.
167
+
168
+ Args:
169
+ product: American vanilla option to price
170
+ pricing_env: Pricing environment with market data
171
+
172
+ Returns:
173
+ Option price
174
+
175
+ Raises:
176
+ PricingError: If product is not an AmericanOption
177
+ ValidationError: If pricing parameters are invalid
178
+ """
179
+ if not isinstance(product, AmericanOption):
180
+ raise PricingError(
181
+ f"AmericanOptionMCEngine only supports AmericanOption, "
182
+ f"got {type(product).__name__}"
183
+ )
184
+
185
+ S = pricing_env.spot
186
+ K = product.strike
187
+ T = product.get_maturity(pricing_env)
188
+ r = pricing_env.get_rate(T)
189
+ q = pricing_env.get_div_yield(T)
190
+ sigma = pricing_env.get_vol(K, T)
191
+
192
+ self._validate_inputs(S, K, T, r, q, sigma)
193
+
194
+ if is_zero(T):
195
+ return product.get_payoff(S)
196
+
197
+ if self.method == MonteCarloMethod.RANDOMIZED_QUASI:
198
+ result = self._price_rqmc(product, S, K, T, r, q, sigma)
199
+ else:
200
+ result = self._price_mc_or_qmc(product, S, K, T, r, q, sigma)
201
+
202
+ contract_multiplier = product.contract_multiplier
203
+ result.price *= contract_multiplier
204
+ result.std_error *= contract_multiplier
205
+ self._last_result = result
206
+
207
+ if result.price < 0.0:
208
+ raise PricingError(f"Negative price computed: {result.price}")
209
+
210
+ intrinsic = product.intrinsic_value(S)
211
+ return max(result.price, intrinsic)
212
+
213
+ def _validate_inputs(
214
+ self, S: float, K: float, T: float, r: float, q: float, sigma: float
215
+ ) -> None:
216
+ """Validate pricing inputs."""
217
+ validate_positive(S, "spot")
218
+ validate_positive(K, "strike")
219
+ validate_non_negative(T, "time_to_maturity")
220
+ validate_positive(sigma, "volatility")
221
+ validate_non_negative(q, "dividend_yield")
222
+ if not is_finite(r):
223
+ raise ValidationError(f"risk_free_rate must be finite, got {r}")
224
+
225
+ def _create_path_generator(
226
+ self,
227
+ S: float,
228
+ r: float,
229
+ q: float,
230
+ sigma: float,
231
+ T: float,
232
+ num_paths: Optional[int] = None,
233
+ ) -> GBMPathGenerator:
234
+ """Create a GBMPathGenerator configured for the current method."""
235
+ params = self.params
236
+ effective_num_paths = params.num_paths if num_paths is None else int(num_paths)
237
+ if effective_num_paths <= 0:
238
+ raise ValidationError(
239
+ f"num_paths must be positive, got {effective_num_paths}"
240
+ )
241
+
242
+ if self.method == MonteCarloMethod.PSEUDO:
243
+ random_stream = PseudoRandomNormalGenerator(seed=params.seed)
244
+ is_qmc = False
245
+ elif self.method in (MonteCarloMethod.QUASI, MonteCarloMethod.RANDOMIZED_QUASI):
246
+ random_stream = SobolNormalGenerator(base_seed=params.seed)
247
+ is_qmc = True
248
+ else:
249
+ raise ValidationError(f"Unknown Monte Carlo method: {self.method}")
250
+
251
+ vr_config = None
252
+ if params.use_antithetic and not is_qmc:
253
+ vr_config = VarianceReductionConfig(antithetic=True)
254
+
255
+ return GBMPathGenerator(
256
+ initial_value=S,
257
+ vol=sigma,
258
+ rrf=r,
259
+ div=q,
260
+ maturity=T,
261
+ time_steps=params.time_steps,
262
+ num_paths=effective_num_paths,
263
+ model="bsm",
264
+ random_stream=random_stream,
265
+ use_brownian_bridge=False,
266
+ vr_config=vr_config,
267
+ is_qmc=is_qmc,
268
+ )
269
+
270
+ def _price_mc_or_qmc(
271
+ self,
272
+ product: AmericanOption,
273
+ S: float,
274
+ K: float,
275
+ T: float,
276
+ r: float,
277
+ q: float,
278
+ sigma: float,
279
+ ) -> AmericanMCResult:
280
+ """Price using normal MC or QMC (non-randomized)."""
281
+ generator = self._create_path_generator(S, r, q, sigma, T)
282
+ paths, _ = generator.generate_paths(return_aux=False)
283
+
284
+ discount_factors = safe_exp(-r * generator.dt_vector)
285
+
286
+ payoffs, exercise_steps = self._lsm_discounted_payoffs(
287
+ product=product,
288
+ paths=paths,
289
+ discount_factors=discount_factors,
290
+ strike=K,
291
+ return_exercise_steps=True,
292
+ )
293
+
294
+ price = float(payoffs.mean())
295
+ if payoffs.shape[0] > 1:
296
+ std_payoff = float(payoffs.std(ddof=1))
297
+ std_error = safe_divide(
298
+ std_payoff, safe_sqrt(payoffs.shape[0]), fallback=0.0
299
+ )
300
+ else:
301
+ std_error = 0.0
302
+
303
+ exercise_times = self._exercise_times_in_years(
304
+ exercise_steps=exercise_steps,
305
+ times=generator.times,
306
+ maturity=T,
307
+ )
308
+ early_exercise_ratio = float(np.mean(exercise_steps < generator.time_steps))
309
+ avg_exercise_time = float(exercise_times.mean())
310
+
311
+ return AmericanMCResult(
312
+ price=price,
313
+ std_error=std_error,
314
+ num_paths=payoffs.shape[0],
315
+ early_exercise_ratio=early_exercise_ratio,
316
+ avg_exercise_time=avg_exercise_time,
317
+ )
318
+
319
+ def _price_rqmc(
320
+ self,
321
+ product: AmericanOption,
322
+ S: float,
323
+ K: float,
324
+ T: float,
325
+ r: float,
326
+ q: float,
327
+ sigma: float,
328
+ ) -> AmericanMCResult:
329
+ """Price using Randomized QMC with adaptive batching."""
330
+ params = self.params
331
+ max_batches = getattr(
332
+ params, "rqmc_max_batches", getattr(params, "max_batches", 32)
333
+ )
334
+ min_batches = getattr(
335
+ params, "rqmc_min_batches", getattr(params, "min_batches", 4)
336
+ )
337
+ if hasattr(params, "resolve_rqmc_target_std"):
338
+ target_std = params.resolve_rqmc_target_std(product=product)
339
+ else:
340
+ target_std = getattr(params, "target_std", 1e-4)
341
+ if hasattr(params, "resolve_rqmc_paths_per_batch"):
342
+ per_batch_paths = params.resolve_rqmc_paths_per_batch(
343
+ max_batches=max_batches
344
+ )
345
+ else:
346
+ per_batch_paths = params.num_paths
347
+
348
+ generator = self._create_path_generator(
349
+ S, r, q, sigma, T, num_paths=per_batch_paths
350
+ )
351
+ discount_factors = safe_exp(-r * generator.dt_vector)
352
+
353
+ def pricer_fn(paths, aux):
354
+ return self._lsm_discounted_payoffs(
355
+ product=product,
356
+ paths=paths,
357
+ discount_factors=discount_factors,
358
+ strike=K,
359
+ return_exercise_steps=False,
360
+ )
361
+
362
+ result = run_rqmc(
363
+ pricer_fn=pricer_fn,
364
+ path_generator=generator,
365
+ max_batches=max_batches,
366
+ target_std=target_std,
367
+ min_batches=min_batches,
368
+ )
369
+
370
+ self._last_rqmc_result = result
371
+
372
+ return AmericanMCResult(
373
+ price=result.price,
374
+ std_error=result.std_error,
375
+ num_paths=result.total_paths,
376
+ early_exercise_ratio=None,
377
+ avg_exercise_time=None,
378
+ batches_used=result.batches_used,
379
+ )
380
+
381
+ def _lsm_discounted_payoffs(
382
+ self,
383
+ product: AmericanOption,
384
+ paths: np.ndarray,
385
+ discount_factors: np.ndarray,
386
+ strike: float,
387
+ return_exercise_steps: bool = False,
388
+ ) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]:
389
+ """
390
+ Apply Longstaff-Schwartz regression to estimate optimal exercise.
391
+
392
+ Returns discounted cashflows at time 0 and optionally exercise steps.
393
+ """
394
+ num_paths, num_steps_plus_one = paths.shape
395
+ time_steps = num_steps_plus_one - 1
396
+
397
+ payoffs = self._intrinsic_values(product, paths[:, -1], strike)
398
+ exercise_steps = np.full(num_paths, time_steps, dtype=int)
399
+
400
+ for step in range(time_steps - 1, 0, -1):
401
+ payoffs = payoffs * discount_factors[step]
402
+
403
+ spot = paths[:, step]
404
+ exercise_values = self._intrinsic_values(product, spot, strike)
405
+ in_the_money = exercise_values > Tolerance.ZERO
406
+
407
+ if not np.any(in_the_money):
408
+ continue
409
+
410
+ if np.count_nonzero(in_the_money) >= self.min_regression_points:
411
+ continuation = self._estimate_continuation(
412
+ spots=spot[in_the_money],
413
+ cashflows=payoffs[in_the_money],
414
+ strike=strike,
415
+ )
416
+ else:
417
+ continuation = payoffs[in_the_money]
418
+
419
+ exercise_now = exercise_values[in_the_money] > continuation
420
+ if np.any(exercise_now):
421
+ exercise_indices = np.where(in_the_money)[0][exercise_now]
422
+ payoffs[exercise_indices] = exercise_values[exercise_indices]
423
+ exercise_steps[exercise_indices] = step
424
+
425
+ payoffs = payoffs * discount_factors[0]
426
+
427
+ if return_exercise_steps:
428
+ return payoffs, exercise_steps
429
+ return payoffs
430
+
431
+ def _estimate_continuation(
432
+ self, spots: np.ndarray, cashflows: np.ndarray, strike: float
433
+ ) -> np.ndarray:
434
+ """Estimate continuation value via polynomial regression."""
435
+ normalized = safe_divide(spots, strike, fallback=0.0)
436
+ design = self._build_regression_matrix(normalized)
437
+
438
+ try:
439
+ coeffs, _, _, _ = np.linalg.lstsq(design, cashflows, rcond=None)
440
+ continuation = design @ coeffs
441
+ except np.linalg.LinAlgError:
442
+ return cashflows
443
+
444
+ if not np.all(is_finite(continuation)):
445
+ return cashflows
446
+
447
+ return continuation
448
+
449
+ def _build_regression_matrix(self, x: np.ndarray) -> np.ndarray:
450
+ """Build polynomial regression basis matrix."""
451
+ columns = [np.ones_like(x)]
452
+ for power in range(1, self.regression_degree + 1):
453
+ columns.append(safe_power(x, power))
454
+ return np.column_stack(columns)
455
+
456
+ @staticmethod
457
+ def _intrinsic_values(
458
+ product: AmericanOption, spot: np.ndarray, strike: float
459
+ ) -> np.ndarray:
460
+ """Compute intrinsic values for call/put options."""
461
+ if product.is_call():
462
+ return np.maximum(spot - strike, 0.0)
463
+ return np.maximum(strike - spot, 0.0)
464
+
465
+ @staticmethod
466
+ def _exercise_times_in_years(
467
+ exercise_steps: np.ndarray, times: np.ndarray, maturity: float
468
+ ) -> np.ndarray:
469
+ """Convert exercise step indices to exercise times."""
470
+ max_step = times.shape[0]
471
+ indices = np.clip(exercise_steps - 1, 0, max_step - 1)
472
+ exercise_times = times[indices]
473
+ exercise_times = np.where(exercise_steps == max_step, maturity, exercise_times)
474
+ return exercise_times
475
+
476
+ def get_last_result(self) -> Optional[AmericanMCResult]:
477
+ """Get the result from the last pricing run."""
478
+ return self._last_result
479
+
480
+ def get_last_rqmc_result(self) -> Optional[RQMCResult]:
481
+ """Get the RQMC result from the last RQMC pricing run."""
482
+ return self._last_rqmc_result
483
+
484
+ def __repr__(self) -> str:
485
+ return f"AmericanOptionMCEngine(method={self.method.name})"