optPricing 2.0.0__tar.gz → 2.0.3__tar.gz
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.
- {optpricing-2.0.0/src/optPricing.egg-info → optpricing-2.0.3}/PKG-INFO +36 -28
- {optpricing-2.0.0 → optpricing-2.0.3}/README.md +14 -6
- {optpricing-2.0.0 → optpricing-2.0.3}/pyproject.toml +25 -24
- {optpricing-2.0.0 → optpricing-2.0.3/src/optPricing.egg-info}/PKG-INFO +36 -28
- optpricing-2.0.3/src/optPricing.egg-info/requires.txt +23 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/cli.py +202 -34
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/dashboard/pages/1_Calibration.py +19 -3
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/dashboard/pages/2_Pricer_and_Greeks.py +18 -6
- optpricing-2.0.3/src/quantfin/dashboard/pages/3_Financial_Tools.py +231 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/data/market_data_manager.py +3 -3
- {optpricing-2.0.0 → optpricing-2.0.3}/tests/test_cli.py +0 -28
- optpricing-2.0.0/src/optPricing.egg-info/requires.txt +0 -24
- optpricing-2.0.0/src/quantfin/dashboard/pages/3_Financial_Tools.py +0 -69
- {optpricing-2.0.0 → optpricing-2.0.3}/CHANGELOG.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/LICENSE +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/MANIFEST.in +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/guide/dashboard.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/guide/getting_started.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/guide/installation.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/guide/introduction.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/images/bates.png +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/images/calibration.png +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/images/fit_jump.png +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/images/zcb.png +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/atoms/bond.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/atoms/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/atoms/option.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/atoms/rate.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/atoms/stock.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/calibration/calibrator.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/calibration/fit_jump_parameters.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/calibration/fit_market_params.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/calibration/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/calibration/iv_surface.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/calibration/technique_selector.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/calibration/vectorized_bsm_iv.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/calibration/vectorized_integration_iv.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/cli.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/dashboard/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/dashboard/plots.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/dashboard/service.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/dashboard/widgets.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/data/historical_manager.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/data/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/data/market_data_manager.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/base/base_model.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/base/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/base/validators.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/bates.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/blacks_approx.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/bsm.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/cev.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/cgmy.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/cir.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/dupire_local.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/heston.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/hyperbolic.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/kou.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/merton_jump.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/nig.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/perpetual_put.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/sabr.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/sabr_jump.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/vasicek.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/models/vg.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/parity/implied_rate.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/parity/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/parity/parity_model.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/base/base_technique.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/base/greek_mixin.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/base/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/base/iv_mixin.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/base/lattice_technique.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/base/pricing_result.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/base/random_utils.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/closed_form.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/crr.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/fft.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/integration.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/kernels/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/kernels/lattice_kernels.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/kernels/mc_kernels.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/leisen_reimer.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/monte_carlo.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/pde.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/techniques/topm.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/workflows/backtest_workflow.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/workflows/daily_workflow.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/docs/reference/workflows/index.md +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/mkdocs.yml +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/setup.cfg +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/optPricing.egg-info/SOURCES.txt +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/optPricing.egg-info/dependency_links.txt +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/optPricing.egg-info/entry_points.txt +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/optPricing.egg-info/top_level.txt +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/atoms/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/atoms/bond.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/atoms/option.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/atoms/rate.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/atoms/stock.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/calibration/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/calibration/calibrator.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/calibration/fit_jump_parameters.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/calibration/fit_market_params.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/calibration/iv_surface.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/calibration/technique_selector.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/calibration/vectorized_bsm_iv.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/calibration/vectorized_integration_iv.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/dashboard/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/dashboard/app.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/dashboard/pages/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/dashboard/plots.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/dashboard/service.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/dashboard/widgets.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/data/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/data/historical_manager.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/base/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/base/base_model.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/base/validators.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/bates.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/blacks_approx.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/bsm.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/cev.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/cgmy.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/cir.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/dupire_local.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/heston.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/hyperbolic.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/kou.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/merton_jump.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/nig.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/perpetual_put.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/sabr.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/sabr_jump.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/vasicek.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/models/vg.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/parity/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/parity/implied_rate.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/parity/parity_model.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/base/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/base/base_technique.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/base/greek_mixin.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/base/iv_mixin.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/base/lattice_technique.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/base/pricing_result.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/base/random_utils.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/closed_form.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/crr.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/fft.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/integration.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/kernels/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/kernels/lattice_kernels.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/kernels/mc_kernels.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/leisen_reimer.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/monte_carlo.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/pde.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/techniques/topm.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/backtest_workflow.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/__init__.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/bates_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/bsm_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/cev_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/cgmy_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/heston_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/hyperbolic_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/kou_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/merton_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/nig_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/sabr_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/configs/vg_config.py +0 -0
- {optpricing-2.0.0 → optpricing-2.0.3}/src/quantfin/workflows/daily_workflow.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: optPricing
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: A financial options pricing and analysis library.
|
|
5
5
|
Author-email: Diljit Singh <first_last22@google.com>
|
|
6
6
|
License: # MIT LICENSE
|
|
@@ -21,34 +21,34 @@ Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
-
Requires-Dist: numpy
|
|
25
|
-
Requires-Dist: scipy
|
|
26
|
-
Requires-Dist: pandas
|
|
27
|
-
Requires-Dist: numba
|
|
28
|
-
Requires-Dist: pyyaml
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
|
|
32
|
-
Requires-Dist: streamlit
|
|
33
|
-
Requires-Dist: matplotlib
|
|
34
|
-
Requires-Dist: plotly
|
|
35
|
-
Requires-Dist: yfinance
|
|
36
|
-
Requires-Dist: tabulate
|
|
24
|
+
Requires-Dist: numpy~=2.2.5
|
|
25
|
+
Requires-Dist: scipy~=1.15.2
|
|
26
|
+
Requires-Dist: pandas~=2.2.3
|
|
27
|
+
Requires-Dist: numba~=0.61.2
|
|
28
|
+
Requires-Dist: pyyaml~=6.0.2
|
|
29
|
+
Requires-Dist: click~=8.1
|
|
30
|
+
Requires-Dist: polygon-api-client~=1.14.6
|
|
31
|
+
Requires-Dist: typer~=0.15.2
|
|
32
|
+
Requires-Dist: streamlit~=1.45.1
|
|
33
|
+
Requires-Dist: matplotlib~=3.10.1
|
|
34
|
+
Requires-Dist: plotly~=6.1.2
|
|
35
|
+
Requires-Dist: yfinance~=0.2.63
|
|
36
|
+
Requires-Dist: tabulate~=0.9.0
|
|
37
37
|
Provides-Extra: dev
|
|
38
|
-
Requires-Dist: pytest
|
|
39
|
-
Requires-Dist: pytest-cov
|
|
40
|
-
Requires-Dist: ruff
|
|
41
|
-
Requires-Dist: mkdocs
|
|
42
|
-
Requires-Dist: mkdocs-material
|
|
43
|
-
Requires-Dist: mkdocstrings[python]
|
|
44
|
-
Requires-Dist: mkdocs-section-index
|
|
45
|
-
Requires-Dist: line_profiler
|
|
38
|
+
Requires-Dist: pytest; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
40
|
+
Requires-Dist: ruff; extra == "dev"
|
|
41
|
+
Requires-Dist: mkdocs; extra == "dev"
|
|
42
|
+
Requires-Dist: mkdocs-material; extra == "dev"
|
|
43
|
+
Requires-Dist: mkdocstrings[python]; extra == "dev"
|
|
44
|
+
Requires-Dist: mkdocs-section-index; extra == "dev"
|
|
45
|
+
Requires-Dist: line_profiler; extra == "dev"
|
|
46
46
|
Dynamic: license-file
|
|
47
47
|
|
|
48
48
|
# QuantFin
|
|
49
49
|
|
|
50
50
|
[](https://github.com/diljit22/quantfin/actions/workflows/ci.yml)
|
|
51
|
-
[](https://pypi.org/project/
|
|
51
|
+
[](https://pypi.org/project/optPricing/2.0.0/)
|
|
52
52
|
[](https://opensource.org/licenses/MIT)
|
|
53
53
|
[](https://www.python.org/downloads/)
|
|
54
54
|
|
|
@@ -73,7 +73,7 @@ Get started in minutes using the command-line interface.
|
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
75
|
# 1. Install the library with all features, including the dashboard
|
|
76
|
-
pip install optPricing[app]
|
|
76
|
+
pip install "optPricing[app,dev]"
|
|
77
77
|
|
|
78
78
|
# 2. Download historical data for a ticker (used by some models)
|
|
79
79
|
quantfin data download --ticker SPY
|
|
@@ -89,10 +89,18 @@ quantfin demo
|
|
|
89
89
|
|
|
90
90
|
For a detailed tutorial, full API reference, and more examples, please see the official documentation.
|
|
91
91
|
|
|
92
|
-
- **Getting Started**:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
- **Getting Started**:
|
|
93
|
+
[Installation Guide](https://diljit22.github.io/quantFin/guide/installation/) ·
|
|
94
|
+
[Walkthrough](https://diljit22.github.io/quantFin/guide/getting_started/)
|
|
95
|
+
|
|
96
|
+
- **Documentation**:
|
|
97
|
+
[API Reference](https://diljit22.github.io/quantFin)
|
|
98
|
+
|
|
99
|
+
- **Interactive Dashboard**:
|
|
100
|
+
[Launch the UI](https://diljit22.github.io/quantFin/guide/dashboard/)
|
|
101
|
+
|
|
102
|
+
- **About Me**:
|
|
103
|
+
[LinkedIn](https://www.linkedin.com/in/singhdiljit/)
|
|
96
104
|
|
|
97
105
|
To explore all available commands, run:
|
|
98
106
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# QuantFin
|
|
2
2
|
|
|
3
3
|
[](https://github.com/diljit22/quantfin/actions/workflows/ci.yml)
|
|
4
|
-
[](https://pypi.org/project/
|
|
4
|
+
[](https://pypi.org/project/optPricing/2.0.0/)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://www.python.org/downloads/)
|
|
7
7
|
|
|
@@ -26,7 +26,7 @@ Get started in minutes using the command-line interface.
|
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
# 1. Install the library with all features, including the dashboard
|
|
29
|
-
pip install optPricing[app]
|
|
29
|
+
pip install "optPricing[app,dev]"
|
|
30
30
|
|
|
31
31
|
# 2. Download historical data for a ticker (used by some models)
|
|
32
32
|
quantfin data download --ticker SPY
|
|
@@ -42,10 +42,18 @@ quantfin demo
|
|
|
42
42
|
|
|
43
43
|
For a detailed tutorial, full API reference, and more examples, please see the official documentation.
|
|
44
44
|
|
|
45
|
-
- **Getting Started**:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
- **Getting Started**:
|
|
46
|
+
[Installation Guide](https://diljit22.github.io/quantFin/guide/installation/) ·
|
|
47
|
+
[Walkthrough](https://diljit22.github.io/quantFin/guide/getting_started/)
|
|
48
|
+
|
|
49
|
+
- **Documentation**:
|
|
50
|
+
[API Reference](https://diljit22.github.io/quantFin)
|
|
51
|
+
|
|
52
|
+
- **Interactive Dashboard**:
|
|
53
|
+
[Launch the UI](https://diljit22.github.io/quantFin/guide/dashboard/)
|
|
54
|
+
|
|
55
|
+
- **About Me**:
|
|
56
|
+
[LinkedIn](https://www.linkedin.com/in/singhdiljit/)
|
|
49
57
|
|
|
50
58
|
To explore all available commands, run:
|
|
51
59
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "optPricing"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.3"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Diljit Singh", email="first_last22@google.com" },
|
|
10
10
|
]
|
|
@@ -20,33 +20,31 @@ classifiers = [
|
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
dependencies = [
|
|
23
|
-
"numpy
|
|
24
|
-
"scipy
|
|
25
|
-
"pandas
|
|
26
|
-
"numba
|
|
27
|
-
"pyyaml
|
|
28
|
-
"
|
|
29
|
-
"
|
|
23
|
+
"numpy~=2.2.5",
|
|
24
|
+
"scipy~=1.15.2",
|
|
25
|
+
"pandas~=2.2.3",
|
|
26
|
+
"numba~=0.61.2",
|
|
27
|
+
"pyyaml~=6.0.2",
|
|
28
|
+
"click~=8.1",
|
|
29
|
+
"polygon-api-client~=1.14.6",
|
|
30
|
+
"typer~=0.15.2",
|
|
31
|
+
"streamlit~=1.45.1",
|
|
32
|
+
"matplotlib~=3.10.1",
|
|
33
|
+
"plotly~=6.1.2",
|
|
34
|
+
"yfinance~=0.2.63",
|
|
35
|
+
"tabulate~=0.9.0",
|
|
30
36
|
]
|
|
31
37
|
|
|
32
38
|
[project.optional-dependencies]
|
|
33
|
-
app = [
|
|
34
|
-
"streamlit==1.45.1",
|
|
35
|
-
"matplotlib==3.10.1",
|
|
36
|
-
"plotly==6.1.2",
|
|
37
|
-
"yfinance==0.2.63",
|
|
38
|
-
"tabulate==0.9.0",
|
|
39
|
-
|
|
40
|
-
]
|
|
41
39
|
dev = [
|
|
42
|
-
"pytest
|
|
43
|
-
"pytest-cov
|
|
44
|
-
"ruff
|
|
45
|
-
"mkdocs
|
|
46
|
-
"mkdocs-material
|
|
47
|
-
"mkdocstrings[python]
|
|
48
|
-
"mkdocs-section-index
|
|
49
|
-
"line_profiler
|
|
40
|
+
"pytest",
|
|
41
|
+
"pytest-cov",
|
|
42
|
+
"ruff",
|
|
43
|
+
"mkdocs",
|
|
44
|
+
"mkdocs-material",
|
|
45
|
+
"mkdocstrings[python]",
|
|
46
|
+
"mkdocs-section-index",
|
|
47
|
+
"line_profiler",
|
|
50
48
|
]
|
|
51
49
|
|
|
52
50
|
[project.urls]
|
|
@@ -56,6 +54,9 @@ dev = [
|
|
|
56
54
|
optPricing = "quantfin.cli:app"
|
|
57
55
|
quantfin = "quantfin.cli:app"
|
|
58
56
|
|
|
57
|
+
[tool.setuptools]
|
|
58
|
+
package-dir = {"" = "src"}
|
|
59
|
+
|
|
59
60
|
[tool.setuptools.packages.find]
|
|
60
61
|
where = ["src"]
|
|
61
62
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: optPricing
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: A financial options pricing and analysis library.
|
|
5
5
|
Author-email: Diljit Singh <first_last22@google.com>
|
|
6
6
|
License: # MIT LICENSE
|
|
@@ -21,34 +21,34 @@ Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
-
Requires-Dist: numpy
|
|
25
|
-
Requires-Dist: scipy
|
|
26
|
-
Requires-Dist: pandas
|
|
27
|
-
Requires-Dist: numba
|
|
28
|
-
Requires-Dist: pyyaml
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
|
|
32
|
-
Requires-Dist: streamlit
|
|
33
|
-
Requires-Dist: matplotlib
|
|
34
|
-
Requires-Dist: plotly
|
|
35
|
-
Requires-Dist: yfinance
|
|
36
|
-
Requires-Dist: tabulate
|
|
24
|
+
Requires-Dist: numpy~=2.2.5
|
|
25
|
+
Requires-Dist: scipy~=1.15.2
|
|
26
|
+
Requires-Dist: pandas~=2.2.3
|
|
27
|
+
Requires-Dist: numba~=0.61.2
|
|
28
|
+
Requires-Dist: pyyaml~=6.0.2
|
|
29
|
+
Requires-Dist: click~=8.1
|
|
30
|
+
Requires-Dist: polygon-api-client~=1.14.6
|
|
31
|
+
Requires-Dist: typer~=0.15.2
|
|
32
|
+
Requires-Dist: streamlit~=1.45.1
|
|
33
|
+
Requires-Dist: matplotlib~=3.10.1
|
|
34
|
+
Requires-Dist: plotly~=6.1.2
|
|
35
|
+
Requires-Dist: yfinance~=0.2.63
|
|
36
|
+
Requires-Dist: tabulate~=0.9.0
|
|
37
37
|
Provides-Extra: dev
|
|
38
|
-
Requires-Dist: pytest
|
|
39
|
-
Requires-Dist: pytest-cov
|
|
40
|
-
Requires-Dist: ruff
|
|
41
|
-
Requires-Dist: mkdocs
|
|
42
|
-
Requires-Dist: mkdocs-material
|
|
43
|
-
Requires-Dist: mkdocstrings[python]
|
|
44
|
-
Requires-Dist: mkdocs-section-index
|
|
45
|
-
Requires-Dist: line_profiler
|
|
38
|
+
Requires-Dist: pytest; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
40
|
+
Requires-Dist: ruff; extra == "dev"
|
|
41
|
+
Requires-Dist: mkdocs; extra == "dev"
|
|
42
|
+
Requires-Dist: mkdocs-material; extra == "dev"
|
|
43
|
+
Requires-Dist: mkdocstrings[python]; extra == "dev"
|
|
44
|
+
Requires-Dist: mkdocs-section-index; extra == "dev"
|
|
45
|
+
Requires-Dist: line_profiler; extra == "dev"
|
|
46
46
|
Dynamic: license-file
|
|
47
47
|
|
|
48
48
|
# QuantFin
|
|
49
49
|
|
|
50
50
|
[](https://github.com/diljit22/quantfin/actions/workflows/ci.yml)
|
|
51
|
-
[](https://pypi.org/project/
|
|
51
|
+
[](https://pypi.org/project/optPricing/2.0.0/)
|
|
52
52
|
[](https://opensource.org/licenses/MIT)
|
|
53
53
|
[](https://www.python.org/downloads/)
|
|
54
54
|
|
|
@@ -73,7 +73,7 @@ Get started in minutes using the command-line interface.
|
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
75
|
# 1. Install the library with all features, including the dashboard
|
|
76
|
-
pip install optPricing[app]
|
|
76
|
+
pip install "optPricing[app,dev]"
|
|
77
77
|
|
|
78
78
|
# 2. Download historical data for a ticker (used by some models)
|
|
79
79
|
quantfin data download --ticker SPY
|
|
@@ -89,10 +89,18 @@ quantfin demo
|
|
|
89
89
|
|
|
90
90
|
For a detailed tutorial, full API reference, and more examples, please see the official documentation.
|
|
91
91
|
|
|
92
|
-
- **Getting Started**:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
- **Getting Started**:
|
|
93
|
+
[Installation Guide](https://diljit22.github.io/quantFin/guide/installation/) ·
|
|
94
|
+
[Walkthrough](https://diljit22.github.io/quantFin/guide/getting_started/)
|
|
95
|
+
|
|
96
|
+
- **Documentation**:
|
|
97
|
+
[API Reference](https://diljit22.github.io/quantFin)
|
|
98
|
+
|
|
99
|
+
- **Interactive Dashboard**:
|
|
100
|
+
[Launch the UI](https://diljit22.github.io/quantFin/guide/dashboard/)
|
|
101
|
+
|
|
102
|
+
- **About Me**:
|
|
103
|
+
[LinkedIn](https://www.linkedin.com/in/singhdiljit/)
|
|
96
104
|
|
|
97
105
|
To explore all available commands, run:
|
|
98
106
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
numpy~=2.2.5
|
|
2
|
+
scipy~=1.15.2
|
|
3
|
+
pandas~=2.2.3
|
|
4
|
+
numba~=0.61.2
|
|
5
|
+
pyyaml~=6.0.2
|
|
6
|
+
click~=8.1
|
|
7
|
+
polygon-api-client~=1.14.6
|
|
8
|
+
typer~=0.15.2
|
|
9
|
+
streamlit~=1.45.1
|
|
10
|
+
matplotlib~=3.10.1
|
|
11
|
+
plotly~=6.1.2
|
|
12
|
+
yfinance~=0.2.63
|
|
13
|
+
tabulate~=0.9.0
|
|
14
|
+
|
|
15
|
+
[dev]
|
|
16
|
+
pytest
|
|
17
|
+
pytest-cov
|
|
18
|
+
ruff
|
|
19
|
+
mkdocs
|
|
20
|
+
mkdocs-material
|
|
21
|
+
mkdocstrings[python]
|
|
22
|
+
mkdocs-section-index
|
|
23
|
+
line_profiler
|
|
@@ -3,17 +3,27 @@ from __future__ import annotations
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
5
|
import subprocess
|
|
6
|
-
from
|
|
6
|
+
from importlib import resources
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Annotated, Optional
|
|
7
9
|
|
|
10
|
+
import numpy as np
|
|
11
|
+
import pandas as pd
|
|
8
12
|
import typer
|
|
9
13
|
|
|
10
|
-
from quantfin.
|
|
14
|
+
from quantfin.atoms import Option, OptionType, Rate, Stock
|
|
15
|
+
from quantfin.calibration import fit_rate_and_dividend
|
|
16
|
+
from quantfin.calibration.technique_selector import select_fastest_technique
|
|
17
|
+
from quantfin.config import _config
|
|
11
18
|
from quantfin.data import (
|
|
12
19
|
get_available_snapshot_dates,
|
|
20
|
+
get_live_option_chain,
|
|
13
21
|
load_market_snapshot,
|
|
14
22
|
save_historical_returns,
|
|
15
23
|
save_market_snapshot,
|
|
16
24
|
)
|
|
25
|
+
from quantfin.models import BaseModel
|
|
26
|
+
from quantfin.parity import ImpliedRateModel
|
|
17
27
|
from quantfin.workflows import BacktestWorkflow, DailyWorkflow
|
|
18
28
|
from quantfin.workflows.configs import ALL_MODEL_CONFIGS
|
|
19
29
|
|
|
@@ -35,6 +45,9 @@ app = typer.Typer(
|
|
|
35
45
|
data_app = typer.Typer(name="data", help="Tools for downloading and managing data.")
|
|
36
46
|
app.add_typer(data_app)
|
|
37
47
|
|
|
48
|
+
tools_app = typer.Typer(name="tools", help="Miscellaneous financial utility tools.")
|
|
49
|
+
app.add_typer(tools_app)
|
|
50
|
+
|
|
38
51
|
|
|
39
52
|
# Utility function for logging setup
|
|
40
53
|
def setup_logging(verbose: bool):
|
|
@@ -57,25 +70,13 @@ def dashboard():
|
|
|
57
70
|
Launches the Streamlit dashboard application.
|
|
58
71
|
"""
|
|
59
72
|
# Note: We point directly to the source file now.
|
|
60
|
-
app_path = PROJECT_ROOT / "src" / "quantfin" / "dashboard" / "app.py"
|
|
61
|
-
typer.echo(f"Launching Streamlit dashboard from: {app_path}")
|
|
62
|
-
|
|
63
|
-
if not app_path.exists():
|
|
64
|
-
typer.secho(
|
|
65
|
-
f"Error: Dashboard entry point not found at '{app_path}'.",
|
|
66
|
-
fg=typer.colors.RED,
|
|
67
|
-
)
|
|
68
|
-
raise typer.Exit(code=1)
|
|
69
|
-
|
|
70
73
|
try:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
check=True
|
|
74
|
-
)
|
|
74
|
+
with resources.path("quantfin.dashboard", "app.py") as app_path:
|
|
75
|
+
typer.echo(f"Launching Streamlit dashboard from: {app_path}")
|
|
76
|
+
subprocess.run(["streamlit", "run", str(app_path)], check=True)
|
|
75
77
|
except FileNotFoundError:
|
|
76
78
|
typer.secho(
|
|
77
|
-
"Error: 'streamlit' command not found; install
|
|
78
|
-
"'pip install optPricing[app]'",
|
|
79
|
+
"Error: 'streamlit' command not found; 'pip install optpricing[app]'",
|
|
79
80
|
fg=typer.colors.RED,
|
|
80
81
|
)
|
|
81
82
|
raise typer.Exit(code=1)
|
|
@@ -174,6 +175,11 @@ def calibrate(
|
|
|
174
175
|
"""
|
|
175
176
|
setup_logging(verbose)
|
|
176
177
|
|
|
178
|
+
current_dir = Path.cwd()
|
|
179
|
+
artifacts_base_dir = current_dir / _config.get("artifacts_directory", "artifacts")
|
|
180
|
+
calibrated_params_dir = artifacts_base_dir / "calibrated_params"
|
|
181
|
+
calibrated_params_dir.mkdir(parents=True, exist_ok=True)
|
|
182
|
+
|
|
177
183
|
# --- 1. Determine the snapshot date to use ---
|
|
178
184
|
if date is None:
|
|
179
185
|
typer.echo(
|
|
@@ -248,7 +254,7 @@ def calibrate(
|
|
|
248
254
|
}
|
|
249
255
|
# Example filename: SPY_Heston_2023-01-01.json
|
|
250
256
|
filename = f"{ticker}_{model_name}_{date}.json"
|
|
251
|
-
save_path =
|
|
257
|
+
save_path = calibrated_params_dir / filename
|
|
252
258
|
with open(save_path, "w") as f:
|
|
253
259
|
json.dump(params_to_save, f, indent=4)
|
|
254
260
|
typer.echo(f" - Saved parameters to: {save_path}")
|
|
@@ -308,21 +314,12 @@ def demo(
|
|
|
308
314
|
If a model name is provided (e.g., 'BSM'), it runs only that benchmark.
|
|
309
315
|
Otherwise, it runs the full suite.
|
|
310
316
|
"""
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
try:
|
|
319
|
-
subprocess.run(command_to_run, check=True)
|
|
320
|
-
except FileNotFoundError:
|
|
321
|
-
typer.secho(
|
|
322
|
-
f"Error: Demo script not found at '{benchmark_script_path}'.",
|
|
323
|
-
fg=typer.colors.RED,
|
|
324
|
-
)
|
|
325
|
-
raise typer.Exit(code=1)
|
|
317
|
+
typer.secho(
|
|
318
|
+
"The 'demo' command for developers and requires the full source repository.",
|
|
319
|
+
fg=typer.colors.YELLOW,
|
|
320
|
+
)
|
|
321
|
+
typer.echo("Please run 'make demo' from the project's root directory instead.")
|
|
322
|
+
raise typer.Exit()
|
|
326
323
|
|
|
327
324
|
|
|
328
325
|
@data_app.command(name="snapshot")
|
|
@@ -370,3 +367,174 @@ def save_snapshot(
|
|
|
370
367
|
|
|
371
368
|
save_market_snapshot(tickers_to_download)
|
|
372
369
|
typer.secho("Snapshot complete.", fg=typer.colors.GREEN)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
@app.command()
|
|
373
|
+
def price(
|
|
374
|
+
ticker: Annotated[
|
|
375
|
+
str, typer.Option("--ticker", "-t", help="Stock ticker for the option.")
|
|
376
|
+
],
|
|
377
|
+
strike: Annotated[
|
|
378
|
+
float, typer.Option("--strike", "-k", help="Strike price of the option.")
|
|
379
|
+
],
|
|
380
|
+
maturity: Annotated[
|
|
381
|
+
str,
|
|
382
|
+
typer.Option("--maturity", "-T", help="Maturity date in YYYY-MM-DD format."),
|
|
383
|
+
],
|
|
384
|
+
option_type: Annotated[
|
|
385
|
+
str, typer.Option("--type", help="Option type: 'call' or 'put'.")
|
|
386
|
+
] = "call",
|
|
387
|
+
model: Annotated[
|
|
388
|
+
str, typer.Option("--model", "-m", help="The model to use for pricing.")
|
|
389
|
+
] = "BSM",
|
|
390
|
+
param: Annotated[
|
|
391
|
+
list[str] | None,
|
|
392
|
+
typer.Option(
|
|
393
|
+
"--param",
|
|
394
|
+
help="Set a model parameter (e.g., 'sigma=0.2'). Can use multiple times.",
|
|
395
|
+
),
|
|
396
|
+
] = None,
|
|
397
|
+
):
|
|
398
|
+
"""Prices a single option using live market data and user model parameters."""
|
|
399
|
+
msg = (
|
|
400
|
+
f"Pricing {ticker} {strike} {option_type.upper()} expiring {maturity} "
|
|
401
|
+
f"using {model} model..."
|
|
402
|
+
)
|
|
403
|
+
typer.echo(msg)
|
|
404
|
+
|
|
405
|
+
# 1. Parse model parameters
|
|
406
|
+
model_params = {}
|
|
407
|
+
if param:
|
|
408
|
+
for p in param:
|
|
409
|
+
try:
|
|
410
|
+
key, value = p.split("=")
|
|
411
|
+
model_params[key.strip()] = float(value)
|
|
412
|
+
except ValueError:
|
|
413
|
+
typer.secho(
|
|
414
|
+
f"Invalid format for parameter: '{p}'. Use 'key=value'.",
|
|
415
|
+
fg=typer.colors.RED,
|
|
416
|
+
)
|
|
417
|
+
raise typer.Exit(code=1)
|
|
418
|
+
|
|
419
|
+
# 2. Get live market data for r, q, and spot
|
|
420
|
+
typer.echo("Fetching live market data...")
|
|
421
|
+
live_chain = get_live_option_chain(ticker)
|
|
422
|
+
if live_chain is None or live_chain.empty:
|
|
423
|
+
typer.secho(
|
|
424
|
+
f"Error: Could not fetch live option chain for {ticker}.",
|
|
425
|
+
fg=typer.colors.RED,
|
|
426
|
+
)
|
|
427
|
+
raise typer.Exit(code=1)
|
|
428
|
+
|
|
429
|
+
spot = live_chain["spot_price"].iloc[0]
|
|
430
|
+
calls = live_chain[live_chain["optionType"] == "call"]
|
|
431
|
+
puts = live_chain[live_chain["optionType"] == "put"]
|
|
432
|
+
r, q = fit_rate_and_dividend(calls, puts, spot)
|
|
433
|
+
typer.echo(
|
|
434
|
+
f"Live Data -> Spot: {spot:.2f}, Implied Rate: {r:.4f}, Implied Div: {q:.4f}"
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
# 3. Create objects and price
|
|
438
|
+
stock = Stock(spot=spot, dividend=q)
|
|
439
|
+
rate = Rate(rate=r)
|
|
440
|
+
maturity_years = (pd.to_datetime(maturity) - pd.Timestamp.now()).days / 365.25
|
|
441
|
+
option = Option(
|
|
442
|
+
strike=strike,
|
|
443
|
+
maturity=maturity_years,
|
|
444
|
+
option_type=OptionType[option_type.upper()],
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
model_class = ALL_MODEL_CONFIGS[model]["model_class"]
|
|
448
|
+
model_instance = model_class(params=model_params)
|
|
449
|
+
technique = select_fastest_technique(model_instance)
|
|
450
|
+
|
|
451
|
+
# Prepare kwargs for techniques that need extra info (e.g., Heston's v0)
|
|
452
|
+
pricing_kwargs = model_params.copy()
|
|
453
|
+
|
|
454
|
+
price_result = technique.price(
|
|
455
|
+
option, stock, model_instance, rate, **pricing_kwargs
|
|
456
|
+
)
|
|
457
|
+
delta = technique.delta(option, stock, model_instance, rate, **pricing_kwargs)
|
|
458
|
+
gamma = technique.gamma(option, stock, model_instance, rate, **pricing_kwargs)
|
|
459
|
+
vega = technique.vega(option, stock, model_instance, rate, **pricing_kwargs)
|
|
460
|
+
|
|
461
|
+
# 4. Display results
|
|
462
|
+
typer.secho("\n--- Pricing Results ---", fg=typer.colors.CYAN)
|
|
463
|
+
typer.echo(f"Price: {price_result.price:.4f}")
|
|
464
|
+
typer.echo(f"Delta: {delta:.4f}")
|
|
465
|
+
typer.echo(f"Gamma: {gamma:.4f}")
|
|
466
|
+
typer.echo(f"Vega: {vega:.4f}")
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
@tools_app.command(name="implied-rate")
|
|
470
|
+
def get_implied_rate(
|
|
471
|
+
ticker: Annotated[
|
|
472
|
+
str, typer.Option("--ticker", "-t", help="Stock ticker for the option pair.")
|
|
473
|
+
],
|
|
474
|
+
strike: Annotated[
|
|
475
|
+
float, typer.Option("--strike", "-k", help="Strike price of the option pair.")
|
|
476
|
+
],
|
|
477
|
+
maturity: Annotated[
|
|
478
|
+
str,
|
|
479
|
+
typer.Option("--maturity", "-T", help="Maturity date in YYYY-MM-DD format."),
|
|
480
|
+
],
|
|
481
|
+
):
|
|
482
|
+
"""Calculates the implied risk-free rate from a live call-put pair."""
|
|
483
|
+
typer.echo(
|
|
484
|
+
f"Fetching live prices for {ticker} {strike} options expiring {maturity}..."
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
live_chain = get_live_option_chain(ticker)
|
|
488
|
+
if live_chain is None or live_chain.empty:
|
|
489
|
+
typer.secho(
|
|
490
|
+
f"Error: Could not fetch live option chain for {ticker}.",
|
|
491
|
+
fg=typer.colors.RED,
|
|
492
|
+
)
|
|
493
|
+
raise typer.Exit(code=1)
|
|
494
|
+
|
|
495
|
+
maturity_dt = pd.to_datetime(maturity).date()
|
|
496
|
+
chain_for_expiry = live_chain[live_chain["expiry"].dt.date == maturity_dt]
|
|
497
|
+
|
|
498
|
+
call_option = chain_for_expiry[
|
|
499
|
+
(chain_for_expiry["strike"] == strike)
|
|
500
|
+
& (chain_for_expiry["optionType"] == "call")
|
|
501
|
+
]
|
|
502
|
+
put_option = chain_for_expiry[
|
|
503
|
+
(chain_for_expiry["strike"] == strike)
|
|
504
|
+
& (chain_for_expiry["optionType"] == "put")
|
|
505
|
+
]
|
|
506
|
+
|
|
507
|
+
if call_option.empty or put_option.empty:
|
|
508
|
+
typer.secho(
|
|
509
|
+
f"Error: Did not find both: call & put for strike {strike} on {maturity}.",
|
|
510
|
+
fg=typer.colors.RED,
|
|
511
|
+
)
|
|
512
|
+
raise typer.Exit(code=1)
|
|
513
|
+
|
|
514
|
+
call_price = call_option["marketPrice"].iloc[0]
|
|
515
|
+
put_price = put_option["marketPrice"].iloc[0]
|
|
516
|
+
|
|
517
|
+
spot_price = call_option["spot_price"].iloc[0]
|
|
518
|
+
maturity_years = call_option["maturity"].iloc[0]
|
|
519
|
+
|
|
520
|
+
pair_msg = (
|
|
521
|
+
f"Found Pair -> Call Price: {call_price:.2f}, Put Price: {put_price:.2f}, "
|
|
522
|
+
f"Spot: {spot_price:.2f}"
|
|
523
|
+
)
|
|
524
|
+
typer.echo(pair_msg)
|
|
525
|
+
|
|
526
|
+
implied_rate_model = ImpliedRateModel(params={})
|
|
527
|
+
try:
|
|
528
|
+
implied_r = implied_rate_model.price_closed_form(
|
|
529
|
+
call_price=call_price,
|
|
530
|
+
put_price=put_price,
|
|
531
|
+
spot=spot_price,
|
|
532
|
+
strike=strike,
|
|
533
|
+
t=maturity_years,
|
|
534
|
+
q=0,
|
|
535
|
+
)
|
|
536
|
+
typer.secho(
|
|
537
|
+
f"\nImplied Risk-Free Rate (r): {implied_r:.4%}", fg=typer.colors.GREEN
|
|
538
|
+
)
|
|
539
|
+
except Exception as e:
|
|
540
|
+
typer.secho(f"\nError calculating implied rate: {e}", fg=typer.colors.RED)
|
|
@@ -11,21 +11,37 @@ st.caption(
|
|
|
11
11
|
"Calibrate models to market data and visualize the resulting volatility smiles."
|
|
12
12
|
)
|
|
13
13
|
AVAILABLE_TICKERS = _config.get("default_tickers", ["SPY", "AAPL"])
|
|
14
|
+
ENABLED_MODELS = ["BSM", "Merton"]
|
|
15
|
+
|
|
16
|
+
all_model_names = list(ALL_MODEL_CONFIGS.keys())
|
|
17
|
+
disabled_models = [name for name in all_model_names if name not in ENABLED_MODELS]
|
|
18
|
+
AVAILABLE_MODELS_FOR_CALIBRATION = {
|
|
19
|
+
name: config for name, config in ALL_MODEL_CONFIGS.items() if name in ENABLED_MODELS
|
|
20
|
+
}
|
|
14
21
|
|
|
15
22
|
with st.sidebar:
|
|
16
23
|
st.header("Configuration")
|
|
17
24
|
ticker = st.selectbox("Ticker", AVAILABLE_TICKERS)
|
|
25
|
+
|
|
18
26
|
data_source_options = get_available_snapshot_dates(ticker)
|
|
27
|
+
if data_source_options:
|
|
28
|
+
data_source_options.insert(0, "Live Data")
|
|
29
|
+
else:
|
|
30
|
+
data_source_options = ["Live Data"]
|
|
31
|
+
|
|
19
32
|
snapshot_date = st.selectbox("Snapshot Date", data_source_options)
|
|
33
|
+
|
|
20
34
|
model_selection = st.multiselect(
|
|
21
35
|
"Select Models to Calibrate",
|
|
22
|
-
list(
|
|
23
|
-
default=["
|
|
36
|
+
list(AVAILABLE_MODELS_FOR_CALIBRATION.keys()),
|
|
37
|
+
default=["BSM"],
|
|
24
38
|
)
|
|
25
39
|
run_button = st.button("Run Calibration Analysis")
|
|
26
40
|
|
|
27
41
|
if run_button:
|
|
28
|
-
selected_configs = {
|
|
42
|
+
selected_configs = {
|
|
43
|
+
name: AVAILABLE_MODELS_FOR_CALIBRATION[name] for name in model_selection
|
|
44
|
+
}
|
|
29
45
|
with st.spinner("Initializing analysis..."):
|
|
30
46
|
service = DashboardService(ticker, snapshot_date, selected_configs)
|
|
31
47
|
try:
|