最近面试的时候,面试官问我怎么用蒙卡模拟无股息的美式期权定价。我瞬间石化。。。不怕死地申请了期权建模的实习。。。主要参考课件

主要内容二叉树定价推导+Python

Longstaff-Schwartz定价推导+Python

一、引言

本讲的大前提:股票无股息。

1、美式期权主要问题是:在

之间找到合适的停止点

,从而美式期在t时刻价值

其中,

是收益,又称为内在价值。等式不难理解:给定t时刻的期权价格为

,找到未来合适的停止点

,然后把那一刻的期权价值折现到t时刻。

注意:

是随机值(random variable)。对于股票过程(例如GBM)的每个不同路径,

可以不同。解决之道:每时每刻基于标的股票的当前价值、评估此刻执行期权是不是最优的。

可以证明,V(t,s)是下面方程的弱解(weak solution) :

又是解PDE。。。我之前写过欧式期权的PDE,可参考丹尼尔:Code and Finance 4 期权定价之有限差分法​zhuanlan.zhihu.com

美式期权实际上有3中解法,①PDE(以后有空再整理);②二叉树(Binomial tree);③Longstaff-Schwarts(※※※)。本文主要讲解后两种~

二、二叉树求解美式期权定价

1、基本逻辑前提假设风险中性的世界中,衍生品的现值=未来预期收益的折现值,折现率为无风险收益率

股价在

的时间内,上升概率为

,下降概率为

即为无风险概率。

上升幅度为

,下降幅度为

当前时间是t=0,当前标的资产股价为

,当前衍生品价格为

时间后,股价要么上升到

,对应的衍生品价值为

;要么下降到

,对应的衍生品价值为

如何求解p? ,那么

如何求解u和d?前提条件:

Grisanov's theoremu和d选择的必要条件:股价收益率的波动率在现实世界和风险中性世界一致(股价收益率在两个世界可以不同)。

综上:

2、实例+代码例子:当前股价为100,put行权价为100,时间为1年,无风险利率为0.1,年化波动率为0.2。求出当前时间的美式看跌期权价格。

假设我把1年的时间切分成100份,那么在最后一次,一共有101个分支价格,这就是S_T是101个数据点;然后分别和K进行比较,得到每个点的call/put价格。接着,将第100个时间点向第99个时间点折现,注意:

的期权折现值

接着,比较

提前行权的期权价值

和折现值的大小;哪个大那么就选择哪个。代码

import numpy as np

S0 = 100

K = 100

T = 1

r = 0.1

sig = 0.2

payoff = "put"

def getAmeOption(S0, K, T, r, sig, N, payoff):

# 将时间T拆分为N份,每份是dT。

dT = float(T) / N

#计算u,d,p,q。

u = np.exp(sig * np.sqrt(dT))

d = 1.0 / u

a = np.exp(r * dT)

p = (a - d)/(u - d)

q = 1.0 - p

# V承接N+1个价格

V = np.zeros(N+1)

# 注意S_T的生成顺序,是从u=0,d=N开始.

S_T = np.array( [(S0 * u**j * d**(N - j)) for j in range(N + 1)] ) # price S_T at time T

if payoff =="call":

V[:] = np.maximum(S_T-K, 0.0)

elif payoff =="put":

V[:] = np.maximum(K-S_T, 0.0)

for i in range(N-1, -1, -1):

# 这一步至关重要:V在第k轮迭代中,只关注0~N-k的位置,

# 每个位置=(下一个位置上升的期权*p+下一个位置下降的期权*q)*折现因子

V[:-1] = np.exp(-r*dT) * (p * V[1:] + q * V[:-1])

# 股价也进行新一轮的迭代,同样只有0~N-k是需要关注的,剩下的位置无关紧要。

S_T = S_T * u

# 比较此刻行权和下一轮预期收益的折现

if payoff=="call":

V = np.maximum( V, S_T-K )

elif payoff=="put":

V = np.maximum( V, K-S_T )

return V[0]

结果

getAmeOption(S0, K, T, r, sig, 10000, 'put')

getAmeOption(S0, K, T, r, sig, 10000, 'call')

put价格为4.816201361591469,call价格为13.269467766434364。

三、Longstaff-Schwartz这个方法又称为是最小二乘法。

1、步骤详解——通过例子详细解答假设:我模拟了10条(paths=10)路径,以及将时间分成了4段(N=4,0-1-2-3),

,每段时间的折现因子

。求出0时刻的call&put价格。

第一步:求出10条路径的股价发展过程首先,第0个时间点的10条路径是[100, ... 100](10个100);

第1个时间点的10条路径计算方式是把第0条的10个100作为输入值,

=[95.84, ..., 121.39](10个随机数);

第2个时间点的10条路径是把第1个时间点的10条路径的股价作为S0输入,结果为[93.16, ... , 135.93];

第3个时间点的10条路径是把第2个时间点的10个路径的股价作为S0输入,结果为[103.58, ... , 145.24]。

因此股价的矩阵为

代码

from random import gauss

from math import exp, sqrt

def calculate_S_T(S, v, r, T):

