sdevpy 1.0.5__tar.gz → 1.0.7__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 (236) hide show
  1. {sdevpy-1.0.5 → sdevpy-1.0.7}/PKG-INFO +8 -7
  2. sdevpy-1.0.7/pyproject.toml +38 -0
  3. sdevpy-1.0.7/sdevpy/__init__.py +21 -0
  4. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/analytics/americantree.py +3 -3
  5. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/analytics/bachelier.py +1 -0
  6. sdevpy-1.0.7/sdevpy/analytics/black.py +64 -0
  7. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/analytics/fbsabr.py +86 -88
  8. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/analytics/mcheston.py +76 -80
  9. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/analytics/mcsabr.py +92 -95
  10. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/analytics/mczabr.py +79 -82
  11. sdevpy-1.0.7/sdevpy/cointegration/back_testing.py +224 -0
  12. sdevpy-1.0.7/sdevpy/cointegration/coint_trading.py +677 -0
  13. sdevpy-1.0.7/sdevpy/cointegration/data_io.py +14 -0
  14. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/cointegration/mean_reversion.py +117 -128
  15. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/cointegration/model_settings.py +6 -5
  16. sdevpy-1.0.7/sdevpy/cointegration/utils.py +132 -0
  17. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/machinelearning/datasets.py +11 -8
  18. {sdevpy-1.0.5/src/sdevpy/machinelearning → sdevpy-1.0.7/sdevpy/machinelearning/keras}/callbacks.py +1 -3
  19. {sdevpy-1.0.5/src/sdevpy/machinelearning → sdevpy-1.0.7/sdevpy/machinelearning/keras}/learningmodel.py +6 -4
  20. {sdevpy-1.0.5/src/sdevpy/machinelearning → sdevpy-1.0.7/sdevpy/machinelearning/keras}/learningschedules.py +1 -3
  21. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/attention.py +3 -5
  22. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/chat.py +2 -2
  23. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/datasets.py +0 -1
  24. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/gpt.py +7 -6
  25. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/instructions.py +8 -8
  26. sdevpy-1.0.5/src/sdevpy/llms/ModelConverter.py → sdevpy-1.0.7/sdevpy/machinelearning/llms/modelconverter.py +3 -5
  27. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/training.py +2 -1
  28. sdevpy-1.0.7/sdevpy/market/correlations.py +76 -0
  29. sdevpy-1.0.7/sdevpy/market/eqforward.py +197 -0
  30. sdevpy-1.0.7/sdevpy/market/eqvolsurface.py +155 -0
  31. sdevpy-1.0.7/sdevpy/market/fixings.py +181 -0
  32. sdevpy-1.0.7/sdevpy/market/spot.py +81 -0
  33. sdevpy-1.0.7/sdevpy/market/yieldcurve.py +246 -0
  34. sdevpy-1.0.7/sdevpy/maths/__init__.py +0 -0
  35. sdevpy-1.0.7/sdevpy/maths/constants.py +28 -0
  36. sdevpy-1.0.7/sdevpy/maths/integration.py +36 -0
  37. sdevpy-1.0.7/sdevpy/maths/interpolation.py +299 -0
  38. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/maths/metrics.py +1 -14
  39. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/maths/optimization.py +94 -39
  40. sdevpy-1.0.7/sdevpy/maths/rand/__init__.py +0 -0
  41. sdevpy-1.0.7/sdevpy/maths/rand/correlations.py +44 -0
  42. sdevpy-1.0.7/sdevpy/maths/rand/pathconstruction.py +180 -0
  43. sdevpy-1.0.7/sdevpy/maths/rand/rng.py +148 -0
  44. sdevpy-1.0.7/sdevpy/maths/regression.py +4 -0
  45. sdevpy-1.0.7/sdevpy/maths/specialfunctions.py +11 -0
  46. sdevpy-1.0.7/sdevpy/maths/tridiag.py +46 -0
  47. sdevpy-1.0.7/sdevpy/models/__init__.py +0 -0
  48. sdevpy-1.0.7/sdevpy/models/assetmodels.py +90 -0
  49. sdevpy-1.0.7/sdevpy/models/multiasset_heston.py +37 -0
  50. sdevpy-1.0.7/sdevpy/montecarlo/__init__.py +0 -0
  51. sdevpy-1.0.7/sdevpy/montecarlo/mcpricer.py +188 -0
  52. sdevpy-1.0.7/sdevpy/montecarlo/mcrun.py +102 -0
  53. sdevpy-1.0.7/sdevpy/montecarlo/pathgenerator.py +31 -0
  54. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/__init__.py +0 -0
  55. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/basic.py +669 -0
  56. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/cashflows.py +32 -0
  57. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/exotics.py +96 -0
  58. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/vanillas.py +76 -0
  59. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/montecarlo/smoothers.py +1 -9
  60. sdevpy-1.0.7/sdevpy/pde/__init__.py +0 -0
  61. sdevpy-1.0.7/sdevpy/pde/forwardpde.py +267 -0
  62. sdevpy-1.0.7/sdevpy/pde/pdeschemes.py +140 -0
  63. sdevpy-1.0.7/sdevpy/projects/__init__.py +0 -0
  64. sdevpy-1.0.7/sdevpy/projects/aad/__init__.py +0 -0
  65. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/aad/aad_mc_nd.py +3 -3
  66. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/chat_gpt2.py +3 -3
  67. sdevpy-1.0.7/sdevpy/projects/raschka/__init__.py +0 -0
  68. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/raschka/ch2_working_with_text.py +3 -3
  69. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/raschka/ch3_coding_attention.py +3 -3
  70. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/raschka/ch4_gpt_model.py +3 -3
  71. sdevpy-1.0.5/src/sdevpy/projects/raschka/ch5_loadGPT2.py → sdevpy-1.0.7/sdevpy/projects/raschka/ch5_loadgpt2.py +2 -2
  72. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/raschka/ch5_pretraining.py +7 -7
  73. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/raschka/ch7_instruction_finetuning.py +2 -2
  74. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/raschka/raschka_datasetloader.py +2 -2
  75. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/raschka/raschka_dnn.py +1 -1
  76. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/raschka/raschka_gpt_download.py +1 -1
  77. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/set_limits.py +5 -6
  78. sdevpy-1.0.7/sdevpy/projects/stovol/__init__.py +0 -0
  79. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/stovol/stovolplot.py +1 -1
  80. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/stovol/stovoltrain.py +0 -1
  81. sdevpy-1.0.7/sdevpy/projects/stovolinverse/__init__.py +0 -0
  82. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/stovolinverse/stovolinvtrain.py +5 -5
  83. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/update_db.py +3 -3
  84. sdevpy-1.0.7/sdevpy/settings.py +57 -0
  85. sdevpy-1.0.7/sdevpy/tensorflow/__init__.py +0 -0
  86. {sdevpy-1.0.5/src/sdevpy/analytics → sdevpy-1.0.7/sdevpy/tensorflow}/tf_black.py +4 -4
  87. sdevpy-1.0.7/sdevpy/tensorflow/tf_metrics.py +14 -0
  88. sdevpy-1.0.7/sdevpy/tests/test.py +82 -0
  89. sdevpy-1.0.7/sdevpy/tests/test_algos.py +125 -0
  90. sdevpy-1.0.7/sdevpy/tests/test_dates.py +58 -0
  91. sdevpy-1.0.7/sdevpy/tests/test_impliedvol.py +100 -0
  92. sdevpy-1.0.7/sdevpy/tests/test_interpolation.py +55 -0
  93. sdevpy-1.0.7/sdevpy/tests/test_localvol.py +0 -0
  94. sdevpy-1.0.7/sdevpy/tests/test_marketdata.py +48 -0
  95. sdevpy-1.0.7/sdevpy/tests/test_mc.py +85 -0
  96. sdevpy-1.0.7/sdevpy/tests/test_pde.py +116 -0
  97. sdevpy-1.0.7/sdevpy/tests/test_timegrids.py +49 -0
  98. sdevpy-1.0.7/sdevpy/tests/test_utils.py +67 -0
  99. sdevpy-1.0.7/sdevpy/tests/test_yieldcurves.py +49 -0
  100. sdevpy-1.0.7/sdevpy/thirdparty/__init__.py +0 -0
  101. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/__init__.py +1 -0
  102. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/constants.py +1 -0
  103. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/erf_cody.py +1 -0
  104. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/exceptions.py +1 -0
  105. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/lets_be_rational.py +1 -0
  106. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/normaldistribution.py +1 -0
  107. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/rationalcubic.py +1 -0
  108. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/__init__.py +1 -0
  109. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black/__init__.py +1 -0
  110. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/black/greeks/__init__.py +0 -0
  111. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black/greeks/analytical.py +1 -0
  112. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black/greeks/numerical.py +1 -0
  113. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black/implied_volatility.py +1 -0
  114. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes/__init__.py +1 -0
  115. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/black_scholes/greeks/__init__.py +0 -0
  116. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes/greeks/analytical.py +1 -0
  117. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes/greeks/numerical.py +1 -0
  118. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes/implied_volatility.py +1 -0
  119. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes_merton/__init__.py +1 -0
  120. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/__init__.py +0 -0
  121. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/analytical.py +1 -0
  122. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/numerical.py +1 -0
  123. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes_merton/implied_volatility.py +1 -0
  124. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/__init__.py +1 -0
  125. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/constants.py +1 -0
  126. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/distributions.py +1 -0
  127. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/doctest_helper.py +1 -0
  128. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/exceptions.py +1 -0
  129. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/numerical_greeks.py +1 -0
  130. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/__init__.py +1 -0
  131. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black/__init__.py +1 -0
  132. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/__init__.py +0 -0
  133. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/analytical.py +1 -0
  134. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/numerical.py +1 -0
  135. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black/implied_volatility.py +1 -0
  136. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/__init__.py +1 -0
  137. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/__init__.py +0 -0
  138. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/analytical.py +1 -0
  139. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/numerical.py +1 -0
  140. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/implied_volatility.py +1 -0
  141. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/__init__.py +1 -0
  142. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/__init__.py +0 -0
  143. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/analytical.py +1 -0
  144. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/numerical.py +1 -0
  145. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/implied_volatility.py +1 -0
  146. sdevpy-1.0.7/sdevpy/timeseries/__init__.py +0 -0
  147. sdevpy-1.0.7/sdevpy/timeseries/backtesting.py +86 -0
  148. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/timeseries/cointegration.py +22 -22
  149. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/timeseries/meanreversion.py +47 -48
  150. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/timeseries/timeseriestools.py +15 -18
  151. sdevpy-1.0.7/sdevpy/tools/__init__.py +0 -0
  152. sdevpy-1.0.7/sdevpy/tools/algos.py +115 -0
  153. sdevpy-1.0.7/sdevpy/tools/book.py +51 -0
  154. sdevpy-1.0.7/sdevpy/tools/dates.py +31 -0
  155. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tools/network.py +5 -2
  156. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tools/pydotnet.py +8 -6
  157. sdevpy-1.0.7/sdevpy/tools/scalendar.py +287 -0
  158. sdevpy-1.0.7/sdevpy/tools/speriods.py +25 -0
  159. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tools/timegrids.py +50 -13
  160. sdevpy-1.0.7/sdevpy/tools/utils.py +52 -0
  161. sdevpy-1.0.7/sdevpy/tree/__init__.py +0 -0
  162. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tree/trees.py +1 -16
  163. sdevpy-1.0.7/sdevpy/volatility/__init__.py +0 -0
  164. sdevpy-1.0.7/sdevpy/volatility/impliedvol/__init__.py +0 -0
  165. sdevpy-1.0.7/sdevpy/volatility/impliedvol/impliedvol.py +45 -0
  166. sdevpy-1.0.7/sdevpy/volatility/impliedvol/impliedvol_calib.py +125 -0
  167. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/__init__.py +0 -0
  168. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/biexp.py +168 -0
  169. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/cubicvol.py +205 -0
  170. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/gsvi.py +63 -0
  171. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/svi.py +95 -0
  172. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/tssvi1.py +143 -0
  173. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/vsvi.py +148 -0
  174. sdevpy-1.0.7/sdevpy/volatility/impliedvol/optionsurface.py +167 -0
  175. sdevpy-1.0.7/sdevpy/volatility/impliedvol/zerosurface.py +251 -0
  176. sdevpy-1.0.7/sdevpy/volatility/localvol/__init__.py +0 -0
  177. sdevpy-1.0.7/sdevpy/volatility/localvol/localvol.py +92 -0
  178. sdevpy-1.0.7/sdevpy/volatility/localvol/localvol_calib.py +303 -0
  179. sdevpy-1.0.7/sdevpy/volatility/localvol/localvol_factory.py +201 -0
  180. sdevpy-1.0.7/sdevpy/volsurfacegen/__init__.py +0 -0
  181. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/volsurfacegen/mchestongenerator.py +2 -2
  182. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/volsurfacegen/mczabrgenerator.py +1 -1
  183. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/volsurfacegen/sabrgenerator.py +24 -34
  184. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/volsurfacegen/smilegenerator.py +3 -4
  185. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy.egg-info/PKG-INFO +8 -7
  186. sdevpy-1.0.7/sdevpy.egg-info/SOURCES.txt +215 -0
  187. sdevpy-1.0.7/sdevpy.egg-info/requires.txt +8 -0
  188. sdevpy-1.0.7/sdevpy.egg-info/top_level.txt +2 -0
  189. sdevpy-1.0.5/pyproject.toml +0 -26
  190. sdevpy-1.0.5/src/sdevpy/analytics/black.py +0 -128
  191. sdevpy-1.0.5/src/sdevpy/cointegration/back_testing.py +0 -233
  192. sdevpy-1.0.5/src/sdevpy/cointegration/black_analytics.py +0 -45
  193. sdevpy-1.0.5/src/sdevpy/cointegration/coint_trading.py +0 -839
  194. sdevpy-1.0.5/src/sdevpy/cointegration/data_io.py +0 -225
  195. sdevpy-1.0.5/src/sdevpy/cointegration/implied_vol.py +0 -116
  196. sdevpy-1.0.5/src/sdevpy/cointegration/plotting.py +0 -296
  197. sdevpy-1.0.5/src/sdevpy/cointegration/run_unit_test.py +0 -572
  198. sdevpy-1.0.5/src/sdevpy/cointegration/utils.py +0 -477
  199. sdevpy-1.0.5/src/sdevpy/maths/interpolations.py +0 -31
  200. sdevpy-1.0.5/src/sdevpy/maths/rand.py +0 -99
  201. sdevpy-1.0.5/src/sdevpy/settings.py +0 -57
  202. sdevpy-1.0.5/src/sdevpy/test.py +0 -578
  203. sdevpy-1.0.5/src/sdevpy/timeseries/backtesting.py +0 -91
  204. sdevpy-1.0.5/src/sdevpy/tools/utils.py +0 -42
  205. sdevpy-1.0.5/src/sdevpy.egg-info/SOURCES.txt +0 -137
  206. sdevpy-1.0.5/src/sdevpy.egg-info/requires.txt +0 -7
  207. sdevpy-1.0.5/src/sdevpy.egg-info/top_level.txt +0 -1
  208. sdevpy-1.0.5/tests/test.py +0 -13
  209. {sdevpy-1.0.5 → sdevpy-1.0.7}/README.md +0 -0
  210. {sdevpy-1.0.5/src/sdevpy/thirdparty/py_vollib/black/greeks → sdevpy-1.0.7/sdevpy/analytics}/__init__.py +0 -0
  211. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/analytics/sabr.py +0 -0
  212. {sdevpy-1.0.5/src/sdevpy/thirdparty/py_vollib/black_scholes/greeks → sdevpy-1.0.7/sdevpy/cointegration}/__init__.py +0 -0
  213. {sdevpy-1.0.5/src/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks → sdevpy-1.0.7/sdevpy/machinelearning}/__init__.py +0 -0
  214. {sdevpy-1.0.5/src/sdevpy/thirdparty/py_vollib/ref_python/black/greeks → sdevpy-1.0.7/sdevpy/machinelearning/keras}/__init__.py +0 -0
  215. {sdevpy-1.0.5/src/sdevpy/machinelearning → sdevpy-1.0.7/sdevpy/machinelearning/keras}/topology.py +0 -0
  216. {sdevpy-1.0.5/src/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks → sdevpy-1.0.7/sdevpy/machinelearning/llms}/__init__.py +0 -0
  217. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/textgen.py +0 -0
  218. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/tokenizers.py +0 -0
  219. {sdevpy-1.0.5/src/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks → sdevpy-1.0.7/sdevpy/market}/__init__.py +0 -0
  220. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/maths/sets.py +0 -0
  221. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/aad/aad_mc.py +0 -0
  222. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/datafiles.py +0 -0
  223. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/stovol/stovolgen.py +0 -0
  224. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/projects/stovolinverse/stovolinvgen.py +0 -0
  225. {sdevpy-1.0.5/src/sdevpy → sdevpy-1.0.7/sdevpy/tests}/__init__.py +0 -0
  226. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/numba_helper.py +0 -0
  227. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tools/clipboard.py +0 -0
  228. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tools/constants.py +0 -0
  229. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tools/filemanager.py +0 -0
  230. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tools/jsonmanager.py +0 -0
  231. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/tools/timer.py +0 -0
  232. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/volsurfacegen/fbsabrgenerator.py +0 -0
  233. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/volsurfacegen/mcsabrgenerator.py +0 -0
  234. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy/volsurfacegen/stovolfactory.py +0 -0
  235. {sdevpy-1.0.5/src → sdevpy-1.0.7}/sdevpy.egg-info/dependency_links.txt +0 -0
  236. {sdevpy-1.0.5 → sdevpy-1.0.7}/setup.cfg +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdevpy
