场外期权系列——鲨鱼鳍期权的蒙特卡洛定价

鲨鱼鳍期权是市场上交易非常活跃的一类期权。本文将结合实际品种简要介绍这种期权,并说明如何使用Python对最简单形式的鲨鱼鳍期权进行定价。

首先声明,本文数据均为示意性数据,提供的方法也仅供交流学习用,请勿用于实操。(当然也没人这么可爱吧233)

鲨鱼鳍期权的概念

第一次听到鲨鱼鳍期权的时候我是懵逼的,我甚至以为是标的物为鲨鱼鳍的期权(手动狗头)。其实鲨鱼鳍期权就是我们常说的障碍期权(barrier option)。不过在国内场外市场都称鲨鱼鳍期权。鲨鱼鳍期权又分为欧式鲨鱼鳍和美式鲨鱼鳍,本文先介绍欧式结构,然后美式结构也能很好理解。

与普通的欧式看涨期权相比,欧式看涨鲨鱼鳍仅仅加入敲入锁定收益机制,也就是常说的障碍。对于普通期权来说,标的资产期末价格越高,买方能获得的收益也越高。而鲨鱼鳍期权则给这个收益制定了一个障碍价格,如果标的资产期末价格达到这个障碍价格,也就是常说的敲出,则买方获得敲出收益,这个敲出收益一般比普通期权能获得的期权低一点。

结合以下收益图应该能更好的帮助理解。(图示期权默认行权价等于起始价,实际中也常常这样)

看涨鲨鱼鳍收益图

如图所示,期末价格如果低于行权价,买方获得收益为保底收益2%。随着标的价格上升,买方获得的年化收益率升高。但对于鲨鱼鳍期权来说,这种上涨不是无限制的,如果期末价格大于等于期初价格的110%时,这个期权的收益率则下降为5.5%。这里的110%就是障碍价格,又称敲出价格。您看这个图它像不像一个的鳍?

了解完欧式鲨鱼鳍后,美式鲨鱼鳍也很好理解了。美式鲨鱼鳍要求逐日盯市场,在到期日前的任何一个交易日,如果当日收盘价打到了障碍价格,则这个期权就敲出了,买卖双方在这个时候就确定了双方的收益。以上面的期权为例,如果一个月后期权到期,但今天标的股票上涨了10%,则该美式鲨鱼鳍立即敲出,名义上已经是到期了。

鲨鱼鳍期权的特点

当挂钩标的温和上涨时,鲨鱼鳍期权跟普通期权的收益图完全一致,买方可按照一定的参与率分享上涨收益。但从第一个部分可以看到,由于障碍价格的存在,期权卖方的收益是有限的,因此相对于普通期权来说,鲨鱼鳍期权对卖方更有利,因此相对而言期权费更低。

因此,购买看涨鲨鱼鳍期权的投资者一般会认为未来标的资产很可能温和上涨,此时购买鲨鱼鳍期权的费用要低于购买普通期权的费用。

鲨鱼鳍期权的蒙特卡洛定价

本部分将提供利用蒙特卡洛方法给美式看涨鲨鱼鳍期权定价的Python代码。不知道什么是蒙特卡洛方法的可以点这里看看。

此处假设标的资产价格路径服从几何布朗运动,即:

其中为标的资产时刻的价格,为标的资产的初始价格,为标的资产收益率,为标的资产价格的波动率,或标准差,是一个维纳过程,也称布朗运动,简单地说,服从均值为0,方差为的正态分布,也可以理解为个标准正态分布之和。

from scipy.stats import norm
import numpy as np
import pandas as pd
import time, datetime

MC_M = 100000 # 模拟次数

# 此函数用于生成几何布朗运动价格序列
# 输入的参数S为期初价格,T为时间(年),MC_M为模拟次数
def St_MC(S,mu,T,vol):
    # 初始化标准正态分布矩阵,252为一年的交易日总数
    rdmatrix = np.random.randn(MC_M, int(252*T)) 
    rdarray = np.array(rdmatrix)
    M = rdarray.shape[0] # M为模拟次数
    N = rdarray.shape[1] # N为观察次数
    dt = np.linspace(T/N, T, N) # 观察日序列
    W = rdarray.cumsum(1) # 布朗运动累加
    # 初始化价格序列矩阵,多了一列为期初价格
    St = np.ones((M, N + 1)) * S
    # 几何布朗运动序列
    St[:, 1:] = S * np.exp((mu - 1 / 2 * vol ** 2) * dt + vol*np.sqrt(T/N)*W)
    return St

# 看涨鲨鱼鳍(美式)
# 此函数利用蒙特卡洛方法对给定的一组参数(mu, vol)定价
# K为行权价,r为无风险收益率,T为时间(年),vol为波动率
# upout为障碍价格,comp_return为敲出收益率,S为期初价格
def up_out_Am_MC(K,r,mu,T,vol,upout,comp_return,S=100):
    St = St_MC(S,mu,T,vol)
    M = St.shape[0]
    N = St.shape[1]
    f = np.zeros(M) # 初始化每次模拟的期权价格向量
    for i in range(M):
        if St[i,:].max() > upout:
            f[i] = comp_return
        else:
            f[i] = np.maximum(St[i,-1]-K,0)
    return np.exp(-r*T) * f.mean()

# 在实际定价里,我们只能获得mu和vol的大致范围。因此要对每个参数组合定价,取最大值
# vol_range为波动率范围,mu_range为标的资产收益率范围,二者均为list,
# comp_return为敲出收益
def up_out_Am(K,r,T,vol_range,mu_range,upout,comp_return):
    #rdmatrix = np.random.randn(MC_M, int(252*T))
    price = []
    # 遍历每一种(vol, mu)组合
    for vol in np.linspace(vol_range[0],vol_range[1],5):
        for mu in np.linspace(mu_range[0],mu_range[1],5):
            price.append(up_out_Am_MC(K, r, mu, T, vol, upout, comp_return))
    return  max(price) # 取对定价方有利的最大值

# 与美式鲨鱼鳍相比,欧式鲨鱼鳍不同的只是期权的回报函数不同
#看涨鲨鱼鳍(欧式)
def up_out_Eu_MC(K,r,mu,T,vol,upout,comp_return,S=100):
    St = St_MC(S,r,T,vol,r-mu)
    M = St.shape[0]
    f = np.zeros(M)
    for i in range(M):
        if St[i,-1] > upout:
            f[i] = comp_return
        else:
            f[i] = np.maximum(St[i,-1]-K,0)
    return np.exp(-r*T) * f.mean()
def up_out_Eu(K,r,T,vol_range,mu_range,upout,comp_return):
    price = []
    for vol in np.linspace(vol_range[0], vol_range[1], 5): 
        for mu in np.linspace(mu_range[0], mu_range[1], 5):
            price.append(up_out_Eu_MC(K, r, mu, T, vol, upout, comp_return))
    return max(price)

总结

嗨呀,这是我的第一篇博文,写了些实习期间经常遇到的一种期权,其实很简单,对期权有一定了解的人一看就会。那为什么我要写这篇博文呢?我看过一句话说:当你学了一些东西后一定要留下些什么。这些知识或许很简单,但多年后我可能遗忘了,我希望将他们记录下来,写博文则是一种最好的办法。

如果您觉得本文有什么问题,请您根据主页的联系方式联系我,或者在评论区留言,感谢您的支持。

你可能感兴趣的:(场外期权系列——鲨鱼鳍期权的蒙特卡洛定价)