Как преобразовать вычисления Normal / cdf (), которые изначально были написаны с использованием sympy.statistics, для использования sympy.stats? - PullRequest
0 голосов
/ 26 апреля 2019

Я не поспевал за изменениями в SymPy.Я смотрел на следующую формулу Блэка Шоулза: https://aaronschlegel.me/black-scholes-formula-python.html. Кажется, в SymPy был какой-то рефакторинг, поэтому он больше не работает.Как бы изменить следующее, чтобы оно снова заработало:

import sympy as sy
import sympy.statistics as systats

def euro_put_sym(S, K, T, r, sigma):        
    #S: spot price
    #K: strike price
    #T: time to maturity
    #r: interest rate
    #sigma: volatility of underlying asset

    N = systats.Normal(0.0, 1.0)

    d1 = (sy.ln(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * sy.sqrt(T))
    d2 = (sy.ln(S / K) + (r - 0.5 * sigma ** 2) * T) / (sigma * sy.sqrt(T))

    put = (K * sy.exp(-r * T) * N.cdf(-d2) - S * N.cdf(-d1))

    return put

Я получаю следующие ошибки:

В модуле 'sympy'

* 1010 нет имени 'statistics'* Невозможно импортировать 'sympy.statistics'

В частности, как теперь будут выполняться операции Normal и cdf?

Ответы [ 2 ]

1 голос
/ 27 апреля 2019

Модуль статистики в Sympy называется stats. Также Normal принимает 3 параметра. Простой пример использования показан ниже:

>>> from sympy import symbols

>>> from sympy.stats import Normal, density, cdf

>>> x, mu, sigma = symbols("x mu sigma")

>>> N = Normal("N", mu, sigma)

>>> density(N)(x)

sqrt(2)*exp(-(-mu + x)**2/(2*sigma**2))/(2*sqrt(pi)*sigma)

>>> cdf(N)(x)

erf(sqrt(2)*(-mu + x)/(2*sigma))/2 + 1/2

Для получения дополнительной информации см. Документы Sympy Stats и Документы нормального распределения .

Теперь по вашему делу, позвольте мне объяснить, что вы должны делать.

import sympy as sy
import sympy.stats as systats

def euro_put_sym(S, K, T, r, sigma):        
    #S: spot price
    #K: strike price
    #T: time to maturity
    #r: interest rate
    #sigma: volatility of underlying asset

    N = systats.Normal('N', 0.0, 1.0)

    d1 = (sy.ln(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * sy.sqrt(T))
    d2 = (sy.ln(S / K) + (r - 0.5 * sigma ** 2) * T) / (sigma * sy.sqrt(T))

    put = (K * sy.exp(-r * T) * systats.cdf(N)(-d2) - S * systats.cdf(N)(-d1))

    return put

Теперь

S, K, T, r, sigma = sy.symbols("S K T r sigma")
sy.pprint(euro_put_sym(S, K, T, r, sigma), use_unicode=False)

дает вывод как

  /       /      ___ /  /             2\      /S\\\\           /       /      
  |       |0.5*\/ 2 *|T*\r - 0.5*sigma / + log|-||||           |       |0.5*\/
  |       |          \                        \K//||           |       |      
  |    erf|---------------------------------------||           |    erf|------
  |       |                ___                    ||           |       |      
  |1      \              \/ T *sigma              /|  -T*r     |1      \      
K*|- - --------------------------------------------|*e     - S*|- - ----------
  \2                        2                      /           \2             

___ /  /             2\      /S\\\\
 2 *|T*\r + 0.5*sigma / + log|-||||
    \                        \K//||
---------------------------------||
          ___                    ||
        \/ T *sigma              /|
----------------------------------|
           2                      /

Это ожидаемый результат?

Я проверил это на примере по предоставленной вами ссылке, и результаты совпадают.

>>> euro_put_sym(50, 100, 1, 0.05, 0.25)
-25*erf(1.22379436111989*sqrt(2)) + 22.5614712250357 + 47.5614712250357*erf(1.34879436111989*sqrt(2))
0 голосов
/ 26 апреля 2019

Я думаю, что это правильное преобразование из старого пакета статистики в новый.Что вы, ребята, думаете?

import sympy as sy
import sympy.stats as systats

def euro_put_sym(S, K, T, r, sigma):        
    #S: spot price
    #K: strike price
    #T: time to maturity
    #r: interest rate
    #sigma: volatility of underlying asset

    N = systats.Normal('x', 0.0, 1.0)

    d1 = (sy.ln(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * sy.sqrt(T))
    d2 = (sy.ln(S / K) + (r - 0.5 * sigma ** 2) * T) / (sigma * sy.sqrt(T))

    put = (K * sy.exp(-r * T) * systats.cdf(N)(-d2) - S * systats.cdf(N)(-d1))

    return put
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...