FpML to QuantLib 外滙歐式Barrier選擇權估值

Non-Copylefted 2019 Alvin Cho. Provided ‘AS IS’. 10 May 2019.
Any quantitative method used in this file may not 100% correct for some reasons. Please use them after you fully understand them.
版權沒有, 歡迎使用, 沒有任何保證. 裡面使用的估值方法只為說明方便, 可能因為任何理由不正確或是不適用你的情況, 請完全理解再使用.

FpML 解析

from lxml import etree

利用 etree.parse 將 xml 檔案載入並 parse. 這個 FpML 文檔是 FpML 5.11 Second Working Draft Comfirmation View 裡的 fx-ex12-fx-barrier-option.xml. 將 FpML.org 下載的最新版規格壓後就可以找到. 此 FpML 文檔的詳細說明請參考 這篇文章

fp=etree.parse('FpML/confirmation/products/fx-derivatives/fx-ex12-fx-barrier-option.xml')

Confirmation View 的 namespace 一律是這個, 在任何 xpath 搜尋都需要指定 namespace.
在 FpML 裡面 namespace 用得不是很複雜, 同一個 view 裡的都用一樣

ns={"ns":"http://www.fpml.org/FpML-5/confirmation"}
asset=fp.xpath('//ns:trade/*',namespaces=ns)[1].tag

找到 tag 為 trade 的 node, 裡面有交易的細節. 第二個子節點就是這筆交易的產品. 這個文檔是做 fxOption

asset
'{http://www.fpml.org/FpML-5/confirmation}fxOption'
exercise=fp.xpath('//ns:fxOption/ns:americanExercise | //ns:fxOption/ns:europeanExercise',namespaces=ns)[0].tag

判斷這個外滙選擇權是美式還是歐式. 此產品是歐式, 也就是只在到期日能行權.

exercise
'{http://www.fpml.org/FpML-5/confirmation}europeanExercise'
expiryDate=fp.xpath('//ns:expiryDate/text()',namespaces=ns)[0]

其他要素一一提出

expiryDate
'2002-02-06'
putCurrency=fp.xpath('//ns:putCurrencyAmount/ns:currency/text()',namespaces=ns)[0]
putCurrency
'USD'
putCurrencyAmount=fp.xpath('//ns:putCurrencyAmount/ns:amount/text()',namespaces=ns)[0]
putCurrencyAmount
'4500000'
callCurrency=fp.xpath('//ns:callCurrencyAmount/ns:currency/text()',namespaces=ns)[0]
callCurrency
'EUR'
callCurrencyAmount=fp.xpath('//ns:callCurrencyAmount/ns:amount/text()',namespaces=ns)[0]
putCurrencyAmount
'4500000'
strike=fp.xpath('//ns:strike/ns:rate/text()',namespaces=ns)[0]
strike
'0.9'
strikeQuoteBasis=fp.xpath('//ns:strike/ns:strikeQuoteBasis/text()',namespaces=ns)[0]
strikeQuoteBasis
'PutCurrencyPerCallCurrency'

檢查是不是複雜選擇權, 看看有沒有 features 節點.

features=fp.xpath('//ns:features',namespaces=ns)
if len(features)>0: print('complex')
else:print('vanilla')
complex

果然是個複雜選擇權, 檢查各種複雜要素. 我們知道這裡面只有 barrier 這一項, 就只檢查 barrier 了.

barriers=fp.xpath('//ns:barrier',namespaces=ns)
len(barriers)
1

只有一個 barrier 定義

barrierType=fp.xpath('//ns:barrierType/text()',namespaces=ns)[0]
barrierType
'Knockin'

是屬於 Knock-In 形式

spotRate=fp.xpath('//ns:spotRate/text()',namespaces=ns)[0]
spotRate
'0.8935'
triggerRate=fp.xpath('//ns:triggerRate/text()',namespaces=ns)[0]
triggerRate
'0.8975'
direction=fp.xpath('//ns:barrier/ns:direction/text()',namespaces=ns)[0]
direction
'Up'

