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,583 @@
1
+ """
2
+ Black '76 pricing engine for European bond options.
3
+
4
+ The Black model is the standard approach for pricing European options on
5
+ bonds and other fixed income instruments.
6
+ """
7
+ import math
8
+ from dataclasses import dataclass
9
+ from datetime import datetime
10
+ from typing import Optional
11
+
12
+ from scipy import stats
13
+
14
+ from quantark.asset.bond.product.option.euro_short_term_bond_option import EuroShortTermBondOption
15
+ from quantark.asset.bond.engine.discount.bond_discount_engine import BondDiscountEngine
16
+ from quantark.priceenv import PricingEnvironment
17
+ from quantark.util.exceptions import ValidationError, NumericalError, PricingError
18
+
19
+
20
+ @dataclass
21
+ class BlackBondOptionResults:
22
+ """
23
+ Results from Black model bond option pricing.
24
+
25
+ Attributes:
26
+ price: Option price
27
+ forward_bond_price: Forward price of the underlying bond
28
+ d1: Black model d1 parameter
29
+ d2: Black model d2 parameter
30
+ discount_factor: Discount factor to option expiry
31
+ time_to_expiry: Time to option expiry in years
32
+ volatility: Volatility used in pricing
33
+ """
34
+ price: float
35
+ forward_bond_price: float
36
+ d1: float
37
+ d2: float
38
+ discount_factor: float
39
+ time_to_expiry: float
40
+ volatility: float
41
+
42
+
43
+ class BlackBondOptionEngine:
44
+ """
45
+ Black '76 pricing engine for European bond options.
46
+
47
+ Uses the Black '76 model to price European options on bonds:
48
+
49
+ Call = D(T) * [F * N(d1) - K * N(d2)]
50
+ Put = D(T) * [K * N(-d2) - F * N(-d1)]
51
+
52
+ where:
53
+ D(T) = discount factor to option expiry
54
+ F = forward bond price
55
+ K = strike price
56
+ d1 = [ln(F/K) + σ²T/2] / (σ√T)
57
+ d2 = d1 - σ√T
58
+ σ = volatility of bond price
59
+
60
+ The forward bond price is calculated by:
61
+ F = (Dirty Price - PV of coupons before expiry) * exp(r*T)
62
+
63
+ Attributes:
64
+ pricing_env: Pricing environment with market data
65
+ bond_engine: Engine for pricing the underlying bond
66
+ """
67
+
68
+ def __init__(self, pricing_env: PricingEnvironment):
69
+ """
70
+ Initialize Black bond option engine.
71
+
72
+ Args:
73
+ pricing_env: Pricing environment with rate curve and volatility
74
+
75
+ Raises:
76
+ ValidationError: If pricing environment is invalid
77
+ """
78
+ if pricing_env is None:
79
+ raise ValidationError("Pricing environment is required")
80
+
81
+ self.pricing_env = pricing_env
82
+ self.bond_engine = BondDiscountEngine(pricing_env)
83
+
84
+ def price(
85
+ self,
86
+ option: EuroShortTermBondOption,
87
+ volatility: Optional[float] = None,
88
+ valuation_date: Optional[datetime] = None
89
+ ) -> float:
90
+ """
91
+ Price a European bond option using Black '76 model.
92
+
93
+ Args:
94
+ option: Bond option to price
95
+ volatility: Price volatility (if None, uses vol surface from pricing_env)
96
+ valuation_date: Valuation date (default: pricing env date)
97
+
98
+ Returns:
99
+ Option price
100
+
101
+ Raises:
102
+ PricingError: If option has expired or pricing fails
103
+ NumericalError: If numerical issues occur
104
+ """
105
+ results = self.price_with_details(option, volatility, valuation_date)
106
+ return results.price
107
+
108
+ def price_with_details(
109
+ self,
110
+ option: EuroShortTermBondOption,
111
+ volatility: Optional[float] = None,
112
+ valuation_date: Optional[datetime] = None
113
+ ) -> BlackBondOptionResults:
114
+ """
115
+ Price a European bond option with detailed results.
116
+
117
+ Args:
118
+ option: Bond option to price
119
+ volatility: Price volatility (if None, uses vol surface from pricing_env)
120
+ valuation_date: Valuation date (default: pricing env date)
121
+
122
+ Returns:
123
+ BlackBondOptionResults with pricing details
124
+
125
+ Raises:
126
+ PricingError: If option has expired or pricing fails
127
+ NumericalError: If numerical issues occur
128
+ """
129
+ if valuation_date is None:
130
+ valuation_date = self.pricing_env.valuation_date
131
+
132
+ # Check if option has expired
133
+ if option.is_expired(valuation_date):
134
+ raise PricingError("Option has expired")
135
+
136
+ # Calculate time to expiry
137
+ T = option.get_time_to_expiry(valuation_date)
138
+
139
+ # Handle near-expiry case
140
+ if T < 1e-10:
141
+ bond_price = self._get_bond_price(option, valuation_date)
142
+ payoff = option.get_payoff(bond_price)
143
+ return BlackBondOptionResults(
144
+ price=payoff,
145
+ forward_bond_price=bond_price,
146
+ d1=0.0,
147
+ d2=0.0,
148
+ discount_factor=1.0,
149
+ time_to_expiry=T,
150
+ volatility=0.0
151
+ )
152
+
153
+ # Get forward bond price
154
+ F = self._calculate_forward_bond_price(option, valuation_date)
155
+
156
+ # Get strike
157
+ K = option.strike
158
+
159
+ # Get discount factor to option expiry
160
+ discount_factor = self.pricing_env.get_discount_factor(T)
161
+
162
+ # Get volatility
163
+ if volatility is None:
164
+ volatility = self._get_volatility(option, valuation_date, F, T)
165
+
166
+ # Validate inputs
167
+ self._validate_inputs(F, K, T, volatility)
168
+
169
+ # Calculate d1 and d2
170
+ d1, d2 = self._calculate_d1_d2(F, K, T, volatility)
171
+
172
+ # Calculate option price
173
+ if option.is_call():
174
+ price = self._price_call(F, K, discount_factor, d1, d2)
175
+ else:
176
+ price = self._price_put(F, K, discount_factor, d1, d2)
177
+
178
+ # Apply notional
179
+ price *= option.notional
180
+
181
+ # Sanity check
182
+ if price < 0:
183
+ raise NumericalError(f"Negative price computed: {price}")
184
+
185
+ return BlackBondOptionResults(
186
+ price=price,
187
+ forward_bond_price=F,
188
+ d1=d1,
189
+ d2=d2,
190
+ discount_factor=discount_factor,
191
+ time_to_expiry=T,
192
+ volatility=volatility
193
+ )
194
+
195
+ def _get_bond_price(
196
+ self,
197
+ option: EuroShortTermBondOption,
198
+ valuation_date: datetime
199
+ ) -> float:
200
+ """
201
+ Get current bond price (clean or dirty based on option specs).
202
+
203
+ Args:
204
+ option: Bond option
205
+ valuation_date: Valuation date
206
+
207
+ Returns:
208
+ Bond price
209
+ """
210
+ if option.strike_is_clean:
211
+ return self.bond_engine.clean_price(
212
+ option.underlying,
213
+ valuation_date,
214
+ valuation_date
215
+ )
216
+ else:
217
+ return self.bond_engine.dirty_price(
218
+ option.underlying,
219
+ valuation_date,
220
+ valuation_date
221
+ )
222
+
223
+ def _calculate_forward_bond_price(
224
+ self,
225
+ option: EuroShortTermBondOption,
226
+ valuation_date: datetime
227
+ ) -> float:
228
+ """
229
+ Calculate the forward price of the bond to option expiry.
230
+
231
+ Forward Price = (Spot Dirty Price - PV of coupons before expiry) * exp(r*T)
232
+
233
+ For clean price options, we adjust by subtracting accrued interest at expiry.
234
+
235
+ Args:
236
+ option: Bond option
237
+ valuation_date: Valuation date
238
+
239
+ Returns:
240
+ Forward bond price
241
+ """
242
+ underlying = option.underlying
243
+ expiry_date = option.expiry_date
244
+
245
+ # Get time to expiry
246
+ T = option.get_time_to_expiry(valuation_date)
247
+
248
+ # Get current dirty price
249
+ spot_dirty = self.bond_engine.dirty_price(underlying, valuation_date, valuation_date)
250
+
251
+ # Get cashflows between valuation and expiry
252
+ all_cashflows = underlying.get_cashflows(valuation_date)
253
+
254
+ # Calculate PV of coupons paid before expiry
255
+ coupon_pv = 0.0
256
+ for cf in all_cashflows:
257
+ if cf.payment_date <= expiry_date:
258
+ # Time from valuation to coupon payment
259
+ time_to_coupon = (cf.payment_date - valuation_date).days / 365.0
260
+ if time_to_coupon >= 0:
261
+ df = self.pricing_env.get_discount_factor(time_to_coupon)
262
+ coupon_pv += cf.amount * df
263
+
264
+ # Forward dirty price
265
+ r = self.pricing_env.get_rate(T)
266
+ forward_dirty = (spot_dirty - coupon_pv) * math.exp(r * T)
267
+
268
+ # Adjust for clean vs dirty
269
+ if option.strike_is_clean:
270
+ # Calculate accrued interest at expiry
271
+ accrued_at_expiry = underlying.calculate_accrued_interest(expiry_date)
272
+ forward_clean = forward_dirty - accrued_at_expiry
273
+ return forward_clean
274
+ else:
275
+ return forward_dirty
276
+
277
+ def _get_volatility(
278
+ self,
279
+ option: EuroShortTermBondOption,
280
+ valuation_date: datetime,
281
+ forward_price: float,
282
+ time_to_expiry: float
283
+ ) -> float:
284
+ """
285
+ Get volatility for pricing.
286
+
287
+ First tries to use the vol surface from pricing environment.
288
+ If not available, uses a default volatility.
289
+
290
+ Args:
291
+ option: Bond option
292
+ valuation_date: Valuation date
293
+ forward_price: Forward bond price
294
+ time_to_expiry: Time to option expiry
295
+
296
+ Returns:
297
+ Volatility for pricing
298
+ """
299
+ try:
300
+ # Try to use vol surface if available
301
+ if self.pricing_env.vol_surface is not None:
302
+ return self.pricing_env.get_vol(option.strike, time_to_expiry)
303
+ except Exception:
304
+ pass
305
+
306
+ # Default volatility for bonds (typically lower than equities)
307
+ # Around 5-15% for government bonds
308
+ return 0.10 # 10% default
309
+
310
+ def _validate_inputs(
311
+ self,
312
+ F: float,
313
+ K: float,
314
+ T: float,
315
+ sigma: float
316
+ ) -> None:
317
+ """
318
+ Validate inputs for numerical stability.
319
+
320
+ Args:
321
+ F: Forward price
322
+ K: Strike price
323
+ T: Time to expiry
324
+ sigma: Volatility
325
+
326
+ Raises:
327
+ ValidationError: If inputs are invalid
328
+ """
329
+ if F <= 0:
330
+ raise ValidationError(f"Forward price must be positive, got {F}")
331
+ if K <= 0:
332
+ raise ValidationError(f"Strike must be positive, got {K}")
333
+ if T < 0:
334
+ raise ValidationError(f"Time to expiry must be non-negative, got {T}")
335
+ if sigma <= 0:
336
+ raise ValidationError(f"Volatility must be positive, got {sigma}")
337
+ if sigma > 5.0:
338
+ raise ValidationError(f"Volatility too high: {sigma}")
339
+
340
+ def _calculate_d1_d2(
341
+ self,
342
+ F: float,
343
+ K: float,
344
+ T: float,
345
+ sigma: float
346
+ ) -> tuple:
347
+ """
348
+ Calculate Black model d1 and d2 parameters.
349
+
350
+ d1 = [ln(F/K) + σ²T/2] / (σ√T)
351
+ d2 = d1 - σ√T
352
+
353
+ Args:
354
+ F: Forward price
355
+ K: Strike price
356
+ T: Time to expiry
357
+ sigma: Volatility
358
+
359
+ Returns:
360
+ Tuple of (d1, d2)
361
+ """
362
+ try:
363
+ sqrt_T = math.sqrt(T)
364
+ log_moneyness = math.log(F / K)
365
+
366
+ # Check for extreme values
367
+ if abs(log_moneyness) > 100:
368
+ raise NumericalError(f"Extreme moneyness: ln(F/K) = {log_moneyness}")
369
+
370
+ numerator = log_moneyness + 0.5 * sigma * sigma * T
371
+ denominator = sigma * sqrt_T
372
+
373
+ if denominator <= 1e-10:
374
+ raise NumericalError(f"Denominator too small: σ√T = {denominator}")
375
+
376
+ d1 = numerator / denominator
377
+ d2 = d1 - sigma * sqrt_T
378
+
379
+ return d1, d2
380
+
381
+ except (OverflowError, ValueError) as e:
382
+ raise NumericalError(f"Numerical error in d1/d2 calculation: {e}")
383
+
384
+ def _price_call(
385
+ self,
386
+ F: float,
387
+ K: float,
388
+ discount_factor: float,
389
+ d1: float,
390
+ d2: float
391
+ ) -> float:
392
+ """
393
+ Calculate call option price using Black formula.
394
+
395
+ Call = D(T) * [F * N(d1) - K * N(d2)]
396
+
397
+ Args:
398
+ F: Forward price
399
+ K: Strike price
400
+ discount_factor: Discount factor to expiry
401
+ d1: d1 parameter
402
+ d2: d2 parameter
403
+
404
+ Returns:
405
+ Call option price
406
+ """
407
+ N_d1 = stats.norm.cdf(d1)
408
+ N_d2 = stats.norm.cdf(d2)
409
+
410
+ return discount_factor * (F * N_d1 - K * N_d2)
411
+
412
+ def _price_put(
413
+ self,
414
+ F: float,
415
+ K: float,
416
+ discount_factor: float,
417
+ d1: float,
418
+ d2: float
419
+ ) -> float:
420
+ """
421
+ Calculate put option price using Black formula.
422
+
423
+ Put = D(T) * [K * N(-d2) - F * N(-d1)]
424
+
425
+ Args:
426
+ F: Forward price
427
+ K: Strike price
428
+ discount_factor: Discount factor to expiry
429
+ d1: d1 parameter
430
+ d2: d2 parameter
431
+
432
+ Returns:
433
+ Put option price
434
+ """
435
+ N_minus_d1 = stats.norm.cdf(-d1)
436
+ N_minus_d2 = stats.norm.cdf(-d2)
437
+
438
+ return discount_factor * (K * N_minus_d2 - F * N_minus_d1)
439
+
440
+ def implied_volatility(
441
+ self,
442
+ option: EuroShortTermBondOption,
443
+ market_price: float,
444
+ valuation_date: Optional[datetime] = None,
445
+ initial_guess: float = 0.10,
446
+ max_iterations: int = 100,
447
+ tolerance: float = 1e-6
448
+ ) -> float:
449
+ """
450
+ Calculate implied volatility from market price using Newton-Raphson.
451
+
452
+ Args:
453
+ option: Bond option
454
+ market_price: Observed market price
455
+ valuation_date: Valuation date
456
+ initial_guess: Initial volatility guess (default: 10%)
457
+ max_iterations: Maximum iterations
458
+ tolerance: Convergence tolerance
459
+
460
+ Returns:
461
+ Implied volatility
462
+
463
+ Raises:
464
+ NumericalError: If convergence fails
465
+ """
466
+ if valuation_date is None:
467
+ valuation_date = self.pricing_env.valuation_date
468
+
469
+ if market_price <= 0:
470
+ raise ValidationError(f"Market price must be positive, got {market_price}")
471
+
472
+ # Adjust for notional
473
+ target_price = market_price / option.notional
474
+
475
+ sigma = initial_guess
476
+
477
+ for iteration in range(max_iterations):
478
+ # Calculate price and vega at current volatility
479
+ results = self.price_with_details(option, sigma, valuation_date)
480
+ price = results.price / option.notional
481
+
482
+ # Calculate raw vega (not per 1% change) for Newton-Raphson
483
+ vega = self._calculate_raw_vega(
484
+ results.forward_bond_price,
485
+ option.strike,
486
+ results.time_to_expiry,
487
+ sigma,
488
+ results.discount_factor,
489
+ results.d1
490
+ )
491
+
492
+ # Check convergence
493
+ price_diff = price - target_price
494
+
495
+ if abs(price_diff) < tolerance:
496
+ return sigma
497
+
498
+ # Newton-Raphson update with fallback to bisection if vega too small
499
+ if abs(vega) < 1e-10:
500
+ # Fallback: try bisection step
501
+ if price < target_price:
502
+ sigma = sigma * 1.5 # increase vol
503
+ else:
504
+ sigma = sigma * 0.5 # decrease vol
505
+ else:
506
+ sigma = sigma - price_diff / vega
507
+
508
+ # Bounds check
509
+ sigma = max(0.001, min(5.0, sigma))
510
+
511
+ raise NumericalError(
512
+ f"Implied volatility did not converge after {max_iterations} iterations"
513
+ )
514
+
515
+ def _calculate_raw_vega(
516
+ self,
517
+ F: float,
518
+ K: float,
519
+ T: float,
520
+ sigma: float,
521
+ discount_factor: float,
522
+ d1: float
523
+ ) -> float:
524
+ """
525
+ Calculate raw vega (sensitivity to volatility) for Newton-Raphson.
526
+
527
+ Vega = D(T) * F * √T * n(d1)
528
+
529
+ where n(d1) is the standard normal PDF.
530
+
531
+ Args:
532
+ F: Forward price
533
+ K: Strike price
534
+ T: Time to expiry
535
+ sigma: Volatility
536
+ discount_factor: Discount factor
537
+ d1: d1 parameter
538
+
539
+ Returns:
540
+ Raw vega (∂V/∂σ)
541
+ """
542
+ sqrt_T = math.sqrt(T)
543
+ n_d1 = stats.norm.pdf(d1)
544
+
545
+ # Raw vega without scaling
546
+ return discount_factor * F * sqrt_T * n_d1
547
+
548
+ def _calculate_vega(
549
+ self,
550
+ F: float,
551
+ K: float,
552
+ T: float,
553
+ sigma: float,
554
+ discount_factor: float,
555
+ d1: float
556
+ ) -> float:
557
+ """
558
+ Calculate vega (sensitivity to volatility).
559
+
560
+ Vega = D(T) * F * √T * n(d1)
561
+
562
+ where n(d1) is the standard normal PDF.
563
+
564
+ Args:
565
+ F: Forward price
566
+ K: Strike price
567
+ T: Time to expiry
568
+ sigma: Volatility
569
+ discount_factor: Discount factor
570
+ d1: d1 parameter
571
+
572
+ Returns:
573
+ Vega (per 1% vol change)
574
+ """
575
+ sqrt_T = math.sqrt(T)
576
+ n_d1 = stats.norm.pdf(d1)
577
+
578
+ # Vega per 1% change (divide by 100)
579
+ return discount_factor * F * sqrt_T * n_d1 / 100
580
+
581
+ def __repr__(self):
582
+ return f"BlackBondOptionEngine(valuation_date={self.pricing_env.valuation_date.date()})"
583
+