本帖最后由 Liwu 于 2023-12-29 11:41 编辑
不少朋友用 QMT 在玩期权,那期权最重要的一些指标,我们常叫做希腊字母值,目前QMT还没有直接提供,那我们如何才能得到呢?今天就给大家分享一个例子,先看效果:

在K线下方的指标区域,我们就很方便地显示出了该只期权对应的希腊字母值,具体的代码如下:
还有要跟大家分享的就是,迅投研
#coding:gbk
from math import log, pow,sqrt,exp,pi
from scipy import stats
import datetime
"""
计算股票期权希腊值
"""
print('-\n\n')
def init(C):
C.target_option = C.stockcode + '.' + C.market
option_basic_info = C.get_option_detail_data(C.target_option)
print ('期权基本信息', option_basic_info)
C.etf_code = option_basic_info['OptUndlCode'] + '.' + option_basic_info['OptUndlMarket']
C.exercise_price = option_basic_info['OptExercisePrice'] #行权价格 float类型
C.exercise_date = str(option_basic_info['ExpireDate'])
C.rf = float(option_basic_info['OptUndlRiskFreeRate'])
name = C.get_stock_name(C.target_option)
#print (11111,option_basic_info['ExpireDate'])
C.cp = 'call'
if '购' in name:
C.cp = 'call'
elif '沽' in name:
C.cp = 'put'#认沽put 认购call str类型
else:
print ('认沽认购type not found')
C.given_dividend = 0 #存续期内标的证券将付股利 默认为零 float
print (C.exercise_price, C.exercise_date)
#
def handlebar(C):
try:
d = C.barpos
t = C.get_bar_timetag(d)
bar_time = timetag_to_datetime(t,'%Y%m%d')
actual_price = C.get_market_data(['close'],stock_code =[C.target_option],period=C.period)
s = C.get_market_data(["close"],stock_code = [C.etf_code],period=C.period)
s = round(s,4)
k = C.exercise_price
due_date = C.exercise_date
t = ((datetime.datetime.strptime(due_date, "%Y%m%d") - datetime.datetime.strptime(bar_time, "%Y%m%d")).days) / 365.0
print ('days',((datetime.datetime.strptime(due_date, "%Y%m%d") - datetime.datetime.strptime(bar_time, "%Y%m%d")).days))
print ('t', t)
r = C.rf
divid_rate = C.given_dividend / s
cp = C.cp
iv = calculate_implied_volatility(s,k,t,r,divid_rate,actual_price,C.cp)
if iv == 0:
print (bar_time,'iv = 0')
return
C.paint('iv',iv,-1,0)
print((bar_time, 's',s,'actual_price',actual_price,'k',k,'t',t,'r',r,'divid_rate',divid_rate,'iv',iv))
d1_result=d1(s,k,t,r,divid_rate,iv)
d2_result=d2(s,k,t,r,divid_rate,iv)
delta_result=delta(s,k,t,r,divid_rate,iv,cp)
theta_result=theta(s,k,t,r,divid_rate,iv,cp)
gamma_result=gamma(s,k,t,r,divid_rate,iv)
vega_result= vega(s,k,t,r,divid_rate,iv)
rho_result=rho(s,k,t,r,divid_rate,iv,cp)
print ('d1_result',d1_result)
print ('d2_result',d2_result)
print ('delta_result',delta_result)
print ('theta_result',theta_result)
print ('gamma_result',gamma_result)
print ('vega_result',vega_result)
print ('rho_result',rho_result)
if C.is_last_bar():
print(1111, s, k, t, r, iv)
C.paint('delta',delta_result,-1,0)
C.paint('theta',theta_result,-1,0)
C.paint('gamma',gamma_result,-1,0)
C.paint('vega',vega_result,-1,0)
C.paint('rho',rho_result,-1,0)
except:
import traceback
print(bar_time, traceback.format_exc())
def get_fourth_wednesday(year, month):
"""
获取指定月份第四个周三
"""
n = 0
for i in range(31):
delta = datetime.timedelta(days=i)
exercise_date = datetime.datetime(year, month, 1) + delta
if exercise_date.weekday() == 2 and n < 3:
n += 1
continue
if exercise_date.weekday() == 2 and n == 3:
return exercise_date.strftime('%Y%m%d')
def d1(s,k,t,r,d,sigma):
"""计算BS price的中间变量"""
result = (log(s/k) + (r-d) * t) / (sigma * sqrt(t)) + 0.5 * sigma * sqrt(t)
return result
def d2(s,k,t,r,d,sigma):
"""计算BS price的中间变量"""
result = d1(s,k,t,r,d,sigma) - sigma * sqrt(t)
return result
def bs_price(s,k,t,r,d,sigma,cp):
"""计算BS price"""
if cp == 'call':
return s * exp(-d*t) * stats.norm.cdf(d1(s,k,t,r,d,sigma)) - k * exp(-r * t) * stats.norm.cdf(d2(s,k,t,r,d,sigma))
if cp == 'put':
return s * exp(-d*t) * stats.norm.cdf(d1(s,k,t,r,d,sigma)) - k * exp(-r * t) * stats.norm.cdf(d2(s,k,t,r,d,sigma)) + k * exp(-r * t) - s * exp(-d*t)
def calculate_implied_volatility(s,k,t,r,d,actual_price,cp, epsilon = 0.00001):
"""二分法求隐含波动率"""
high = 2.0
low = 0.0
while high - low > epsilon:
if bs_price(s,k,t,r,d,(high + low)/2,cp) > actual_price:
high = (high + low) / 2
else:
low = (high + low) / 2
return (high + low) / 2
def std_normal_pdf(x):
"""标准正态分布的概率密度函数"""
return exp(- x ** 2 / 2) / (2 * pi) ** 0.5
def delta(s,k,t,r,d,sigma,cp):
"""希腊值 delta"""
call_delta = exp(-d * t) * stats.norm.cdf(d1(s,k,t,r,d,sigma))
if cp == 'call':
return call_delta
if cp == 'put':
return call_delta - 1
def gamma(s,k,t,r,d,sigma):
"""希腊值 gamma"""
return exp(-d*t) * std_normal_pdf(d1(s,k,t,r,d,sigma)) / (s * sigma * t ** 0.5)
def vega(s,k,t,r,d,sigma):
"""希腊值 vega"""
return exp(-d*t) * s * t ** 0.5 * std_normal_pdf(d1(s,k,t,r,d,sigma))
def theta(s,k,t,r,d,sigma,cp):
"""希腊值 theta"""
part1 = -s * std_normal_pdf(d1(s,k,t,r,d,sigma)) * sigma * exp(-d*t) / (2 * t ** 0.5)
part2 = d * s * stats.norm.cdf(d1(s,k,t,r,d,sigma)) * exp(-d*t) - r * k * exp(-r*t) * stats.norm.cdf(d2(s,k,t,r,d,sigma))
if cp == 'call':
return part1 + part2
if cp == 'put':
return part1 - part2
def rho(s,k,t,r,d,sigma,cp):
"""希腊值 rho"""
if cp == 'call':
return k * t * exp(-r*t) * stats.norm.cdf(d2(s,k,t,r,d,sigma))
if cp == 'put':
return -k * t * exp(-r*t) * stats.norm.cdf(d2(s,k,t,r,d,sigma))
提供更全面的期权数据,包括过期期权,期权连续,这些数据具体可以参考:期权数据
