再次观测波动率

年前12月18号写过一篇对波动率的观测,当时市场隐含波动率在逐步攀高,而我的结论是已实现波动率没有持续 上行的趋势。

下图是已实现波动率的两种度量,日内和日间。可以看到我看空的时间点没问题,几乎可以认为时间点选的很好,不过这只是图上看,后面有个尖点在图上容易不当做一回事,但是交易日内碰到这样的,那感觉是不一样的。但事后来看,对已实现波动率的判断没有问题。落实到我的操作上,当时虽然日内波动有几个交易日上来一点,但认为还是显著低于隐含波动率的,因此做空gamma,这个操作问题不大。

不过在隐含波动率上,但是市场没有特别给面子,19,20两天标的继续下跌,市场隐含波动率继续升高,然后才开始回落,下图是最近三个月的隐含波动率图,上交所发布的。在我觉得隐含波动率被高估之后,市场隐含波动率维持高位维持了一周左右,期间标的在19和20号都轻微下跌,因此期权市场有点恐慌的味道。

我在19号做空gamma的同时,把vega几乎调整成了正值,这点操作完全错误,特别是在看对已实现波动率的情况下,这也就是自己在交易时,过于保守。不过但是想的是,做空gamma的同时,要避免黑天鹅事件,就是主要就是指16号etf跌了2.2%,最多跌了3%多,因此买了很多的深度虚值的认沽,这本来不是问题,保守稳健本来就是自己的风格。

但是现在反思,我错误的地方在于,在买了深度虚值的认沽的同时,没有卖空平值认沽。我看空已实现波动率,但是对隐含波动率确偷偷的认为不会轻易下跌,甚至可能轻微上涨。

可实际上,就算隐含波动率上涨,涨幅也不大,因此,我至少可以做平vega,因此可以认为是交易上的失误之处。

Posted in 思考评论 | Tagged | Leave a comment

美式期权baw定价的python实现

这一年多,写小程序的语言,逐步从matalb转到了python。实际上,我觉得MATLAB对于我来说,要友好很多,帮助文件论述清晰,还有详尽的示例,而且相关工具函数齐备,临时做些计算非常方便。不过,知乎上提及金融分析,基本上都是python了,而且社区论坛python也要活跃很多。虽然这些论坛主要是搞程序的在做,但对新进入的人来说,肯定优选python作为入门工具了。Matlab在金融工程里面的份额肯定要减少很多了。

# -*- coding: utf-8 -*-
"""
__author__ = 'laofish'
__title__=pyderivatives_fun.py
__mtime__ = 2017-01-07
"""

import numpy as np
import time
import pandas as pd
from optbkfun import *
from scipy.stats import norm
# from statsmodels import *
import scipy.optimize as opt


from math import * # cmath支持负数


class opttypeerr(Exception):
    """自定义期权类型错误"""

    # 上面这种语法实际上是一个类的继承语法
    def __init__(self, value):
        Exception.__init__(self)
        self.value = "期权类型错误"

def bsprice(S,K,sigma,T,r):
    """普通期权的bs定价公式"""

    d1=(log(S/K)+(r+sigma**2/2)*T)/(sigma*sqrt(T))
    d2=d1-sigma*sqrt(T)

    c=S*norm.cdf(d1)-K*exp(-r*T)*norm.cdf(d2)
    p=K*exp(-r*T)*norm.cdf(-d2)-S*norm.cdf(-d1)

    return [c,p]

def bsmprice(S,K,sigma,T,r,q):
    """普通期权的bsm定价公式,带股息率"""
    d1=(log(S/K)+(r-q+sigma**2/2)*T)/(sigma*sqrt(T))
    d2=d1-sigma*sqrt(T)

    c=S*exp(-q*T)*norm.cdf(d1)-K*exp(-r*T)*norm.cdf(d2)
    p=K*exp(-r*T)*norm.cdf(-d2)-S*exp(-q*T)*norm.cdf(-d1)

    return [c,p]


def futOptPrice(F,K,sigma,T,r):
    """black76 期货期权定价公式"""
    # sigma为期货波动率
    # 期货和期权的到期日不需要一致
    d1=(log(F/K)+sigma**2*T/2)/(sigma*sqrt(T))
    d2=d1-sigma*sqrt(T)

    c=exp(-r*T)*(F*norm.cdf(d1)-K*norm.cdf(d2))
    p=exp(-r*T)*(K*norm.cdf(-d2)-F*norm.cdf(-d1))

    return [c,p]

def imp_br(c,p,S,K,r,T):
    """计算隐含股息率"""
    q=-1/T*log((c-p+K*exp(-r*T))/S)

    return q

