sdevpy 1.0.6__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 (235) hide show
  1. {sdevpy-1.0.6 → sdevpy-1.0.7}/PKG-INFO +7 -1
  2. {sdevpy-1.0.6 → sdevpy-1.0.7}/pyproject.toml +14 -6
  3. sdevpy-1.0.7/sdevpy/__init__.py +21 -0
  4. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/analytics/americantree.py +3 -3
  5. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/analytics/bachelier.py +1 -0
  6. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/analytics/black.py +4 -4
  7. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/analytics/fbsabr.py +86 -88
  8. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/analytics/mcheston.py +76 -80
  9. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/analytics/mcsabr.py +92 -95
  10. {sdevpy-1.0.6 → 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.6 → sdevpy-1.0.7}/sdevpy/cointegration/mean_reversion.py +117 -128
  15. {sdevpy-1.0.6 → 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.6 → sdevpy-1.0.7}/sdevpy/machinelearning/datasets.py +11 -8
  18. {sdevpy-1.0.6/sdevpy/machinelearning → sdevpy-1.0.7/sdevpy/machinelearning/keras}/callbacks.py +1 -3
  19. {sdevpy-1.0.6/sdevpy/machinelearning → sdevpy-1.0.7/sdevpy/machinelearning/keras}/learningmodel.py +6 -4
  20. {sdevpy-1.0.6/sdevpy/machinelearning → sdevpy-1.0.7/sdevpy/machinelearning/keras}/learningschedules.py +1 -3
  21. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/attention.py +3 -5
  22. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/chat.py +2 -2
  23. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/datasets.py +0 -1
  24. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/gpt.py +7 -6
  25. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/instructions.py +8 -8
  26. sdevpy-1.0.6/sdevpy/llms/ModelConverter.py → sdevpy-1.0.7/sdevpy/machinelearning/llms/modelconverter.py +3 -5
  27. {sdevpy-1.0.6/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.6 → sdevpy-1.0.7}/sdevpy/maths/interpolation.py +73 -35
  37. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/maths/optimization.py +30 -27
  38. sdevpy-1.0.7/sdevpy/maths/rand/__init__.py +0 -0
  39. sdevpy-1.0.7/sdevpy/maths/rand/correlations.py +44 -0
  40. sdevpy-1.0.7/sdevpy/maths/rand/pathconstruction.py +180 -0
  41. sdevpy-1.0.7/sdevpy/maths/rand/rng.py +148 -0
  42. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/maths/regression.py +1 -1
  43. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/maths/specialfunctions.py +1 -0
  44. sdevpy-1.0.7/sdevpy/models/__init__.py +0 -0
  45. sdevpy-1.0.7/sdevpy/models/assetmodels.py +90 -0
  46. sdevpy-1.0.7/sdevpy/models/multiasset_heston.py +37 -0
  47. sdevpy-1.0.7/sdevpy/montecarlo/__init__.py +0 -0
  48. sdevpy-1.0.7/sdevpy/montecarlo/mcpricer.py +188 -0
  49. sdevpy-1.0.7/sdevpy/montecarlo/mcrun.py +102 -0
  50. sdevpy-1.0.7/sdevpy/montecarlo/pathgenerator.py +31 -0
  51. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/__init__.py +0 -0
  52. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/basic.py +669 -0
  53. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/cashflows.py +32 -0
  54. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/exotics.py +96 -0
  55. sdevpy-1.0.7/sdevpy/montecarlo/payoffs/vanillas.py +76 -0
  56. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/montecarlo/smoothers.py +1 -9
  57. sdevpy-1.0.7/sdevpy/pde/__init__.py +0 -0
  58. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/pde/forwardpde.py +16 -19
  59. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/pde/pdeschemes.py +1 -4
  60. sdevpy-1.0.7/sdevpy/projects/__init__.py +0 -0
  61. sdevpy-1.0.7/sdevpy/projects/aad/__init__.py +0 -0
  62. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/aad/aad_mc_nd.py +3 -3
  63. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/chat_gpt2.py +3 -3
  64. sdevpy-1.0.7/sdevpy/projects/raschka/__init__.py +0 -0
  65. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/raschka/ch2_working_with_text.py +3 -3
  66. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/raschka/ch3_coding_attention.py +3 -3
  67. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/raschka/ch4_gpt_model.py +3 -3
  68. sdevpy-1.0.6/sdevpy/projects/raschka/ch5_loadGPT2.py → sdevpy-1.0.7/sdevpy/projects/raschka/ch5_loadgpt2.py +2 -2
  69. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/raschka/ch5_pretraining.py +7 -7
  70. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/raschka/ch7_instruction_finetuning.py +2 -2
  71. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/raschka/raschka_datasetloader.py +2 -2
  72. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/raschka/raschka_dnn.py +1 -1
  73. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/raschka/raschka_gpt_download.py +1 -1
  74. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/set_limits.py +5 -6
  75. sdevpy-1.0.7/sdevpy/projects/stovol/__init__.py +0 -0
  76. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/stovol/stovolplot.py +1 -1
  77. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/stovol/stovoltrain.py +0 -1
  78. sdevpy-1.0.7/sdevpy/projects/stovolinverse/__init__.py +0 -0
  79. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/stovolinverse/stovolinvtrain.py +5 -5
  80. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/update_db.py +3 -3
  81. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/settings.py +7 -6
  82. sdevpy-1.0.7/sdevpy/tensorflow/__init__.py +0 -0
  83. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tensorflow/tf_black.py +4 -4
  84. sdevpy-1.0.7/sdevpy/tests/test.py +82 -0
  85. sdevpy-1.0.7/sdevpy/tests/test_algos.py +125 -0
  86. sdevpy-1.0.7/sdevpy/tests/test_dates.py +58 -0
  87. sdevpy-1.0.7/sdevpy/tests/test_impliedvol.py +100 -0
  88. sdevpy-1.0.7/sdevpy/tests/test_interpolation.py +55 -0
  89. sdevpy-1.0.7/sdevpy/tests/test_localvol.py +0 -0
  90. sdevpy-1.0.7/sdevpy/tests/test_marketdata.py +48 -0
  91. sdevpy-1.0.7/sdevpy/tests/test_mc.py +85 -0
  92. sdevpy-1.0.7/sdevpy/tests/test_pde.py +116 -0
  93. sdevpy-1.0.7/sdevpy/tests/test_timegrids.py +49 -0
  94. sdevpy-1.0.7/sdevpy/tests/test_utils.py +67 -0
  95. sdevpy-1.0.7/sdevpy/tests/test_yieldcurves.py +49 -0
  96. sdevpy-1.0.7/sdevpy/thirdparty/__init__.py +0 -0
  97. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/__init__.py +1 -0
  98. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/constants.py +1 -0
  99. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/erf_cody.py +1 -0
  100. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/exceptions.py +1 -0
  101. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/lets_be_rational.py +1 -0
  102. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/normaldistribution.py +1 -0
  103. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/rationalcubic.py +1 -0
  104. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/__init__.py +1 -0
  105. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black/__init__.py +1 -0
  106. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/black/greeks/__init__.py +0 -0
  107. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black/greeks/analytical.py +1 -0
  108. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black/greeks/numerical.py +1 -0
  109. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black/implied_volatility.py +1 -0
  110. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes/__init__.py +1 -0
  111. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/black_scholes/greeks/__init__.py +0 -0
  112. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes/greeks/analytical.py +1 -0
  113. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes/greeks/numerical.py +1 -0
  114. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes/implied_volatility.py +1 -0
  115. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes_merton/__init__.py +1 -0
  116. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/__init__.py +0 -0
  117. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/analytical.py +1 -0
  118. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks/numerical.py +1 -0
  119. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/black_scholes_merton/implied_volatility.py +1 -0
  120. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/__init__.py +1 -0
  121. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/constants.py +1 -0
  122. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/distributions.py +1 -0
  123. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/doctest_helper.py +1 -0
  124. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/exceptions.py +1 -0
  125. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/helpers/numerical_greeks.py +1 -0
  126. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/__init__.py +1 -0
  127. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black/__init__.py +1 -0
  128. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/__init__.py +0 -0
  129. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/analytical.py +1 -0
  130. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black/greeks/numerical.py +1 -0
  131. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black/implied_volatility.py +1 -0
  132. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/__init__.py +1 -0
  133. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/__init__.py +0 -0
  134. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/analytical.py +1 -0
  135. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks/numerical.py +1 -0
  136. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/implied_volatility.py +1 -0
  137. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/__init__.py +1 -0
  138. sdevpy-1.0.7/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/__init__.py +0 -0
  139. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/analytical.py +1 -0
  140. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks/numerical.py +1 -0
  141. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/implied_volatility.py +1 -0
  142. sdevpy-1.0.7/sdevpy/timeseries/__init__.py +0 -0
  143. sdevpy-1.0.7/sdevpy/timeseries/backtesting.py +86 -0
  144. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/timeseries/cointegration.py +22 -22
  145. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/timeseries/meanreversion.py +47 -48
  146. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/timeseries/timeseriestools.py +15 -18
  147. sdevpy-1.0.7/sdevpy/tools/__init__.py +0 -0
  148. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/algos.py +5 -3
  149. sdevpy-1.0.7/sdevpy/tools/book.py +51 -0
  150. sdevpy-1.0.7/sdevpy/tools/dates.py +31 -0
  151. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/network.py +5 -2
  152. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/pydotnet.py +8 -6
  153. sdevpy-1.0.7/sdevpy/tools/scalendar.py +287 -0
  154. sdevpy-1.0.7/sdevpy/tools/speriods.py +25 -0
  155. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/timegrids.py +35 -6
  156. sdevpy-1.0.7/sdevpy/tools/utils.py +52 -0
  157. sdevpy-1.0.7/sdevpy/tree/__init__.py +0 -0
  158. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tree/trees.py +1 -16
  159. sdevpy-1.0.7/sdevpy/volatility/__init__.py +0 -0
  160. sdevpy-1.0.7/sdevpy/volatility/impliedvol/__init__.py +0 -0
  161. {sdevpy-1.0.6/sdevpy/models → sdevpy-1.0.7/sdevpy/volatility/impliedvol}/impliedvol.py +9 -5
  162. sdevpy-1.0.7/sdevpy/volatility/impliedvol/impliedvol_calib.py +125 -0
  163. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/__init__.py +0 -0
  164. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/volatility/impliedvol}/models/biexp.py +57 -64
  165. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/cubicvol.py +205 -0
  166. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/gsvi.py +63 -0
  167. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/volatility/impliedvol}/models/svi.py +18 -29
  168. sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/tssvi1.py +143 -0
  169. sdevpy-1.0.6/sdevpy/models/svivol.py → sdevpy-1.0.7/sdevpy/volatility/impliedvol/models/vsvi.py +51 -50
  170. sdevpy-1.0.7/sdevpy/volatility/impliedvol/optionsurface.py +167 -0
  171. sdevpy-1.0.7/sdevpy/volatility/impliedvol/zerosurface.py +251 -0
  172. sdevpy-1.0.7/sdevpy/volatility/localvol/__init__.py +0 -0
  173. sdevpy-1.0.7/sdevpy/volatility/localvol/localvol.py +92 -0
  174. sdevpy-1.0.7/sdevpy/volatility/localvol/localvol_calib.py +303 -0
  175. sdevpy-1.0.7/sdevpy/volatility/localvol/localvol_factory.py +201 -0
  176. sdevpy-1.0.7/sdevpy/volsurfacegen/__init__.py +0 -0
  177. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/volsurfacegen/mchestongenerator.py +2 -2
  178. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/volsurfacegen/mczabrgenerator.py +1 -1
  179. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/volsurfacegen/sabrgenerator.py +24 -34
  180. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/volsurfacegen/smilegenerator.py +3 -4
  181. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy.egg-info/PKG-INFO +7 -1
  182. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy.egg-info/SOURCES.txt +89 -28
  183. sdevpy-1.0.7/sdevpy.egg-info/requires.txt +8 -0
  184. sdevpy-1.0.6/sdevpy/cointegration/back_testing.py +0 -233
  185. sdevpy-1.0.6/sdevpy/cointegration/black_analytics.py +0 -45
  186. sdevpy-1.0.6/sdevpy/cointegration/coint_trading.py +0 -839
  187. sdevpy-1.0.6/sdevpy/cointegration/data_io.py +0 -225
  188. sdevpy-1.0.6/sdevpy/cointegration/implied_vol.py +0 -116
  189. sdevpy-1.0.6/sdevpy/cointegration/plotting.py +0 -296
  190. sdevpy-1.0.6/sdevpy/cointegration/run_unit_test.py +0 -572
  191. sdevpy-1.0.6/sdevpy/cointegration/utils.py +0 -477
  192. sdevpy-1.0.6/sdevpy/market/volsurface.py +0 -21
  193. sdevpy-1.0.6/sdevpy/maths/constants.py +0 -7
  194. sdevpy-1.0.6/sdevpy/maths/rand.py +0 -99
  195. sdevpy-1.0.6/sdevpy/models/localvol.py +0 -74
  196. sdevpy-1.0.6/sdevpy/models/localvol_calib.py +0 -301
  197. sdevpy-1.0.6/sdevpy/models/localvol_factory.py +0 -109
  198. sdevpy-1.0.6/sdevpy/montecarlo/singlefactormc.py +0 -11
  199. sdevpy-1.0.6/sdevpy/test.py +0 -66
  200. sdevpy-1.0.6/sdevpy/timeseries/backtesting.py +0 -91
  201. sdevpy-1.0.6/sdevpy/tools/utils.py +0 -42
  202. sdevpy-1.0.6/sdevpy.egg-info/requires.txt +0 -2
  203. {sdevpy-1.0.6 → sdevpy-1.0.7}/README.md +0 -0
  204. {sdevpy-1.0.6/sdevpy/thirdparty/py_vollib/black/greeks → sdevpy-1.0.7/sdevpy/analytics}/__init__.py +0 -0
  205. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/analytics/sabr.py +0 -0
  206. {sdevpy-1.0.6/sdevpy/thirdparty/py_vollib/black_scholes/greeks → sdevpy-1.0.7/sdevpy/cointegration}/__init__.py +0 -0
  207. {sdevpy-1.0.6/sdevpy/thirdparty/py_vollib/black_scholes_merton/greeks → sdevpy-1.0.7/sdevpy/machinelearning}/__init__.py +0 -0
  208. {sdevpy-1.0.6/sdevpy/thirdparty/py_vollib/ref_python/black/greeks → sdevpy-1.0.7/sdevpy/machinelearning/keras}/__init__.py +0 -0
  209. {sdevpy-1.0.6/sdevpy/machinelearning → sdevpy-1.0.7/sdevpy/machinelearning/keras}/topology.py +0 -0
  210. {sdevpy-1.0.6/sdevpy/thirdparty/py_vollib/ref_python/black_scholes/greeks → sdevpy-1.0.7/sdevpy/machinelearning/llms}/__init__.py +0 -0
  211. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/textgen.py +0 -0
  212. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/machinelearning}/llms/tokenizers.py +0 -0
  213. {sdevpy-1.0.6/sdevpy/thirdparty/py_vollib/ref_python/black_scholes_merton/greeks → sdevpy-1.0.7/sdevpy/market}/__init__.py +0 -0
  214. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/maths/integration.py +0 -0
  215. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/maths/metrics.py +0 -0
  216. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/maths/sets.py +0 -0
  217. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/maths/tridiag.py +0 -0
  218. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/aad/aad_mc.py +0 -0
  219. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/datafiles.py +0 -0
  220. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/stovol/stovolgen.py +0 -0
  221. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/projects/stovolinverse/stovolinvgen.py +0 -0
  222. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tensorflow/tf_metrics.py +0 -0
  223. {sdevpy-1.0.6/sdevpy → sdevpy-1.0.7/sdevpy/tests}/__init__.py +0 -0
  224. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/thirdparty/py_lets_be_rational/numba_helper.py +0 -0
  225. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/clipboard.py +0 -0
  226. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/constants.py +0 -0
  227. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/filemanager.py +0 -0
  228. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/jsonmanager.py +0 -0
  229. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/tools/timer.py +0 -0
  230. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/volsurfacegen/fbsabrgenerator.py +0 -0
  231. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/volsurfacegen/mcsabrgenerator.py +0 -0
  232. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy/volsurfacegen/stovolfactory.py +0 -0
  233. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy.egg-info/dependency_links.txt +0 -0
  234. {sdevpy-1.0.6 → sdevpy-1.0.7}/sdevpy.egg-info/top_level.txt +0 -0
  235. {sdevpy-1.0.6 → sdevpy-1.0.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdevpy
3
- Version: 1.0.6
3
+ Version: 1.0.7
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
@@ -11,6 +11,12 @@ Requires-Python: >=3.6
11
11
  Description-Content-Type: text/markdown
12
12
  Requires-Dist: pandas
13
13
  Requires-Dist: numpy
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
14
20
 
15
21
  # SDev.Python
16
22
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sdevpy"
7
- version = "1.0.6"
7
+ version = "1.0.7"
8
8
  license-files = []
9
9
  authors = [{ name="Sebastien Gurrieri", email="sebgur@gmail.com" }]
10
10
  description = "Python package for Finance"
@@ -14,17 +14,25 @@ classifiers = [
14
14
  "Programming Language :: Python :: 3",
15
15
  "Operating System :: OS Independent",
16
16
  ]
17
- dependencies = ["pandas", "numpy"]
18
- #dependencies = [
19
- # "pandas","pyperclip","numpy","tensorflow",
20
- # "scikit-learn", "tensorflow_probability", "silence_tensorflow"
21
- #]
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
22
 
23
23
  [tool.setuptools.packages.find]
24
24
  where = ["."]
25
25
  include = ["sdevpy*", "notebooks*"] # Only include these
26
26
  #exclude = ["notebooks*", "spreadsheets*"] # Exclude these
27
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
+
28
36
  [project.urls]
29
37
  "Git page" = "https://github.com/sebgur/SDev.Python"
30
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_):
@@ -1,14 +1,14 @@
1
1
  """ Utilities for Black-Scholes model """
