quant-kernel 2.9.0__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.
Files changed (196) hide show
  1. quant_kernel-2.9.0/.clang-format +3 -0
  2. quant_kernel-2.9.0/.github/workflows/ci.yml +128 -0
  3. quant_kernel-2.9.0/.github/workflows/wheels.yml +81 -0
  4. quant_kernel-2.9.0/.gitignore +41 -0
  5. quant_kernel-2.9.0/CMakeLists.txt +16 -0
  6. quant_kernel-2.9.0/LICENSE +13 -0
  7. quant_kernel-2.9.0/Makefile +68 -0
  8. quant_kernel-2.9.0/PKG-INFO +304 -0
  9. quant_kernel-2.9.0/README.md +260 -0
  10. quant_kernel-2.9.0/cpp/CMakeLists.txt +132 -0
  11. quant_kernel-2.9.0/cpp/bench/benchmark_all.cpp +156 -0
  12. quant_kernel-2.9.0/cpp/bench/benchmark_bsm_batch.cpp +92 -0
  13. quant_kernel-2.9.0/cpp/include/quantkernel/qk_abi.h +33 -0
  14. quant_kernel-2.9.0/cpp/include/quantkernel/qk_api.h +570 -0
  15. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/aad/aad.cpp +72 -0
  16. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/aad/aad.h +15 -0
  17. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/adjoint_greeks_models.h +10 -0
  18. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/common/internal_util.h +55 -0
  19. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/common/params.h +26 -0
  20. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/likelihood_ratio/likelihood_ratio.cpp +58 -0
  21. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/likelihood_ratio/likelihood_ratio.h +15 -0
  22. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/pathwise_derivative/pathwise_derivative.cpp +52 -0
  23. quant_kernel-2.9.0/cpp/src/algorithms/adjoint_greeks/pathwise_derivative/pathwise_derivative.h +15 -0
  24. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/bachelier/bachelier.cpp +30 -0
  25. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/bachelier/bachelier.h +13 -0
  26. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/black_1976/black_1976.cpp +32 -0
  27. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/black_1976/black_1976.h +13 -0
  28. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/black_scholes_merton/black_scholes_merton.cpp +34 -0
  29. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/black_scholes_merton/black_scholes_merton.h +13 -0
  30. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/closed_form_models.h +15 -0
  31. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/common/internal_util.h +171 -0
  32. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/common/params.h +38 -0
  33. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/dupire/dupire.cpp +53 -0
  34. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/dupire/dupire.h +18 -0
  35. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/heston/heston.cpp +55 -0
  36. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/heston/heston.h +15 -0
  37. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/merton_jump_diffusion/merton_jump_diffusion.cpp +56 -0
  38. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/merton_jump_diffusion/merton_jump_diffusion.h +15 -0
  39. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/sabr/sabr.cpp +64 -0
  40. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/sabr/sabr.h +16 -0
  41. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/variance_gamma/variance_gamma.cpp +51 -0
  42. quant_kernel-2.9.0/cpp/src/algorithms/closed_form_semi_analytical/variance_gamma/variance_gamma.h +15 -0
  43. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/adi/adi.cpp +479 -0
  44. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/adi/adi.h +20 -0
  45. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/common/internal_util.h +103 -0
  46. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/common/params.h +27 -0
  47. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/crank_nicolson/crank_nicolson.cpp +98 -0
  48. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/crank_nicolson/crank_nicolson.h +15 -0
  49. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/explicit_fd/explicit_fd.cpp +75 -0
  50. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/explicit_fd/explicit_fd.h +15 -0
  51. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/finite_difference_models.h +12 -0
  52. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/implicit_fd/implicit_fd.cpp +91 -0
  53. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/implicit_fd/implicit_fd.h +15 -0
  54. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/psor/psor.cpp +99 -0
  55. quant_kernel-2.9.0/cpp/src/algorithms/finite_difference_methods/psor/psor.h +16 -0
  56. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/carr_madan_fft/carr_madan_fft.cpp +75 -0
  57. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/carr_madan_fft/carr_madan_fft.h +14 -0
  58. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/common/internal_util.h +183 -0
  59. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/common/params.h +38 -0
  60. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/cos_method/cos_method.cpp +71 -0
  61. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/cos_method/cos_method.h +14 -0
  62. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/fourier_transform_models.h +12 -0
  63. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/fractional_fft/fractional_fft.cpp +76 -0
  64. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/fractional_fft/fractional_fft.h +14 -0
  65. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/hilbert_transform/hilbert_transform.cpp +58 -0
  66. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/hilbert_transform/hilbert_transform.h +14 -0
  67. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/lewis_fourier_inversion/lewis_fourier_inversion.cpp +42 -0
  68. quant_kernel-2.9.0/cpp/src/algorithms/fourier_transform_methods/lewis_fourier_inversion/lewis_fourier_inversion.h +14 -0
  69. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/adaptive_quadrature/adaptive_quadrature.cpp +49 -0
  70. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/adaptive_quadrature/adaptive_quadrature.h +14 -0
  71. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/common/internal_util.h +314 -0
  72. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/common/params.h +30 -0
  73. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/gauss_hermite/gauss_hermite.cpp +41 -0
  74. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/gauss_hermite/gauss_hermite.h +14 -0
  75. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/gauss_laguerre/gauss_laguerre.cpp +89 -0
  76. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/gauss_laguerre/gauss_laguerre.h +14 -0
  77. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/gauss_legendre/gauss_legendre.cpp +47 -0
  78. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/gauss_legendre/gauss_legendre.h +14 -0
  79. quant_kernel-2.9.0/cpp/src/algorithms/integral_quadrature/integral_quadrature_models.h +11 -0
  80. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/common/internal_util.h +137 -0
  81. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/common/params.h +37 -0
  82. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/deep_bsde/deep_bsde.cpp +99 -0
  83. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/deep_bsde/deep_bsde.h +15 -0
  84. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/deep_hedging/deep_hedging.cpp +128 -0
  85. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/deep_hedging/deep_hedging.h +15 -0
  86. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/machine_learning_models.h +11 -0
  87. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/neural_sde_calibration/neural_sde_calibration.cpp +56 -0
  88. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/neural_sde_calibration/neural_sde_calibration.h +15 -0
  89. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/pinns/pinns.cpp +178 -0
  90. quant_kernel-2.9.0/cpp/src/algorithms/machine_learning/pinns/pinns.h +15 -0
  91. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/antithetic_variates/antithetic_variates.cpp +45 -0
  92. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/antithetic_variates/antithetic_variates.h +14 -0
  93. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/common/internal_util.h +133 -0
  94. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/common/params.h +16 -0
  95. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/control_variates/control_variates.cpp +54 -0
  96. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/control_variates/control_variates.h +14 -0
  97. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/euler_maruyama/euler_maruyama.cpp +52 -0
  98. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/euler_maruyama/euler_maruyama.h +14 -0
  99. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/importance_sampling/importance_sampling.cpp +35 -0
  100. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/importance_sampling/importance_sampling.h +14 -0
  101. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/longstaff_schwartz/longstaff_schwartz.cpp +132 -0
  102. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/longstaff_schwartz/longstaff_schwartz.h +14 -0
  103. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/milstein/milstein.cpp +53 -0
  104. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/milstein/milstein.h +14 -0
  105. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/monte_carlo_models.h +16 -0
  106. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/multilevel_monte_carlo/multilevel_monte_carlo.cpp +74 -0
  107. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/multilevel_monte_carlo/multilevel_monte_carlo.h +15 -0
  108. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/quasi_monte_carlo/quasi_monte_carlo.cpp +58 -0
  109. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/quasi_monte_carlo/quasi_monte_carlo.h +18 -0
  110. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/standard_monte_carlo/standard_monte_carlo.cpp +46 -0
  111. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/standard_monte_carlo/standard_monte_carlo.h +14 -0
  112. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/stratified_sampling/stratified_sampling.cpp +37 -0
  113. quant_kernel-2.9.0/cpp/src/algorithms/monte_carlo_methods/stratified_sampling/stratified_sampling.h +14 -0
  114. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/common/internal_util.h +108 -0
  115. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/common/params.h +31 -0
  116. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/polynomial_chaos_expansion/polynomial_chaos_expansion.cpp +86 -0
  117. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/polynomial_chaos_expansion/polynomial_chaos_expansion.h +15 -0
  118. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/proper_orthogonal_decomposition/proper_orthogonal_decomposition.cpp +207 -0
  119. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/proper_orthogonal_decomposition/proper_orthogonal_decomposition.h +15 -0
  120. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/radial_basis_functions/radial_basis_functions.cpp +96 -0
  121. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/radial_basis_functions/radial_basis_functions.h +15 -0
  122. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/regression_approximation_models.h +11 -0
  123. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/sparse_grid_collocation/sparse_grid_collocation.cpp +72 -0
  124. quant_kernel-2.9.0/cpp/src/algorithms/regression_approximation/sparse_grid_collocation/sparse_grid_collocation.h +15 -0
  125. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/common/internal_util.h +105 -0
  126. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/common/params.h +15 -0
  127. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/crr/crr.cpp +33 -0
  128. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/crr/crr.h +13 -0
  129. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/implied_tree/derman_kani.cpp +338 -0
  130. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/implied_tree/derman_kani.h +30 -0
  131. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/jarrow_rudd/jarrow_rudd.cpp +30 -0
  132. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/jarrow_rudd/jarrow_rudd.h +13 -0
  133. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/leisen_reimer/leisen_reimer.cpp +50 -0
  134. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/leisen_reimer/leisen_reimer.h +13 -0
  135. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/tian/tian.cpp +31 -0
  136. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/tian/tian.h +13 -0
  137. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/tree_lattice_models.h +13 -0
  138. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/trinomial_tree/trinomial_tree.cpp +86 -0
  139. quant_kernel-2.9.0/cpp/src/algorithms/tree_lattice_methods/trinomial_tree/trinomial_tree.h +13 -0
  140. quant_kernel-2.9.0/cpp/src/common/math_util.h +55 -0
  141. quant_kernel-2.9.0/cpp/src/common/option_util.h +50 -0
  142. quant_kernel-2.9.0/cpp/src/qk_api.cpp +1723 -0
  143. quant_kernel-2.9.0/cpp/tests/test_closed_form.cpp +71 -0
  144. quant_kernel-2.9.0/cpp/tests/test_error_handling.cpp +110 -0
  145. quant_kernel-2.9.0/cpp/tests/test_fdm_iqm_ram_agm_mlm.cpp +200 -0
  146. quant_kernel-2.9.0/cpp/tests/test_fourier.cpp +50 -0
  147. quant_kernel-2.9.0/cpp/tests/test_harness.h +92 -0
  148. quant_kernel-2.9.0/cpp/tests/test_monte_carlo.cpp +48 -0
  149. quant_kernel-2.9.0/cpp/tests/test_tree_lattice.cpp +50 -0
  150. quant_kernel-2.9.0/examples/quickstart.ipynb +113 -0
  151. quant_kernel-2.9.0/fuzztest/CMakeLists.txt +83 -0
  152. quant_kernel-2.9.0/fuzztest/fuzz_adjoint_greeks_models.cpp +77 -0
  153. quant_kernel-2.9.0/fuzztest/fuzz_closed_form_models.cpp +151 -0
  154. quant_kernel-2.9.0/fuzztest/fuzz_finite_difference_models.cpp +185 -0
  155. quant_kernel-2.9.0/fuzztest/fuzz_fourier_transform_models.cpp +149 -0
  156. quant_kernel-2.9.0/fuzztest/fuzz_integral_quadrature_models.cpp +100 -0
  157. quant_kernel-2.9.0/fuzztest/fuzz_machine_learning_models.cpp +82 -0
  158. quant_kernel-2.9.0/fuzztest/fuzz_monte_carlo_models.cpp +145 -0
  159. quant_kernel-2.9.0/fuzztest/fuzz_regression_approximation_models.cpp +78 -0
  160. quant_kernel-2.9.0/fuzztest/fuzz_tree_lattice_models.cpp +135 -0
  161. quant_kernel-2.9.0/pyproject.toml +61 -0
  162. quant_kernel-2.9.0/python/examples/benchmark_scalar_batch_cpp.py +127 -0
  163. quant_kernel-2.9.0/python/examples/demo_accelerator.py +51 -0
  164. quant_kernel-2.9.0/python/examples/demo_pricing.py +17 -0
  165. quant_kernel-2.9.0/python/examples/quantlib_american_ref.cpp +144 -0
  166. quant_kernel-2.9.0/python/examples/quantlib_bsm_ref.cpp +84 -0
  167. quant_kernel-2.9.0/python/examples/quantlib_synthetic_model_ref.cpp +435 -0
  168. quant_kernel-2.9.0/python/examples/run_all_algos.py +217 -0
  169. quant_kernel-2.9.0/python/examples/validate_historical_algo_suite.py +444 -0
  170. quant_kernel-2.9.0/python/examples/validate_historical_american_suite.py +345 -0
  171. quant_kernel-2.9.0/python/examples/validate_historical_batch.py +542 -0
  172. quant_kernel-2.9.0/python/examples/validate_synthetic_model_suite.py +729 -0
  173. quant_kernel-2.9.0/python/quantkernel/__init__.py +42 -0
  174. quant_kernel-2.9.0/python/quantkernel/__init__.pyi +632 -0
  175. quant_kernel-2.9.0/python/quantkernel/_abi.py +14 -0
  176. quant_kernel-2.9.0/python/quantkernel/_loader.py +295 -0
  177. quant_kernel-2.9.0/python/quantkernel/_native_batch.pyx +1728 -0
  178. quant_kernel-2.9.0/python/quantkernel/accelerator.py +1360 -0
  179. quant_kernel-2.9.0/python/quantkernel/engine.py +1796 -0
  180. quant_kernel-2.9.0/python/quantkernel/py.typed +0 -0
  181. quant_kernel-2.9.0/python/tests/conftest.py +10 -0
  182. quant_kernel-2.9.0/python/tests/test_abi_version.py +13 -0
  183. quant_kernel-2.9.0/python/tests/test_accelerator.py +390 -0
  184. quant_kernel-2.9.0/python/tests/test_adjoint_greeks_api.py +48 -0
  185. quant_kernel-2.9.0/python/tests/test_batch_api.py +651 -0
  186. quant_kernel-2.9.0/python/tests/test_closed_form_api.py +89 -0
  187. quant_kernel-2.9.0/python/tests/test_finite_difference_api.py +50 -0
  188. quant_kernel-2.9.0/python/tests/test_fourier_transform_api.py +43 -0
  189. quant_kernel-2.9.0/python/tests/test_integral_quadrature_api.py +76 -0
  190. quant_kernel-2.9.0/python/tests/test_machine_learning_api.py +59 -0
  191. quant_kernel-2.9.0/python/tests/test_monte_carlo_api.py +76 -0
  192. quant_kernel-2.9.0/python/tests/test_parity_guard.py +192 -0
  193. quant_kernel-2.9.0/python/tests/test_perf_regression.py +168 -0
  194. quant_kernel-2.9.0/python/tests/test_regression_approximation_api.py +48 -0
  195. quant_kernel-2.9.0/python/tests/test_tree_lattice_api.py +79 -0
  196. quant_kernel-2.9.0/requirements.txt +3 -0
