You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用字典替代列表计算期权希腊值?如何用apply/assign替代循环?

期权希腊值计算:字典实现与无循环方案

样本DataFrame df

Date           Expiry      Strike Price  LTP    Open Int    Underlying Value    Days
2019-06-04   2019-06-27       12500     19.9    1945425         12021.65         23
2019-06-10   2019-06-27       12500      6.5    2708100         11922.70         17

原计算代码(可正常运行)

def greek(underlyingprice,strikeprice,interestrate,expirationdate,callprice):
    
    x = mibian.BS([underlyingprice,strikeprice,interestrate,expirationdate], callPrice=callprice)
    
    IV = x.impliedVolatility
    
    c = mibian.BS([underlyingprice,strikeprice,interestrate,expirationdate], volatility = IV)
    
    delta = c.callDelta
    theta = c.callTheta
    rho = c.callRho
    vega = c.vega
    gamma = c.gamma
    
    return [delta,theta,rho,vega,gamma,IV]

underlyingprice = df['Underlying Value'].values
strikeprice = df['Strike Price'].values
expirationdate = df['Days'].values
interestrate = 7.3
callprice = df['LTP'].values

final = []
for i, j, k, l in zip(underlyingprice, strikeprice, expirationdate, callprice):
    final.append(greek(i,j,interestrate,k, l))
    
final = pd.DataFrame(np.array(final))
final.columns = ['Delta','Theta','Rho','Vega','Gamma','Implied Volatility']
final[['Underlying Value','Strike Price','LTP']] = df[['Underlying Value','Strike Price','LTP']]
final.reset_index(inplace=True)
final.head()

输出结果

Delta   Theta   Rho Vega    Gamma   Implied Volatility  Underlying Value    Strike Price    LTP
0.118572    -1.772300   0.885692    5.985913    0.000574    11.459351   12021.65    12500   19.9
0.050060    -1.076517   0.274938    2.656285    0.000327    12.268066   11922.70    12500   6.5

问题1:改用字典实现存储结果

直接在循环中生成字典列表,每个字典的键对应最终DataFrame的列名,值为计算得到的希腊值或原数据,之后直接将字典列表转为DataFrame即可,无需后续手动设置列名和合并数据:

方案1:修改函数直接返回字典

def greek_dict(underlyingprice, strikeprice, interestrate, expirationdate, callprice):
    x = mibian.BS([underlyingprice, strikeprice, interestrate, expirationdate], callPrice=callprice)
    IV = x.impliedVolatility
    c = mibian.BS([underlyingprice, strikeprice, interestrate, expirationdate], volatility=IV)
    
    return {
        'Delta': c.callDelta,
        'Theta': c.callTheta,
        'Rho': c.callRho,
        'Vega': c.vega,
        'Gamma': c.gamma,
        'Implied Volatility': IV,
        'Underlying Value': underlyingprice,
        'Strike Price': strikeprice,
        'LTP': callprice
    }

interestrate = 7.3
final_dict = []
for idx, row in df.iterrows():
    res = greek_dict(row['Underlying Value'], row['Strike Price'], interestrate, row['Days'], row['LTP'])
    final_dict.append(res)

final_df = pd.DataFrame(final_dict)
final_df.reset_index(inplace=True)
final_df.head()

方案2:基于原函数结果构建字典

如果不想修改原greek函数,可基于返回的列表构建字典:

final_dict = []
for i,j,k,l in zip(underlyingprice, strikeprice, expirationdate, callprice):
    greek_vals = greek(i,j,interestrate,k,l)
    res_dict = {
        'Delta': greek_vals[0],
        'Theta': greek_vals[1],
        'Rho': greek_vals[2],
        'Vega': greek_vals[3],
        'Gamma': greek_vals[4],
        'Implied Volatility': greek_vals[5],
        'Underlying Value': i,
        'Strike Price': j,
        'LTP': l
    }
    final_dict.append(res_dict)

final_df = pd.DataFrame(final_dict)

问题2:不使用for循环,用apply实现逐行计算

利用pandas.DataFrame.apply(),指定axis=1实现逐行处理,将每行的对应字段传入修改后的函数,返回包含所有希腊值的Series,直接与原DataFrame合并:

def greek_series(row, interestrate):
    x = mibian.BS([row['Underlying Value'], row['Strike Price'], interestrate, row['Days']], callPrice=row['LTP'])
    IV = x.impliedVolatility
    c = mibian.BS([row['Underlying Value'], row['Strike Price'], interestrate, row['Days']], volatility=IV)
    
    return pd.Series({
        'Delta': c.callDelta,
        'Theta': c.callTheta,
        'Rho': c.callRho,
        'Vega': c.vega,
        'Gamma': c.gamma,
        'Implied Volatility': IV
    })

interestrate = 7.3
# 合并原DataFrame与计算结果
final_apply = df.join(df.apply(greek_series, axis=1, args=(interestrate,)))
final_apply.reset_index(inplace=True)
final_apply.head()

如果需要单独生成某几个列,也可以用assign配合lambda(效率略低于一次性返回Series):

def calculate_delta(row, interestrate):
    x = mibian.BS([row['Underlying Value'], row['Strike Price'], interestrate, row['Days']], callPrice=row['LTP'])
    IV = x.impliedVolatility
    c = mibian.BS([row['Underlying Value'], row['Strike Price'], interestrate, row['Days']], volatility=IV)
    return c.callDelta

# 按需添加其他希腊值计算函数
final_assign = df.assign(
    Delta=lambda df: df.apply(calculate_delta, axis=1, args=(7.3,)),
    # Theta=lambda df: df.apply(calculate_theta, axis=1, args=(7.3,)),
    # ...其他列同理
)

注意:apply本质仍是逐行循环,但代码更简洁、符合pandas API风格;由于mibian.BS不支持向量化输入,这是最简洁的无显式循环方案。


内容的提问来源于stack exchange,提问作者Raagib khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:00:06