"""模拟epsilon,计算S_T"""

return S * exp((r - 0.5 * v ** 2) * T + v * sqrt(T) * gauss(0.0, 1.0))

def getRoundStockPrice(S, v, r, N, T, rounds, paths):

firstRound = [S] * paths

nextRound = firstRound.copy()

for i in range(rounds):

nextRound1 = nextRound[-paths:]

for s in nextRound1:

nextS = calculate_S_T(s, v, r, T)

nextRound.append(nextS)

nextRound = np.array(nextRound).reshape((-1, paths)).T

return nextRound

S = 100

v = 0.2

r = 0.1

N = 3

T = 1 / N

paths = 10

S_Matrix = getRoundStockPrice(S, v, r, N, T, N, paths)第二步:求出每个时期行权的收益,称为exercise value(EV)call的EV=max(S-K, 0),put的EV=max(K-S, 0),第三步t=3的时候,必须要行权,exercise value(EV)=holding value(HV)。

t=2的时候,计算第2期的收益现值HV,就是t=3的EV折现(这是因为第三期就到期了,第三期的EV=HV),即为下两张表的第2列2callHV和2putHV。

然后,将t=2的EV>0的部分圈出来(※※※※※),对于call而言,即为2.3.6.7.10,对于put而言,即为1.4.5.8.9;

然后对相应行进行least-squares回归,回归方程

;其中S是第2期的股价,HV是第二期的持有价值HV;即为y是2callHV(2putHV),自变量是S2和S2^2;得到回归系数之后,再代入第二期的股价S,求出E(HV);注意,put和call分开回归,不是一起回归。

然后计算出E(HV),即为2callE(HV)和2putE(HV),比较E(HV)和EV大小;如果E(HV)>EV,那么绝不提前行权;如果E(HV)≤EV,那么第二期立刻行权。最后,得到了第二期的期权情况,即为最后一列。t=1的时候,第2列1callHV和1putHV,分别是上面两张表的最后一列的折现值;第二列来自H矩阵在t=1的值;同样,圈出EV>0的情况,call是2、3、6、7、10行,put是1、4、5、8、9行,分别和S1&S1^2回归,然后计算得到1callE(HV)和1putE(HV);比较E(HV)和EV的大小,if E(HV)>EV,绝不提前行权;else 提前行权;最终得到1call和1put。最后一步,将1call和1put分别计算均值,然后折现到t=0时期,即为

和二叉树差的有点远。。应该是我分的区间太小了。下面拆成10000*10000的网格点的时候,明显结果更加稳健。

2、代码详解

可以看到,上面的计算,程序基本大同小异,那么使用python一次性解决。

import scipy.stats as ss

import numpy as np

def LSM(S0, K, T, r, sig, payoff, N=10000, paths=10000, order=2):

dt = T/(N-1) # time interval

df = np.exp(r * dt) # discount factor per time time interval

X0 = np.zeros((paths,1))

increments = ss.norm.rvs(loc=(r - sig**2/2)*dt, scale=np.sqrt(dt)*sig, size=(paths,N-1))

X = np.concatenate((X0,increments), axis=1).cumsum(1)

S = S0 * np.exp(X)

if payoff == "put":

H = np.maximum(K - S, 0) # intrinsic values for put option

if payoff == "call":

H = np.maximum(S - K, 0) # intrinsic values for call option

V = np.zeros_like(H) # value matrix

V[:,-1] = H[:,-1]

# Valuation by LS Method

for t in range(N-2, 0, -1):

good_paths = H[:,t] > 0

# polynomial regression:将EV>0的部分挑出来回归

rg = np.polyfit( S[good_paths, t], V[good_paths, t+1] * df, 2)

# 估计E(HV)

C = np.polyval( rg, S[good_paths,t] )

# 如果E(HV)

exercise = np.zeros( len(good_paths), dtype=bool)

exercise[good_paths] = H[good_paths,t] > C

V[exercise,t] = H[exercise,t]

V[exercise,t+1:] = 0

discount_path = (V[:,t] == 0)

V[discount_path,t] = V[discount_path,t+1] * df

V0 = np.mean(V[:,1]) * df #

return V0

结果

call = LSM(100, 100, 1, 0.1, 0.2, 'call', N=10000, paths=10000, order=2)

put = LSM(100, 100, 1, 0.1, 0.2, 'put', N=10000, paths=10000, order=2)

得到call=13.297700328385172,put=4.755646113796444。

基本和二叉树的结果一致。

整理了一天,终于完成这篇小作业~对于二叉树定价,我这里也是第一次试验,结果还挺不错;以前以为二叉树是不是太简单的,现在来看,结果和复杂的Longstaff-Schwartz结果一致;而且运行速度也更占优势。

以上是美式无股息期权定价推导+Python代码,希望能够给你带来帮助~

参考