2
2
  import numpy as np
3
+ # import numpy.typing as npt
3
4
  import scipy.stats
4
5
  from scipy.optimize import minimize_scalar
5
6
  from sdevpy.thirdparty.py_vollib.black import implied_volatility as jaeckel
6
- from sdevpy import settings
7
7
 
8
8
  N = scipy.stats.norm.cdf
9
9
 
10
10
 
11
- def price(expiry, strike, is_call, fwd, vol):
11
+ def price(expiry: float, strike: float, is_call: bool, fwd: float, vol: float) -> float:
12
12
  """ Option price under the Black-Scholes model """
13
13
  w = 1.0 if is_call else -1.0
14
14
  s = vol * np.sqrt(expiry)
@@ -17,7 +17,7 @@ def price(expiry, strike, is_call, fwd, vol):
17
17
  return w * (fwd * N(w * d1) - strike * N(w * d2))
18
18
 
19
19
 
20
- def implied_vol_jaeckel(expiry, strike, is_call, fwd, fwd_price):
20
+ def implied_vol_jaeckel(expiry: float, strike: float, is_call: bool, fwd: float, fwd_price: float) -> float:
21
21
  """ Black-Scholes implied volatility using P. Jaeckel's 'Let's be rational' method,
22
22
  from package py_vollib. Install with pip install py_vollib or at
23
23
  https://pypi.org/project/py_vollib/. Unfortunately we found it has instabilities
@@ -28,7 +28,7 @@ def implied_vol_jaeckel(expiry, strike, is_call, fwd, fwd_price):
28
28
  return iv
29
29
 
30
30
 
31
- def implied_vol(expiry, strike, is_call, fwd, fwd_price):
31
+ def implied_vol(expiry: float, strike: float, is_call: bool, fwd: float, fwd_price: float) -> float:
32
32
  """ Direct method by numerical inversion using Brent """
33
33
  options = {'xtol': 1e-4, 'maxiter': 100, 'disp': False}
34
34
  xmin = 1e-6
@@ -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):