如何成为 Quant Dev 3 - 语言
之前的连篇文章主要介绍了 Quant Dev (QD) 的分类和学习路径,这一篇我们重点介绍行业内常用的软件、语言和框架。
注意 本系列主要针对买方 Quant Dev,而不是卖方或者 Quant 这个职业。通常来说,Quant 和 Quant Dev 的技能和技术栈有一些重叠,但是差异仍然较大。
之前的文章提过,Quant Dev 首先必须是一个好的程序员,通常是一个好的后端程序员,因此,QD 的基础技术栈跟一般的后端程序员非常类似,而由于业务的关系 QD 对某些语言、框架和知识的需求更多一些。
首先我们来说买方 QD 常用的计算机语言,不出预料就是下面四位:
- Python
- Java
- C#
- C++
近些年,我也观察到一些其他语言正在慢慢进入 QD 的世界,其中比较有潜力的就是Rust
,因为 Rust 是近些年底层语言领域唯一有希望跟 C++ 在性能和流行度一争高下的语言。当然,也有一些公司会用一些比较小众的语言,比如 JaneStreet 大量使用了Ocaml
,一些做量化交易软件的公司会配合使用F#
。
虽然在对冲基金内部,使用的语言通常跑不出这些主流语言,但是他们的应用场景却非常不同。
Python
TL;DR
优势:
- 数据科学生态好
- 研究和生产部署统一技术栈
- 快速迭代、部署、Debug
劣势:
- 执行效率低、内存占用高
- 动态类型、运行时异常
- GC、无法提供稳定延迟
解决方案:
- 执行效率和内存:numba | cython | pypy
- 运行时异常:mypy + 类型标注
- 相对稳定 GC 延迟:pypy
适用领域:
- 数据预处理、清洗
- 策略以及投资组合研究、分析
- 中低频策略执行
- 盘后分析
不适领域:
- 订单执行、管理系统
- 高频策略执行
优势
Python
现在是数据相关行业的首选,包括对冲基金,主要是得益于他强壮的数据科学生态:数据抓取、清洗、分析、机器学习等等方面都有丰富的支持。
Python
还有一个独特的优势,就是对于研究人员,比如 Quant 非常友好,同时它又有相对健全的通用编程生态,比如异步、并发、数据库接口、丰富的云生态等等,这些都使得Python
在很多对冲基金同时成为了研究语言和生产语言,也就是说同一个语言兼顾了研究和生产环境。这种协调统一显然加速了策略从研究到投产的过程,使得交易策略可以快速迭代。这一点新兴的“科学计算”语言Julia
就相差较远了。
Python
的另一优势在于动态语言方便的 Debug 能力和自省能力,代码编写变得非常轻松,通常比起语言需要更少的代码量来实现业务功能。而且,量化对冲基金的业务模式对 Bug 非常敏感,一旦出现软件问题,能否快速的定位和修复异常重要。当然,这些不是一个语言单独可以解决的问题,但动态语言的特性绝对有助于加速定位和修复。
劣势
Python
的短板也非常明显。主要由两个问题:性能和动态类型。这两个短板也是相互联系的,通常动态语言的性能都会相对较差。
首先,性能。性能主要体现在两个方面:内存和运行速度。Python 的内存占用对比其他语言,比如 C++,要大不少,这种劣势会随着数据量和计算量的增加逐渐凸显。特别是当使用类似 Pandas、Numpy 库时,一些数据计算单次需要用到的内存可能会达到 80 到 100GB。而且通常是峰值内存较大,比如计算过程中需要拷贝数据,这种峰值内存导致容器化的内存上线必须提高,造成浪费。而且如果类似的计算太多,就会对计算集群提出更高的需求。运行速度则是另外一个短板,尽管我们有一些方案,比如 PyPy
,numba
,Cython
,但是这些方案无疑提高了开发复杂度,同时语言本身的Overhead仍然存在。
其次,动态类型。动态类型再生产过程中最主要的问题是,运行时错误。因为没有静态类型,也没有编译器,编译器无法提前告诉我们代码中潜在的类型问题。这一点在项目体积变大,文件数量庞大的时候,变得尤其突出,经常是改了一个地方,隐藏的破坏了另一个地方,而没有编译器提前告诉程序员。这些错误,通常只能在运行时暴露出来,所以 Python 开发对于测试的编写非常依赖。但是。。测试终究不能覆盖所有情况。当然,社区也有对应的解决方法,比如类型分析包:mypy
,通过在代码中增加类型标注,配合 mypy
进行静态类型检查。
GIL,全局解释器所,也是 CPython 一直被诟病的点,社区提出了不少应对方案,如 PyPy
、多进程、异步,当终究隔靴搔痒。
最后一点是所有带垃圾回收的语言都会存在的问题,延迟不稳定。因为 Python 也带有一个 STW,Stop The World,GC,因此系统随时可能迎来GC,特别是当堆内存巨大的时候,这种延迟可能达到数百毫秒。因此,在对实时性要求较高的应用中 CPython 并不合适。
C++ / Rust
TL;DR
优势:
- 执行效率高
- 内存占用低
- 延迟可控
- 类型系统和编译器( Rust 尤其突出 )
劣势:
- 数据科学工具链相对薄弱、难用
- 上手难度大、语言特性繁多
- 内存安全问题 ( Rust 基本没有这个问题 )
- 编写复杂业务逻辑成本较高
适用领域
- 回测框架的核心代码
- 高频交易系统
- 低延迟订单管理、执行系统
不适领域:
- 策略研究、原型测试
Java / C# / Go
TL;DR
这一卦的语言呢,介于 Python 和 Rust、C++ 之间,基本属于万金油。特别 Java 系在大数据领域仍然出于老大哥位置,绝大部分的中间件都是 JVM 实现的,比如 Kafka、Spark、Flink 等等。在各大投行、对冲基金中,这一卦 GC 语言仍然占据半壁江山。
如果说 Python 的优势在于快速迭代测试、适合中低频策略;C++、Rust 适合高频、低延迟领域;这一卦 GC 语言就比较适合订单管理、执行系统。