spotRate < triggerRate, 表示 spotRate 上漲才會觸碰界限, 所以這是 Up and In 形式.

rateSource=fp.xpath('//ns:barrier//ns:rateSource/text()',namespaces=ns)[0]
rateSource
'Reuters'
rateSourcePage=fp.xpath('//ns:barrier//ns:rateSourcePage/text()',namespaces=ns)[0]
rateSourcePage
'EUR='

價格參考是路透社的 EUR=. 可能大多數讀者都沒有辦法取得路透數據, 在此就不多做說明. 未來制作實際的計算器再來介紹如何取得實際市場數據.

observationStartDate=fp.xpath('//ns:barrier//ns:observationStartDate/text()',namespaces=ns)[0]
observationStartDate
'2001-08-16'
observationEndDate=fp.xpath('//ns:barrier//ns:observationEndDate/text()',namespaces=ns)[0]
observationEndDate
'2002-02-06'

觀察期為 2001-08-16 到 2002-02-06.

到這裡我們結束了 lxml 的工作, 要進入到 QuantLib 的世界了

QuantLib 估值

from QuantLib import *
e=expiryDate.split('-')
e
['2002', '02', '06']

使用 QuantLib 的日期, 不但是估值過程需要, 對一些節假日調整和工作日計算也很有用.

expiry=Date(int(e[2]),int(e[1]),int(e[0]))
expiry
Date(6,2,2002)

日曆在 FpML 和 QuantLib 都處理得很仔細,這是在美國紐約的交易, 使用 QuantLib 內建的美國行事曆.

calendar=UnitedStates()

原本應該用今天的日期, 但這產品早就到期閮, 把估值日定為觀察期的開始日.

v=observationStartDate.split('-')
valuationDate=Date(int(v[2]),int(v[1]),int(v[0]))
valuationDate
Date(16,8,2001)

到美國 FED 提供的數據庫找滙率歷史價格

fredEXCode={'USDEUR':'DEXUSEU', 'CNYUSD':'DEXCNUS', 'JPYUSD':'DEXJPUS', 'USDGBP':'DEXUSUK', 'AUDUSD':'DEXUSAL'}
currencyPair=putCurrency+callCurrency
fred=fredEXCode[currencyPair]

取 253 個資料點, 可以做出 252 個報酬率數據, 用這些數據來計算歷史波動率 volatility. 注意: 這個歷史波動率所計算出來的價格跟市場價會有差距.

volStartDate=calendar.advance(valuationDate,Period(-253,Days))
volStartDate
Date(14,8,2000)

準備好日期之後, 我們要調用 FED 提供的匯率歷史數據. 利用 Pandas-datareader

import pandas_datareader.data as pddr
priceData=pddr.DataReader(fred,'fred',str(volStartDate.dayOfMonth())+'/'+str(volStartDate.month())+'/'+str(volStartDate.year()),str(valuationDate.dayOfMonth())+'/'+str(valuationDate.month())+'/'+str(valuationDate.year()))
priceData
DEXUSEU
DATE
2000-08-14 0.9037
2000-08-15 0.9135
2000-08-16 0.9143
2000-08-17 0.9152
2000-08-18 0.9068
2000-08-21 0.9027
2000-08-22 0.8965
2000-08-23 0.8967
2000-08-24 0.9028
2000-08-25 0.9024
2000-08-28 0.9002
2000-08-29 0.8966
2000-08-30 0.8924
2000-08-31 0.8878
2000-09-01 0.8993
2000-09-04 NaN
2000-09-05 0.8876
2000-09-06 0.8702
2000-09-07 0.8740
2000-09-08 0.8664
2000-09-11 0.8624
2000-09-12 0.8596
2000-09-13 0.8640
2000-09-14 0.8617
2000-09-15 0.8572
2000-09-18 0.8523
2000-09-19 0.8514
2000-09-20 0.8462
2000-09-21 0.8558
2000-09-22 0.8793
... ...
2001-07-06 0.8465
2001-07-09 0.8474
2001-07-10 0.8557
2001-07-11 0.8614
2001-07-12 0.8530
2001-07-13 0.8527
2001-07-16 0.8549
2001-07-17 0.8549
2001-07-18 0.8701
2001-07-19 0.8690
2001-07-20 0.8713
2001-07-23 0.8676
2001-07-24 0.8752
2001-07-25 0.8797
2001-07-26 0.8765
2001-07-27 0.8749
2001-07-30 0.8750
2001-07-31 0.8752
2001-08-01 0.8793
2001-08-02 0.8813
2001-08-03 0.8843
2001-08-06 0.8802
2001-08-07 0.8775
2001-08-08 0.8778
2001-08-09 0.8886
2001-08-10 0.8940
2001-08-13 0.8983
2001-08-14 0.9025
2001-08-15 0.9114
2001-08-16 0.9138

