sdevpy 1.0.7__tar.gz → 1.0.8__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 (224) hide show
  1. {sdevpy-1.0.7 → sdevpy-1.0.8}/PKG-INFO +2 -1
  2. {sdevpy-1.0.7 → sdevpy-1.0.8}/pyproject.toml +9 -4
  3. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/analytics/americantree.py +4 -5
  4. sdevpy-1.0.8/sdevpy/analytics/bachelier.py +140 -0
  5. sdevpy-1.0.8/sdevpy/analytics/black.py +105 -0
  6. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/datasets.py +1 -1
  7. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/keras/learningmodel.py +2 -2
  8. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/keras/learningschedules.py +2 -1
  9. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/market/correlations.py +1 -1
  10. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/market/eqforward.py +1 -1
  11. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/market/eqvolsurface.py +14 -3
  12. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/market/fixings.py +4 -4
  13. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/market/spot.py +1 -1
  14. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/market/yieldcurve.py +2 -2
  15. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/rand/pathconstruction.py +1 -1
  16. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/mcpricer.py +1 -1
  17. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/mcrun.py +2 -2
  18. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/payoffs/basic.py +2 -2
  19. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/payoffs/exotics.py +1 -1
  20. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/pde/forwardpde.py +1 -1
  21. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/aad/aad_mc.py +2 -1
  22. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/aad/aad_mc_nd.py +1 -1
  23. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/datafiles.py +1 -1
  24. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/set_limits.py +2 -4
  25. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/stovol/stovolgen.py +3 -3
  26. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/stovol/stovolplot.py +1 -2
  27. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/stovol/stovoltrain.py +3 -3
  28. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/stovolinverse/stovolinvgen.py +4 -3
  29. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/stovolinverse/stovolinvtrain.py +3 -3
  30. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/update_db.py +1 -6
  31. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test.py +2 -2
  32. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_algos.py +1 -1
  33. sdevpy-1.0.8/sdevpy/tests/test_analytics.py +132 -0
  34. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_dates.py +3 -3
  35. sdevpy-1.0.8/sdevpy/tests/test_impliedvol.py +172 -0
  36. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_interpolation.py +0 -1
  37. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_mc.py +1 -1
  38. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_pde.py +1 -1
  39. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_timegrids.py +1 -1
  40. sdevpy-1.0.8/sdevpy/tests/test_utils.py +67 -0
  41. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_yieldcurves.py +1 -1
  42. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/timeseries/cointegration.py +1 -4
  43. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/book.py +1 -1
  44. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/dates.py +1 -1
  45. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/scalendar.py +2 -3
  46. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/timegrids.py +2 -2
  47. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/impliedvol_calib.py +36 -24
  48. {sdevpy-1.0.7/sdevpy/analytics → sdevpy-1.0.8/sdevpy/volatility/impliedvol/models}/fbsabr.py +3 -3
  49. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/models/gsvi.py +7 -3
  50. sdevpy-1.0.8/sdevpy/volatility/impliedvol/models/logmix.py +459 -0
  51. {sdevpy-1.0.7/sdevpy/analytics → sdevpy-1.0.8/sdevpy/volatility/impliedvol/models}/mcheston.py +2 -2
  52. {sdevpy-1.0.7/sdevpy/analytics → sdevpy-1.0.8/sdevpy/volatility/impliedvol/models}/mcsabr.py +5 -5
  53. {sdevpy-1.0.7/sdevpy/analytics → sdevpy-1.0.8/sdevpy/volatility/impliedvol/models}/mczabr.py +4 -4
  54. {sdevpy-1.0.7/sdevpy/analytics → sdevpy-1.0.8/sdevpy/volatility/impliedvol/models}/sabr.py +14 -11
  55. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/models/tssvi1.py +71 -19
  56. sdevpy-1.0.8/sdevpy/volatility/impliedvol/models/tssvi2.py +183 -0
  57. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/optionsurface.py +2 -2
  58. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/zerosurface.py +24 -59
  59. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/localvol/localvol.py +1 -1
  60. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/localvol/localvol_calib.py +1 -1
  61. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/localvol/localvol_factory.py +1 -1
  62. {sdevpy-1.0.7/sdevpy/volsurfacegen → sdevpy-1.0.8/sdevpy/volatility/mlsurfacegen}/fbsabrgenerator.py +4 -4
  63. {sdevpy-1.0.7/sdevpy/volsurfacegen → sdevpy-1.0.8/sdevpy/volatility/mlsurfacegen}/mchestongenerator.py +4 -4
  64. {sdevpy-1.0.7/sdevpy/volsurfacegen → sdevpy-1.0.8/sdevpy/volatility/mlsurfacegen}/mcsabrgenerator.py +4 -4
  65. {sdevpy-1.0.7/sdevpy/volsurfacegen → sdevpy-1.0.8/sdevpy/volatility/mlsurfacegen}/mczabrgenerator.py +4 -4
  66. {sdevpy-1.0.7/sdevpy/volsurfacegen → sdevpy-1.0.8/sdevpy/volatility/mlsurfacegen}/sabrgenerator.py +8 -8
  67. {sdevpy-1.0.7/sdevpy/volsurfacegen → sdevpy-1.0.8/sdevpy/volatility/mlsurfacegen}/smilegenerator.py +1 -1
  68. {sdevpy-1.0.7/sdevpy/volsurfacegen → sdevpy-1.0.8/sdevpy/volatility/mlsurfacegen}/stovolfactory.py +5 -5
  69. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy.egg-info/PKG-INFO +2 -1
  70. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy.egg-info/SOURCES.txt +31 -28
  71. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy.egg-info/requires.txt +1 -0
  72. sdevpy-1.0.8/sdevpy.egg-info/top_level.txt +1 -0
  73. sdevpy-1.0.7/sdevpy/analytics/bachelier.py +0 -82
  74. sdevpy-1.0.7/sdevpy/analytics/black.py +0 -64
  75. sdevpy-1.0.7/sdevpy/tests/test_impliedvol.py +0 -100
  76. sdevpy-1.0.7/sdevpy/tests/test_utils.py +0 -67
  77. sdevpy-1.0.7/sdevpy.egg-info/top_level.txt +0 -2
  78. {sdevpy-1.0.7 → sdevpy-1.0.8}/README.md +0 -0
  79. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/__init__.py +0 -0
  80. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/analytics/__init__.py +0 -0
  81. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/cointegration/__init__.py +0 -0
  82. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/cointegration/back_testing.py +0 -0
  83. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/cointegration/coint_trading.py +0 -0
  84. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/cointegration/data_io.py +0 -0
  85. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/cointegration/mean_reversion.py +0 -0
  86. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/cointegration/model_settings.py +0 -0
  87. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/cointegration/utils.py +0 -0
  88. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/__init__.py +0 -0
  89. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/keras/__init__.py +0 -0
  90. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/keras/callbacks.py +0 -0
  91. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/keras/topology.py +0 -0
  92. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/__init__.py +0 -0
  93. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/attention.py +0 -0
  94. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/chat.py +0 -0
  95. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/datasets.py +0 -0
  96. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/gpt.py +0 -0
  97. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/instructions.py +0 -0
  98. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/modelconverter.py +0 -0
  99. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/textgen.py +0 -0
  100. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/tokenizers.py +0 -0
  101. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/machinelearning/llms/training.py +0 -0
  102. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/market/__init__.py +0 -0
  103. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/__init__.py +0 -0
  104. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/constants.py +0 -0
  105. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/integration.py +0 -0
  106. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/interpolation.py +0 -0
  107. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/metrics.py +0 -0
  108. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/optimization.py +0 -0
  109. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/rand/__init__.py +0 -0
  110. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/rand/correlations.py +0 -0
  111. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/rand/rng.py +0 -0
  112. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/regression.py +0 -0
  113. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/sets.py +0 -0
  114. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/specialfunctions.py +0 -0
  115. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/maths/tridiag.py +0 -0
  116. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/models/__init__.py +0 -0
  117. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/models/assetmodels.py +0 -0
  118. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/models/multiasset_heston.py +0 -0
  119. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/__init__.py +0 -0
  120. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/pathgenerator.py +0 -0
  121. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/payoffs/__init__.py +0 -0
  122. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/payoffs/cashflows.py +0 -0
  123. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/payoffs/vanillas.py +0 -0
  124. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/montecarlo/smoothers.py +0 -0
  125. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/pde/__init__.py +0 -0
  126. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/pde/pdeschemes.py +0 -0
  127. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/__init__.py +0 -0
  128. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/aad/__init__.py +0 -0
  129. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/chat_gpt2.py +0 -0
  130. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/__init__.py +0 -0
  131. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/ch2_working_with_text.py +0 -0
  132. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/ch3_coding_attention.py +0 -0
  133. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/ch4_gpt_model.py +0 -0
  134. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/ch5_loadgpt2.py +0 -0
  135. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/ch5_pretraining.py +0 -0
  136. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/ch7_instruction_finetuning.py +0 -0
  137. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/raschka_datasetloader.py +0 -0
  138. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/raschka_dnn.py +0 -0
  139. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/raschka/raschka_gpt_download.py +0 -0
  140. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/stovol/__init__.py +0 -0
  141. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/projects/stovolinverse/__init__.py +0 -0
  142. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/settings.py +0 -0
  143. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tensorflow/__init__.py +0 -0
  144. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tensorflow/tf_black.py +0 -0
  145. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tensorflow/tf_metrics.py +0 -0
  146. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/__init__.py +0 -0
  147. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_localvol.py +0 -0
  148. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tests/test_marketdata.py +0 -0
  149. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/__init__.py +0 -0
  150. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_lets_be_rational/__init__.py +0 -0
  151. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_lets_be_rational/constants.py +0 -0
  152. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_lets_be_rational/erf_cody.py +0 -0
  153. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_lets_be_rational/exceptions.py +0 -0
  154. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_lets_be_rational/lets_be_rational.py +0 -0
  155. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_lets_be_rational/normaldistribution.py +0 -0
  156. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_lets_be_rational/numba_helper.py +0 -0
  157. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_lets_be_rational/rationalcubic.py +0 -0
  158. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/__init__.py +0 -0
  159. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black/__init__.py +0 -0
  160. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black/greeks/__init__.py +0 -0
  161. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black/greeks/analytical.py +0 -0
  162. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black/greeks/numerical.py +0 -0
  163. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black/implied_volatility.py +0 -0
  164. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes/__init__.py +0 -0
  165. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes/greeks/__init__.py +0 -0
  166. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes/greeks/analytical.py +0 -0
  167. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes/greeks/numerical.py +0 -0
  168. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes/implied_volatility.py +0 -0
  169. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes_merton/__init__.py +0 -0
  170. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/__init__.py +0 -0
  171. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/analytical.py +0 -0
  172. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/numerical.py +0 -0
  173. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/black_scholes_merton/implied_volatility.py +0 -0
  174. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/helpers/__init__.py +0 -0
  175. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/helpers/constants.py +0 -0
  176. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/helpers/distributions.py +0 -0
  177. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/helpers/doctest_helper.py +0 -0
  178. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/helpers/exceptions.py +0 -0
  179. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/helpers/numerical_greeks.py +0 -0
  180. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/__init__.py +0 -0
  181. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black/__init__.py +0 -0
  182. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/__init__.py +0 -0
  183. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/analytical.py +0 -0
  184. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/numerical.py +0 -0
  185. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black/implied_volatility.py +0 -0
  186. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/__init__.py +0 -0
  187. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/__init__.py +0 -0
  188. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/analytical.py +0 -0
  189. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/numerical.py +0 -0
  190. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/implied_volatility.py +0 -0
  191. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/__init__.py +0 -0
  192. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/__init__.py +0 -0
  193. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/analytical.py +0 -0
  194. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/numerical.py +0 -0
  195. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/implied_volatility.py +0 -0
  196. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/timeseries/__init__.py +0 -0
  197. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/timeseries/backtesting.py +0 -0
  198. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/timeseries/meanreversion.py +0 -0
  199. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/timeseries/timeseriestools.py +0 -0
  200. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/tree}/__init__.py +0 -0
  201. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/tree/trees.py +0 -0
  202. {sdevpy-1.0.7/sdevpy/tree → sdevpy-1.0.8/sdevpy/utilities}/__init__.py +0 -0
  203. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/algos.py +0 -0
  204. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/clipboard.py +0 -0
  205. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/constants.py +0 -0
  206. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/filemanager.py +0 -0
  207. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/jsonmanager.py +0 -0
  208. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/network.py +0 -0
  209. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/pydotnet.py +0 -0
  210. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/speriods.py +0 -0
  211. {sdevpy-1.0.7/sdevpy/tools → sdevpy-1.0.8/sdevpy/utilities}/timer.py +0 -0
  212. /sdevpy-1.0.7/sdevpy/tools/utils.py → /sdevpy-1.0.8/sdevpy/utilities/tools.py +0 -0
  213. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/__init__.py +0 -0
  214. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/__init__.py +0 -0
  215. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/impliedvol.py +0 -0
  216. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/models/__init__.py +0 -0
  217. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/models/biexp.py +0 -0
  218. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/models/cubicvol.py +0 -0
  219. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/models/svi.py +0 -0
  220. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/impliedvol/models/vsvi.py +0 -0
  221. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy/volatility/localvol/__init__.py +0 -0
  222. {sdevpy-1.0.7/sdevpy/volsurfacegen → sdevpy-1.0.8/sdevpy/volatility/mlsurfacegen}/__init__.py +0 -0
  223. {sdevpy-1.0.7 → sdevpy-1.0.8}/sdevpy.egg-info/dependency_links.txt +0 -0
  224. {sdevpy-1.0.7 → sdevpy-1.0.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdevpy
3
- Version: 1.0.7
3
+ Version: 1.0.8
4
4
  Summary: Python package for Finance
5
5
  Author-email: Sebastien Gurrieri <sebgur@gmail.com>
6
6
  Project-URL: Git page, https://github.com/sebgur/SDev.Python
@@ -17,6 +17,7 @@ Requires-Dist: holidays
17
17
  Requires-Dist: pandas_market_calendars
18
18
  Requires-Dist: openpyxl
19
19
  Requires-Dist: colorlog
20
+ Requires-Dist: scikit-learn
20
21
 
21
22
  # SDev.Python
22
23
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sdevpy"
7
- version = "1.0.7"
7
+ version = "1.0.8"
8
8
  license-files = []
9
9
  authors = [{ name="Sebastien Gurrieri", email="sebgur@gmail.com" }]
10
10
  description = "Python package for Finance"
@@ -15,15 +15,20 @@ classifiers = [
15
15
  "Operating System :: OS Independent",
16
16
  ]
17
17
  dependencies = ["pandas", "numpy", "scipy", "matplotlib", "holidays",
18
- "pandas_market_calendars", "openpyxl", "colorlog"
18
+ "pandas_market_calendars", "openpyxl", "colorlog",
19
+ "scikit-learn"
19
20
  ]
20
21
  #dependencies = ["pyperclip", "tensorflow", "scikit-learn",
21
22
  # "tensorflow_probability", "silence_tensorflow"]
22
23
 
23
24
  [tool.setuptools.packages.find]
24
25
  where = ["."]
25
- include = ["sdevpy*", "notebooks*"] # Only include these
26
- #exclude = ["notebooks*", "spreadsheets*"] # Exclude these
26
+ include = ["sdevpy*"] # Only include these
27
+ exclude = ["sdevpy/volatility/impliedvol/models/tssvi2*"]
28
+ #exclude = ["notebooks*", "spreadsheets*"] # Exclude these
29
+
30
+ [tool.setuptools.package-data]
31
+ "sdevpy" = ["datasets/**/*", "notebooks/**/*.ipynb"]
27
32
 
28
33
  [tool.ruff]
29
34
  line-length = 120
@@ -7,15 +7,15 @@ from sdevpy.tree import trees
7
7
  from sdevpy.tree.trees import Payoff
8
8
 
9
9
 
10
- def option_price(ttm, strike, is_call, is_american, spot, vol, rf_rate, div_rate, disc_rate,
11
- method='trinomial', n_steps = 30):
10
+ def option_price(ttm: float, strike: float, is_call: bool, is_american: bool, spot: float, vol: float,
11
+ rf_rate: float, div_rate: float, disc_rate: float, method: str='trinomial', n_steps: int=30):
12
12
  """ Price of an American option using binomial or trinomial trees under Black-Scholes model """
13
13
  payoff = Payoff(ttm, strike, is_call, is_american)
14
14
  return price(payoff, spot, vol, rf_rate, div_rate, disc_rate, method, n_steps)
15
15
 
16
16
 
17
- def price(payoff, spot, vol, rf_rate, div_rate, disc_rate,
18
- method='trinomial', n_steps = 30):
17
+ def price(payoff, spot: float, vol: float, rf_rate: float, div_rate: float, disc_rate: float,
18
+ method: str='trinomial', n_steps: int=30):
19
19
  """ Price of a payoff using binomial or trinomial trees under Black-Scholes model """
20
20
  if method == 'binomial':
21
21
  tree = trees.BinomialTree(n_steps)
@@ -86,7 +86,6 @@ if __name__ == "__main__":
86
86
  bin_p = [100.0 * (x / cf - 1.0) for x in bin_p]
87
87
  tri_p = [100.0 * (x / cf - 1.0) for x in tri_p]
88
88
 
89
-
90
89
  # Plot the results
91
90
  plt.figure(figsize=(10, 6))
92
91
  plt.plot(bin_t, bin_p, label='Binomial Tree Price')
@@ -0,0 +1,140 @@
1
+ """ Utilities for Bachelier model """
2
+ import numpy as np
3
+ import numpy.typing as npt
4
+ from scipy.stats import norm
5
+ from scipy.optimize import minimize_scalar
6
+
7
+
8
+ def price(expiry: npt.ArrayLike, strike: npt.ArrayLike, is_call: npt.ArrayLike, fwd: npt.ArrayLike,
9
+ vol: npt.ArrayLike) -> npt.ArrayLike:
10
+ """ Option price under the Bachelier model """
11
+ stdev = vol * expiry**0.5
12
+ d = (fwd - strike) / stdev
13
+ wd = np.where(is_call, d, -d)
14
+ # wd = d if is_call else -d
15
+ return stdev * (wd * norm.cdf(wd) + norm.pdf(d))
16
+
17
+
18
+ def price_straddles(expiry: npt.ArrayLike, strike: npt.ArrayLike, fwd: npt.ArrayLike,
19
+ vol: npt.ArrayLike) -> npt.ArrayLike:
20
+ """ Straddle price under the Bachelier model.
21
+ Note: we could improve the speed by writing the code in-line instead of
22
+ calling the price() function twice """
23
+ expiries_ = np.asarray(expiry).reshape(-1, 1)
24
+ prices = []
25
+ for i, exp_row in enumerate(expiries_):
26
+ k_prices = []
27
+ for j, k in enumerate(strike[i]):
28
+ iv = vol[i, j]
29
+ call_price = price(exp_row, k, True, fwd, iv)
30
+ put_price = price(exp_row, k, False, fwd, iv)
31
+ k_prices.append(call_price[0] + put_price[0])
32
+ prices.append(k_prices)
33
+
34
+ return np.asarray(prices)
35
+
36
+
37
+ def implied_vol_jaeckel(expiry: float, strike: float, is_call: bool, fwd: float, fwd_price: float) -> float:
38
+ """ P. Jaeckel's method in "Implied Normal Volatility", 6th Jun. 2017.
39
+ This is the original, non-vectorized. """
40
+ m = fwd - strike
41
+ abs_m = np.abs(m)
42
+ # Special case at ATM
43
+ if abs_m < 1e-8:
44
+ return fwd_price * np.sqrt(2.0 * np.pi) / np.sqrt(expiry)
45
+
46
+ # General case
47
+ tilde_phi_star_c = -0.001882039271
48
+ theta = 1.0 if is_call else -1.0
49
+
50
+ tilde_phi_star = -np.abs(fwd_price - np.maximum(theta * m, 0.0)) / abs_m
51
+ em5 = 1e-5
52
+
53
+ if tilde_phi_star < tilde_phi_star_c:
54
+ g = 1.0 / (tilde_phi_star - 0.5)
55
+ g2 = g**2
56
+ em3 = 1e-3
57
+ num = 0.032114372355 - g2 * (0.016969777977 - g2 * (2.6207332461 * em3
58
+ - 9.6066952861 * em5 * g2))
59
+ den = 1.0 - g2 * (0.6635646938 - g2 * (0.14528712196 - 0.010472855461 * g2))
60
+ eta_bar = num / den
61
+ xb = g * (eta_bar * g2 + 1.0 / np.sqrt(2.0 * np.pi))
62
+ else:
63
+ h = np.sqrt(-np.log(-tilde_phi_star))
64
+ num = 9.4883409779 - h * (9.6320903635 - h * (0.58556997323 + 2.1464093351 * h))
65
+ den = 1.0 - h * (0.65174820867 + h * (1.5120247828 + 6.6437847132 * em5 * h))
66
+ xb = num / den
67
+
68
+ q = (norm.cdf(xb) + norm.pdf(xb) / xb - tilde_phi_star) / norm.pdf(xb)
69
+ xb2 = xb**2
70
+ num = 3.0 * q * xb2 * (2.0 - q * xb * (2.0 + xb2))
71
+ den = 6.0 + q * xb * (-12.0 + xb * (6.0 * q + xb * (-6.0 + q * xb * (3.0 + xb2))))
72
+ xs = xb + num / den
73
+ sigma = abs_m / (np.abs(xs) * np.sqrt(expiry))
74
+ return sigma
75
+
76
+
77
+ def implied_vol(expiry: npt.ArrayLike, strike: npt.ArrayLike, is_call: npt.ArrayLike,
78
+ fwd: npt.ArrayLike, fwd_price: npt.ArrayLike) -> npt.NDArray[np.float64]:
79
+ """ P. Jaeckel's method in "Implied Normal Volatility", 6th Jun. 2017.
80
+ Vectorized version (vectorization not in Jaeckel). """
81
+ strike = np.asarray(strike, dtype=float)
82
+ fwd_price = np.asarray(fwd_price, dtype=float)
83
+ is_call = np.asarray(is_call, dtype=bool)
84
+
85
+ #### ATM branch ####
86
+ m = fwd - strike
87
+ abs_m = np.abs(m)
88
+ atm_mask = (abs_m < 1e-8)
89
+ atm_result = fwd_price * np.sqrt(2.0 * np.pi / expiry)
90
+
91
+ #### General case ####
92
+ tilde_phi_star_c = -0.001882039271
93
+ theta = np.where(is_call, 1.0, -1.0)
94
+ tilde_phi_star = -np.abs(fwd_price - np.maximum(theta * m, 0.0)) / np.where(atm_mask, 1.0, abs_m)
95
+ em5 = 1e-5
96
+ mask_low = (tilde_phi_star < tilde_phi_star_c)
97
+
98
+ # Branch = lower
99
+ g = 1.0 / (tilde_phi_star - 0.5)
100
+ g2 = g**2
101
+ em3 = 1e-3
102
+ num_low = 0.032114372355 - g2 * (0.016969777977 - g2 * (2.6207332461 * em3 - 9.6066952861 * em5 * g2))
103
+ den_low = 1.0 - g2 * (0.6635646938 - g2 * (0.14528712196 - 0.010472855461 * g2))
104
+ eta_bar = num_low / den_low
105
+ xb_low = g * (eta_bar * g2 + 1.0 / np.sqrt(2.0 * np.pi))
106
+
107
+ # Branch = higher
108
+ # Note: substitute a safe value where mask_low is True to avoid sqrt(log(large))
109
+ safe_tps = np.where(mask_low, -0.001, tilde_phi_star)
110
+ h = np.sqrt(-np.log(-safe_tps))
111
+ num_high = 9.4883409779 - h * (9.6320903635 - h * (0.58556997323 + 2.1464093351 * h))
112
+ den_high = 1.0 - h * (0.65174820867 + h * (1.5120247828 + 6.6437847132 * em5 * h))
113
+ xb_high = num_high / den_high
114
+
115
+ # Join lower/higher
116
+ xb = np.where(mask_low, xb_low, xb_high)
117
+ q = (norm.cdf(xb) + norm.pdf(xb) / xb - tilde_phi_star) / norm.pdf(xb)
118
+ xb2 = xb**2
119
+ num = 3.0 * q * xb2 * (2.0 - q * xb * (2.0 + xb2))
120
+ den = 6.0 + q * xb * (-12.0 + xb * (6.0 * q + xb * (-6.0 + q * xb * (3.0 + xb2))))
121
+ xs = xb + num / den
122
+ sigma = abs_m / (np.abs(xs) * np.sqrt(expiry))
123
+
124
+ # Join ATM/OTM
125
+ return np.where(atm_mask, atm_result, sigma)
126
+
127
+
128
+ def implied_vol_solve(expiry: float, strike: float, is_call: bool, fwd: float, fwd_price: float) -> float:
129
+ """ Direct method by numerical inversion using Brent """
130
+ options = {'xtol': 1e-4, 'maxiter': 100, 'disp': False}
131
+ xmin = 1e-6
132
+ xmax = 1.0
133
+
134
+ def error(vol):
135
+ premium = price(expiry, strike, is_call, fwd, vol)
136
+ return (premium - fwd_price) ** 2
137
+
138
+ res = minimize_scalar(fun=error, bracket=(xmin, xmax), options=options, method='brent')
139
+
140
+ return res.x
@@ -0,0 +1,105 @@
1
+ """ Utilities for Black-Scholes model """
2
+ import numpy as np
3
+ import numpy.typing as npt
4
+ from scipy.stats import norm
5
+ from scipy.optimize import minimize_scalar
6
+ from sdevpy.thirdparty.py_vollib.black import implied_volatility as jaeckel
7
+ from sdevpy.utilities.tools import isiterable
8
+
9
+
10
+ def price(expiry: npt.ArrayLike, strike: npt.ArrayLike, is_call: npt.ArrayLike, fwd: npt.ArrayLike,
11
+ vol: npt.ArrayLike) -> npt.NDArray[np.float64]:
12
+ """ Option price under the Black-Scholes model """
13
+ # w = 1.0 if is_call else -1.0
14
+ w = np.where(is_call, 1.0, -1.0)
15
+ s = vol * np.sqrt(expiry)
16
+ d1 = np.log(fwd / strike) / s + 0.5 * s
17
+ d2 = d1 - s
18
+ return w * (fwd * norm.cdf(w * d1) - strike * norm.cdf(w * d2))
19
+
20
+
21
+ def implied_vol(expiry: float, strike: float, is_call: bool, fwd: float, fwd_price: float) -> float:
22
+ """ Direct method by numerical inversion using Brent.
23
+ Non-vectorized due to solver. """
24
+ options = {'xtol': 1e-4, 'maxiter': 100, 'disp': False}
25
+ xmin = 1e-6
26
+ xmax = 1.0
27
+
28
+ def error(vol):
29
+ premium = price(expiry, strike, is_call, fwd, vol)
30
+ return (premium - fwd_price) ** 2
31
+
32
+ res = minimize_scalar(fun=error, bracket=(xmin, xmax), options=options, method='brent')
33
+ return res.x
34
+
35
+
36
+ def implied_vols(expiry: float, strike: npt.ArrayLike, is_call: bool, fwd: float,
37
+ fwd_price: npt.ArrayLike) -> npt.ArrayLike:
38
+ """ Black implied volatility for vector of strikes/prices """
39
+ if isiterable(strike) and isiterable(fwd_price):
40
+ ivs = [implied_vol(expiry, k, is_call, fwd, p) for k, p in zip(strike, fwd_price, strict=True)]
41
+ return np.asarray(ivs)
42
+ elif not isiterable(strike) and not isiterable(fwd_price):
43
+ return implied_vol(expiry, strike, is_call, fwd, fwd_price)
44
+ else:
45
+ raise ValueError("Incompatible shapes between strikes and prices")
46
+
47
+
48
+ def implied_vol_newton(expiry: float, strike: npt.ArrayLike, is_call: bool, fwd: float,
49
+ fwd_price: npt.ArrayLike, tol: float=1e-8, max_iter: int=50) -> npt.ArrayLike:
50
+ """ Using vectorized Newton-Raphson, with faster convergence than Brent.
51
+ However, this method can struggle for very small vegas, so we may want to switch
52
+ to another method (maybe Brent above) below a certain vega threshold.
53
+ Or to switch to Halley's method.
54
+ To be investigated if speed becomes a bottleneck or Brent's method has issues. """
55
+ strike = np.asarray(strike, dtype=float)
56
+ fwd_price = np.asarray(fwd_price, dtype=float)
57
+ vol = np.full_like(fwd_price, 0.25) # Initial guess: flat 25%
58
+ sqrt_t = np.sqrt(expiry)
59
+ for _ in range(max_iter):
60
+ s = vol * sqrt_t
61
+ d1 = np.log(fwd / strike) / s + 0.5 * s
62
+ vega = fwd * norm.pdf(d1) * sqrt_t
63
+ diff = price(expiry, strike, is_call, fwd, vol) - fwd_price
64
+ vol -= diff / vega
65
+ vol = np.maximum(vol, 1e-8) # Keep vol positive
66
+ if np.all(np.abs(diff) < tol):
67
+ break
68
+
69
+ # if len(strike) == 1 and len(fwd_price) == 1 and len(vol) == 1: # Return a scalar if inputs are scalar
70
+ # return vol[0]
71
+ # else:
72
+ # return vol
73
+ return (vol.item() if vol.ndim == 0 or vol.size ==1 else vol)
74
+
75
+
76
+ def implied_vol_jaeckel(expiry: float, strike: float, is_call: bool, fwd: float, fwd_price: float) -> float:
77
+ """ Black-Scholes implied volatility using P. Jaeckel's 'Let's be rational' method,
78
+ from package py_vollib. Install with pip install py_vollib or at
79
+ https://pypi.org/project/py_vollib/. Unfortunately we found it has instabilities
80
+ near ATM. """
81
+ flag = 'c' if is_call else 'p'
82
+ p = fwd_price
83
+ iv = jaeckel.implied_volatility_of_undiscounted_option_price(p, fwd, strike, expiry, flag)
84
+ return iv
85
+
86
+
87
+ if __name__ == "__main__":
88
+ EXPIRY = 1.0
89
+ VOL = 0.25
90
+ IS_CALL = True
91
+ NUM_POINTS = 100
92
+ # FWD = 100
93
+ # K = 100
94
+ # p = price(EXPIRY, K, IS_CALL, FWD, VOL)
95
+ # iv = implied_vol(EXPIRY, K, IS_CALL, FWD, p)
96
+ # print(iv)
97
+ f_space = np.linspace(100, 120, NUM_POINTS)
98
+ k_space = np.linspace(20, 2180, NUM_POINTS)
99
+ prices = price(EXPIRY, k_space, IS_CALL, f_space, VOL)
100
+ # print(prices)
101
+ implied_vols = []
102
+ for i, k in enumerate(k_space):
103
+ implied_vols.append(implied_vol(EXPIRY, k, IS_CALL, f_space[i], prices[i]))
104
+
105
+ # print(implied_vols)
@@ -3,7 +3,7 @@ import os
3
3
  import numpy as np
4
4
  import numpy.typing as npt
5
5
  import pandas as pd
6
- from sdevpy.tools import filemanager
6
+ from sdevpy.utilities import filemanager
7
7
 
8
8
 
9
9
  def prepare_sets(inputs: npt.ArrayLike, outputs: npt.ArrayLike, train_percent: float) -> npt.ArrayLike:
@@ -5,8 +5,8 @@ from sklearn.preprocessing import StandardScaler
5
5
  import tensorflow as tf
6
6
  import joblib
7
7
  import absl.logging
8
- from sdevpy.tools import jsonmanager
9
- from sdevpy.tools import filemanager
8
+ from sdevpy.utilities import jsonmanager
9
+ from sdevpy.utilities import filemanager
10
10
 
11
11
  class LearningModel:
12
12
  """ Wrapper class for machine learning models, including scalers, and simplifying
@@ -1,7 +1,8 @@
1
1
  """ Custom learning schedules """
2
2
  import numpy as np
3
3
  import tensorflow as tf
4
- from sdevpy.tools.constants import TWO_PI
4
+ from sdevpy.utilities.constants import TWO_PI
5
+
5
6
 
6
7
  # Custom learning rate scheduler, exponentially decreases between given values
7
8
  class FlooredExponentialDecay(tf.keras.optimizers.schedules.LearningRateSchedule):
@@ -2,7 +2,7 @@ from pathlib import Path
2
2
  import numpy as np
3
3
  import pandas as pd
4
4
  import datetime as dt
5
- from sdevpy.tools import dates as dts
5
+ from sdevpy.utilities import dates as dts
6
6
 
7
7
 
8
8
  def get_correlations(names: list[str], date: dt.datetime, **kwargs):
@@ -2,7 +2,7 @@ import os, json
2
2
  import datetime as dt
3
3
  import numpy as np
4
4
  from pathlib import Path
5
- from sdevpy.tools import dates, timegrids
5
+ from sdevpy.utilities import dates, timegrids
6
6
  from sdevpy.maths import interpolation as itp
7
7
  from sdevpy.market import yieldcurve as ycrv
8
8
  from sdevpy.market.spot import get_spots
@@ -2,7 +2,9 @@ import os, json, logging
2
2
  import datetime as dt
3
3
  import numpy as np
4
4
  from pathlib import Path
5
- from sdevpy.tools import dates
5
+ from sdevpy.utilities import dates
6
+ from sdevpy.utilities import timegrids
7
+ from sdevpy.analytics import black
6
8
  log = logging.getLogger(__name__)
7
9
 
8
10
 
@@ -21,8 +23,6 @@ class EqVolSurfaceData:
21
23
  self.forwards = np.asarray([s['forward'] for s in sections])
22
24
  self.input_strikes = [np.asarray(s['strikes']) for s in sections]
23
25
  self.vols = [np.asarray(s['vols']) for s in sections]
24
- # self.input_strikes = np.asarray([s['strikes'] for s in sections])
25
- # self.vols = np.asarray([s['vols'] for s in sections])
26
26
 
27
27
  # Size checks
28
28
  n_times = len(self.expiries)
@@ -43,12 +43,23 @@ class EqVolSurfaceData:
43
43
  else:
44
44
  raise ValueError(f"Strike input type not supported yet: {self.strike_input_type}")
45
45
 
46
+ # Calculate prices
47
+ self.call_prices = []
48
+ for exp_idx, expiry in enumerate(self.expiries):
49
+ t = timegrids.model_time(self.valdate, expiry)
50
+ fwd = self.forwards[exp_idx]
51
+ strikes = self.abs_strikes[exp_idx]
52
+ vols = self.vols[exp_idx]
53
+ self.call_prices.append(black.price(t, strikes, True, fwd, vols))
54
+
46
55
  def get_strikes(self, type: str='absolute'):
47
56
  req_type = type.lower()
48
57
  if req_type == 'absolute':
49
58
  return self.abs_strikes
50
59
  elif req_type == 'relative':
51
60
  return self.abs_strikes / self.forwards.reshape(-1, 1)
61
+ else:
62
+ raise ValueError(f"Unknown strike type {req_type}: expected absolute or relative")
52
63
 
53
64
  def dump(self, file, indent=2):
54
65
  data = self.dump_data()
@@ -2,8 +2,8 @@ import os
2
2
  import datetime as dt
3
3
  import pandas as pd
4
4
  from pathlib import Path
5
- from sdevpy.tools import dates as dts
6
- from sdevpy.tools.utils import isiterable
5
+ from sdevpy.utilities import dates as dts
6
+ from sdevpy.utilities.tools import isiterable
7
7
  from sdevpy.maths import interpolation as itp
8
8
 
9
9
 
@@ -131,8 +131,8 @@ def test_data_folder():
131
131
 
132
132
  if __name__ == "__main__":
133
133
  # import numpy as np
134
- # from sdevpy.tools.scalendar import make_schedule
135
- # from sdevpy.tools.timegrids import model_time
134
+ # from sdevpy.utilities.scalendar import make_schedule
135
+ # from sdevpy.utilities.timegrids import model_time
136
136
  # from sdevpy.maths.rand.rng import get_rng
137
137
  name = "ABC"
138
138
 
@@ -2,7 +2,7 @@ import os, json
2
2
  import datetime as dt
3
3
  import numpy as np
4
4
  from pathlib import Path
5
- from sdevpy.tools import dates
5
+ from sdevpy.utilities import dates
6
6
 
7
7
 
8
8
  def get_spots(names: list[str], valdate: dt.datetime, **kwargs):
@@ -4,7 +4,7 @@ import datetime as dt
4
4
  import numpy as np
5
5
  from abc import ABC, abstractmethod
6
6
  from enum import Enum
7
- from sdevpy.tools import timegrids, dates
7
+ from sdevpy.utilities import timegrids, dates
8
8
  from sdevpy.maths import interpolation as itp
9
9
 
10
10
 
@@ -201,7 +201,7 @@ def test_data_folder():
201
201
 
202
202
  if __name__ == "__main__":
203
203
  import matplotlib.pyplot as plt
204
- from sdevpy.tools import dates
204
+ from sdevpy.utilities import dates
205
205
 
206
206
  valdate = dt.datetime(2026, 2, 15)
207
207
 
@@ -131,7 +131,7 @@ if __name__ == "__main__":
131
131
  # Sobol with scrambling in incremental construction thatn Sobol without scrambling
132
132
  # in the Brownian bridge construction.
133
133
  # from sdevpy.maths.rand import rng
134
- # from sdevpy.tools import timer
134
+ # from sdevpy.utilities import timer
135
135
 
136
136
  # Make time grid
137
137
  n_steps = 5
@@ -2,7 +2,7 @@
2
2
  multi-d vector. This way we can get those paths from an independent engine. """
3
3
  import numpy as np
4
4
  import datetime as dt
5
- from sdevpy.tools import timegrids, timer
5
+ from sdevpy.utilities import timegrids, timer
6
6
  from sdevpy.volatility.localvol import localvol_factory as lvf
7
7
  from sdevpy.models.assetmodels import MultiAssetGBM
8
8
  from sdevpy.montecarlo.pathgenerator import PathGenerator
@@ -7,8 +7,8 @@ from sdevpy.montecarlo.payoffs.exotics import WorstOfBarrier, make_basket_option
7
7
  from sdevpy.montecarlo.mcpricer import price_book
8
8
  from sdevpy.models.localvol_factory import get_local_vols
9
9
  from sdevpy.analytics import black
10
- from sdevpy.tools import timegrids
11
- from sdevpy.tools import book as bk
10
+ from sdevpy.utilities import timegrids
11
+ from sdevpy.utilities import book as bk
12
12
  from sdevpy.market.yieldcurve import get_yieldcurve
13
13
  from sdevpy.market.eqforward import get_forward_curves
14
14
  from sdevpy.montecarlo.payoffs import cashflows as cfl
@@ -1,8 +1,8 @@
1
1
  import numpy as np
2
2
  import datetime as dt
3
3
  from abc import ABC, abstractmethod
4
- from sdevpy.tools.scalendar import make_schedule
5
- from sdevpy.tools.utils import rand_str
4
+ from sdevpy.utilities.scalendar import make_schedule
5
+ from sdevpy.utilities.tools import rand_str
6
6
  from sdevpy.market import fixings as fxgs
7
7
 
8
8
 
@@ -60,7 +60,7 @@ def make_asian_option(name: str, strike: float, optiontype: str, start: dt.datet
60
60
  return payoff
61
61
 
62
62
 
63
- def make_basket_option(names: list[str], weights: list[float], strike: float, optiontype: str, expiry: dt.dateime):
63
+ def make_basket_option(names: list[str], weights: list[float], strike: float, optiontype: str, expiry: dt.datetime):
64
64
  """ Create Basket option payoff """
65
65
  spots = [Terminal(name, expiry) for name in names]
66
66
  basket = Basket(spots, weights)
@@ -5,7 +5,7 @@ import matplotlib.pyplot as plt
5
5
  from sdevpy.analytics import black
6
6
  from sdevpy.maths import metrics
7
7
  from sdevpy.pde import pdeschemes
8
- from sdevpy.tools import timegrids
8
+ from sdevpy.utilities import timegrids
9
9
 
10
10
 
11
11
  def density_step(old_p, old_x, old_dx, t_grid, local_vol, config):
@@ -6,7 +6,8 @@ import matplotlib.pyplot as plt
6
6
  from sdevpy.montecarlo import smoothers
7
7
  from sdevpy import settings
8
8
  from sdevpy.analytics import black
9
- from sdevpy.tools.timer import Stopwatch
9
+ from sdevpy.utilities.timer import Stopwatch
10
+
10
11
 
11
12
  # ################ Runtime configuration ##########################################################
12
13
  # Parameters
@@ -6,7 +6,7 @@ from scipy.stats import norm
6
6
  import matplotlib.pyplot as plt
7
7
  from sdevpy.analytics import black
8
8
  from sdevpy.montecarlo import smoothers
9
- from sdevpy.tools.timer import Stopwatch
9
+ from sdevpy.utilities.timer import Stopwatch
10
10
 
11
11
  # In this script we calculate PV, Delta and Gamma for a hypothetical product
12
12
  # (an option on the multiplicated spots) using Monte-Carlo with bumps, closed-form
@@ -1,7 +1,7 @@
1
1
  """ Operations on data files e.g. merging, etc. """
2
2
  import os
3
3
  import pandas as pd
4
- from sdevpy.tools import filemanager
4
+ from sdevpy.utilities import filemanager
5
5
  from sdevpy import settings
6
6
 
7
7
 
@@ -1,11 +1,9 @@
1
- # Import packages
2
1
  import datetime as dt
3
- # import pandas as pd
4
- # from dateutil.relativedelta import relativedelta
5
- from sdevpy.tools import dates
2
+ from sdevpy.utilities import dates
6
3
  from openbb import obb
7
4
  obb.user.preferences.output_type = "dataframe"
8
5
 
6
+
9
7
  names = ['SPY', 'VTV', 'VUG', 'VBR', 'VBK', 'VGK', 'VPL']
10
8
  colors = ['blue', 'red', 'green', 'brown', 'orange', 'yellow']
11
9
  today = dt.date.today()
@@ -3,10 +3,10 @@
3
3
  a network that learns the so-called 'direct' calculation, i.e. prices from parameter. """
4
4
  import os
5
5
  from datetime import datetime
6
- from sdevpy.volsurfacegen import stovolfactory
6
+ from sdevpy.volatility.mlsurfacegen import stovolfactory
7
7
  from sdevpy import settings
8
- from sdevpy.tools import filemanager
9
- from sdevpy.tools.timer import Stopwatch
8
+ from sdevpy.utilities import filemanager
9
+ from sdevpy.utilities.timer import Stopwatch
10
10
 
11
11
 
12
12
  # ################ Runtime configuration ##########################################################
@@ -4,7 +4,6 @@ import matplotlib.pyplot as plt
4
4
  import matplotlib.ticker as mtick
5
5
  from sdevpy.analytics import bachelier
6
6
  from sdevpy.analytics import black
7
- # from sdevpy.tools import clipboard
8
7
 
9
8
 
10
9
  def plot_transform_surface(expiries, strikes, are_calls, fwd, ref_prices, mod_prices, title_,
@@ -70,7 +69,7 @@ def transform_surface(expiries, strikes, are_calls, fwd, prices, transform='Shif
70
69
  are_calls_ = are_calls[i]
71
70
  # trans_prices_ = []
72
71
  for j, strike in enumerate(strikes_):
73
- trans_prices[i, j] = bachelier.implied_vol(expiry, strike, are_calls_[j], fwd,
72
+ trans_prices[i, j] = bachelier.implied_vol_jaeckel(expiry, strike, are_calls_[j], fwd,
74
73
  prices[i, j])
75
74
  # trans_prices_.append(bachelier.implied_vol(expiry, strike, are_calls_[j], fwd,
76
75
  # prices[i, j]))
@@ -14,10 +14,10 @@ from sdevpy.machinelearning.learningmodel import LearningModel, load_learning_mo
14
14
  from sdevpy.machinelearning.learningschedules import FlooredExponentialDecay
15
15
  from sdevpy.machinelearning.callbacks import RefCallback
16
16
  from sdevpy.machinelearning import datasets
17
- from sdevpy.tools import filemanager
18
- from sdevpy.tools.timer import Stopwatch
17
+ from sdevpy.utilities import filemanager
18
+ from sdevpy.utilities.timer import Stopwatch
19
19
  from sdevpy.maths.metrics import bps_rmse, tf_bps_rmse
20
- from sdevpy.volsurfacegen.stovolfactory import set_generator
20
+ from sdevpy.volatility.mlsurfacegen.stovolfactory import set_generator
21
21
  from sdevpy.projects.stovol import stovolplot as xplt
22
22
 
23
23
 
@@ -3,10 +3,11 @@
3
3
  a network that learns the so-called 'inverse' calculation, i.e. parameters from prices. """
4
4
  import os
5
5
  from datetime import datetime
6
- from sdevpy.volsurfacegen import stovolfactory
6
+ from sdevpy.volatility.mlsurfacegen import stovolfactory
7
7
  from sdevpy import settings
8
- from sdevpy.tools import filemanager
9
- from sdevpy.tools.timer import Stopwatch
8
+ from sdevpy.utilities import filemanager
9
+ from sdevpy.utilities.timer import Stopwatch
10
+
10
11
 
11
12
  # ################ Runtime configuration ##########################################################
12
13
  MODEL_TYPE = "SABR"