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,7 @@
1
+ """
2
+ Stochastic processes for equity modeling.
3
+ """
4
+ from .bsm import BSMProcess
5
+
6
+ __all__ = ['BSMProcess']
7
+
@@ -0,0 +1,7 @@
1
+ """
2
+ Black-Scholes-Merton process.
3
+ """
4
+ from .bsm_process import BSMProcess
5
+
6
+ __all__ = ['BSMProcess']
7
+
@@ -0,0 +1,108 @@
1
+ """
2
+ Black-Scholes-Merton process with continuous dividend yield.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+ from quantark.util.exceptions import ValidationError
7
+
8
+
9
+ @dataclass
10
+ class BSMProcess:
11
+ """
12
+ Black-Scholes-Merton stochastic process for equity pricing.
13
+
14
+ The BSM model assumes the underlying asset follows geometric Brownian motion:
15
+ dS/S = (r - q) dt + σ dW
16
+
17
+ where:
18
+ S = spot price
19
+ r = risk-free rate
20
+ q = continuous dividend yield
21
+ σ = volatility
22
+ W = Wiener process
23
+
24
+ Attributes:
25
+ spot: Current spot price
26
+ volatility: Annualized volatility (σ)
27
+ risk_free_rate: Risk-free interest rate (r)
28
+ dividend_yield: Continuous dividend yield (q)
29
+ """
30
+
31
+ spot: float
32
+ volatility: float
33
+ risk_free_rate: float
34
+ dividend_yield: float = 0.0
35
+
36
+ def __post_init__(self):
37
+ """Validate process parameters."""
38
+ if self.spot <= 0:
39
+ raise ValidationError(f"Spot must be positive, got {self.spot}")
40
+ if self.volatility <= 0:
41
+ raise ValidationError(f"Volatility must be positive, got {self.volatility}")
42
+ if self.volatility > 5.0: # 500% vol - sanity check
43
+ raise ValidationError(
44
+ f"Volatility seems unreasonably high: {self.volatility}"
45
+ )
46
+ if self.dividend_yield < 0:
47
+ raise ValidationError(
48
+ f"Dividend yield must be non-negative, got {self.dividend_yield}"
49
+ )
50
+ # Allow negative rates
51
+ if self.risk_free_rate < -0.10 or self.risk_free_rate > 0.50:
52
+ raise ValidationError(
53
+ f"Risk-free rate outside reasonable bounds: {self.risk_free_rate}"
54
+ )
55
+
56
+ @property
57
+ def drift(self) -> float:
58
+ """
59
+ Get the risk-neutral drift rate.
60
+
61
+ Under risk-neutral measure: μ = r - q
62
+
63
+ Returns:
64
+ Drift rate (r - q)
65
+ """
66
+ return self.risk_free_rate - self.dividend_yield
67
+
68
+ @property
69
+ def forward_price(self) -> float:
70
+ """
71
+ Calculate the forward price.
72
+
73
+ F = S * exp((r - q) * T)
74
+
75
+ For T=1 year, returns the 1-year forward.
76
+
77
+ Returns:
78
+ Forward price (1 year)
79
+ """
80
+ import math
81
+
82
+ return self.spot * math.exp(self.drift)
83
+
84
+ def get_forward_price(self, time_to_maturity: float) -> float:
85
+ """
86
+ Calculate forward price for a given maturity.
87
+
88
+ F(T) = S * exp((r - q) * T)
89
+
90
+ Args:
91
+ time_to_maturity: Time to maturity in years
92
+
93
+ Returns:
94
+ Forward price
95
+ """
96
+ import math
97
+
98
+ if time_to_maturity < 0:
99
+ raise ValidationError(
100
+ f"Time to maturity must be non-negative, got {time_to_maturity}"
101
+ )
102
+ return self.spot * math.exp(self.drift * time_to_maturity)
103
+
104
+ def __repr__(self):
105
+ return (
106
+ f"BSMProcess(S={self.spot:.2f}, σ={self.volatility:.2%}, "
107
+ f"r={self.risk_free_rate:.2%}, q={self.dividend_yield:.2%})"
108
+ )
@@ -0,0 +1,401 @@
1
+ """
2
+ Created on Mon Nov 17 2025
3
+
4
+ @author: yaofuxin
5
+ @description: Brownian bridge utilities for constructing Brownian motion
6
+ paths from standard normal draws, plus barrier crossing
7
+ helpers for barrier-style options.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from dataclasses import dataclass
13
+
14
+ import numpy as np
15
+
16
+ from quantark.util.numerical import safe_log
17
+
18
+
19
+ @dataclass
20
+ class BrownianBridge:
21
+ """
22
+ Brownian bridge constructor for a given time grid.
23
+
24
+ The bridge is defined on times t_1 < ... < t_n with t_0 = 0.0. Given
25
+ independent standard normal samples Z_1, ..., Z_n, the bridge produces
26
+ Brownian motion values W(t_k) with the correct covariance structure but
27
+ in a dimension ordering that is better suited for QMC (low effective
28
+ dimension).
29
+ """
30
+
31
+ times: np.ndarray
32
+ indices: np.ndarray
33
+ left: np.ndarray
34
+ right: np.ndarray
35
+ variances: np.ndarray
36
+
37
+ @classmethod
38
+ def from_time_grid(cls, times: np.ndarray) -> "BrownianBridge":
39
+ """
40
+ Precompute the Brownian bridge structure for a strictly increasing
41
+ time grid.
42
+
43
+ Parameters
44
+ ----------
45
+ times : np.ndarray
46
+ One-dimensional array of shape (n_steps,) with t_k > 0 and
47
+ strictly increasing.
48
+ """
49
+ times = np.asarray(times, dtype=float)
50
+ if times.ndim != 1:
51
+ raise ValueError("times must be a one-dimensional array")
52
+ if not np.all(np.isfinite(times)):
53
+ raise ValueError("times must be finite")
54
+ if np.any(times <= 0.0):
55
+ raise ValueError("times must be strictly positive")
56
+ if np.any(np.diff(times) <= 0.0):
57
+ raise ValueError("times must be strictly increasing")
58
+
59
+ n = times.shape[0]
60
+ indices = np.empty(n, dtype=int)
61
+ left = np.full(n, -1, dtype=int)
62
+ right = np.full(n, -1, dtype=int)
63
+ variances = np.zeros(n, dtype=float)
64
+
65
+ # First dimension corresponds to terminal time T
66
+ indices[0] = n - 1
67
+ left[0] = -1
68
+ right[0] = -1
69
+ variances[0] = times[-1]
70
+
71
+ # Recursively fill midpoints
72
+ counter = 1
73
+
74
+ def build(l_idx: int, r_idx: int, cnt: int) -> int:
75
+ # Build bridge between times t_l and t_r, where l_idx/r_idx are
76
+ # indices in [0, n-1], with l_idx == -1 representing time 0.
77
+ if r_idx - l_idx <= 1:
78
+ return cnt
79
+ m_idx = (l_idx + r_idx) // 2
80
+ indices[cnt] = m_idx
81
+ left[cnt] = l_idx
82
+ right[cnt] = r_idx
83
+
84
+ t_l = 0.0 if l_idx == -1 else times[l_idx]
85
+ t_r = times[r_idx]
86
+ t_m = times[m_idx]
87
+
88
+ variance = (t_m - t_l) * (t_r - t_m) / (t_r - t_l)
89
+ variances[cnt] = max(variance, 0.0)
90
+
91
+ cnt = build(l_idx, m_idx, cnt + 1)
92
+ cnt = build(m_idx, r_idx, cnt)
93
+ return cnt
94
+
95
+ counter = build(-1, n - 1, counter)
96
+ if counter != n:
97
+ raise RuntimeError(
98
+ "BrownianBridge construction failed to fill all dimensions"
99
+ )
100
+
101
+ return cls(
102
+ times=times, indices=indices, left=left, right=right, variances=variances
103
+ )
104
+
105
+ def transform(self, z: np.ndarray) -> np.ndarray:
106
+ """
107
+ Map independent normals z to Brownian increments via Brownian bridge.
108
+
109
+ Parameters
110
+ ----------
111
+ z : np.ndarray
112
+ Array of shape (n_paths, n_steps) with independent N(0, 1)
113
+ samples along the second axis.
114
+
115
+ Returns
116
+ -------
117
+ np.ndarray
118
+ Array of Brownian increments dW of shape (n_paths, n_steps),
119
+ ordered chronologically in time.
120
+ """
121
+ z = np.asarray(z, dtype=float)
122
+ if z.ndim != 2:
123
+ raise ValueError("z must be a 2D array of shape (n_paths, n_steps)")
124
+
125
+ n_paths, n_steps = z.shape
126
+ if n_steps != self.times.shape[0]:
127
+ raise ValueError(
128
+ f"z has {n_steps} time steps but BrownianBridge is configured "
129
+ f"for {self.times.shape[0]} steps."
130
+ )
131
+
132
+ W = np.zeros((n_paths, n_steps), dtype=float)
133
+
134
+ # First dimension: terminal time T
135
+ idx0 = self.indices[0]
136
+ std0 = np.sqrt(self.variances[0])
137
+ W[:, idx0] = std0 * z[:, 0]
138
+
139
+ # Remaining dimensions: midpoints
140
+ for j in range(1, n_steps):
141
+ k = self.indices[j]
142
+ l = self.left[j]
143
+ r = self.right[j]
144
+
145
+ t_l = 0.0 if l == -1 else self.times[l]
146
+ t_r = self.times[r]
147
+ t_m = self.times[k]
148
+
149
+ if l == -1:
150
+ W_l = 0.0
151
+ else:
152
+ W_l = W[:, l]
153
+ W_r = W[:, r]
154
+
155
+ # Conditional mean and variance for the bridge
156
+ denom = t_r - t_l
157
+ if denom <= 0.0:
158
+ raise ValueError("Invalid Brownian bridge interval length.")
159
+ mean = ((t_r - t_m) * W_l + (t_m - t_l) * W_r) / denom
160
+ std = np.sqrt(self.variances[j])
161
+
162
+ W[:, k] = mean + std * z[:, j]
163
+
164
+ # Convert Brownian motion values to increments
165
+ dW = np.empty_like(W)
166
+ dW[:, 0] = W[:, 0]
167
+ if n_steps > 1:
168
+ dW[:, 1:] = W[:, 1:] - W[:, :-1]
169
+
170
+ return dW
171
+
172
+
173
+ def apply_brownian_bridge(z: np.ndarray, times: np.ndarray) -> np.ndarray:
174
+ """
175
+ Convenience function: apply Brownian bridge to standard normals.
176
+
177
+ Parameters
178
+ ----------
179
+ z : np.ndarray
180
+ Standard normal samples of shape (n_paths, n_steps).
181
+ times : np.ndarray
182
+ Time grid with shape (n_steps,) and strictly increasing values.
183
+
184
+ Returns
185
+ -------
186
+ np.ndarray
187
+ Brownian increments dW with shape (n_paths, n_steps).
188
+ """
189
+ bridge = BrownianBridge.from_time_grid(times)
190
+ return bridge.transform(z)
191
+
192
+
193
+ def apply_brownian_bridge_multi_asset(z: np.ndarray, times: np.ndarray) -> np.ndarray:
194
+ """
195
+ Apply Brownian bridge construction to multi-asset standard normals.
196
+
197
+ This function applies the Brownian bridge transformation independently
198
+ to each asset's time series. This is the recommended approach for
199
+ multi-asset QMC simulations as it preserves the low-discrepancy
200
+ properties of the underlying sequence for each asset's marginal
201
+ distribution.
202
+
203
+ Parameters
204
+ ----------
205
+ z : np.ndarray
206
+ Standard normal samples of shape (n_assets, n_paths, n_steps).
207
+ Each asset's normals are in z[i, :, :].
208
+ times : np.ndarray
209
+ Time grid with shape (n_steps,) and strictly increasing values.
210
+ The same time grid is used for all assets.
211
+
212
+ Returns
213
+ -------
214
+ np.ndarray
215
+ Brownian increments dW with shape (n_assets, n_paths, n_steps),
216
+ where dW[i, :, :] contains the increments for asset i.
217
+
218
+ Notes
219
+ -----
220
+ The Brownian bridge is applied per-asset because:
221
+ 1. It preserves QMC effectiveness for path-dependent payoffs
222
+ 2. Correlation between assets is applied separately after building
223
+ the increments, using Cholesky decomposition
224
+ 3. Each asset's marginal distribution benefits from the low effective
225
+ dimension property of Brownian bridge construction
226
+
227
+ Example
228
+ -------
229
+ >>> import numpy as np
230
+ >>> from asset.equity.process.qmc_brownian_bridge import (
231
+ ... apply_brownian_bridge_multi_asset
232
+ ... )
233
+ >>> n_assets, n_paths, n_steps = 3, 1000, 252
234
+ >>> z = np.random.standard_normal((n_assets, n_paths, n_steps))
235
+ >>> times = np.linspace(1/252, 1.0, n_steps)
236
+ >>> dW = apply_brownian_bridge_multi_asset(z, times)
237
+ >>> dW.shape
238
+ (3, 1000, 252)
239
+ """
240
+ z = np.asarray(z, dtype=float)
241
+ times = np.asarray(times, dtype=float)
242
+
243
+ if z.ndim != 3:
244
+ raise ValueError(
245
+ f"z must be a 3D array of shape (n_assets, n_paths, n_steps), "
246
+ f"got ndim={z.ndim}"
247
+ )
248
+
249
+ n_assets, n_paths, n_steps = z.shape
250
+
251
+ if times.ndim != 1:
252
+ raise ValueError("times must be a 1D array")
253
+ if times.shape[0] != n_steps:
254
+ raise ValueError(
255
+ f"times has {times.shape[0]} elements but z has {n_steps} time steps"
256
+ )
257
+
258
+ # Create bridge once and reuse for all assets
259
+ bridge = BrownianBridge.from_time_grid(times)
260
+
261
+ # Apply bridge to each asset
262
+ dW = np.zeros_like(z)
263
+ for i in range(n_assets):
264
+ dW[i] = bridge.transform(z[i])
265
+
266
+ return dW
267
+
268
+
269
+ def compute_step_crossing_probabilities(
270
+ paths: np.ndarray,
271
+ barrier_level: float,
272
+ sigma: float,
273
+ times: np.ndarray,
274
+ ) -> np.ndarray:
275
+ """
276
+ Compute step-wise barrier crossing probabilities using a Brownian bridge.
277
+
278
+ For each simulated path and each time interval, it returns the probability
279
+ that the path has crossed the barrier between the endpoints.
280
+
281
+ Parameters
282
+ ----------
283
+ paths : np.ndarray
284
+ Simulated spot paths of shape (n_paths, n_steps + 1).
285
+ barrier_level : float
286
+ Barrier level in spot space.
287
+ sigma : float
288
+ Volatility used in the GBM dynamics.
289
+ times : np.ndarray
290
+ Time grid of shape (n_steps,) corresponding to the path intervals
291
+ (excluding t=0).
292
+
293
+ Returns
294
+ -------
295
+ np.ndarray
296
+ Array of shape (n_paths, n_steps) containing the crossing probability
297
+ per step.
298
+ """
299
+ paths = np.asarray(paths, dtype=float)
300
+ times = np.asarray(times, dtype=float)
301
+
302
+ if paths.ndim != 2:
303
+ raise ValueError("paths must be a 2D array of shape (n_paths, n_steps + 1)")
304
+ if times.ndim != 1:
305
+ raise ValueError("times must be a 1D array of shape (n_steps,)")
306
+ if barrier_level <= 0.0:
307
+ raise ValueError("barrier_level must be positive")
308
+ if sigma <= 0.0:
309
+ raise ValueError("sigma must be positive")
310
+ if paths.shape[1] != times.shape[0] + 1:
311
+ raise ValueError(
312
+ "paths second dimension must be n_steps + 1 where n_steps = len(times)"
313
+ )
314
+ if np.any(np.diff(times) <= 0.0):
315
+ raise ValueError("times must be strictly increasing")
316
+
317
+ n_paths, n_cols = paths.shape
318
+ n_steps = n_cols - 1
319
+
320
+ S0 = paths[:, :-1]
321
+ S1 = paths[:, 1:]
322
+ dt = np.empty(n_steps, dtype=float)
323
+ dt[0] = times[0]
324
+ if n_steps > 1:
325
+ dt[1:] = np.diff(times)
326
+
327
+ # Broadcast dt to match shape of path slices
328
+ dt_matrix = dt.reshape(1, -1)
329
+ h2 = (sigma * sigma) * dt_matrix
330
+
331
+ # Initialize probabilities per step
332
+ prob = np.zeros_like(S0, dtype=float)
333
+
334
+ # Determine where paths are on different sides of the barrier
335
+ crossed_mask = ((S0 < barrier_level) & (S1 > barrier_level)) | (
336
+ (S0 > barrier_level) & (S1 < barrier_level)
337
+ )
338
+ touched_mask = (S0 == barrier_level) | (S1 == barrier_level)
339
+
340
+ # Opposite-side or touching endpoints imply a hit with probability 1
341
+ prob[crossed_mask | touched_mask] = 1.0
342
+
343
+ # Same-side endpoints: Brownian-bridge crossing probability
344
+ same_side = ~(crossed_mask | touched_mask)
345
+ if np.any(same_side):
346
+ log_term = safe_log(S0 / barrier_level) * safe_log(S1 / barrier_level)
347
+ bridge_prob = np.exp(-2.0 * log_term / h2)
348
+ bridge_prob = np.clip(bridge_prob, 0.0, 1.0)
349
+ prob[same_side] = bridge_prob[same_side]
350
+
351
+ return prob
352
+
353
+
354
+ def compute_barrier_crossing_probabilities(
355
+ paths: np.ndarray,
356
+ barrier_level: float,
357
+ sigma: float,
358
+ times: np.ndarray,
359
+ ) -> np.ndarray:
360
+ """
361
+ Approximate barrier crossing probabilities using a Brownian bridge.
362
+
363
+ This utility is designed for geometric Brownian motion paths and can be
364
+ used by pricing engines for barrier-style options. For each simulated
365
+ path, it returns the probability that the path has crossed the barrier
366
+ between any pair of consecutive observation times.
367
+
368
+ Parameters
369
+ ----------
370
+ paths : np.ndarray
371
+ Simulated spot paths of shape (n_paths, n_steps + 1). The second axis
372
+ is assumed to be ordered chronologically.
373
+ barrier_level : float
374
+ Barrier level in spot space.
375
+ sigma : float
376
+ Volatility used in the GBM dynamics.
377
+ times : np.ndarray
378
+ Time grid of shape (n_steps,) corresponding to the path intervals
379
+ (excluding t=0).
380
+
381
+ Returns
382
+ -------
383
+ np.ndarray
384
+ Array of shape (n_paths,) containing the approximate probability that
385
+ each path crosses the barrier at least once.
386
+ """
387
+ prob = compute_step_crossing_probabilities(paths, barrier_level, sigma, times)
388
+
389
+ # Combine step-wise probabilities into overall crossing probability
390
+ # Assuming conditional independence given endpoints (standard Brownian bridge approximation)
391
+ no_hit_prob = np.prod(1.0 - prob, axis=1)
392
+ return 1.0 - no_hit_prob
393
+
394
+
395
+ __all__ = [
396
+ "BrownianBridge",
397
+ "apply_brownian_bridge",
398
+ "apply_brownian_bridge_multi_asset",
399
+ "compute_step_crossing_probabilities",
400
+ "compute_barrier_crossing_probabilities",
401
+ ]