专栏名称: 浙商银行FICC
“浙商银行FICC”由浙商银行金融市场部主办,展现本行对固定收益、信用、外汇、贵金属与商品等市场的研究与解读,以期更好地参与市场、服务客户。
目录
相关文章推荐
TGB湖南人  ·  【3.6复盘】放量跳空大涨!BUFF叠这么多 ... ·  10 小时前  
创伙伴  ·  2025,中国科创新元年! ·  昨天  
独角兽智库  ·  人形机器人产业梳理之二:爆发元年,空间无限 ·  2 天前  
红杉汇  ·  红杉学者项目升级 | 第七届招募即刻启动 ·  2 天前  
51好读  ›  专栏  ›  浙商银行FICC

浅谈Python外汇期权定价提速方案

浙商银行FICC  · 公众号  ·  · 2024-06-20 02:30

正文


作者 | 姚申宗、陈卓


一、Python语言的优势与劣势


Python是一种解释型、高级编程语言,以其简洁、易学和开发高效而闻名。Python在金融市场中有着广泛的应用,其强大的数据处理能力、丰富的库支持以及易于上手的特性,使其成为金融行业的重要工具,在数据分析与处理、金融建模、算法交易、机器学习和人工智能等场景中备受欢迎。


然而,与其他一些编程语言相比,Python的运行速度广受诟病。尤其是在期权定价、蒙特卡洛模拟等计算密集型任务中略显乏力。


主要原因有以下几点:


解释型语言: Python是一种解释型语言,这意味着代码在运行时逐行解释执行,而不是像编译型语言那样在运行前将代码转换为机器码。解释过程本身就引入了额外的开销。


高层次抽象: Python提供了许多高层次的抽象和内置函数,这些功能使得代码编写更加方便,但有时也会导致性能下降,因为这些抽象层在底层需要更多的操作。


动态类型: Python是一种动态类型语言,变量的类型在运行时确定。这使得编译器难以进行某些优化,因为类型信息在编译时是未知的。


内存管理: Python使用自动内存管理(垃圾回收),这也会引入一些性能开销。虽然这简化了编程,但垃圾回收的运行时间和频率会影响程序的性能。


全局解释器锁(GIL): Python的 GIL 是一个全局互斥锁,它确保任何时候只有一个线程在执行 Python 字节码。这限制了多线程程序的并行性,使得多线程的 Python 程序在多核处理器上的性能提升有限。

二、外汇期权定价

Python计算基准程序


外汇期权的定价常用的模型之一是Black-76模型。Black-76模型用于定价期权的公式如下:



首先,采用Python编写Black76期权定价公式,并测算10万次计算所消耗的时间:



执行结果输出:

基准方法计算时间: 0.11799860000610352 秒

计算结果 0.08288601745700033


对于需要高计算效率的场景,这个计算时间可能还不是足够的快。


特别是在以下两个场景中:


高频交易: 高频交易需要在极短的时间内完成大量计算,并且快速响应市场变化。在这种情况下,计算时间的每一毫秒都非常关键。即使是0.1秒的延迟,也可能导致交易机会的丧失或产生不利的交易结果。


大规模的计算: 当需要处理非常大的数据量时,计算时间的累积效应会显著增加。对于需要处理上百万甚至上亿次计算的情况,单次计算的时间虽然看上去很短,但总的计算时间将非常庞大。这在实际应用中是难以接受的。


上述Python的程序可作为基准,后文将基于此程序,采用多种方式进行优化提速。


三、优化计算方法


1、使用Numba优化


Numba主要针对Python解释型及动态类型的特点进行优化,它是一个JIT(Just-In-Time)编译器,能够在运行时将Python代码编译为机器码,并且进行类型特化使生成的机器码更加高效。这意味着第一次运行函数时会有编译开销,但之后的调用会非常快。


使用Numba优化后的代码:



执行结果输出:

Numba方法计算时间: 0.02299809455871582 秒

计算结果 0.08288601745700033


从执行结果来看,Numba优化后的效率是基准的Python程序的5倍,并且对基准的Python程序的改动非常小,上述例子仅增加了两个njit装饰器。


但是Numba也有一些局限性和缺点。


兼容性问题: Numba 并不支持所有的 Python 功能和库。它主要专注于数值计算和科学计算,对于一些高级的 Python 特性(如异常处理、生成器等)和某些第三方库(如 Pandas)的支持有限。


编译开销: 虽然 Numba 的 JIT 编译在多次调用同一个函数时可以提高性能,但在第一次调用时会有一定的编译开销。对于一些只执行一次的函数,这种开销可能会抵消掉性能提升。


2、使用Cython优化


除了Numba外,Cython也具有相同的功能。Cython是一种编程语言,它可以编写与Python语言兼容的代码,并且可以在需要的时候使用C语言的功能(C语言和Python的结合顾取名Cython)。它采用AOT(Ahead-Of-Time)编译方式,通过使用Cython,可以将关键的计算部分编译成C代码,从而大大提升执行效率。但优化的复杂度会较Numba更高一些,下面是使用Cython优化的代码和步骤:


首先,创建一个名为black76.pyx的Cython文件,其中包含要优化的Black76模型函数:



创建一个名为setup.py的文件,用于编译black76.pyx的Cython代码:



在命令行中运行以下命令来编译Cython代码,将black76.pyx的Cython代码编译成Python可以调用的black76模块:



创建一个Python程序来调用编译后的Cython代码:



执行结果输出:

Cython方法计算时间: 0.014998435974121094 秒

计算结果 0.08288601745700033


从执行结果来看,Cython方法又进一步的缩短了计算用时,计算效率约为基准的Python程序的8倍,Numba方案的1.5倍。


通过使用Cython,将Python中的计算密集型部分编译成了高效的C代码。这种优化提升了语言的执行效率,减少了由于动态类型和解释执行带来的开销。


具体改进包括:


静态类型声明: 在Cython中,可以使用C语言的类型声明,减少了运行时类型检查的开销;


直接调用C函数: Cython允许直接调用C函数(如log、exp等),这些函数的执行效率比Python的对应函数更高。


编译优化: 通过编译选项/Ox,可以进一步提升代码的执行效率。


Cython与Python代码的兼容度非常高,能支持大型项目的开发,如NumPy、SciPy、uvloop等知名第三方库均有用到Cython优化性能。


相比Numba的方案,Cython需要花更多的力气修改程序,而且需要用一套新的语法编写代码,虽然Cython的语法兼容Python,但显然需要额外的学习成本。


3、向量化计算


使用向量化的思路对基准的Python程序进行优化。优化思出发点是批量计算:尽可能不使用循环逐个计算,而采用批量计算,降低额外的开销。


调整后的代码:



执行结果输出:

向量化计算时间: 0.011967182159423828 秒

计算结果 0.08288601745700033


通过Numpy实现的向量化计算,计算效率比基准的Python程序快了约10倍,比Cython优化的方法提升约20%。


主要原因分析:


Numpy的向量化计算一次性处理整个数组,而不是逐个元素进行计算。这种方式利用了底层的高效实现,使得计算速度大大提高。







请到「今天看啥」查看全文