3
- Version: 1.0.5
4
- Summary: Python package for Machine Learning in Finance
3
+ Version: 1.0.7
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
7
7
  Project-URL: SDev Finance, http://sdev-finance.com/
@@ -10,12 +10,13 @@ Classifier: Operating System :: OS Independent
10
10
  Requires-Python: >=3.6
11
11
  Description-Content-Type: text/markdown
12
12
  Requires-Dist: pandas
13
- Requires-Dist: pyperclip
14
13
  Requires-Dist: numpy
15
- Requires-Dist: tensorflow
16
- Requires-Dist: scikit-learn
17
- Requires-Dist: tensorflow_probability
18
- Requires-Dist: silence_tensorflow
14
+ Requires-Dist: scipy
15
+ Requires-Dist: matplotlib
16
+ Requires-Dist: holidays
17
+ Requires-Dist: pandas_market_calendars
18
+ Requires-Dist: openpyxl
19
+ Requires-Dist: colorlog
19
20
 
20
21
  # SDev.Python
21
22
 
@@ -0,0 +1,38 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sdevpy"
7
+ version = "1.0.7"
8
+ license-files = []
9
+ authors = [{ name="Sebastien Gurrieri", email="sebgur@gmail.com" }]
10
+ description = "Python package for Finance"
11
+ readme = "README.md"
12
+ requires-python = ">=3.6"
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ dependencies = ["pandas", "numpy", "scipy", "matplotlib", "holidays",
18
+ "pandas_market_calendars", "openpyxl", "colorlog"
19
+ ]
20
+ #dependencies = ["pyperclip", "tensorflow", "scikit-learn",
21
+ # "tensorflow_probability", "silence_tensorflow"]
22
+
23
+ [tool.setuptools.packages.find]
24
+ where = ["."]
25
+ include = ["sdevpy*", "notebooks*"] # Only include these
26
+ #exclude = ["notebooks*", "spreadsheets*"] # Exclude these
27
+
28
+ [tool.ruff]
29
+ line-length = 120
30
+ target-version = "py313"
31
+
32
+ [tool.ruff.lint]
33
+ select = ["E", "F", "N", "W", "UP", "B"]
34
+ ignore = ["E401", "I001"]
35
+
36
+ [project.urls]
37
+ "Git page" = "https://github.com/sebgur/SDev.Python"
38
+ "SDev Finance" = "http://sdev-finance.com/"
@@ -0,0 +1,21 @@
1
+ __version__ = '1.0.5'
2
+
3
+ import logging
4
+ import colorlog
5
+
6
+ handler = colorlog.StreamHandler()
7
+ handler.setFormatter(colorlog.ColoredFormatter(
8
+ "%(log_color)s%(levelname)-8s%(reset)s %(name)s - %(message)s",
9
+ log_colors={
10
+ "DEBUG": "cyan",
11
+ "INFO": "green",
12
+ "WARNING": "yellow",
13
+ "ERROR": "red",
14
+ "CRITICAL": "bold_red",
15
+ }
16
+ ))
17
+
18
+ root = logging.getLogger()
19
+ root.addHandler(handler)
20
+ root.setLevel(logging.WARNING)
21
+ logging.getLogger("sdevpy").setLevel(logging.DEBUG)
@@ -4,6 +4,7 @@ import time
4
4
  import matplotlib.pyplot as plt
