Sympy - вычисление «подразумеваемых» значений из функции - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть следующая функция:

import sympy as sy
import sympy.stats as systats
def euro_vanilla_price(S, K, T, r, vol, call=True):

    N = systats.Normal("n",0.0, 1.0)

    d1 = (sy.ln(S / K) + (r + 0.5 * vol ** 2) * T) / (vol * sy.sqrt(T))
    d2 = (sy.ln(S / K) + (r - 0.5 * vol ** 2) * T) / (vol * sy.sqrt(T))
    norm_d1 = systats.cdf(N)(d1)
    norm_d2 = systats.cdf(N)(d2)

    if call:
        price = (S * norm_d1 - K * sy.exp(-r * T) * norm_d2)
    else: price = (K * sy.exp(-r * T) *( 1-norm_d2) - S * (1-norm_d1))

    return price

I Итак, эта конкретная функция имеет 5 входов (игнорируя переменную вызова по умолчанию) и один выход. Если я передам некоторые значения следующим образом:

p,S,K,T,r, vol, call = symbols('p S K T r vol call')
exp = euro_vanilla_price(S, K, T, r, vol,call)

subs = {S:100, K:100, T:1, r:0.1, vol: 0.2}
price = exp.evalf(subs = subs)
print(price)

Тогда все прекрасно работает, и я получаю цену 13,27 ... что правильно. Однако, что я действительно хочу сделать, это передать цену и 4 других значения и вычислить недостающее значение. Итак, я хотел бы установить цену = 13,27 ... S = 100, K = 100, r = 0,1, а затем иметь «возврат» vol = 0,2. Я хотел бы, чтобы это было generi c для любого неизвестного значения, заданного другими. Я провел несколько часов, экспериментируя с различными вариантами, но безрезультатно. Раньше я делал это, написав отдельную функцию для каждого неизвестного и начав с «предположения», а затем пересчитывая цену, пока она не приблизится к допустимому значению фактической цены (бинарная отбивная). Это привело к большому количеству повторяющегося кода, поэтому хотелось бы избежать

1 Ответ

1 голос
/ 25 февраля 2020

Ваше выражение и желаемое значение и все указанные переменные, кроме одной, приведут к уравнению (возможно, сложному) для одной переменной. Это то, в чем nsoslve хорош. Все, что вам нужно, это оценить, какой, по вашему мнению, будет ответ (и для получения этого значения есть много хитростей, но иногда системы хорошо позиционируются и прощают в этом отношении, и почти любое первоначальное предположение сработает):

>>> guess = 1; val = 13.27
>>> nsolve(exp.subs({S:100, K:100, T:1, r:0.1})-val, guess).round(2)
0.20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...