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,58 @@
1
+ """
2
+ Interest Rate derivatives module.
3
+
4
+ This module provides:
5
+ - Interest Rate Swap (IRS) products
6
+ - Basis Swaps
7
+ - Forward Rate Agreements (FRA)
8
+ - Interest Rate Caps, Floors, and Collars
9
+ - Swaptions (options on swaps)
10
+ - Pricing engines for rate products
11
+ """
12
+
13
+ from .product import (
14
+ InterestRateSwap,
15
+ BasisSwap,
16
+ FixedLeg,
17
+ FloatingLeg,
18
+ ForwardRateAgreement,
19
+ CapFloor,
20
+ CapFloorType,
21
+ Caplet,
22
+ Collar,
23
+ Swaption,
24
+ SwaptionType,
25
+ SwaptionExerciseStyle,
26
+ )
27
+ from .engine import (
28
+ IRSDiscountEngine,
29
+ FRAEngine,
30
+ CapFloorEngine,
31
+ SwaptionEngine,
32
+ SwaptionModelType,
33
+ )
34
+
35
+ __all__ = [
36
+ # IRS
37
+ 'InterestRateSwap',
38
+ 'BasisSwap',
39
+ 'FixedLeg',
40
+ 'FloatingLeg',
41
+ # FRA
42
+ 'ForwardRateAgreement',
43
+ # Cap/Floor
44
+ 'CapFloor',
45
+ 'CapFloorType',
46
+ 'Caplet',
47
+ 'Collar',
48
+ # Swaption
49
+ 'Swaption',
50
+ 'SwaptionType',
51
+ 'SwaptionExerciseStyle',
52
+ # Engines
53
+ 'IRSDiscountEngine',
54
+ 'FRAEngine',
55
+ 'CapFloorEngine',
56
+ 'SwaptionEngine',
57
+ 'SwaptionModelType',
58
+ ]
@@ -0,0 +1,25 @@
1
+ """
2
+ Interest Rate derivative pricing engines.
3
+ """
4
+
5
+ from .irs_discount_engine import IRSDiscountEngine, IRSPricingResults
6
+ from .fra_engine import FRAEngine, FRAPricingResults
7
+ from .cap_floor_engine import CapFloorEngine, CapFloorPricingResults, CapletPricingResult
8
+ from .swaption_engine import SwaptionEngine, SwaptionPricingResults, SwaptionModelType
9
+
10
+ __all__ = [
11
+ # IRS
12
+ 'IRSDiscountEngine',
13
+ 'IRSPricingResults',
14
+ # FRA
15
+ 'FRAEngine',
16
+ 'FRAPricingResults',
17
+ # Cap/Floor
18
+ 'CapFloorEngine',
19
+ 'CapFloorPricingResults',
20
+ 'CapletPricingResult',
21
+ # Swaption
22
+ 'SwaptionEngine',
23
+ 'SwaptionPricingResults',
24
+ 'SwaptionModelType',
25
+ ]
@@ -0,0 +1,514 @@
1
+ """
2
+ Analytical pricing engine for Interest Rate Caps, Floors, and Collars.
3
+
4
+ Uses Black's model (Black-76) to price each caplet/floorlet individually,
5
+ then aggregates to obtain the full cap/floor price.
6
+
7
+ Black's caplet formula:
8
+ Caplet = df * dcf * N * [F * N(d1) - K * N(d2)]
9
+ Floorlet = df * dcf * N * [K * N(-d2) - F * N(-d1)]
10
+
11
+ where:
12
+ d1 = [ln(F/K) + 0.5 * sigma^2 * T_fix] / (sigma * sqrt(T_fix))
13
+ d2 = d1 - sigma * sqrt(T_fix)
14
+ F = forward rate for the caplet period
15
+ K = strike rate
16
+ sigma = implied volatility (flat or from vol surface)
17
+ T_fix = time to fixing date (option expiry for this caplet)
18
+ df = discount factor to payment date
19
+ dcf = day count fraction for the accrual period
20
+ N = notional
21
+ N(.) = standard normal CDF
22
+ """
23
+
24
+ from dataclasses import dataclass, field
25
+ from datetime import datetime
26
+ from typing import List, Optional
27
+
28
+ from scipy.stats import norm
29
+
30
+ from quantark.asset.rate.product.cap_floor import CapFloor, CapFloorType, Caplet, Collar
31
+ from quantark.priceenv import PricingEnvironment
32
+ from quantark.param.rrf import RateCurve, FlatRateCurve
33
+ from quantark.util.exceptions import ValidationError, MarketDataError
34
+ from quantark.util.numerical import safe_log, safe_sqrt, safe_divide, is_zero
35
+
36
+
37
+ @dataclass
38
+ class CapletPricingResult:
39
+ """
40
+ Pricing result for a single caplet/floorlet.
41
+
42
+ Attributes:
43
+ price: Present value of the caplet/floorlet
44
+ forward_rate: Forward rate for this period
45
+ vol: Implied volatility used
46
+ d1: Black's d1
47
+ d2: Black's d2
48
+ intrinsic: Intrinsic value (max(0, F-K)*dcf*N*df for cap)
49
+ time_value: Time value (price - intrinsic)
50
+ delta: Rate delta (sensitivity to forward rate)
51
+ vega: Sensitivity to vol (per 1% vol move)
52
+ accrual_start: Start of accrual period
53
+ accrual_end: End of accrual period
54
+ """
55
+
56
+ price: float
57
+ forward_rate: float
58
+ vol: float
59
+ d1: float
60
+ d2: float
61
+ intrinsic: float
62
+ time_value: float
63
+ delta: float
64
+ vega: float
65
+ accrual_start: datetime
66
+ accrual_end: datetime
67
+
68
+
69
+ @dataclass
70
+ class CapFloorPricingResults:
71
+ """
72
+ Results container for Cap/Floor pricing.
73
+
74
+ Attributes:
75
+ npv: Total present value of the cap/floor
76
+ caplet_prices: Individual caplet/floorlet prices
77
+ caplet_details: Detailed results per caplet
78
+ par_rate: Flat vol implied par strike (forward swap rate)
79
+ flat_vol: Flat vol that reprices the cap/floor (if provided)
80
+ dv01: Dollar value of 1 basis point
81
+ vega: Total vega (sensitivity to 1% vol shift)
82
+ """
83
+
84
+ npv: float
85
+ caplet_prices: List[float] = field(default_factory=list)
86
+ caplet_details: List[CapletPricingResult] = field(default_factory=list)
87
+ par_rate: Optional[float] = None
88
+ flat_vol: Optional[float] = None
89
+ dv01: Optional[float] = None
90
+ vega: Optional[float] = None
91
+
92
+
93
+ class CapFloorEngine:
94
+ """
95
+ Analytical pricing engine for Caps, Floors, and Collars.
96
+
97
+ Uses Black's model (Black-76) to price each caplet/floorlet. Supports:
98
+ - Flat volatility (same vol for all caplets)
99
+ - Per-caplet volatility from vol surface
100
+ - Single-curve or dual-curve pricing
101
+ """
102
+
103
+ def __init__(
104
+ self,
105
+ pricing_env: PricingEnvironment,
106
+ projection_curve: Optional[RateCurve] = None,
107
+ vol: Optional[float] = None,
108
+ ):
109
+ """
110
+ Initialize the Cap/Floor engine.
111
+
112
+ Args:
113
+ pricing_env: Pricing environment with discount curve.
114
+ If vol_surface is set, it provides per-caplet vols.
115
+ projection_curve: Separate curve for forward rate projection.
116
+ If None, uses the discount curve.
117
+ vol: Flat volatility override. If provided, uses this vol for
118
+ all caplets instead of the vol surface.
119
+ """
120
+ if pricing_env is None:
121
+ raise ValidationError("Pricing environment is required")
122
+ if pricing_env.rate_curve is None:
123
+ raise MarketDataError("Rate curve is required for cap/floor pricing")
124
+
125
+ self.pricing_env = pricing_env
126
+ self.projection_curve = projection_curve or pricing_env.rate_curve
127
+ self.flat_vol = vol
128
+
129
+ def price(
130
+ self,
131
+ product: CapFloor,
132
+ valuation_date: Optional[datetime] = None,
133
+ ) -> float:
134
+ """
135
+ Calculate the NPV of a Cap or Floor.
136
+
137
+ Args:
138
+ product: Cap or Floor to price
139
+ valuation_date: Valuation date (default: pricing env date)
140
+
141
+ Returns:
142
+ Net present value (positive for long position)
143
+ """
144
+ if valuation_date is None:
145
+ valuation_date = self.pricing_env.valuation_date
146
+
147
+ if product.is_expired(valuation_date):
148
+ return 0.0
149
+
150
+ caplets = product.get_future_caplets(valuation_date)
151
+ total = 0.0
152
+
153
+ for caplet in caplets:
154
+ total += self._price_caplet(caplet, product.cap_floor_type, valuation_date)
155
+
156
+ return total
157
+
158
+ def price_collar(
159
+ self,
160
+ collar: Collar,
161
+ valuation_date: Optional[datetime] = None,
162
+ ) -> float:
163
+ """
164
+ Calculate the NPV of a Collar (long cap + short floor).
165
+
166
+ Args:
167
+ collar: Collar to price
168
+ valuation_date: Valuation date
169
+
170
+ Returns:
171
+ NPV = cap_price - floor_price (borrower's hedge)
172
+ """
173
+ cap_pv = self.price(collar.cap, valuation_date)
174
+ floor_pv = self.price(collar.floor, valuation_date)
175
+ return cap_pv - floor_pv
176
+
177
+ def dv01(
178
+ self,
179
+ product: CapFloor,
180
+ valuation_date: Optional[datetime] = None,
181
+ bump_size: float = 0.0001,
182
+ ) -> float:
183
+ """
184
+ Calculate DV01 via central difference.
185
+
186
+ Args:
187
+ product: Cap or Floor
188
+ valuation_date: Valuation date
189
+ bump_size: Rate bump (default: 1bp)
190
+
191
+ Returns:
192
+ DV01 value
193
+ """
194
+ if valuation_date is None:
195
+ valuation_date = self.pricing_env.valuation_date
196
+
197
+ original_curve = self.pricing_env.rate_curve
198
+ original_projection = self.projection_curve
199
+ base_rate = original_curve.get_rate(1.0)
200
+
201
+ try:
202
+ up_curve = FlatRateCurve(rate=base_rate + bump_size)
203
+ self.pricing_env.rate_curve = up_curve
204
+ self.projection_curve = up_curve
205
+ npv_up = self.price(product, valuation_date)
206
+
207
+ down_curve = FlatRateCurve(rate=base_rate - bump_size)
208
+ self.pricing_env.rate_curve = down_curve
209
+ self.projection_curve = down_curve
210
+ npv_down = self.price(product, valuation_date)
211
+ finally:
212
+ self.pricing_env.rate_curve = original_curve
213
+ self.projection_curve = original_projection
214
+
215
+ return (npv_down - npv_up) / (2 * bump_size)
216
+
217
+ def vega(
218
+ self,
219
+ product: CapFloor,
220
+ valuation_date: Optional[datetime] = None,
221
+ vol_bump: float = 0.01,
222
+ ) -> float:
223
+ """
224
+ Calculate total vega (sensitivity to flat vol shift of 1%).
225
+
226
+ Args:
227
+ product: Cap or Floor
228
+ valuation_date: Valuation date
229
+ vol_bump: Vol bump size (default: 1% = 0.01)
230
+
231
+ Returns:
232
+ Vega (dollar change per 1% vol increase)
233
+ """
234
+ if valuation_date is None:
235
+ valuation_date = self.pricing_env.valuation_date
236
+
237
+ if self.flat_vol is None:
238
+ return 0.0
239
+
240
+ original_vol = self.flat_vol
241
+
242
+ try:
243
+ self.flat_vol = original_vol + vol_bump
244
+ npv_up = self.price(product, valuation_date)
245
+
246
+ self.flat_vol = original_vol - vol_bump
247
+ npv_down = self.price(product, valuation_date)
248
+ finally:
249
+ self.flat_vol = original_vol
250
+
251
+ return (npv_up - npv_down) / (2 * vol_bump) * 0.01
252
+
253
+ def full_analysis(
254
+ self,
255
+ product: CapFloor,
256
+ valuation_date: Optional[datetime] = None,
257
+ ) -> CapFloorPricingResults:
258
+ """
259
+ Perform full analysis of a Cap or Floor.
260
+
261
+ Args:
262
+ product: Cap or Floor
263
+ valuation_date: Valuation date
264
+
265
+ Returns:
266
+ CapFloorPricingResults with all metrics
267
+ """
268
+ if valuation_date is None:
269
+ valuation_date = self.pricing_env.valuation_date
270
+
271
+ caplets = product.get_future_caplets(valuation_date)
272
+ caplet_prices = []
273
+ caplet_details = []
274
+ total_npv = 0.0
275
+
276
+ for caplet in caplets:
277
+ detail = self._analyze_caplet(
278
+ caplet, product.cap_floor_type, valuation_date
279
+ )
280
+ caplet_details.append(detail)
281
+ caplet_prices.append(detail.price)
282
+ total_npv += detail.price
283
+
284
+ total_vega = sum(d.vega for d in caplet_details)
285
+ dv01_val = self.dv01(product, valuation_date)
286
+
287
+ return CapFloorPricingResults(
288
+ npv=total_npv,
289
+ caplet_prices=caplet_prices,
290
+ caplet_details=caplet_details,
291
+ flat_vol=self.flat_vol,
292
+ dv01=dv01_val,
293
+ vega=total_vega,
294
+ )
295
+
296
+ # =========================================================================
297
+ # Internal Pricing Methods
298
+ # =========================================================================
299
+
300
+ def _price_caplet(
301
+ self,
302
+ caplet: Caplet,
303
+ cap_floor_type: CapFloorType,
304
+ valuation_date: datetime,
305
+ ) -> float:
306
+ """
307
+ Price a single caplet/floorlet using Black's formula.
308
+
309
+ Args:
310
+ caplet: Caplet to price
311
+ cap_floor_type: CAP or FLOOR
312
+ valuation_date: Valuation date
313
+
314
+ Returns:
315
+ Present value of the caplet/floorlet
316
+ """
317
+ # If caplet has already fixed, compute intrinsic value
318
+ if not caplet.is_projected and caplet.index_fixing is not None:
319
+ return self._price_fixed_caplet(caplet, cap_floor_type, valuation_date)
320
+
321
+ # Forward rate
322
+ fwd = self._get_forward_rate(caplet, valuation_date)
323
+ K = caplet.strike
324
+ dcf = caplet.day_count_fraction
325
+ N = caplet.notional
326
+
327
+ # Time to fixing (option expiry for this caplet)
328
+ t_fix = (caplet.fixing_date - valuation_date).days / 365.0
329
+ if t_fix <= 0:
330
+ t_fix = 0.0
331
+
332
+ # Volatility
333
+ sigma = self._get_vol(caplet, fwd, t_fix)
334
+
335
+ # Discount factor to payment date
336
+ t_pay = (caplet.payment_date - valuation_date).days / 365.0
337
+ df = self.pricing_env.get_discount_factor(t_pay)
338
+
339
+ # Near-expiry or zero vol: use intrinsic
340
+ if is_zero(t_fix) or is_zero(sigma):
341
+ if cap_floor_type == CapFloorType.CAP:
342
+ payoff = max(0.0, fwd - K)
343
+ else:
344
+ payoff = max(0.0, K - fwd)
345
+ return df * dcf * N * payoff
346
+
347
+ # Black's formula
348
+ sqrt_t = safe_sqrt(t_fix)
349
+ sigma_sqrt_t = sigma * sqrt_t
350
+
351
+ if is_zero(sigma_sqrt_t):
352
+ if cap_floor_type == CapFloorType.CAP:
353
+ payoff = max(0.0, fwd - K)
354
+ else:
355
+ payoff = max(0.0, K - fwd)
356
+ return df * dcf * N * payoff
357
+
358
+ d1 = safe_divide(
359
+ safe_log(fwd / K) + 0.5 * sigma * sigma * t_fix,
360
+ sigma_sqrt_t,
361
+ fallback=0.0,
362
+ )
363
+ d2 = d1 - sigma_sqrt_t
364
+
365
+ if cap_floor_type == CapFloorType.CAP:
366
+ price = df * dcf * N * (fwd * norm.cdf(d1) - K * norm.cdf(d2))
367
+ else:
368
+ price = df * dcf * N * (K * norm.cdf(-d2) - fwd * norm.cdf(-d1))
369
+
370
+ return max(0.0, price)
371
+
372
+ def _price_fixed_caplet(
373
+ self,
374
+ caplet: Caplet,
375
+ cap_floor_type: CapFloorType,
376
+ valuation_date: datetime,
377
+ ) -> float:
378
+ """Price a caplet that has already fixed (intrinsic only)."""
379
+ L = caplet.index_fixing
380
+ K = caplet.strike
381
+
382
+ if cap_floor_type == CapFloorType.CAP:
383
+ payoff = max(0.0, L - K)
384
+ else:
385
+ payoff = max(0.0, K - L)
386
+
387
+ t_pay = (caplet.payment_date - valuation_date).days / 365.0
388
+ if t_pay <= 0:
389
+ return 0.0
390
+
391
+ df = self.pricing_env.get_discount_factor(t_pay)
392
+ return df * caplet.day_count_fraction * caplet.notional * payoff
393
+
394
+ def _analyze_caplet(
395
+ self,
396
+ caplet: Caplet,
397
+ cap_floor_type: CapFloorType,
398
+ valuation_date: datetime,
399
+ ) -> CapletPricingResult:
400
+ """Full analysis of a single caplet including Greeks."""
401
+ fwd = self._get_forward_rate(caplet, valuation_date)
402
+ K = caplet.strike
403
+ dcf = caplet.day_count_fraction
404
+ N = caplet.notional
405
+
406
+ t_fix = max(0.0, (caplet.fixing_date - valuation_date).days / 365.0)
407
+ sigma = self._get_vol(caplet, fwd, t_fix)
408
+
409
+ t_pay = (caplet.payment_date - valuation_date).days / 365.0
410
+ df = self.pricing_env.get_discount_factor(t_pay)
411
+
412
+ # Calculate d1, d2
413
+ sqrt_t = safe_sqrt(t_fix)
414
+ sigma_sqrt_t = sigma * sqrt_t if not is_zero(t_fix) else 0.0
415
+
416
+ if is_zero(sigma_sqrt_t):
417
+ d1 = 0.0
418
+ d2 = 0.0
419
+ else:
420
+ d1 = safe_divide(
421
+ safe_log(fwd / K) + 0.5 * sigma * sigma * t_fix,
422
+ sigma_sqrt_t,
423
+ fallback=0.0,
424
+ )
425
+ d2 = d1 - sigma_sqrt_t
426
+
427
+ # Price
428
+ price = self._price_caplet(caplet, cap_floor_type, valuation_date)
429
+
430
+ # Intrinsic
431
+ if cap_floor_type == CapFloorType.CAP:
432
+ intrinsic = df * dcf * N * max(0.0, fwd - K)
433
+ else:
434
+ intrinsic = df * dcf * N * max(0.0, K - fwd)
435
+
436
+ # Delta: dPrice/dF
437
+ if cap_floor_type == CapFloorType.CAP:
438
+ delta = df * dcf * N * norm.cdf(d1)
439
+ else:
440
+ delta = -df * dcf * N * norm.cdf(-d1)
441
+
442
+ # Vega: dPrice/dSigma (per 1% move)
443
+ vega_val = df * dcf * N * fwd * norm.pdf(d1) * sqrt_t * 0.01
444
+
445
+ return CapletPricingResult(
446
+ price=price,
447
+ forward_rate=fwd,
448
+ vol=sigma,
449
+ d1=d1,
450
+ d2=d2,
451
+ intrinsic=intrinsic,
452
+ time_value=price - intrinsic,
453
+ delta=delta,
454
+ vega=vega_val,
455
+ accrual_start=caplet.accrual_start,
456
+ accrual_end=caplet.accrual_end,
457
+ )
458
+
459
+ def _get_forward_rate(
460
+ self, caplet: Caplet, valuation_date: datetime
461
+ ) -> float:
462
+ """Get forward rate for a caplet's accrual period."""
463
+ # If already fixed, use the fixing
464
+ if not caplet.is_projected and caplet.index_fixing is not None:
465
+ return caplet.index_fixing
466
+
467
+ t1 = (caplet.accrual_start - valuation_date).days / 365.0
468
+ t2 = (caplet.accrual_end - valuation_date).days / 365.0
469
+
470
+ if t1 < 0:
471
+ t1 = 0.0
472
+
473
+ return self.projection_curve.get_forward_rate(t1, t2)
474
+
475
+ def _get_vol(
476
+ self, caplet: Caplet, forward_rate: float, time_to_fixing: float
477
+ ) -> float:
478
+ """
479
+ Get implied volatility for a caplet.
480
+
481
+ Priority:
482
+ 1. Flat vol override (self.flat_vol)
483
+ 2. Vol surface from pricing env (if available)
484
+ 3. Raise error if neither available
485
+
486
+ Args:
487
+ caplet: Caplet
488
+ forward_rate: Forward rate (used as strike proxy for vol surface)
489
+ time_to_fixing: Time to caplet expiry
490
+
491
+ Returns:
492
+ Implied volatility
493
+ """
494
+ if self.flat_vol is not None:
495
+ return self.flat_vol
496
+
497
+ if self.pricing_env.vol_surface is not None:
498
+ # Use caplet strike as lookup key
499
+ # For rate vol surfaces, strike = rate level
500
+ return self.pricing_env.vol_surface.get_vol(
501
+ caplet.strike, time_to_fixing, forward_rate
502
+ )
503
+
504
+ raise MarketDataError(
505
+ "No volatility provided: set flat_vol or provide vol_surface "
506
+ "in PricingEnvironment"
507
+ )
508
+
509
+ def __repr__(self):
510
+ vol_str = f", flat_vol={self.flat_vol:.2%}" if self.flat_vol else ""
511
+ return (
512
+ f"CapFloorEngine(valuation_date="
513
+ f"{self.pricing_env.valuation_date.date()}{vol_str})"
514
+ )