5
5
  from sdevpy.analytics import black
6
6
  from sdevpy.tree import trees
7
+ from sdevpy.tree.trees import Payoff
7
8
 
8
9
 
9
10
  def option_price(ttm, strike, is_call, is_american, spot, vol, rf_rate, div_rate, disc_rate,
@@ -93,11 +94,10 @@ if __name__ == "__main__":
93
94
  if not payoff.is_american:
94
95
  plt.plot(cf_t, cf_p, label='Vanilla CF Price')
95
96
  # # plt.plot(steps_range, trinomial_prices, label='Trinomial Tree Price')
96
- # plt.hlines(bs_price, steps_range[0], steps_range[-1], colors='r', linestyles='dashed', label='Black-Scholes Price')
97
+ # plt.hlines(bs_price, steps_range[0], steps_range[-1], colors='r', linestyles='dashed',
98
+ # label='Black-Scholes Price')
97
99
  plt.title('Convergence to Black-Scholes Price for Call Options')
98
100
  plt.xlabel('Runtime')
99
101
  plt.ylabel('Option Price')
100
102
  plt.legend()
101
103
  plt.show()
102
-
103
-
@@ -13,6 +13,7 @@ def price(expiry, strike, is_call, fwd, vol):
13
13
 
14
14
 
15
15
  def price_straddles(expiries, strikes, fwd, vols):
16
+ """ Straddle price under the Bachelier model """
16
17
  expiries_ = np.asarray(expiries).reshape(-1, 1)
17
18
  prices = []
18
19
  for i, expiry in enumerate(expiries_):
@@ -0,0 +1,64 @@
1
+ """ Utilities for Black-Scholes model """
2
+ import numpy as np
3
+ # import numpy.typing as npt
4
+ import scipy.stats
5
+ from scipy.optimize import minimize_scalar
6
+ from sdevpy.thirdparty.py_vollib.black import implied_volatility as jaeckel
7
+
8
+ N = scipy.stats.norm.cdf
9
+
10
+
11
+ def price(expiry: float, strike: float, is_call: bool, fwd: float, vol: float) -> float:
12
+ """ Option price under the Black-Scholes model """
13
+ w = 1.0 if is_call else -1.0
14
+ s = vol * np.sqrt(expiry)
15
+ d1 = np.log(fwd / strike) / s + 0.5 * s
16
+ d2 = d1 - s
17
+ return w * (fwd * N(w * d1) - strike * N(w * d2))
18
+
19
+
20
+ def implied_vol_jaeckel(expiry: float, strike: float, is_call: bool, fwd: float, fwd_price: float) -> float:
21
+ """ Black-Scholes implied volatility using P. Jaeckel's 'Let's be rational' method,
22
+ from package py_vollib. Install with pip install py_vollib or at
23
+ https://pypi.org/project/py_vollib/. Unfortunately we found it has instabilities
24
+ near ATM. """
25
+ flag = 'c' if is_call else 'p'
26
+ p = fwd_price
27
+ iv = jaeckel.implied_volatility_of_undiscounted_option_price(p, fwd, strike, expiry, flag)
28
+ return iv
29
+
30
+
31
+ def implied_vol(expiry: float, strike: float, is_call: bool, fwd: float, fwd_price: float) -> float:
32
+ """ Direct method by numerical inversion using Brent """
33
+ options = {'xtol': 1e-4, 'maxiter': 100, 'disp': False}
34
+ xmin = 1e-6
35
+ xmax = 1.0
36
+
37
+ def error(vol):
38
+ premium = price(expiry, strike, is_call, fwd, vol)
39
+ return (premium - fwd_price) ** 2
40
+
41
+ res = minimize_scalar(fun=error, bracket=(xmin, xmax), options=options, method='brent')
42
+
43
+ return res.x
44
+
45
+
46
+ if __name__ == "__main__":
47
+ EXPIRY = 1.0
48
+ VOL = 0.25
49
+ IS_CALL = True
50
+ NUM_POINTS = 100
51
+ # FWD = 100
52
+ # K = 100
53
+ # p = price(EXPIRY, K, IS_CALL, FWD, VOL)
54
+ # iv = implied_vol(EXPIRY, K, IS_CALL, FWD, p)
55
+ # print(iv)
56
+ f_space = np.linspace(100, 120, NUM_POINTS)
57
+ k_space = np.linspace(20, 2180, NUM_POINTS)
58
+ prices = price(EXPIRY, k_space, IS_CALL, f_space, VOL)
59
+ # print(prices)
60
+ implied_vols = []
61
+ for i, k in enumerate(k_space):
62
+ implied_vols.append(implied_vol(EXPIRY, k, IS_CALL, f_space[i], prices[i]))
63
+
64
+ # print(implied_vols)
@@ -1,14 +1,14 @@
1
1
  """ Monte-Carlo simulation for Free-Boundary SABR model (vanillas) """
2
2
  import numpy as np
3
+ import numpy.typing as npt
3
4
  import matplotlib.pyplot as plt
4
5
  import scipy.stats as sp
5
- # from analytics.sabr import calculate_alpha
6
6
  from sdevpy.tools.timegrids import SimpleTimeGridBuilder
7
7
  from sdevpy.tools import timer
8
8
 
9
9
 
10
- def price(expiries, strikes, are_calls, fwd, parameters, num_mc=10000, points_per_year=10,
11
- scheme='Andersen'):
10
+ def price(expiries: npt.ArrayLike, strikes: npt.ArrayLike, are_calls: npt.ArrayLike, fwd: float,
11
+ parameters: list[float], num_mc: int=10000, points_per_year: int=10, scheme: str='Andersen'):
12
12
  """ Calculate vanilla prices under Free-Boundary SABR model by Monte-Carlo simulation"""
13
13
  floor = 0.00001
14
14
 
@@ -16,98 +16,96 @@ def price(expiries, strikes, are_calls, fwd, parameters, num_mc=10000, points_pe
16
16
  # the spot becomes so close to 0 that Python effectively handles it as 0. This results in
17
17
  # a warning when taking a negative power of it. However, this is not an issue as Python
18
18
  # correctly finds +infinity and since we use a floor, this case is correctly handled.
19
- np.seterr(divide='ignore')
20
-
21
- # Build time grid
22
- time_grid_builder = SimpleTimeGridBuilder(points_per_year=points_per_year)
23
- time_grid_builder.add_grid(expiries)
24
- time_grid = time_grid_builder.complete_grid()
25
- num_factors = 2
26
-
27
- # Find payoff times
28
- is_payoff = np.in1d(time_grid, expiries)
29
-
30
- # Retrieve parameters
31
- lnvol = parameters['LnVol']
32
- beta = parameters['Beta']
33
- nu = parameters['Nu']
34
- rho = parameters['Rho']
35
- alpha = calculate_fbsabr_alpha(lnvol, fwd, beta)
36
- nu2 = nu**2
37
- sqrtmrho2 = np.sqrt(1.0 - rho**2)
38
-
39
- # Draw all gaussians
40
- # gaussians = rand.gaussians(num_steps, num_mc, num_factors, rand_method)
41
-
42
- # Define dimensions
43
- mean = np.zeros(num_factors)
44
- corr = np.zeros((num_factors, num_factors))
45
- for c in range(num_factors):
46
- corr[c, c] = 1.0
47
-
48
- # Draw for each step
49
- seed = 42
50
- rng = np.random.RandomState(seed)
51
-
52
- # Initialize paths
53
- spot = np.ones((2 * num_mc, 1)) * fwd
54
- vol = np.ones((2 * num_mc, 1)) * 1.0
55
-
56
- # Loop over time grid
57
- ts = te = 0
58
- payoff_count = 0
59
- mc_prices = []
60
- for i, t in enumerate(time_grid):
61
- # print("time iteration " + str(i))
62
- ts = te
63
- te = t
64
- dt = te - ts
65
- sqrt_dt = np.sqrt(dt)
66
-
67
- # Evolve
68
- dz = rng.multivariate_normal(mean, corr, size=num_mc) * sqrt_dt
69
- dz = np.concatenate((dz, -dz), axis=0) # Antithetic paths
70
- dz0 = dz[:, 0].reshape(-1, 1)
71
- dz1 = dz[:, 1].reshape(-1, 1)
72
-
73
- vols = vol
74
- abs_f = np.maximum(np.abs(spot), floor)
75
-
76
- # Evolve vol
77
- vol *= np.exp(-0.5 * nu2 * dt + nu * dz1)
78
-
79
- # Evolve spot
80
- if scheme == 'Euler':
81
- dw = rho * dz1 + sqrtmrho2 * dz0
82
- spot = spot + alpha * abs_f**beta * dw * vols
83
- elif scheme == 'Andersen':
84
- vole = vol
85
- spot = spot + alpha * abs_f**beta * (sqrtmrho2 * vols * dz0 + rho / nu * (vole - vols))
86
- else:
87
- raise ValueError("Unknown scheme in FBSABR: " + scheme)
88
-
89
- # Calculate payoff
90
- if is_payoff[i]:
91
- w = [1.0 if is_call else -1.0 for is_call in are_calls[payoff_count]]
92
- w = np.asarray(w).reshape(1, -1)
93
- k = np.asarray(strikes[payoff_count]).reshape(1, -1)
94
- payoff = np.maximum(w * (spot - k), 0.0)
95
- rpayoff = np.mean(payoff, axis=0)
96
- mc_prices.append(rpayoff)
97
- payoff_count += 1
98
-
99
- np.seterr(divide='warn')
19
+ with np.errstate(divide='ignore'):
20
+ # Build time grid
21
+ time_grid_builder = SimpleTimeGridBuilder(points_per_year=points_per_year)
22
+ time_grid_builder.add_grid(expiries)
23
+ time_grid = time_grid_builder.complete_grid()
24
+ num_factors = 2
25
+
26
+ # Find payoff times
27
+ is_payoff = np.in1d(time_grid, expiries)
28
+
29
+ # Retrieve parameters
30
+ lnvol = parameters['LnVol']
31
+ beta = parameters['Beta']
32
+ nu = parameters['Nu']
33
+ rho = parameters['Rho']
34
+ alpha = calculate_fbsabr_alpha(lnvol, fwd, beta)
35
+ nu2 = nu**2
36
+ sqrtmrho2 = np.sqrt(1.0 - rho**2)
37
+
38
+ # Draw all gaussians
39
+ # gaussians = rand.gaussians(num_steps, num_mc, num_factors, rand_method)
40
+
41
+ # Define dimensions
42
+ mean = np.zeros(num_factors)
43
+ corr = np.zeros((num_factors, num_factors))
44
+ for c in range(num_factors):
45
+ corr[c, c] = 1.0
46
+
47
+ # Draw for each step
48
+ seed = 42
49
+ rng = np.random.RandomState(seed)
50
+
51
+ # Initialize paths
52
+ spot = np.ones((2 * num_mc, 1)) * fwd
53
+ vol = np.ones((2 * num_mc, 1)) * 1.0
54
+
55
+ # Loop over time grid
56
+ ts = te = 0
57
+ payoff_count = 0
58
+ mc_prices = []
59
+ for i, t in enumerate(time_grid):
60
+ # print("time iteration " + str(i))
61
+ ts = te
62
+ te = t
63
+ dt = te - ts
64
+ sqrt_dt = np.sqrt(dt)
65
+
66
+ # Evolve
67
+ dz = rng.multivariate_normal(mean, corr, size=num_mc) * sqrt_dt
68
+ dz = np.concatenate((dz, -dz), axis=0) # Antithetic paths
69
+ dz0 = dz[:, 0].reshape(-1, 1)
70
+ dz1 = dz[:, 1].reshape(-1, 1)
71
+
72
+ vols = vol
73
+ abs_f = np.maximum(np.abs(spot), floor)
74
+
75
+ # Evolve vol
76
+ vol *= np.exp(-0.5 * nu2 * dt + nu * dz1)
77
+
78
+ # Evolve spot
79
+ if scheme == 'Euler':
80
+ dw = rho * dz1 + sqrtmrho2 * dz0
81
+ spot = spot + alpha * abs_f**beta * dw * vols
82
+ elif scheme == 'Andersen':
83
+ vole = vol
84
+ spot = spot + alpha * abs_f**beta * (sqrtmrho2 * vols * dz0 + rho / nu * (vole - vols))
85
+ else:
86
+ raise ValueError("Unknown scheme in FBSABR: " + scheme)
87
+
88
+ # Calculate payoff
89
+ if is_payoff[i]:
90
+ w = [1.0 if is_call else -1.0 for is_call in are_calls[payoff_count]]
91
+ w = np.asarray(w).reshape(1, -1)
92
+ k = np.asarray(strikes[payoff_count]).reshape(1, -1)
93
+ payoff = np.maximum(w * (spot - k), 0.0)
94
+ rpayoff = np.mean(payoff, axis=0)
95
+ mc_prices.append(rpayoff)
96
+ payoff_count += 1
100
97
 
101
98
  return np.asarray(mc_prices)
102
99
 
103
100
 
104
- def calculate_fbsabr_alpha(ln_vol, fwd, beta):
101
+ def calculate_fbsabr_alpha(ln_vol: float, fwd: float, beta: float) -> float:
105
102
  """ Calculate parameter alpha with our definition in terms of ln_vol, i.e.
106
103
  alpha = ln_vol * fwd ^ (1.0 - beta) """
107
104
  floor = 0.00001
108
105
  abs_f = np.maximum(np.abs(fwd), floor)
109
106
  return ln_vol * abs_f ** (1.0 - beta)
110
107
 
108
+
111
109
  if __name__ == "__main__":
112
110
  EXPIRIES = [3.0, 8.0, 13, 19, 22, 31, 34]
113
111
  NSTRIKES = 50
@@ -151,12 +149,12 @@ if __name__ == "__main__":
151
149
  # print(MC_PRICES)
152
150
 
153
151
  # Convert to IV and compare against approximate closed-form
154
- # import black
155
- import bachelier
152
+ # import sdevpy.analytics.black as black
153
+ import sdevpy.analytics.bachelier as bachelier
156
154
  mc_ivs = []
157
155
  for a, expiry in enumerate(EXPIRIES):
158
156
  mc_iv = []
159
- for j, sstrike in enumerate(SSTRIKES[a]):
157
+ for j, _ in enumerate(SSTRIKES[a]):
160
158
  # mc_iv.append(black.implied_vol(expiry, sstrike, IS_CALL, SFWD, MC_PRICES[a, j]))
161
159
  mc_iv.append(bachelier.implied_vol(expiry, STRIKES[a, j], IS_CALL, FWD,
162
160
  MC_PRICES[a, j]))
@@ -5,7 +5,6 @@
5
5
  import numpy as np
6
6
  import matplotlib.pyplot as plt
7
7
  import scipy.stats as sp
8
- # from analytics.sabr import calculate_alpha
9
8
  from sdevpy.tools.timegrids import SimpleTimeGridBuilder
10
9
  from sdevpy.tools import timer
11
10
 
@@ -20,83 +19,80 @@ def price(expiries, strikes, are_calls, fwd, parameters, num_mc=10000, points_pe
20
19
  # the spot becomes so close to 0 that Python effectively handles it as 0. This results in
21
20
  # a warning when taking a negative power of it. However, this is not an issue as Python
22
21
  # correctly finds +infinity and since we use a floor, this case is correctly handled.
23
- np.seterr(divide='ignore')
24
-
25
- # Build time grid
26
- time_grid_builder = SimpleTimeGridBuilder(points_per_year=points_per_year)
27
- time_grid_builder.add_grid(expiries)
28
- time_grid = time_grid_builder.complete_grid()
29
- num_factors = 2
30
-
31
- # Find payoff times
32
- is_payoff = np.in1d(time_grid, expiries)
33
-
34
- # Retrieve parameters
35
- lnvol = parameters['LnVol']
36
- kappa = parameters['Kappa']
37
- theta = parameters['Theta']
38
- xi = parameters['Xi']
39
- rho = parameters['Rho']
40
- sqrtmrho2 = np.sqrt(1.0 - rho**2)
41
- v0 = calculate_v0(lnvol)
42
-
43
- # Draw all gaussians
44
- # gaussians = rand.gaussians(num_steps, num_mc, num_factors, rand_method)
45
-
46
- # Define dimensions
47
- mean = np.zeros(num_factors)
48
- corr = np.zeros((num_factors, num_factors))
49
- for c in range(num_factors):
50
- corr[c, c] = 1.0
51
-
52
- # Draw for each step
53
- seed = 42
54
- rng = np.random.RandomState(seed)
55
-
56
- # Initialize paths
57
- spot = np.ones((2 * num_mc, 1)) * fwd
58
- vol2 = np.ones((2 * num_mc, 1)) * v0
59
-
60
- # Loop over time grid
61
- ts = te = 0
62
- payoff_count = 0
63
- mc_prices = []
64
- for i, t in enumerate(time_grid):
65
- ts = te
66
- te = t
67
- dt = te - ts
68
- sqrt_dt = np.sqrt(dt)
69
-
70
- # Evolve
71
- dz = rng.multivariate_normal(mean, corr, size=num_mc) * sqrt_dt
72
- dz = np.concatenate((dz, -dz), axis=0) # Antithetic paths
73
- dz0 = dz[:, 0].reshape(-1, 1)
74
- dz1 = dz[:, 1].reshape(-1, 1)
75
-
76
- # Evolve vol
77
- vol2s = np.abs(vol2)
78
- sqrt_vol2s = np.sqrt(vol2s)
79
- vol2e = vol2s + kappa * (theta - vol2s) * dt + xi * sqrt_vol2s * dz1
80
- vol2e = np.abs(vol2e)
81
- vol2 = vol2e
82
-
83
- # Evolve spot
84
- intvol2 = 0.5 * (vol2s + vol2e) * dt
85
- ito = 0.5 * intvol2
86
- dw = rho * dz1 + sqrtmrho2 * dz0
87
- spot *= np.exp(-ito + sqrt_vol2s * dw)
88
-
89
- # Calculate payoff
90
- if is_payoff[i]:
91
- w = [1.0 if is_call else -1.0 for is_call in are_calls[payoff_count]]
92
- w = np.asarray(w).reshape(1, -1)
93
- k = np.asarray(strikes[payoff_count]).reshape(1, -1)
94
- payoff = np.maximum(w * (spot - k), 0.0)
95
- rpayoff = np.mean(payoff, axis=0)
96
- mc_prices.append(rpayoff)
97
- payoff_count += 1
98
-
99
- np.seterr(divide='warn')
22
+ with np.errstate(divide='ignore'):
23
+ # Build time grid
24
+ time_grid_builder = SimpleTimeGridBuilder(points_per_year=points_per_year)
25
+ time_grid_builder.add_grid(expiries)
26
+ time_grid = time_grid_builder.complete_grid()
27
+ num_factors = 2
28
+
29
+ # Find payoff times
30
+ is_payoff = np.in1d(time_grid, expiries)
31
+
32
+ # Retrieve parameters
33
+ lnvol = parameters['LnVol']
34
+ kappa = parameters['Kappa']
35
+ theta = parameters['Theta']
36
+ xi = parameters['Xi']
37
+ rho = parameters['Rho']
38
+ sqrtmrho2 = np.sqrt(1.0 - rho**2)
39
+ v0 = calculate_v0(lnvol)
40
+
41
+ # Draw all gaussians
42
+ # gaussians = rand.gaussians(num_steps, num_mc, num_factors, rand_method)
43
+
44
+ # Define dimensions
45
+ mean = np.zeros(num_factors)
46
+ corr = np.zeros((num_factors, num_factors))
47
+ for c in range(num_factors):
48
+ corr[c, c] = 1.0
49
+
50
+ # Draw for each step
51
+ seed = 42
52
+ rng = np.random.RandomState(seed)
53
+
54
+ # Initialize paths
55
+ spot = np.ones((2 * num_mc, 1)) * fwd
56
+ vol2 = np.ones((2 * num_mc, 1)) * v0
57
+
58
+ # Loop over time grid
59
+ ts = te = 0
60
+ payoff_count = 0
61
+ mc_prices = []
62
+ for i, t in enumerate(time_grid):
63
+ ts = te
64
+ te = t
65
+ dt = te - ts
66
+ sqrt_dt = np.sqrt(dt)
67
+
68
+ # Evolve
69
+ dz = rng.multivariate_normal(mean, corr, size=num_mc) * sqrt_dt
70
+ dz = np.concatenate((dz, -dz), axis=0) # Antithetic paths
71
+ dz0 = dz[:, 0].reshape(-1, 1)
72
+ dz1 = dz[:, 1].reshape(-1, 1)
73
+
74
+ # Evolve vol
75
+ vol2s = np.abs(vol2)
76
+ sqrt_vol2s = np.sqrt(vol2s)
77
+ vol2e = vol2s + kappa * (theta - vol2s) * dt + xi * sqrt_vol2s * dz1
78
+ vol2e = np.abs(vol2e)
79
+ vol2 = vol2e
80
+
81
+ # Evolve spot
82
+ intvol2 = 0.5 * (vol2s + vol2e) * dt
83
+ ito = 0.5 * intvol2
84
+ dw = rho * dz1 + sqrtmrho2 * dz0
85
+ spot *= np.exp(-ito + sqrt_vol2s * dw)
86
+
87
+ # Calculate payoff
88
+ if is_payoff[i]:
89
+ w = [1.0 if is_call else -1.0 for is_call in are_calls[payoff_count]]
90
+ w = np.asarray(w).reshape(1, -1)
91
+ k = np.asarray(strikes[payoff_count]).reshape(1, -1)
92
+ payoff = np.maximum(w * (spot - k), 0.0)
93
+ rpayoff = np.mean(payoff, axis=0)
94
+ mc_prices.append(rpayoff)
95
+ payoff_count += 1
100
96
 
101
97
  return np.asarray(mc_prices)
102
98
 
@@ -147,8 +143,8 @@ if __name__ == "__main__":
147
143
  mc_timer.print()
148
144
 
149
145
  # Convert to IV and compare against approximate closed-form
150
- import black
151
- import bachelier
146
+ import sdevpy.analytics.black as black
147
+ import sdevpy.analytics.bachelier as bachelier
152
148
  mc_ivs = []
153
149
  n_ivs = []
154
150
  for a, expiry in enumerate(EXPIRIES):