以Java语言改写QuantLib C++链接库

发布于:2022-11-07 ⋅ 阅读:(401) ⋅ 点赞:(0)

在金工的领域中,QuantLib C++链接库早已奠定武林盟主的角色,不论是产品的广度,或是使用模型的深度,都是其它链接库难以望其项背的。然而在现实的金融IT产业中,却很难由其得到直接的效益。究其原因在于,大部分的IT公司在开发大型商业应用系统时,倾向于使用Java语言,C++并不是市场上主要的开发工具。另外一个障碍是,QuantLib架构的复杂度太高,如果没有熟悉金融市场的金工人员指导,单独IT人员很难了解其对象的继承关系,与财务计算的逻辑。

不久前,一位任职于金融IT产业的好友,向我求助,他遇到金工模型开发的瓶颈。朋友在公司负责金融工程中心,手下有6名人手。需要帮公司的大型交易与风管系统,开发核心的计算模块,公司就是使用Java语言来撰写系统的。

我便向他建议,可以使用QuantLib链接库,解决此一问题。事实上,QuantLib可以透过SWIG的包覆,提供Java叫用的接口。在我的协助下,他们确实尝试了这一方法,而且顺利的产生正确的计算结果。因此,他们公司等于立刻拥有全世界的金工专家,免费帮他们开发核心计算模块。然而,他们还是需要我的协助,才能正确的运用这个链接库。因为QuantLib的结构太复杂了,另外如果不了解金融市场的运作逻辑,也无法正确的使用它。

然而,新的问题又浮现出来。一方面是透过SWIG调用C++的DLL,往往会造成计算效能的折扣,另一个潜在的问题是QuantLib C++不支持多线程的运算方式。前者的耗损尤其在执行蒙地卡罗模拟法时特别的突出,因为不断的呼叫C++链接库来模拟每一步的计算,是非常没有效率的事情。如果是叫用只是传递参数,取得价格计算的结果,则性能还算不错。

另外,QuantLib C++之所以无法支持多线程的运算,则是与其架构中使用的Observer、Observable的设计样式有关。20年前的计算机性能不佳,未避免系统过度进行无谓的计算,QuantLib项目人员使用了前述样式,搭配Lazy Object的模式来开发系统。这造成QuantLib只能在一个进程中,使用单一的线程的运算。20年前的决定,是当年时空环境下的正确决定,但20年后情况已大为改变,现在来看却已成桎梏难解。

一方面由于IC制程的大跃进,多核芯片已为主流,计算性能已不是20年前可以比拟,另外。异质性计算架构,如GPU、FPGA都已成熟,更是将计算能力提升数个量级。金融市场的风险不断提升,实时的风险评估已不容或缺。监理机关对于风险评估的要求也大幅提升,以最近要上线的Basel III而言,同样的市场风险标准法,新法的运算能力要求可能接近旧法的100倍。

另一个更复杂的问题也要面对,那就是大型银行的系统采购,往往需要IT公司提供源代码。QuantLib的C++程序代码虽然是公开的,但毕竟不是IT公司使用的Java程序代码。这可能会间接造成银行IT人员的困扰。而且以外挂叫用C++ DLL的方法,总觉得与系统的融合度就是差了一点。

有鉴于此,朋友公司的技术长请我研究,能否以Pure Java Code来改写QuantLib链接库,这样便能与公司的程序代码100%兼容。一方面计算效能可以大幅提升;另一方面,甚至可以使用多线程与GPU来进行关键计算的加速。于是,我便找到一个人生的重大意义-以Java语言来改写QuantLib C++链接库。

其实,以Java改写QuantLib C++这样的想法,在14年前(2008)便有人开始进行了。在那个年代,还有另一个团队,以C#改写QuantLib。但最终这两个计划都嘎然而止,留下一些凭吊的网站。图一是Java项目的网址,我由其上的连结,下载了一份程序代码,将之安装在Eclipse的IDE下(图二),在补足一些Jars后,便没有明显的语法错误。然而,当我真的去执行项目中的测试案例,便发现执行有误。我试着去解决,但不得其法。我还联络当年的项目经理,但得到的答复是,他已不再维护这个项目,令人好不遗憾。

 

但我想想,反正现在时间空档不少。另外当年(2008)我曾经下载QLNet(图三),C#版改写QuantLib的专案。此项目当年是以QuantLib C++ 1.0为对象,改写了5成多的程序代码。后来我花了10多年的时间,以QLNet为基础,慢慢研究QuantLib C++,逐步将其它的C++程序代码改写成C#,最后我完成了95%左右的改写。后来我在银行开发的资产负债管理(ALM)系统与结构商品评价系统,便是以这个C#版的QuantLib为核心。

 于是,我便开始我的征途,自己重头开始翻写QuantLib C++为Java语言。其实,有这些前人的成果可以参考,事情也没有想象中的困难,当然这也不是一个简单的事情。在一段努力之后,我成功的翻写了部分的代码,原来我使用QuantLib-SWIG C++ DLL链接库开发的SnowBall结构商品定价程序,现在可以搬到我自己Pure Java的DQLJava链接库上了,果然性能大幅提升。

我还是使用之前SnowBall的范例进行比较测试,(https://blog.csdn.net/AndyDong1209/article/details/123749688?spm=1001.2014.3001.5501),以一年期契约为例,每月敲出110%,每日敲入70%,或有年息15%,一倍杠杆。测试产品计算时点为期初报价时点(t=0,契约刚要开始,尚未进行任何比价)。仿真路径数目为102,400条路径,每日一步,一共365步,S0 = 100.0。

方法一(图四)为QuantLib-SWIG C++ DLL链接库,NPV = 98.68279241864619,Time = 58.1612658(sec)。方法二(图五)为Pure Java的DQLJava链接库,NPV = 98.78961980278707,Time = 2.3270442(sec)。

 

 结论是,改写为Pure Java的链接库后,

一、路径增加后,两者价格收敛,差距不大(diff=0.1, 0.1%)。

二、方式二性能明显提升,效益显著(25X)。

三、方式二可使用多线程运算,且可并用GPU(OpneCL)。

看来我已经帮我的后半辈子,找到一件极具挑战性而且做不完的工作了。希望这个成果,可以协助非欧美资本主义市场的金融IT产业,建立起自己的计算能力。毕竟全世界被以英美为首的基督教文明世界,控制金融产业太久了。


网站公告

今日签到

点亮在社区的每一天
去签到