栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Golang 期权 指标计算

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Golang 期权 指标计算

用golang做期权行情指标计算时,关于sigma, delta, gamma, vega, theta, rho等的计算,需要用到black-scholes模型

期权指标计算其他语言已有现成的包或者代码,我参考了其他博主的python代码,用go完整的写了一遍,包含隐含波动率、正态分布函数等

 直接贴代码

//DN 标准正态分布的概率密度函数公式
func DN(x float64) float64 {
	return math.Exp(-0.5*math.Pow(x, 2)) / math.Sqrt(2*math.Pi)
}

//CalcVega 计算期权Vega指标  隐含波动率变化引起的期权价格变化

func CalcVega(St, K, T, r, sigma float64) float64 {
	d1 := calcD1(St, K, sigma, r, T)
	return calcVega(d1, St, T)
}

func calcVega(d1, St, T float64) float64 {
	return St * math.Sqrt(T) * DN(d1) / 100.0
}

//CalcDelta 标的资产价格变化引起期权价格变化 计算期权Delta值  n=1看涨期权   n=-1看跌期权

func CalcDelta(St, K, T, r, sigma float64, n float64) float64 {
	d1 := calcD1(St, K, sigma, r, T)
	return calcDelta(d1, n)
}

func calcDelta(d1, n float64) float64 {
	return n * N(n*d1)
}

//CalcGamma 标的资产价格变化引起delta值的变化

func CalcGamma(St, K, T, r, sigma float64) float64 {
	d1 := calcD1(St, K, sigma, r, T)
	return calcGamma(d1, St, T, sigma)
}


func calcGamma(d1, St, T, sigma float64) float64 {
	return DN(d1) * (St * sigma * math.Sqrt(T)) / 1000
}

//CalcRho 期权价格对(无风险)利率变化的敏感程度

func CalcRho(St, K, T, r, sigma, n float64) float64 {
	d1 := calcD1(St, K, sigma, r, T)
	d2 := calcD2(d1, sigma, T)
	return calcRho(d2, K, T, r, n)
}


func calcRho(d2, K, T, r, n float64) float64 {
	return n * K * T * math.Exp(-r*T) * N(n*d2) / 100
}

//CalcTheta 期权的时间价值随时间流逝耗损的速度

func CalcTheta(St, K, T, r, sigma float64, n float64) float64 {
	d1 := calcD1(St, K, sigma, r, T)
	d2 := calcD2(d1, sigma, T)
	//业内习惯Theta用来衡量每日的time decay,而BS Model中的时间单位是年,所以按此公式算出来的Theta需要再除以365
	return calcTheta(d1, d2, St, K, T, r, sigma, n)
}


func calcTheta(d1, d2, St, K, T, r, sigma float64, n float64) float64 {
	//业内习惯Theta用来衡量每日的time decay,而BS Model中的时间单位是年,所以按此公式算出来的Theta需要再除以365
	return (-St*DN(d1)*sigma/(2*math.Sqrt(T)) - n*r*K*math.Exp(-r*T)*N(n*d2)) / 365
}

// N 计算值u的标准正态分布概率
func N(u float64) float64 {
	//取绝对值
	y := math.Abs(u)
	//平方值
	y2 := math.Pow(y, 2)
	z := math.Exp(-0.5*y2) * 0.398942280401432678
	p := float64(0)
	k := 28
	s := float64(-1)
	fj := float64(k)
	if y > 3 {
		//当y>3
		for i := 1; i <= k; i++ {
			p = fj / (y + p)
			fj = fj - 1.0
		}
		p = z / (y + p)
	} else {
		//当y<3
		for i := 1; i <= k; i++ {
			p = fj * y2 / (2.0*fj + 1.0 + s*p)
			s = -s
			fj = fj - 1.0
		}
		p = 0.5 - z*y/(1-p)
	}
	if u > 0 {
		p = 1.0 - p
	}
	return p
}

//计算期权对股价的敏感程度 BS mode中的d1

func calcD1(S float64, K float64, sigma float64, r float64, t float64) float64 {
	return (math.Log(S/K) + (r+0.5*math.Pow(sigma, 2))*t) / (sigma * math.Sqrt(t))
}

//计算期权最后被执行的可能性 BS mode中的d2

func calcD2(d1 float64, sigma float64, t float64) float64 {
	return d1 - sigma*math.Sqrt(t)
}

// GetC 计算预期定价

func GetC(S float64, K float64, sigma float64, r float64, t float64) float64 {
	d1 := calcD1(S, K, sigma, r, t)
	d2 := calcD2(d1, sigma, t)
	return S*N(d1) - K*math.Exp(-r*t)*N(d2)
}

// CalcVolatility 计算引伸波幅,对冲值。采取逼近法计算

