python期权价格计算器_GitHub - jason88888/Options-Calculator: 期权价格计算器——金融工程第二次展示...
更多精彩內(nèi)容請訪問我的博客,一起來康康吧!
Options Calculator
這是一個全能的期權(quán)計算器,涵蓋 BS法,蒙特卡洛法,二叉數(shù)法,能夠?qū)礉q期權(quán),看跌期權(quán),歐式期權(quán),美式期權(quán),有股利期權(quán),無股利期權(quán)進行定價,并附帶GUI客戶端。
本計算器的特色在于
支持非常全面的期權(quán)類型
美觀優(yōu)雅簡潔大方的界面
采用了多線程的方式來優(yōu)化用戶體驗
可以直接提取使用其中的 Option 類來應(yīng)用于你所需要的計算期權(quán)價格的地方
可以指定具體日期而不用再手動算時間間隔
可以直接輸入一年計無風(fēng)險利率而不用用戶計算連續(xù)復(fù)利
以上兩點直接將 Options Calculator 從普通的學(xué)術(shù)研究計算器拉到了普世的,實用的價值層面。廣度層面的延伸。
可以比較觀察不同方法的計算結(jié)果差異
可以手動指定二叉樹方法和蒙特卡羅方法的迭代次數(shù),更好地理解期權(quán)定價。
以上兩點深化了 Options Calculator 的學(xué)術(shù)研究價值意義。深度層面的加強。
功能介紹
主界面采用流行的左右布局,左側(cè)是 LOGO 和 六個 Tab 標(biāo)簽功能頁,右側(cè)為每一個標(biāo)簽頁對應(yīng)的主界面。默認(rèn)在第一個 Tab 下,即歡迎光臨。因為還沒有輸入?yún)?shù),因此無法查看價格,第三個標(biāo)簽是禁止的。
在輸入?yún)?shù)界面,涵蓋了有關(guān)期權(quán)的一些參數(shù)錄入。首先是當(dāng)前日期,默認(rèn)會設(shè)置今天的日期,可以指定往期日期。這里點擊后會調(diào)用一個日歷格式。到期日期默認(rèn)為當(dāng)前日期的后十天。然后有美式歐式和看漲看跌的選項,只提供兩種選擇。最后是標(biāo)的資產(chǎn)現(xiàn)價,期權(quán)執(zhí)行價,波動率,一年單利計無風(fēng)險利率,一年單利計股息利率的輸入。這里會默認(rèn)提供一些,以便用戶想直接看結(jié)果。波動率,無風(fēng)險利率,股息利率都是結(jié)尾是%的,即如果用戶要輸入 5%,只要輸入5即可。在其他期權(quán)計算器中往往都是讓用戶直接輸入無風(fēng)險利率,而我們這里要求用戶需要輸入的是一年單利計利率,將轉(zhuǎn)換交給了計算器本身。最后可以指定蒙特卡羅迭代次數(shù)和二叉樹次數(shù),也可以使用默認(rèn)的設(shè)定。
當(dāng)點擊確定輸入后,會彈出提示框讓用戶等待,并在完成后自動跳轉(zhuǎn)到查看價格的 Tab。可以觀察三種方法的計算結(jié)果。
算法一覽直(tou)接(lan)進入MBA的網(wǎng)頁界面。
關(guān)于我們。
再見頁面。
編譯方法
項目依賴于 Python3以及下列Python包:numpy,pyqt5,qtawesome 和 scipy。
安裝完 python 后可進入項目目錄通過以下指令安裝缺少的包。
pip install requirements.txt
在 本頁面 下載此倉庫,并解壓
在終端中輸入
cd 到剛剛解壓的目錄
cd Frontend
chmod a+x main.py
python main.py
即可。
項目結(jié)構(gòu)
本項目總共621行,結(jié)構(gòu)如下:
.
├── Backend
│?? ├── __init__.py
│?? ├── Option.py
├── Frontend
│?? ├── about.py
│?? ├── img
│?? │?? ├── background_2.png
│?? │?? ├── background_3.png
│?? │?? ├── background.png
│?? │?? ├── hint.png
│?? │?? └── logo2.png
│?? ├── input.py
│?? ├── list.py
│?? ├── main.py
│?? ├── page.py
│?? ├── quit.py
│?? ├── result.py
│?? ├── style.qss
│?? └── welcome.py
├── img
│?? ├── about.png
│?? ├── input.png
│?? ├── list.png
│?? ├── quit.png
│?? ├── result.png
│?? └── welcome.png
├── README.md
└── requirements.txt
項目分為前端和后端,前端在Frontend 文件夾里,后端在 Backend 文件夾里。README.md 即本文件。根目錄下 img 里的文件只是為了本文檔的渲染而已,忽略即可。 requirements.txt 記錄了項目的依賴。
后端
后端里有__init__.py 和 option.py。 前者僅僅只是為了前端導(dǎo)入所必要的文件,其內(nèi)容為空。
而 Option.py 是核心,有一個 option 類,內(nèi)含期權(quán)的數(shù)據(jù)和計算價格的方法??梢源蜷_閱讀,有詳盡的注釋。我們需要 numpy 來計算ndarray列表和生成隨機數(shù),需要scipy 來計算正態(tài)分布分布函數(shù)。內(nèi)置了 B-S 算法,蒙特卡羅算法和二叉樹算法。
前端
前端基于Qt的主框架,主界面在 main.py 里,需要 qtawesome來繪制圖標(biāo)。page.py是一個單獨頁面的基礎(chǔ)。
welcome.py input.py result.py list.py about.py quit.py 分別對應(yīng)歡迎頁面,輸入頁面,結(jié)果頁面,算法一覽頁面和退出頁面。style.qss 是樣式,定義了一些諸如哪些按鈕應(yīng)該長什么樣等等。此目錄里的 img 里的文件是繪制界面需要用的一些圖片。
算法詳解
Option 類
european 為是否是歐式期權(quán) (False 為歐式期權(quán))
kind 看漲或看跌(Put 為 -1 ,Call 為 1)
s0 標(biāo)的資產(chǎn)現(xiàn)價
k 期權(quán)執(zhí)行價
t 期權(quán)到期時間 - 現(xiàn)在時間
r 適用的無風(fēng)險利率
sigma 適用的波動率
dv 股利利率
class Option:
def __init__(self, european, kind, s0, k, t, r, sigma, dv):
self.european = european
self.kind = kind
self.s0 = s0
self.k = k
self.t = t /365
self.sigma = sigma
self.r = r
self.dv = dv
self.bsprice = None
self.mcprice = None
self.btprice = None
這里認(rèn)為傳遞給期權(quán)的構(gòu)造函數(shù)的無風(fēng)險利率和股利利率都是一年計利率,我們在構(gòu)造時將其計算為連續(xù)復(fù)利。
B-S-M 計算方法
因為涉及到了股利利率,所以嚴(yán)格來說不是BS算法而是BSM算法。
def bs(self):
if self.european or self.kind == 1:
d_1 = (np.log(self.s0 / self.k) + (
self.r - self.dv + .5 * self.sigma ** 2) * self.t) / self.sigma / np.sqrt(
self.t)
d_2 = d_1 - self.sigma * np.sqrt(self.t)
self.bsprice = self.kind * self.s0 * np.exp(-self.dv * self.t) * sps.norm.cdf(
self.kind * d_1) - self.kind * self.k * np.exp(-self.r * self.t) * sps.norm.cdf(self.kind * d_2)
else:
self.bsprice = "美式看跌期權(quán)不適合這種計算方法"
BSM 算法本身只能用于歐式期權(quán),由于美式看漲期權(quán)和歐式看漲期權(quán)價格相等,因此我們將擴展到僅僅是不能計算美式看跌期權(quán)。
其中我們算了d1 和 d2 它們是用于最終計算的中間變量。涉及到有股利情況下,它們是
$$
d_1 = \frac{ln\frac{S0}{k} + (r+ 0.5 \cdot \sigma^2 - dv)t}{\sigma \cdot \sqrt{t}}
$$
$$
d_2 = d_1 - \sigma \sqrt{t}
$$
而看漲期權(quán)(涉及股利)的價格為
$$
P = S_0 \cdot e^{-dv \cdot t} \cdot N(d_1) - k \cdot e^{-rt}N(d_2)
$$
看跌期權(quán)的價格就是
$$
P = ke^{-rt}[1-N(d_2)] - S_0[1-N(d_1)]
$$
這里運用了一些小技巧,將kind表示成一個flag標(biāo)記,使得同一個式子能應(yīng)用于看漲看跌兩種情況。注意
$$
N(d) = 1 - N(-d)
$$
這是我們的公式能正確運行的原因。
蒙特卡羅模擬計算方法
蒙特卡羅算法本身只能用于歐式期權(quán),由于美式看漲期權(quán)和歐式看漲期權(quán)價格相等,因此我們將擴展到僅僅是不能計算美式看跌期權(quán)。
蒙特卡洛模擬計算方法需要指定迭代次數(shù)iteration。
注意我們生成的 zt 是一個列表,不是一個單一的值,它的所有值的分布符合一個標(biāo)準(zhǔn)正態(tài)分布,總共有iteration個值,它代表波動的上漲或下跌。
接下來我們根據(jù)這個公式
$$
st = s0 * e^{(r-dv-0.5*\sigma^2)*t + \sigma *t ^{0.05}*zt}
$$
來計算最終價值,這里根據(jù)迭代次數(shù)生成了迭代次數(shù)個最終價值。這些最終價值要根據(jù)看漲或看跌進行 k- x 或者 x-k 的處理,并取處理后和0相比的較大值。
我們計算這些最終價值的平均值,再貼現(xiàn)到當(dāng)前日期。貼現(xiàn)是指原價值乘以e^(-r*t)
# 蒙特卡羅定價
def mc(self, iteration):
if self.european or self.kind == 1:
zt = np.random.normal(0, 1, iteration)
st = self.s0 * np.exp((self.r - self.dv - .5 * self.sigma ** 2) * self.t + self.sigma * self.t ** .5 * zt)
st = np.maximum(self.kind * (st - self.k), 0)
self.mcprice = np.average(st) * np.exp(-self.r * self.t)
else:
self.mcprice = "美式看跌期權(quán)不適合這種計算方法"
二叉樹計算方法
此方法最難,但是適用于所有期權(quán),因此也最為必要。我們首先要計算u,d,p。u代表上漲,d代表下跌,p是一個風(fēng)險中性概率。每一期可能上漲,也可能下跌,u,d即衡量上漲會漲的倍數(shù)和下跌會下跌的倍數(shù)。p即上漲的概率,1-p 是下跌的概率。從最開始的單一起點(標(biāo)的資產(chǎn)價值)慢慢往未來推,可能上漲可能下降,下降后又可能上漲可能下降,這樣子慢慢形成一棵二叉樹。這時候二叉樹的價格不是期權(quán)價值,是站在未來時間的估計現(xiàn)價。 而我們需要的是期權(quán)價格。
我們需要從樹的葉子節(jié)點從后往前推導(dǎo)期權(quán)價值。舉例來說,最后一步最上面節(jié)點的期權(quán)價值等于(n = 迭代次數(shù)),每一個節(jié)點類似,只是下面的節(jié)點需要將u替換成d,n以每個節(jié)點減少2的等差往下降。
$$
max(0,k-s_0u^n)
$$
這是看跌期權(quán),看漲期權(quán)則為
$$
max(0,s_0u^n-k)
$$
這樣我們得到了二叉樹最后一層葉子節(jié)點的所有期權(quán)價值。
每次往前推的過程是這樣,
n-1節(jié)點的期權(quán)價值等于n步對應(yīng)的兩個節(jié)點的風(fēng)險中性概率加權(quán)再無風(fēng)險利率貼現(xiàn)的值,(美式同時和提前行權(quán)的價值取較大值)。
舉例來說,s0 u^500 和 s0 u^498的父節(jié)點是s0 u^499,它的期權(quán)價值等于
p *(500的節(jié)點的期權(quán)價值) * (1-p) *(499的節(jié)點的期權(quán)價值) × 無風(fēng)險利率貼現(xiàn)
無風(fēng)險利率貼現(xiàn)就是 e^(-rt)
注意,如果是美式期權(quán)的話,這個價值還要和 k - s0 u^499 相比,(看漲是 s0 u^499 - k)取較大值。
這樣一層層往前推,就推導(dǎo)到了我們的根節(jié)點,就是站在此時此刻的期權(quán)價值。
def bt(self, iteration):
if iteration % 2 != 0:
iteration += 1
delta = self.t / iteration
u = np.exp(self.sigma * np.sqrt(delta))
d = 1 / u
p = (np.exp((self.r - self.dv) * delta) - d) / (u - d)
tree = []
for j in range(int(iteration / 2) + 1):
i = j * 2
temp = self.s0 * np.power(u, iteration - i)
temp = np.max([(temp - self.k) * self.kind, 0])
tree.append(temp)
for j in range(1, int(iteration / 2) + 1):
i = j * 2
temp = self.s0 * np.power(d, i)
temp = np.max([(temp - self.k) * self.kind, 0])
tree.append(temp)
for j in range(0, iteration):
newtree = []
for i in (range(len(tree) - 1)):
temp = tree[i] * p + (1 - p) * tree[i + 1]
temp = temp * np.exp(-self.r * delta)
if not self.european:
# 每一層的最高冪次
k = iteration - j - 1
if i < (k + 1) / 2:
power = k - i * 2
compare = self.s0 * np.power(u, power)
else:
power = i * 2 - k
compare = self.s0 * np.power(d, power)
temp = np.max([temp, (compare - self.k) * self.kind])
newtree.append(temp)
tree = newtree
self.btprice = tree[0]
總結(jié)
以上是生活随笔為你收集整理的python期权价格计算器_GitHub - jason88888/Options-Calculator: 期权价格计算器——金融工程第二次展示...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AsciiDoc 学习
- 下一篇: [AsciiDoc]_[项目管理]_[适