@@ -0,0 +1,3 @@
1
+ BasedOnStyle: Google
2
+ IndentWidth: 4
3
+ ColumnLimit: 100
@@ -0,0 +1,128 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - "**"
7
+ pull_request:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ build-and-test:
14
+ runs-on: ubuntu-latest
15
+ timeout-minutes: 45
16
+
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v4.1.7
20
+ with:
21
+ persist-credentials: false
22
+
23
+ - name: Setup Python
24
+ uses: actions/setup-python@v5.1.0
25
+ with:
26
+ python-version: "3.11"
27
+
28
+ - name: Install Python dependencies
29
+ run: python -m pip install --upgrade pip && python -m pip install -r requirements.txt
30
+
31
+ - name: Run API parity guard checks
32
+ env:
33
+ PYTHONPATH: python
34
+ run: |
35
+ python -m pytest -q python/tests/test_parity_guard.py
36
+
37
+ - name: Build C++ library
38
+ run: make build
39
+
40
+ - name: Run C++ unit tests
41
+ run: make test-cpp
42
+
43
+ - name: Run Python tests
44
+ run: make test-py
45
+
46
+ - name: Run deterministic batch/perf regression tests
47
+ env:
48
+ PYTHONPATH: python
49
+ QK_LIB_PATH: ${{ github.workspace }}/build/cpp
50
+ PYTHONHASHSEED: "0"
51
+ OMP_NUM_THREADS: "1"
52
+ run: |
53
+ python -m pytest -q python/tests/test_batch_api.py python/tests/test_perf_regression.py
54
+
55
+ - name: Generate benchmark comparison table
56
+ env:
57
+ PYTHONPATH: python
58
+ QK_LIB_PATH: ${{ github.workspace }}/build/cpp
59
+ PYTHONHASHSEED: "0"
60
+ OMP_NUM_THREADS: "1"
61
+ run: |
62
+ cmake --build build -j 4 --target qk_bench_bsm_batch
63
+ python python/examples/benchmark_scalar_batch_cpp.py --n 50000 --repeats 3 | tee benchmark_table.md
64
+ cat benchmark_table.md >> "${GITHUB_STEP_SUMMARY}"
65
+
66
+ - name: Configure fuzz tests
67
+ run: cmake -S fuzztest -B build/fuzztest
68
+
69
+ - name: Build fuzz test binaries
70
+ run: cmake --build build/fuzztest -j 4
71
+
72
+ - name: Run all fuzz test suites under fuzztest/
73
+ timeout-minutes: 15
74
+ shell: bash
75
+ env:
76
+ FUZZTEST_PRNG_SEED: NNMQpT7FLDG9rOgxXhD87HtvjqCtE-6NHWnDn00xICI
77
+ run: |
78
+ set -euo pipefail
79
+ shopt -s nullglob
80
+ sources=(fuzztest/fuzz_*.cpp)
81
+ if (( ${#sources[@]} == 0 )); then
82
+ echo "No fuzz sources found under fuzztest/"
83
+ exit 1
84
+ fi
85
+ for src in "${sources[@]}"; do
86
+ bin="$(basename "${src%.cpp}")"
87
+ exe="./build/fuzztest/${bin}"
88
+ echo "Running ${exe}"
89
+ if [[ ! -x "${exe}" ]]; then
90
+ echo "Expected fuzz binary not found: ${exe}"
91
+ exit 1
92
+ fi
93
+ "${exe}"
94
+ done
95
+
96
+ - name: Build wheel (packaging check)
97
+ run: |
98
+ python -m pip install --upgrade pip build
99
+ python -m build --wheel
100
+
101
+ - name: Validate wheel metadata
102
+ run: |
103
+ python -m pip install --upgrade twine
104
+ python -m twine check dist/*
105
+
106
+ - name: Install built wheel and run end-user smoke test
107
+ run: |
108
+ python -m pip install --force-reinstall dist/*.whl
109
+ python - <<'PY'
110
+ import numpy as np
111
+ from quantkernel import QuantKernel, QK_CALL, QK_PUT
112
+
113
+ qk = QuantKernel()
114
+ bsm = qk.black_scholes_merton_price(100.0, 100.0, 1.0, 0.2, 0.03, 0.01, QK_CALL)
115
+ am = qk.crr_price(100.0, 100.0, 1.0, 0.2, 0.03, 0.01, QK_PUT, 200, 1)
116
+ heston = qk.heston_price_cf(100.0, 100.0, 1.0, 0.03, 0.01, 0.04, 2.0, 0.04, 0.5, -0.7, QK_CALL, 512, 100.0)
117
+ batch = qk.black_scholes_merton_price_batch(
118
+ np.array([100.0, 101.0]),
119
+ np.array([100.0, 100.0]),
120
+ np.array([1.0, 1.0]),
121
+ np.array([0.2, 0.2]),
122
+ np.array([0.03, 0.03]),
123
+ np.array([0.01, 0.01]),
124
+ np.array([QK_CALL, QK_PUT], dtype=np.int32),
125
+ )
126
+ assert bsm > 0.0 and am > 0.0 and heston > 0.0 and batch.shape == (2,)
127
+ print("Wheel smoke test passed.")
128
+ PY
@@ -0,0 +1,81 @@
1
+ name: Wheels
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - "v*"
8
+
9
+ permissions:
10
+ contents: read
11
+ id-token: write
12
+
13
+ jobs:
14
+ build-sdist:
15
+ name: Build sdist
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v4
20
+
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.11"
25
+
26
+ - name: Build sdist
27
+ run: pip install build && python -m build --sdist
28
+
29
+ - name: Upload sdist artifact
30
+ uses: actions/upload-artifact@v4
31
+ with:
32
+ name: sdist
33
+ path: dist/*.tar.gz
34
+
35
+ build-wheels:
36
+ name: Build wheels (${{ matrix.os }})
37
+ runs-on: ${{ matrix.os }}
38
+ strategy:
39
+ fail-fast: false
40
+ matrix:
41
+ os: [ubuntu-latest, macos-14]
42
+
43
+ steps:
44
+ - name: Checkout
45
+ uses: actions/checkout@v4
46
+
47
+ - name: Set up Python
48
+ uses: actions/setup-python@v5
49
+ with:
50
+ python-version: "3.11"
51
+
52
+ - name: Build wheels
53
+ uses: pypa/cibuildwheel@v2.23.3
54
+ env:
55
+ CIBW_OUTPUT_DIR: wheelhouse
56
+
57
+ - name: Upload wheel artifacts
58
+ uses: actions/upload-artifact@v4
59
+ with:
60
+ name: wheels-${{ matrix.os }}
61
+ path: wheelhouse/*.whl
62
+
63
+ publish-pypi:
64
+ name: Publish to PyPI
65
+ needs: [build-sdist, build-wheels]
66
+ if: startsWith(github.ref, 'refs/tags/v')
67
+ runs-on: ubuntu-latest
68
+ environment:
69
+ name: "pypi"
70
+ url: https://pypi.org/p/quant-kernel
71
+
72
+ steps:
73
+ - name: Download all artifacts
74
+ uses: actions/download-artifact@v4
75
+ with:
76
+ pattern: "{sdist,wheels-*}"
77
+ path: dist
78
+ merge-multiple: true
79
+
80
+ - name: Publish wheels
81
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,41 @@
1
+ build/
2
+ cmake-build-*/
3
+ __pycache__/
4
+ *.pyc
5
+ .pytest_cache/
6
+ *.egg-info/
7
+ dist/
8
+ wheelhouse/
9
+ CMakeCache.txt
10
+ CMakeFiles/
11
+ cmake_install.cmake
12
+ .claude
13
+ target/
14
+ rust/runtime/target/
15
+ rust/runtime/target_local/
16
+ rust/runtime/.tmp/
17
+ third_party_source/
18
+
19
+ fuzztest/fuzztest/
20
+ # Editor / OS local files
21
+ .vscode/
22
+ .idea/
23
+ .DS_Store
24
+ *.swp
25
+ *.swo
26
+ claude_session.txt
27
+ # Python local environments / coverage
28
+ .venv/
29
+ venv/
30
+ .env
31
+ .env.*
32
+ .ipynb_checkpoints/
33
+ .mypy_cache/
34
+ .ruff_cache/
35
+ .coverage
36
+ coverage.xml
37
+ htmlcov/
38
+
39
+ compile_commands.json
40
+ python/quantkernel/_native_batch.cpp
41
+ python/quantkernel/_native_batch*.so
@@ -0,0 +1,16 @@
1
+ cmake_minimum_required(VERSION 3.20)
2
+ project(QuantKernel LANGUAGES CXX)
3
+
4
+ set(CMAKE_CXX_STANDARD 17)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
7
+ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
8
+
9
+ option(QK_BUILD_TESTS "Build C++ tests" ON)
10
+ option(QK_BUILD_BENCHMARKS "Build C++ benchmarks" ON)
11
+
12
+ if(QK_BUILD_TESTS)
13
+ enable_testing()
14
+ endif()
15
+
16
+ add_subdirectory(cpp)
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
@@ -0,0 +1,68 @@
1
+ SHELL := /bin/bash
2
+
3
+ BUILD_DIR ?= build
4
+ CMAKE ?= cmake
5
+ PYTHON ?= python3
6
+ PYTEST ?= pytest
7
+ JOBS ?= $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)
8
+
9
+ .DEFAULT_GOAL := quick
10
+
11
+ .PHONY: help configure build build-wheel bench test-cpp test-py test demo quick clean clean-fuzz clean-caches clean-all clean-venv
12
+
13
+ help:
14
+ @echo "Targets:"
15
+ @echo " make quick # Configure, build, C++ tests, Python tests"
16
+ @echo " make build # Configure + C++ build"
17
+ @echo " make build-wheel # Build Python wheel (platform-specific)"
18
+ @echo " make bench # Run scalar/batch benchmark table script"
19
+ @echo " make test # Run C++ and Python tests"
20
+ @echo " make demo # Run Python demo (direct kernel path)"
21
+ @echo " make clean # Remove build artifacts"
22
+ @echo " make clean-fuzz # Remove fuzztest build artifacts"
23
+ @echo " make clean-caches # Remove local caches (pycache/pytest/compile_commands)"
24
+ @echo " make clean-all # clean + clean-fuzz + clean-caches"
25
+ @echo " make clean-venv # Remove local .venv"
26
+
27
+ configure:
28
+ $(CMAKE) -S . -B $(BUILD_DIR) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
29
+
30
+ build: configure
31
+ $(CMAKE) --build $(BUILD_DIR) -j $(JOBS)
32
+
33
+ build-wheel:
34
+ $(PYTHON) -m pip wheel . --no-deps -w dist
35
+
36
+ bench: build
37
+ PYTHONPATH=python QK_LIB_PATH="$(CURDIR)/$(BUILD_DIR)/cpp" $(PYTHON) python/examples/benchmark_scalar_batch_cpp.py --n 50000 --repeats 3
38
+
39
+ test-cpp: build
40
+ ctest --test-dir $(BUILD_DIR) --output-on-failure
41
+
42
+ test-py: build
43
+ PYTHONPATH=python QK_LIB_PATH="$(CURDIR)/$(BUILD_DIR)/cpp" $(PYTEST) -q python/tests
44
+
45
+ test: test-cpp test-py
46
+
47
+ demo: build
48
+ PYTHONPATH=python $(PYTHON) python/examples/demo_pricing.py
49
+
50
+ quick: test
51
+
52
+ clean:
53
+ $(CMAKE) -E rm -rf $(BUILD_DIR)
54
+ $(CMAKE) -E rm -rf target
55
+
56
+ clean-fuzz:
57
+ $(CMAKE) -E rm -rf fuzztest/build
58
+ $(CMAKE) -E rm -rf fuzztest/dist
59
+
60
+ clean-caches:
61
+ $(CMAKE) -E rm -rf .pytest_cache
62
+ find python -type d -name __pycache__ -prune -exec rm -rf {} +
63
+ $(CMAKE) -E rm -f compile_commands.json
64
+
65
+ clean-all: clean clean-fuzz clean-caches
66
+
67
+ clean-venv:
68
+ $(CMAKE) -E rm -rf .venv
@@ -0,0 +1,304 @@
1
+ Metadata-Version: 2.1
2
+ Name: quant-kernel
3
+ Version: 2.9.0
4
+ Summary: High-performance derivative pricing engine with 40+ algorithms
5
+ Keywords: quant,options,pricing,derivatives,finance,hpc
6
+ Author: QuantKernel Contributors
7
+ License: DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
8
+ Version 2, December 2004
9
+
10
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
11
+
12
+ Everyone is permitted to copy and distribute verbatim or modified
13
+ copies of this license document, and changing it is allowed as long
14
+ as the name is changed.
15
+
16
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
17
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
18
+
19
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
20
+ Classifier: Development Status :: 4 - Beta
21
+ Classifier: Intended Audience :: Financial and Insurance Industry
22
+ Classifier: Intended Audience :: Science/Research
23
+ Classifier: Operating System :: MacOS
24
+ Classifier: Operating System :: POSIX :: Linux
25
+ Classifier: Programming Language :: C++
26
+ Classifier: Programming Language :: Python :: 3
27
+ Classifier: Programming Language :: Python :: 3.11
28
+ Classifier: Programming Language :: Python :: 3.12
29
+ Classifier: Programming Language :: Python :: 3.13
30
+ Classifier: Topic :: Office/Business :: Financial
31
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
32
+ Project-URL: Homepage, https://github.com/yluoc/Quant-Kernel
33
+ Project-URL: Repository, https://github.com/yluoc/Quant-Kernel
34
+ Project-URL: Issues, https://github.com/yluoc/Quant-Kernel/issues
35
+ Requires-Python: >=3.11
36
+ Requires-Dist: numpy>=1.24
37
+ Requires-Dist: build>=1.2.2; extra == "dev"
38
+ Requires-Dist: cibuildwheel>=2.23.0; extra == "dev"
39
+ Requires-Dist: pytest>=8.0; extra == "dev"
40
+ Requires-Dist: cupy>=12.0; extra == "gpu"
41
+ Provides-Extra: dev
42
+ Provides-Extra: gpu
43
+ Description-Content-Type: text/markdown
44
+
45
+ # QuantKernel
46
+
47
+ QuantKernel is a C++17 quantitative pricing kernel with Python bindings.
48
+ It focuses on fast scalar and batch option analytics across closed-form, lattice,
49
+ finite-difference, Monte Carlo, Fourier, quadrature, regression-approximation,
50
+ Greek-estimation, and ML-inspired methods.
51
+
52
+ Linux, macOS, and Windows are supported.
53
+
54
+ ## Scope
55
+
56
+ QuantKernel provides:
57
+ - C++ shared library (`libquantkernel.so` / `libquantkernel.dylib` / `libquantkernel.dll`) with C ABI exports.
58
+ - Python package (`quantkernel`) with scalar and batch methods.
59
+ - Optional Python-level accelerator (`QuantAccelerator`) for backend selection (`auto`, `cpu`, `gpu`).
60
+
61
+ ## Install (Not available yet, more test needed)
62
+
63
+ End users (recommended):
64
+
65
+ ```bash
66
+ python -m pip install --upgrade pip
67
+ python -m pip install quant-kernel
68
+ ```
69
+
70
+ This installs a prebuilt wheel on supported platforms and does not require local C++ compilation.
71
+
72
+ ## Implemented Algorithm Families
73
+
74
+ ### Closed-form / Semi-analytical
75
+ - Black-Scholes-Merton
76
+ - Black-76
77
+ - Bachelier
78
+ - Heston characteristic-function pricing
79
+ - Merton jump-diffusion
80
+ - Variance-Gamma characteristic-function pricing
81
+ - SABR (Hagan lognormal IV + Black-76 pricing)
82
+ - Dupire local volatility inversion
83
+
84
+ ### Tree / Lattice
85
+ - CRR
86
+ - Jarrow-Rudd
87
+ - Tian
88
+ - Leisen-Reimer
89
+ - Trinomial tree
90
+ - Derman-Kani style local-vol tree entrypoints:
91
+ - Constant local vol surface (`derman_kani_const_local_vol_price`)
92
+ - Vanilla call-surface driven entrypoint (`derman_kani_call_surface_price`)
93
+
94
+ ### Finite Difference
95
+ - Explicit FD
96
+ - Implicit FD
97
+ - Crank-Nicolson
98
+ - ADI (Douglas, Craig-Sneyd, Hundsdorfer-Verwer)
99
+ - PSOR
100
+
101
+ ### Monte Carlo
102
+ - Standard Monte Carlo
103
+ - Euler-Maruyama
104
+ - Milstein
105
+ - Longstaff-Schwartz
106
+ - Quasi Monte Carlo (Sobol, Halton)
107
+ - Multilevel Monte Carlo
108
+ - Importance Sampling
109
+ - Control Variates
110
+ - Antithetic Variates
111
+ - Stratified Sampling
112
+
113
+ ### Fourier Transform Methods
114
+ - Carr-Madan FFT
115
+ - COS (Fang-Oosterlee)
116
+ - Fractional FFT
117
+ - Lewis Fourier inversion
118
+ - Hilbert transform pricing
119
+
120
+ ### Integral Quadrature
121
+ - Gauss-Hermite
122
+ - Gauss-Laguerre
123
+ - Gauss-Legendre
124
+ - Adaptive quadrature
125
+
126
+ ### Regression Approximation
127
+ - Polynomial Chaos Expansion
128
+ - Radial Basis Functions
129
+ - Sparse Grid Collocation
130
+ - Proper Orthogonal Decomposition
131
+
132
+ ### Greeks / Adjoint Methods
133
+ - Pathwise derivative delta
134
+ - Likelihood ratio delta
135
+ - AAD delta
136
+
137
+ ### Machine-learning Inspired Pricing
138
+ - Deep BSDE
139
+ - PINNs
140
+ - Deep Hedging
141
+ - Neural SDE calibration
142
+
143
+ ## Repository Layout
144
+
145
+ - `cpp/`
146
+ - `include/quantkernel/qk_api.h`: C API declarations
147
+ - `src/`: implementations and API bridge (`qk_api.cpp`)
148
+ - `tests/`: C++ test executables
149
+ - `python/`
150
+ - `quantkernel/`: Python API (`QuantKernel`, `QuantAccelerator`)
151
+ - `tests/`: pytest suite
152
+ - `examples/`: usage and benchmark scripts
153
+ - `Makefile`: common build/test commands
154
+
155
+ ## Requirements
156
+
157
+ - CMake >= 3.14
158
+ - C++17 compiler
159
+ - Python >= 3.11
160
+ - NumPy
161
+
162
+ Optional:
163
+ - CuPy (for GPU backend in accelerator paths)
164
+
165
+ ## Build
166
+
167
+ From project root:
168
+
169
+ ```bash
170
+ python3 -m venv .venv
171
+ source .venv/bin/activate
172
+ python3 -m pip install --upgrade pip
173
+ python3 -m pip install -r requirements.txt
174
+
175
+ cmake -S . -B build
176
+ cmake --build build -j
177
+ ```
178
+
179
+ ## Python Setup (from source checkout)
180
+
181
+ Point Python to the package and shared library:
182
+
183
+ ```bash
184
+ export PYTHONPATH=$PWD/python
185
+ export QK_LIB_PATH=$PWD/build/cpp
186
+ ```
187
+
188
+ Then use:
189
+
190
+ ```python
191
+ from quantkernel import QuantKernel, QK_CALL
192
+
193
+ qk = QuantKernel()
194
+ price = qk.black_scholes_merton_price(
195
+ 100.0, 100.0, 1.0, 0.2, 0.03, 0.01, QK_CALL
196
+ )
197
+ print(price)
198
+ ```
199
+
200
+ ## Batch Usage
201
+
202
+ ```python
203
+ import numpy as np
204
+ from quantkernel import QuantKernel, QK_CALL, QK_PUT
205
+
206
+ qk = QuantKernel()
207
+ n = 100_000
208
+ rng = np.random.default_rng(42)
209
+
210
+ spot = rng.uniform(80.0, 120.0, n)
211
+ strike = rng.uniform(80.0, 120.0, n)
212
+ t = rng.uniform(0.25, 2.0, n)
213
+ vol = rng.uniform(0.1, 0.6, n)
214
+ r = rng.uniform(0.0, 0.08, n)
215
+ q = rng.uniform(0.0, 0.04, n)
216
+ option_type = np.where((np.arange(n) & 1) == 0, QK_CALL, QK_PUT).astype(np.int32)
217
+
218
+ prices = qk.black_scholes_merton_price_batch(spot, strike, t, vol, r, q, option_type)
219
+ print(prices[:3])
220
+ ```
221
+
222
+ ## Derman-Kani Call-Surface API (Python)
223
+
224
+ `derman_kani_call_surface_price` accepts:
225
+ - `surface_strikes`: 1D strikes
226
+ - `surface_maturities`: 1D maturities
227
+ - `surface_call_prices`:
228
+ - 2D array with shape `(len(surface_maturities), len(surface_strikes))`, or
229
+ - flattened 1D array of that size
230
+
231
+ Example:
232
+
233
+ ```python
234
+ from quantkernel import QuantKernel, QK_CALL
235
+
236
+ qk = QuantKernel()
237
+ spot, r, q = 100.0, 0.03, 0.01
238
+ surface_strikes = [80, 90, 100, 110, 120]
239
+ surface_maturities = [0.5, 1.0, 1.5]
240
+
241
+ # Synthetic surface here; in production use observed call prices.
242
+ surface_call_prices = [
243
+ [qk.black_scholes_merton_price(spot, k, tau, 0.2, r, q, QK_CALL) for k in surface_strikes]
244
+ for tau in surface_maturities
245
+ ]
246
+
247
+ price = qk.derman_kani_call_surface_price(
248
+ spot=spot,
249
+ strike=100.0,
250
+ t=1.0,
251
+ r=r,
252
+ q=q,
253
+ option_type=QK_CALL,
254
+ surface_strikes=surface_strikes,
255
+ surface_maturities=surface_maturities,
256
+ surface_call_prices=surface_call_prices,
257
+ steps=20,
258
+ )
259
+ print(price)
260
+ ```
261
+
262
+ If `QK_LIB_PATH` is unset, the package also searches for a bundled shared library from an installed wheel.
263
+
264
+ ## Testing
265
+
266
+ From project root:
267
+
268
+ ```bash
269
+ make test-cpp
270
+ make test-py
271
+ # or
272
+ make quick
273
+ ```
274
+
275
+ Direct commands:
276
+
277
+ ```bash
278
+ ctest --test-dir build --output-on-failure
279
+ PYTHONPATH=python QK_LIB_PATH=build/cpp pytest -q python/tests
280
+ ```
281
+
282
+ ## Benchmark
283
+
284
+ ```bash
285
+ PYTHONPATH=python QK_LIB_PATH=build/cpp \
286
+ python3 python/examples/benchmark_scalar_batch_cpp.py --n 50000 --repeats 3
287
+ ```
288
+
289
+ ## Error Handling
290
+
291
+ ### C API
292
+ - Batch functions return ABI error codes (`QK_OK`, `QK_ERR_NULL_PTR`, `QK_ERR_BAD_SIZE`, `QK_ERR_INVALID_INPUT`, etc.).
293
+ - Use `qk_get_last_error()` for thread-local error detail.
294
+
295
+ ### Python API
296
+ - Raises typed exceptions:
297
+ - `QKError`
298
+ - `QKNullPointerError`
299
+ - `QKBadSizeError`
300
+ - `QKInvalidInputError`
301
+
302
+ ## License
303
+
304
+ `LICENSE` (WTFPL).