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.
- quantark/__init__.py +3 -0
- quantark/_compat.py +150 -0
- quantark/asset/__init__.py +8 -0
- quantark/asset/bond/__init__.py +2 -0
- quantark/asset/bond/engine/__init__.py +44 -0
- quantark/asset/bond/engine/analytical/__init__.py +12 -0
- quantark/asset/bond/engine/analytical/black_engine.py +583 -0
- quantark/asset/bond/engine/analytical/bond_forward_engine.py +390 -0
- quantark/asset/bond/engine/analytical/bond_futures_engine.py +569 -0
- quantark/asset/bond/engine/convertible/__init__.py +12 -0
- quantark/asset/bond/engine/convertible/convertible_bond_engine.py +800 -0
- quantark/asset/bond/engine/discount/__init__.py +10 -0
- quantark/asset/bond/engine/discount/bond_discount_engine.py +517 -0
- quantark/asset/bond/engine/discount/frn_engine.py +913 -0
- quantark/asset/bond/engine/pde/__init__.py +14 -0
- quantark/asset/bond/engine/pde/convertible/__init__.py +21 -0
- quantark/asset/bond/engine/pde/convertible/jump_diffusion_engine.py +603 -0
- quantark/asset/bond/engine/pde/convertible/pde_params.py +59 -0
- quantark/asset/bond/engine/pde/convertible/tf_engine.py +546 -0
- quantark/asset/bond/engine/tree/__init__.py +14 -0
- quantark/asset/bond/engine/tree/convertible/__init__.py +21 -0
- quantark/asset/bond/engine/tree/convertible/binomial_engine.py +488 -0
- quantark/asset/bond/engine/tree/convertible/tree_params.py +72 -0
- quantark/asset/bond/engine/tree/convertible/trinomial_engine.py +1341 -0
- quantark/asset/bond/product/__init__.py +37 -0
- quantark/asset/bond/product/base_bond_product.py +114 -0
- quantark/asset/bond/product/convertible/__init__.py +16 -0
- quantark/asset/bond/product/convertible/convertible_bond.py +595 -0
- quantark/asset/bond/product/couponbond/__init__.py +12 -0
- quantark/asset/bond/product/couponbond/fixed_bond.py +285 -0
- quantark/asset/bond/product/couponbond/frn.py +538 -0
- quantark/asset/bond/product/forward/__init__.py +9 -0
- quantark/asset/bond/product/forward/base_bond_forward.py +92 -0
- quantark/asset/bond/product/forward/bond_forward.py +335 -0
- quantark/asset/bond/product/futures/__init__.py +8 -0
- quantark/asset/bond/product/futures/bond_futures.py +532 -0
- quantark/asset/bond/product/option/__init__.py +9 -0
- quantark/asset/bond/product/option/euro_short_term_bond_option.py +231 -0
- quantark/asset/bond/riskmeasures/__init__.py +13 -0
- quantark/asset/bond/riskmeasures/bond_greeks_calculator.py +484 -0
- quantark/asset/bond/schedule/__init__.py +21 -0
- quantark/asset/bond/schedule/cashflow.py +595 -0
- quantark/asset/equity/__init__.py +11 -0
- quantark/asset/equity/analysis/__init__.py +4 -0
- quantark/asset/equity/analysis/autocallable_path_analyzer.py +257 -0
- quantark/asset/equity/engine/__init__.py +84 -0
- quantark/asset/equity/engine/analytical/__init__.py +37 -0
- quantark/asset/equity/engine/analytical/american_option_engine.py +682 -0
- quantark/asset/equity/engine/analytical/asian_option_analytical_engine.py +1102 -0
- quantark/asset/equity/engine/analytical/barrier_analytical_engine.py +455 -0
- quantark/asset/equity/engine/analytical/black_scholes_engine.py +322 -0
- quantark/asset/equity/engine/analytical/deltaone_engine.py +340 -0
- quantark/asset/equity/engine/analytical/digital_option_engine.py +168 -0
- quantark/asset/equity/engine/analytical/double_barrier_option_engine.py +481 -0
- quantark/asset/equity/engine/analytical/double_sharkfin_option_analytical_engine.py +508 -0
- quantark/asset/equity/engine/analytical/one_touch_analytical_engine.py +302 -0
- quantark/asset/equity/engine/analytical/range_accrual_analytical_engine.py +396 -0
- quantark/asset/equity/engine/analytical/single_sharkfin_option_analytical_engine.py +229 -0
- quantark/asset/equity/engine/base_engine.py +137 -0
- quantark/asset/equity/engine/event_stats.py +85 -0
- quantark/asset/equity/engine/mc/__init__.py +31 -0
- quantark/asset/equity/engine/mc/american_option_mc_engine.py +485 -0
- quantark/asset/equity/engine/mc/asian_option_mc_engine.py +678 -0
- quantark/asset/equity/engine/mc/barrier_option_mc_engine.py +726 -0
- quantark/asset/equity/engine/mc/digital_option_mc_engine.py +419 -0
- quantark/asset/equity/engine/mc/double_sharkfin_option_mc_engine.py +676 -0
- quantark/asset/equity/engine/mc/euro_mc_engine.py +423 -0
- quantark/asset/equity/engine/mc/phoenix_mc_engine.py +1206 -0
- quantark/asset/equity/engine/mc/range_accrual_mc_engine.py +738 -0
- quantark/asset/equity/engine/mc/single_sharkfin_option_mc_engine.py +549 -0
- quantark/asset/equity/engine/mc/snowball_mc_engine.py +2250 -0
- quantark/asset/equity/engine/pde/__init__.py +36 -0
- quantark/asset/equity/engine/pde/american_pde_solver.py +211 -0
- quantark/asset/equity/engine/pde/barrier_pde_solver.py +692 -0
- quantark/asset/equity/engine/pde/base_pde_solver.py +994 -0
- quantark/asset/equity/engine/pde/double_barrier_pde_solver.py +510 -0
- quantark/asset/equity/engine/pde/double_one_touch_pde_solver.py +435 -0
- quantark/asset/equity/engine/pde/european_pde_solver.py +170 -0
- quantark/asset/equity/engine/pde/ko_reset_snowball_pde_solver.py +477 -0
- quantark/asset/equity/engine/pde/one_touch_pde_solver.py +439 -0
- quantark/asset/equity/engine/pde/phoenix_pde_solver.py +613 -0
- quantark/asset/equity/engine/pde/snowball_pde_solver.py +1810 -0
- quantark/asset/equity/engine/pde/spatial_grid.py +750 -0
- quantark/asset/equity/engine/pde/time_grid.py +308 -0
- quantark/asset/equity/engine/pde_engine.py +238 -0
- quantark/asset/equity/engine/quad/__init__.py +23 -0
- quantark/asset/equity/engine/quad/discrete_quad_engine.py +106 -0
- quantark/asset/equity/engine/quad/european_quad_engine.py +325 -0
- quantark/asset/equity/engine/quad/ko_reset_snowball_quad_engine.py +362 -0
- quantark/asset/equity/engine/quad/phoenix_quad_engine.py +614 -0
- quantark/asset/equity/engine/quad/quad_adapters.py +1260 -0
- quantark/asset/equity/engine/quad/quad_core.py +513 -0
- quantark/asset/equity/engine/quad/quad_math.py +219 -0
- quantark/asset/equity/engine/quad/snowball_quad_engine.py +1137 -0
- quantark/asset/equity/engine/validation/script/benchmark_check_american_analytical.py +117 -0
- quantark/asset/equity/engine/validation/script/benchmark_check_american_pde.py +114 -0
- quantark/asset/equity/engine/validation/script/benchmark_check_asian_analytical.py +440 -0
- quantark/asset/equity/engine/validation/script/benchmark_check_barrier_analytical.py +269 -0
- quantark/asset/equity/engine/validation/script/benchmark_check_barrier_pde_solver.py +636 -0
- quantark/asset/equity/engine/validation/script/benchmark_check_digital_option.py +256 -0
- quantark/asset/equity/engine/validation/script/benchmark_check_snowball_pde_solver.py +807 -0
- quantark/asset/equity/engine/validation/script/boundary_check_american_analytical.py +290 -0
- quantark/asset/equity/engine/validation/script/boundary_check_american_pde.py +242 -0
- quantark/asset/equity/engine/validation/script/boundary_check_asian_analytical.py +612 -0
- quantark/asset/equity/engine/validation/script/boundary_check_barrier_analytical.py +434 -0
- quantark/asset/equity/engine/validation/script/boundary_check_barrier_pde_solver.py +748 -0
- quantark/asset/equity/engine/validation/script/boundary_check_digital_option.py +575 -0
- quantark/asset/equity/engine/validation/script/boundary_check_snowball_pde_solver.py +1101 -0
- quantark/asset/equity/engine/validation/script/greeks_check_digital_option.py +349 -0
- quantark/asset/equity/engine/validation/script/mc_comparison_barrier_pde.py +270 -0
- quantark/asset/equity/engine/validation/script/quick_mc_compare.py +51 -0
- quantark/asset/equity/engine/validation/script/validation_stepdown_improved.py +97 -0
- quantark/asset/equity/param/__init__.py +24 -0
- quantark/asset/equity/param/engine_param_profiles.py +325 -0
- quantark/asset/equity/param/engine_params.py +728 -0
- quantark/asset/equity/process/__init__.py +7 -0
- quantark/asset/equity/process/bsm/__init__.py +7 -0
- quantark/asset/equity/process/bsm/bsm_process.py +108 -0
- quantark/asset/equity/process/bsm/qmc_brownian_bridge.py +401 -0
- quantark/asset/equity/process/bsm/qmc_path_generator.py +694 -0
- quantark/asset/equity/process/bsm/qmc_rqmc_driver.py +163 -0
- quantark/asset/equity/process/bsm/qmc_sobol.py +195 -0
- quantark/asset/equity/process/bsm/qmc_variance_reduction.py +292 -0
- quantark/asset/equity/product/__init__.py +8 -0
- quantark/asset/equity/product/base_equity_product.py +72 -0
- quantark/asset/equity/product/deltaone/__init__.py +22 -0
- quantark/asset/equity/product/deltaone/base_deltaone_product.py +147 -0
- quantark/asset/equity/product/deltaone/futures.py +485 -0
- quantark/asset/equity/product/deltaone/spot_instrument.py +118 -0
- quantark/asset/equity/product/option/__init__.py +104 -0
- quantark/asset/equity/product/option/american_option.py +114 -0
- quantark/asset/equity/product/option/asian_option.py +531 -0
- quantark/asset/equity/product/option/barrier_option.py +289 -0
- quantark/asset/equity/product/option/base_equity_option.py +659 -0
- quantark/asset/equity/product/option/digital_option.py +102 -0
- quantark/asset/equity/product/option/double_barrier_option.py +286 -0
- quantark/asset/equity/product/option/double_one_touch_option.py +310 -0
- quantark/asset/equity/product/option/double_sharkfin_option.py +466 -0
- quantark/asset/equity/product/option/european_vanilla_option.py +103 -0
- quantark/asset/equity/product/option/ko_reset_snowball_option.py +563 -0
- quantark/asset/equity/product/option/observation_schedule.py +530 -0
- quantark/asset/equity/product/option/one_touch_option.py +287 -0
- quantark/asset/equity/product/option/phoenix_config.py +116 -0
- quantark/asset/equity/product/option/phoenix_helpers.py +576 -0
- quantark/asset/equity/product/option/phoenix_option.py +1167 -0
- quantark/asset/equity/product/option/range_accrual_config.py +288 -0
- quantark/asset/equity/product/option/range_accrual_helpers.py +608 -0
- quantark/asset/equity/product/option/range_accrual_option.py +526 -0
- quantark/asset/equity/product/option/single_sharkfin_option.py +420 -0
- quantark/asset/equity/product/option/snowball_config.py +261 -0
- quantark/asset/equity/product/option/snowball_helpers.py +977 -0
- quantark/asset/equity/product/option/snowball_option.py +1242 -0
- quantark/asset/equity/report/__init__.py +15 -0
- quantark/asset/equity/report/autocallable_risk_report.py +2118 -0
- quantark/asset/equity/report/plotting.py +87 -0
- quantark/asset/equity/report/snowball_risk_comparison_report.py +2230 -0
- quantark/asset/equity/report/surfaces.py +123 -0
- quantark/asset/equity/report/term_structure.py +126 -0
- quantark/asset/equity/riskmeasures/__init__.py +7 -0
- quantark/asset/equity/riskmeasures/greeks_calculator.py +1204 -0
- quantark/asset/rate/__init__.py +58 -0
- quantark/asset/rate/engine/__init__.py +25 -0
- quantark/asset/rate/engine/cap_floor_engine.py +514 -0
- quantark/asset/rate/engine/fra_engine.py +286 -0
- quantark/asset/rate/engine/irs_discount_engine.py +891 -0
- quantark/asset/rate/engine/swaption_engine.py +587 -0
- quantark/asset/rate/product/__init__.py +67 -0
- quantark/asset/rate/product/cap_floor.py +550 -0
- quantark/asset/rate/product/fra.py +219 -0
- quantark/asset/rate/product/irs.py +1223 -0
- quantark/asset/rate/product/swaption.py +372 -0
- quantark/backtest/__init__.py +153 -0
- quantark/backtest/base.py +263 -0
- quantark/backtest/dashboard.py +874 -0
- quantark/backtest/equity/__init__.py +35 -0
- quantark/backtest/equity/config.py +118 -0
- quantark/backtest/equity/engine.py +408 -0
- quantark/backtest/equity/hedge_executor.py +374 -0
- quantark/backtest/equity/metrics.py +396 -0
- quantark/backtest/equity/results.py +232 -0
- quantark/backtest/equity/state.py +252 -0
- quantark/backtest/examples/__init__.py +4 -0
- quantark/backtest/examples/advanced_backtest.py +345 -0
- quantark/backtest/examples/basic_delta_hedge.py +246 -0
- quantark/backtest/examples/fi_dv01_hedge.py +267 -0
- quantark/backtest/fi/__init__.py +30 -0
- quantark/backtest/fi/config.py +114 -0
- quantark/backtest/fi/engine.py +378 -0
- quantark/backtest/fi/hedge_executor.py +254 -0
- quantark/backtest/fi/metrics.py +308 -0
- quantark/backtest/fi/results.py +193 -0
- quantark/backtest/fi/state.py +212 -0
- quantark/backtest/logger.py +393 -0
- quantark/backtest/otc/__init__.py +74 -0
- quantark/backtest/otc/_replay.py +637 -0
- quantark/backtest/otc/book_engine.py +587 -0
- quantark/backtest/otc/config.py +175 -0
- quantark/backtest/otc/dashboard.py +1006 -0
- quantark/backtest/otc/engine.py +420 -0
- quantark/backtest/otc/engine_factory.py +138 -0
- quantark/backtest/otc/market.py +216 -0
- quantark/backtest/otc/results.py +107 -0
- quantark/backtest/otc/state.py +166 -0
- quantark/backtest/report_generator.py +608 -0
- quantark/backtest/strategy/__init__.py +28 -0
- quantark/backtest/strategy/base_strategy.py +235 -0
- quantark/backtest/strategy/convexity_neutral_strategy.py +247 -0
- quantark/backtest/strategy/delta_neutral_strategy.py +283 -0
- quantark/backtest/strategy/dv01_neutral_strategy.py +283 -0
- quantark/backtest/transaction_costs.py +485 -0
- quantark/backtest/visualizer.py +1019 -0
- quantark/cashleg/__init__.py +31 -0
- quantark/cashleg/accrual_leg.py +120 -0
- quantark/cashleg/base.py +48 -0
- quantark/cashleg/base_amount.py +60 -0
- quantark/cashleg/deterministic_leg.py +39 -0
- quantark/cashleg/event_distribution.py +262 -0
- quantark/cashleg/fixed_payoff_leg.py +92 -0
- quantark/cashleg/leg_schedule.py +95 -0
- quantark/cashleg/leg_valuator.py +40 -0
- quantark/dynamicscenario/__init__.py +97 -0
- quantark/dynamicscenario/base.py +297 -0
- quantark/dynamicscenario/config.py +122 -0
- quantark/dynamicscenario/engine.py +703 -0
- quantark/dynamicscenario/equity/__init__.py +14 -0
- quantark/dynamicscenario/fi/__init__.py +24 -0
- quantark/dynamicscenario/fi/config.py +149 -0
- quantark/dynamicscenario/fi/engine.py +500 -0
- quantark/dynamicscenario/fi/results.py +503 -0
- quantark/dynamicscenario/path/__init__.py +17 -0
- quantark/dynamicscenario/path/day_path.py +397 -0
- quantark/dynamicscenario/path/fi_path_library.py +488 -0
- quantark/dynamicscenario/path/path_builder.py +726 -0
- quantark/dynamicscenario/path/path_library.py +620 -0
- quantark/dynamicscenario/report/__init__.py +12 -0
- quantark/dynamicscenario/report/dynamic_report.py +1175 -0
- quantark/dynamicscenario/report/visualizer.py +1586 -0
- quantark/dynamicscenario/results/__init__.py +19 -0
- quantark/dynamicscenario/results/dynamic_results.py +579 -0
- quantark/dynamicscenario/results/result_exporter.py +438 -0
- quantark/param/__init__.py +75 -0
- quantark/param/basis/__init__.py +19 -0
- quantark/param/basis/basis_yield.py +301 -0
- quantark/param/div/__init__.py +16 -0
- quantark/param/div/dividend_yield.py +123 -0
- quantark/param/index/__init__.py +52 -0
- quantark/param/index/rate_index.py +568 -0
- quantark/param/quote/__init__.py +7 -0
- quantark/param/quote/spot_quote.py +35 -0
- quantark/param/rrf/__init__.py +22 -0
- quantark/param/rrf/rate_curve.py +436 -0
- quantark/param/vol/__init__.py +6 -0
- quantark/param/vol/vol_surface.py +118 -0
- quantark/portfolio/__init__.py +61 -0
- quantark/portfolio/base.py +203 -0
- quantark/portfolio/equity/__init__.py +17 -0
- quantark/portfolio/equity/portfolio.py +391 -0
- quantark/portfolio/equity/position.py +368 -0
- quantark/portfolio/fi/__init__.py +14 -0
- quantark/portfolio/fi/portfolio.py +424 -0
- quantark/portfolio/fi/position.py +272 -0
- quantark/portfolio/portfolio_snapshot.py +221 -0
- quantark/portfolio/portfolio_storage.py +414 -0
- quantark/priceenv/__init__.py +7 -0
- quantark/priceenv/pricing_environment.py +196 -0
- quantark/rfq/__init__.py +32 -0
- quantark/rfq/builders.py +102 -0
- quantark/rfq/models.py +214 -0
- quantark/rfq/registry.py +611 -0
- quantark/rfq/service.py +237 -0
- quantark/simm/__init__.py +155 -0
- quantark/simm/calibration/__init__.py +206 -0
- quantark/simm/calibration/accessors.py +439 -0
- quantark/simm/calibration/commodity.py +156 -0
- quantark/simm/calibration/credit_non_qualifying.py +79 -0
- quantark/simm/calibration/credit_qualifying.py +130 -0
- quantark/simm/calibration/cross_risk.py +39 -0
- quantark/simm/calibration/equity.py +125 -0
- quantark/simm/calibration/fx.py +92 -0
- quantark/simm/calibration/ir.py +152 -0
- quantark/simm/calibration/version.py +33 -0
- quantark/simm/config.py +186 -0
- quantark/simm/crif/__init__.py +35 -0
- quantark/simm/crif/models.py +230 -0
- quantark/simm/crif/parser.py +585 -0
- quantark/simm/engines/__init__.py +62 -0
- quantark/simm/engines/aggregation/__init__.py +67 -0
- quantark/simm/engines/aggregation/addon.py +141 -0
- quantark/simm/engines/aggregation/bucket_aggregator.py +298 -0
- quantark/simm/engines/aggregation/concentration.py +349 -0
- quantark/simm/engines/aggregation/product_class_aggregator.py +183 -0
- quantark/simm/engines/aggregation/risk_class_aggregator.py +403 -0
- quantark/simm/engines/aggregation/simm_calculator.py +430 -0
- quantark/simm/engines/aggregation/weighted_sensitivity.py +272 -0
- quantark/simm/engines/base.py +231 -0
- quantark/simm/engines/classification/__init__.py +10 -0
- quantark/simm/engines/classification/bucket_mapper.py +347 -0
- quantark/simm/engines/factory.py +137 -0
- quantark/simm/engines/portfolio_adapter.py +336 -0
- quantark/simm/engines/result.py +176 -0
- quantark/simm/engines/risk_class/__init__.py +18 -0
- quantark/simm/engines/risk_class/equity_engine.py +263 -0
- quantark/simm/engines/risk_class/ir_engine.py +264 -0
- quantark/simm/report/__init__.py +17 -0
- quantark/simm/report/crif_export.py +284 -0
- quantark/simm/report/excel_generator.py +401 -0
- quantark/simm/report/html_generator.py +840 -0
- quantark/simm/results/__init__.py +38 -0
- quantark/simm/results/attribution.py +313 -0
- quantark/simm/results/simm_result.py +339 -0
- quantark/simm/results/whatif.py +268 -0
- quantark/simm/sensitivity.py +533 -0
- quantark/simm/taxonomy.py +416 -0
- quantark/stresstest/__init__.py +67 -0
- quantark/stresstest/base.py +116 -0
- quantark/stresstest/config.py +5 -0
- quantark/stresstest/engine.py +5 -0
- quantark/stresstest/equity/__init__.py +17 -0
- quantark/stresstest/equity/config.py +69 -0
- quantark/stresstest/equity/engine.py +272 -0
- quantark/stresstest/equity/report/__init__.py +7 -0
- quantark/stresstest/equity/report/report_generator.py +423 -0
- quantark/stresstest/equity/report/visualizer.py +328 -0
- quantark/stresstest/equity/results.py +145 -0
- quantark/stresstest/fi/__init__.py +15 -0
- quantark/stresstest/fi/config.py +59 -0
- quantark/stresstest/fi/engine.py +213 -0
- quantark/stresstest/fi/metrics.py +60 -0
- quantark/stresstest/fi/results.py +64 -0
- quantark/stresstest/report/__init__.py +12 -0
- quantark/stresstest/report/report_generator.py +5 -0
- quantark/stresstest/report/visualizer.py +5 -0
- quantark/stresstest/results/__init__.py +16 -0
- quantark/stresstest/results/result_aggregator.py +325 -0
- quantark/stresstest/results/result_exporter.py +286 -0
- quantark/stresstest/results/stress_results.py +5 -0
- quantark/stresstest/scenario/__init__.py +13 -0
- quantark/stresstest/scenario/scenario.py +242 -0
- quantark/stresstest/scenario/scenario_builder.py +376 -0
- quantark/stresstest/scenario/scenario_library.py +435 -0
- quantark/stresstest/scenario/scenario_storage.py +224 -0
- quantark/stresstest/stress/__init__.py +13 -0
- quantark/stresstest/stress/stress_applicator.py +590 -0
- quantark/stresstest/stress/stress_types.py +142 -0
- quantark/util/__init__.py +23 -0
- quantark/util/barrier_shift.py +44 -0
- quantark/util/calendar/__init__.py +27 -0
- quantark/util/calendar/business_calendar.py +584 -0
- quantark/util/calendar/day_counter.py +517 -0
- quantark/util/calendar/holidayfile/china.csv +1920 -0
- quantark/util/calendar/holidayfile/china_sse.csv +1462 -0
- quantark/util/enum/__init__.py +81 -0
- quantark/util/enum/bond_enums.py +112 -0
- quantark/util/enum/deltaone_enums.py +16 -0
- quantark/util/enum/engine_enums.py +137 -0
- quantark/util/enum/greeks_enums.py +29 -0
- quantark/util/enum/option_enums.py +221 -0
- quantark/util/exceptions.py +66 -0
- quantark/util/marketdata/__init__.py +39 -0
- quantark/util/marketdata/adapter/base_adapter.py +203 -0
- quantark/util/marketdata/adapter/mock_adapter.py +265 -0
- quantark/util/marketdata/converter.py +289 -0
- quantark/util/marketdata/example_usage.py +314 -0
- quantark/util/marketdata/generator/__init__.py +7 -0
- quantark/util/marketdata/generator/mock_generator.py +466 -0
- quantark/util/marketdata/models.py +358 -0
- quantark/util/marketdata/storage/__init__.py +7 -0
- quantark/util/marketdata/storage/parquet_storage.py +340 -0
- quantark/util/numerical/__init__.py +98 -0
- quantark/util/numerical/comparison.py +219 -0
- quantark/util/numerical/constants.py +98 -0
- quantark/util/numerical/formatting.py +380 -0
- quantark/util/numerical/pnl.py +17 -0
- quantark/util/numerical/safe_math.py +238 -0
- quantark/util/numerical/validation.py +315 -0
- quantark/var/__init__.py +39 -0
- quantark/var/attribution.py +398 -0
- quantark/var/backtest/__init__.py +7 -0
- quantark/var/backtest/var_backtester.py +309 -0
- quantark/var/base.py +63 -0
- quantark/var/config.py +219 -0
- quantark/var/engines/__init__.py +13 -0
- quantark/var/engines/historical.py +925 -0
- quantark/var/engines/monte_carlo.py +870 -0
- quantark/var/engines/parametric.py +1199 -0
- quantark/var/results/__init__.py +16 -0
- quantark/var/results/incremental_var_result.py +131 -0
- quantark/var/results/var_report.py +346 -0
- quantark/var/results/var_result.py +134 -0
- quantark/var/risk_factors/__init__.py +22 -0
- quantark/var/risk_factors/base.py +41 -0
- quantark/var/risk_factors/equity_factors.py +158 -0
- quantark/var/risk_factors/fi_factors.py +99 -0
- quantark-0.1.0.dist-info/METADATA +351 -0
- quantark-0.1.0.dist-info/RECORD +399 -0
- quantark-0.1.0.dist-info/WHEEL +4 -0
- quantark-0.1.0.dist-info/licenses/LICENSE +202 -0
- quantark-0.1.0.dist-info/licenses/NOTICE +2 -0
- quantark_compat.pth +1 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Barrier option implementation.
|
|
3
|
+
|
|
4
|
+
Barrier options have a payoff that depends on whether the underlying
|
|
5
|
+
price crosses a barrier level during the option's life.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import Optional, List
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
from .base_equity_option import BaseEquityOption
|
|
12
|
+
from .observation_schedule import ObservationRecord, ObservationSchedule
|
|
13
|
+
from quantark.util.enum import (
|
|
14
|
+
OptionType,
|
|
15
|
+
ExerciseType,
|
|
16
|
+
BarrierType,
|
|
17
|
+
ObservationType,
|
|
18
|
+
ObservationAggregation,
|
|
19
|
+
)
|
|
20
|
+
from quantark.util.exceptions import ValidationError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class BarrierOption(BaseEquityOption):
|
|
25
|
+
"""
|
|
26
|
+
Single barrier option (knock-in or knock-out).
|
|
27
|
+
|
|
28
|
+
Barrier options are path-dependent options whose existence or payoff
|
|
29
|
+
depends on whether the underlying asset price reaches a specified barrier.
|
|
30
|
+
|
|
31
|
+
Types:
|
|
32
|
+
- UP_IN: Activates (knocks in) when price goes UP above barrier
|
|
33
|
+
- UP_OUT: Deactivates (knocks out) when price goes UP above barrier
|
|
34
|
+
- DOWN_IN: Activates when price goes DOWN below barrier
|
|
35
|
+
- DOWN_OUT: Deactivates when price goes DOWN below barrier
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
strike: Strike price
|
|
39
|
+
maturity: Time to maturity in years
|
|
40
|
+
option_type: CALL or PUT
|
|
41
|
+
barrier: Barrier price level
|
|
42
|
+
barrier_type: UP_IN, UP_OUT, DOWN_IN, or DOWN_OUT
|
|
43
|
+
rebate: Amount paid if knocked out (or not knocked in at expiry)
|
|
44
|
+
observation_type: CONTINUOUS or DISCRETE monitoring
|
|
45
|
+
observation_dates: For discrete monitoring, list of observation times (year fractions)
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
barrier: float = 0.0
|
|
49
|
+
barrier_type: BarrierType = BarrierType.DOWN_OUT
|
|
50
|
+
rebate: float = 0.0
|
|
51
|
+
participation_rate: float = 1.0
|
|
52
|
+
pay_at_hit: bool = False
|
|
53
|
+
observation_type: ObservationType = ObservationType.CONTINUOUS
|
|
54
|
+
observation_dates: Optional[List[float]] = None
|
|
55
|
+
observation_schedule: Optional[ObservationSchedule] = None
|
|
56
|
+
|
|
57
|
+
def __init__(
|
|
58
|
+
self,
|
|
59
|
+
strike: float,
|
|
60
|
+
option_type: OptionType,
|
|
61
|
+
barrier: float,
|
|
62
|
+
barrier_type: BarrierType,
|
|
63
|
+
maturity: Optional[float] = None,
|
|
64
|
+
exercise_date: Optional[datetime] = None,
|
|
65
|
+
settlement_date: Optional[datetime] = None,
|
|
66
|
+
rebate: float = 0.0,
|
|
67
|
+
participation_rate: float = 1.0,
|
|
68
|
+
pay_at_hit: bool = False,
|
|
69
|
+
observation_type: ObservationType = ObservationType.CONTINUOUS,
|
|
70
|
+
observation_dates: Optional[List[float]] = None,
|
|
71
|
+
observation_schedule: Optional[ObservationSchedule] = None,
|
|
72
|
+
contract_multiplier: float = 1.0,
|
|
73
|
+
):
|
|
74
|
+
"""
|
|
75
|
+
Initialize barrier option.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
strike: Strike price
|
|
79
|
+
option_type: CALL or PUT
|
|
80
|
+
barrier: Barrier price level
|
|
81
|
+
barrier_type: UP_IN, UP_OUT, DOWN_IN, or DOWN_OUT
|
|
82
|
+
maturity: Time to maturity in years (optional if exercise_date provided)
|
|
83
|
+
exercise_date: Expiration date (optional if maturity provided)
|
|
84
|
+
settlement_date: Settlement date (optional)
|
|
85
|
+
rebate: Rebate amount (default: 0)
|
|
86
|
+
observation_type: CONTINUOUS or DISCRETE (default: CONTINUOUS)
|
|
87
|
+
observation_dates: For discrete, list of observation times in year fractions
|
|
88
|
+
|
|
89
|
+
Raises:
|
|
90
|
+
ValidationError: If parameters are invalid
|
|
91
|
+
"""
|
|
92
|
+
# Default maturity handling
|
|
93
|
+
if maturity is None and exercise_date is None:
|
|
94
|
+
maturity = 0.0
|
|
95
|
+
elif maturity is None:
|
|
96
|
+
maturity = 0.0
|
|
97
|
+
|
|
98
|
+
# Store barrier parameters before calling super().__init__
|
|
99
|
+
self.barrier = barrier
|
|
100
|
+
self.barrier_type = barrier_type
|
|
101
|
+
self.rebate = rebate
|
|
102
|
+
self.participation_rate = participation_rate
|
|
103
|
+
self.pay_at_hit = pay_at_hit
|
|
104
|
+
self.observation_type = observation_type
|
|
105
|
+
self.observation_dates = observation_dates
|
|
106
|
+
self.observation_schedule = observation_schedule
|
|
107
|
+
|
|
108
|
+
super().__init__(
|
|
109
|
+
strike=strike,
|
|
110
|
+
maturity=maturity,
|
|
111
|
+
option_type=option_type,
|
|
112
|
+
exercise_type=ExerciseType.EUROPEAN, # Barrier options are typically European
|
|
113
|
+
exercise_date=exercise_date,
|
|
114
|
+
settlement_date=settlement_date,
|
|
115
|
+
contract_multiplier=contract_multiplier,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
def validate(self) -> None:
|
|
119
|
+
"""
|
|
120
|
+
Validate barrier option parameters.
|
|
121
|
+
|
|
122
|
+
Raises:
|
|
123
|
+
ValidationError: If parameters are invalid
|
|
124
|
+
"""
|
|
125
|
+
super().validate()
|
|
126
|
+
|
|
127
|
+
if self.barrier <= 0:
|
|
128
|
+
raise ValidationError(f"Barrier must be positive, got {self.barrier}")
|
|
129
|
+
|
|
130
|
+
if self.rebate < 0:
|
|
131
|
+
raise ValidationError(f"Rebate must be non-negative, got {self.rebate}")
|
|
132
|
+
if not isinstance(self.pay_at_hit, bool):
|
|
133
|
+
raise ValidationError(f"pay_at_hit must be boolean, got {self.pay_at_hit}")
|
|
134
|
+
if self.participation_rate <= 0:
|
|
135
|
+
raise ValidationError(
|
|
136
|
+
f"Participation rate must be positive, got {self.participation_rate}"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
if not isinstance(self.barrier_type, BarrierType):
|
|
140
|
+
raise ValidationError(f"Invalid barrier type: {self.barrier_type}")
|
|
141
|
+
|
|
142
|
+
if not isinstance(self.observation_type, ObservationType):
|
|
143
|
+
raise ValidationError(f"Invalid observation type: {self.observation_type}")
|
|
144
|
+
|
|
145
|
+
# For discrete observation, must have observation dates
|
|
146
|
+
if (
|
|
147
|
+
self.observation_type == ObservationType.DISCRETE
|
|
148
|
+
and self.observation_schedule is None
|
|
149
|
+
and (self.observation_dates is None or len(self.observation_dates) == 0)
|
|
150
|
+
):
|
|
151
|
+
raise ValidationError(
|
|
152
|
+
"Observation dates required for discrete barrier monitoring"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Validate observation dates if provided
|
|
156
|
+
if self.observation_dates is not None:
|
|
157
|
+
for t in self.observation_dates:
|
|
158
|
+
if t < 0:
|
|
159
|
+
raise ValidationError(
|
|
160
|
+
f"Observation dates must be non-negative, got {t}"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Normalize observation schedule (preferred) or legacy dates for discrete monitoring
|
|
164
|
+
if self.observation_schedule is not None:
|
|
165
|
+
if self.observation_type in (
|
|
166
|
+
ObservationType.CONTINUOUS,
|
|
167
|
+
ObservationType.EXPIRY,
|
|
168
|
+
):
|
|
169
|
+
raise ValidationError(
|
|
170
|
+
"ObservationSchedule requires DISCRETE observation_type."
|
|
171
|
+
)
|
|
172
|
+
normalized_schedule = ObservationSchedule(
|
|
173
|
+
records=[
|
|
174
|
+
ObservationRecord(
|
|
175
|
+
observation_time=rec.observation_time,
|
|
176
|
+
observation_date=rec.observation_date,
|
|
177
|
+
barrier=(
|
|
178
|
+
rec.barrier if rec.barrier is not None else self.barrier
|
|
179
|
+
),
|
|
180
|
+
payoff=rec.payoff if rec.payoff is not None else self.rebate,
|
|
181
|
+
return_rate=rec.return_rate,
|
|
182
|
+
)
|
|
183
|
+
for rec in self.observation_schedule.records
|
|
184
|
+
],
|
|
185
|
+
aggregation_mode=self.observation_schedule.aggregation_mode,
|
|
186
|
+
frequency=self.observation_schedule.frequency,
|
|
187
|
+
)
|
|
188
|
+
normalized_schedule.validate(require_single=True)
|
|
189
|
+
self.observation_schedule = normalized_schedule
|
|
190
|
+
if self.observation_schedule.times:
|
|
191
|
+
self.observation_dates = self.observation_schedule.times
|
|
192
|
+
self.observation_type = ObservationType.DISCRETE
|
|
193
|
+
elif self.observation_type == ObservationType.DISCRETE:
|
|
194
|
+
self.observation_schedule = ObservationSchedule.from_legacy(
|
|
195
|
+
observation_dates=self.observation_dates or [],
|
|
196
|
+
default_barrier=self.barrier,
|
|
197
|
+
default_payoff=self.rebate,
|
|
198
|
+
aggregation_mode=ObservationAggregation.STOP_FIRST_HIT,
|
|
199
|
+
)
|
|
200
|
+
self.observation_dates = self.observation_schedule.times
|
|
201
|
+
else:
|
|
202
|
+
# EXPIRY monitoring does not use schedules or legacy dates
|
|
203
|
+
self.observation_schedule = None
|
|
204
|
+
self.observation_dates = self.observation_dates or []
|
|
205
|
+
|
|
206
|
+
def get_payoff(self, spot: float) -> float:
|
|
207
|
+
"""
|
|
208
|
+
Calculate the option payoff at maturity (assuming barrier not hit for knock-out
|
|
209
|
+
or barrier hit for knock-in).
|
|
210
|
+
|
|
211
|
+
Note: This returns the vanilla payoff. The actual payoff depends on
|
|
212
|
+
whether the barrier was hit during the option's life.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
spot: Spot price at maturity
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Option payoff (call or put style)
|
|
219
|
+
"""
|
|
220
|
+
if spot < 0:
|
|
221
|
+
raise ValidationError(f"Spot price must be non-negative, got {spot}")
|
|
222
|
+
|
|
223
|
+
if self.is_call():
|
|
224
|
+
intrinsic = max(spot - self.strike, 0.0)
|
|
225
|
+
else:
|
|
226
|
+
intrinsic = max(self.strike - spot, 0.0)
|
|
227
|
+
|
|
228
|
+
return intrinsic * self.contract_multiplier
|
|
229
|
+
|
|
230
|
+
def intrinsic_value(self, spot: float) -> float:
|
|
231
|
+
"""
|
|
232
|
+
Calculate intrinsic value.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
spot: Current spot price
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Intrinsic value
|
|
239
|
+
"""
|
|
240
|
+
return self.get_payoff(spot)
|
|
241
|
+
|
|
242
|
+
@property
|
|
243
|
+
def is_knock_in(self) -> bool:
|
|
244
|
+
"""Check if this is a knock-in barrier."""
|
|
245
|
+
return self.barrier_type.is_knock_in
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def is_knock_out(self) -> bool:
|
|
249
|
+
"""Check if this is a knock-out barrier."""
|
|
250
|
+
return self.barrier_type.is_knock_out
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
def is_up_barrier(self) -> bool:
|
|
254
|
+
"""Check if barrier is above spot."""
|
|
255
|
+
return self.barrier_type.is_up
|
|
256
|
+
|
|
257
|
+
@property
|
|
258
|
+
def is_down_barrier(self) -> bool:
|
|
259
|
+
"""Check if barrier is below spot."""
|
|
260
|
+
return self.barrier_type.is_down
|
|
261
|
+
|
|
262
|
+
def is_barrier_hit(self, spot: float) -> bool:
|
|
263
|
+
"""
|
|
264
|
+
Check if the barrier would be hit at a given spot price.
|
|
265
|
+
|
|
266
|
+
Args:
|
|
267
|
+
spot: Spot price to check
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
True if barrier is hit
|
|
271
|
+
"""
|
|
272
|
+
if self.is_up_barrier:
|
|
273
|
+
return spot >= self.barrier
|
|
274
|
+
else: # down barrier
|
|
275
|
+
return spot <= self.barrier
|
|
276
|
+
|
|
277
|
+
@property
|
|
278
|
+
def pay_at_expiry(self) -> bool:
|
|
279
|
+
"""Rebate paid at expiry if True (i.e., not at hit)."""
|
|
280
|
+
return not self.pay_at_hit
|
|
281
|
+
|
|
282
|
+
def __repr__(self):
|
|
283
|
+
return (
|
|
284
|
+
f"BarrierOption("
|
|
285
|
+
f"{self.option_type}, K={self.strike:.2f}, "
|
|
286
|
+
f"B={self.barrier:.2f}, {self.barrier_type}, T={self.maturity:.4f}, "
|
|
287
|
+
f"rebate={self.rebate:.2f}, pay_at_hit={self.pay_at_hit}, "
|
|
288
|
+
f"participation={self.participation_rate:.4f})"
|
|
289
|
+
)
|