264 rows × 1 columns

要估值的 valueDate 設定為 observationStartDate

Settings.instance().evaluationDate=valuationDate

好, 所有信息都齊備了, 我們要建立這個期權的基本信息

option=BarrierOption(Barrier.UpIn, float(triggerRate), 0.0, PlainVanillaPayoff(Option.Call, float(strike)),EuropeanExercise(expiry))

以下要進入估值階段了. 使用 numpy 的數學公式來計算 volatility. NaN的值未處理

import numpy
priceData['Log_Return']= numpy.log(priceData[fred] / priceData[fred].shift(1) )
volatility=numpy.std(priceData['Log_Return'])*numpy.sqrt(252)
volatility
0.11406364037803043

建立一個常數型的波動率, Day Count 是 Actual/365 Fixed

volatilityTS=BlackVolTermStructureHandle(BlackConstantVol(valuationDate, calendar, volatility, Actual365Fixed()))

下一步是準備 Garman Kohlagen Process 做外滙選擇權估值所需要的兩個貨幣的無風險利率, 要從網路取得免費的各國無風險利率值有點困難, 先定為 0.02 和 0.03 常數

r=0.02
rTS=YieldTermStructureHandle(FlatForward(valuationDate,r,Actual365Fixed()))
f=0.03
fTS=YieldTermStructureHandle(FlatForward(valuationDate,f,Actual365Fixed()))

Spot 價格可以取歷史數據最後一筆, 也可以直接用產品內容的 spotRate. 用 spotRate 比較不會有 Up 或 Down 矛盾的地方. 它是個 Handle, 跟變數一樣可以調整 Handle 的再重新估值, 以後再詳細說明這部份.

spot=float(spotRate)
spot
0.8935
spotHandle=QuoteHandle(SimpleQuote(spot))

再來是建立 Garman Kohlagen Process

gkProcess=GarmanKohlagenProcess(spotHandle, fTS, rTS, volatilityTS)

將 Process 指定給一個 AnalyticBarrierEngine

option.setPricingEngine(AnalyticBarrierEngine(gkProcess))

大功告成, 可以估值了!

option.NPV()
0.02283339143459734

再試試另一個 Finite-Differences Black Scholes Barrier Engine

grid=5; maxGrid=1000
option.setPricingEngine(FdBlackScholesBarrierEngine(gkProcess, grid, maxGrid))
option.NPV()
0.02295666531645272