美式期权定价python_蒙特卡洛模拟和美式期权定价相关推荐

  1. 最小二乘蒙特卡洛模拟方法-美式期权定价

    对于最小二乘蒙特卡洛模拟方法,相信很多人刚开始都搞不清楚到底是怎么回事,特别是对于非金融专业的同学来说,解决此类问题有点吃力,但解决美式期权定价问题,此方法被广泛使用,下面给出介绍: 由于美式期权允许 ...

  2. (三十八)期权定价的蒙特卡洛模拟方法

    蒙特卡洛模拟法对欧式期权定价   对于标的资产价格为S0,执行价格是X的欧式看涨期权,到期日T的价格为CT = max(0,ST-X),在风险中性世界里用无风险利率r贴现,则期权在t时刻的价格为CT ...

  3. 美式期权定价python_【优质好课】Python量化期权实战应用

    优质好课 · 涨价预警 <Python量化期权实战应用>课程,在预售初期就备受关注,课程开始上线以来,内容更是受到了广大学员的一致好评. 现在,眼看着课程就快要更新完毕了,如果还没有开始学 ...

  4. 美式期权定价方法之最小二乘蒙特卡洛模拟(LSM)

    美式期权定价方法之最小二乘蒙特卡洛模拟 前言 前文对欧式期权的蒙特卡洛模拟定价方法进行了介绍和python量化,本章节主要是对前一章节的补充.也就是介绍美式期权的蒙特卡洛定价方法. 一.美式期权 不同 ...

  5. 第9节 蒙卡模拟计算美式期权价格(b)

    第9节 蒙卡模拟计算美式期权价格(b) 9.1 简介 9.2 参数化执行边界算法 9.3 算法Python代码实现 9.4 计算示例 9.5 参考资料 9.1 简介 使用蒙卡模拟计算美式期权价格除了最 ...

  6. 第8节 蒙卡模拟计算美式期权价格(a)

    第8节 蒙卡模拟计算美式期权价格(a) 8.1 简介 8.2 最小二乘法计算美式期权价格 8.3 算法Python代码实现 8.4 计算示例 8.5 相关说明 8.5.1 美式看涨期权不会被提前行使 ...

  7. matlab腔内光子寿命,mcFORnp matlab环境下,利用蒙特卡洛模拟光子包在生物组织内的光路传输 271万源代码下载- www.pudn.com...

    文件名称: mcFORnp下载  收藏√  [ 5  4  3  2  1 ] 开发工具: matlab 文件大小: 215 KB 上传时间: 2014-12-29 下载次数: 8 提 供 者: 徐某 ...

  8. python 蒙特卡洛模拟股价_12 Python总结之蒙特卡洛模拟

    蒙特卡洛模拟 蒙特卡洛模拟是金融学和数值科学中最重要的算法之一.它之所以重要,是因为在期权定价或者风险管理问题上有很强的能力.和其它数值方法相比,蒙特卡洛方法很容易处理高维问题,在这种问题上复杂度和计 ...

  9. 12 Python总结之蒙特卡洛模拟

    蒙特卡洛模拟 蒙特卡洛模拟是金融学和数值科学中最重要的算法之一.它之所以重要,是因为在期权定价或者风险管理问题上有很强的能力.和其它数值方法相比,蒙特卡洛方法很容易处理高维问题,在这种问题上复杂度和计 ...

最新文章

  1. MATLAB符号计算
  2. css实现页面文字不换行、自动换行、强制换行
  3. 浏览器缓存问题原理以及解决方案
  4. 【图片】图像基本知识以及三原色原理 (rgb)
  5. java解析xml文件失败,在Java中解析大型XML文件时找不到文件异常
  6. Javascript-逻辑运算符()
  7. ESXi配置vCenter服务器
  8. R语言—简介、安装、包(package)的安装与加载
  9. 军用设备环境试验方法湿热试验标准
  10. 跨平台数据库ODB实战1-ODB安装
  11. 崩溃,执行DELETE没加WHERE条件,该怎么办?
  12. CTF靶机 Lian_Yu 笔记
  13. go的目录结构pkg
  14. 基于aspnet+20ajax问卷调查系统的设计和实现_百度文库,基于ASP.NET的网络问卷调查系统的设计与实现...
  15. 银行制定快捷支付限额原因
  16. sphinx在windows下的简单安装与使用
  17. layui 怎么设置点击图片放大_layui图片如何放大
  18. 阿里旺铺运营怎样做到低价引流
  19. 第11篇- 抓取免费代理IP并搭建自己的代理IP池
  20. 826. Most Profit Assigning Work

热门文章

  1. 初识爬虫——爬虫与HTML介绍
  2. A Sample Crash Log
  3. linux下同时装ananocda2和anaconda3通过修改.bashrc文件进行切换
  4. [博弈论] Nim游戏及SG函数(经典+台阶+集合+拆分)
  5. 电子商务宝盒PRIMO
  6. Java版KTV预定管理系统源码
  7. Win10 英伟达显卡驱动安装不上,显示由于该设备有问题,Windows已将其停止,错误代码43
  8. 同步四进制可逆加减法计数器分析
  9. 计算机教师师徒结对师傅总结,师徒结对师傅总结
  10. 分布式消息队列RocketMQ—个人笔记(尚硅谷老雷老师视频)