合并二叉树进行期权定价
合并二叉樹(shù)進(jìn)行期權(quán)定價(jià) – 潘登同學(xué)的Quant筆記
文章目錄
- 合并二叉樹(shù)進(jìn)行期權(quán)定價(jià) -- 潘登同學(xué)的Quant筆記
- 理論背景
- 合并二叉樹(shù)
- 疊期望定理
- Gisanov's Theorem(戈薩諾夫定理)
- 計(jì)算合并二叉樹(shù)的關(guān)鍵點(diǎn)
- 模型參數(shù)
- 中間結(jié)果
- 構(gòu)建合并二叉樹(shù)
- 構(gòu)建二叉樹(shù)節(jié)點(diǎn)
- 構(gòu)建合并二叉樹(shù)
- 完整代碼
- 算例
理論背景
合并二叉樹(shù)對(duì)期權(quán)的定價(jià)是建立在單期模型向多期模型拓展的基礎(chǔ)之上的,而多期模型與單期模型的最大區(qū)別在于: 單期模型只在最初做決策,而多期模型在多個(gè)時(shí)點(diǎn)連續(xù)作出投資決策; 為了將套利定價(jià)理論拓展到多期、動(dòng)態(tài)的情形下,必須要滿足的條件就是動(dòng)態(tài)完備;
對(duì)于單期模型來(lái)說(shuō),資產(chǎn)個(gè)數(shù)至少大于狀態(tài)的數(shù)量,市場(chǎng)才可能是完備的; 而在動(dòng)態(tài)模型中,如果長(zhǎng)存資產(chǎn)的數(shù)目不低于樹(shù)中各個(gè)結(jié)點(diǎn)引出的直接后繼節(jié)點(diǎn)數(shù)量的最大值,那么市場(chǎng)就是完備的;
合并二叉樹(shù)
大家對(duì)二叉樹(shù)都很熟悉,一個(gè)節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn),子節(jié)點(diǎn)的個(gè)數(shù)與層數(shù)的關(guān)系就是2n2^n2n(從第0層算起), 那么最終的子節(jié)點(diǎn)個(gè)數(shù)就會(huì)呈指數(shù)級(jí)增加,而金融里面的資產(chǎn)價(jià)格變動(dòng)往往是用乘積因子做變化的; 如從0時(shí)刻到1時(shí)刻,資產(chǎn)價(jià)格從S0S_0S0?變化到uS0uS_0uS0?或dS0dS_0dS0?(u表示上升,d表示下降),到2時(shí)刻資產(chǎn)價(jià)格從uS0uS_0uS0?變化到uuS0uuS_0uuS0?或udS0udS_0udS0?, 從dS0dS_0dS0?變化到udS0udS_0udS0?或ddS0ddS_0ddS0?,可以發(fā)現(xiàn)其中的udS0udS_0udS0?同時(shí)出現(xiàn)在1時(shí)刻的兩個(gè)子節(jié)點(diǎn)上; 在不關(guān)心路徑的前提下,可以將兩個(gè)節(jié)點(diǎn)合并,如下圖所示
但是有的期權(quán)不能這樣,比如:回望期權(quán),他是路徑依賴的,取決于標(biāo)的資產(chǎn)在期權(quán)有效期內(nèi)的最低或最高價(jià)格;
疊期望定理
期權(quán)本質(zhì)上是一種資產(chǎn),但這個(gè)資產(chǎn)的payoff只有在最后一期才能知道(European options),所以要在第一期知道其期望就需要用到疊期望定理:
在t時(shí)刻對(duì)某隨機(jī)變量x~\tilde{x}x~的期望應(yīng)當(dāng)嚴(yán)格地寫成:
E[x~∣Ft],Ft表示在t時(shí)刻擁有的信息E[\tilde{x}|F_t]\quad , \quad F_t表示在t時(shí)刻擁有的信息 E[x~∣Ft?],Ft?表示在t時(shí)刻擁有的信息
疊期望定理表示為
Et[x~]=Et[Et+1[x~]]E_t[\tilde{x}] = E_t[E_{t+1}[\tilde{x}]] Et?[x~]=Et?[Et+1?[x~]]
Gisanov’s Theorem(戈薩諾夫定理)
假設(shè)一個(gè)單位長(zhǎng)度為△t\triangle t△t,在真實(shí)世界中的資產(chǎn)波動(dòng)率為σ\sigmaσ,在風(fēng)險(xiǎn)中性的概率下,在一個(gè)單位內(nèi)股價(jià)回報(bào)率為(u?1)(u-1)(u?1)的概率為q,回報(bào)為(d?1)(d-1)(d?1)的概率為(1-q),運(yùn)用公式var(X)=E(X2)?[E(X)]2var(X) = E(X^2) - [E(X)]^2var(X)=E(X2)?[E(X)]2
q(u?1)2+(1?q)(d?1)2?[q(u?1)+(1?q)(d?1)]2=σ2△tq(u-1)^2 + (1-q)(d-1)^2 - [q(u-1)+(1-q)(d-1)]^2 = \sigma^2 \triangle t q(u?1)2+(1?q)(d?1)2?[q(u?1)+(1?q)(d?1)]2=σ2△t
得到風(fēng)險(xiǎn)中性概率為
q=er△t?du?dq = \frac{e^{r \triangle t}-d}{u-d} q=u?der△t?d?
注意上式的等號(hào)左邊是風(fēng)險(xiǎn)中性世界的方差,等號(hào)右邊卻是真實(shí)世界的方差,這兩個(gè)方差計(jì)算所用的概率都不一樣,為什么能放到一起, Girsanov’s Theorem告訴我們,在做概率測(cè)度變換的時(shí)候(如從真實(shí)世界概率轉(zhuǎn)換到風(fēng)險(xiǎn)中性概率),資產(chǎn)價(jià)格收益率的均值一般會(huì)發(fā)生變化,但其波動(dòng)率不變。
計(jì)算合并二叉樹(shù)的關(guān)鍵點(diǎn)
對(duì)于European option的計(jì)算, 可以分為兩步-正向過(guò)程和反向過(guò)程,正向過(guò)程是根據(jù)資產(chǎn)的波動(dòng)率計(jì)算未來(lái)時(shí)刻資產(chǎn)價(jià)格,反向過(guò)程是根據(jù)最后一期的資產(chǎn)價(jià)格計(jì)算最后一期的期權(quán)價(jià)格,再用疊期望定理將期權(quán)一步步折現(xiàn)得到期權(quán)的現(xiàn)值; 接下來(lái)我們就用python實(shí)現(xiàn)以下過(guò)程:
模型參數(shù)
- σ\sigmaσ: 隱含波動(dòng)率 用246個(gè)交易日的roll average計(jì)算得到的序列的方差, 資產(chǎn)價(jià)格波動(dòng)率 σ\sigmaσ 被定義為,使得在△t\triangle t△t 的時(shí)長(zhǎng)上計(jì)算的回報(bào)率波動(dòng)標(biāo)準(zhǔn)差等于σ△t\sigma\sqrt{\triangle t}σ△t?
- r: 無(wú)風(fēng)險(xiǎn)利率 用七天回購(gòu)利率的246個(gè)交易日的roll average計(jì)算得到的序列的均值
- t: 一年的交易日數(shù)(246天)
- underlying_asset_price: 標(biāo)的資產(chǎn)的現(xiàn)值
- k:行權(quán)價(jià)
中間結(jié)果
- u: 資產(chǎn)上漲的幅度
- d:資產(chǎn)下跌的幅度(假設(shè)d = 1/u)
- q: 風(fēng)險(xiǎn)中性概率
構(gòu)建合并二叉樹(shù)
構(gòu)建二叉樹(shù)節(jié)點(diǎn)
二叉樹(shù)節(jié)點(diǎn)需要記錄以下數(shù)據(jù)
- 當(dāng)前的資產(chǎn)價(jià)格
- 當(dāng)前的期權(quán)價(jià)格
- 當(dāng)前的時(shí)刻
- 其子節(jié)點(diǎn)
- 其父節(jié)點(diǎn)
- 節(jié)點(diǎn)的名稱(可有可無(wú), 寫了能分辨出是哪個(gè)節(jié)點(diǎn))
構(gòu)建合并二叉樹(shù)
合并二叉樹(shù)要有以下功能
- 根據(jù)期數(shù)將所有二叉樹(shù)節(jié)點(diǎn)合并
- 進(jìn)行正向傳播計(jì)算資產(chǎn)價(jià)格
- 進(jìn)行反向傳播計(jì)算期權(quán)價(jià)格
所以二叉樹(shù)需要有如下屬性
- 標(biāo)的資產(chǎn)的現(xiàn)值
- 上漲幅度,下跌幅度
- 行權(quán)價(jià)
- 風(fēng)險(xiǎn)中性概率
- 折現(xiàn)率
- 期權(quán)到期日
- 根節(jié)點(diǎn)(只要知道根節(jié)點(diǎn)就能知道后續(xù)的資產(chǎn)價(jià)格)
然后就要根據(jù)資產(chǎn)變化的特點(diǎn)構(gòu)建合并二叉樹(shù),關(guān)鍵點(diǎn)是
- 其中有一些父節(jié)點(diǎn)擁有相同的子節(jié)點(diǎn),而實(shí)現(xiàn)的關(guān)鍵是這些擁有相同子節(jié)點(diǎn)的父節(jié)點(diǎn)往往是相鄰的(價(jià)格相鄰),構(gòu)建過(guò)程使用了類似雙指針的方法分別指向父節(jié)點(diǎn)與子節(jié)點(diǎn),依次移動(dòng)兩個(gè)指針將其連接上
然后就是一個(gè)工具方法,用于顯示資產(chǎn)價(jià)格或期權(quán)價(jià)格,現(xiàn)在還沒(méi)算到期權(quán),后面會(huì)計(jì)算,計(jì)算完再調(diào)用該方法就能顯示期權(quán)價(jià)格變化,關(guān)鍵點(diǎn)是
- 使用BFS從根節(jié)點(diǎn)進(jìn)行搜索,將節(jié)點(diǎn)放入一個(gè)隊(duì)列,依次從隊(duì)列中取出節(jié)點(diǎn),記錄其資產(chǎn)價(jià)格,其子節(jié)點(diǎn)入隊(duì),直到隊(duì)列為空;
- 將資產(chǎn)價(jià)格保存在一個(gè)矩陣中打印輸出;
- 其中的_calrow方法是用于計(jì)算一個(gè)上三角矩陣,當(dāng)元素按列放的時(shí)候,其行號(hào)的函數(shù);
計(jì)算期權(quán)價(jià)格,關(guān)鍵點(diǎn)是
- 期權(quán)價(jià)值是從后往前計(jì)算的,所以要采用遞歸的方式進(jìn)行;
- 對(duì)于American options的計(jì)算需要關(guān)注最優(yōu)停時(shí),也就是在每個(gè)地方判斷一下當(dāng)前行權(quán)的價(jià)值與未來(lái)行權(quán)的期望,選大的那個(gè)即可;
- 而對(duì)于Call options來(lái)說(shuō),根據(jù)Put-Call parity,American options是不會(huì)行權(quán)的,當(dāng)然可以直接用European Options代替,但是為了嚴(yán)謹(jǐn)與完整,還是單獨(dú)寫了,后面有個(gè)驗(yàn)證的例子;
完整代碼
class TreeNode():'''### @Author : Pan Deng### @Time : 2022/10/02'''def __init__(self, key, s, left=None, right=None,time=0):self.key = keyself.asset_price = sself.options_price = Noneself.left = leftself.right = rightself.time = timeself.leftparent = Noneself.rightparent = Noneclass CombineBinaryTree():'''### @Author : Pan Deng### @Time : 2022/10/02'''def __init__(self,total_time,underlying_asset_price,is_European=True,is_call=True):self.underlying_asset_price = underlying_asset_priceself.rootnode = TreeNode('underlying_asset_price',underlying_asset_price)self.u = uself.d = dself.k = kself.q = q # 向右節(jié)點(diǎn)傳播的概率self.discount_rate = r_delta_t # 折現(xiàn)率self.total_time = total_timeself.is_European = is_Europeanself.is_call = is_callself._build([self.rootnode],total_time)def _build(self, node, total_time):parent_node = nodenow = parent_node[0].time+1if now <= total_time:children_node = [TreeNode(f'{now}-u ** {now} d ** {i}',u**(now-i)*d**(i)*self.underlying_asset_price,time=now,u=now,d=i) for i in range(now+1)]i,j = 0,0while i < len(parent_node) and j < len(children_node):parent_node[i].right = children_node[j]children_node[j].leftparent = parent_node[i]j += 1parent_node[i].left = children_node[j]children_node[j].rightparent = parent_node[i]i += 1self._build(children_node,total_time)def BFS(self, item, phase='資產(chǎn)價(jià)格'):'''遍歷打印node的某個(gè)item'''result = np.zeros((self.total_time+1,self.total_time+1))queue = [self.rootnode]i = 0while queue:temp = queue.pop(0)i += 1if temp.left:if temp.right not in queue:queue.append(temp.right)if temp.left not in queue:queue.append(temp.left)row = self._calrow(i)col = temp.timeif item == 'asset':result[row,col] = round(temp.asset_price,3)self.all_asset_price = resultif item == 'options':result[row,col] = round(temp.options_price,3)self.all_options_price = resultprint(f'{phase}: \n',result)def _cal_option_value(self,node):if node.options_price:return node.options_priceelif node.time == self.total_time:if self.is_call:node.options_price = max(node.asset_price - self.k, 0)else:node.options_price = max(self.k - node.asset_price, 0)return node.options_priceelse:if self.is_European:node.options_price = 1/(1+self.discount_rate) * (self.q * self._cal_option_value(node.right) + (1 - self.q) * self._cal_option_value(node.left))else:if self.is_call:# 一般來(lái)說(shuō)美式買入期權(quán)是不會(huì)提前行權(quán)的, 這里只是為了保證完整性, 最后可以驗(yàn)證一下node.options_price = max(node.asset_price - self.k, 1/(1+self.discount_rate) * (self.q * self._cal_option_value(node.right) + (1 - self.q) * self._cal_option_value(node.left)))else:node.options_price = max(self.k - node.asset_price, 1/(1+self.discount_rate) * (self.q * self._cal_option_value(node.right) + (1 - self.q) * self._cal_option_value(node.left)))return node.options_pricedef cal_option_value(self):self._cal_option_value(self.rootnode)def _calrow(self,num):for i in range(1,num+1):if num <= i:breakelse:num -= ireturn num - 1算例
# 模型參數(shù) sigma = 0.26 # 隱含波動(dòng)率 用246個(gè)交易日的roll average計(jì)算得到的序列的方差 # 資產(chǎn)價(jià)格波動(dòng)率 σ 被定義為,使得在△t 的時(shí)長(zhǎng)上計(jì)算的回報(bào)率波動(dòng)標(biāo)準(zhǔn)差等于σ(△t)^(1/2) r = 0.03 # 無(wú)風(fēng)險(xiǎn)利率 用七天回購(gòu)利率的246個(gè)交易日的roll average計(jì)算得到的序列的均值 t = 246 # 一年的交易日數(shù) r_delta_t = r / t # 日利率underlying_asset_price_0 = 2.906 underlying_asset_price_1 = 2.5 # 2.906 u = np.exp(sigma * 1/t ** (1/2)) d = 1/uq = (np.exp(r_delta_t)-d) / (u-d) # 風(fēng)險(xiǎn)中性概率 k = 2.8 # 行權(quán)價(jià)print('European call options:') tree = CombineBinaryTree(8,underlying_asset_price_0) tree.BFS('asset','資產(chǎn)價(jià)格') tree.cal_option_value() tree.BFS('options','期權(quán)價(jià)格')print('American call options:') tree = CombineBinaryTree(8,underlying_asset_price_0,is_European=False) tree.BFS('asset','資產(chǎn)價(jià)格') tree.cal_option_value() tree.BFS('options','期權(quán)價(jià)格')print('European put options:') tree = CombineBinaryTree(8,underlying_asset_price_1,is_call=False) tree.BFS('asset','資產(chǎn)價(jià)格') tree.cal_option_value() tree.BFS('options','期權(quán)價(jià)格')print('American put options:') tree = CombineBinaryTree(8,underlying_asset_price_1,is_European=False,is_call=False) tree.BFS('asset','資產(chǎn)價(jià)格') tree.cal_option_value() tree.BFS('options','期權(quán)價(jià)格')結(jié)果如下:
可以看出驗(yàn)證結(jié)果與理論一致…
文章寫作不易,轉(zhuǎn)載請(qǐng)注明出處…
總結(jié)
以上是生活随笔為你收集整理的合并二叉树进行期权定价的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python自动下载小说
- 下一篇: DirectX12(D3D12)基础教程