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