def findSx(Sx,K,r,q,v,T,PutCall):
    """找到美式期权提前行权的Sx"""

    n = 2 * (r - q) / v ** 2
    k = 2 * r / v ** 2 / (1 - exp(-r * T))

    sigma=v

    if Sx<0:
        y=1e1000
    elif PutCall=='C':
        q2 = (1-n+sqrt((n-1)**2+4*k))/2
        y = (bsmprice(Sx,K,sigma,T,r,q)[0]
             + (1 - exp(-q * T) * norm.cdf((log(Sx / K) + (r - q + v **2 / 2)) / v / sqrt(T))) * Sx / q2
             - Sx + K) ** 2
    elif PutCall=='P':
        q1 = (1 - n - sqrt((n - 1) ** 2 + 4 * k)) / 2
        y = (bsmprice(Sx,K,sigma,T,r,q)[1]
             - (1 - exp(-q * T) * norm.cdf(-(log(Sx / K) + (r - q + v ** 2 / 2)) / v / sqrt(T))) * Sx / q1
             + Sx - K) ** 2
    else:
        raise opttypeerr

    return y




# def findSx_baw(x)

def bawPrice(S,K,sigma,T,r,q):

    """美式期权baw定价近似解法"""
    v=sigma

    [c,p]=bsmprice(S,K,sigma,T,r,q)
    start = S

    func=lambda s:findSx(s, K, r, q, v, T, 'C')
    data = opt.fmin(func, start)
    Sx=data[0]

    # print(data)
    d1 = (log(Sx / K) + (r - q + v ** 2 / 2)) / v / sqrt(T)
    n = 2 * (r - q) / v ** 2
    k = 2 * r / v ** 2 / (1 - exp(-r * T))
    q2 = (1 - n + sqrt((n - 1) ** 2 + 4 * k)) / 2
    A2 = Sx * (1 - exp(-q * T) * norm.cdf(d1)) / q2
    if S < Sx:
        ac = c + A2 * (S / Sx) ** q2
    else:
        ac = S - K

    print(Sx)

    func = lambda s: findSx(s, K, r, q, v, T, 'P')
    data= opt.fmin(func, start)
    Sx=data[0]

    d1 = (log(Sx/K) + (r - q + v ** 2 / 2)) / v / sqrt(T)
    n = 2 * (r - q) / v ** 2
    k = 2 * r / v ** 2 / (1 - exp(-r * T))
    q1 = (1 - n - sqrt((n - 1) ** 2 + 4 * k)) / 2
    A1 = -Sx * (1 - exp(-q * T) * norm.cdf(-d1)) / q1
    if S > Sx:
        ap = p + A1 * (S / Sx) ** q1
    else:
        ap = K - S

    print(Sx)

    return [ac,ap]






if __name__=='__main__':
    try:
        bawPrice(100, 150, 0.2, 0.3, 0.04, 0.01)
        print(bsprice(100,100,0.2,1,0.05))
        print(futOptPrice(20, 18, 0.25, 4/12, 0.09))

    except opttypeerr as e:
        print(e.value)



Posted in 学术研究 | Tagged | 3 Comments

美式认沽期权何时会被提前行权

很久不思考业务细节了,今天遇到一个问题,需要动脑子了。

我们知道美式认购期权不需要提前行权,原因有两个,一个是期权波动价值(由于价格波动获得利润的可能性),二是早晚行权支付的资金是一样的,那么晚点支付可以节省资金成本。如果你想了结头寸,你的选择应该是保留期权卖空股票,或者直接卖出期权而不是行权。实际上,上述也就是认购期权的时间价值,由于二者都是正的,因此美式认购期权时间价值永远大于零。

但是美式认沽期权就存在提前行权的必要了。不过在说美式期权之前,先要说欧式认沽期权。我们知道,欧式认沽期权有时候 theta 是正值,也就是说,它的时间价值为负。

但是需要注意的是,是深度实值认沽期权 theta 是正值,并不是实值 theta 是正值。

为什么会这样,这里同样有两点,其一是波动率,其二是资金成本,如果波动率消失了,那么现在拿到现金比将来拿到现金更好,这个是和 carry 有关,和前面认购期权相反。

波动率上,和认购期权不同的是,那么实际上因为股票价格不能为负,因此深度实值的认沽期权,波动上总是对我们不利的情况要远大于波动率对我们有利的情况,因此需要提前行权。

这还可以从 theta 的公式角度考虑,

image

其实也好理解,比如轻微实值的认沽期权,标的价格可能向下波动,也就是说内在价值可能增加,如果现在行权,那么你放弃了一部分波动的可能性,theta 的前半部分,就和这个波动的价值有关。

但是由于在股票价格下跌后,波动的不对称性,同样的波动,对内在价值的影响是不对称的。

再搞清上面的问题之后。美式认沽期权,若波动率溢价高于所损失的无风险利率,那么时间价值为正,反之为负。所以投资者可能会在波动率小到一定程度时,选择执行期权。

顺便提一句,什么时候提前行权带红利认购期权,只要红利超过剩余时间价值,就应该提前行权。

Posted in 学术研究 | Tagged , | Leave a comment