func CalcVolatility(isRise bool, warPx float64, cr float64, S float64, r float64, L float64, T float64, Dt float64) (float64, float64) {
	if warPx == 0 || S == 0.0 {
		return 0.0, 0.0
	}
	NowC := warPx * cr
	sigma := float64(0)
	var c float64
	for i := 0; i < 20; i++ {
		c, _ = CalcC(isRise, S, r, sigma*sigma, L, T, Dt)
		if c > NowC {
			sigma -= 0.1
			break
		} else {
			sigma += 0.1
		}
	}
	for i := 0; i < 10; i++ {
		c, _ = CalcC(isRise, S, r, sigma*sigma, L, T, Dt)
		if c > NowC {
			sigma -= 0.01
			break
		} else {
			sigma += 0.01
		}
	}
	for i := 0; i < 10; i++ {
		c, _ = CalcC(isRise, S, r, sigma*sigma, L, T, Dt)
		if c > NowC {
			sigma -= 0.001
			break
		} else {
			sigma += 0.001
		}
	}
	var delta float64
	for i := 0; i < 10; i++ {
		c, delta = CalcC(isRise, S, r, sigma*sigma, L, T, Dt)
		if c > NowC {
			break
		} else {
			sigma += 0.0001
		}
	}
	return sigma, delta
}

//CalcC 计算理论价

func CalcC(isRise bool, S float64, r float64, sigma float64, K float64, T float64, Dt float64) (float64, float64) {
	d1 := CalcD1(S, r, sigma, K, T)
	d2 := CalcD2(d1, sigma, T)
	a := Dt
	b := N(d1)
	c := math.Exp(-1 * r * T)
	d := N(d2)
	C := (S-a)*b - K*c*d
	if !isRise {
		C = K*c*(1-d) - (S-a)*(1-b)
		b = b - 1
	}
	return C, b
}

//CalcD1 计算期权对股价的敏感程度 BS mode中的d1

func CalcD1(S float64, r float64, sigma float64, K float64, T float64) float64 {
	pv := K / math.Pow(1+r, T)
	return math.Log(S/pv)/(math.Sqrt(sigma*T)) + math.Sqrt(sigma*T)/2
}

//CalcD2 计算期权最后被执行的可能性 BS mode中的d2

func CalcD2(d1 float64, sigma float64, T float64) float64 {
	return d1 - math.Sqrt(sigma*T)
}


func bsCall(S, K, T, r, sigma float64) float64 {
	d1 := (math.Log(S/K) + (r+0.5*math.Pow(sigma, 2))*T) / (sigma * math.Sqrt(T))
	d2 := (math.Log(S/K) + (r-0.5*math.Pow(sigma, 2))*T) / (sigma * math.Sqrt(T))
	return S*N(d1) - K*math.Exp(-r*T)*N(d2)
}


func bsPrice(S, K, T, r, sigma, n float64) float64 {
	d1 := (math.Log(S/K) + (r+0.5*math.Pow(sigma, 2))*T) / (sigma * math.Sqrt(T))
	d2 := (math.Log(S/K) + (r-0.5*math.Pow(sigma, 2))*T) / (sigma * math.Sqrt(T))
	return n*S*N(n*d1) - n*K*math.Exp(-r*T)*N(n*d2)
}


func bsPut(S, K, T, r, sigma float64) float64 {
	d1 := (math.Log(S/K) + (r+0.5*math.Pow(sigma, 2))*T) / (sigma * math.Sqrt(T))
	d2 := (math.Log(S/K) + (r-0.5*math.Pow(sigma, 2))*T) / (sigma * math.Sqrt(T))
	return -S*N(-d1) + K*math.Exp(-r*T)*N(-d2)
}

//CalcSigma 计算隐含波动率

func CalcSigma(S, K, T, r, price, n float64) float64 {
	EPS := 1e-5
	lo := 1e-5
	hi := 0.5
	var c float64
	for lo+EPS < hi {
		sigma := (lo + hi) / 2
		if n == 1 {
			c = bsCall(S, K, T, r, sigma)
		} else {
			c = bsPut(S, K, T, r, sigma)
		}
		//c = bsPrice(S, K, T, r, sigma, n)
		if c-price < 0 {
			lo = sigma
		} else {
			hi = sigma
		}
	}
	return lo
}

//CalcOptionQuota 计算期权指标

func CalcOptionQuota(S, K, T, r, price float64, isRise bool) (sigma, delta, gamma, vega, theta, rho float64) {
	n := 1.0
	if !isRise {
		n = -1.0
	}
	sigma = CalcSigma(S, K, T, r, price, n)
	d1 := calcD1(S, K, sigma, r, T)
	d2 := calcD2(d1, sigma, T)
	delta = calcDelta(d1, n)
	gamma = calcGamma(d1, S, T, sigma)
	vega = calcVega(d1, S, T)
	theta = (-S*DN(d1)*sigma/(2*math.Sqrt(T)) - n*r*K*math.Exp(-r*T)*N(n*d2)) / 365
	rho = calcRho(d2, K, T, r, n)
	return
}

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1015136.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号