作者:李士昱、孫冬凱、梁程遠(yuǎn)
雪球期權(quán)是一種新興的結(jié)構(gòu)較為復(fù)雜的期權(quán)產(chǎn)品,雪球期權(quán)的定價(jià)的準(zhǔn)確性和速度直接影響交易雙方的收益和風(fēng)險(xiǎn)水平。目前我司雪球期權(quán)定價(jià)采用的是基于C++程序?qū)崿F(xiàn)蒙特卡羅模擬的方法。本文為解決基于C++的傳統(tǒng)定價(jià)程序帶來的處理時(shí)間長(zhǎng)、延遲高、處理速率低的問題,提出并實(shí)現(xiàn)了一種基于FPGA的并行流水線計(jì)算處理設(shè)計(jì),能夠完成對(duì)雪球期權(quán)的定價(jià)功能,并使用HLS開發(fā)模式對(duì)設(shè)計(jì)進(jìn)行了實(shí)現(xiàn)。通過對(duì)比測(cè)試,相對(duì)于通用處理器與C++軟件實(shí)現(xiàn)的定價(jià)方式可獲得約17.83倍的性能提升。
引 言
普通歐式期權(quán)通常可以使用Black-Scholes模型進(jìn)行定價(jià),雪球期權(quán)在歐式期權(quán)的基礎(chǔ)上引入的觀察日和敲入敲出的概念,使得其定價(jià)無法運(yùn)用類似模型獲得一個(gè)確定的期望價(jià)格,因此需要使用蒙特卡羅方法進(jìn)行模擬。蒙特卡羅方法是一種對(duì)過程隨機(jī)抽樣的程序,我們可以通過隨機(jī)采樣得到近似的結(jié)果,其擁有采樣越多,越近似最優(yōu)解的特點(diǎn)。蒙特卡羅方法廣泛應(yīng)用于科學(xué)計(jì)算的各種領(lǐng)域。傳統(tǒng)思路是使用通用微處理器(CPU)進(jìn)行蒙特卡羅模擬,在這種情況下通常需要通過提高處理器單核性能或者多線程方式提高模擬速度,也有使用GPU等專用計(jì)算處理器的嘗試。然而近年來,隨著摩爾定律漸漸失效,處理器單核性能提升逐漸放緩,而人們對(duì)計(jì)算量的需求隨著大數(shù)據(jù)、人工智能等技術(shù)的發(fā)展卻越來越大,因此對(duì)傳統(tǒng)體系結(jié)構(gòu)的變革需求變得越來越迫切。
隨著FPGA技術(shù)的不斷發(fā)展,利用FPGA進(jìn)行硬件加速已經(jīng)逐步成為一個(gè)新的趨勢(shì)。一方面相比通用架構(gòu),F(xiàn)PGA能夠根據(jù)功能需求進(jìn)行定制,獲得更好的性能和功耗;另一方面相比開發(fā)專用硬件,F(xiàn)PGA的開發(fā)周期更短,成本更低,其可重構(gòu)特性使得能夠根據(jù)算法變化快速進(jìn)行更新迭代。此外,Xilinx公司推出的HLS和蘋果等公司推出的OpenCL等開發(fā)標(biāo)準(zhǔn)使得開發(fā)者能夠使用高級(jí)語言如C或C++進(jìn)行硬件開發(fā)工作,進(jìn)一步降低了開發(fā)門檻,提升了開發(fā)效率[1]。
本文設(shè)計(jì)并使用Xilinx公司提供的HLS開發(fā)方式,利用C++語言實(shí)現(xiàn)了定價(jià)實(shí)現(xiàn)了基于FPGA的雪球期權(quán)定價(jià)程序,并作為動(dòng)態(tài)鏈接庫(kù),通過Java本地接口JNI提供調(diào)用,作為dubbo服務(wù)整合到了場(chǎng)外衍生品OMS訂單管理系統(tǒng)中。
1 雪球期權(quán)的定價(jià)方法
雪球期權(quán)的本質(zhì)是一種賣出帶觸發(fā)條件的看跌期權(quán)。雪球期權(quán)屬于奇異期權(quán),因此帶有奇異期權(quán)的障礙概念,“障礙”是指當(dāng)標(biāo)的資產(chǎn)價(jià)格在特定時(shí)間內(nèi)穿越某一水平該期權(quán)才會(huì)生效或者失效。“障礙”一般分為敲出和敲入兩類。敲出即當(dāng)標(biāo)的資產(chǎn)價(jià)格達(dá)到一個(gè)特定的障礙水平時(shí),該期權(quán)了結(jié)并兌現(xiàn)賠付,若規(guī)定時(shí)間內(nèi)標(biāo)的資產(chǎn)價(jià)格沒有觸及障礙水平,則為一個(gè)普通期權(quán)。敲入與敲出期權(quán)相反,當(dāng)標(biāo)的資產(chǎn)價(jià)格達(dá)到一個(gè)特定障礙水平時(shí),該期權(quán)才能觸發(fā)約定賠付機(jī)制,若規(guī)定時(shí)間內(nèi)標(biāo)的資產(chǎn)價(jià)格沒有觸及障礙水平,則不觸發(fā)約定賠付機(jī)制。
一個(gè)雪球期權(quán)的要素表示如下:
雪球期權(quán)存續(xù)或結(jié)束時(shí)可能出現(xiàn)三種情形:
(1)產(chǎn)品發(fā)出敲出事件,此時(shí)無論是否發(fā)生敲入事件,產(chǎn)品將提前結(jié)束,客戶可獲得票息收益,按照產(chǎn)品實(shí)際存續(xù)期計(jì)算。
(2)產(chǎn)品存續(xù)期未發(fā)生敲出或敲入事件,客戶可在產(chǎn)品到期時(shí)獲得票息收益,按產(chǎn)品期限計(jì)算。
(3)產(chǎn)品存續(xù)期發(fā)生了敲入事件但未發(fā)生敲出事件,則客戶無票息收益,且可能承擔(dān)虧損,,如無跌幅則無虧損。
由上述條件可得到雪球期權(quán)收益率如圖1所示:
圖 1雪球期權(quán)收益
由于雪球期權(quán)障礙的存在,我們難以直接給出雪球期權(quán)的價(jià)格模型,因此考慮采用蒙特卡羅方法對(duì)作為標(biāo)的的股票價(jià)格進(jìn)行抽樣,根據(jù)股票價(jià)格和障礙條件確定雪球期權(quán)最終收益,將收益折現(xiàn)后得到雪球期權(quán)的當(dāng)前價(jià)格。
2 雪球期權(quán)定價(jià)程序設(shè)計(jì)
2.1 雪球期權(quán)蒙特卡羅定價(jià)程序設(shè)計(jì)
我們以幾何布朗運(yùn)動(dòng)模型描述風(fēng)險(xiǎn)中性情況下股票價(jià)格隨時(shí)間變化的離散形式如下[2]:
其中為無風(fēng)險(xiǎn)利率 ,為股票波動(dòng)率,服從標(biāo)準(zhǔn)正態(tài)分布。我們需要對(duì)該隨機(jī)過程進(jìn)行蒙特卡羅模擬,獲得標(biāo)的股票期權(quán)存續(xù)期內(nèi)的價(jià)格路徑。蒙特卡羅模擬程序主要有兩個(gè)模塊,一是生成服從標(biāo)準(zhǔn)正態(tài)分布的隨機(jī)數(shù),二是完成價(jià)格計(jì)算,進(jìn)行股票價(jià)格路徑模擬,并根據(jù)模擬結(jié)果計(jì)算雪球期權(quán)價(jià)格,由此可得到定價(jià)程序流程圖如圖2所示:
圖 2雪球期權(quán)定價(jià)程序流程圖
在通用處理器上程序都是串行順序執(zhí)行,執(zhí)行效率不高。本文提出了基于FPGA的解決方案。在處理方式上采用流水線執(zhí)行,并在路徑模擬部分根據(jù)硬件資源使用進(jìn)行一定程度的并發(fā),進(jìn)一步提高了路徑模擬的吞吐量。
圖3雪球期權(quán)定價(jià)在FPGA多并發(fā)流水線的執(zhí)行流程示例
2.2 定價(jià)程序開發(fā)模式
傳統(tǒng)FPGA開發(fā)方式通常采用RTL級(jí)描述,如使用Verilog或VHDL語言。RTL級(jí)開發(fā)雖然直接描述硬件的行為,能夠獲得更加準(zhǔn)確、性能更好的電路設(shè)計(jì),但是對(duì)于軟件工程師來說門檻較高,調(diào)試優(yōu)化時(shí)間也更長(zhǎng),就好像在用匯編語言進(jìn)行軟件開發(fā)一樣。為了解決這些問題,Xilinx公司推出了支持高層次綜合(High-Level Synthesis)的編譯工具,使開發(fā)人員能夠使用C/C++語言進(jìn)行FPGA開發(fā),把精力更多集中在算法實(shí)現(xiàn)上面,不需要親自動(dòng)手進(jìn)行底層細(xì)節(jié)的實(shí)現(xiàn),極大提升了開發(fā)效率。圖4展示了使用RTL設(shè)計(jì)方法的傳統(tǒng)FPGA開發(fā)方式、HLS開發(fā)方式與其他平臺(tái)主流設(shè)計(jì)開發(fā)方法的開發(fā)時(shí)間和理想性能對(duì)比。
圖4不同平臺(tái)開發(fā)方式時(shí)間和理想性能對(duì)比[3]
總體來說,HLS可以自動(dòng)完成以下曾經(jīng)需要手動(dòng)完成的工作,包括[4]:
(1)HLS自動(dòng)分析并利用一個(gè)算法中潛在的并發(fā)性;
(2)HLS自動(dòng)在需要的路徑上插入寄存器,并自動(dòng)選擇最理想的時(shí)鐘;
(3)HLS自動(dòng)產(chǎn)生控制數(shù)據(jù)在一個(gè)路徑上出入方向的邏輯;
(4)HLS自動(dòng)完成設(shè)計(jì)的部分與系統(tǒng)中其他部分的接口;
(5)HLS自動(dòng)映射數(shù)據(jù)到儲(chǔ)存單位以平衡資源使用與帶寬;
(6)HLS自動(dòng)將程序中計(jì)算的部分對(duì)應(yīng)到邏輯單位,在實(shí)現(xiàn)等效計(jì)算的前提下自動(dòng)選取最有效的實(shí)施方式。
本文采用HLS方式進(jìn)行雪球期權(quán)定價(jià)程序的開發(fā),一方面可以降低開發(fā)難度,將冪計(jì)算、開方計(jì)算、浮點(diǎn)數(shù)處理等硬件開發(fā)難點(diǎn)交由編譯器進(jìn)行處理,提升開發(fā)速度,另一方面能夠?qū)W⒂谒惴▽?shí)現(xiàn),從更高層級(jí)優(yōu)化程序的執(zhí)行效率,提升程序優(yōu)化效率,在更短時(shí)間內(nèi)獲得更高性能提升。
3定價(jià)程序?qū)崿F(xiàn)與優(yōu)化
3.1 總體設(shè)計(jì)與實(shí)現(xiàn)
雪球定價(jià)程序參照Xilinx推薦的層次結(jié)構(gòu),總體自下至上可以分為三個(gè)層次:最下層L1層提供了用于構(gòu)建內(nèi)核的低級(jí)原語,包括隨機(jī)數(shù)生成器、路徑模擬、累加器等模塊;中間層由L1層各模塊構(gòu)建,并輔以更高層次層次邏輯控制和計(jì)算模塊,并以FPGA內(nèi)核形式提供定價(jià)引擎的接口;L3層則將數(shù)據(jù)傳輸、與內(nèi)核相關(guān)的資源配置和任務(wù)調(diào)度的低層細(xì)節(jié)抽象化,提供了供高級(jí)語言或軟件可直接調(diào)用的接口,通過調(diào)用即可完成定價(jià)引擎內(nèi)核的部署和運(yùn)行。
此外,我們將定價(jià)用JNI包裝后編譯成動(dòng)態(tài)鏈接庫(kù),使用Java微服務(wù)進(jìn)行調(diào)用,從而將定價(jià)服務(wù)云化,進(jìn)一步為交易人員提供使用便利。圖5展示了定價(jià)功能的整體架構(gòu)。
圖5FPGA雪球定價(jià)程序總體架構(gòu)設(shè)計(jì)
3.2 核心模塊設(shè)計(jì)實(shí)現(xiàn)與優(yōu)化
蒙特卡羅模擬主要功能在L1層實(shí)現(xiàn),L1層共分為隨機(jī)數(shù)生成、路徑模擬和累加器三個(gè)模塊。
3.2.1 隨機(jī)數(shù)生成
隨機(jī)數(shù)生成模塊要求能夠生成符合標(biāo)準(zhǔn)正態(tài)分布的隨機(jī)數(shù),這里我們復(fù)用了Xilinx提供的隨機(jī)數(shù)發(fā)生器。Xilinx共提供了三種正態(tài)分布隨機(jī)數(shù)發(fā)生器,分別為MT19937IcnRng、MT2003IcnRng和MT19937BoxMullerNomralRng。第一種使用MT19937隨機(jī)數(shù),通過逆累計(jì)函數(shù)變換獲得最終結(jié)果;第二種使用MT2203隨機(jī)數(shù),同樣為逆累計(jì)函數(shù)變換獲得結(jié)果,與第一種不同的是MT2203的周期略短,同時(shí)理論上多實(shí)例的相關(guān)性更弱,隨機(jī)性也更好一些;第三種是使用MT19937隨機(jī)數(shù),通過Box-Muller變換得到正態(tài)隨機(jī)數(shù),其優(yōu)點(diǎn)是性能和資源消耗略小。本文采用MT19937BoxMullerNomralRng隨機(jī)數(shù)發(fā)生器來生成隨機(jī)數(shù)。生成的隨機(jī)數(shù)會(huì)按序放入一個(gè)隊(duì)列中結(jié)構(gòu)中,供路徑模擬模塊取用,并通過這一隊(duì)列將兩個(gè)模塊銜接起來組成一個(gè)長(zhǎng)流水線。在HLS中這種隊(duì)列使用hls命名空間的stream類型來表示。
3.2.2 路徑模擬
路徑模擬是定價(jià)程序最重要的模塊,也是邏輯最復(fù)雜、對(duì)總體性能影響最大的模塊。在該模塊中需要對(duì)一條完整的隨機(jī)過程路徑進(jìn)行模擬,也即模擬標(biāo)的股票在期權(quán)存續(xù)期內(nèi)的價(jià)格,并根據(jù)價(jià)格判斷是否觸發(fā)雪球期權(quán)的敲入敲出。
路徑中每節(jié)點(diǎn)開始首先判斷期權(quán)是否已經(jīng)敲出,如敲出則該路徑直接結(jié)束,如未敲出,則將上一節(jié)點(diǎn)價(jià)格和隨機(jī)數(shù)計(jì)算帶入定價(jià)公式,算出當(dāng)前節(jié)點(diǎn)股票價(jià)格,隨后判斷是否是觀察日和敲入敲出等障礙條件是否滿足,并根據(jù)結(jié)果調(diào)整敲入敲出標(biāo)志,最后判斷該路徑模擬是否已經(jīng)結(jié)束,如未結(jié)束則開始模擬路徑中下一個(gè)節(jié)點(diǎn),處理流程如圖6所示。
圖6路徑模擬模塊初始處理流程
FPGA的性能優(yōu)勢(shì)主要體現(xiàn)在流水線處理和并行兩個(gè)方面,在HLS開發(fā)過程中主要是通過對(duì)循環(huán)進(jìn)行流水線處理和展開實(shí)現(xiàn),可以通過加入Pragma提示編譯器進(jìn)行優(yōu)化工作,如:
for(int i = 0; i
#pragma HLS pipeline II = 1
…
}
其中#pragma HLS pipeline即告訴編譯器將該循環(huán)按照流水線展開,II為循環(huán)起始間隔,即本次循環(huán)到下一次循環(huán)開始的時(shí)鐘周期數(shù),本例II=1即告訴編譯器我們期望每周期能夠啟動(dòng)新的循環(huán)迭代,相應(yīng)的即流水線填滿后每周期能夠產(chǎn)生一個(gè)結(jié)果,編譯器會(huì)根據(jù)期望結(jié)果進(jìn)行嘗試,實(shí)際優(yōu)化效果未必能夠完全實(shí)現(xiàn)。
編譯器對(duì)于能夠流水線化循環(huán)的結(jié)構(gòu)也有兩點(diǎn)要求:一是循環(huán)盡量為單層循環(huán)且有固定邊界,二是如果無法滿足單層循環(huán),則盡量在兩層循環(huán)之間沒有邏輯操作且讓內(nèi)層循環(huán)擁有固定邊界[5]。
回顧路徑模擬的處理流程圖我們可以發(fā)現(xiàn),循環(huán)初始對(duì)敲入敲出的判斷在CPU順序執(zhí)行的情況下能夠避免后續(xù)無用的循環(huán),但是在FPGA平臺(tái)則會(huì)導(dǎo)致循環(huán)無法順利流水化,因此需要對(duì)處理流程進(jìn)行調(diào)整,將敲出結(jié)果保存下來留到循環(huán)結(jié)束再進(jìn)行處理,從而固定循環(huán)邊界,使循環(huán)能夠順利展開并減少分支損耗。該優(yōu)化使得循環(huán)迭代周期從II=17降至II=5,優(yōu)化后的處理流程如圖7所示:
圖7優(yōu)化后的路徑模擬處理流程
3.2.3 累加器
累加器模塊一方面將各個(gè)路徑的結(jié)果累加并求平均得到最終結(jié)果,另一方面也負(fù)責(zé)隨機(jī)數(shù)生成和路徑模擬兩個(gè)模塊的銜接,以及路徑模擬的并行展開控制。
由于蒙特卡羅模擬路徑各路徑間的結(jié)果相互獨(dú)立,因此非常適合并行執(zhí)行,在HLS中的實(shí)現(xiàn)方式也非常簡(jiǎn)單,如下所示:
for(int i = 0; i
#pragma HLS unroll factor = unrollNum
mcSimulation();//蒙特卡羅模擬函數(shù)
}
通過#pragma HLS unroll告知編譯器對(duì)該循環(huán)進(jìn)行展開并行執(zhí)行,factor = unrollNum告知編譯器并行度,該部分可以省略,如省略則編譯器會(huì)將循環(huán)完全展開。
各路徑模擬結(jié)果將會(huì)暫存至與隨機(jī)數(shù)類似的隊(duì)列流中,該隊(duì)列在實(shí)例化為硬件后將會(huì)是一個(gè)RAM結(jié)構(gòu),其讀寫口數(shù)量和大小編譯器會(huì)根據(jù)代碼自動(dòng)確定,通常為1讀口1寫口。使用同樣RAM結(jié)構(gòu)的C++數(shù)據(jù)結(jié)構(gòu)還有數(shù)組等。當(dāng)循環(huán)充分流水線化且并行展開后,對(duì)RAM的讀寫將會(huì)非常頻繁,自動(dòng)生成的RAM讀寫口數(shù)量可能會(huì)無法滿足我們的需求,造成流水線阻塞。這時(shí)候就需要告知編譯器所需要的RAM大小和讀寫口數(shù)量,一種方式是直接告知采用的RAM規(guī)格,另一種方式是通過將數(shù)組或隊(duì)列拆分。以一個(gè)完全拆分即每一個(gè)數(shù)均采用寄存器存儲(chǔ),深度為64的隊(duì)列為例,使用HLS的實(shí)現(xiàn)寫法為:
#pragma HLS stream variable = sumStrm depth =64
#pragma HLS array_partition variable =sunStrm dim = 0
4 測(cè)試與分析
4.1 測(cè)試環(huán)境
FPGA測(cè)試平臺(tái):Xilinx公司的Alveo U200 FPGA加速卡,該FPGA加速卡被劃分為3個(gè)內(nèi)核,本次測(cè)試僅測(cè)試單核下的資源利用達(dá)到極限的性能,XRT運(yùn)行環(huán)境版本為u200_201830_2,在Vitis 2019.2開發(fā)環(huán)境下完成的開發(fā)、綜合、驗(yàn)證工作。
對(duì)比程序?yàn)槭褂肣uantLib庫(kù)開發(fā)的基于蒙特卡羅模擬的雪球期權(quán)定價(jià)程序,開發(fā)語言為C++,運(yùn)行環(huán)境處理器為Intel i7-8700,主頻3.2GHz,內(nèi)存16GB,操作系統(tǒng)為64位Windows 10。
測(cè)試方法:在兩個(gè)平臺(tái)使用相同期權(quán)參數(shù)分別運(yùn)行雪球期權(quán)的定價(jià)程序,蒙特卡羅路徑數(shù)為20萬條,路徑節(jié)點(diǎn)數(shù)為246個(gè),對(duì)應(yīng)246個(gè)交易日。程序循環(huán)運(yùn)行100次,每次對(duì)股票波動(dòng)率進(jìn)行調(diào)整,對(duì)比平均運(yùn)行時(shí)間和定價(jià)結(jié)果誤差。期權(quán)主要參數(shù)如表2所示:
4.2 結(jié)果分析
FPGA與C++對(duì)比程序定價(jià)結(jié)果如圖8所示,F(xiàn)PGA定價(jià)結(jié)果相對(duì)C++定價(jià)結(jié)果誤差平均值為2.6%,方差為0.0245。與FPGA定價(jià)結(jié)果相比,C++程序的定價(jià)曲線更不平滑,考慮到兩邊隨機(jī)數(shù)的種子與隨機(jī)數(shù)生成方式均不相同,且蒙特卡羅為對(duì)隨機(jī)過程的抽樣近似,可以認(rèn)為FPGA的定價(jià)結(jié)果準(zhǔn)確,能夠滿足定價(jià)使用要求。
圖8雪球期權(quán)FPGA定價(jià)結(jié)果與C++程序定價(jià)結(jié)果對(duì)比
兩者執(zhí)行時(shí)間對(duì)比,C++程序平均每次定價(jià)時(shí)間為1153.48ms,F(xiàn)PGA程序平均定價(jià)時(shí)間為62.75ms,性能提升約為17.38倍。資源利用率如表3所示,其中最高的LUT查找表單核使用率為98%,基本達(dá)到單核性能極限。
5 結(jié)束語
本文采用流水線并行的設(shè)計(jì)結(jié)構(gòu)實(shí)現(xiàn)了對(duì)雪球期權(quán)的定價(jià),相比于傳統(tǒng)軟件的處理方式,本設(shè)計(jì)在處理時(shí)間上顯著提高,其性能提升約為17.38倍左右。基于本設(shè)計(jì)在現(xiàn)有的Alveo U200 FPGA加速卡上使用HLS開發(fā)模式構(gòu)建了雪球期權(quán)定價(jià)功能,具有穩(wěn)定性好、延遲低、效率高、處理速率快等特點(diǎn),取得了良好的測(cè)試效果,具有較高的工程實(shí)用價(jià)值。
審核編輯:郭婷
評(píng)論