ValueError:序列的真值不明确.在尝试将函数与pandas-df一起使用时,请使用a.empty、a.bool(



我有以下代码,它会产生以下错误。我认为错误来自循环部分while epsilon > tol:。我在列"中添加了具有期望结果的小df;IV";。

第1478行,在非零中引发ValueError(ValueError:序列的真值不明确。使用a.empty、a.bool((、a.item((、.any((或.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

我设法找到了一个解决方案,它是:

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)

它很难看,可能效率也不高,尤其是对于较大的数据集,所以如果有人能改进这一点,我将不胜感激。

你说得对。

您想以df.iterrows((的形式对df的每一行进行计算吗?

否则,按照目前的情况,您将为calc函数中的每个df['x']调用传递一个序列,因此您的epsilon和tol实际上是一个序列而不是绝对值。或者,地图功能在这里可能对广播您的功能很有用。

#  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()])

很难说数据集中的列数是多少,但如果你想一次在计算中传递一行,它应该是这样的。

itetuple可以用来避免重命名所有内容:

#  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()])

最新更新