#python #pandas #numpy #loops
#python #панды #numpy #циклы
Вопрос:
У меня есть следующий код, который выдает следующую ошибку. Я думаю, что ошибка исходит из раздела цикла while epsilon > tol:
. Я добавил небольшой df с желаемыми результатами в столбец «IV».
строка 1478, в ненулевом повышении ValueError( ValueError: значение истинности ряда неоднозначно. Используйте.empty, a.bool(), a.item(), a.any() или a.all() .
def d(sigma, S, K, r, q, t):
d1 = 1 / (sigma * np.sqrt(t)) * ( np.log(S/K) (r - q sigma**2/2) * t)
d2 = d1 - sigma * np.sqrt(t)
return d1, d2
def call_price(sigma, S, K, r, q, t, d1, d2):
C = norm.cdf(d1) * S * np.exp(-q * t)- norm.cdf(d2) * K * np.exp(-r * t)
return C
# From Put call Prity
def put_price(sigma, S, K, r, q, t, d1, d2):
P = - S * np.exp(-q * t) K * np.exp(-r * t) call_price(sigma, S, K, r, q, t, d1, d2)
return P
def calc_put_iv(S,K,t,r,q,P0,tol,epsilon,count,max_iter,vol):
while epsilon > tol:
# Count how many iterations and make sure while loop doesn't run away
count = 1
print(count)
if count >= max_iter:
print('Breaking on count')
break;
# Log the value previously calculated to computer percent change
# between iterations
orig_vol = vol
# Calculate the vale of the call price
d1, d2 = d(vol, S, K, r,q, t)
function_value = put_price(vol, S, K, r, q, t, d1, d2) - P0
# Calculate vega, the derivative of the price with respect to
# volatility
vega = S * norm.pdf(d1) * np.sqrt(t)* np.exp(-q * t)
# Update for value of the volatility
vol = -function_value / vega vol
# Check the percent change between current and last iteration
epsilon = abs( (vol - orig_vol) / orig_vol )
print(vol)
return vol
# Print out the results
df["IV"] = calc_put_iv(df["Stock Price"], df["Strike"], df["Length / 365"],0.001,df["Div Yield"],df["Premium"],1e-8,1,0,1000,.5)
Strike Stock Price Premium Length Div Yield Length / 365 IV
470 407.339996 65.525 17 0 0.008219178 1.3080322786580916
400 407.339996 14.375 3 0 0.008219178 1.2202688594244515
490 490.649994 17.35 17 0 0.046575342 0.4190594565249461
Ответ №1:
Мне удалось найти решение, которое:
list_of_iv = []
# Print out the results
for index, row in df.iterrows():
iv = calc_put_iv(df["Stock Price"].iloc[index], df["Strike"].iloc[index], df["Length/365"].iloc[index],0.001,df["Div Yield"].iloc[index],df["Premium"].iloc[index],1e-8,1,0,1000,.5)
list_of_iv.append(iv)
df['Put IV'] = pd.Series(list_of_iv)
Это довольно уродливо и, вероятно, не так эффективно, особенно с большими наборами данных, поэтому я был бы очень признателен, если кто-нибудь сможет улучшить это.
Ответ №2:
Вы правы.
Вы хотели выполнить вычисления для каждой строки df как df.iterrows() ?
В противном случае, как и в настоящее время, вы передаете серию для каждого вызова df[‘x’] в вашей функции calc, поэтому ваши epsilon и tol на самом деле являются серией, а не абсолютным значением. В качестве альтернативы, функция map может быть полезна здесь для трансляции ваших функций.
# Print out the results
df["IV"] = list([calc_put_iv(row[1], row[0], row[5],0.001,row[4],row[2],1e-8,1,0,1000,.5) for row in df.iterrows()])
Трудно сказать, какое количество столбцов из dset , но это должно выглядеть примерно так, если вы хотите передавать в свои вычисления по 1 строке за раз.
itertuple можно использовать, чтобы обойти переименование всего:
# Print out the results
df["IV"] = list([calc_put_iv(df["Stock Price"], df["Strike"], df["Length / 365"],0.001,df["Div Yield"],df["Premium"],1e-8,1,0,1000,.5) for df in df.itertuples()])
Комментарии:
1. Привет, Клинтон, я хотел бы выполнить вычисления для каждой строки да. Я не могу сказать, что я особенно хорошо разбираюсь в python не могли бы вы подробнее рассказать об этих двух методах?