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,196 @@
1
+ """
2
+ Pricing environment that bundles all market data.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Optional
7
+ from datetime import datetime
8
+ from quantark.param import SpotQuote, VolatilitySurface, RateCurve, DividendYield, BasisYield
9
+ from quantark.util.exceptions import MarketDataError
10
+ from quantark.util.calendar import Calendar, DayCountConvention
11
+ from quantark.util.numerical import safe_sqrt
12
+
13
+
14
+ @dataclass
15
+ class PricingEnvironment:
16
+ """
17
+ Pricing environment containing all market data required for pricing.
18
+
19
+ This class bundles together all market parameters needed for derivative pricing:
20
+ spot price, volatility surface, risk-free rate curve, and dividend yield.
21
+
22
+ For bond pricing, only rate_curve and valuation_date are required.
23
+ For equity derivatives, spot_quote and vol_surface are also required.
24
+
25
+ Attributes:
26
+ rate_curve: Risk-free rate curve (required)
27
+ valuation_date: Date of valuation (required)
28
+ spot_quote: Current spot price of the underlying (optional, required for equity)
29
+ vol_surface: Volatility surface (optional, required for equity derivatives)
30
+ div_yield: Dividend yield (optional, defaults to zero)
31
+ basis_yield: Annualized basis yield for futures (optional, defaults to None)
32
+ day_count_convention: Convention for calculating year fractions (default: CALENDAR_DAYS)
33
+ bus_days_in_year: Number of business days per year for business day convention (default: 252)
34
+ calendar: Optional business day calendar (used when day_count_convention is BUSINESS_DAYS)
35
+ """
36
+
37
+ rate_curve: RateCurve
38
+ valuation_date: datetime
39
+ spot_quote: Optional[SpotQuote] = None
40
+ vol_surface: Optional[VolatilitySurface] = None
41
+ div_yield: Optional[DividendYield] = None
42
+ basis_yield: Optional[BasisYield] = None
43
+ day_count_convention: DayCountConvention = DayCountConvention.CALENDAR_DAYS
44
+ bus_days_in_year: int = 252
45
+ calendar: Optional[Calendar] = None
46
+
47
+ def __post_init__(self):
48
+ """Validate pricing environment."""
49
+ if self.rate_curve is None:
50
+ raise MarketDataError("Rate curve is required")
51
+ if self.valuation_date is None:
52
+ raise MarketDataError("Valuation date is required")
53
+ if self.bus_days_in_year <= 0:
54
+ raise MarketDataError(
55
+ f"Business days per year must be positive, got {self.bus_days_in_year}"
56
+ )
57
+
58
+ @property
59
+ def spot(self) -> float:
60
+ """
61
+ Get current spot price.
62
+
63
+ Raises:
64
+ MarketDataError: If spot quote is not available
65
+ """
66
+ if self.spot_quote is None:
67
+ raise MarketDataError(
68
+ "Spot quote not available in this pricing environment"
69
+ )
70
+ return self.spot_quote.spot
71
+
72
+ def get_vol(self, strike: float, time_to_maturity: float) -> float:
73
+ """
74
+ Get volatility for given strike and maturity.
75
+
76
+ Args:
77
+ strike: Strike price
78
+ time_to_maturity: Time to maturity in years
79
+
80
+ Returns:
81
+ Implied volatility
82
+
83
+ Raises:
84
+ MarketDataError: If volatility surface is not available
85
+ """
86
+ if self.vol_surface is None:
87
+ raise MarketDataError(
88
+ "Volatility surface not available in this pricing environment"
89
+ )
90
+ if self.spot_quote is None:
91
+ raise MarketDataError(
92
+ "Spot quote not available in this pricing environment"
93
+ )
94
+ return self.vol_surface.get_vol(strike, time_to_maturity, self.spot)
95
+
96
+ def get_step_volatility(
97
+ self, strike: float, t_start: float, t_end: float
98
+ ) -> float:
99
+ """
100
+ Get effective volatility for a time step from implied vol term structure.
101
+
102
+ Uses total variance difference:
103
+ sigma_step = sqrt((w(t_end) - w(t_start)) / (t_end - t_start))
104
+ where:
105
+ w(t) = sigma_imp(strike, t)^2 * t
106
+
107
+ Args:
108
+ strike: Reference strike for volatility lookup (often spot)
109
+ t_start: Start time in years from valuation
110
+ t_end: End time in years from valuation
111
+
112
+ Returns:
113
+ Effective step volatility (annualized)
114
+ """
115
+ dt = t_end - t_start
116
+ if dt <= 0:
117
+ return self.get_vol(strike, max(t_end, 0.001))
118
+
119
+ vol_end = self.get_vol(strike, t_end)
120
+ w_end = vol_end * vol_end * t_end
121
+
122
+ if t_start <= 0:
123
+ w_start = 0.0
124
+ else:
125
+ vol_start = self.get_vol(strike, t_start)
126
+ w_start = vol_start * vol_start * t_start
127
+
128
+ var_step = max(0.0, w_end - w_start)
129
+ return safe_sqrt(var_step / dt)
130
+
131
+ def get_rate(self, time_to_maturity: float) -> float:
132
+ """
133
+ Get risk-free rate for given maturity.
134
+
135
+ Args:
136
+ time_to_maturity: Time to maturity in years
137
+
138
+ Returns:
139
+ Risk-free rate
140
+ """
141
+ return self.rate_curve.get_rate(time_to_maturity)
142
+
143
+ def get_discount_factor(self, time_to_maturity: float) -> float:
144
+ """
145
+ Get discount factor for given maturity.
146
+
147
+ Args:
148
+ time_to_maturity: Time to maturity in years
149
+
150
+ Returns:
151
+ Discount factor
152
+ """
153
+ return self.rate_curve.get_discount_factor(time_to_maturity)
154
+
155
+ def get_div_yield(self, time_to_maturity: float) -> float:
156
+ """
157
+ Get dividend yield for given maturity.
158
+
159
+ Args:
160
+ time_to_maturity: Time to maturity in years
161
+
162
+ Returns:
163
+ Dividend yield (0 if not specified)
164
+ """
165
+ if self.div_yield is None:
166
+ return 0.0
167
+ return self.div_yield.get_yield(time_to_maturity)
168
+
169
+ def get_basis_yield(self, time_to_maturity: float) -> float:
170
+ """
171
+ Get basis yield for given maturity.
172
+
173
+ Args:
174
+ time_to_maturity: Time to maturity in years
175
+
176
+ Returns:
177
+ Basis yield (0 if not specified)
178
+ """
179
+ if self.basis_yield is None:
180
+ return 0.0
181
+ return self.basis_yield.get_basis_yield(time_to_maturity)
182
+
183
+ def __repr__(self):
184
+ parts = [f"valuation_date={self.valuation_date.date()}"]
185
+
186
+ if self.spot_quote is not None:
187
+ parts.append(f"spot={self.spot:.2f}")
188
+
189
+ parts.append(f"rate={self.rate_curve.get_rate(1.0):.2%}")
190
+
191
+ if self.vol_surface is not None and self.spot_quote is not None:
192
+ parts.append(
193
+ f"vol={self.vol_surface.get_vol(self.spot, 1.0, self.spot):.2%}"
194
+ )
195
+
196
+ return f"PricingEnvironment({', '.join(parts)})"
@@ -0,0 +1,32 @@
1
+ """
2
+ RFQ module for equity OTC quote solving.
3
+ """
4
+
5
+ from quantark.rfq.models import (
6
+ RFQEngineSpec,
7
+ RFQInputMode,
8
+ RFQObjectInput,
9
+ RFQQuote,
10
+ RFQQuoteStatus,
11
+ RFQRequest,
12
+ RFQTarget,
13
+ RFQTargetLabel,
14
+ RFQTermsheetInput,
15
+ RFQUnknownSpec,
16
+ )
17
+ from quantark.rfq.service import RFQService, quote_rfq
18
+
19
+ __all__ = [
20
+ "RFQEngineSpec",
21
+ "RFQInputMode",
22
+ "RFQObjectInput",
23
+ "RFQQuote",
24
+ "RFQQuoteStatus",
25
+ "RFQRequest",
26
+ "RFQTarget",
27
+ "RFQTargetLabel",
28
+ "RFQTermsheetInput",
29
+ "RFQUnknownSpec",
30
+ "RFQService",
31
+ "quote_rfq",
32
+ ]
@@ -0,0 +1,102 @@
1
+ """
2
+ Normalization helpers for term-sheet RFQ inputs.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from datetime import datetime
8
+ from typing import Any, Dict
9
+
10
+ from quantark.param import (
11
+ ContinuousDividendYield,
12
+ FlatRateCurve,
13
+ FlatVolSurface,
14
+ SpotQuote,
15
+ )
16
+ from quantark.priceenv import PricingEnvironment
17
+ from quantark.rfq.models import RFQTermsheetInput
18
+ from quantark.rfq.registry import ENGINE_BUILDERS, PRODUCT_BUILDERS
19
+ from quantark.util.exceptions import ValidationError
20
+
21
+
22
+ def build_product_from_termsheet(termsheet: RFQTermsheetInput) -> Any:
23
+ """Build product instance from term-sheet input."""
24
+ return PRODUCT_BUILDERS.build(termsheet.product_type, termsheet.product_kwargs)
25
+
26
+
27
+ def build_engine_from_termsheet(termsheet: RFQTermsheetInput) -> Any:
28
+ """Build engine instance from term-sheet engine spec."""
29
+ return ENGINE_BUILDERS.build(termsheet.engine_spec)
30
+
31
+
32
+ def build_pricing_env_from_market_kwargs(market_kwargs: Dict[str, Any]) -> PricingEnvironment:
33
+ """Build pricing environment from a normalized market kwargs mapping."""
34
+ allowed = {
35
+ "valuation_date",
36
+ "rate_curve",
37
+ "rate",
38
+ "spot_quote",
39
+ "spot",
40
+ "asset_name",
41
+ "vol_surface",
42
+ "volatility",
43
+ "div_yield",
44
+ "dividend_yield",
45
+ "q",
46
+ "basis_yield",
47
+ "day_count_convention",
48
+ "bus_days_in_year",
49
+ "calendar",
50
+ }
51
+ unknown = set(market_kwargs) - allowed
52
+ if unknown:
53
+ unknown_list = ", ".join(sorted(unknown))
54
+ raise ValidationError(f"Unsupported market_kwargs: {unknown_list}")
55
+
56
+ valuation_date = market_kwargs.get("valuation_date")
57
+ if valuation_date is None:
58
+ raise ValidationError("market_kwargs.valuation_date is required")
59
+ if not isinstance(valuation_date, datetime):
60
+ raise ValidationError("market_kwargs.valuation_date must be datetime")
61
+
62
+ rate_curve = market_kwargs.get("rate_curve")
63
+ if rate_curve is None:
64
+ rate = market_kwargs.get("rate")
65
+ if rate is None:
66
+ raise ValidationError(
67
+ "market_kwargs requires either rate_curve or rate"
68
+ )
69
+ rate_curve = FlatRateCurve(rate=float(rate))
70
+
71
+ spot_quote = market_kwargs.get("spot_quote")
72
+ if spot_quote is None and "spot" in market_kwargs:
73
+ spot_quote = SpotQuote(
74
+ spot=float(market_kwargs["spot"]),
75
+ timestamp=valuation_date,
76
+ asset_name=market_kwargs.get("asset_name"),
77
+ )
78
+
79
+ vol_surface = market_kwargs.get("vol_surface")
80
+ if vol_surface is None and "volatility" in market_kwargs:
81
+ vol_surface = FlatVolSurface(volatility=float(market_kwargs["volatility"]))
82
+
83
+ div_yield = market_kwargs.get("div_yield")
84
+ if div_yield is None:
85
+ if "dividend_yield" in market_kwargs:
86
+ div_yield = ContinuousDividendYield(
87
+ div_yield=float(market_kwargs["dividend_yield"])
88
+ )
89
+ elif "q" in market_kwargs:
90
+ div_yield = ContinuousDividendYield(div_yield=float(market_kwargs["q"]))
91
+
92
+ return PricingEnvironment(
93
+ rate_curve=rate_curve,
94
+ valuation_date=valuation_date,
95
+ spot_quote=spot_quote,
96
+ vol_surface=vol_surface,
97
+ div_yield=div_yield,
98
+ basis_yield=market_kwargs.get("basis_yield"),
99
+ day_count_convention=market_kwargs.get("day_count_convention"),
100
+ bus_days_in_year=market_kwargs.get("bus_days_in_year", 252),
101
+ calendar=market_kwargs.get("calendar"),
102
+ )
quantark/rfq/models.py ADDED
@@ -0,0 +1,214 @@
1
+ """
2
+ Data models for RFQ quote solving.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from dataclasses import dataclass, field
8
+ from datetime import datetime
9
+ from enum import Enum
10
+ from typing import Any, Dict, Optional
11
+
12
+ from quantark.asset.equity.engine.base_engine import BaseEngine
13
+ from quantark.priceenv import PricingEnvironment
14
+ from quantark.util.exceptions import ValidationError
15
+ from quantark.util.numerical import is_close
16
+
17
+
18
+ class RFQInputMode(Enum):
19
+ """Supported RFQ request input modes."""
20
+
21
+ OBJECT = "object"
22
+ TERMSHEET = "termsheet"
23
+
24
+
25
+ class RFQTargetLabel(Enum):
26
+ """Target labels supported by the RFQ solver."""
27
+
28
+ PRICE = "price"
29
+ PREMIUM = "premium"
30
+ REOFFER = "reoffer"
31
+
32
+
33
+ class RFQQuoteStatus(Enum):
34
+ """RFQ quote lifecycle status for v1."""
35
+
36
+ SUCCESS = "success"
37
+
38
+
39
+ @dataclass(frozen=True)
40
+ class RFQUnknownSpec:
41
+ """Describe the single unknown value to solve for."""
42
+
43
+ field_path: str
44
+ lower_bound: float
45
+ upper_bound: float
46
+ initial_guess: Optional[float] = None
47
+ display_label: Optional[str] = None
48
+
49
+ def __post_init__(self) -> None:
50
+ if not self.field_path:
51
+ raise ValidationError("field_path is required")
52
+ if self.lower_bound >= self.upper_bound:
53
+ raise ValidationError(
54
+ "lower_bound must be strictly less than upper_bound"
55
+ )
56
+ if self.initial_guess is not None:
57
+ if not (self.lower_bound <= self.initial_guess <= self.upper_bound):
58
+ raise ValidationError(
59
+ "initial_guess must lie within [lower_bound, upper_bound]"
60
+ )
61
+
62
+
63
+ @dataclass(frozen=True)
64
+ class RFQTarget:
65
+ """Explicit target price objective."""
66
+
67
+ label: RFQTargetLabel
68
+ value: float
69
+
70
+ def __post_init__(self) -> None:
71
+ if not isinstance(self.label, RFQTargetLabel):
72
+ raise ValidationError(f"Invalid RFQ target label: {self.label}")
73
+
74
+
75
+ @dataclass(frozen=True)
76
+ class RFQObjectInput:
77
+ """Object-based RFQ input path."""
78
+
79
+ product: Any
80
+ pricing_env: PricingEnvironment
81
+ engine: BaseEngine
82
+
83
+ def __post_init__(self) -> None:
84
+ if self.product is None:
85
+ raise ValidationError("product is required for object RFQ input")
86
+ if self.pricing_env is None:
87
+ raise ValidationError("pricing_env is required for object RFQ input")
88
+ if self.engine is None:
89
+ raise ValidationError("engine is required for object RFQ input")
90
+
91
+
92
+ @dataclass(frozen=True)
93
+ class RFQEngineSpec:
94
+ """Term-sheet engine selection."""
95
+
96
+ engine_name: str
97
+ params_type: Optional[str] = None
98
+ params_kwargs: Dict[str, Any] = field(default_factory=dict)
99
+ method: Optional[Any] = None
100
+ engine_kwargs: Dict[str, Any] = field(default_factory=dict)
101
+
102
+ def __post_init__(self) -> None:
103
+ if not self.engine_name:
104
+ raise ValidationError("engine_name is required in engine_spec")
105
+
106
+
107
+ @dataclass(frozen=True)
108
+ class RFQTermsheetInput:
109
+ """Term-sheet RFQ input path."""
110
+
111
+ product_type: str
112
+ product_kwargs: Dict[str, Any]
113
+ market_kwargs: Dict[str, Any]
114
+ engine_spec: RFQEngineSpec
115
+
116
+ def __post_init__(self) -> None:
117
+ if not self.product_type:
118
+ raise ValidationError("product_type is required for term-sheet RFQ input")
119
+ if self.product_kwargs is None:
120
+ raise ValidationError("product_kwargs is required for term-sheet RFQ input")
121
+ if self.market_kwargs is None:
122
+ raise ValidationError("market_kwargs is required for term-sheet RFQ input")
123
+ if self.engine_spec is None:
124
+ raise ValidationError("engine_spec is required for term-sheet RFQ input")
125
+
126
+
127
+ @dataclass(frozen=True)
128
+ class RFQRequest:
129
+ """Canonical RFQ request."""
130
+
131
+ input_mode: RFQInputMode
132
+ unknown: RFQUnknownSpec
133
+ target: RFQTarget
134
+ object_input: Optional[RFQObjectInput] = None
135
+ termsheet_input: Optional[RFQTermsheetInput] = None
136
+ valid_until: Optional[datetime] = None
137
+ metadata: Dict[str, Any] = field(default_factory=dict)
138
+
139
+ def __post_init__(self) -> None:
140
+ if not isinstance(self.input_mode, RFQInputMode):
141
+ raise ValidationError(f"Invalid RFQ input mode: {self.input_mode}")
142
+ if self.unknown is None:
143
+ raise ValidationError("unknown is required")
144
+ if self.target is None:
145
+ raise ValidationError("target is required")
146
+
147
+ if self.input_mode == RFQInputMode.OBJECT:
148
+ if self.object_input is None:
149
+ raise ValidationError("object_input is required when input_mode=OBJECT")
150
+ if self.termsheet_input is not None:
151
+ raise ValidationError(
152
+ "termsheet_input must not be supplied when input_mode=OBJECT"
153
+ )
154
+ elif self.input_mode == RFQInputMode.TERMSHEET:
155
+ if self.termsheet_input is None:
156
+ raise ValidationError(
157
+ "termsheet_input is required when input_mode=TERMSHEET"
158
+ )
159
+ if self.object_input is not None:
160
+ raise ValidationError(
161
+ "object_input must not be supplied when input_mode=TERMSHEET"
162
+ )
163
+
164
+
165
+ @dataclass(frozen=True)
166
+ class RFQQuote:
167
+ """Successful RFQ quote response."""
168
+
169
+ quote_id: str
170
+ quoted_at: datetime
171
+ status: RFQQuoteStatus
172
+ field_path: str
173
+ field_label: str
174
+ solved_value: float
175
+ target_label: RFQTargetLabel
176
+ target_value: float
177
+ achieved_price: float
178
+ residual: float
179
+ engine_summary: Dict[str, Any]
180
+ request_summary: Dict[str, Any]
181
+ valid_until: Optional[datetime] = None
182
+
183
+ def __post_init__(self) -> None:
184
+ if not self.quote_id:
185
+ raise ValidationError("quote_id is required")
186
+ if not isinstance(self.status, RFQQuoteStatus):
187
+ raise ValidationError(f"Invalid RFQ quote status: {self.status}")
188
+ if not isinstance(self.target_label, RFQTargetLabel):
189
+ raise ValidationError(f"Invalid RFQ target label: {self.target_label}")
190
+
191
+ @property
192
+ def converged(self) -> bool:
193
+ """Whether the solved price matches the target within tight tolerance."""
194
+ return is_close(self.achieved_price, self.target_value, abs_tol=1e-8)
195
+
196
+ def to_dict(self) -> Dict[str, Any]:
197
+ """Serialize quote payload for reporting and tests."""
198
+ return {
199
+ "quote_id": self.quote_id,
200
+ "quoted_at": self.quoted_at.isoformat(),
201
+ "status": self.status.value,
202
+ "field_path": self.field_path,
203
+ "field_label": self.field_label,
204
+ "solved_value": self.solved_value,
205
+ "target_label": self.target_label.value,
206
+ "target_value": self.target_value,
207
+ "achieved_price": self.achieved_price,
208
+ "residual": self.residual,
209
+ "engine_summary": dict(self.engine_summary),
210
+ "request_summary": dict(self.request_summary),
211
+ "valid_until": (
212
+ self.valid_until.isoformat() if self.valid_until is not None else None
213
+ ),
214
+ }