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,584 @@
1
+ """
2
+ Business day calendar for settlement date adjustments.
3
+ """
4
+
5
+ from enum import Enum
6
+ from datetime import datetime, timedelta
7
+ from importlib import resources
8
+ from typing import Set, Optional
9
+ import csv
10
+ from quantark.util.exceptions import ValidationError
11
+
12
+
13
+ class BusinessDayConvention(Enum):
14
+ """
15
+ Business day conventions for date adjustments.
16
+
17
+ - FOLLOWING: Roll forward to next business day
18
+ - MODIFIED_FOLLOWING: Roll forward unless crosses month, then roll backward
19
+ - PRECEDING: Roll backward to previous business day
20
+ - MODIFIED_PRECEDING: Roll backward unless crosses month, then roll forward
21
+ - UNADJUSTED: No adjustment
22
+ """
23
+
24
+ FOLLOWING = "following"
25
+ MODIFIED_FOLLOWING = "modified_following"
26
+ PRECEDING = "preceding"
27
+ MODIFIED_PRECEDING = "modified_preceding"
28
+ UNADJUSTED = "unadjusted"
29
+
30
+
31
+ class CalendarType(Enum):
32
+ """
33
+ Standard calendar types with predefined holiday schedules.
34
+ """
35
+
36
+ US = "us" # US holidays (Federal Reserve)
37
+ UK = "uk" # UK holidays
38
+ TARGET = "target" # Trans-European Automated Real-time Gross settlement (ECB)
39
+ CHINA = "china" # China holidays (national)
40
+ CHINA_SSE = "china_sse" # China holidays (SSE)
41
+ NONE = "none" # No holidays, only weekends
42
+
43
+
44
+ class Calendar:
45
+ """
46
+ Business day calendar supporting holidays and business day adjustments.
47
+
48
+ A calendar defines which days are business days (non-holidays, non-weekends)
49
+ and provides methods to adjust dates according to business day conventions.
50
+
51
+ Attributes:
52
+ holidays: Set of holiday dates
53
+ weekend_days: Set of weekend day numbers (0=Monday, 6=Sunday)
54
+ name: Calendar name for identification
55
+ """
56
+
57
+ def __init__(
58
+ self,
59
+ holidays: Optional[Set[datetime]] = None,
60
+ weekend_days: Optional[Set[int]] = None,
61
+ name: str = "Custom",
62
+ ):
63
+ """
64
+ Initialize calendar.
65
+
66
+ Args:
67
+ holidays: Set of holiday dates (default: empty set)
68
+ weekend_days: Set of weekend day numbers, 0=Mon, 6=Sun (default: {5, 6})
69
+ name: Calendar name
70
+ """
71
+ self.holidays = holidays if holidays is not None else set()
72
+ self.weekend_days = (
73
+ weekend_days if weekend_days is not None else {5, 6}
74
+ ) # Sat, Sun
75
+ self.name = name
76
+
77
+ # Normalize holiday dates to midnight
78
+ self.holidays = {self._normalize_date(d) for d in self.holidays}
79
+
80
+ @staticmethod
81
+ def _normalize_date(date: datetime) -> datetime:
82
+ """Normalize date to midnight."""
83
+ return datetime(date.year, date.month, date.day)
84
+
85
+ def is_business_day(self, date: datetime) -> bool:
86
+ """
87
+ Check if a date is a business day.
88
+
89
+ Args:
90
+ date: Date to check
91
+
92
+ Returns:
93
+ True if business day, False if weekend or holiday
94
+ """
95
+ normalized = self._normalize_date(date)
96
+
97
+ # Check if weekend
98
+ if normalized.weekday() in self.weekend_days:
99
+ return False
100
+
101
+ # Check if holiday
102
+ if normalized in self.holidays:
103
+ return False
104
+
105
+ return True
106
+
107
+ def is_holiday(self, date: datetime) -> bool:
108
+ """
109
+ Check if a date is a holiday.
110
+
111
+ Args:
112
+ date: Date to check
113
+
114
+ Returns:
115
+ True if holiday, False otherwise
116
+ """
117
+ normalized = self._normalize_date(date)
118
+ return normalized in self.holidays
119
+
120
+ def adjust_date(
121
+ self, date: datetime, convention: BusinessDayConvention
122
+ ) -> datetime:
123
+ """
124
+ Adjust a date according to business day convention.
125
+
126
+ Args:
127
+ date: Date to adjust
128
+ convention: Business day convention to apply
129
+
130
+ Returns:
131
+ Adjusted date
132
+
133
+ Raises:
134
+ ValidationError: If convention is invalid
135
+ """
136
+ if convention == BusinessDayConvention.UNADJUSTED:
137
+ return date
138
+
139
+ if convention == BusinessDayConvention.FOLLOWING:
140
+ return self._adjust_following(date)
141
+
142
+ if convention == BusinessDayConvention.MODIFIED_FOLLOWING:
143
+ adjusted = self._adjust_following(date)
144
+ # If adjustment crosses month boundary, use preceding instead
145
+ if adjusted.month != date.month:
146
+ return self._adjust_preceding(date)
147
+ return adjusted
148
+
149
+ if convention == BusinessDayConvention.PRECEDING:
150
+ return self._adjust_preceding(date)
151
+
152
+ if convention == BusinessDayConvention.MODIFIED_PRECEDING:
153
+ adjusted = self._adjust_preceding(date)
154
+ # If adjustment crosses month boundary, use following instead
155
+ if adjusted.month != date.month:
156
+ return self._adjust_following(date)
157
+ return adjusted
158
+
159
+ raise ValidationError(f"Unsupported business day convention: {convention}")
160
+
161
+ def _adjust_following(self, date: datetime) -> datetime:
162
+ """Roll forward to next business day."""
163
+ current = date
164
+ max_iterations = 10 # Prevent infinite loops
165
+ iterations = 0
166
+
167
+ while not self.is_business_day(current) and iterations < max_iterations:
168
+ current = current + timedelta(days=1)
169
+ iterations += 1
170
+
171
+ if iterations >= max_iterations:
172
+ raise ValidationError(
173
+ f"Could not find business day within {max_iterations} days"
174
+ )
175
+
176
+ return current
177
+
178
+ def _adjust_preceding(self, date: datetime) -> datetime:
179
+ """Roll backward to previous business day."""
180
+ current = date
181
+ max_iterations = 10 # Prevent infinite loops
182
+ iterations = 0
183
+
184
+ while not self.is_business_day(current) and iterations < max_iterations:
185
+ current = current - timedelta(days=1)
186
+ iterations += 1
187
+
188
+ if iterations >= max_iterations:
189
+ raise ValidationError(
190
+ f"Could not find business day within {max_iterations} days"
191
+ )
192
+
193
+ return current
194
+
195
+ def add_business_days(self, date: datetime, num_days: int) -> datetime:
196
+ """
197
+ Add a number of business days to a date.
198
+
199
+ Args:
200
+ date: Starting date
201
+ num_days: Number of business days to add (can be negative)
202
+
203
+ Returns:
204
+ Date after adding business days
205
+ """
206
+ if num_days == 0:
207
+ return date
208
+
209
+ direction = 1 if num_days > 0 else -1
210
+ remaining = abs(num_days)
211
+ current = date
212
+
213
+ while remaining > 0:
214
+ current = current + timedelta(days=direction)
215
+ if self.is_business_day(current):
216
+ remaining -= 1
217
+
218
+ return current
219
+
220
+ def count_business_days(
221
+ self,
222
+ start_date: datetime,
223
+ end_date: datetime,
224
+ include_start: bool = True,
225
+ include_end: bool = True,
226
+ ) -> int:
227
+ """
228
+ Count business days between two dates.
229
+
230
+ Args:
231
+ start_date: Start date (inclusive by default)
232
+ end_date: End date (inclusive by default)
233
+ include_start: Whether to include start_date if business day
234
+ include_end: Whether to include end_date if business day
235
+
236
+ Returns:
237
+ Number of business days in the range
238
+ """
239
+ if end_date < start_date:
240
+ return 0
241
+
242
+ count = 0
243
+ current = start_date
244
+ while current <= end_date:
245
+ if self.is_business_day(current):
246
+ if current == start_date and not include_start:
247
+ pass
248
+ elif current == end_date and not include_end:
249
+ pass
250
+ else:
251
+ count += 1
252
+ current += timedelta(days=1)
253
+ return count
254
+
255
+ def __repr__(self):
256
+ return f"Calendar(name={self.name}, holidays={len(self.holidays)})"
257
+
258
+
259
+ def create_calendar(
260
+ calendar_type: CalendarType, year_range: tuple = (2020, 2030)
261
+ ) -> Calendar:
262
+ """
263
+ Create a calendar with predefined holidays.
264
+
265
+ Args:
266
+ calendar_type: Type of calendar to create
267
+ year_range: (start_year, end_year) for generating holidays
268
+
269
+ Returns:
270
+ Calendar with appropriate holidays
271
+ """
272
+ if calendar_type == CalendarType.NONE:
273
+ return Calendar(holidays=set(), name="No Holidays")
274
+
275
+ if calendar_type == CalendarType.US:
276
+ return _create_us_calendar(year_range)
277
+
278
+ if calendar_type == CalendarType.UK:
279
+ return _create_uk_calendar(year_range)
280
+
281
+ if calendar_type == CalendarType.TARGET:
282
+ return _create_target_calendar(year_range)
283
+
284
+ if calendar_type == CalendarType.CHINA:
285
+ return _create_china_calendar(year_range)
286
+
287
+ if calendar_type == CalendarType.CHINA_SSE:
288
+ return _create_china_sse_calendar(year_range)
289
+
290
+ raise ValidationError(f"Unsupported calendar type: {calendar_type}")
291
+
292
+
293
+ def _create_us_calendar(year_range: tuple) -> Calendar:
294
+ """
295
+ Create US Federal Reserve holiday calendar.
296
+
297
+ Includes: New Year's Day, MLK Day, Presidents Day, Memorial Day,
298
+ Independence Day, Labor Day, Columbus Day, Veterans Day,
299
+ Thanksgiving, Christmas
300
+ """
301
+ holidays = set()
302
+ start_year, end_year = year_range
303
+
304
+ for year in range(start_year, end_year + 1):
305
+ # New Year's Day (Jan 1)
306
+ holidays.add(datetime(year, 1, 1))
307
+
308
+ # Martin Luther King Jr. Day (3rd Monday in January)
309
+ holidays.add(_nth_weekday(year, 1, 0, 3))
310
+
311
+ # Presidents Day (3rd Monday in February)
312
+ holidays.add(_nth_weekday(year, 2, 0, 3))
313
+
314
+ # Memorial Day (last Monday in May)
315
+ holidays.add(_last_weekday(year, 5, 0))
316
+
317
+ # Independence Day (July 4)
318
+ holidays.add(datetime(year, 7, 4))
319
+
320
+ # Labor Day (1st Monday in September)
321
+ holidays.add(_nth_weekday(year, 9, 0, 1))
322
+
323
+ # Columbus Day (2nd Monday in October)
324
+ holidays.add(_nth_weekday(year, 10, 0, 2))
325
+
326
+ # Veterans Day (Nov 11)
327
+ holidays.add(datetime(year, 11, 11))
328
+
329
+ # Thanksgiving (4th Thursday in November)
330
+ holidays.add(_nth_weekday(year, 11, 3, 4))
331
+
332
+ # Christmas (Dec 25)
333
+ holidays.add(datetime(year, 12, 25))
334
+
335
+ return Calendar(holidays=holidays, name="US Federal Reserve")
336
+
337
+
338
+ def _create_uk_calendar(year_range: tuple) -> Calendar:
339
+ """
340
+ Create UK holiday calendar.
341
+
342
+ Includes: New Year's Day, Good Friday, Easter Monday, Early May,
343
+ Spring Bank Holiday, Summer Bank Holiday, Christmas, Boxing Day
344
+ """
345
+ holidays = set()
346
+ start_year, end_year = year_range
347
+
348
+ for year in range(start_year, end_year + 1):
349
+ # New Year's Day
350
+ holidays.add(datetime(year, 1, 1))
351
+
352
+ # Good Friday and Easter Monday (based on Easter calculation)
353
+ easter = _calculate_easter(year)
354
+ holidays.add(easter - timedelta(days=2)) # Good Friday
355
+ holidays.add(easter + timedelta(days=1)) # Easter Monday
356
+
357
+ # Early May Bank Holiday (1st Monday in May)
358
+ holidays.add(_nth_weekday(year, 5, 0, 1))
359
+
360
+ # Spring Bank Holiday (last Monday in May)
361
+ holidays.add(_last_weekday(year, 5, 0))
362
+
363
+ # Summer Bank Holiday (last Monday in August)
364
+ holidays.add(_last_weekday(year, 8, 0))
365
+
366
+ # Christmas Day
367
+ holidays.add(datetime(year, 12, 25))
368
+
369
+ # Boxing Day
370
+ holidays.add(datetime(year, 12, 26))
371
+
372
+ return Calendar(holidays=holidays, name="UK")
373
+
374
+
375
+ def _create_target_calendar(year_range: tuple) -> Calendar:
376
+ """
377
+ Create TARGET (Trans-European Automated Real-time Gross settlement) calendar.
378
+ Used by European Central Bank.
379
+
380
+ Includes: New Year's Day, Good Friday, Easter Monday, Labour Day,
381
+ Christmas, Boxing Day
382
+ """
383
+ holidays = set()
384
+ start_year, end_year = year_range
385
+
386
+ for year in range(start_year, end_year + 1):
387
+ # New Year's Day
388
+ holidays.add(datetime(year, 1, 1))
389
+
390
+ # Good Friday and Easter Monday
391
+ easter = _calculate_easter(year)
392
+ holidays.add(easter - timedelta(days=2)) # Good Friday
393
+ holidays.add(easter + timedelta(days=1)) # Easter Monday
394
+
395
+ # Labour Day (May 1)
396
+ holidays.add(datetime(year, 5, 1))
397
+
398
+ # Christmas Day
399
+ holidays.add(datetime(year, 12, 25))
400
+
401
+ # Boxing Day (Dec 26)
402
+ holidays.add(datetime(year, 12, 26))
403
+
404
+ return Calendar(holidays=holidays, name="TARGET")
405
+
406
+
407
+ def _load_holidays_from_csv(
408
+ calendar_name: str, year_range: tuple
409
+ ) -> Optional[Set[datetime]]:
410
+ start_year, end_year = year_range
411
+ csv_resource = (
412
+ resources.files("quantark.util")
413
+ / "calendar"
414
+ / "holidayfile"
415
+ / f"{calendar_name}.csv"
416
+ )
417
+ if not csv_resource.is_file():
418
+ return None
419
+
420
+ holidays: Set[datetime] = set()
421
+ try:
422
+ with csv_resource.open("r", newline="", encoding="utf-8") as handle:
423
+ reader = csv.DictReader(handle)
424
+ for row in reader:
425
+ date_str = (row.get("date") or row.get("Date") or "").strip()
426
+ if not date_str:
427
+ continue
428
+ try:
429
+ parsed = datetime.strptime(date_str, "%Y-%m-%d")
430
+ except ValueError:
431
+ continue
432
+ if start_year <= parsed.year <= end_year:
433
+ holidays.add(datetime(parsed.year, parsed.month, parsed.day))
434
+ except Exception:
435
+ return None
436
+
437
+ return holidays or None
438
+
439
+
440
+ def _create_china_calendar(year_range: tuple) -> Calendar:
441
+ """
442
+ Create China holiday calendar (national).
443
+
444
+ Note: Uses util/calendar/holidayfile/china.csv when available.
445
+ Falls back to a simplified fixed-date set if the CSV is missing.
446
+
447
+ Includes: New Year's Day, Spring Festival (approximate), Qingming,
448
+ Labour Day, Dragon Boat Festival (approximate), Mid-Autumn Festival (approximate),
449
+ National Day
450
+ """
451
+ holidays = _load_holidays_from_csv("china", year_range)
452
+ if holidays:
453
+ return Calendar(holidays=holidays, name="China")
454
+
455
+ holidays = set()
456
+ start_year, end_year = year_range
457
+
458
+ for year in range(start_year, end_year + 1):
459
+ # New Year's Day (Jan 1)
460
+ holidays.add(datetime(year, 1, 1))
461
+
462
+ # Spring Festival / Chinese New Year (approximate - late Jan/early Feb)
463
+ # Using approximate dates; actual dates vary by lunar calendar
464
+ # Typically a week-long holiday
465
+ for day in range(1, 8):
466
+ holidays.add(datetime(year, 2, day))
467
+
468
+ # Qingming Festival (April 4 or 5)
469
+ holidays.add(datetime(year, 4, 4))
470
+ holidays.add(datetime(year, 4, 5))
471
+
472
+ # Labour Day (May 1-3)
473
+ holidays.add(datetime(year, 5, 1))
474
+ holidays.add(datetime(year, 5, 2))
475
+ holidays.add(datetime(year, 5, 3))
476
+
477
+ # Dragon Boat Festival (approximate - June)
478
+ holidays.add(datetime(year, 6, 12))
479
+ holidays.add(datetime(year, 6, 13))
480
+ holidays.add(datetime(year, 6, 14))
481
+
482
+ # Mid-Autumn Festival (approximate - September)
483
+ holidays.add(datetime(year, 9, 15))
484
+ holidays.add(datetime(year, 9, 16))
485
+ holidays.add(datetime(year, 9, 17))
486
+
487
+ # National Day (Oct 1-7)
488
+ for day in range(1, 8):
489
+ holidays.add(datetime(year, 10, day))
490
+
491
+ return Calendar(holidays=holidays, name="China")
492
+
493
+
494
+ def _create_china_sse_calendar(year_range: tuple) -> Calendar:
495
+ """
496
+ Create China SSE holiday calendar.
497
+
498
+ Note: Uses util/calendar/holidayfile/china_sse.csv when available.
499
+ Falls back to the national China calendar when the CSV is missing.
500
+ """
501
+ holidays = _load_holidays_from_csv("china_sse", year_range)
502
+ if holidays:
503
+ return Calendar(holidays=holidays, name="China (SSE)")
504
+
505
+ fallback = _create_china_calendar(year_range)
506
+ fallback.name = "China (SSE)"
507
+ return fallback
508
+
509
+
510
+ def _nth_weekday(year: int, month: int, weekday: int, n: int) -> datetime:
511
+ """
512
+ Find the nth occurrence of a weekday in a month.
513
+
514
+ Args:
515
+ year: Year
516
+ month: Month (1-12)
517
+ weekday: Day of week (0=Monday, 6=Sunday)
518
+ n: Which occurrence (1=first, 2=second, etc.)
519
+
520
+ Returns:
521
+ Date of nth weekday
522
+ """
523
+ first_day = datetime(year, month, 1)
524
+ first_weekday = first_day.weekday()
525
+
526
+ # Calculate days until first occurrence of target weekday
527
+ days_until = (weekday - first_weekday) % 7
528
+ first_occurrence = first_day + timedelta(days=days_until)
529
+
530
+ # Add weeks to get to nth occurrence
531
+ return first_occurrence + timedelta(weeks=n - 1)
532
+
533
+
534
+ def _last_weekday(year: int, month: int, weekday: int) -> datetime:
535
+ """
536
+ Find the last occurrence of a weekday in a month.
537
+
538
+ Args:
539
+ year: Year
540
+ month: Month (1-12)
541
+ weekday: Day of week (0=Monday, 6=Sunday)
542
+
543
+ Returns:
544
+ Date of last weekday in month
545
+ """
546
+ # Start from last day of month
547
+ if month == 12:
548
+ last_day = datetime(year, 12, 31)
549
+ else:
550
+ last_day = datetime(year, month + 1, 1) - timedelta(days=1)
551
+
552
+ last_weekday_val = last_day.weekday()
553
+
554
+ # Calculate days back to target weekday
555
+ days_back = (last_weekday_val - weekday) % 7
556
+ return last_day - timedelta(days=days_back)
557
+
558
+
559
+ def _calculate_easter(year: int) -> datetime:
560
+ """
561
+ Calculate Easter Sunday using Meeus/Jones/Butcher algorithm.
562
+
563
+ Args:
564
+ year: Year
565
+
566
+ Returns:
567
+ Date of Easter Sunday
568
+ """
569
+ a = year % 19
570
+ b = year // 100
571
+ c = year % 100
572
+ d = b // 4
573
+ e = b % 4
574
+ f = (b + 8) // 25
575
+ g = (b - f + 1) // 3
576
+ h = (19 * a + b - d - g + 15) % 30
577
+ i = c // 4
578
+ k = c % 4
579
+ l = (32 + 2 * e + 2 * i - h - k) % 7
580
+ m = (a + 11 * h + 22 * l) // 451
581
+ month = (h + l - 7 * m + 114) // 31
582
+ day = ((h + l - 7 * m + 114) % 31) + 1
583
+
584
+ return datetime(year, month, day)