FpML to QuantLib 外滙歐式Barrier選擇權估值 fx-ex12-fx-barrier-option.xml相关推荐

  1. FpML to QuantLib 外滙美式選擇權估值

    FpML to QuantLib 外滙美式選擇權估值 Non-Copylefted 2019 Alvin Cho. Provided 'AS IS'. 7 May 2019. Any quantita ...

  2. pl/sql函数学习

    7種函數的詳細介紹及用法: 1.錯誤報告(error reporting)函數    sqlcode   返回oracle錯誤號    sqlerrm   返回oracle錯誤信息 主要用於異常處理 ...

  3. VCD(俗称影音光碟)

    VCD 影音光碟(),又稱影音壓縮光碟,是一種在光碟(Compact Disc)上存儲視訊信息的標準.VCD可以在個人電腦和VCD播放器[1]以及大部分DVD播放機中播放,但現時大部份藍光光碟播放機已 ...

  4. qq在线咨询代码,MSN在线代码,贸易通在线留言源代码!

    QQ在线咨询代码,MSN在线代码,雅虎通在线代码,贸易通在线代码 ------------------------------------------------------------------- ...

  5. (转)jQuery 基础

    [初探] jQuery 怎麼用來「快速選取元素」並且「做一些事情」呢?請看看程式碼: $("div").addClass("special"); 錢記號 $ 是 ...

  6. Jenkins:設定一次後就很方便的排程工具

    Jenkins擁有定時排程功能 Jenlins可以結合GIt,達到維持本機端程式碼為最新版本 Jenkins可以結合Unity,達到定期自動編譯版本的功能 Jenkins可以結合CIFS(網路芳鄰), ...

  7. barrier linux,LinuxBarrierI/O的介绍有哪些呢? 爱问知识人

    Barrier I/O的目的是使其之前的I/O在其之前写入存储介质,之后的I/O需要等到其写入完成后才能得到执行.为了实现这个要求,我们最多需要执行2次flush(刷新)操作.(注意,这儿所说的flu ...

  8. Iceberg 在基于 Flink 的流式数据入库场景中的应用

    本文以流式数据入库的场景为基础,介绍引入 Iceberg 作为落地格式和嵌入 Flink sink 的收益,并分析了当前可实现的框架及要点. 应用场景 流式数据入库,是大数据和数据湖的典型应用场景.上 ...

  9. Python 线程障碍对象 Barrier - Python零基础入门教程

    目录 一.Python 线程障碍对象 Barrier 简介 二.Python 线程障碍对象 Barrier 原理 三.Python 线程障碍对象 Barrier 函数介绍 四.Python 线程障碍对 ...

最新文章

  1. numpy库中ones和zeros函数传入的shape(表示各个维度的度数)参数的详解
  2. leetcode精选
  3. Betriebssystem I 操作系统课件 01. Evolution von Rechnersystemen 计算机操作系统的演变
  4. UA MATH566 统计理论10 Bootstrap简介
  5. 程序员面试题精选100题(52)-C++面试题(1)
  6. jupyter 数据分析可视化案例_Python数据分析及可视化实例之Anaconda、Jupyter简介
  7. 在定时器中service注入不进去的解决方案
  8. Tensorrt7: AttributeError: ‘NoneType‘ object has no attribute ‘create_execution_context‘
  9. java+classpath的理解_Java配置path和classpath的含义详解-Go语言中文社区
  10. Jquery打造AdRotator轮转图片
  11. WebWorker和Server-Sent Events和HTML5 WebSocket
  12. 六石编程学:方便调试输出的标准C代码
  13. windows 添加开机启动项
  14. 从远景论坛上学到的完美激活NERO8 NERO9的经验
  15. Robin广场舞案例实践分析之深入思考
  16. 罗克韦尔AB PLC安装Studio5000提示未安装Microsoft .NET Framework 3.5的解决方法
  17. 正则表达式验证中文或者英文
  18. 《C#零基础入门之百识百例》(三十五)方法返回 -- 自守数
  19. 数组转集合问题Arrays.asList()
  20. 使用皮皮影院搭建电影展

热门文章

  1. 华为WATCH GT3正式开售,健康监测和运动管理我全都要
  2. 灵魂的拷问 怎么将代码写得让人无法维护?
  3. 易淘食创始人口述:做外卖O2O的诀窍是“打穿商家”
  4. strongswan简单介绍
  5. js 捕获子元素的 focus 事件
  6. html边角效果图,PS制作卷边/卷角效果图2种方法,PS交错的作用,PS压缩图像方法,PSHTML+图像的解释,PS颜色位数的作用...
  7. 基于SSM医药后台管理系统
  8. FreeMaker语法大全及示例
  9. docker-compose模板指令 命令行指令
  10. echarts地图中增加图片的实例