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,423 @@
1
+ """
2
+ Monte Carlo pricing engine for European vanilla options.
3
+ """
4
+
5
+ import math
6
+ from typing import Optional, Union, Tuple
7
+ import numpy as np
8
+
9
+ from quantark.asset.equity.engine.base_engine import BaseEngine
10
+ from quantark.asset.equity.product.option import EuropeanVanillaOption
11
+ from quantark.asset.equity.product.base_equity_product import BaseEquityProduct
12
+ from quantark.asset.equity.param import MCParams
13
+ from quantark.priceenv import PricingEnvironment
14
+ from quantark.util.enum.engine_enums import MonteCarloMethod, EngineType
15
+ from quantark.util.exceptions import ValidationError, PricingError
16
+ from quantark.util.numerical import safe_exp
17
+
18
+ from quantark.asset.equity.process.bsm.qmc_path_generator import GBMPathGenerator
19
+ from quantark.asset.equity.process.bsm.qmc_sobol import (
20
+ PseudoRandomNormalGenerator,
21
+ SobolNormalGenerator,
22
+ )
23
+ from quantark.asset.equity.process.bsm.qmc_rqmc_driver import run_rqmc
24
+ from quantark.asset.equity.process.bsm.qmc_variance_reduction import VarianceReductionConfig
25
+
26
+
27
+ class EuropeanMCEngine(BaseEngine):
28
+ """
29
+ Monte Carlo pricing engine for European vanilla options.
30
+
31
+ Supports three Monte Carlo methods:
32
+ - PSEUDO: Standard Monte Carlo with pseudorandom numbers
33
+ - QUASI: Quasi-Monte Carlo with Sobol sequences
34
+ - RANDOMIZED_QUASI: Randomized QMC with adaptive batching
35
+
36
+ Usage:
37
+ # Preferred: Two-level enum pattern
38
+ engine = EuropeanMCEngine(
39
+ params=MCParams(num_paths=10000, time_steps=252),
40
+ method=EngineType.MONTE_CARLO(MonteCarloMethod.QUASI)
41
+ )
42
+
43
+ # Alternative: Direct method enum
44
+ engine = EuropeanMCEngine(
45
+ params=MCParams(num_paths=10000),
46
+ method=MonteCarloMethod.QUASI
47
+ )
48
+
49
+ # Backward compatibility: String
50
+ engine = EuropeanMCEngine(method="quasi")
51
+
52
+ The engine creates a GBMPathGenerator internally based on the pricing
53
+ environment and MCParams configuration.
54
+ """
55
+
56
+ engine_type = EngineType.MONTE_CARLO
57
+
58
+ DEFAULT_METHOD = MonteCarloMethod.PSEUDO
59
+
60
+ def __init__(
61
+ self,
62
+ params: Optional[MCParams] = None,
63
+ method: Union[str, MonteCarloMethod, tuple, None] = None,
64
+ ):
65
+ """
66
+ Initialize Monte Carlo engine.
67
+
68
+ Args:
69
+ params: Monte Carlo configuration parameters (MCParams)
70
+ method: Monte Carlo method selection, one of:
71
+ - EngineType.MONTE_CARLO(MonteCarloMethod.XXX) (preferred)
72
+ - MonteCarloMethod.XXX
73
+ - String: "pseudo", "quasi", "randomized_quasi"
74
+ - None: defaults to MonteCarloMethod.PSEUDO
75
+
76
+ Raises:
77
+ ValidationError: If method is invalid or params are invalid
78
+ """
79
+ if params is None:
80
+ params = MCParams()
81
+
82
+ if not isinstance(params, MCParams):
83
+ raise ValidationError(
84
+ f"params must be MCParams instance, got {type(params).__name__}"
85
+ )
86
+
87
+ super().__init__(params)
88
+
89
+ if method is None:
90
+ self.method = self.DEFAULT_METHOD
91
+ elif isinstance(method, tuple):
92
+ engine_type, mc_method = method
93
+ if engine_type != EngineType.MONTE_CARLO:
94
+ raise ValidationError(
95
+ f"Expected EngineType.MONTE_CARLO, got {engine_type}"
96
+ )
97
+ if not isinstance(mc_method, MonteCarloMethod):
98
+ raise ValidationError(
99
+ f"Expected MonteCarloMethod, got {type(mc_method).__name__}"
100
+ )
101
+ self.method = mc_method
102
+ elif isinstance(method, MonteCarloMethod):
103
+ self.method = method
104
+ elif isinstance(method, str):
105
+ try:
106
+ self.method = MonteCarloMethod[method.upper()]
107
+ except KeyError:
108
+ valid_methods = [m.name for m in MonteCarloMethod]
109
+ raise ValidationError(
110
+ f"Invalid method string '{method}'. Valid methods: {valid_methods}"
111
+ )
112
+ else:
113
+ raise ValidationError(
114
+ f"Invalid method type {type(method).__name__}. "
115
+ "Expected MonteCarloMethod, tuple, str, or None"
116
+ )
117
+
118
+ def price(
119
+ self, product: BaseEquityProduct, pricing_env: PricingEnvironment
120
+ ) -> float:
121
+ """
122
+ Price a European vanilla option using Monte Carlo simulation.
123
+
124
+ Args:
125
+ product: European vanilla option to price
126
+ pricing_env: Pricing environment with market data
127
+
128
+ Returns:
129
+ Option price
130
+
131
+ Raises:
132
+ PricingError: If product is not a European vanilla option
133
+ ValidationError: If pricing parameters are invalid
134
+ """
135
+ if not isinstance(product, EuropeanVanillaOption):
136
+ raise PricingError(
137
+ f"EuropeanMCEngine only supports EuropeanVanillaOption, "
138
+ f"got {type(product).__name__}"
139
+ )
140
+
141
+ S = pricing_env.spot
142
+ K = product.strike
143
+ T = product.get_maturity(pricing_env)
144
+ r = pricing_env.get_rate(T)
145
+ q = pricing_env.get_div_yield(T)
146
+ sigma = pricing_env.get_vol(K, T)
147
+
148
+ self._validate_inputs(S, K, T, r, q, sigma)
149
+
150
+ if T < 1e-10:
151
+ return product.get_payoff(S)
152
+
153
+ if self.method == MonteCarloMethod.RANDOMIZED_QUASI:
154
+ price, std_error = self._price_rqmc(
155
+ product, S, K, T, r, q, sigma
156
+ )
157
+ else:
158
+ price, std_error = self._price_mc_or_qmc(
159
+ product, S, K, T, r, q, sigma
160
+ )
161
+
162
+ contract_multiplier = product.contract_multiplier
163
+ price *= contract_multiplier
164
+ std_error *= contract_multiplier
165
+ self._last_std_error = std_error
166
+
167
+ if price < 0:
168
+ raise PricingError(f"Negative price computed: {price}")
169
+
170
+ lower_bound = self._european_lower_bound(product, S, K, T, r, q)
171
+ if price < lower_bound - 1e-6:
172
+ raise PricingError(
173
+ f"Price ({price:.6f}) below discounted European lower bound "
174
+ f"({lower_bound:.6f})"
175
+ )
176
+
177
+ return price
178
+
179
+ def _european_lower_bound(
180
+ self,
181
+ product: EuropeanVanillaOption,
182
+ S: float,
183
+ K: float,
184
+ T: float,
185
+ r: float,
186
+ q: float,
187
+ ) -> float:
188
+ """Calculate the discounted no-arbitrage lower bound for a European option."""
189
+ spot_pv = S * safe_exp(-q * T)
190
+ strike_pv = K * safe_exp(-r * T)
191
+ if product.is_call():
192
+ lower_bound = max(spot_pv - strike_pv, 0.0)
193
+ else:
194
+ lower_bound = max(strike_pv - spot_pv, 0.0)
195
+ return lower_bound * product.contract_multiplier
196
+
197
+ def _validate_inputs(
198
+ self, S: float, K: float, T: float, r: float, q: float, sigma: float
199
+ ) -> None:
200
+ """Validate pricing inputs."""
201
+ if S <= 0:
202
+ raise ValidationError(f"Spot price must be positive, got {S}")
203
+ if K <= 0:
204
+ raise ValidationError(f"Strike price must be positive, got {K}")
205
+ if T < 0:
206
+ raise ValidationError(f"Time to maturity must be non-negative, got {T}")
207
+ if sigma <= 0:
208
+ raise ValidationError(f"Volatility must be positive, got {sigma}")
209
+ if q < 0:
210
+ raise ValidationError(f"Dividend yield must be non-negative, got {q}")
211
+
212
+ def _create_path_generator(
213
+ self,
214
+ S: float,
215
+ r: float,
216
+ q: float,
217
+ sigma: float,
218
+ T: float,
219
+ num_paths: Optional[int] = None,
220
+ ) -> GBMPathGenerator:
221
+ """
222
+ Create a GBMPathGenerator configured for the current method.
223
+
224
+ Args:
225
+ S: Spot price
226
+ r: Risk-free rate
227
+ q: Dividend yield
228
+ sigma: Volatility
229
+ T: Time to maturity
230
+
231
+ Returns:
232
+ Configured GBMPathGenerator
233
+ """
234
+ params = self.params
235
+ effective_num_paths = params.num_paths if num_paths is None else int(num_paths)
236
+ if effective_num_paths <= 0:
237
+ raise ValidationError(
238
+ f"num_paths must be positive, got {effective_num_paths}"
239
+ )
240
+
241
+ if self.method == MonteCarloMethod.PSEUDO:
242
+ random_stream = PseudoRandomNormalGenerator(seed=params.seed)
243
+ is_qmc = False
244
+ elif self.method in (MonteCarloMethod.QUASI, MonteCarloMethod.RANDOMIZED_QUASI):
245
+ random_stream = SobolNormalGenerator(base_seed=params.seed)
246
+ is_qmc = True
247
+ else:
248
+ raise ValidationError(f"Unknown Monte Carlo method: {self.method}")
249
+
250
+ vr_config = None
251
+ if params.use_antithetic and not is_qmc:
252
+ vr_config = VarianceReductionConfig(antithetic=True)
253
+
254
+ generator = GBMPathGenerator(
255
+ initial_value=S,
256
+ vol=sigma,
257
+ rrf=r,
258
+ div=q,
259
+ maturity=T,
260
+ time_steps=params.time_steps,
261
+ num_paths=effective_num_paths,
262
+ model="bsm",
263
+ random_stream=random_stream,
264
+ use_brownian_bridge=False,
265
+ vr_config=vr_config,
266
+ is_qmc=is_qmc,
267
+ )
268
+
269
+ return generator
270
+
271
+ def _calculate_payoffs(
272
+ self, product: EuropeanVanillaOption, terminal_prices: np.ndarray
273
+ ) -> np.ndarray:
274
+ """
275
+ Calculate option payoffs from terminal prices.
276
+
277
+ Args:
278
+ product: European vanilla option
279
+ terminal_prices: Array of terminal spot prices, shape (num_paths,)
280
+
281
+ Returns:
282
+ Array of payoffs, shape (num_paths,)
283
+ """
284
+ K = product.strike
285
+
286
+ if product.is_call():
287
+ payoffs = np.maximum(terminal_prices - K, 0.0)
288
+ else:
289
+ payoffs = np.maximum(K - terminal_prices, 0.0)
290
+
291
+ return payoffs
292
+
293
+ def _price_mc_or_qmc(
294
+ self,
295
+ product: EuropeanVanillaOption,
296
+ S: float,
297
+ K: float,
298
+ T: float,
299
+ r: float,
300
+ q: float,
301
+ sigma: float,
302
+ ) -> Tuple[float, float]:
303
+ """
304
+ Price using normal MC or QMC (non-randomized).
305
+
306
+ Args:
307
+ product: European vanilla option
308
+ S: Spot price
309
+ K: Strike price
310
+ T: Time to maturity
311
+ r: Risk-free rate
312
+ q: Dividend yield
313
+ sigma: Volatility
314
+
315
+ Returns:
316
+ Tuple of (price, standard_error)
317
+ """
318
+ generator = self._create_path_generator(S, r, q, sigma, T)
319
+
320
+ paths, aux = generator.generate_paths(return_aux=True)
321
+
322
+ terminal_prices = paths[:, -1]
323
+
324
+ payoffs = self._calculate_payoffs(product, terminal_prices)
325
+
326
+ discount_factor = math.exp(-r * T)
327
+ discounted_payoffs = discount_factor * payoffs
328
+
329
+ mean_payoff = float(discounted_payoffs.mean())
330
+ std_payoff = float(discounted_payoffs.std(ddof=1))
331
+
332
+ std_error = std_payoff / math.sqrt(len(payoffs))
333
+
334
+ return mean_payoff, std_error
335
+
336
+ def _price_rqmc(
337
+ self,
338
+ product: EuropeanVanillaOption,
339
+ S: float,
340
+ K: float,
341
+ T: float,
342
+ r: float,
343
+ q: float,
344
+ sigma: float,
345
+ ) -> Tuple[float, float]:
346
+ """
347
+ Price using Randomized QMC with adaptive batching.
348
+
349
+ Args:
350
+ product: European vanilla option
351
+ S: Spot price
352
+ K: Strike price
353
+ T: Time to maturity
354
+ r: Risk-free rate
355
+ q: Dividend yield
356
+ sigma: Volatility
357
+
358
+ Returns:
359
+ Tuple of (price, standard_error)
360
+ """
361
+ discount_factor = math.exp(-r * T)
362
+
363
+ def pricer_fn(paths, aux):
364
+ """Pricer function for RQMC driver."""
365
+ terminal_prices = paths[:, -1]
366
+ payoffs = self._calculate_payoffs(product, terminal_prices)
367
+ discounted_payoffs = discount_factor * payoffs
368
+ return discounted_payoffs
369
+
370
+ params = self.params
371
+ max_batches = getattr(
372
+ params, "rqmc_max_batches", getattr(params, "max_batches", 32)
373
+ )
374
+ min_batches = getattr(
375
+ params, "rqmc_min_batches", getattr(params, "min_batches", 4)
376
+ )
377
+ if hasattr(params, "resolve_rqmc_target_std"):
378
+ target_std = params.resolve_rqmc_target_std(product=product)
379
+ else:
380
+ target_std = getattr(params, "target_std", 1e-4)
381
+ if hasattr(params, "resolve_rqmc_paths_per_batch"):
382
+ per_batch_paths = params.resolve_rqmc_paths_per_batch(
383
+ max_batches=max_batches
384
+ )
385
+ else:
386
+ per_batch_paths = params.num_paths
387
+
388
+ generator = self._create_path_generator(
389
+ S, r, q, sigma, T, num_paths=per_batch_paths
390
+ )
391
+
392
+ result = run_rqmc(
393
+ pricer_fn=pricer_fn,
394
+ path_generator=generator,
395
+ max_batches=max_batches,
396
+ target_std=target_std,
397
+ min_batches=min_batches,
398
+ )
399
+
400
+ self._last_rqmc_result = result
401
+
402
+ return result.price, result.std_error
403
+
404
+ def get_last_std_error(self) -> Optional[float]:
405
+ """
406
+ Get the standard error from the last pricing run.
407
+
408
+ Returns:
409
+ Standard error, or None if no pricing has been performed yet
410
+ """
411
+ return getattr(self, '_last_std_error', None)
412
+
413
+ def get_last_rqmc_result(self):
414
+ """
415
+ Get the full RQMC result from the last RQMC pricing run.
416
+
417
+ Returns:
418
+ RQMCResult object, or None if last pricing was not RQMC
419
+ """
420
+ return getattr(self, '_last_rqmc_result', None)
421
+
422
+ def __repr__(self):
423
+ return f"EuropeanMCEngine(method={self.method.name})"