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,439 @@
1
+ """
2
+ PDE solver for one-touch (and no-touch) options.
3
+
4
+ Implements the finite difference method for digital barrier options
5
+ that pay a fixed rebate on touching (or not touching) a barrier.
6
+ """
7
+
8
+ from typing import Dict, Optional, List, Set
9
+ import numpy as np
10
+
11
+ from quantark.asset.equity.product.base_equity_product import BaseEquityProduct
12
+ from quantark.asset.equity.product.option.one_touch_option import OneTouchOption
13
+ from quantark.asset.equity.param import PDEParams
14
+ from quantark.priceenv import PricingEnvironment
15
+ from quantark.util.enum import ObservationType, ObservationAggregation, TouchType
16
+ from quantark.util.exceptions import PricingError
17
+
18
+ from .base_pde_solver import BasePDESolver
19
+ from .spatial_grid import SpatialGrid
20
+ from .time_grid import TimeGrid
21
+
22
+
23
+ class OneTouchPDESolver(BasePDESolver):
24
+ """
25
+ PDE solver for one-touch and no-touch options.
26
+
27
+ One-touch options pay a fixed rebate if the barrier is touched.
28
+ No-touch options pay a fixed rebate if the barrier is NOT touched.
29
+
30
+ For one-touch (payment at expiry):
31
+ Terminal condition: rebate at barrier side, 0 elsewhere
32
+ Boundary at barrier: rebate (discounted if payment at expiry)
33
+
34
+ For no-touch:
35
+ Terminal condition: rebate inside (away from barrier), 0 at barrier
36
+ Boundary at barrier: 0
37
+
38
+ For one-touch with payment at hit:
39
+ We solve for the present value of the expected rebate,
40
+ with the barrier being an absorbing boundary with value = rebate.
41
+ """
42
+
43
+ def __init__(self, params: Optional[PDEParams] = None):
44
+ """
45
+ Initialize one-touch option PDE solver.
46
+
47
+ Args:
48
+ params: PDE engine configuration parameters
49
+ """
50
+ super().__init__(params)
51
+ self._observation_indices: Set[int] = set()
52
+ self._schedule_records: Dict[int, List] = {}
53
+ self._schedule_aggregation: ObservationAggregation = (
54
+ ObservationAggregation.STOP_FIRST_HIT
55
+ )
56
+
57
+ def price(
58
+ self, product: BaseEquityProduct, pricing_env: PricingEnvironment
59
+ ) -> float:
60
+ """
61
+ Price a one-touch or no-touch option using PDE method.
62
+
63
+ Args:
64
+ product: One-touch option
65
+ pricing_env: Pricing environment
66
+
67
+ Returns:
68
+ Option price
69
+
70
+ Raises:
71
+ PricingError: If product is not a one-touch option
72
+ """
73
+ if not isinstance(product, OneTouchOption):
74
+ raise PricingError(
75
+ f"OneTouchPDESolver only supports OneTouchOption, "
76
+ f"got {type(product).__name__}"
77
+ )
78
+
79
+ # Check if barrier already hit
80
+ spot = pricing_env.spot
81
+ if product.is_barrier_hit(spot):
82
+ if product.is_one_touch:
83
+ # Already touched, immediate rebate
84
+ return product.rebate
85
+ else:
86
+ # No-touch already failed
87
+ return 0.0
88
+
89
+ return super().price(product, pricing_env)
90
+
91
+ def calculate_greeks(
92
+ self, product: BaseEquityProduct, pricing_env: PricingEnvironment
93
+ ) -> Dict[str, float]:
94
+ """
95
+ Calculate Greeks for a one-touch or no-touch option.
96
+
97
+ Args:
98
+ product: One-touch option
99
+ pricing_env: Pricing environment
100
+
101
+ Returns:
102
+ Dictionary with price, delta, gamma
103
+
104
+ Raises:
105
+ PricingError: If product is not a one-touch option
106
+ """
107
+ if not isinstance(product, OneTouchOption):
108
+ raise PricingError(
109
+ f"OneTouchPDESolver only supports OneTouchOption, "
110
+ f"got {type(product).__name__}"
111
+ )
112
+
113
+ spot = pricing_env.spot
114
+ tau = product.get_maturity(pricing_env)
115
+
116
+ # Handle expired case
117
+ if tau <= 0:
118
+ return {
119
+ "price": self._calculate_intrinsic(product, spot),
120
+ "delta": self._intrinsic_delta(product, spot),
121
+ "gamma": 0.0,
122
+ }
123
+
124
+ # Check if barrier already hit
125
+ if product.is_barrier_hit(spot):
126
+ if product.is_one_touch:
127
+ # Already touched, fixed rebate (delta=gamma=0)
128
+ return {"price": product.rebate, "delta": 0.0, "gamma": 0.0}
129
+ else:
130
+ # No-touch already failed
131
+ return {"price": 0.0, "delta": 0.0, "gamma": 0.0}
132
+
133
+ return super().calculate_greeks(product, pricing_env)
134
+
135
+ def set_terminal_condition(
136
+ self,
137
+ grid: np.ndarray,
138
+ x_vec: np.ndarray,
139
+ s_vec: np.ndarray,
140
+ product: BaseEquityProduct,
141
+ pricing_env: PricingEnvironment,
142
+ ) -> None:
143
+ """
144
+ Set the terminal condition at maturity.
145
+
146
+ For one-touch (payment at expiry):
147
+ - If barrier not touched by expiry, one-touch pays 0
148
+ - This is handled by solving backwards
149
+
150
+ For no-touch:
151
+ - Pays rebate at expiry if barrier was never touched
152
+ - So terminal is rebate away from barrier, 0 at barrier
153
+
154
+ Args:
155
+ grid: Solution grid [num_x, num_t]
156
+ x_vec: Log-price grid points
157
+ s_vec: Price grid points
158
+ product: One-touch option
159
+ pricing_env: Pricing environment
160
+ """
161
+ barrier = product.barrier
162
+ rebate = product.rebate
163
+
164
+ if product.is_one_touch:
165
+ # One-touch: at maturity, if we haven't touched, we get 0
166
+ # But at barrier, we get rebate (this is set in boundary conditions)
167
+ grid[:, -1] = 0.0
168
+
169
+ # Set barrier boundary to rebate value
170
+ if product.is_up_barrier:
171
+ grid[s_vec >= barrier, -1] = rebate
172
+ else:
173
+ grid[s_vec <= barrier, -1] = rebate
174
+ else:
175
+ # No-touch: pays rebate at expiry if never touched
176
+ # Terminal is rebate everywhere except at barrier
177
+ grid[:, -1] = rebate
178
+
179
+ # Zero at barrier (already touched)
180
+ if product.is_up_barrier:
181
+ grid[s_vec >= barrier, -1] = 0.0
182
+ else:
183
+ grid[s_vec <= barrier, -1] = 0.0
184
+
185
+ def set_boundary_conditions(
186
+ self,
187
+ grid: np.ndarray,
188
+ x_vec: np.ndarray,
189
+ s_vec: np.ndarray,
190
+ t_idx: int,
191
+ tau: float,
192
+ product: BaseEquityProduct,
193
+ pricing_env: PricingEnvironment,
194
+ ) -> None:
195
+ """
196
+ Set boundary conditions at spatial edges.
197
+
198
+ For one-touch:
199
+ - Barrier boundary: rebate (discounted if payment at expiry)
200
+ - Far boundary: 0 (never reach barrier from there)
201
+
202
+ For no-touch:
203
+ - Barrier boundary: 0 (touched = failed)
204
+ - Far boundary: discounted rebate
205
+
206
+ Args:
207
+ grid: Solution grid [num_x, num_t]
208
+ x_vec: Log-price grid points
209
+ s_vec: Price grid points
210
+ t_idx: Current time index
211
+ tau: Time remaining to maturity
212
+ product: One-touch option
213
+ pricing_env: Pricing environment
214
+ """
215
+ rebate = product.rebate
216
+ r = pricing_env.get_rate(tau) if tau > 0 else 0.0
217
+
218
+ # Discount factor
219
+ df = np.exp(-r * tau) if tau > 0 else 1.0
220
+
221
+ if product.is_one_touch:
222
+ if product.payment_at_hit:
223
+ # Pay immediately on hit - boundary is full rebate
224
+ barrier_value = rebate
225
+ else:
226
+ # Pay at expiry - discount the rebate
227
+ barrier_value = rebate * df
228
+
229
+ far_value = 0.0 # Too far from barrier to ever reach it
230
+ else:
231
+ # No-touch
232
+ barrier_value = 0.0 # Touched = no payout
233
+ far_value = rebate * df # Never touch = get discounted rebate
234
+
235
+ if product.is_up_barrier:
236
+ # Up barrier: upper boundary is barrier
237
+ grid[0, t_idx] = far_value
238
+ grid[-1, t_idx] = barrier_value
239
+ else:
240
+ # Down barrier: lower boundary is barrier
241
+ grid[0, t_idx] = barrier_value
242
+ grid[-1, t_idx] = far_value
243
+
244
+ def _apply_step_modifications(
245
+ self,
246
+ grid: np.ndarray,
247
+ x_vec: np.ndarray,
248
+ s_vec: np.ndarray,
249
+ t_idx: int,
250
+ tau: float,
251
+ product: BaseEquityProduct,
252
+ pricing_env: PricingEnvironment,
253
+ ) -> None:
254
+ """
255
+ Apply barrier checks at each time step.
256
+
257
+ For discrete monitoring, only check at observation times.
258
+
259
+ Args:
260
+ grid: Solution grid
261
+ x_vec: Log-price grid points
262
+ s_vec: Price grid points
263
+ t_idx: Current time index
264
+ tau: Time remaining to maturity
265
+ product: One-touch option
266
+ pricing_env: Pricing environment
267
+ """
268
+ # For discrete monitoring, only check at observation times
269
+ if product.observation_type == ObservationType.DISCRETE:
270
+ if t_idx not in self._observation_indices:
271
+ return
272
+
273
+ barrier = product.barrier
274
+ rebate = product.rebate
275
+ r = pricing_env.get_rate(tau) if tau > 0 else 0.0
276
+ df = np.exp(-r * tau) if tau > 0 else 1.0
277
+
278
+ schedule_records = self._schedule_records.get(t_idx)
279
+ if schedule_records:
280
+ for rec in schedule_records:
281
+ barrier = rec.barrier if rec.barrier is not None else product.barrier
282
+ payoff = rec.payoff
283
+ if product.is_one_touch:
284
+ barrier_value = payoff if product.payment_at_hit else payoff * df
285
+ else:
286
+ barrier_value = 0.0
287
+ if self._schedule_aggregation == ObservationAggregation.ACCUMULATE:
288
+ if product.is_up_barrier:
289
+ grid[s_vec >= barrier, t_idx] += barrier_value
290
+ else:
291
+ grid[s_vec <= barrier, t_idx] += barrier_value
292
+ else:
293
+ if product.is_up_barrier:
294
+ grid[s_vec >= barrier, t_idx] = barrier_value
295
+ else:
296
+ grid[s_vec <= barrier, t_idx] = barrier_value
297
+ return
298
+ return
299
+
300
+ if product.is_one_touch:
301
+ if product.payment_at_hit:
302
+ barrier_value = rebate
303
+ else:
304
+ barrier_value = rebate * df
305
+ else:
306
+ barrier_value = 0.0
307
+
308
+ # Apply barrier value where barrier is hit
309
+ if product.is_up_barrier:
310
+ grid[s_vec >= barrier, t_idx] = barrier_value
311
+ else:
312
+ grid[s_vec <= barrier, t_idx] = barrier_value
313
+
314
+ def _build_grids(
315
+ self,
316
+ product: BaseEquityProduct,
317
+ pricing_env: PricingEnvironment,
318
+ spot: float,
319
+ sigma: float,
320
+ tau: float,
321
+ r: float,
322
+ q: float,
323
+ ):
324
+ """Build grids for one-touch option."""
325
+ params: PDEParams = self.params
326
+ barrier = product.barrier
327
+
328
+ # Use volatility-based bounds with wider range for barrier options
329
+ # This ensures proper probability capture for touch/no-touch dynamics
330
+ s_min, s_max = SpatialGrid.calculate_auto_bounds(
331
+ spot,
332
+ sigma,
333
+ tau,
334
+ r,
335
+ q,
336
+ barriers=[barrier],
337
+ num_std=5.0, # Wider range for barrier options
338
+ )
339
+
340
+ # Ensure barrier is at the appropriate boundary edge
341
+ if product.is_up_barrier:
342
+ # Up barrier: upper boundary should be at/beyond barrier
343
+ s_max = max(s_max, barrier * 1.01)
344
+ else:
345
+ # Down barrier: lower boundary should be at/beyond barrier
346
+ s_min = min(s_min, barrier * 0.99)
347
+
348
+ # Override with user bounds if specified
349
+ if params.s_min > 0:
350
+ s_min = params.s_min
351
+ if params.s_max > 0:
352
+ s_max = params.s_max
353
+
354
+ # Build spatial grid with concentration at barrier
355
+ critical_points = [barrier]
356
+
357
+ x_vec, s_vec, dx_vec = SpatialGrid.build(
358
+ s_min,
359
+ s_max,
360
+ params.grid_size,
361
+ critical_points=critical_points,
362
+ use_adaptive=params.adaptive_grid,
363
+ )
364
+
365
+ # Get event times
366
+ event_times = self._get_event_times(product, tau)
367
+
368
+ # Build time grid
369
+ t_vec, dt_vec = TimeGrid.build(
370
+ tau,
371
+ params.time_steps,
372
+ method=params.time_grid_type,
373
+ event_times=event_times,
374
+ grade_exponent=params.grade_exponent,
375
+ )
376
+
377
+ # Setup observation indices for discrete monitoring
378
+ self._observation_indices.clear()
379
+ self._schedule_records.clear()
380
+ self._schedule_aggregation = ObservationAggregation.STOP_FIRST_HIT
381
+ schedule = getattr(product, "observation_schedule", None)
382
+ if schedule is not None:
383
+ resolved_records = schedule.resolve(
384
+ pricing_env=pricing_env,
385
+ default_barrier=product.barrier,
386
+ default_payoff=product.rebate,
387
+ require_single=True,
388
+ )
389
+ self._schedule_aggregation = schedule.aggregation_mode
390
+ if self._schedule_aggregation in (
391
+ ObservationAggregation.BEST,
392
+ ObservationAggregation.WORST,
393
+ ):
394
+ raise PricingError(
395
+ f"PDE solver does not support aggregation mode {self._schedule_aggregation.value}"
396
+ )
397
+ for rec in resolved_records:
398
+ if 0 < rec.observation_time < tau:
399
+ idx = np.argmin(np.abs(t_vec - rec.observation_time))
400
+ self._observation_indices.add(idx)
401
+ self._schedule_records.setdefault(idx, []).append(rec)
402
+ elif (
403
+ product.observation_type == ObservationType.DISCRETE
404
+ and product.observation_dates is not None
405
+ ):
406
+ for obs_time in product.observation_dates:
407
+ if 0 < obs_time < tau:
408
+ idx = np.argmin(np.abs(t_vec - obs_time))
409
+ self._observation_indices.add(idx)
410
+
411
+ return x_vec, s_vec, dx_vec, t_vec, dt_vec
412
+
413
+ def get_critical_points(
414
+ self, product: BaseEquityProduct, pricing_env: PricingEnvironment
415
+ ) -> List[float]:
416
+ """
417
+ Get critical prices for grid concentration.
418
+
419
+ For one-touch, only the barrier is critical.
420
+
421
+ Args:
422
+ product: One-touch option
423
+ pricing_env: Pricing environment
424
+
425
+ Returns:
426
+ List containing the barrier
427
+ """
428
+ points = [product.barrier]
429
+ schedule = getattr(product, "observation_schedule", None)
430
+ if schedule is not None:
431
+ for rec in schedule.records:
432
+ if rec.barrier is not None:
433
+ points.append(rec.barrier)
434
+ # sort and make unique before return
435
+ points = sorted(set(points))
436
+ return points
437
+
438
+ def __repr__(self):
439
+ return "OneTouchPDESolver()"