Точка сходимости в объекте списка Python

#python #list #optimization

Вопрос:

У меня есть объект списка, который в основном принимает разницу между двумя значениями. Это проблема оптимизации, в которой я пытаюсь определить значение, где оно ближе к нулю, чтобы я мог найти локальные минимумы. Объект списка будет иметь значения из [-100,-90,-80,…0.0001,…80,90,100].

 import numpy as np
import scipy.stats as sp

def BSM_Call(S,K,T,r,Sigma):
    d1 = (np.log(S/K)   (r Sigma**2/2)*T) / (Sigma*np.sqrt(T))
    d2 = d1 - (Sigma*np.sqrt(T))
    Call = S*sp.norm.cdf(d1) - K*np.exp(-r*T)*sp.norm.cdf(d2)
    return Call 

ini_vol = 0.0001
rng = np.arange(0.0001,1,0.0001)
diff = []
for i in range(len(rng)):
    diff.append(67.33923210204784 - BSM_Call(4395.26,4400,31/365,0,ini_vol rng[i]))   
 

После определения оптимизированной точки я хотел бы получить значение, соответствующее ini_vol rng[i].

Комментарии:

1. Можете ли вы показать код для BSM_Call(). Кроме того, я не понимаю, зачем вам нужен массив numpy. Просто начните с переменной, равной 0,0001, затем добавьте к ней 0,0001, пока она меньше 1

2. Хорошо, значит, это Блэк-Скоулз. Теперь нам нужно знать, что вы подразумеваете под «оптимизированной точкой». Как бы вы это определили?

Ответ №1:

Мне кажется, что вы пытаетесь найти значение для Сигмы, которое дает ближайший результат к нулю (после вычитания возвращаемого значения из BSM_Call и константы 67.339…). Предполагая, что это так, вот что я бы сделал:-

 import numpy as np
import scipy.stats as sp


def BSM(S, K, T, r, Sigma):
    _St = Sigma * np.sqrt(T)
    d1 = (np.log(S / K)   (r   Sigma**2 / 2) * T) / _St
    return S * sp.norm.cdf(d1) - K * np.exp(-r * T) * sp.norm.cdf(d1 - _St)


lo = None
ini = None
for i in range(1, 10000):
    ini_vol = i / 10000
    bsm = BSM(4395.26, 4400, 31 / 365, 0, ini_vol)
    diff = 67.33923210204784 - bsm
    adiff = abs(diff)
    if lo is None or adiff < lo:
        lo = diff
        ini = ini_vol
        if lo == 0:
            break
print(f'ini_vol = {ini:.4f}')
 

Обратите внимание, что я изменил BSM_Call на BSM, чтобы подчеркнуть незначительное повышение эффективности. Также обратите внимание, что нет необходимости создавать список, так как вы можете понять это, работая в цикле. Есть вероятность раннего перерыва, поэтому я учел это