Python-金融理论指南-全-

Python 金融理论指南(全)

原文:annas-archive.org/md5/367d6a9f43f01d09b8031d6096c8f769

译者:飞龙

协议:CC BY-NC-SA 4.0

序言

Python 迅速成为数据科学、机器学习和自然语言处理的事实标准语言;它将释放创新的新源泉。Python 允许我们参与其庞大的开源社区,快速引入最先进的技术,并支持定制化。¹

Kindman 和 Taylor (2021)

为什么选择这本书?

在线交易平台、开源软件和开放金融数据等技术趋势显著降低或完全消除了进入全球金融市场的门槛。只有少量闲置资金的个人可以在几小时内开始例如算法交易。金融学科的学生和学者只需具备少量编程背景知识,就可以轻松将机器学习和深度学习的尖端创新应用于金融数据——在他们带到金融课堂的笔记本上。在硬件方面,云服务提供商从每月 5 美元起提供专业计算和数据处理能力,按小时计费,并具有几乎无限的可伸缩性。迄今为止,学术和专业金融教育只在某种程度上对这些趋势做出了反应。

本书从零开始教授金融和Python编程语言。如今,金融和编程已经密切交织,Python 是金融行业中最广泛使用的编程语言之一。本书以集成但不过于技术化的方式呈现相关的基础知识——包括数学、金融和编程。传统上,理论金融和计算金融一直是或多或少分离的学科。然而,现在,编程课程(例如 Python,也包括 C++)已成为金融工程硕士及类似课程的必要组成部分,显示出编程技能在该领域的重要性。

然而,数学基础理论金融基本编程技术仍然经常独立教授,并且只有在稍后与计算金融结合时才会进行教学。本书采用了不同的方法,即数学概念——例如线性代数和概率论——提供了共同的背景,用于引入金融思想和编程技术。抽象的数学概念从金融和编程两个角度进行了动机推动。此外,这种方法允许新的学习体验,因为数学和金融概念可以直接转化为可执行代码,然后进行交互式探索。

我的另一本书《Python 金融学》(第二版,2018 年,O'Reilly)的几位读者指出,该书并不从零开始教授金融或 Python。事实上,该书的读者预期至少具有一些金融和 Python(编程)经验。《Python 金融理论》填补了这一空白,因为它侧重于来自金融和 Python 编程的更基本的概念。从这个意义上说,完成本书的读者可以自然地进入《Python 金融学》进一步建立和提高他们将 Python 应用于金融的技能。最后一章提供了更多指导。

目标读者群体

我写了几本关于 Python 应用于金融的书籍。我的公司,Python 量化分析(The Python Quants),提供多种线上和线下的 Python 金融培训课程。对于我之前的所有书籍和培训课程,我们期望书籍读者和培训参与者已经具备一定的金融和 Python 编程或类似语言的背景知识。

本书从零开始,只需读者具备一些基本的数学知识,特别是微积分、线性代数和概率论。尽管本书的材料几乎是关于引入的数学概念的自包含的,但建议需要更多细节的话参考 Pemberton 和 Rau(2016 年)的介绍性数学书籍^(2)。

鉴于这种方法,本书的目标读者包括学生、学者和希望学习金融理论、金融数据建模和 Python 在计算金融中应用的专业人士。这是一个系统的介绍,可以通过更高级的书籍或培训课程进一步扩展。具有正式金融背景的读者会发现本书的数学和金融元素相当简单和直接。另一方面,具有较强编程背景的读者会发现 Python 元素相当简单和易于理解。

即使读者不打算进入更高级的计算金融、算法交易或资产管理主题,通过这本书学到的 Python 和金融技能也可以有益地应用于金融中的标准问题,例如根据现代投资组合理论(MPT)构建投资组合的方法。例如,本书还教授了如何通过复制投资组合或风险中性定价等标准方法估值期权和其他衍生品。

本书也适合于希望了解 Python 编程语言在金融领域应用的金融行业高管。另一方面,已经精通 Python 或其他编程语言的人士也可以阅读本书,了解 Python 在金融中的应用。

书籍概览

本书由以下章节组成:

第一章

第一章为本书的其余部分奠定了基础。它提供了金融的简明历史,解释了本书使用 Python 进行金融的方法,并展示了如何建立一个适合与提供的代码和本书附带的 Jupyter 笔记本一起工作的基本 Python 基础设施。

第二章

本章涵盖了最简单的模型经济,其中可以对不确定性下的金融进行分析:只有两个相关日期和两种可能的不确定未来状态。有时候人们谈论一个静态的两状态经济。尽管它很简单,但该框架允许引入金融的基本概念,如净现值,预期回报,波动性,条件性要求,期权复制,套利定价,鞅测度,市场完备性,风险中性定价和均值-方差投资组合。

第三章

本章向模型引入了第三个不确定的未来状态,分析了静态三状态经济。这使我们能够分析市场不完全性,鞅测度的不确定性,条件性要求的超复制和近似复制。它还介绍了作为金融资产均衡定价方法的资本资产定价模型。

第四章

本章介绍了具有各自决策问题的代理商。本章的分析主要依赖于金融中在不确定性下做出决策的主导范式:期望效用最大化。基于所谓的代表性代理,引入了均衡概念,并且说明了最优性和均衡与鞅测度和风险中性定价之间的联系。代表性代理也是克服在市场不完全的经济中出现的困难的一种方式。

第五章

本章将前面的概念和结果推广到一个具有有限但可能很大数量的不确定未来状态的环境中。这需要更多的数学形式化来分析这个一般静态经济

第六章

基于对一般静态经济的分析,本章向金融建模工具箱引入了动态,以分析离散时间动态经济的两种特殊情况。基本见解是,对于一般经济的未来状态的不确定性随时间逐渐解决。这可以通过使用随机过程来建模,其中一个例子是可以通过二项树来直观表示的二项过程。

第七章

最后一章提供了丰富的额外资源,供读者探索数学、金融理论和 Python 编程领域。它还提供了在读者完成本书后如何继续的指导。

本书中使用的约定

本书使用以下排版约定:

斜体

表示新术语、网址、电子邮件地址、文件名和文件扩展名。

常量宽度

用于程序列表以及段落内部,用于指代变量或函数名、数据库、数据类型、环境变量、语句和关键字等程序元素。

常量宽度粗体

显示用户应该逐字输入的命令或其他文本。

常量宽度斜体

显示应该用用户提供的值或上下文确定的值替换的文本。

注意

此元素表示一般注释。

警告

此元素表示警告或注意。

重要

此元素指示重要信息。

使用代码示例

附加材料(代码示例、练习等)可在https://finpy.pqp.io下载。

如果您有技术问题或在使用代码示例时遇到问题,请发送电子邮件至bookquestions@oreilly.com

本书旨在帮助您完成工作。一般来说,如果本书提供示例代码,则您可以在自己的程序和文档中使用它。除非您复制了代码的大部分内容,否则无需征得我们的许可。例如,编写一个使用本书中多个代码片段的程序不需要许可。销售或分发 O’Reilly 图书的示例代码需要许可。引用本书并引用示例代码来回答问题不需要许可。将本书中大量示例代码纳入产品文档中需要许可。

我们感激,但通常不要求署名。署名通常包括标题、作者、出版商和 ISBN。例如,这本书将被署名为“使用 Python 的金融理论,作者 Yves Hilpisch(O’Reilly)。版权所有 2022 Yves Hilpisch,978-1-098-10435-1。”

如果您认为您使用的代码示例超出了公平使用范围或上述许可,请随时与我们联系,邮箱为permissions@oreilly.com

O’Reilly 在线学习

注意

40 多年来,O’Reilly Media提供技术和商业培训、知识和见解,帮助公司取得成功。

我们独特的专家和创新者网络通过书籍、文章和我们的在线学习平台分享他们的知识和专业知识。O’Reilly 的在线学习平台为您提供按需访问实时培训课程、深入学习路径、交互式编码环境以及来自 O’Reilly 和其他 200 多个出版商的广泛文本和视频资源。欲了解更多信息,请访问http://oreilly.com

如何联系我们

请向出版商发送关于这本书的评论和问题:

  • O’Reilly 媒体公司

  • Gravenstein 高速公路北 1005 号

  • 加利福尼亚州塞巴斯托波尔 95472

  • 800-998-9938(美国或加拿大地区)

  • 707-829-0515(国际或本地)

  • 707-829-0104(传真)

我们为这本书设立了一个网页,列出勘误、示例和任何其他信息。您可以访问https://oreil.ly/fin-theory-with-python

发送邮件至bookquestions@oreilly.com,评论或者询问关于这本书的技术问题。

获取我们的图书和课程的新闻和信息,请访问http://oreilly.com

在 Facebook 上找到我们:http://facebook.com/oreilly

在 Twitter 上关注我们:http://twitter.com/oreillymedia

在 YouTube 上观看我们:http://www.youtube.com/oreillymedia

致谢

这本书受益于我们的 Python 金融证书项目的代表宝贵反馈。他们随着时间的推移指出了许多改进之处。

我非常感谢我从技术审阅者那里收到的几条有用的评论。

我也非常感谢整个 O’Reilly 团队的帮助和支持。

我把这本书献给我的妻子桑德拉。你是我生命中的爱。

Kindman, Andrew and Tom Taylor, “Why We Rewrote Our USD30 Billion Asset Management Platform in Python.”(2021 年 3 月 29 日),https://oreil.ly/GghS6

找到这个标题的完整引用,请参阅第七章。

第一章:金融与 Python

金融理论的历史是抽象理论化与实际应用相互作用的有趣例子。

Frank Milne (1995)

近年来,对冲基金吸引了数十亿美元的投资,越来越多地依靠技术。同样的技术也使得在这些机构做出财务决策的人们受益。

Laurence Fletcher (2020)

本章简要概述了本书相关主题。它旨在为接下来的章节提供财务和技术框架。"金融简史"首先简要介绍了金融的历史和现状。"金融主要趋势"讨论了推动金融演变的主要趋势:数学、技术、数据和人工智能。在此背景下,"四种语言的世界"认为当今的金融是四种紧密相互关联的语言学科:英语、金融、数学和编程。本书的整体方法在"本书的方法"中有详细说明。"Python 入门"展示了如何在读者的计算机上安装适当的 Python 环境。但所有代码也可以通过Quant 平台的常规 Web 浏览器使用和执行,以便稍后设置本地 Python 安装。

金融简史

要更好地理解金融及其行业的当前状态,有必要看一看它们如何随时间发展。金融作为一个科学领域的历史可以根据 Rubinstein(2006 年)的说法大致分为三个时期:

古代时期(1950 年前)

主要以非正式推理、经验法则和市场从业者的经验为特征的时期。

古典时期(1950 年至 1980 年)

主要特点是引入形式推理和数学到该领域。在此期间开发了专业模型(例如,Black 和 Scholes 的(1973 年)期权定价模型)以及通用框架(例如,Harrison 和 Kreps 的(1979 年)风险中性定价方法)。

现代时期(1980 年至 2000 年)

这一时期在金融的具体子领域中取得了许多进展(例如,计算金融),并处理了金融市场中的重要经验现象,如随机利率(例如,Cox,Ingersoll 和 Ross(1985 年))或随机波动率(例如,Heston(1993 年))。

在 Rubinstein(2006 年)书籍出版十五年后,我们今天可以添加第四和第五个时期。这两个时期促成了 Python 在金融中的崛起和当前无处不在:

计算时期(2000 年至 2020 年)

在这一时期,金融领域由理论重心向计算重心转变,这一变化受到了金融硬件和软件的进步推动。Longstaff 和 Schwartz(2001 年)提供了一种高效的数值算法,通过蒙特卡罗模拟对美式期权进行估值,很好地展示了这一范式转变。他们的算法在一般情况下对于估值一个单一期权需要进行数十万次模拟和多次普通最小二乘回归。

人工智能时代(2020 年后)

人工智能(AI)的进步和相关成功案例促使人们在金融领域利用 AI 的能力产生了浓厚兴趣。虽然 AI 在金融中已经有成功的应用(参见 Hilpisch(2020)),但可以预期从 2020 年开始,会逐步向AI 优先金融的系统范式转变。AI 优先金融描述了从金融中简单的、通常是线性的模型向使用 AI 中的先进模型和算法——如深度神经网络或强化学习——捕捉、描述和解释金融现象的转变。

金融的主要趋势

像许多其他学科和行业一样,金融随着时间的推移变得更加形式化的科学学科,驱动因素包括日益使用的正式数学、先进技术、增加的数据可用性和改进的算法,如来自 AI 的算法。因此,随着时间的推移,金融的演变可以被四个主要趋势所描述:

数学

从 1950 年代开始的古典时期起,金融变得越来越形式化,系统地利用数学的不同领域,如线性代数或随机微积分。马科维茨(1952 年)的均值方差组合理论可以被认为是量化金融的一大突破,如果不是其起始点本身——这使得古代时期主要以非正式推理为特征。

技术

个人计算机、工作站和服务器的普及与使用,主要始于 20 世纪 80 年代末和 90 年代初,将更多技术引入了金融领域。尽管计算能力和容量起初相对有限,但如今已经达到了足以攻克金融中甚至最复杂问题的水平,往往通过纯粹的暴力计算,常常使得寻找特定的高效模型和方法——这些特征了古典和现代时期的模式——变得过时。如今的硬件主张变成了“扩展您的硬件,并结合现代软件和适当的数值方法使用”。另一方面,大多数宿舍和起居室中现代硬件已经足够强大,以至于甚至高性能的方法,如并行处理,通常可以在这类大众硬件上使用——极大地降低了计算和 AI 优先金融的准入门槛。

数据

虽然研究人员和从业者们主要依赖于古代和古典时期印刷的金融信息和数据(想想华尔街日报金融时报),但从现代时期开始,电子金融数据集的可用性变得更加广泛。然而,计算时期见证了金融数据可用性的爆炸性增长。高频日内数据集已成为经验研究的主要基础,已取代了每日结束价格。单只股票每个交易日可能会生成超过 100,000 个数据点的日内数据集——这个数量大致相当于同一只股票 400 年的每日结束价格(每年 250 个交易日乘以 400 年)。最近更进一步,观察到了开放或免费数据集的激增,这也显著降低了进入计算金融、算法交易或金融计量经济学的门槛。

人工智能

越来越多的金融数据的可用性(“大数据金融数据”)使得应用 AI 算法(例如机器学习、深度学习或强化学习,详见 Hilpisch (2020))不仅仅是可能的,而且在许多情况下现在是必需的。传统的金融计量经济学中的传统统计方法通常不再适用于应对当今金融市场的复杂性。面对非线性、多维、不断变化的金融环境,基于 AI 的算法往往可能是发现相关关系和模式、生成有价值洞察并从改进的预测能力中获益的唯一选择。

通过阅读本书,读者在金融数学和用于实施正式金融模型的现代技术领域奠定了基础。读者还获得了处理金融领域常见的金融数据集的技能。总之,这为读者更轻松地探索应用于金融的高级主题,如计算金融或 AI,做好了准备。

Python 和金融

越来越多的金融领域由计算需求量大的算法、日益增加的数据可用性和 AI 驱动。Python 已被证明是应对该领域观察到的主要趋势所带来的要求和挑战的正确编程语言和技术平台。

一个四语言世界

在此背景下,金融已经成为一个四语言世界:

自然语言

今天,英语语言是该领域在发布的研究、书籍、文章或新闻方面唯一相关的语言。

金融语言

像其他领域一样,金融有描述某些现象或想法的技术术语、概念和表达,这些在其他领域通常不相关。

数学语言

数学是在形式化金融的概念和观念方面的首选工具和语言。

编程语言

正如前言开头的引语所指出的那样,Python 作为一种编程语言已经成为金融行业许多领域的首选语言。

因此,精通金融需要学术界和从业者流利掌握四种语言:英语、财务、数学和 Python。这并意味着,例如,英语和 Python 是唯一相关的自然语言或编程语言。相反,如果你只有有限的时间学习一门编程语言,你应该优先选择 Python——在学习数学金融的过程中。

本书的方法论

本书如何处理金融所需的四种语言?英语是显而易见的——你已经在阅读它了。然而,还有三种语言需要学习。

例如,本书无法详细介绍金融所需的每一个数学细节,也无法详细介绍计算金融所需的每一个(Python)编程概念。然而,它在可能和合理的情况下尽量同时介绍金融、数学和编程相关的概念。

从第二章开始,本书介绍了一个金融概念,并且分别以数学表示和 Python 实现为基础进行阐述。例如,请看下面来自第三章的表格。该表格列出了金融主题、主要的数学元素以及用于实现金融数学的主要 Python 数据结构:

财务 数学 Python
不确定性 概率空间 ndarray
金融资产 向量、矩阵 ndarray
可实现的偶发索赔 向量空间的跨度、向量空间的基 ndarray

以下是一个具体示例的步骤,其详细信息在后续章节中提供。此时的示例仅用于说明本书的一般方法论。

举例来说,从前述表格中的金融领域中获取 不确定性 的中心概念。不确定性体现了模型经济的未来状态事先不可知的概念。经济的未来状态的不同可能是重要的,例如用于确定欧式看涨期权的支付。在离散情况下,人们处理这种状态的有限数量,如两个、三个或更多。在仅有两个未来状态的最简单情况下,欧式看涨期权的支付在数学上表示为一个 随机变量,进而可以形式化地表示为一个自身是 向量 v向量空间 2 的元素。向量空间是对象集合,称为向量,对其定义了加法和标量乘法。形式上,对于这样一个向量 v ,例如可以写成:

v = v u v d ≥0 2

在此,假设向量的两个元素都是非负实数 v u ,v d ≥0 。更具体地说,如果在此背景下给定的欧式看涨期权所写的股票的不确定、状态相关价格是:

S = 20 5 ≥0 2

若期权的行使价格为 K = 15,则欧式看涨期权的支付 C

C = max ( S - K , 0 ) = max ( 20 - 15 , 0 ) max ( 5 - 15 , 0 ) = 5 0 ≥0 2

这说明了如何数学上建模 股票的不确定价格欧式期权的状态相关支付 作为一个向量。处理数学中向量和向量空间的学科称为 线性代数

如何将这一切翻译成 Python 编程?首先,实数 在 Python 中表示为 浮点数float 对象:

In [1]: vu = 1.5  

In [2]: vd = 3.75  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [3]: type(vu)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[3]: float

In [4]: vu + vd  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[4]: 5.25

1

定义一个名为 vu 的变量,并赋值为 1.5。

2

定义一个名为 vd 的变量,并赋值为 3.75。

3

查找 vu 对象的类型——它是一个 float 对象。

4

计算 vuvd 的值的总和。

其次,在编程中,通常称同一类型对象的集合为 数组。在 Python 中,NumPy 包提供了对这种数据结构的支持。该包提供的主要数据结构称为 ndarray,这是 n 维数组的缩写。用 NumPy 可以轻松地建模实数向量:

In [5]: import numpy as np  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [6]: v = np.array((vu, vd))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [7]: v  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[7]: array([1.5 , 3.75])

In [8]: v.dtype  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[8]: dtype('float64')

In [9]: v.shape  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[9]: (2,)

In [10]: v + v  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[10]: array([3. , 7.5])

In [11]: 3 * v  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[11]: array([ 4.5 , 11.25])

1

导入 NumPy 包。

2

实例化一个 ndarray 对象。

3

打印对象中存储的数据。

4

查找所有元素的数据类型。

5

查找对象的形状。

6

向量加法的示例。

7

标量乘法的示例。

这展示了围绕向量的数学概念如何在 Python 中表示和应用。然后,将这些见解应用于金融只是进一步的一步:

In [12]: S = np.array((20, 5))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [13]: K = 15  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [14]: C = np.maximum(S - K, 0)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [15]: C  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[15]: array([5, 0])

1

将股票的不确定价格定义为 ndarray 对象。

2

将行权价格定义为具有整数值的 Python 变量(int 对象)。

3

计算每个表达式元素的最大值。

4

显示现在存储在 ndarray 对象 C 中的结果数据。

这说明了本书的风格和方法:

  1. 介绍了金融中的概念和概念。

  2. 提供数学表示和模型。

  3. 将数学模型转化为可执行的 Python 代码。

在这个意义上,金融激发了数学的使用,而数学的使用又激发了 Python 编程技术的使用。

Python 入门指南

Python 的一个好处是它是一种开源语言,绝大多数重要的包也是如此。这使得语言和所需的包在 macOS、Windows 和 Linux 等所有主要操作系统上的安装变得非常容易。除了基本的 Python 解释器外,这本书和金融一般需要的代码只需要几个重要的包:

NumPy

这个包允许高效处理大型、n 维数的数值数据集。

pandas

这个包主要用于高效处理表格数据集,如金融时间序列数据。尽管本书的目的不需要,但 pandas 已经成为金融领域最流行的 Python 包之一。

SciPy

这个包是科学函数的集合,例如解决典型的优化问题所需的函数。

SymPy

这个包允许使用 Python 进行符号数学运算,在处理金融模型和算法时有时会派上用场。

matplotlib

这个包是 Python 中用于可视化的标准包。它允许您生成和自定义不同类型的图表,如线图、条形图和直方图。

同样,只有两个工具是开始交互式 Python 编码所需的:

IPython

这是在命令行(终端、Shell)上进行交互式 Python 编码的最受欢迎环境。

JupyterLab

这是在浏览器中进行交互式 Python 编码和开发的互动开发环境。

学习 Python 编程的技术先决条件很少。这本书中使用 Python 代码的基本选择有两种:

Quant Platform

Quant Platform上(您可以免费注册),您会找到一个完整的互动金融分析环境,可以通过浏览器使用本书中提供的 Python 代码,无需本地安装。免费注册后,您可以自动访问所有代码和附带书籍的 Jupyter 笔记本,可以立即在浏览器中执行代码。

本地 Python 环境

如今安装本地 Python 环境并在自己的计算机上进行金融分析和书籍代码的最有效方式也是非常直接的。本节介绍如何执行此操作。

本地安装与 Quant Platform 比较

根据经验,对于刚开始接触编程的人来说,本地安装适当的 Python 环境有时可能会比较困难。因此,如果在本地安装 Python 时遇到任何问题,建议您不要在开始阶段花费太多时间。相反,可以利用Quant Platform,稍后在积累了一些经验后,仍然可以返回并在本地机器上安装 Python。

使用conda软件包和环境管理器安装 Python 的简单而现代的方式(参见图 1-1)。

ftwp 0101

图 1-1. conda 网页

安装conda和基本 Python 解释器的最高效方式是通过Miniconda发行版(见 Miniconda 下载页面,提供了最重要的操作系统和 Python 版本的安装包(参见图 1-2)。Miniforge 项目还提供了额外的选项,如适用于 Apple M1 芯片(“Apple Silicon”)的选项(https://oreil.ly/gKeo3)。

ftwp 0102

图 1-2. Miniconda 下载页面

根据操作系统提供的指南安装了 Miniconda 或 Miniforge 之后,应打开 Shell 或命令提示符,并检查conda是否可用。以下示例基于在搭载 M1 芯片的 Apple Mac 计算机上通过 Miniforge 安装的conda。您应该会得到类似于这样的输出:

(base) minione:finpy yves$ conda --version
conda 4.10.3
(base) minione:finpy yves$

还要注意conda基础 Python 安装的提示符中的(base)部分。下一步是按以下方式创建一个新的Python 环境(并在提示时回答“y”):

pro:finpy yves$ conda create --name finpy python=3.9
...
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
#     $ conda activate finpy
#
# To deactivate an active environment, use
#
#     $ conda deactivate

成功完成后,激活环境如下所示:

(base) minione:finpy yves$ conda activate finpy
(finpy) minione:finpy yves$

注意提示符的变化。接下来,按照以下方式安装所需工具 IPython 和 JupyterLab(在提示时回答“y”):

(finpy) minione:finpy yves$ conda install ipython jupyterlab
...

然后,你应该安装通常用于金融数据科学的主要 Python 包,如下所示(使用 -y 标志避免确认提示):

(finpy) minione:finpy yves$ conda install -y numpy pandas matplotlib scipy sympy
...

这提供了一般数据分析和特别是金融分析中最重要的 Python 包。你可以检查是否已经安装完成,如下所示:

(finpy) minione:finpy yves$ conda list
# packages in environment at /Users/yves/Python/envs/finpy:
#
# Name                    Version                   Build    Channel
anyio                     3.3.0            py39h2804cbe_0    conda-forge
appnope                   0.1.2            py39h2804cbe_1    conda-forge
argon2-cffi               20.1.0           py39h5161555_2    conda-forge
...
jupyterlab                3.1.12             pyhd8ed1ab_0    conda-forge
...
numpy                     1.21.2           py39h1f3b974_0    conda-forge
...
python                    3.9.7        h54d631c_1_cpython    conda-forge
...
zipp                      3.5.0              pyhd8ed1ab_0    conda-forge
zlib                      1.2.11            h31e879b_1009    conda-forge
zstd                      1.5.0                h861e0a7_0    conda-forge
(finpy) minione:finpy yves$

通过简单地输入 python,然后启动交互式 Python 会话:

(finpy) minione:finpy yves$ python
Python 3.9.7 | packaged by conda-forge | (default, Sep 14 2021, 01:14:24)
[Clang 11.1.0 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print('Hello Finance World.')
Hello Finance World.
>>> exit()
(finpy) minione:finpy yves$

更好的交互式 shell 由 IPython 提供,通过在 shell 上输入 ipython 启动:

(finpy) minione:finpy yves$ ipython
Python 3.9.7 | packaged by conda-forge | (default, Sep 14 2021, 01:14:24)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.27.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from numpy.random import default_rng

In [2]: rng = default_rng(100)

In [3]: rng.random(10)
Out[3]:
array([0.83498163, 0.59655403, 0.28886324, 0.04295157, 0.9736544 ,
       0.5964717 , 0.79026316, 0.91033938, 0.68815445, 0.18999147])

In [4]: exit
(finpy) minione:finpy yves$

然而,特别是对于 Python 初学者,推荐在浏览器中使用 JupyterLab。为此,请在 shell 中输入 jupyter lab,将输出类似以下的消息:

(finpy) minione:finpy yves$ jupyter lab
...
[I 2021-09-16 14:18:21.774 ServerApp] Jupyter Server 1.11.0 is running at:
[I 2021-09-16 14:18:21.774 ServerApp] http://localhost:8888/lab
[I 2021-09-16 14:18:21.774 ServerApp]  or http://127.0.0.1:8888/lab
[I 2021-09-16 14:18:21.774 ServerApp] Use Control-C to stop this server
	 and shut down all kernels (twice to skip confirmation).

通常会自动打开一个新的浏览器标签页,然后显示类似 图 1-3 的 JupyterLab 启动页面。

接下来,你可以打开一个新的 Jupyter Notebook 并开始交互式 Python 编码,如 图 1-4 所示。要在单元格中编写代码,请单击单元格。要执行代码,请使用 Shift-Return、Ctrl-Return 或 Alt-Return(你会注意到不同)。

ftwp 0103

图 1-3. JupyterLab 启动页面

ftwp 0104

图 1-4. 新的 Jupyter Notebook

你也可以打开本书提供的其中一个 Jupyter Notebook 文件(见 图 1-5)。

ftwp 0105

图 1-5. 本书附带的 Jupyter Notebook

本节只提供了开始使用 Python 和相关工具(如 IPython 和 JupyterLab)的基础知识。关于如何使用 IPython 等更多详细信息,请参考 VanderPlas(2016)在 第七章 中列出的书籍。

结论

金融可以回顾长期历史。从 1950 年到 1980 年,以严格的数学分析引入为特征。从 1980 年代开始,特别是自 2000 年以来,计算机和计算金融的角色显著增加。这一趋势将因人工智能在领域中的增加作用而进一步加强,其机器学习(ML)和深度学习(DL)的计算需求算法。

金融领域使用四种不同类型的语言:自然语言(一般是英语)、金融语言(专有名词和表达方式)、数学语言(如线性代数或概率论)、以及编程语言(例如本书使用的 Python)。

本书的方法是将金融、数学和 Python 编程的相关概念同时介绍。目前,Python 方面的必备先决条件很少,conda包和环境管理器通常是管理 Python 环境的首选工具。

您现在可以继续阅读第二章,该章节讨论了本书中介绍的最简单的金融模型,并引入了许多核心的金融概念。您在最简单的金融模型中获得的直觉应该很容易转移到从第三章开始讨论的更高级模型和方法中。

参考文献

在本章引用的文章和书籍中:

  • Cox, John, Jonathan Ingersoll 和 Stephen Ross. 1985. “利率期限结构理论.” 计量经济学 53 (2): 385–407.

  • Fletcher, Laurence. 2020. “对冲基金利用技术降低成本和浪费.” 《金融时报》, 2020 年 12 月 15 日. https://oreil.ly/HE4Cc.

  • Heston, Steven. 1993. “随机波动率期权的闭式解及其在债券和货币期权中的应用.” 金融研究评论 6 (2): 327–343.

  • Hilpisch, Yves. 2018. Python 金融实战. 第 2 版. Sebastopol: O’Reilly.

  • Hilpisch, Yves. 2020. 金融中的人工智能:基于 Python 的指南. Sebastopol: O’Reilly.

  • Longstaff, Francis 和 Eduardo Schwartz. 2001. “通过模拟估值美式期权:一种简单的最小二乘方法.” 金融研究评论 14 (1): 113–147.

  • Markowitz, Harry. 1952. “投资组合选择.” 《金融杂志》 7 (1): 77-91.

  • Milne, Frank. 1995. 金融理论与资产定价. New York: Oxford University Press.

  • Rubinstein, Mark. 2006. 投资理论的历史. Hoboken: Wiley Finance.

第二章:两态经济

作为一个经验领域,金融旨在寻找特定的答案,例如给定证券的适当价值,或者持有其股票的最佳数量。

达雷尔·达菲(1988 年)

套利的概念对现代金融理论至关重要。

德尔班和沙赫迈尔(2006 年)

本章的分析基于最简单的模型经济,它足够丰富,可以引入金融的许多重要概念和思想:一个只有两个相关时间点和两个不确定未来状态的经济。它还允许我们呈现该领域的一些重要结果,如资产定价基本定理,这些结果在本章中进行了讨论。¹

所选的简单模型是为了简化正式引入有时相当抽象的数学概念和金融思想,尽可能避免技术性问题。一旦这些思想被详细阐述和深入理解,转移到更现实的金融模型通常是无缝的。

本章主要涵盖了金融、数学和 Python 编程的以下核心主题:

金融 数学 Python
时间 自然数 int, type
货币(货币单位) 实数 float
现金流 元组 tuple, list
回报、利息 实数 abs
(净)现值 函数 def, return
不确定性 向量空间 2 NumPy, ndarray, np.array
金融资产 过程 ndarray, tuple
风险 概率、状态空间、幂集、映射 ndarray
期望、预期回报 点积 np.dot
波动率 方差、标准差 np.sqrt
条件性索赔 随机变量 np.arange, np.maximum, plt.plot
复制、套利 线性方程、矩阵形式 ndarray(2d), np.linalg.solve, np.dot
完备性、阿罗-德布鲁证券 线性独立性、张成 np.linalg.solve
鞅定价 鞅、鞅测度 np.dot
均值-方差 期望、方差、标准差 np.linspace, .std(), [x for y in z]

经济

金融模型的第一个要素是经济的概念。经济是一个抽象概念,涵盖了金融模型的其他元素,如资产(实际、金融)、代理人(个人、机构)或货币。就像现实世界一样,经济不能被看到或触摸。也不能直接进行形式化建模——但是拥有这样一个概括性术语可以简化沟通。单一的模型元素共同形成经济。²

实际资产

经济中有多个实际资产可供使用,可以用于不同目的。实际资产可能是鸡蛋或用于生产其他实际资产的复杂机器。在这一点上,例如,生产实际资产的人或者拥有它们的人并不重要。

代理人

代理人可以被视为在经济中活跃的个体人类。他们可能参与生产实际资产,消费它们或交易它们。他们在交易中接受货币并在其他交易中支出它。代理人也可以是像银行这样的机构,允许其他代理人存入货币,并支付利息。

时间

经济活动,如交易实际资产,仅在离散的时间点发生。形式上,这适用于时间点 t 0 , 1 , 2 , 3 , . . .t 0 。在接下来的内容中,只有两个时间点 t = 0t = 1 是相关的。它们最好被理解为今天一年后,尽管这不一定是相关时间间隔的唯一解释。在许多背景下,也可以将其视为今天明天。无论如何,如果只有两个时间点相关,金融理论则谈论静态经济

用于模拟自然数 的 Python 数据类型是int,代表整数。³ 可对整数进行典型的算术运算,如加法、减法、乘法等:

In [1]: 1 + 3  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[1]: 4

In [2]: 3 * 4  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[2]: 12

In [3]: t = 0  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [4]: t  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[4]: 0

In [5]: t = 1  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [6]: type(t)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[6]: int

1

将两个整数值相加。

2

计算两个整数值的乘积。

3

将变量名t的值赋为0

4

输出变量t的值。

5

将变量t的新值赋为1

6

查找并输出变量t的 Python 类型。

货币

在经济中,货币(或货币)供应是无限的。货币也是无限可分的。货币和货币应仅以抽象术语思考,而不是以现金(实体硬币或纸币)的形式。

通常来说,货币在经济中作为计量单位,其中一个货币单位(例如美元、欧元、英镑等)的价值被标准化为精确的 1。其他所有商品的价格则以这些单位的分数或倍数表示。形式上,货币单位被表示为(非负)实数 c ≥0

在 Python 中,float是用于表示实数 的标准数据类型。它代表浮点数。与int类型一样,它允许进行典型的算术运算,如加法和减法:

In [7]: 1 + 0.5   ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[7]: 1.5

In [8]: 10.5 - 2  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[8]: 8.5

In [9]: c = 2 + 0.75  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [10]: c  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[10]: 2.75

In [11]: type(c)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[11]: float

1

加两个数。

2

减去两个数。

3

将加法结果赋给变量c

4

打印变量c的值。

5

查找并打印变量c的 Python 类型。

除了作为计量单位,货币还允许经济主体买卖实物资产或在时间上储存价值。这两个功能基于对货币确实具有今天和一年后都有内在价值的信任。一般来说,这转化为对人们和机构愿意在任何交易中今天和将来都接受货币的信任。计量单位功能独立于此信任,因为它仅仅是一个数值操作。

现金流量

结合时间与货币导致现金流的概念。考虑一个投资项目,今天需要投资 9.5 货币单位,并在一年后支付 11.75 货币单位。投资通常被认为是现金流出,通常将其表示为负实数, c <0 ,或者更具体地说, c = –9.5。支付是现金流入,因此是正实数, c ≥0 ,或者在例子中是 c = +11.75。

为了指示现金流发生的时间点,使用时间索引:在例子中,c t=0 = –9.5 和 c t=1 = 11.75,或简称为 c 0 = –9.5 和 c 1 = 11.75。

数学上,现在和一年后的现金流对被建模为有序对二元组,将两个相关的现金流组合成一个对象:c 2,其中 c = ( c 0 , c 1 ),且 c 0 , c 1

在 Python 中,有多种数据结构可用于建模这样的数学对象。最基本的两种是tuplelist。类型为tuple的对象是不可变的,即在实例化后无法更改;而类型为list的对象是可变的,在实例化后可以更改。首先是tuple对象的示例(用括号表示):

In [12]: c0 = -9.5  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [13]: c1 = 11.75  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [14]: c = (c0, c1)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [15]: c  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[15]: (-9.5, 11.75)

In [16]: type(c)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[16]: tuple

In [17]: c[0]  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[17]: -9.5

In [18]: c[1]  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[18]: 11.75

1

定义今天的现金流出。

2

定义一年后的现金流入。

3

定义tuple对象c(请注意使用括号)。

4

打印现金流对(请注意括号)。

5

查找并显示对象c的类型。

6

访问对象c的第一个元素。

7

访问对象c的第二个元素。

其次,list对象的示例(用方括号表示):

In [19]: c = [c0, c1]  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [20]: c  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[20]: [-9.5, 11.75]

In [21]: type(c)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[21]: list

In [22]: c[0]  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[22]: -9.5

In [23]: c[1]  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[23]: 11.75

In [24]: c[0] = 10  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [25]: c  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[25]: [10, 11.75]

1

定义list对象c(请注意使用方括号)。

2

打印现金流对(请注意括号)。

3

查找并显示对象 c 的类型。

4

访问对象 c 的第一个元素。

5

访问对象 c 的第二个元素。

6

覆盖对象 c 中第一个索引位置的值。

7

显示结果的变化。

返回

考虑一个具有现金流 c = ( c 0 , c 1 ) = (–10, 12) 的投资项目。该项目的 回报 R 是现金流的总和 R = c 0 + c 1 = –10 + 12 = 2. 项目的 回报率r ,是回报 R 除以投资现值的绝对值 | c 0 | 得到的结果:

r = R |c 0 | = -10+12 10 = 2 10 = 0.2

在 Python 中,这归结为简单的算术操作:

In [26]: c = (-10, 12)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [27]: R = sum(c)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [28]: R  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[28]: 2

In [29]: r = R / abs(c[0])  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [30]: r  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[30]: 0.2

1

将现金流对定义为 tuple 对象。

2

使用 c 的所有元素的总和计算回报 R 并…

3

…打印出结果。

4

使用 abs(x) 计算利率 r,给出 x 的绝对值并…

5

…打印出结果。

利息

今天现金流和一年后的现金流之间存在差异。这种差异是由于货币单位上 赚取的利息 或需要 支付的利息 导致的。在这种情况下,利息是为控制属于另一位代理的资金而支付的 代价

拥有不需要的货币单位的代理可以将其存入银行或借给另一位代理以 赚取利息。如果代理需要比当前可用的货币单位更多的货币单位,可以向银行或其他代理借款,但需 支付利息

假设一个代理人今天在银行存入c 0 = -10 货币单位。根据存款合同,一年后他们从银行获得c 1 = 11货币单位。存款所产生的利息I ,为I = c 0 + c 1 = -10 + 11 = 1。利率i ,相应地为i = I |c 0 | = 0.1。

下文假设,对于借贷和存款,相关利率相同且在整个经济中固定。

现值

提供了借贷或存款选择,导致在投资项目中使用资金的机会成本。比如,一年后的现金流c 1 = 12.1 不能直接与今天的现金流c 0 = 12.1 价值相比,因为货币单位未投入项目可以获得利息。

要适当地比较一年后的现金流和今天的现金流,需要计算现值。这通过在经济中使用的固定利率折现来完成。折现可以建模为函数D : , c 1 D ( c 1 ),将一年后的现金流映射到今天的另一个实数。它满足

c 0 = D ( c 1 ) = c 1 1+i = 12.1 1+0.1 = 11

对于利率i = 0.1。这种关系源于与银行存款的替代“投资”:

c 1 = ( 1 + i ) · c 0 c 0 = c 1 1+i

Python 函数非常适合表示数学函数,比如折现函数:

In [31]: i = 0.1  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [32]: def D(c1):  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
             return c1 / (1 + i)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [33]: D(12.1)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[33]: 10.999999999999998

In [34]: D(11)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[34]: 10.0

1

固定利率i

2

使用def语句定义函数;D为函数名称;c1为参数名称。

3

使用return语句返回现值。

4

计算 12.1 的现值;注意由于内部浮点数表示问题而导致的舍入误差。

5

计算 11 的现值(在这种情况下为“准确地”)。

净现值

一个代理如何决定是否进行投资项目?其中一个标准是净现值。净现值,N P V ,是今天的现金流出总和以及一年后现金流入的现值之和:

N P V ( c ) = c 0 + D ( c 1 )

在这里,净现值计算是一个函数N P V : 2 ,将现金流元组映射到一个实数。如果净现值为正,则应进行项目;如果为负,则不应—因为将钱存入银行的替代方案更具吸引力。

考虑一个投资项目,其现金流为c A = (–10.5, 12.1)。净现值为N P V ( c A ) = –10.5 + D (12.1) = –10.5 + 11 = 0.5。该项目应当进行。考虑另一个投资项目,现金流为c B = (–10.5, 11)。该项目的净现值为负数,不应进行: N P V ( c B ) = –10.5 + D (11) = –10.5 + 10 = –0.5。

在前述定义基础上,可以轻松定义相应的 Python 函数:

In [35]: def NPV(c):
             return c[0] + D(c[1])

In [36]: cA = (-10.5, 12.1)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [37]: cB = (-10.5, 11)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [38]: NPV(cA)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[38]: 0.4999999999999982

In [39]: NPV(cB)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[39]: -0.5

1

正净现值项目。

2

负净现值项目。

不确定性

从投资项目一年后的现金流入总体上来说是不确定的。它们可能受到现实中多种因素的影响(竞争力量、新技术、经济增长、天气、项目实施中的问题等)。在模型经济中,一年后经济的状态的概念涵盖了所有相关因素的影响。

假设一年后经济可能处于两种不同的状态 ud ,可以解释为上升(“好”)和下降(“坏”)。项目一年后的现金流 c 1 就成为一个向量

c 1 2

具有两个不同的值

c 1 u , c 1 d

表示与经济状态相关的现金流量的相关现金流。从形式上讲,这被称为所谓的列向量

c 1 = c 1 u c 1 d

在数学上,对这种向量定义了一些操作,如标量乘法加法,例如:

α · c 1 + β = α · c 1 u c 1 d + β = α · c 1 u + β α · c 1 d + β

向量的另一个重要操作是向量的线性组合的创建。考虑两个不同的向量:c 1 , d 1 2 。线性组合由以下给出:

α · c 1 + β · d 1 = α · c 1 u + β · d 1 u α · c 1 d + β · d 1 d

在此之前和之后,假定 α , β

在 Python 中建模向量(和矩阵)的最常见方式是通过NumPy包,这是一个外部包,需要单独安装。对于以下代码,请考虑一个投资项目,其中 c 0 = –10 和 c 1 = (20,5) T ,其中上标 T 表示向量的转置(将行或水平向量转换为列或垂直向量)。用于建模向量的主要类是 ndarray 类,代表n 维数组

In [40]: import numpy as np  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [41]: c0 = -10  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [42]: c1 = np.array((20, 5))  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [43]: type(c1)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[43]: numpy.ndarray

In [44]: c1  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[44]: array([20,  5])

In [45]: c = (c0, c1)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [46]: c  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[46]: (-10, array([20,  5]))

In [47]: 1.5 * c1 + 2  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[47]: array([32. ,  9.5])

In [48]: c1 + 1.5 * np.array((10, 4))  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
Out[48]: array([35., 11.])

1

导入 numpy 包作为 np

2

今天的现金流出。

3

一年后的不确定现金流;一维 ndarray 对象不区分行(水平)和列(垂直)。

4

查找并打印 c1 的类型。

5

打印现金流向量。

6

将现金流组合成一个tuple对象。

7

一个tuple,就像一个list对象一样,可以包含其他复杂的数据结构。

8

通过标量乘法和加法对向量进行线性变换;技术上也谈论向量化数值操作和广播。

9

两个ndarray对象(向量)的线性组合。

金融资产

金融资产是具有今天固定价格和一年后不确定价格的金融工具(“合同”)。想象一下,一个公司进行投资项目的股权份额。这样的股份可能今天以价格S 0 >0 的价格可用。一年后股份的价格取决于投资项目的成功,即在u状态观察到高现金流入还是在d状态观察到低现金流入。形式上,S 1 u ,S 1 d ≥0 ,其中 S 1 u > S 1 d

人们也称之为金融资产S: 0 ×{u,d} ≥0价格过程,将时间和经济状态映射到金融资产价格上。注意,今天的价格与状态S 0 u = S 0 d S 0无关,而一年后的价格一般而言不是。人们也写成(S t ) t{0,1} = ( S 0 , S 1 ),或简写为S = ( S 0 , S 1 )。建模的工具再次是NumPy包:

In [49]: S0 = 10  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [50]: S1 = np.array((12.5, 7.5))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [51]: S = (S0, S1)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [52]: S  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[52]: (10, array([12.5,  7.5]))

In [53]: S[0]  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[53]: 10

In [54]: S[1][0]  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[54]: 12.5

In [55]: S[1][1]  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[55]: 7.5

1

今天的金融资产价格。

2

一年后的不确定价格作为一个向量(ndarray对象)。

3

价格过程作为一个tuple对象。

4

打印价格过程信息。

5

访问今天的价格。

6

访问u(第一个)状态下一年后的价格。

7

访问d(第二个)状态下一年后的价格。

风险

通常会默认假设经济的两种状态等可能。这通常意味着,在经济实验被重复(无限次)进行时,观察到一半的时间为状态u,另一半时间为状态d

这是一种频率主义的观点,根据这种观点,状态发生的概率是根据观察到该状态的频率除以导致观察的实验总数来计算的。如果状态u在 50 次实验中观察到 30 次,则概率p ≥0,满足0 p 1,相应地为p = 30 50 = 0.6,或 60%。

在建模的背景下,所有可能状态发生的概率被认为是先验给定的。有时候会谈到客观物理概率。

概率测度

对于物理上可能的事件的概率一起形成概率测度。这样的概率测度是一个函数P : ( { u , d } ) 0,将{ u , d }幂集的所有元素映射到单位区间。在这种情况下,幂集包含所有物理上可能发生的事件。

在这个背景下,集合{ u , d }也被称为状态空间,用Ω符号表示。三元组( Ω , ( Ω ) , P )称为概率空间

代表概率测度的函数P需要满足三个条件:

  1. P ( ) = 0

  2. 0 P ( ω ) , ω Ω 1

  3. P ( Ω ) = P ( u ) + P ( d ) = 1

第一个条件意味着至少会出现其中一个状态。第二个条件暗示着状态实现的概率在 0 到 1 之间。第三个条件表明所有概率相加等于 1。

在仅有两个状态的简单模型经济中,定义 p P ( u ) 是方便的,并相应地有 P ( d ) = 1 - p ,考虑到前述第三个条件。固定 p 就定义了概率度量 P

如果有一个完全指定的概率度量可用,模型经济通常称为 风险经济 。如果一个模型经济没有完全指定的概率度量,通常称为 歧义经济

在应用中,概率度量通常也被建模为向量和 ndarray 对象,分别适用于具有有限元素的离散状态空间:

In [56]: p = 0.4

In [57]: 1 - p
Out[57]: 0.6

In [58]: P = np.array((p, 1-p))

In [59]: P
Out[59]: array([0.4, 0.6])

不确定性的概念

在金融背景下,不确定性可以采取不同的形式。 风险 通常指的是在整个经济未来状态的概率分布是(假定为)已知的情况。 歧义 指的是这样的情况,即这种分布是未知的。传统上,金融几乎完全依赖于在风险下的模型经济,尽管有一些研究致力于处理歧义下的金融问题(参见 Guidolin 和 Rinaldi(2012 年)对研究文献的概述)。

期望值

基于概率度量,可以计算不确定数量的 期望值 ,例如金融资产一年后的价格。期望值可以解释为 加权平均值 ,其中权重由概率给出。这是一个平均值,因为概率相加等于一。

考虑价格过程为 S = S 0 , S 1 的金融资产。一年后在概率度量 P 下,不确定价格 S 1 的期望值为

𝐄 P ( S 1 ) ωΩ P ( ω ) · S 1 ω = p · S 1 u + ( 1 - p ) · S 1 d

其中 p P ( u ) 。如果 S 1 = (20,5) T 并且 p = 0.4 成立,期望值为:

𝐄 P ( S 1 ) = 0.4 · 20 + ( 1 - 0.4 ) · 5 = 11

在数学上,期望可以表达为两个向量的点乘(或内积)。如果 x , y 2 ,则点乘被定义为

( x , y ) = i=1 2 x i · y i = x 1 · y 1 + x 2 · y 2

因此,有 P (p,1-p) TS 1 = (S 1 u ,S 1 d ) T ,期望值是

𝐄 P ( S 1 ) = ( P , S 1 ) = p 1 - p , S 1 u S 1 d = p · S 1 u + ( 1 - p ) · S 1 d

在 Python 中使用 ndarray 对象,点乘被定义为 NumPy 包提供的一个函数:

In [60]: P  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[60]: array([0.4, 0.6])

In [61]: S0 = 10  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [62]: S1 = np.array((20, 5))  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [63]: np.dot(P, S1)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[63]: 11.0

1

先前定义的概率测度。

2

金融资产的今天价格。

3

一年后的不确定价格向量。

4

计算两个向量的点乘以求期望值。

预期回报

在不确定性下,回报和回报率的概念需要调整。在这种情况下,金融资产的预期回报被定义为一年后价格的期望值减去今天的价格。这可以通过对不确定回报 R = (R u ,R d ) T 进行期望值计算得出:

𝐄 P ( R ) = p 1 - p , R u R d = p 1 - p , S 1 u - S 0 S 1 d - S 0 = p · ( S 1 u - S 0 ) + ( 1 - p ) · ( S 1 d - S 0 ) = p · S 1 u + ( 1 - p ) · S 1 d - S 0 = 𝐄 P ( S 1 ) - S 0

根据之前的假设,得到以下结果:

𝐄 P ( R ) = 0.4 · ( 20 - 10 ) + ( 1 - 0.4 ) · ( 5 - 10 ) = 11 - 10 = 1

预期回报率 简单地是预期回报除以今天的价格

𝐄 P ( r ) = 𝐄 P (R) S 0

这也可以通过类似于对预期收益的变换一步步导出。接下来,预期收益率用 μ 𝐄 P ( r ) 符号表示以简洁。

预期收益和收益率的计算可以通过两个简单的 Python 函数进行建模:

In [64]: def ER(x0, x1):
             return np.dot(P, x1) - x0  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [65]: ER(S0, S1)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[65]: 1.0

In [66]: def mu(x0, x1):
             return (np.dot(P, x1) - x0) / x0  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [67]: mu(S0, S1)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[67]: 0.1

1

预期收益的定义。

2

先前定义的金融资产的预期收益。

3

预期收益率的定义。

4

计算该资产的预期收益率。

波动率

在金融领域,风险和预期收益 是支配性的一对概念。风险可以用许多方式来衡量,而由收益率的标准差测量的 波动率 可能是最常见的度量。在当前情境下,金融资产的收益率的 方差 由以下定义:

σ 2 ( r ) = 𝐄 P (r-μ) 2 = p 1 - p , (r u -μ) 2 (r d -μ) 2

r ω ( S 1 ω - S 0 ) / S 0 , ω Ω波动率 定义为收益率的标准差,即方差的平方根。

σ ( r ) = σ 2 ( r )

以下给出了这两种风险度量的 Python 函数,以及用于计算收益率向量的辅助函数:

In [68]: def r(x0, x1):
             return (x1 - x0) / x0  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [69]: r(S0, S1)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[69]: array([ 1. , -0.5])

In [70]: mu = np.dot(P, r(S0, S1))  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [71]: mu  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[71]: 0.10000000000000003

In [72]: def sigma2(P, r, mu):
             return np.dot(P, (r - mu) ** 2)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [73]: sigma2(P, r(S0, S1), mu)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[73]: 0.54

In [74]: def sigma(P, r, mu):
             return np.sqrt(np.dot(P, (r - mu) ** 2))  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)

In [75]: sigma(P, r(S0, S1), mu)  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[75]: 0.7348469228349535

1

收益率向量的矢量化计算。

2

将函数应用于之前的金融资产。

3

通过点积计算的预期收益率…

4

…打印出。

5

收益率的方差的定义。

6

应用于收益率向量的函数。

7

波动率的定义。

8

应用于回报率向量。

向量、矩阵和 NumPy

作为应用数学学科的金融学在很大程度上依赖于线性代数和概率论。在离散模型经济中,可以通过使用NumPy包及其强大的ndarray对象高效处理这两个数学学科。这不仅仅从建模角度来看是真实的,而且从处理、计算、优化、可视化及其他角度也是如此。本书中的所有示例都将支持这些说法。

有条件索赔

现在假设经济中交易一个有条件索赔。这是一种金融资产,由某些合同正式化,它提供从现在起一年后的状态相关偿付。这样的有条件索赔可以具有任意的状态相关偿付或者从其他金融资产的偿付派生而来。在后一种情况下,通常称为衍生资产衍生工具。形式上,有条件索赔是一个函数 C 1 : Ω 0 , ω C 1 ( ω ) 将事件映射到(非负)实数。

假设在经济中交易两种金融资产:价格过程为 B = ( B 0 , B 1 ) 的无风险债券和价格过程

S = S 0 , (S 1 u ,S 1 d ) T

股票的看涨期权在一年后的偿付为 C 1 ( S 1 ( ω ) ) = max ( S 1 ( ω ) - K , 0 ),其中 ω ΩK ≥0 被称为期权的行权价格

在概率论中,有条件索赔通常称为随机变量,其定义特征是将状态空间的元素映射到实数——可能通过其他随机变量,如衍生资产的情况。从这个意义上说,股票一年后的价格 S 1 :Ω ≥0 ,ωS 1 (ω) 也是一个随机变量。⁴

为了说明,以下 Python 代码在实线段上可视化期权的支付。在经济中,当然只有两个状态——因此只有两个相关的值。图 2-1 图形地显示了支付函数:

In [76]: S1 = np.arange(20)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [77]: S1[:7]  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[77]: array([0, 1, 2, 3, 4, 5, 6])

In [78]: K = 10  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [79]: C1 = np.maximum(S1 - K, 0)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [80]: C1  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[80]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [81]: from pylab import mpl, plt  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
         # plotting configuration
         plt.style.use('seaborn')
         mpl.rcParams['savefig.dpi'] = 300
         mpl.rcParams['font.family'] = 'serif'

In [82]: plt.figure(figsize=(10, 6))
         plt.plot(S1, C1, lw = 3.0, label='$C_1 = \max(S_1 - K, 0)$')  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
         plt.legend(loc=0)  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
         plt.xlabel('$S_1$')  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
         plt.ylabel('$C_1$');  ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)

1

生成一个ndarray对象,其中包含从 0 到 19 的数字。

2

展示前几个数字。

3

为期权设定执行价格。

4

以向量化方式计算期权的支付值。

5

显示这些值——许多值为 0。

6

matplotlib中导入主绘图子包。

7

绘制期权支付与股票价值的图表,将线宽设置为 3 像素,并定义一个标签作为包含Latex代码的字符串对象。

8

将图例放在最佳位置(与绘图元素最小重叠)。

9

x轴上放置标签…

10

…以及y轴。

ftwp 0201

图 2-1. 期权的支付

复制

当将一项有条件的索赔引入经济时,一个重要的问题是索赔的支付是否冗余。数学上,人们称有条件索赔的支付向量为线性相关线性独立

期权的支付在以下问题存在解时被称为线性相关或冗余。

b · B 1 B 1 + s · S 1 u S 1 d = C 1 u C 1 d

其中 b , s

这个问题可以表示为线性方程组

b · B 1 + s · S 1 u = C 1 u b · B 1 + s · S 1 d = C 1 d

对于 S 1 u S 1 d ,解决方案为

s * = C 1 u -C 1 d S 1 u -S 1 d

b * = 1 B 1 C 1 d ·S 1 u -C 1 u ·S 1 d S 1 u -S 1 d

假设如前所述,交易两个金融资产,一个无风险债券 B = ( 10 , 11 ) 和一个风险股票 S = ( 10 , (20,5) T ) 。进一步假设 K = 15 使得 C 1 = (5,0) T 。则最优数值解为

s * = 5-0 20-5 = 1 3

b * = 1 11 · 0·20-5·5 20-5 = - 5 33

换句话说,购买股票的三分之一并将债券的 五分之三十三 卖空可以完美复制看涨期权的回报。因此,看涨期权的回报与债券和股票的回报向量线性相关。

从技术上讲,空头卖出 意味着从另一个代理商借入今天的相应数量的金融资产单位,并立即在市场上出售这些单位。一年后,借款代理商以当时的市场价格购买相同数量的金融资产单位,并将其转回给另一代理商。

这里的分析假设所有金融资产——如货币——都是无限可分的,这在实际中可能并非如此。它还假设所有交易的金融资产可以进行空头卖出,这在市场实践中可能并不是太不现实的情况。

作为在 Python 中实现的准备工作,考虑另一种制定复制问题的方式。为此,需要数学概念 矩阵。而向量是一维对象,矩阵是二维对象。对于本节的目的,请考虑一个四元素的方阵 — 意味着 2×2 — 其中

= B 1 S 1 u B 1 S 1 d

债券和股票的未来支付向量分别代表矩阵的第一列和第二列中的值。第一行包含状态u中两种金融资产的支付,而第二行包含来自状态d的支付。按照这些约定,复制问题可以用矩阵形式表示为

· ϕ = C 1

其中ϕ 2是包含债券和股票投资组合位置的向量,用于复制ϕ (b,s) Tϕ通常被称为投资组合交易策略。因此:

B 1 S 1 u B 1 S 1 d · b s = C 1 u C 1 d

在这个背景下,矩阵乘法定义为

B 1 S 1 u B 1 S 1 d · b s B 1 · b + S 1 u · s B 1 · b + S 1 d · s

这显示了表示复制问题的这种方式与之前的方式之间的等价性。

ndarray类允许在 Python 中对矩阵进行建模。NumPy包在子包np.linalg中提供了大量的线性代数操作函数,其中包括解决矩阵形式线性方程组的函数——正是这里需要的:

In [83]: B = (10, np.array((11, 11)))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [84]: S = (10, np.array((20, 5)))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [85]: M = np.array((B[1], S[1])).T  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [86]: M  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[86]: array([[11, 20],
                [11,  5]])

In [87]: K = 15  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [88]: C1 = np.maximum(S[1] - K, 0)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [89]: C1  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[89]: array([5, 0])

In [90]: phi = np.linalg.solve(M, C1)  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)

In [91]: phi  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[91]: array([-0.15151515,  0.33333333])

1

定义了无风险债券的价格过程。

2

定义了风险股票的价格过程。

3

定义了一个矩阵——即一个二维ndarray对象——带有未来的支付向量。

4

展示了具有数值的矩阵。

5

确定了看涨期权的执行价格和…

6

…计算了一年后支付向量的值。

7

展示了支付向量的数值。

8

以矩阵形式解决复制问题以获取最优投资组合位置。

套利定价

如何复制看涨期权的支付需要多少成本?一旦推导出用于完成复制的投资组合,这个问题就很容易回答了。通过定义今天复制投资组合的价值为V 0 ( ϕ )。 它由点乘法表示

V 0 ( ϕ ) b s , B 0 S 0 = b · B 0 + s · S 0

或者用数字表示为

V 0 ( ϕ ) = b · B 0 + s · S 0 = 10 3 - 50 33 = 1 . 818181

一年内再现投资组合的不确定价值 V 1 ( ϕ ) 可以通过矩阵乘法表示为

V 1 ( ϕ ) = B 1 S 1 u B 1 S 1 d · b s = 5 0

联合起来,投资组合的价值过程可以表示为 V ( ϕ ) = ( V 0 ( ϕ ) , V 1 ( ϕ ) ) ,或者简写为 V = ( V 0 , V 1 ),如果投资组合没有歧义。

拥有一个能够完全再现未来条件索赔的投资组合引发了下一个问题:如果今天条件索赔的价格与设置再现投资组合的成本不同怎么办?答案很简单但严肃:这时经济中存在套利套利机会。套利是一种交易策略 ϕ,从零投资中获得无风险利润。形式上,如果存在一个套利,那么 ϕ 是套利。

V 0 ( ϕ ) = 0𝐄 P V 1 ( ϕ ) > 0

或者

V 0 ( ϕ ) > 0V 1 ( ϕ ) = 0

假设期权的价格为 C 0 = 2 ,高于建立复制组合的成本。在市场上以 2 的价格出售期权并以 1.81818 的价格购买复制组合的交易策略将立即获得差额利润。一年后,复制组合和期权的支付互相抵消,形成无套利价格过程

- C 1 u C 1 d + b B 1 B 1 + s S 1 u S 1 d = 0 0

通过复制组合的定义。在另一种情况下,当今天期权的价格低于复制组合的价格时,假设 C 0 = 1.5,购买期权并卖出复制组合的交易策略将带来无风险利润,即市场期权价格与建立复制组合的成本之间的差额。当然,在两种情况下,无风险利润可以通过简单地将头寸乘以大于一的正因子来增加。

可以考虑允许套利机会的经济模型是不可行的。因此,与无套利一致的唯一价格是 C 0 = 1.818181。这个价格被称为期权的套利价格。每当存在一个复制条件性索赔的组合 ϕ ,使得 V 1 ( ϕ ) = C 1 ,那么条件性索赔的套利价格是 C 0 = V 0 ( ϕ )

形式上,套利价格是复制组合和复制金融资产价格向量的点积。

C 0 V 0 ( ϕ ) = ϕ , B 0 S 0 = b · B 0 + s * · S 0

产生条件性索赔的无套利价格过程为 C = ( C 0 , C 1 )

在 Python 中,这是一个单独的计算,给定先前的定义和计算:

In [92]: C0 = np.dot(phi, (B[0], S[0]))

In [93]: C0
Out[93]: 1.8181818181818183

In [94]: 10/3 - 50/33
Out[94]: 1.8181818181818183

市场完备性

套利定价对于每一个条件性索赔都有效吗?是的,至少对于那些可以通过在经济中交易的金融资产组合复制的索赔。可达条件性索赔集合 𝔸 包括所有可以通过交易金融资产来复制的条件性索赔。它由张成给出,即所有交易金融资产未来价格向量的所有线性组合的集合

𝔸 = · ϕ , ϕ ≥0 2

如果禁止做空,并

𝔸 = · ϕ , ϕ 2

如果允许无限制地进行。

考虑之前的无风险债券和风险股票,其价格过程为B = ( B 0 , B 1 )S = S 0 , (S 1 u ,S 1 d ) T ,分别为B 1 ,S 1 ≥0 2S 1 u S 1 d 。因此很容易显示复制问题

· ϕ = C 1

因此对于任何C 1 ≥0 2 都有唯一解。解由以下给出

ϕ = b s *

因此,每一个条件性索赔都可以通过复制和套利来定价。形式上,唯一的要求是一年内两个金融资产的价格向量线性无关。这意味着

ϕ * = 1 B 1 C 1 d ·S 1 u -C 1 u ·S 1 d S 1 u -S 1 d C 1 u -C 1 d S 1 u -S 1 d

它是在特殊认购期权收益复制的背景下推导出来的。由于对支付没有作任何特殊假设,解可以推广到一般情况,除了C 1 ≥0 2

由于每一个条件性索赔都可以通过持有无风险债券和风险股票的组合来复制,因此我们谈论完全市场模型

B 1 S 1 u B 1 S 1 d · b s = 0 0

仅有唯一解ϕ = (0,0) T,没有其他解。事实上,在市场完备性下,任意权利的复制问题都有唯一解。这两个交易金融资产的支付向量跨越了 2,因为它们构成 2基础*。

可以通过 Python 和matplotlib包来可视化跨度属性。为此,模拟了 1,000 个随机投资组合。首要限制条件是投资组合位置应为正,并且总和应为 1。图 2-2 显示了结果:

In [95]: from numpy.random import default_rng
         rng = default_rng(100)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [96]: n = 1000  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [97]: b = rng.random(n)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [98]: b[:5]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[98]: array([0.83498163, 0.59655403, 0.28886324, 0.04295157, 0.9736544 ])

In [99]: s = (1 - b)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [100]: s[:5]  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[100]: array([0.16501837, 0.40344597, 0.71113676, 0.95704843, 0.0263456 ])

In [101]: def portfolio(b, s):
              A = [b[i] * B[1] + s[i] * S[1] for i in range(n)]  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
              return np.array(A)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [102]: A = portfolio(b, s)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)

In [103]: A[:3]  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[103]: array([[12.48516533, 10.00988978],
                 [14.63101376,  8.57932416],
                 [17.40023082,  6.73317945]])

In [104]: plt.figure(figsize=(10, 6))
          plt.plot(A[:, 0], A[:, 1], 'r.');  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)

1

为随机数发生器设置种子。

2

要模拟的值的数量。

3

通过均匀分布模拟值在 0 到 1 之间的债券头寸。

4

推导出股票头寸,即 1 与债券头寸的差值。

5

计算所有随机投资组合构成的投资组合收益向量,并将它们收集到一个list对象中;这种 Python 惯用语称为list推导。

6

该函数返回结果的ndarray版本。

7

启动计算。

8

绘制结果。

ftwp 0202

图 2-2。随机投资组合仅跨越一维线。

图 2-3 显示了图形结果,在此处投资组合位置无需加起来等于 1:

In [105]: s = rng.random(n)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [106]: b[:5] + s[:5]
Out[106]: array([1.36885777, 1.5863474 , 0.71245805, 0.32077672, 1.5401562 ])

In [107]: A = portfolio(b, s)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [108]: plt.figure(figsize=(10, 6))
          plt.plot(A[:, 0], A[:, 1], 'r.');

1

股票头寸可以自由模拟在 0 到 1 之间的值。

2

计算投资组合的收益向量。

ftwp 0203

图 2-3。随机投资组合跨越二维区域(菱形)

最后,图 2-4 允许债券和股票的正和负的投资组合。产生的投资组合回报向量覆盖原点周围的(椭圆形)区域:

In [109]: b = rng.standard_normal(n)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [110]: s = rng.standard_normal(n)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [111]: b[:5] + s[:5]  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[111]: array([-0.23046605, -3.45760465,  1.10260637, -2.44445777,
           1.05866637])

In [112]: A = portfolio(b, s)

In [113]: plt.figure(figsize=(10, 6))
          plt.plot(A[:, 0], A[:, 1], 'r.');

1

通过标准正态分布模拟正和负的投资组合头寸。

ftwp 0204

图 2-4. 随机投资组合覆盖的二维区域(围绕原点)

如果bs 在实线上可以取任意值,b , s ,则得到的投资组合完全覆盖了向量空间 2。正如前面指出的,交易的金融资产的回报向量在这种情况下跨越了 2

阿罗-德布鲁证券

阿罗-德布鲁证券的定义是在指定的未来状态下支付一单位货币。在仅有两种不同未来状态的模型经济中,只能存在两种不同的这种证券。阿罗-德布鲁证券简单地说就是一个特殊情况的条件索赔,之前的复制论证同样适用。换句话说,由于市场是完备的,阿罗-德布鲁证券可以通过债券和股票的投资组合进行复制。因此,两个复制问题都有(唯一的)解,并且这两种证券有唯一的套利价格。这两个复制问题是

· ϕ = 1 0

并且

· ϕ = 0 1

为什么这些证券很重要?数学上,这两种回报向量形成了 2 向量空间的标准基自然基。这反过来意味着该空间中的任何向量都可以作为形成标准基的向量的线性组合唯一表达(复制)。从财务上讲,用阿罗-德布鲁证券替代债券和股票的原始未来价格向量作为模型经济的基础,极大地简化了所有其他条件索赔的复制问题。

过程是首先推导出两个阿罗-德布鲁证券的复制投资组合和两者的套利价格。然后基于标准基和这两种证券的套利价格复制和定价其他条件索赔。

考虑两个 Arrow-Debreu 证券,其价格过程为 γ u = ( γ 0 u , (1,0) T )γ d = ( γ 0 d , (0,1) T ) 并定义:

M γ = 1 0 0 1

考虑一个一般的条件索赔,其未来支付向量为:

C 1 = C 1 u C 1 d

条件索赔的复制投资组合 ϕ γ 则显然由 ϕ γ = (C 1 u ,C 1 d ) T ,因为:

V 1 ( ϕ γ ) = γ · ϕ γ = 1 0 0 1 · C 1 u C 1 d = C 1 u C 1 d

因此,条件索赔的套利价格是:

C 0 = V 0 ( ϕ γ ) = C 1 u · γ 0 u + C 1 d · γ 0 d

这说明引入 Arrow-Debreu 证券如何简化条件索赔复制和套利定价。

鞅定价

鞅测度 Q:(Ω) ≥0 是一种特殊的概率测度。它使得金融资产的折现价格过程成为。为了使得股票在 Q 下成为鞅,以下关系必须成立:

S 0 = 1 1+i · 𝐄 Q ( S 1 )

如果 i = B 1 -B 0 B 0 ,那么对于无风险债券,这个关系显然成立:

B 0 = 1 1+i · 𝐄 Q ( B 1 ) = 1 1+i · B 1

人们还谈论到价格过程在鞅测度下(平均)漂移与无风险利率的关系:

B 0 · ( 1 + i ) = B 1 S 0 · ( 1 + i ) = 𝐄 Q ( S 1 )

q Q ( u ) 。得到

q · S 1 u + ( 1 - q ) · S 1 d = S 0 · ( 1 + i )

或经过一些简单的操作后:

q = S 0 ·(1+i)-S 1 d S 1 u -S 1 d

给定前提条件,对于 q 来定义一个有效的概率测度,必须满足 S 1 u > S 0 · ( 1 + i ) > S 1 d。如果满足,就会得到一个新的概率空间 ( Ω , ( Ω ) , Q ),其中 Q 取代 P

如果这些关系对 S 1 不成立,那么一个简单的套利要么是在情况 S 0 · ( 1 + i ) S 1 d 中买入风险资产,或者在另一种情况下简单地卖出它,S 0 · ( 1 + i ) S 1 u

如果在这些关系中等号成立,那么也称为弱套利,因为无风险利润只能平均预期而非确定性地获得。

假设之前的数值价格过程,用 Python 计算 q 只是在浮点数上进行算术运算:

In [114]: i = (B[1][0] - B[0]) / B[0]

In [115]: i
Out[115]: 0.1

In [116]: q = (S[0] * (1 + i) - S[1][1]) / (S[1][0] - S[1][1])

In [117]: q
Out[117]: 0.4

资产定价的第一基本定理

前一节的考虑暗示了对一方面的鞅测度与对另一方面的套利之间存在关系。在数学金融中,形式上关联这些看似不相关的概念的一个中心结果是资产定价的第一基本定理。在这方面的开创性工作由 Cox 和 Ross(1976)、Harrison 和 Kreps(1979)以及 Harrison 和 Pliska(1981)发表。

资产定价的第一基本定理(1FTAP)

下列陈述等价:

  1. 存在一个鞅测度。

  2. 经济是无套利的。

给定之前的计算和讨论,对于具有无风险债券和风险股票的模型经济体来说,该定理很容易证明。

首先,陈述 1 意味着陈述 2:如果存在鞅测度,则价格过程不允许简单(弱)套利。由于两个未来价格向量线性独立,每个条件索赔都可以通过交易两个金融资产来复制,暗示唯一的套利价格。因此,不存在套利机会。

其次,陈述 2 意味着陈述 1:如果模型经济是无套利的,则存在鞅测度,如前所述。

期望定价

1FTAP 的一个推论是,任何可实现的条件索赔C 1 𝔸可以通过在鞅测度下对其未来回报的期望和以无风险利率折现来定价。看涨期权的套利价格通过复制已知。假设交易的金融资产具有相同的数字价格过程,并且看涨期权的未来支付向量相同,则看涨期权的鞅价格为:

C 0 = 1 1+i · 𝐄 Q ( C 1 ) = 1 1+i · ( q · C 1 u + ( 1 - q ) · C 1 d ) = 1 1+0.1 · ( 0.4 · 5 + ( 1 - 0.4 ) · 0 ) = 1 . 818181

换句话说,看涨期权的折现价格过程——以及任何其他条件索赔——在鞅测度下是一个鞅,使得:

B 0 · ( 1 + i ) = B 1 S 0 · ( 1 + i ) = 𝐄 Q ( S 1 ) C 0 · ( 1 + i ) = 𝐄 Q ( C 1 )

在 Python 中,鞅测定价归结为评估一个点乘积:

In [118]: Q = (q, 1 - q)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [119]: np.dot(Q, C1) / (1 + i)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[119]: 1.8181818181818181

1

将鞅测度定义为元组Q

2

实施鞅测定价公式。

资产定价第二基本定理

还有另一个重要的结果,通常称为资产定价第二基本定理,它将鞅测度的唯一性与市场完备性联系起来。

资产定价第二基本定理(2FTAP)

以下陈述等效:

  1. 鞅测度是唯一的。

  2. 市场模型是完备的。

结果也适用于以前讨论的简单模型经济体。对市场完备性的更详细分析发生在第三章中。

均值-方差组合投资组合

金融领域的一个重大突破是通过由马尔科维茨(1952 年)开创的均值-方差组合投资组合理论(MVP)的形式化和量化来投资组合化。从某种程度上讲,这种方法可以被认为是量化金融的开始,引发了将更多数学引入金融领域的趋势。

MVP 将金融资产简化为其回报的一阶和二阶矩,即均值作为预期收益率和方差作为收益率的波动性,定义为收益率的标准偏差。尽管这种方法通常被称为“均值-方差”,但通常使用的是“均值-波动率”组合。

考虑前面提到的无风险债券和风险股票,其价格过程为B = ( B 0 , B 1 )S = S 0 , (S 1 u ,S 1 d ) T 和未来价格矩阵,其中两列由两个金融资产的未来价格向量给出。对于由b投资于债券和s投资于股票组成的投资组合ϕ,其预期收益率和波动率是多少?请注意,现在假定b + s = 1,其中b,s ≥0成立。当然,这可以放宽,但简化了本节的表达。

预期投资组合收益为:

𝐄 P ( · ϕ ) = p · ( b · B 1 + s · S 1 u ) + ( 1 - p ) · ( b · B 1 + s · S 1 d ) = p · ( b · B 1 ) + ( 1 - p ) · ( b · B 1 ) + p · ( s · S 1 u ) + ( 1 - p ) ( s · S 1 d ) = b · 𝐄 P ( B 1 ) + s · 𝐄 P ( S 1 ) = b · B 1 + s · 𝐄 P ( S 1 )

用文字描述,预期投资组合收益就是简单地b乘以无风险债券收益加上s乘以预期股票收益。

定义 2×2收益率矩阵,其中

= i r 1 u i r 1 d

对于预期投资组合收益率

𝐄 P ( · ϕ ) = b · 𝐄 P ( i ) + s · 𝐄 P ( r 1 ) = b · i + s · μ

用文字描述,预期的投资组合收益率是b乘以无风险利率,再加上s乘以股票的预期收益率。

下一步是计算投资组合方差

σ 2 ( · ϕ ) = 𝔼 P r-𝐄 P (·ϕ) 2 = p 1 - p , (b·i+s·r 1 u -b·i-s·μ) 2 (b·i+s·r 1 d -b·i-s·μ) 2 = p 1 - p , (s·r 1 u -s·μ) 2 (s·r 1 d -s·μ) 2 = s 2 · σ 2 ( r 1 )

用文字描述,投资组合方差是s 2乘以股票方差,这在直觉上是有意义的,因为债券是无风险的,不应对投资组合方差有贡献。这立即得到了关于投资组合波动率的良好比例结果:

σ ( · ϕ ) = σ 2 ( · ϕ ) = s 2 · σ 2 ( r 1 ) = s · σ ( r 1 )

整个分析在 Python 中实现起来非常直接。首先,一些准备工作:

In [120]: B = (10, np.array((11, 11)))

In [121]: S = (10, np.array((20, 5)))

In [122]: M = np.array((B[1], S[1])).T  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [123]: M  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[123]: array([[11, 20],
                 [11,  5]])

In [124]: M0 = np.array((B[0], S[0]))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [125]: R = M / M0 - 1  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [126]: R  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[126]: array([[ 0.1,  1. ],
                 [ 0.1, -0.5]])

In [127]: P = np.array((0.5, 0.5))  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

1

金融资产的未来价格矩阵。

2

今天金融资产价格的向量。

3

以向量化方式计算回报矩阵。

4

显示计算结果。

5

定义概率测度。

根据这些定义,预期的投资组合回报和波动率被计算为点积:

In [128]: np.dot(P, R)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[128]: array([0.1 , 0.25])

In [129]: s = 0.55  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [130]: phi = (1-s, s)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [131]: mu = np.dot(phi, np.dot(P, R))  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [132]: mu  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[132]: 0.18250000000000005

In [133]: sigma = s * R[:, 1].std()  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [134]: sigma  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[134]: 0.41250000000000003

1

债券和股票的预期回报。

2

股票的例子配置以百分比(小数)。

3

具有标准化权重为 1 的结果投资组合。

4

给定分配后的预期投资组合回报。

5

该值位于无风险回报和股票回报之间。

6

投资组合的波动率;这里的 Python 代码仅适用于p = 0.5。

7

再次,该值位于债券的波动率(= 0)和股票的波动率(= 0.75)之间。

调整投资组合中股票权重会导致不同的风险-回报组合。图 2-5 显示了股票分配s在 0 到 1 之间的预期投资组合回报和波动率。如图所示,预期投资组合回报(从 0.1 到 0.25)和波动率(从 0.0 到 0.75)都随着股票分配s的增加而线性增加:

In [135]: values = np.linspace(0, 1, 25)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [136]: mu = [np.dot(((1-s), s), np.dot(P, R))
                for s in values]  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [137]: sigma = [s * R[:, 1].std() for s in values]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [138]: plt.figure(figsize=(10, 6))
          plt.plot(values, mu, lw = 3.0, label='$\mu_p$')
          plt.plot(values, sigma, '--', lw = 3.0, label='$\sigma_p$')
          plt.legend(loc=0)
          plt.xlabel('$s$');

1

生成一个ndarray对象,在 0 和 1 之间均匀间隔的 24 个区间。

2

values中的每个元素计算预期投资组合回报,并将它们存储在一个list对象中。

3

values中的每个元素计算投资组合波动率,并将其存储在另一个list对象中。

ftwp 0205

图 2-5。不同分配的预期投资组合回报和波动率

注意,在前面的列表推导式sigma = [s * R[:, 1].std() for s in values]中,是以下代码的缩写。

sigma = list()
for s in values:
    sigma.append(s * R[:, 1].std())

在 MVP 环境中看到的典型图形之一是将预期投资组合回报绘制成投资组合波动性的图。图 2-6 显示,投资者可以期待更高的回报,如果他们愿意承担更多风险(波动性)。在本节的特殊情况下,这种关系是线性的:

In [139]: plt.figure(figsize=(10, 6))
          plt.plot(sigma, mu, lw = 3.0, label='risk-return')
          plt.legend(loc=0)
          plt.xlabel('$\sigma_p$')
          plt.ylabel('$\mu_p$');

ftwp 0206

图 2-6. 预期组合的投资组合回报和波动性的可行组合

结论

本章介绍金融,从基础开始,并通过简单的 Python 代码示例说明中心数学对象和金融概念。美妙之处在于,金融的基本思想——如套利定价或风险与回报关系——甚至可以在静态的两状态经济中介绍和理解。具备这种基本理解和一些金融和数学直觉后,过渡到越来越现实的金融模型就会显着简化。例如,随后的章节将第三个未来状态添加到状态空间,讨论在市场不完全性背景下出现的问题。

进一步的资源

本章引用的书籍和论文:

  • Cox, John 和 Stephen Ross。1976 年。《替代随机过程的期权定价》。《金融经济学杂志》(3):145–166。

  • Delbaen, Freddy 和 Walter Schachermayer。2006 年。《套利的数学》。柏林:施普林格出版社。

  • Guidolin, Massimo 和 Francesca Rinaldi。2013 年。《资产定价和投资组合选择中的歧义:文献综述》。《理论与决策》(74):183–217。https://ssrn.com/abstract=1673494

  • Harrison, Michael 和 David Kreps。1979 年。《多期证券市场中的鞅和套利》。《经济理论杂志》(20):381–408。

  • Harrison, Michael 和 Stanley Pliska。1981 年。《连续交易的鞅和随机积分理论》。《随机过程及其应用》(11):215–260。

  • Markowitz, Harry。1952 年。《投资组合选择》。《金融学杂志》7 (1):77–91。

关于资产定价基本定理的详细信息,请参阅 Harrison 和 Kreps(1979)以及 Harrison 和 Pliska(1981)的开创性论文。

在第五章中可以找到对经济概念的更正式处理。

有关 Python 标准数据类型的详细信息,请参阅内置类型文档。

查看随机变量的正式定义,请参阅第五章。

参考数据结构文档了解 Python 中数据结构和理解习语的更多内容。

第三章:三态经济

如果每一个条件性索赔都可以通过某种交易策略生成,则模型被称为完全的。否则,模型被称为不完全的。

Stanley Pliska (1997)

假设个人将任何投资的结果视为概率术语来看待;也就是说,他认为可能的结果可以用某种概率分布来描述。然而,在评估特定投资的可取性时,他只愿意基于该分布的两个参数行动——其期望值和标准偏差。

William Sharpe (1964)

前一章是基于最简单模型经济的,其中可以分析金融不确定性的概念。本章通过增加一个额外状态而使得二态经济稍微丰富化,同时保持交易的金融资产数量恒定为两个。在这种略微丰富的静态三态经济中,讨论了市场不完全性和鞍点测度的不确定性概念。介绍了超复制和近似复制方法以应对不完全性及其对条件性索赔定价的影响。本章还介绍了资本资产定价模型(CAPM),该模型基于均值-方差组合分析,并增加了均衡论点,以推导金融资产在均值-波动率空间中的价格,即使它们无法复制。

本章主要涵盖了金融、数学和 Python 编程中以下几个主题:

金融 数学 Python
不确定性 概率空间 ndarray
金融资产 向量,矩阵 ndarray
可达到的条件性索赔 向量的跨度,向量空间的基 ndarray
鞍点定价,套利 概率测度集合,期望值 ndarray, np.dot
超复制 最小化,约束 scipy.optimize.minimize, dict, lambda
近似复制 均方误差,OLS 回归 np.linalg.lstsq
资本市场线 期望值,标准偏差 NumPy
资本资产定价模型 相关性,协方差 NumPy

如果没有明确说明,前一章节的二态经济的假设和概念可以延续到本章讨论的三态经济中。

不确定性

有两个时间点是相关的,即今天,t = 0,和未来一年后的时间点,t = 1。让状态空间Ω = { u , m , d }给定。{ u , m , d }代表经济可能出现的三种不同状态。幂集在状态空间上给出为:

( Ω ) = , { u } , { m } , { d } , { u , m } , { u , d } , { m , d } , Ω

概率度量P定义在幂集上,并假设P ( ω ) = 1 3 , ω Ω。由此产生的概率空间( Ω , ( Ω ) , P )代表模型经济中的不确定性

金融资产

模型经济中有两种金融资产交易。第一种是无风险债券B = ( B 0 , B 1 ),其中B 0 = 10B 1 = (11,11,11) T。因此,无风险利率为i = 0.1。

第二个是风险股票S = S 0 , (S 1 u ,S 1 m ,S 1 d ) T ,其中 S 0 = 10 和:

S 1 = 20 10 5

定义市场支付矩阵 3×2 如下:

B 1 S 1 u B 1 S 1 m B 1 S 1 d = 11 20 11 10 11 5

可达可实现索赔

交易的金融资产的跨度也被称为可达可实现索赔集合 𝔸 。一个可实现的索赔 C 1 : Ω 0 是指其支付可以表示为交易资产的支付向量的线性组合。换句话说,存在一个投资组合 ϕ 使得 V 1 ( ϕ ) = · ϕ = C 1 。因此

𝔸 = · ϕ , ϕ 2

如果投资组合头寸没有限制,或者

𝔸 = · ϕ , ϕ ≥0 2

如果禁止做空。

很容易验证两种金融资产的支付向量是线性独立的。然而,只有两个这样的向量和三种不同的状态。 根据线性代数的标准结果,需要一个矢量空间 3 的基础由三个线性无关的向量组成。换句话说,并非每一个可达索赔都能通过交易的金融资产的投资组合复制。 一个例子是,例如,第一个 Arrow-Debreu 安全性。 复制的线性方程组是:

b · 11 + s · 20 = 1 b · 11 + s · 10 = 0 b · 11 + s · 5 = 0

从第一个方程式减去第二个方程式得到 s = 1 10 。从第一个方程式减去第三个方程式得到 s = 1 15 ,显然与第一个结果矛盾。因此,这个复制问题没有解决方案。

使用 Python,可以在三维空间中可视化可达的条件索赔集合。该方法基于蒙特卡洛模拟进行投资组合。为简单起见,模拟仅允许在 0 到 1 之间的正面投资组合位置。图 3-1 图形显示了结果,并说明这两个向量只能跨越三维空间的二维区域。如果市场是完整的,模拟的支付向量将填充一个立方体(金融资产将跨越 3 ),而不仅仅是一个矩形区域(跨越 2 )。不确定性建模沿用了 第 2 章 中介绍的 Python 代码,针对经济三种可能的未来状态进行了必要的调整:

In [1]: import numpy as np
        from numpy.random import default_rng
        np.set_printoptions(precision=5, suppress=True)

In [2]: rng = default_rng(100)

In [3]: B = (10, np.array((11, 11, 11)))

In [4]: S = (10, np.array((20, 10, 5)))

In [5]: n = 1000  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [6]: b = rng.random(n)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [7]: b[:5]  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[7]: array([0.83498, 0.59655, 0.28886, 0.04295, 0.97365])

In [8]: s = rng.random(n)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [9]: A = [b[i] * B[1] + s[i] * S[1] for i in range(n)]  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [10]: A = np.array(A)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [11]: A[:3]  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[11]: array([[19.86232, 14.52356, 11.85418],
                [26.35796, 16.46003, 11.51106],
                [11.64939,  7.41344,  5.29547]])

In [12]: from pylab import mpl, plt   ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
         plt.style.use('seaborn')
         mpl.rcParams['savefig.dpi'] = 300
         mpl.rcParams['font.family'] = 'serif'
         from mpl_toolkits.mplot3d import Axes3D  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [13]: fig = plt.figure(figsize=(10, 6))  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
         ax = fig.add_subplot(111, projection='3d')  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
         ax.scatter(A[:, 0], A[:, 1], A[:, 2], c='r', marker='.');  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)

1

需要模拟的投资组合数量。

2

在债券中的随机位置,这里列出了一些示例—所有位置值都介于 0 到 1 之间。

3

在股票中的随机位置。

4

一个 list 推导式,用于计算随机组合投资组合的结果支付向量。

5

matplotlib 的基本绘图子包。

6

三维绘图能力。

7

创建一个空画布。

8

添加一个三维对象的子图。

9

将支付向量可视化为每个红点。

市场不完备性

在完整模型经济中,每一个条件索赔都是可达的,但在不完全市场中,通常只有小部分条件索赔是可达的。在这个意义上,从完全模型经济转变为不完全模型经济具有巨大的后果。复制定价,正如 第 2 章 中介绍的那样,依赖于条件索赔的可达性。那么,当复制失败时如何定价?在本章的其余部分回答了这些问题及其他相关问题。

ftwp 0301

图 3-1。在三维中可视化的随机投资组合收益向量

马丁格尔定价

从资产定价的第一基本定理(1FTAP)和第二基本定理(2FTAP)清楚地可以看出马丁格尔测度的重要性。

马丁格尔测度

任何概率测度都使得折现债券价格过程成为马丁格尔过程。那么股票价格过程呢?马丁格尔测度Q:(Ω) ≥0的定义方程是:

S 0 · ( 1 + i ) = 𝐄 Q ( S 1 )

或者

S 0 · ( 1 + i ) = q u · S 1 u + q m · S 1 m + q d · S 1 d

q ω Q ( ω ) , ω Ω 。用数字和q d = 1 - q u - q m表示:

11 = q u · 20 + q m · 10 + ( 1 - q u - q m ) · 5 q m = 6-15·q u 5

回顾概率测度的性质,必须成立(约束条件)

6 - 15 · q u 0 q u 2 5

和(非约束条件)

6-15·q u 5 1 q u 1 15

以及(约束条件)

q d = 1 - q u - q m 0 q u 1 10

和(非约束条件)

q d = 1 - q u - q m 1 q u 3 5

因此,存在无穷多个概率测度使得折现股票价格过程成为马丁格尔过程。设置q q u,与市场模型一致的所有马丁格尔测度的集合是:

= q 6-15·q 5 1 - q - 6-15·q 5 , 1 10 q 2 5

举例来说,取q = 3 10。结果是

Q q = 3 10 = 3 10 6-15·3 10 5 1 - 3 10 - 3 10 = 3 10 3 10 4 10

3 10 · 20 + 3 10 · 10 + 4 10 · 5 = 11

作为股票价格过程的期望。

根据之前的规范,Python 中的计算如下所示:

In [14]: Q = np.array((0.3, 0.3, 0.4))

In [15]: np.dot(Q, S[1])
Out[15]: 11.0

根据第二基本定理,市场模型是不完全的,因为有不止一个与市场模型一致的马丁格尔测度。

不完全市场中的马丁格尔测度

完全市场模型的特征是具有唯一的马丁格尔测度。相比之下,不完全市场模型通常允许与模型经济一致的无穷多个马丁格尔测度。这对于衍生品的定价具有重要的后果,因为不同的马丁格尔测度将导致衍生品的不同价值,这些价值都与无套利的存在一致。

风险中性定价

无限数量的市场一致鞅测度对套期权定价的影响是什么?首先,对于那些可达到的套期权,𝔸,套利定价类似于完全市场设置:复制投资组合的价值等于要复制的套期权的价格 — 否则存在套利机会。形式上,如果V₀(ϕ)等于C₀,则C₀等于V₀(ϕ)

对于那些不可达到的套期权,如果C₁ ∈ 𝔸̅ = ℝ³ \ 𝔸,答案并不简单。假设第一个 Arrow-Debreu 证券γᵘ。正如之前所示,它不能被复制,因此属于集合𝔸̅。它的鞅价格是:

γ 0 u ( q ) = 1 1+i · 𝔼 Q (1,0,0) T = 1 1+i · q

数量γ₀ᵘᵦ通常称为在状态ω ∈ Ω中一单位货币的状态价格。它简单地是该状态的折现鞅概率。

在模型经济中,必须保持1/10 ≤ q ≤ 2/5,因此避免套利机会的鞅价格位于区间内:

10 11 · 1 10 = 1 11 γ 0 u 10 11 · 2 5 = 4 11

简言之,对于第一个 Arrow-Debreu 证券,介于1/114/11之间的每个价格都与消除套利的假设一致。对于不可达到的其他套期权的计算导致类似的结果。

超复制

复制不仅在定价背景下很重要。它还是处理由于不确定权利要求支付而导致的风险的方法。考虑一个任意可达到的权利要求。除了持有权利要求之外,还可以卖空复制组合,以消除任何来自未来支付不确定性的风险。这是因为权利要求和复制组合的支付完美地互相抵消。形式上,如果组合 ϕ * 复制权利要求 C 1 ,则

C 1 - V 1 ( ϕ ) = C 1 - · ϕ = 0

对于不可达到的权利要求,这样一个完美的对冲是不可用的。但是,总是可以构造一个组合来超复制这样一个权利要求的支付。一个组合 ϕ 超复制一个权利要求 C 1 ,如果它在经济的每一个未来状态下的支付都大于或等于权利要求的支付 V 1 ( ϕ ) C 1

再次考虑第一个 Arrow-Debreu 证券 γ u ,它是不可达到的。例如,可以通过仅包含无风险债券的组合来超复制其支付:

ϕ = 1 B 1 ,0 T

结果的支付是

V 1 ( ϕ ) = 1 B 1 · B 1 B 1 B 1 = 1 1 1 1 0 0 = C 1

其中 符号是逐元理解的。虽然这满足超复制的定义,但在设置超复制组合的成本方面可能不是最佳选择。因此,一般引入了成本最小化的论证。

一个权利要求 C 1最小成本超复制问题是:

min ϕ V 0 ( ϕ ) s.t. V 1 ( ϕ ) C 1

或者

min b,s b · B 0 + s · S 0 s.t. b · B 1 + s · S 1 u C 1 u b · B 1 + s · S 1 m C 1 m b · B 1 + s · S 1 d C 1 d

当使用 SciPy 包时,这种最小化问题可以在 Python 中直接建模和求解。以下代码首先计算了仅使用债券的低效超复制组合的成本。然后定义了一个组合的价值函数。它还说明了替代的组合构成确实可以更加成本有效:

In [16]: C1 = np.array((1, 0, 0))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [17]: 1 / B[1][0] * B[1] >= C1  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[17]: array([ True,  True,  True])

In [18]: 1 / B[1][0] * B[0]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[18]: 0.9090909090909092

In [19]: def V(phi, t):  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
             return phi[0] * B[t] + phi[1] * S[t]

In [20]: phi = np.array((0.04, 0.03))  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [21]: V(phi, 0)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[21]: 0.7

In [22]: V(phi, 1)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[22]: array([1.04, 0.74, 0.59])

1

权利要求的支付(第一个 Arrow-Debreu 证券)。

2

仅包含债券的组合已经检查了超复制特性。

3

设置这个组合的成本。

4

一个用于计算投资组合phi在今天(t=0)或一年后(t=1)价值的函数。

5

另一个用于超复制投资组合的猜测。

6

设置它的成本,比仅使用债券要低。

7

和一年后的结果值(回报),它超复制了第一个阿罗-德布鲁证券。

代码的第二部分以向量化的方式实现基于先前不等式约束的最小化程序。成本最优的超复制投资组合比仅使用债券或已经更有效的包括债券和股票的投资组合要便宜得多:

In [23]: from scipy.optimize import minimize  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [24]: cons = ({'type': 'ineq', 'fun': lambda phi: V(phi, 1) - C1})  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [25]: res = minimize(lambda phi: V(phi, 0),  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
                        (0.01, 0.01),  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
                        method='SLSQP',  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
                        constraints=cons)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [26]: res  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[26]:      fun: 0.3636363636310989
              jac: array([10., 10.])
          message: 'Optimization terminated successfully'
             nfev: 6
              nit: 2
             njev: 2
           status: 0
          success: True
                x: array([-0.0303 ,  0.06667])

In [27]: V(res['x'], 0)  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[27]: 0.3636363636310989

In [28]: V(res['x'], 1)  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
Out[28]: array([ 1.     ,  0.33333, -0.     ])

1

scipy.optimize中导入minimize函数。

2

以向量化方式定义基于lambda(或匿名)函数的不等式约束;这里建模的函数λλ ( ϕ ) = V 1 ( ϕ ) - C 1,对应的不等式约束λ ( ϕ ) 0必须成立。

3

要最小化的函数也是一个lambda函数。

4

最优解的初始猜测(这里不太重要)。

5

用于最小化的方法,在这里是顺序最小二乘编程(SLSQP)。

6

之前定义的最小化问题的约束。

7

从最小化中获得的完整结果字典,最优参数在x下,最小函数值在fun下。

8

今天最优超复制投资组合的价值。

9

未来最优超复制投资组合的不确定价值;卖空债券并买入股票的最优投资组合在两种状态下恰好复制相关的回报,并且在中间状态下仅超复制。

近似复制

超复制假设了一种有些极端的情况:有条件索赔的回报必须在任何情况下达到或超过。在实践中可以看到这种情况,例如,当寿险公司投资以满足在所有情况下(这通常在现实世界中转化为“以 99.9%的概率”)其未来的债务和义务(有条件索赔)。然而,在许多情况下,这可能不是一个经济上合理或甚至可行的选择。

这就是近似发挥作用的地方。其思想是在给定一个客观函数的情况下尽可能地复制一个有条件索赔的回报。然后,问题就变成了在给定交易金融资产的情况下最小化复制误差

一个可能作为客观函数或误差函数的候选是均方误差(MSE)。设 V 1 ( ϕ ) 为在给定复制投资组合 ϕ 的情况下的值向量。对于给定投资组合 ϕ 的有条件索赔 C 1,MSE 是:

M S E ( V 1 ( ϕ ) - C 1 ) = 1 |Ω| ωΩ (V 1 ω (ϕ)-C 1 ω ) 2

这是要最小化的量。对于可达到的有条件索赔,MSE 为零。问题本身以矩阵形式是:

min ϕ M S E ( · ϕ - C 1 )

在线性代数中,这是一种属于普通最小二乘回归(OLS 回归)问题的问题。前一个问题是线性OLS 回归问题的特例。

NumPy 提供了函数 np.linalg.lstsq,以标准化和高效的方式解决这类问题:

In [29]: M = np.array((B[1], S[1])).T  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [30]: M  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[30]: array([[11, 20],
                [11, 10],
                [11,  5]])

In [31]: reg = np.linalg.lstsq(M, C1, rcond=-1)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [32]: reg
         # (array, ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
         #  array, ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
         #  int, ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
         #  array) ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[32]: (array([-0.04545,  0.07143]), array([0.07143]), 2, array([28.93836,
          7.11136]))

In [33]: V(reg[0], 0)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[33]: 0.2597402597402598

In [34]: V(reg[0], 1)  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[34]: array([ 0.92857,  0.21429, -0.14286])

In [35]: V(reg[0], 1) - C1  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
Out[35]: array([-0.07143,  0.21429, -0.14286])

In [36]: np.mean((V(reg[0], 1) - C1) ** 2)  ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)
Out[36]: 0.02380952380952381

1

两个交易金融资产的未来价格矩阵。

2

这通过最小化 MSE 来解决线性 OLS 回归问题。

3

最优投资组合位置,即问题的解决方案。

4

来自优化过程的 MSE(最小均方复制误差)。

5

矩阵 M 的秩…

6

...及其奇异值。

7

近似投资组合的价值(低于成本最小化投资组合的价值)。

8

近似复制的回报。

9

复制误差的向量。

10

来自近似复制的 MSE。

在所有情况下,近似复制可能并非适用。但是,有自主决策权的投资者或财务经理可以决定,近似值已经足够好。例如,在可能被认为是超级复制成本过高的情况下,可以做出这样的决定。

资本市场线

假设是均值-方差或者更确切地说是均值-波动率的背景。在接下来的内容中,风险股票被解释为市场组合。人们可以将市场组合看作是广泛的股票指数,如标准普尔 500 股票指数。

正如以前一样,代理人可以组成由债券和市场组合组成的投资组合。债券的回报率—无风险利率—是 i = 0.1,波动率为 0。市场组合的预期回报率为:

μ S = 𝐄 P (S 1 ) S 0 - 1 = 7 6 - 1 = 1 6

它的波动性为:

σ S = 𝐄 P S 1 -S 0 S 0 -μ S 2

在 Python 中进行快速计算,可以得到相应的数值:

In [37]: mu_S = 7 / 6 - 1  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [38]: mu_S  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[38]: 0.16666666666666674

In [39]: sigma_S = (S[1] / S[0]).std()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [40]: sigma_S  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[40]: 0.6236095644623235

1

市场组合的预期回报。

2

市场组合回报的波动率。¹

具有总权重为 1 或 100%的归一化投资组合的可行均值为债券和市场组合,而没有卖空,从 0 到约 0.166。就波动性而言,可能的值介于 0 到约 0.623 之间。

考虑到可以进行卖空,图 3-2 显示出由不同的投资组合组成的资本市场线(CML)。因为允许对债券进行卖空,可以在上升线(具有正斜率)上实现风险和回报的组合,这通常被称为资本市场线。下降线(具有负斜率)原则上无关紧要,因为这些投资组合源于市场组合的空头头寸,在相同的风险下具有较低的预期回报,这是该图表的组成部分:

In [41]: s = np.linspace(-2, 2, 25)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [42]: b = (1 - s)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [43]: i = 0.1  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [44]: mu = b * i + s * mu_S  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [45]: sigma = np.abs(s * sigma_S)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [46]: plt.figure(figsize=(10, 6))
         plt.plot(sigma, mu)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
         plt.xlabel('$\sigma$')
         plt.ylabel('$\mu$');

1

市场组合的仓位取值范围在–200%到 200%之间。

2

债券组合的仓位填满了 100%的总投资组合权重。

3

无风险利率。

4

投资组合的预期回报。

5

投资组合的预期波动率值。

6

绘制市场组合的短头寸和多头寸的 CML。

ftwp 0302

图 3-2. 资本市场线(上升部分)

描述(上升部分的)CML 的方程式为:

μ = i + μ S -i σ S · σ

资本资产定价模型

资本资产定价模型(CAPM),由 Sharpe(1964 年)首创,是一个均衡定价模型,主要是关联任意金融资产或投资组合的预期收益率及其波动性与市场组合的预期收益率和波动性。

此外,金融资产的收益率与市场组合的相关性是重要的。除了市场组合外,考虑另一个风险金融资产,其价格过程为T = ( T 0 , T 1 ) 。相关性ρ 的定义为:

ρ ST = 𝐄 P (r 1 S -μ S )·(r 1 T -μ T ) σ S ·σ T

如果相关性为- 1 ρ ST 1 ,那么两个金融资产有同向移动的趋势。如果是负的,则金融资产有相反方向的移动趋势。在完美正相关的特殊情况下,ρ ST = 1 ,两个金融资产始终同向移动。例如,对于位于 CML 上的投资组合,其回报率仅仅是市场组合回报率按市场组合权重缩放的回报率。在这种情况下,不确定性仅仅来自市场组合部分,因此任何风险的变化都是由市场组合权重变化引起的。

考虑一个金融资产T的情况,它是市场组合的一部分,并且其与市场组合的相关性不会是完美的。对于这样的金融资产,预期收益率由以下给出:

μ T = i + (μ S -i)·ρ ST σ S · σ T = i + ρ ST ·σ S ·σ T σ S 2 · ( μ S - i )

确定证券组合和债券之间的相关性为零是容易的,以致于以前的关系给出了无风险利率,即财务资产T的预期回报。

S 1T 1 之间的 协方差 定义为 σ ST = ρ ST · σ S · σ T,如下所示

μ T = i + σ ST σ S 2 · ( μ S - i ) = i + β T · ( μ S - i )

其中

β T σ ST σ S 2

这给出了著名的 CAPM 线性关系,即市场投资组合的预期收益率与金融资产 T 的预期回报之间的关系,或者任何其他金融资产。从这个意义上讲,CAPM 表明,任何金融资产的回报率仅由市场投资组合超过无风险利率的预期超额回报和贝塔因子决定,贝塔因子是两者之间的协方差,按市场投资组合波动率的平方(收益的方差)进行缩放。

对于 CAPM,CML 被 证券市场线(SML)替代,在 beta-收益空间中绘制如下。图示在 图 3-3 中给出:

In [47]: beta = np.linspace(0, 2, 25)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [48]: mu = i + beta * (mu_S - i)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [49]: plt.figure(figsize=(10, 6))
         plt.plot(beta, mu, label='security market line')  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
         plt.xlabel('$\\beta$')
         plt.ylabel('$\mu$')
         plt.ylim(0, 0.25)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
         plt.plot(1, mu_S, 'ro', label='market portfolio')  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
         plt.legend(loc=0);

1

生成一个带有 beta 值的 ndarray 对象。

2

根据 CAPM 计算预期收益 mu

3

绘制 beta-mu 组合。

4

调整 y 轴的限制。

5

绘制 beta 和市场投资组合的预期回报。

ftwp 0303

图 3-3. 证券市场线

但是,为什么上述关系—特别是 CAPM 公式—首先成立?要回答这个问题,请考虑一个投资组合,其金融资产 T 的标准化权重为 1 或 100%,其中比例 a 投资于金融资产 T,余下的 1 - a 投资于市场投资组合。这一投资组合的预期收益率为:

μ ( a ) = a · μ T + ( 1 - a ) · μ S

投资组合的波动率为(见 Sharpe (1964)):

σ ( a ) = a 2 ·σ T 2 +(1-a) 2 ·σ S 2 +2·a·(1-a)·σ ST 1 2

给定金融资产 T 分配的边际变化,预期投资组合收益率的边际变化由以下偏导数确定:

μ a = μ T - μ S

给定金融资产 T 分配的边际变化,投资组合波动率的边际变化由以下偏导数确定:

σ a = a·σ T 2 -σ S 2 +a·σ S 2 +σ ST -2·a·σ ST a 2 ·σ T 2 +(1-a) 2 ·σ S 2 +2·a·(1-a)·σ ST

CAPM 作为均衡模型的基本见解是金融资产T已经是市场组合的一部分。因此,a只能被解释为对金融资产的超额需求,在均衡状态下,当所有金融资产的超额需求都为零时,a也必须等于零。因此,在均衡状态下,预期组合收益率的偏导数保持不变,而在均衡点a = 0评估时,组合波动率的偏导数显著简化:

σ a a=0 = 1 2 σ S · - 2 · σ S 2 + 2 · σ ST = σ S · σ ST - σ S · σ S 2 = σ ST -σ S 2 σ S

市场均衡下的风险-收益权衡因此是:

μ a σ a a=0 = μ T -μ S σ ST -σ S 2 σ S

推导出前述CAPM 公式所需的最终见解是,在均衡状态下,前述项需要等于 CML 的斜率:

μ T -μ S σ ST -σ S 2 σ S = μ S -i σ S μ T = i + σ ST σ S 2 · ( μ S - i ) = i + β T · ( μ S - i )

CAPM 如何帮助定价不能复制的金融资产?鉴于一年后金融资产T 1的不确定价格向量,不确定收益率为

r T = T 1 -T 0 T 0

其中T 0是今天需要确定的均衡价格。以下关系也成立:

μ T = 𝐄 P (T 1 )-T 0 T 0

现在将单位风险价格定义为市场组合每单位方差的超额回报

λ = μ S -i σ S 2

因此,根据 CAPM,可以得出

μ T = i + λ · σ ST

这表明在均衡状态下,金融资产的预期收益率仅由其与市场组合的协方差决定。将其与金融资产T的预期收益率的前一项相等,得到

𝐄 P (T 1 )-T 0 T 0 = i + λ · σ ST T 0 = 𝐄 P (T 1 ) 1+i+λ·σ ST

分母也可以看作是风险调整贴现因子

MVP、CAPM 和市场完备性

MVP 和 CAPM 都仅依赖于高级统计数据,如期望值、波动性和协方差。例如,当复制有条件权利时,每个可能未来状态中的每个支付都起重要作用—因市场不完备而导致的证明后果。在 MVP 和 CAPM 的背景下,假设投资者只关心总体统计数据而不是每个单独状态。

考虑两个初始价格相同的金融资产的例子,在相等概率测度下,一个金融资产在一种状态下支付 20 货币单位,其他状态下不支付,另一个金融资产在另一种状态下支付与其他金融资产相同的 20 货币单位,其他状态下不支付。这两种金融资产具有相同的风险-收益特征。然而,一个代理可能强烈偏好其中一个,与它们的总体统计数据相同无关。专注于风险和收益通常是方便的简化,但并不总是适当的。

结论

本章的主要内容是不完全的金融市场。从一个两状态模型经济转移到一个具有三状态的模型,并且保持交易金融资产的数量恒定为两个,立即导致市场不完全性。这反过来意味着条件性索赔通常不能通过由无风险债券和风险股票组成的投资组合完全复制。

但是,如果必须在所有情况下满足或超过,则可以对条件性索赔的回报进行超级复制。虽然一般情况下存在无限多个这样的超级复制投资组合,但通常要求选择成本最低的投资组合。如果有更多的灵活性,也可以近似地实现不可实现的条件性索赔的回报。在这种情况下,复制问题被替换为优化问题,根据该问题,复制投资组合的均方误差被最小化。从数学上讲,这归结为线性 OLS 回归问题。

CAPM 基于均衡定价论证来推导预期收益率,同时也给出了在平均-波动率空间中的交易金融资产的价格,考虑了它们的风险-回报特征。相关性和金融资产与市场组合的协方差起着核心作用,假定市场组合包含金融资产本身。

更多资源

本章引用的文章和书籍:

  • Pliska, Stanley. 1997. 数学金融导论. Malden 和 Oxford: Blackwell 出版社。

  • Sharpe, William. 1964. “资本资产价格:在风险条件下市场均衡理论。” 财经杂志 19 (3): 425–442。

¹ 请注意,由于假设三种状态的等概率,因此这种波动性计算仅在这种情况下有效。

第四章:优化与均衡

经济理论的大部分基于这样一个前提:在给定两个选择时,一个代理人可以,并且如果能够的话,会选择更喜欢的一个。

达雷尔·达菲(1988)

投资组合分析始于个别证券的信息,以整体投资组合的结论结束。分析的目的是找到最能满足投资者目标的投资组合。

哈里·马尔科维茨(1959)

本章主要讨论代理人及其优化问题的建模。它呈现了微观经济理论(见 Varian(1992))和金融经济学(见 Eichberger 和 Harper(1997))的一些基本构建模块。本章的核心是预期效用最大化范式,这是在金融经济学中建模代理人偏好的主要方式。基于这一范式,讨论了两个核心主题。

首先,我们讨论了在给定偏好和初始财富的情况下,一个代理人如何选择最佳投资组合。这种类型的问题通常被称为最优投资组合选择。这里提出的方法不依赖于任何形式的简化,例如,不像均值-方差组合(MVP)方法和资本资产定价模型(CAPM)那样,它将选择投资组合的问题简化为金融资产收益分布的一阶和二阶矩以及它们的协方差。

其次,在前两章中,金融资产的价格是事先给定的,而本章从基本原理推导它们,分析了基于所谓代表性代理人的优化问题的金融资产定价,以及均衡论证。粗略地说,代表性代理人可以被视为在(金融)市场中独立行动的(无限)多个代理人的聚合体。这种代表性代理人的存在条件是众所周知的(见 Milne(1995)第六章)——然而,本章并未讨论这些条件,因为一般的金融理论只是假定其存在。

本章主要涵盖了金融、数学和 Python 编程中的以下主题。在 Python 方面,并未引入太多新元素。在离散模型中进行金融的基本数学和 Python 工具集已在前两章中引入和发展:

金融 数学 Python
偏好和效用 效用函数 NumPy
效用最大化 目标函数,预算约束,拉格朗日定理 scipy.optimize.minimize
无差异曲线,预算线 函数 NumPy, matplotlib
对数效用 自然对数 NumPy, matplotlib
时间加法效用 效用函数 NumPy, scipy.optimize.minimize
(时间加法)期望效用 概率测度,拉格朗日定理 NumPy, scipy.optimize.minimize
最优投资组合 拉格朗日定理,一阶条件 NumPy, scipy.optimize.minimize
市场均衡定价,代理人 拉格朗日定理,一阶条件 NumPy, scipy.optimize.minimize, SymPy
不完全市场中的鞅测度 概率测度集合 SymPy, sy.Symbol, sy.solve
通过有条件索赔完成市场 拉格朗日定理,一阶条件 NumPy, scipy.optimize.minimize

效用最大化

形式上,代理人通过 效用函数 进行建模,该函数对代理人面临的一系列选择进行排序,是代理人 偏好 的一种表现(参见 Varian (1992) 第七章)。考虑到没有来自第二章的不确定性的静态经济。此外,假设代理人被赋予一些初始财富, w >0 。代理人可以决定今天花费这些财富的多少, t = 0 ,以及通过银行存款储蓄多少用于未来消费。可以把一个代理人看作是面临如何为退休储蓄的问题。

代理人根据今天的货币效用 c 0 和一年后的效用 c 1 接收效用函数:

U : ≥0 2 ≥0 , ( c 0 , c 1 ) u ( c 0 , c 1 )

例如,假设 u ( c 0 , c 1 ) = c 0 · c 1 —表达了今天和一年后的金钱是替代品的想法,尽管不是完美的替代品(如果其中一个为零,效用也为零)。代理人的受限优化问题形式上为:

max c 0 ,c 1 c 0 · c 1 s.t. c 0 + c 1 = w

根据拉格朗日定理(参见 Sundaram (1996) 第五章),受限优化问题可以转化为以下形式的无约束问题:

max c 0 ,c 1 ,λ f ( c 0 , c 1 , λ ) = c 0 · c 1 - λ · ( c 0 + c 1 - w )

优化的一阶必要条件是:

f c 0 = c 1 - λ = 0 f c 1 = c 0 - λ = 0 f λ = c 0 + c 1 - w = 0

从这些中,可以很容易地推导出 c 0 = c 1 = w 2 作为最佳的消费储蓄计划。

这个优化问题可以在 Python 中进行数值建模和求解,其中应满足 w = 10

In [1]: def u(c):
            return -c[0] * c[1]  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [2]: w = 10  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [3]: from scipy.optimize import minimize

In [4]: cons = ({'type': 'eq', 'fun': lambda c: c[0] + c[1] - w})  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [5]: opt = minimize(u, (1, 1), constraints=cons)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [6]: opt
Out[6]:      fun: -24.999999999999996
             jac: array([-5., -5.])
         message: 'Optimization terminated successfully'
            nfev: 6
             nit: 2
            njev: 2
          status: 0
         success: True
               x: array([5., 5.])

In [7]: opt['x']  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[7]: array([5., 5.])

In [8]: -opt['fun']   ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[8]: 24.999999999999996

1

具有负号的效用函数,以通过最小化实现最大化。

2

代理人的初始财富,在今天和未来之间分配。

3

预算约束作为 minimize 函数的等式约束。

4

具有初始猜测和预算约束的优化。

5

最优消费储蓄计划。

6

通过最优计划获得的最大效用。

无差异曲线

前一节的最优解可以通过 无差异曲线 的方式可视化。无差异曲线由所有这样的组合 c = ( c 0 , c 1 ) 组成,它们给出相同的效用 u ¯。在 ( c 0 , c 1 ) 空间中描述这样一条曲线的方程式是:

u ¯ = c 0 · c 1 c 1 = u ¯ c 0

描述 预算约束 的方程式是:

w = c 0 + c 1 c 1 = w - c 0

在 图 4-1 中可视化了优化问题,其中最优计划由点给出 — 这是 u ¯ = 25 的无差异曲线与表示预算约束线相切的地方。

在 Python 中,这被转化为以下代码:

In [9]: def iu(u, c0):
            return u / c0  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [10]: def c1(c0):
             return w - c0  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [11]: import numpy as np
         np.set_printoptions(precision=5)

In [12]: from pylab import mpl, plt
         plt.style.use('seaborn')
         mpl.rcParams['savefig.dpi'] = 300
         mpl.rcParams['font.family'] = 'serif'

In [13]: c0 = np.linspace(1, w)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [14]: plt.figure(figsize=(10, 6))
         plt.plot(c0, c1(c0), label='budget constraint', lw=3.0)
         plt.plot(c0, iu(15, c0), '--', label='$u=15$')
         plt.plot(c0, iu(25, c0), label='$u=25$')
         plt.plot(c0, iu(35, c0), '-.', label='$u=35$')
         plt.plot(opt['x'][0], opt['x'][1], 'ro', label='$c=(5, 5)$')
         plt.legend(loc=0);

1

无差异曲线函数。

2

预算线函数。

3

绘制两者的域。

ftwp 0401

图 4-1. 最优化问题

适当的效用函数

在金融中,代理人从其在某一特定时间点可用的资金中获得的效用 — 作为可以用该资金购买的任何其他实际资产的替代物 — 通常表示为函数 u: ≥0 ,假定满足三个条件:

  1. u ( x ) 具有两次可微性

  2. du dx > 0

  3. d 2 u dx 2 0

第一个条件是其他两个的技术前提条件。第二个条件形式化了更多的金钱——其他条件相等——比更少的金钱更好的想法。假设代理人是不知足的。第三个条件规定,从额外的一单位货币获得的边际效用比之前的边际单位货币的边际效用要小(或在最大值时相同)。因此,该函数被假定为递增的和(准)凹的。

对数效用

这一部分介绍了一种非常适合基于效用最大化代理的金融分析的函数类型。这样一个函数——满足上一节的三个条件,并且在金融领域中经常用于模拟代理从金钱(或消费)中获得的效用——就是自然对数 u ( x ) = ln x 。对于它,可以得到:

  1. du dx = 1 x > 0 for x >0

  2. d 2 u dx 2 = - 1 x 2 < 0 对于 x >0

Python 允许我们可视化这三个相关函数。NumPy与向量化计算结合使用。图 4-2 展示了以下代码生成的图形:

In [15]: x = np.linspace(0.5, 10, 50)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [16]: x[:5]  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[16]: array([0.5    , 0.69388, 0.88776, 1.08163, 1.27551])

In [17]: u = np.log(x)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [18]: u1 = 1 / x  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [19]: u2 = -1 / x ** 2  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [20]: plt.figure(figsize=(10, 6))  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
         plt.plot(x, u, label='$u$')  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
         plt.plot(x, u1, '--', label='$du/dx$')  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
         plt.plot(x, u2, '-.', label='$d²u/dx²$')  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
         plt.legend(loc=0);  ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)

1

创建一个包含从 0.5 到 10 之间的浮点数,并且均匀间隔的ndarray对象,以获得 50 个值。

2

展示了所得到的数字的一部分选择。

3

计算效用函数的值。

4

以及其一阶导数……

5

…对其二阶导数。

6

创建一个新的绘图画布,并提供大小参数。

7

绘制效用函数。

8

绘制一阶导数。

9

绘制第二导数。

10

在最佳位置放置图例 (loc=0)。

ftwp 0402

图 4-2. 自然对数函数及其一阶和二阶导数

时间加性效用

使用自然对数作为函数来模拟代理人对于货币的效用,代理人对于消费-储蓄计划 c = ( c 0 , c 1 ) 的偏好可以描述为以下形式的时间加性函数:

U : ≥0 2 , ( c 0 , c 1 ) ln c 0 + κ · ln c 1

κ ≥0 假定取值 0 < κ 1 ,代表代理人的时间偏好。它体现了今天的金钱和消费比一年后更受重视的观念。至少在弱意义上,100 美元现在比一年后的 100 美元更受欢迎——无论哪种确切的函数描述了随时间的一致偏好(假设随时间偏好的一致性)。它可以被视为一种非货币折现因子。可以轻松验证该函数满足前述的三个条件——它是二次可微的、增加的和凹的——基于对 c 0c 1 的偏导数。

如果代理人的初始财富为 w ,他们的约束优化问题是:

max c 0 ,c 1 ln c 0 + κ · ln c 1 s.t. c 0 + c 1 = w

max c 0 ,c 1 ,λ f ( c 0 , c 1 , λ ) = ln c 0 + κ · ln c 1 - λ · ( c 0 + c 1 - w )

最优性的一阶必要条件是:

f c 0 = 1 c 0 - λ = 0 f c 1 = κ · 1 c 1 - λ = 0 f λ = c 0 + c 1 - w = 0

由此可得:

1 c 0 = κ · 1 c 1 c 1 = κ · c 0

现在的最优消费储蓄计划反映了时间偏好,即一年内的消费 c 1 设置为 κ · c 0 。还有

c 0 + κ · c 0 = w c 0 = w 1+κ

w 1+κ + c 1 = w c 1 = κ·w 1+κ

预算约束是紧绷的:

w 1+κ + κ·w 1+κ = w+κ·w 1+κ = w

下面的代码通过数值方法解决了优化问题,其中 w = 10 。最优计划反映了时间偏好:

In [21]: import math

In [22]: from scipy.optimize import minimize

In [23]: kappa = 10 / 11

In [24]: def U(c):
             return -(math.log(c[0]) +  kappa * math.log(c[1]))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [25]: w = 10

In [26]: cons = ({'type': 'eq', 'fun': lambda c: c[0] + c[1] - w})  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [27]: opt = minimize(U, (1, 1), constraints=cons)

In [28]: opt
Out[28]:      fun: -3.0747286083026886
              jac: array([-0.19091, -0.19091])
          message: 'Optimization terminated successfully'
             nfev: 18
              nit: 6
             njev: 6
           status: 0
          success: True
                x: array([5.23811, 4.76189])

In [29]: opt['x']  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[29]: array([5.23811, 4.76189])

In [30]: -opt['fun']  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[30]: 3.0747286083026886

1

为了通过最小化来实现最大化,效用函数带有负号。

2

预算约束作为 minimize 函数的等式约束。

3

最优消费储蓄计划反映了时间偏好,其中c 0c 1高出 10%。

4

通过最优计划获得的最大效用。¹

期望效用

现在考虑静态的两状态经济体不确定性。假设一个代理人在一年后只通过在那时可能存在的两种状态中的一种状态中可用的资金来获得效用。这将代表一个纯投资问题,其中所有可用的初始财富将被最优地投资于交易的金融资产中。

假设交易两种金融资产,一个无风险债券的价格过程

B = B 0 , (B 1 ,B 1 ) T

以及风险股票的价格过程

S = S 0 , (S 1 u ,S 1 d ) T

金融资产是将今天的初始财富转移到将来某一时间点的手段。代理人的主要决策问题是决定在未来任一状态中消费什么。

面临不确定性的代理人的投资问题模型由要最大化的代理人的期望效用给出,给定w期望效用函数如下:

U : ≥0 2 , c 1 𝐄 P ( u ( c 1 ) )

价格向量 0 = (B 0 ,S 0 ) T ,代理人可以根据以下方式分配其初始财富:

0 · ϕ = w B 0 · b + S 0 · s = w

其中ϕ=(b,s) T ≥0 2表示代理人组成的包括无风险债券和风险股票在内的投资组合。由于代理人贪得无厌,这预算约束将始终是有效的。不允许进行空头交易。

市场回报矩阵如下:

= B 1 S 1 u B 1 S 1 d

代理人在今后一年中在任何状态下都有多少资金可用?这由代理人选择组成的投资组合决定:

c 1 = · ϕ = B 1 B 1 · b + S 1 u S 1 d · s

这导致

c 1 = b · B 1 + s · S 1 u b · B 1 + s · S 1 d

c 1 u = b · B 1 + s · S 1 u c 1 d = b · B 1 + s · S 1 d

代理人的完整决策问题—关于最优投资组合选择—可以表示为以下受约束优化问题

max c 1 𝐄 P ( u ( c 1 ) ) (i) w = 0 · ϕ (ii) c 1 = · ϕ

或在替代c 1之后

max ϕ 𝐄 P ( u ( · ϕ ) ) w = 0 · ϕ

根据拉格朗日定理,可以将这个问题转化为以下形式的无约束优化问题

max b,s,λ f ( b , s , λ ) = 𝐄 P u ( b · B 1 + s · S 1 ) - λ · ( b · B 0 + s · S 0 - w )

其中代理人选择 bs 在给定预算约束下最大化预期效用。

预期效用理论

几十年来,预期效用理论(EUT)在金融决策中仍然是主导的范式。 其主要假设之一——代理人完全了解可能的未来状态及其概率——在现实中几乎从未得到满足。 然而,对许多人来说,EUT 在理论上很有吸引力,并导致“好”的结果,这些结果通常易于理解和解释。 关于金融中这一核心范式问题的更多信息,请参见 Hilpisch(2020 年,第三章和第四章)。

最优投资组合

预期效用最大化代理人的最优解看起来是什么样的? 一般来说,可以根据必要和充分的一阶条件给出答案:

f b = 0 f s = 0 f λ = 0

或者

f b = p · B 1 · u ' b · B 1 + s · S 1 u + ( 1 - p ) · B 1 · u ' b · B 1 + s · S 1 d - λ · B 0 = 0

f s = p · S 1 u · u ' b · B 1 + s · S 1 u + ( 1 - p ) · S 1 d · u ' b · B 1 + s · S 1 d - λ · S 0 = 0

使用通常的表示法 u ' ( x ) du dx 以及

b · B 0 + s · S 0 = w

假设对数效用和两种交易金融资产的价格过程 B = ( 10 , 11 )S = 10 , (20,5) T ,分别。 对于 w = 10 ,它保持 b + s = 1 使得投资组合头寸表示百分比值。

在 Python 中,scipy.optimize 子包中的 minimize 函数也适用于解决代理人的投资问题:

In [31]: B = (10, (11, 11))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [32]: S = (10, (20, 5))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [33]: M0 = np.array((B[0], S[0]))  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [34]: M = np.array((B[1], S[1])).T  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [35]: p = 0.5  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [36]: P = np.array((p, 1-p))  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [37]: def U(phi):
             c1 = np.dot(M, phi)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
             return -np.dot(P, np.log(c1))  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [38]: -U((1, 0))  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[38]: 2.3978952727983707

In [39]: -U((0, 1))  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[39]: 2.3025850929940455

In [40]: -U((0.5, 0.5))  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[40]: 2.410140782802518

In [41]: w = 10

In [42]: cons = ({'type': 'eq',
                  'fun': lambda phi: np.dot(M0, phi) - w})  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)

In [43]: opt = minimize(U, (1, 1), constraints=cons)  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)

In [44]: opt
Out[44]:      fun: -2.4183062699261972
              jac: array([-1.     , -0.99999])
          message: 'Optimization terminated successfully'
             nfev: 15
              nit: 5
             njev: 5
           status: 0
          success: True
                x: array([0.69442, 0.30558])

In [45]: opt['x']  ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)
Out[45]: array([0.69442, 0.30558])

In [46]: -opt['fun']  ![11](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/11.png)
Out[46]: 2.4183062699261972

In [47]: -U(opt['x'])  ![11](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/11.png)
Out[47]: 2.4183062699261972

In [48]: np.dot(M, opt['x'])  ![12](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/12.png)
Out[48]: array([13.75022,  9.16652])

1

债券价格过程和...

2

…股价过程。

3

两种交易金融资产的价格向量。

4

两种交易金融资产的市场收益矩阵。

5

经济的物理概率测度。

6

具有对数效用的期望效用函数。

7

一些总投资组合权重为 1 的示例值——分散投资是值得的。

8

基于价格和投资组合向量的预算约束。

9

将期望效用最大化问题视为最小化。

10

债券和股票之间的最优配置。

11

最优期望效用值。

12

来自最优投资组合的状态相关支付。

时间加法期望效用

可以将代理人的决策问题制定为包含当天货币效用的问题:

U : R ≥0 × ≥0 , ( c 0 , c 1 ) u ( c 0 ) + κ · 𝐄 P ( u ( c 1 ) )U : R ≥0 × ≥0 , ( c 0 , c 1 ) u ( c 0 ) + κ · 𝐄 P ( u ( c 1 ) )

初始财富w,无约束形式的优化问题如下:

max c 0 ,b,s,λ f ( c 0 , b , s , λ ) = u ( c 0 ) + κ · 𝐄 P u ( b · B 1 + s · S 1 ) - λ · ( c 0 + b · B 0 + s · S 0 - w )

根据前述假设,使用 Python 可以得出最优解如下代码:

In [49]: M0 = np.array((1, B[0], S[0]))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [50]: kappa = 10 / 11  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [51]: def U(phi):
             c0 = phi[0]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
             c1 = np.dot(M, phi[1:])  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
             return -(np.log(c0) + kappa * np.dot(P, np.log(c1)))  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [52]: opt = minimize(U, (1, 1, 1), constraints=cons)

In [53]: opt
Out[53]:      fun: -3.1799295980286093
              jac: array([-0.19088, -1.90932, -1.90974])
          message: 'Optimization terminated successfully'
             nfev: 32
              nit: 8
             njev: 8
           status: 0
          success: True
                x: array([5.23899, 0.33087, 0.14523])

In [54]: -opt['fun']
Out[54]: 3.1799295980286093

In [55]: opt['x'][0]  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[55]: 5.23898714830318

In [56]: np.dot(M, opt['x'][1:])  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[56]: array([6.54422, 4.36571])

1

包括今天消费价格为 1 的价格向量。

2

时间偏好因子。

3

考虑到今天消费和时间偏好的预期效用函数。

4

这是代理从w消费的今天。

5

这是债券和股票头寸的状态相关支付。

完全市场定价

在这一节中,分析基于优化原则转变为定价设置。假设两个 Arrow-Debreu 证券在经济中交易,有两个未来状态,两者的净供应都为一。两个支付向量形成 2标准基,市场支付矩阵为:

= 1 0 0 1

现在假设经济中存在一个代表性代理,这个代理是唯一交易这两种证券的人。在均衡中,代表性代理需要持有两种证券的净供应量,因为没有其他人。确保均衡的机制是今天两种证券的价格,即价格向量:

0 = (γ u ,γ d ) T ≥0 2

平衡定价的理念是,这个价格向量需要调整,以便代表性代理持有所有可用金融资产的净供应量。因为否则就不会有均衡。

通过投资组合ϕ = ϕ u ,ϕ d T,最大化预期效用的代表性代理问题是

max ϕ 𝐄 P ( u ( · ϕ ) ) s.t. 0 · ϕ = w

max ϕ,λ 𝐄 P ( u ( · ϕ ) ) - λ · ( 0 · ϕ - w )

由于特殊的市场支付矩阵,这转化为

max ϕ u ,ϕ d p · u ϕ u + ( 1 - p ) · u ϕ d s.t. γ u · ϕ u + γ d · ϕ d = w

max ϕ u ,ϕ d ,λ f ( ϕ u , ϕ d , λ ) = p · u ϕ u + ( 1 - p ) · u ϕ d - λ · γ u · ϕ u + γ d · ϕ d - w

无约束问题的三个一阶条件为:

f ϕ u = p · u ' ( ϕ u ) - λ · γ u = 0 f ϕ d = ( 1 - p ) · u ' ( ϕ d ) - λ · γ d = 0 f λ = γ u · ϕ u + γ d · ϕ d - w = 0

这些最优条件对于价格 0有什么后果?首先是关于两个 Arrow-Debreu 证券的相对价格

γ u γ d = p·u ' (ϕ u ) (1-p)·u ' (ϕ d )

相对价格完全由两种状态发生的概率和在这两种状态下消费所得到的边际效用决定。 考虑到在均衡状态下 ϕ u = ϕ d = 1 必须成立,相对价格仅由概率测度确定:

γ u γ d = p (1-p)

加上这个额外条件后,我们也得到:

γ u + γ d = w

虽然在这种情况下相对价格由概率测度确定,但绝对价格由初始可用财富决定。 这在直觉上是有吸引力的,因为给定两种证券的净供应是固定的,初始财富越多,价格应该越高。

将初始财富归一化为 w = 1 ,例如,通过以下方式修正价格:

γ u = 1 - γ d

最终得到均衡价格为:

γ u = p γ d = 1 - p

或均衡价格向量 0 * = (p,1-p) T

价格套利

关于给定均衡价格向量 0 * 的套利索赔价格如何? 在每个套利市场中,其中每个套利索赔都是可以达到的,任何这样的可达套利索赔 C 1 𝔸= ≥0 2 的价格如下给出:

C 0 = 0 * · C 1 = γ u · C 1 u + γ d · C 1 d

这是因为复制投资组合简单地是特定状态的支付本身 ϕ = C 1 在两种 Arrow-Debreu 证券的特殊情况下。 因此,Arrow-Debreu 证券的价格也被称为状态价格,因为它们表示在特定状态下一单位货币(消费)的价格。

鞅定价

当前经济的唯一鞅测度是什么样子? 鞅测度 Q 的条件是使所有交易金融资产的贴现价格过程成为鞅。 在矩阵形式中,这些条件是:

0 * = 1 1+i · 𝐄 Q ( )

更明确地说,我们得到:

p · ( 1 + i ) = q ( 1 - p ) · ( 1 + i ) = 1 - q

从这些中得到i = 0,同时也得到q = p 。物理概率测度使所有概率已经是一个鞅。反过来,两个 Arrow-Debreu 证券的价格在均衡状态下设定得以一种方式,使得折现价格过程是鞅。

每个可达的条件索赔C 1 𝔸 可以通过在这种特殊类型的代表性代理人经济中简单地采用物理概率测度的期望来定价。形式上,这转化为:

C 0 = 𝐄 P ( C 1 )

无风险利率

为什么均衡无风险利率为零?答案非常简单:因为没有交易的无风险金融资产可以固定另一利率。考虑一个无风险金融资产在每个状态下支付 1。该金融资产的套利价格

B 0 = 0 * · B 1 = p + ( 1 - p ) = 1

暗示着无风险利率为i = 0。任何其他价格0 < B 0 < 1,即表示正的无风险利率,也会暗示套利机会。

数值示例(I)

到目前为止的均衡定价分析依赖于一些简化假设,允许优雅的解决方案和简单的关系。现在考虑一个具有某种程度更现实的数值假设的案例,这已被多次使用。

具体来说,假设基于对数效用的期望效用最大化,适用于代表性代理人。进一步假设无风险债券的价格过程为

B = B 0 , (11,11) T

以及对于风险股票的

S = S 0 , (20,5) T

市场支付矩阵相应地为:

= 11 20 11 5

物理概率测度由P = p,(1-p) T给出,其中p = 1 3。无风险债券的净供给为b = 1,风险股票为s = 1。代理人可用的初始财富为w = 15

代表性代理人的问题是

max ϕ,λ f ( ϕ , λ ) = 𝐄 P u ( · ϕ ) - λ · 0 · ϕ - w

max b,s,λ f ( b , s , λ ) = 𝐄 P u ( b · B 1 + s · S 1 ) - λ · b · B 0 + s · S 0 - w

第一阶段条件为:

f b = 𝐄 P B 1 · u ' ( b · B 1 + s · S 1 ) - λ · B 0 = 0 f s = 𝐄 P S 1 · u ' ( b · B 1 + s · S 1 ) - λ · S 0 = 0 f λ = b · B 0 + s · S 0 - w = 0

根据优化条件和考虑到两种金融资产的净供应以及对数效用,相对价格是:

S 0 B 0 = 𝐄 P S 1 ·u ' (b·B 1 +s·S 1 ) 𝐄 P B 1 ·u ' (b·B 1 +s·S 1 ) = 𝐄 P S 1 B 1 +S 1 𝐄 P B 1 B 1 +S 1 ζ

将预算约束添加到混合中,不仅修正了相对价格ζ,还修正了绝对价格水平:

B 0 + ζ · B 0 = w B 0 = w 1+ζ

在 Python 中,这些考虑转化为简单的向量化操作,使用NumPy

In [57]: p = 1 / 3  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [58]: P = np.array((p, (1-p)))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [59]: B1 = np.array((11, 11))

In [60]: S1 = np.array((20, 5))

In [61]: zeta = np.dot(S1 / (B1 + S1), P) / np.dot(B1 / (B1 + S1), P)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [62]: zeta  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[62]: 0.7342657342657343

In [63]: w = 15  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [64]: B0 = w / (1 + zeta)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [65]: B0  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[65]: 8.649193548387098

In [66]: S0 = zeta * B0  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [67]: S0  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[67]: 6.350806451612904

In [68]: B0 + S0  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[68]: 15.000000000000002

In [69]: i = B1.mean() / B0 - 1  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)

In [70]: i  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[70]: 0.2717948717948717

In [71]: mu = np.dot(S1, P) / S0 - 1  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)

In [72]: mu  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[72]: 0.5746031746031743

1

概率测度。

2

给定优化条件的价格比zeta

3

初始财富。

4

给定价格比zeta和初始财富w的无风险债券的均衡价格水平。

5

风险股票的均衡价格水平。

6

预算约束是紧束的。

7

风险无息债券的价格水平给定的均衡利率。

8

风险股票的均衡预期收益率。

在这种情况下,均衡定价不导致折现价格过程在物理概率测度下成为鞅。然而,鞅测度可以很容易地推导出来。分析使用 Python 的SymPy包进行符号计算。

In [73]: import sympy as sy  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [74]: q = sy.Symbol('q')  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [75]: eq = (q * 20 + (1 - q) * 5) / (1 + i) - S0  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [76]: eq  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[76]: 11.7943548387097*q - 2.41935483870968

In [77]: q = sy.solve(eq)[0]  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [78]: q  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[78]: 0.205128205128205

In [79]: Q = np.array((q, 1 - q))  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [80]: np.dot(B1, Q) / (1 + i)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[80]: 8.64919354838710

In [81]: np.dot(S1, Q) / (1 + i)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[81]: 6.35080645161290

1

导入符号计算包SymPy

2

定义符号q

3

给定鞅条件的 q 的方程制定。

4

简化的方程。

5

通过数值方法解决这个方程。

6

导致的鞅测度。

7

Q 下,两个折现价格过程都是鞅。

不完全市场定价

不完全市场中代表性代理定价是如何工作的?幸运的是答案是:与完全市场完全相同。

假设两日期,三状态经济中一个带有价格过程的 无风险债券

B = B 0 , (11,11,11) T

和一个价格过程为 风险股票

S = S 0 , (20,10,5) T

被交易。物理概率度量是 P = (p,p,p) T ,其中 p = 1 3 。其他一切与前一节相同。

形式上,代表性代理的优化问题没有改变:

max b,s,λ f ( b , s , λ ) = 𝐄 P u ( b · B 1 + s · S 1 ) - λ · b · B 0 + s · S 0 - w

也不会改变相对价格变化的公式:

S 0 B 0 = 𝐄 P S 1 B 1 +S 1 𝐄 P B 1 B 1 +S 1 ζ

在 Python 中,只需调整金融资产的未来价格向量和表示概率度量的向量:

In [82]: p = 1 / 3  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [83]: P = np.array((p, p, p))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [84]: B1 = np.array((11, 11, 11))

In [85]: S1 = np.array((20, 10, 5))

In [86]: zeta = np.dot(S1 / (B1 + S1), P) / np.dot(B1 / (B1 + S1), P)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [87]: zeta  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[87]: 0.9155274934101636

In [88]: w = 15  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [89]: B0 = w / (1 + zeta)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [90]: B0  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[90]: 7.8307411674347165

In [91]: S0 = zeta * B0  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [92]: S0  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[92]: 7.169258832565284

In [93]: B0 + S0  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[93]: 15.0

In [94]: i = B1.mean() / B0 - 1  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)

In [95]: i  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[95]: 0.40472016183411985

In [96]: mu = np.dot(S1, P) / S0 - 1  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)

In [97]: mu  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[97]: 0.6273183796451287

1

概率度量。

2

给定最优条件的相对价格 zeta 的方程。

3

初始财富。

4

给定价格比率 zeta 和初始财富 w 的无风险债券的均衡价格水平。

5

风险股票的均衡价格水平。

6

预算约束是约束性的。

7

给定无风险债券的价格水平的均衡利率。

8

风险股票的均衡预期收益率。

代表性代理定价

根据代表性代理人优化计算的证券定价是一种适用于完整和不完整市场的方法。与其通过基于额外证券的市场完备性调整市场,此方法做出了额外的假设,例如代表性代理人的初始财富是为了得出特定的绝对证券价格,而不仅仅是相对价格。

鞅测度

虽然在不完全市场中,代表性代理定价与完全市场中的方式相同,但遗憾的是,它并不能直接解决无法实现的偶发索赔定价问题。仍然存在无限多个与市场一致的鞅测度。

下面的 Python 代码显示,存在无限多个与前一节中推导出的平衡价格过程一致的鞅测度:

In [98]: qu = sy.Symbol('qu')  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         qm = sy.Symbol('qm')  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [99]: eq = (qu * 20 + qm * 10 + (1 - qu - qm) * 5) / (1 + i) - S0  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [100]: eq  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[100]: 3.55942780337942*qm + 10.6782834101383*qu - 3.60983102918587

In [101]: Q = sy.solve(eq, set=True)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [102]: Q  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[102]: ([qm], {(1.01416048550236 - 3.00000000000001*qu,)})

1

定义符号 quqm

2

为了给定鞅条件而制定 quqm 的方程。

3

化简方程。

4

这个数值解决了方程,提供了一组解作为结果;这并没有考虑条件 0 q u , q d 1

5

quqm 之间的关系作为解的指示——表明存在无限多个解。

不完全市场中的鞅测度

鞅定价是完备市场中估算偶发索赔的一种便捷而优雅的方法。在不完全市场中,通常有 无限多个 与市场一致的鞅测度。实际上,可以通过使用公开观察到的流动交易偶发索赔的市场价格来解决这个问题,例如普通的欧式看涨或看跌期权。这些价格用于校准模型参数或直接与市场一致的鞅测度。有关模型校准的背景信息和详细信息,请参阅 Hilpisch (2015)。

平衡定价

关于定价有偶发性索赔怎么办?如果它们通过由交易金融资产组成的复制投资组合是可达的,它们的价格可以通过通常的套利论证确定。如果一项偶发性索赔是不可达的呢?在当前调查的简单不完全市场设置中,这只能意味着支付向量与交易金融资产的两个未来价格向量线性无关。这反过来意味着引入具有这种支付向量的偶发性索赔是市场完备的—因为无论如何三个线性无关的向量形成 3 的一组基础。

考虑来自前两个 Arrow-Debreu 证券的市场支付矩阵,每个都以净供给量为一可获得:

= 1 0 0 1 0 0

显然,这个市场是不完全的,因为这两种证券不能跨越 3 。引入一项具有净供给量为一的偶发性索赔,在d 状态支付一单位货币—也就是说,支付确切等同于第三个 Arrow-Debreu 证券的偶发性索赔—完成了市场,如由产生的支付矩阵所示:

= 1 0 0 0 1 0 0 0 1

这三个支付向量现在形成了 3 的标准基础。

形式上,代表性代理人的优化问题与之前相同:

max ϕ 𝐄 P ( u ( · ϕ ) ) s.t. 0 · ϕ = w

在这里, 0 = γ u ,γ m ,γ d T 是状态价格向量,ϕ = (1,1,1) T 是市场投资组合。

明确表述,根据 Lagrange 定理的无约束优化问题为:

max ϕ u ,ϕ m ,ϕ d ,λ f ( ϕ u , ϕ m , ϕ d , λ ) = p u · u ϕ u + p m · u ϕ m + p d · u ϕ d - λ · γ u · ϕ u + γ m · ϕ m + γ d · ϕ d - w

无约束问题的四个一阶条件是:

f ϕ u = p u · u ' ( ϕ u ) - λ · γ u = 0 f ϕ m = p m · u ' ( ϕ m ) - λ · γ m = 0 f ϕ d = p d · u ' ( ϕ d ) - λ · γ d = 0 f λ = γ u · ϕ u + γ m · ϕ m + γ d · ϕ d - w = 0

对于相对价格,可以得到:

γ u γ m = p u ·u ' (ϕ u ) p m ·u ' (ϕ m ) γ u γ d = p u ·u ' (ϕ u ) p d ·u ' (ϕ d )

通过这些,第三个相对价格也被确定了。在对数效用和初始财富固定为w = 1 的特殊情况下,最终得到:

γ u = p u γ m = p m γ d = p d

平衡价格向量是 0 * = (p u ,p m ,p d ) T ,即代表概率测度的向量。这反过来意味着所有折现价格过程在物理概率测度下都是鞅。

数值例子(II)

回到之前的数值例子:假设基于对数效用的预期效用最大化代表性代理。进一步假设无风险债券的价格过程为

B = B 0 , (11,11,11) T

and for the risky stock of

S = S 0 , (20,10,5) T

市场支付矩阵为:

= 11 20 11 10 11 5

物理概率测度为 P = p,p,p T ,其中 p = 1 3 。无风险债券的净供应量为 b = 1 ,而风险股票的净供应量为 s = 1 。代理可用的初始财富为 w = 15

引入具有支付 C 1 = (5,0,0) T 和净供应量 c = 1 的权益索赔。

因此,代表性代理的问题是:

max ϕ,λ f ( ϕ , λ ) = 𝐄 P u ( · ϕ ) - λ · 0 · ϕ - w

max b,s,c,λ f ( b , s , λ ) = 𝐄 P u ( b · B 1 + s · S 1 + c · C 1 ) - λ · b · B 0 + s · S 0 + c · C 0 - w

四个一阶条件是:

f b = 𝐄 P B 1 · u ' ( b · B 1 + s · S 1 + c · C 1 ) - λ · B 0 = 0 f s = 𝐄 P S 1 · u ' ( b · B 1 + s · S 1 + c · C 1 ) - λ · S 0 = 0 f c = 𝐄 P C 1 · u ' ( b · B 1 + s · S 1 + c · C 1 ) - λ · C 0 = 0 f λ = b · B 0 + s · S 0 + c · C 0 - w = 0

三种金融资产的相对价格通过以下方式固定:

S 0 B 0 = 𝐄 P S 1 B 1 +S 1 +C 1 𝐄 P B 1 B 1 +S 1 +C 1 ζ 1 C 0 B 0 = 𝐄 P C 1 B 1 +S 1 +C 1 𝐄 P B 1 B 1 +S 1 +C 1 ζ 2

预算约束添加到混合中,不仅修复了相对价格 ζ 1ζ 2,而且修复了绝对价格水平:

B 0 + ζ 1 · B 0 + ζ 2 · B 0 = w B 0 = w 1+ζ 1 +ζ 2

Python 代码的调整仅在完全市场情况下较小:

In [103]: p = 1 / 3  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [104]: P = np.array((p, p, p))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [105]: B1 = np.array((11, 11, 11))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [106]: S1 = np.array((20, 10, 5))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [107]: C1 = np.array((5, 0, 0))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [108]: zeta_1 = (np.dot(S1 / (B1 + S1 + C1), P) /
                    np.dot(B1 / (B1 + S1 + C1), P))  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [109]: zeta_1  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[109]: 0.8862001308044474

In [110]: zeta_2 = (np.dot(C1 / (B1 + S1 + C1), P) /
                    np.dot(B1 / (B1 + S1 + C1), P))  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [111]: zeta_2  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[111]: 0.09156311314584695

In [112]: w = 15  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [113]: B0 = w / (1 + zeta_1 + zeta_2)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [114]: B0  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[114]: 7.584325396825396

In [115]: S0 = zeta_1 * B0  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)

In [116]: S0  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[116]: 6.721230158730158

In [117]: C0 = zeta_2 * B0  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)

In [118]: C0  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[118]: 0.6944444444444443

In [119]: B0 + S0 + C0  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
Out[119]: 14.999999999999998

In [120]: i = B1.mean() / B0 - 1  ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)

In [121]: i  ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)
Out[121]: 0.45035971223021587

In [122]: muS = np.dot(S1, P) / S0 - 1  ![11](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/11.png)

In [123]: muS  ![11](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/11.png)
Out[123]: 0.7357933579335794

In [124]: muC = np.dot(C1, P) / C0 - 1  ![12](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/12.png)

In [125]: muC  ![12](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/12.png)
Out[125]: 1.4000000000000004

1

概率测度。

2

支付向量。

3

第一个相对价格。

4

第二个相对价格。

5

初始财富…

6

…以及无风险债券的结果价格。

7

风险股票的均衡价格。

8

风险索赔的均衡价格。

9

预算约束是有约束力的。

10

无风险利率。

11

风险股票的均衡预期收益率。

12

风险索赔的均衡预期收益率。

可以通过事实看出,引入风险索赔作为第三个交易金融资产,市场完备性得到满足,因为现在存在唯一的鞅测度:

In [126]: M = np.array((B1, S1, C1)).T  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [127]: M  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[127]: array([[11, 20,  5],
                 [11, 10,  0],
                 [11,  5,  0]])

In [128]: M0 = np.array((B0, S0, C0))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [129]: Q = np.linalg.solve(M.T / (1 + i), M0)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [130]: Q  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[130]: array([0.20144, 0.34532, 0.45324])

In [131]: sum(Q)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[131]: 1.0

In [132]: np.allclose(np.dot(M.T, Q), M0 * (1 + i))  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[132]: True

1

包括风险索赔的新市场支付矩阵。

2

三个金融资产/风险索赔的价格向量。

3

解决表示鞅测度 Q 的向量 Q (请注意转置运算符 .T 的使用)。

4

向量解决方案的分量总和为 1。

5

最后检查是否所有贴现价格过程确实是鞅测度。

结论

本章讨论代理商及其优化问题的建模,主要基于预期效用最大化方法。讨论了两个中心主题:最优投资组合选择完整和不完整市场中金融资产和风险索赔的均衡定价。在第一种情况下,给定价格并选择投资组合中的数量,在后一种情况下,投资组合中持有的数量是固定的,价格是为了对代表性代理人最优化而调整的。Python 再次证明是一个强大的生态系统,具有有用的包来建模和解决相关的优化问题。

虽然本章和前两章的模型经济学确实是简化的,但引入的技术和方法可以推广到一般静态模型经济学,即具有许多甚至是可数无限多个未来状态(而不仅仅是两个或三个)。通过一些额外的形式主义,它们甚至可以推广到具有许多—潜在可数无限多个—相关时间点的动态经济

进一步资源

本章引用的书籍:

  • Duffie, Darrell. 1988. 证券市场—随机模型. 圣地亚哥:学术出版社。

  • Eichberger, Jürgen 和 Ian Harper. 1997. 金融经济学. 纽约:牛津大学出版社。

  • Hilpisch, Yves. 2020. 金融中的人工智能. Sebastopol:O’Reilly。

  • Hilpisch, Yves. 2015. Python 衍生品分析. Wiley Finance。

  • Markowitz, Harry. 1959. 投资组合选择—有效的投资多样化. 纽约:John Wiley & Sons。

  • Milne, Frank. 1995. 金融理论与资产定价. 纽约:牛津大学出版社。

  • Sundaram, Rangarajan. 1996. 优化理论初级课程. 剑桥大学出版社,剑桥。

  • Varian, Hal. 1992. 微观经济分析. 第三版。纽约和伦敦:W.W. Norton & Company。

¹ 效用只能按序数方式理解,即按照不同计划进行排序。将这个数值与之前的最优数值进行比较是没有意义的,因为效用函数是不同的。

第五章:静态经济

证券市场模型仅在存在至少一个等价鞅测度时才是可行的。

Harrison 和 Kreps(1979)

与无套利论据和鞅理论相关的理论核心是所谓的资产定价基本定理。

Delbaen 和 Schachermayer(2006)

本章引入更多形式化内容,以模拟一般静态经济。这样的经济特点是具有任意大但仍有限的状态空间。如前所述,一般静态经济仅在两个相关时间点上分析,例如今天和一年后。因此,本章引入了一个主要的泛化——即关于状态空间。下一章则进一步泛化模型经济,关于相关时间点的数量。这使得可以模拟动态。

本章继续运用线性代数和概率理论概念。在本章目的下,涵盖这些主题的好书包括 Aleskerov 等人(2011)的线性代数和 Jacod 和 Protter(2004)的概率理论。Milne(1995)提供了对一般静态经济及其分析的初步介绍。Pliska(1997)是一本介绍性的教科书,既易于理解又严谨。Duffie(1988)是一本深入研究一般静态经济的高级文献,以自包含的方式提供了所有线性代数和概率的必要工具。

本章涵盖的主题包括一般离散概率空间、金融资产和条件索赔、市场完备性、资产定价的两大基本定理、复制和套利定价、Black-Scholes-Merton(1973)和 Merton(1976)期权定价,以及具有 Arrow-Debreu 证券的代理人定价。以下表格概述了本章发现的金融、数学和 Python 主题:

金融 数学 Python
不确定性 状态空间、代数、概率测度、概率空间 NumPy, ndarray, rng.normal
金融资产、条件索赔 随机变量、期望 rng, mean(), np.dot
市场支付矩阵 矩阵 ndarray, mean(), std()
复制、套利定价 解线性方程组、点乘 np.maximum, np.linalg.solve, np.dot
市场完备性 秩、张成、向量空间 ndarray, np.dot, np.linalg.matrix_rank
马丁格尔测度 概率测度 ndarray, scipy.optimize.minimize
Black-Scholes-Merton 模型(1973) 几何布朗运动、正态分布、蒙特卡洛模拟、复制 rng.standard_normal, np.linalg.lstsq
Merton(1976)模型、对数正态跳跃 跳跃扩散、泊松分布 rng.poisson, np.linalg.lstsq

本章的主要目标是泛化。几乎所有本章介绍的概念和观念都在之前的章节中有所介绍。状态空间的扩展使得引入一些更加正式的形式主义变得必要。然而,在 Python 方面,代码仍然像以前一样简洁。这种泛化的好处应该是显而易见的。仅仅假设可能的未来苹果股票价格只有两三种状态是不现实的。更为现实的假设是股票价格可能取得 100、500 甚至更多个可能的值之一。这是朝着更为现实的金融模型迈出的重要一步。

不确定性

考虑一个具有一般的离散状态空间 Ω 和有限数量元素的经济体 Ω < 。在 Ω 中的代数 是一组集合,满足以下陈述成立:

  1. Ω

  2. 𝔼 𝔼 c

  3. 𝔼 1 , 𝔼 2 , . . . , 𝔼 I i=1 I 𝔼 i

𝔼 c 表示集合 𝔼 的补集。幂集 ( Ω ) 是最大的代数结构,而集合 = { , Ω }Ω 中最小的代数。代数是经济中可观察事件的一个模型。在这个背景下,经济体的一个单一状态 ω Ω 可以被解释为一个原子事件

概率 将实数 0 p ω P ( { ω } ) 1 分配给状态 ω Ω 或实数 0 P ( 𝔼 ) 1 分配给事件 𝔼 。如果所有状态的概率都已知,则有 P ( 𝔼 ) = ω𝔼 p ω

概率测度 P : [ 0 , 1 ] 具有以下特征:

  1. 𝔼 : P ( 𝔼 ) 0

  2. P i=1 I 𝔼 i = i=1 I 𝔼 i for disjoint sets 𝔼 i

  3. P ( Ω ) = 1

这三个元素一起 { Ω , , P } 形成一个 概率空间 。概率空间是对模型经济中的 不确定性 的形式化表示。

随机变量

给定概率空间 { Ω , , P }随机变量 是一个 - 可测函数:

S : Ω ≥0 , ω S ( ω )

- 可测性意味着对于每个 𝔼 { [ a , b [ : a , b , a < b } ,有:

S -1 ( 𝔼 ) { ω Ω : S ( ω ) 𝔼 }

如果 ( Ω ),则随机变量的期望定义为:

𝐄 P ( S ) = ωΩ P ( ω ) · S ( ω )

否则,有:

𝐄 P ( S ) = 𝔼 P ( 𝔼 ) · S ( 𝔼 )

数值示例

为了举一个具体的例子,假设状态空间为Ω = { ω 1 , ω 2 , ω 3 , ω 4 } 。此外,假设有一个代数 = { , { ω 1 , ω 2 } , { ω 3 , ω 4 } , Ω } 已知。可以轻松验证该集合满足Ω中代数的三个特征。概率测度由P ( { ω 1 , ω 2 } ) = P ( { ω 3 , ω 4 } ) = 1 2。同样,可以看出P确实是这些假设下上的概率测度。

现在考虑一个函数T,其满足T ( ω 1 ) = 1 , T ( ω 2 ) = 2 , T ( ω 3 ) = 3 ,以及T ( ω 4 ) = 4 。这个函数不是在概率空间上定义的随机变量,因为代数不能区分,例如ω 1ω 2 ——它们都包含在集合{ ω 1 , ω 2 } 中。可以说这个代数“不够精细”。

再考虑另一个函数S,其满足S ( ω 1 ) = 20 , S ( ω 2 ) = 20 , S ( ω 3 ) = 5 。现在,这是在概率空间上定义的随机变量,其期望为:

𝐄 P ( S ) = 𝔼 P ( 𝔼 ) · S ( 𝔼 ) = 1 2 · 20 + 1 2 · 5 = 12 . 5

通常假设 ( Ω ) ,相应地定义P ,使得函数(随机变量)T 也是 - 可测的,并且期望得到了恰当定义。

使用 Python,可以有效地展示 Ω 很大的情况。以下 Python 代码假设所有可能的状态有相等的概率:

In [1]: import numpy as np
        from numpy.random import default_rng
        np.set_printoptions(precision=5, suppress=True)

In [2]: rng = default_rng(100)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [3]: I = 1000  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [4]: S = rng.normal(loc=100, scale=20, size=I)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [5]: S[:14]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[5]: array([ 76.84901, 105.79512, 115.61708, 110.87947,  80.77235, 121.42017,
               114.02911, 114.09947, 114.90125, 122.08694, 144.85945,  87.77014,
               100.94422, 135.08469])

In [6]: S.mean()  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[6]: 100.88376804485935

1

设置 NumPy 随机数生成器的种子值,以确保结果的可重现性。

2

固定状态空间中的状态数(以便后续模拟)。

3

生成 I 个正态分布(伪)随机数,均值为 loc,标准差为 scale

4

假设每个模拟值(状态)有相等的概率,计算期望(均值)。

当然,也可以选择任何其他概率测度:

In [7]: P = rng.random(I)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [8]: P[:10]  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[8]: array([0.34914, 0.33408, 0.41319, 0.06102, 0.6339 , 0.51285, 0.51177,
               0.92149, 0.72853, 0.58985])

In [9]: P /= P.sum()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [10]: P.sum()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[10]: 1.0

In [11]: P[:10]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[11]: array([0.00072, 0.00069, 0.00085, 0.00013, 0.00131, 0.00106, 0.00106,
                0.0019 , 0.0015 , 0.00122])

In [12]: np.dot(P, S)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[12]: 100.71981640185018

1

在 0 和 1 之间绘制均匀分布的随机数。

2

ndarray 对象中的值标准化,使其总和为 1。

3

根据随机概率测度得到的权重。

4

期望值作为概率向量和表示随机变量的向量的点积。

数学技术

除了线性代数外,传统概率论在离散金融中起着核心作用。它允许我们以系统化、成熟的方式捕捉和分析不确定性和特别是风险。当从离散金融模型转向连续模型时,需要更先进的方法,如随机微积分。对于离散金融模型,标准的线性代数和概率论在大多数情况下已经足够强大。有关离散金融的更多详细信息,请参考 Pliska(1997)。

金融资产

在两个不同日期的经济中考虑 t { 0 , 1 } ,即今天和一年后(或任何未来时间段)。假设给定一个概率空间 { Ω , ( Ω ) , P } ,表示模型经济中未来的不确定性,其中 Ω I 可能的未来状态。在这种情况下,Ω = { ω 1 , ω 2 , . . . , ω I }

一个交易的金融资产由价格过程表示为 S = ( S 0 , S 1 ) ,其中今天的价格固定 S 0 >0 ,一年后的价格 S 1 :Ω ≥0 ,是一个随机变量,其在 - 可测。形式上,一个交易金融资产的未来价格向量是一个具有 I 个元素的向量:

S 1 = S 1 ( ω 1 ) S 1 ( ω 2 ) . . . S 1 ( ω I )

如果有多个交易的金融资产,例如K > 1,它们可以由多个价格过程表示,S k = ( S 0 k , S 1 k ) , k = 1 , 2 , . . . , K市场回报矩阵由交易的金融资产的未来价格向量组成:

= S 1 1 ( ω 1 ) S 1 2 ( ω 1 ) . . . S 1 K ( ω 1 ) S 1 1 ( ω 2 ) S 1 2 ( ω 2 ) . . . S 1 K ( ω 2 ) . . . . . . . . . . . . S 1 1 ( ω 3 ) S 1 2 ( ω 3 ) . . . S 1 K ( ω 3 )

𝒮 ( S 1 , S 2 , . . . , S K ) 表示交易的金融资产集合静态模型经济可以总结如下:

= ( { Ω , , P } , 𝒮 )

在通常假设的情况下, ( Ω )

将可能的未来状态数固定为五个Ω = { ω 1 , . . . , ω 5 },每个状态的概率相等 ω Ω : P ( ω ) = 1 5,并且交易的金融资产数量也为五个,Python 的数值示例说明了这样一个静态模型经济:

In [13]: M = np.array((
             (11, 25, 0,  0,  25),
             (11, 20, 30, 15, 25),
             (11, 10, 0,  20, 10),
             (11, 5,  30, 15, 0),
             (11, 0,  0,  0,  0)
         ))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [14]: M0 = np.array(5 * [10.])  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [15]: M0  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[15]: array([10., 10., 10., 10., 10.])

In [16]: M.mean(axis=0)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[16]: array([11., 12., 12., 10., 12.])

In [17]: mu = M.mean(axis=0) / M0 - 1  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [18]: mu  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[18]: array([0.1, 0.2, 0.2, 0. , 0.2])

In [19]: (M / M0 - 1)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[19]: array([[ 0.1,  1.5, -1. , -1. ,  1.5],
                [ 0.1,  1. ,  2. ,  0.5,  1.5],
                [ 0.1,  0. , -1. ,  1. ,  0. ],
                [ 0.1, -0.5,  2. ,  0.5, -1. ],
                [ 0.1, -1. , -1. , -1. , -1. ]])

In [20]: sigma = (M / M0 - 1).std(axis=0)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [21]: sigma  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[21]: array([0.     , 0.92736, 1.46969, 0.83666, 1.1225 ])

1

假设市场回报矩阵,其中列表示交易的金融资产的未来、不确定价格向量。

2

五种资产的当前价格向量,每种资产的价格均固定为 10。

3

这计算了每个交易的金融资产的预期(或平均)未来价格。

4

这进而计算了预期(或平均)收益率。

5

计算并打印出收益率矩阵。

6

计算每种交易金融资产的收益率标准差或波动率——第一个是无风险的;可以被视为债券。

偶然索赔

鉴于一个模型经济 偶然索赔由价格过程 C = ( C 0 , C 1 ) 特征化,其中 C 1 是一个 - 可测随机变量。

人们可以将欧式看涨和看跌期权视为偶然索赔的典型示例。例如,欧式看涨期权的支付可以相对于第二个交易金融资产定义为 C 1 = max ( S 1 2 - K , 0 ) ,其中 K ≥0 是期权的执行价格。由于期权的支付是“派生”自另一个资产,因此人们经常称其为衍生工具或简称为衍生品

如果一种偶然索赔可以由交易金融资产的投资组合 ϕ K 复制

· ϕ = C 1

那么偶然索赔的套利价格

0 · ϕ = C 0

在数学中, 0 =S 0 1 ,S 0 2 ,...,S 0 K T >0 I 是交易金融资产的当前价格向量

继续前面的 Python 示例,基于线性代数方法复制偶然索赔如下所示:

In [22]: K = 15  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [23]: M[:, 1]  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[23]: array([25, 20, 10,  5,  0])

In [24]: C1 = np.maximum(M[:, 1] - K, 0)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [25]: C1  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[25]: array([10,  5,  0,  0,  0])

In [26]: phi = np.linalg.solve(M, C1)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [27]: phi  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[27]: array([ 0.,  0.5,  0.01667, -0.2, -0.1])

In [28]: np.allclose(C1, np.dot(M, phi))  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[28]: True

In [29]: C0 = np.dot(M0, phi)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [30]: C0  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[30]: 2.1666666666666665

1

欧式看涨期权的行权价,以及相关金融资产的支付向量。

2

看涨期权写在第二个交易金融资产上,未来支付为 S 1 2 = ( 25 , 20 , 10 , 5 , 0 )

3

这解决了市场支付矩阵的复制问题。

4

检查复制投资组合是否确实复制欧式看涨期权的未来支付。

5

从复制投资组合中,通过与交易金融资产的当前价格向量的组合得到套利价格。

市场完整性

可以基于交易金融资产 𝒮 定义的市场静态模型经济的排名分析市场完整性。矩阵的排名等于线性独立(列)向量的数量(见 Aleskerov 等人(2011 年),第 2.7 节)。考虑代表交易金融资产未来价格向量的列向量。如果它们是线性独立的,那么

· ϕ = 0

有唯一解,即空向量 ϕ = (0,0,...,0) T K

对市场支付矩阵 跨度由所有列向量的线性组合给出:

span ( ) = ϕ K : · ϕ

如果可实现的权益索赔集满足𝔸 = I,则模型经济是完备的。然而,可实现的权益索赔集的定义即为交易金融资产𝔸 span ( )。因此,模型经济完备的,如果:

span ( ) = I

在哪些情况下会发生这种情况?如果矩阵的秩至少与可能的未来状态数目一样大,则会发生这种情况。

rank ( ) I

换句话说,的列向量形成了向量空间 I基础(可能比所需的基础向量更多)。一个向量空间𝕍是一组称为向量的元素,其特征包括:

  1. 一个加法函数将两个向量v 1 , v 2 𝕍映射到向量空间的另一个元素( v 1 + v 2 ) 𝕍

  2. 一个标量乘法函数将标量α 和向量v 𝕍映射到向量空间的另一个元素( α · v ) 𝕍

  3. 一个特殊元素——通常称为“零”或“中性元素”——0 𝕍,使得v + 0 = v

可以轻松验证,例如集合 , 5 I ,I >0都是向量空间。

结果,如果模型经济是不完备的:

rank ( ) < I

为了更具体,考虑一个只有三种可能未来状态的状态空间,Ω = { ω 1 , ω 2 , ω 3 }。那么所有随机变量都是向量空间 3中的向量。下面的市场支付矩阵——由三种交易金融资产导致——仅具有秩为 2,因为两列向量线性相关。这导致了一个不完全市场:

= 11 20 10 11 10 5 11 5 2 . 5 rank ( ) = 2

很容易验证金融资产 2 和 3 确实是线性相关的。

S 1 2 = 20 10 5 = 2 · 10 5 2 . 5 = 2 · S 1 3

相比之下,接下来的市场支付矩阵——由另一组三种交易金融资产导致——具有秩为 3,导致了一个完全市场。在这种情况下,也称矩阵具有满秩

= 11 20 10 11 10 25 11 5 10 rank ( ) = 3

假设一个概率空间已经确定,状态空间有五个元素,Ω = { ω 1 , . . . , ω 5 }。未来(不确定的)价格和五个交易金融资产𝒮及所有相关索赔的支付向量,现在都是向量空间 5的元素。接下来的 Python 代码分析基于这样一个模型经济的相关索赔复制。它假定所有五种 Arrow-Debreu 证券都在交易中,并进入随机化市场支付矩阵:

In [31]: M = np.eye(5)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [32]: M  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[32]: array([[1., 0., 0., 0., 0.],
                [0., 1., 0., 0., 0.],
                [0., 0., 1., 0., 0.],
                [0., 0., 0., 1., 0.],
                [0., 0., 0., 0., 1.]])

In [33]: np.linalg.linalg.matrix_rank(M)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[33]: 5

In [34]: C1 = np.arange(10, 0, -2)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [35]: C1  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[35]: array([10,  8,  6,  4,  2])

In [36]: np.linalg.solve(M, C1)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[36]: array([10.,  8.,  6.,  4.,  2.])

1

创建一个二维的ndarray对象,这里是一个单位矩阵。它可以解释为由五种 Arrow-Debreu 证券交易导致的市场支付矩阵。它形成了向量空间 5的所谓标准基础。

2

计算矩阵的秩,对于单位矩阵来说也是显然的。

3

一个需要用交易金融资产复制的相关索赔支付。

4

这解决了复制(表示)问题,在单位矩阵的情况下也是显而易见的。

接下来,生成随机市场支付矩阵,其也具有完整的秩(总体上一般情况下不能保证):

In [37]: rng = default_rng(100)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [38]: M = rng.integers(1, 10, (5, 5))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [39]: M  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[39]: array([[7, 8, 2, 6, 1],
                [3, 4, 1, 6, 9],
                [9, 6, 4, 8, 9],
                [9, 1, 7, 7, 2],
                [5, 9, 7, 3, 3]])

In [40]: np.linalg.matrix_rank(M)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[40]: 5

In [41]: np.linalg.matrix_rank(M.T)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[41]: 5

In [42]: phi = np.linalg.solve(M, C1)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [43]: phi  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[43]: array([-1.16988,  0.52471, -0.3861 ,  2.56409, -0.62085])

In [44]: np.dot(M, phi)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[44]: array([10.,  8.,  6.,  4.,  2.])

1

设置NumPy随机数生成器的种子,以便结果可重现。

2

创建一个随机化市场支付矩阵(形状为(5, 5)ndarray对象,由介于 1 到 10 之间的随机整数填充)。

3

矩阵具有完整的秩——列向量和行向量均线性独立。

4

使用随机基础解决向量空间 5 的复制问题的非平凡解。

5

检查实现完全复制的解决方案。

资产定价的基本定理

考虑一般的静态模型经济 = ( { Ω , , P } , 𝒮 ) ,其中I个可能的状态和K个交易金融资产。假设经济中的无风险短期借贷利率为r ≥0 。¹

套利机会是一种交易金融资产ϕ K 的投资组合,其组合价格为零

S 0 · ϕ = k=1 K S 0 k · ϕ k = 0

期望的支付大于零:

𝐄 P ( · ϕ ) > 0

所有套利机会的集合表示为:

𝕆 { ϕ K : S 0 · ϕ = 0 , 𝐄 P ( · ϕ ) > 0 }

一个马丁格尔测度 Q 使得折现价格过程是马丁格尔,并因此满足以下条件:

1 1+r · 𝐄 Q ( ) = S 0

根据这些定义,资产定价的第一基本定理(参见第二章)将马丁格尔测度的存在与套利机会的缺失联系起来。关于讨论和证明,请参考 Pliska(1997 年,第 1.3 节)。

资产定价的第一基本定理(1FTAP)

以下陈述等价:

  1. 存在一个马丁格尔测度Q

  2. 经济体是无套利的,它成立 0 =

马丁格尔测度的推导在形式上与对应索赔的复制问题的解决方案相同 C = ( C 0 , C 1 ) ,其读取

· ϕ = C 1

并且复制投资组合 ϕ 需要被确定。从数学上讲,这相当于解决一个线性方程组,正如在第二章中所说明的。寻找一个马丁格尔测度可以被写成

1 1+r · 𝐄 Q ( ) = 1 1+r T · Q = ˜ · Q = S 0

其中 ˜ 1 1+r T 并且其中

Q = Q ( ω 1 ) Q ( ω 2 ) . . . Q ( ω I ) , ω Ω : 0 Q ( ω ) 1 , ωΩ Q ( ω ) = 1

这个问题可以被认为是复制问题的对偶问题 ——尽管在一些限制性约束条件下。这些约束条件由于要求解的解必须是一个概率测度,使得在 Python 中需要一种不同的技术方法。找到一个马丁格尔测度的问题可以被建模为一个受限制的最小化问题 —— 而不仅仅是解决一个线性方程组。该示例假设具有五个元素的状态空间和之前的市场支付结构:

In [45]: import scipy.optimize as sco    ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [46]: M = np.array((
             (11, 25, 0,  0,  25),
             (11, 20, 30, 15, 25),
             (11, 10, 0,  20, 10),
             (11, 5,  30, 15, 0),
             (11, 0,  0,  0,  0)
         ))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [47]: np.linalg.matrix_rank(M)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[47]: 5

In [48]: M0 = np.ones(5) * 10  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [49]: M0  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[49]: array([10., 10., 10., 10., 10.])

In [50]: r = 0.1  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [51]: def E(Q):
             return np.sum((np.dot(M.T, Q) - M0 * (1 + r)) ** 2)   ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)

In [52]: E(np.array(5 * [0.2]))
Out[52]: 4.0

In [53]: cons = ({'type': 'eq', 'fun': lambda Q: Q.sum() - 1})  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)

In [54]: bnds = (5 * [(0, 1)])  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)

In [55]: bnds  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
Out[55]: [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]

In [56]: res = sco.minimize(E, 5 * [1],  ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)
                            method='SLSQP',  ![11](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/11.png)
                            constraints=cons,  ![12](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/12.png)
                            bounds=bnds)  ![13](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/13.png)

In [57]: Q = res['x']  ![14](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/14.png)

In [58]: Q  ![14](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/14.png)
Out[58]: array([0.14667, 0.18333, 0.275  , 0.18333, 0.21167])

In [59]: np.dot(M.T, Q) / (1 + r)  ![15](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/15.png)
Out[59]: array([10.     ,  9.99998,  9.99999, 10.00001,  9.99998])

In [60]: np.allclose(M0, np.dot(M.T, Q) / (1 + r))
Out[60]: True

1

scipy 导入 optimize 子包作为 sco

2

定义市场支付矩阵。

3

验证矩阵具有全秩。

4

为交易的金融资产定义价格向量…

5

…并显示所有设置为 10 的值。

6

修正恒定短期利率。

7

定义要最小化的目标函数。这种方法是必要的,因为线性系统要在所有参数的约束和边界条件下解决。

8

单一概率需要加总为一的约束。

9

确定每个单一概率的边界。

10

最小化函数 E 的优化过程…

11

…定义所使用的方法,…

12

…提供需遵守的限制条件,并…

13

…提供参数的界限。

14

结果向量是马丁格尔测度。

15

在马丁格尔测度下,贴现价格过程是马丁格尔。

在一般静态模型经济 中,第二资产定价基本定理也成立。有关讨论和证明,请参阅 Pliska(1997 年,1.5 节)。

第二资产定价基本定理(2FTAP)

以下陈述等价:

  1. 马丁格尔测度 Q 是唯一的。

  2. 经济是完备的,它满足 𝔸 = + I

基本定理

追寻有效期权定价模型的历程导致了 Black 和 Scholes(1973 年)以及 Merton(1973 年)的开创性期权定价模型——共同构成 Black-Scholes-Merton(1973 年)。这些开创性论文中使用的模型相当特定,因为它们假定几何布朗运动作为唯一风险资产价格过程的模型。上世纪 70 年代末和 80 年代初的研究,尤其是 Harrison 和 Kreps(1979 年)以及 Harrison 和 Pliska(1981 年),为金融衍生品定价提供了一个通用框架。在他们的通用框架中,马丁格尔测度和(半)马丁格尔过程发挥了核心作用。(半)马丁格尔过程的类别非常广泛,既包括早期模型(例如几何布朗运动),也包括后来提出并分析的许多更复杂的金融模型(例如跳跃扩散或随机波动率过程)。这也是为什么这些呈现的定理被称为基本定理之一的原因之一——它们适用于许多有趣和重要的金融模型。

Black-Scholes-Merton Option Pricing

Black-Scholes-Merton(1973 年)期权定价模型基于连续模型经济,通常由具有适当边界条件的随机微分方程(SDEs)表示。用于描述单一风险资产(例如股票或股票指数)演变的 SDE 是几何布朗运动。除了风险资产外,模型经济还交易另一个无风险资产,其支付连续、无风险的短期利率。

在只有两个相关时间点的静态情况下,例如t = 0t = T > 0,未来的不确定风险资产S T的值由以下给出:

S T = S 0 · e r-σ 2 2T+σTz

其中S 0 >0是今天风险资产的价格,r ≥0是固定的无风险短期利率,σ >0是固定的波动率因子,而z是标准正态分布的随机变量(见 Jacod 和 Protter(2004),第十六章)。

在离散的数值背景下,例如,可以绘制伪随机数z i , i = 1 , 2 , . . . , I,这些数是标准正态分布的,用于根据前述方程得出I个数值为S T的模拟值。

S T ( z i ) = S 0 · e r-σ 2 2T+σTz i , i = 1 , 2 , . . . , I

这样的过程通常被称为蒙特卡罗模拟。为了简化表示,从现在起S T将指定为股票未来模拟值的向量:

S T S T ( z 1 ) S T ( z 2 ) . . . S T ( z I )

根据这些定义,模型经济如下。存在一个通用概率空间{ Ω , ( Ω ) , P },其经济有I个可能的未来状态。假设每个状态是等可能的,即有:

ω Ω : P ( ω ) = 1 I

交易金融资产集合 𝒮 由无风险资产 债券 和价格过程 B = B 0 , B 0 · e rT 和风险资产 股票(不支付股利),价格过程 S = ( S 0 , S T ) 和之前定义的 S T 组成。这形成了 Black-Scholes-Merton(1973)模型经济体:

BSM = { Ω , , P } , 𝒮 = { B , S }

假设作为条件要求的欧式看涨期权写在股票上。支付是

C T ( S T - K , 0 )

具有行权价格 K ≥0 。期权价格——这里是 蒙特卡洛估计量——由预期(平均)折现支付给出:

C 0 = e -rT 1 I i=1 I max ( S T ( z i ) - K , 0 )

在 Python 中实现模型经济体和基于蒙特卡洛的定价方法是直接的。图 5-1 展示了模拟股票价格值的频率分布,包括均值和均值周围的标准差:

In [61]: import math

In [62]: S0 = 100  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         r = 0.05  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
         sigma = 0.2  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
         T = 1.0  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
         I = 10000  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [63]: rng = default_rng(100)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [64]: ST = S0 * np.exp((r - sigma ** 2 / 2) * T +
              sigma * math.sqrt(T) * rng.standard_normal(I))  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)

In [65]: ST[:8].round(1)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[65]: array([ 81.7, 109.2, 120.5, 114.9,  85. , 127.7, 118.6, 118.6])

In [66]: ST.mean()  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[66]: 105.6675325917807

In [67]: S0 * math.exp(r * T)  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
Out[67]: 105.12710963760242

In [68]: from pylab import mpl, plt
         plt.style.use('seaborn')
         mpl.rcParams['savefig.dpi'] = 300
         mpl.rcParams['font.family'] = 'serif'

In [69]: plt.figure(figsize=(10, 6))
         plt.hist(ST, bins=35, label='frequency');
         plt.axvline(ST.mean(), color='r', label='mean')
         plt.axvline(ST.mean() + ST.std(), color='y', label='sd up')
         plt.axvline(ST.mean() - ST.std(), color='y', label='sd down')
         plt.legend(loc=0);   ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)

1

初始股票价格水平。

2

常数短期利率。

3

波动率因子。

4

年分数时间视角。

5

状态数量和模拟数量。

6

为了可重现性固定了种子值。

7

核心代码行:以NumPy向量化方式实现蒙特卡洛模拟,一步模拟I个值。

8

从模拟的股票价格集合获得的均值。

9

理论上可以期望的股票价格值。

10

这些代码行将模拟结果绘制成直方图,并添加一些主要统计数据。

ftwp 0501

图 5-1. Black-Scholes-Merton(1973)模型中模拟的股票价格的频率分布。

有了模拟股票价格值后,欧式期权定价仅仅是两个更多向量化操作的问题:

In [70]: K = 105  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [71]: CT = np.maximum(ST - K, 0)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [72]: CT[:8].round(1)
Out[72]: array([ 0. ,  4.2, 15.5,  9.9,  0. , 22.7, 13.6, 13.6])

In [73]: C0 = math.exp(-r * T) * CT.mean()  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [74]: C0  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[74]: 8.288763195530931

1

期权的行使价格。

2

期权的支付向量。

3

欧式期权价格的蒙特卡罗估计量。

Black-Scholes-Merton 的完备性。

Black-Scholes-Merton 模型经济体的完备性 BSM如何?前一节推导了蒙特卡罗估计量,用于欧式看涨期权的(套利)价格,尽管经济体的状态远超过金融资产交易的状态数目I 2,而金融资产交易只有K = 2。可以得出两个观察结果:

广义的不完备性。

从更广义上讲,经济体不完备,因为并非每个条件性索赔都可以通过交易资产组合复制,也因为不存在唯一的鞅测度(见 2FTAP)。

特定的完备性。

在狭义上,该模型是完备的,因为每个可以表示为股票价格向量的函数C 1 = f ( S 1 2 )的条件性索赔都可以通过债券和股票的头寸复制。

在前述章节中使用蒙特卡罗模拟推导套利价格的估计量时,利用了模型经济体 BSM在前述具体而狭义上的完备性。欧式看涨期权的支付仅依赖于股票未来价格向量。目前缺失的是复制组合和相应套利价格的计算,以验证蒙特卡罗模拟方法的合理性。

到目前为止,解决复制问题的NumPy函数是np.linalg.solve,需要一个方阵(市场支付)。在只有两个交易金融资产和许多可能未来状态的 Black-Scholes-Merton 经济中,这一先决条件并不存在。然而,可以通过np.linalg.lstsq使用最小二乘法来找到复制问题的数值解:

In [75]: B0 = 100  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [76]: M0 = np.array((B0, S0))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [77]: BT = B0 * np.ones(len(ST)) * math.exp(r * T)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [78]: BT[:4]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[78]: array([105.12711, 105.12711, 105.12711, 105.12711])

In [79]: M = np.array((BT, ST)).T  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [80]: M  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[80]: array([[105.12711,  81.74955],
                [105.12711, 109.19348],
                [105.12711, 120.4628 ],
                ...,
                [105.12711,  71.10624],
                [105.12711, 105.32038],
                [105.12711, 134.77647]])

In [81]: phi = np.linalg.lstsq(M, CT, rcond=None)[0]  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [82]: phi  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[82]: array([-0.51089,  0.59075])

In [83]: np.mean((np.dot(M, phi) - CT))  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[83]: 1.1798206855928583e-14

In [84]: np.dot(M0, phi)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[84]: 7.9850808951857335

1

债券的任意固定价格。

2

今天两个交易金融资产的价格向量。

3

给定初始价格和短期利率的债券的未来价格向量。

4

结果市场收益矩阵,仅为 2 级,相比于 10,000 个未来状态。

5

这通过最小二乘表示解决了复制问题。对于看涨期权的复制,应卖出(做空)债券,并买入股票。

6

平均复制误差,例如由于浮点不精确性和所使用的数值方法而产生,实际上并非零,但非常接近零。

7

这计算了给定(数值上)最优复制投资组合的套利价格。这与之前的蒙特卡罗估算器接近。

Merton 跳跃扩散期权定价

本节介绍了另一个重要的模型经济,可追溯至 Merton(1976 年),并将跳跃组件添加到 Black-Scholes-Merton(1973 年)的股票价格模型中。随机跳跃组件使得模型经济 M76一般上是不完全的。然而,在本章的离散设置中,可以应用与前两节介绍的 BSM期权定价相同的数值方法。该模型被称为跳跃扩散模型,尽管扩散仅在动态背景下定义。

在实际金融时间序列中,人们观察到带有一定规律性的跳跃。它们可能是由股市崩盘或其他罕见和/或极端事件引起的。Merton(1976 年)的模型允许我们明确地建模这些罕见事件及其对金融工具价格的影响。没有跳跃的模型通常不适合解释金融时间序列中常见的某些特征和现象。该模型还能够模拟正跳和负跳。尽管实际上股票指数可能会观察到负跳(大幅下跌),但在波动率指数中,正跳(尖峰)是常见的。

默顿跳跃扩散经济 M76 与 Black-Scholes-Merton 经济 BSM 相同,除了在时间 T 的股票未来价格,这可以在这个经济中模拟,根据

S T ( z i ) = S 0 · e r-r j -σ 2 2T+σTz i 1 + + e μ+δz i 2 - 1 y i , i = 1 , 2 , . . . , I

其中 z i 1 , z i 2 是标准正态分布,而 y i 是强度为 λ 的泊松分布(参见 Jacod 和 Protter (2004),第四章)。跳跃是对数正态分布,期望值为 μ,标准差为 δ(参见 Jacod 和 Protter (2004),第七章)。期望的跳跃大小为:

r j = λ · e μ+δ 2 /2 - 1

在 Python 中实现并模拟这个模型需要定义额外的参数并模拟三个随机变量。图 5-2 展示了模拟值的频率分布,考虑到假设的参数和使用的 Python 代码,这些值可能为负:

In [85]: M0 = np.array((100, 100))   ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [86]: r = 0.05
         sigma = 0.2
         lmbda = 0.3
         mu = -0.3
         delta = 0.1
         rj = lmbda * (math.exp(mu + delta ** 2 / 2) - 1)
         T = 1.0
         I = 10000

In [87]: BT = M0[0] * np.ones(I) * math.exp(r * T)

In [88]: z = rng.standard_normal((2, I))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
         z -= z.mean()  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
         z /= z.std()  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
         y = rng.poisson(lmbda, I)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [89]: ST = S0 * (
             np.exp((r - rj - sigma ** 2 / 2) * T +
                    sigma * math.sqrt(T) * z[0]) +
             (np.exp(mu + delta * z[1]) - 1) * y
         )  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [90]: ST.mean() * math.exp(-r * T)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[90]: 100.53765025420363

In [91]: plt.figure(figsize=(10, 6))
         plt.hist(ST, bins=35, label='frequency');
         plt.axvline(ST.mean(), color='r', label='mean')
         plt.axvline(ST.mean() + ST.std(), color='y', label='sd up')
         plt.axvline(ST.mean() - ST.std(), color='y', label='sd down')
         plt.legend(loc=0);

1

修复两种交易金融资产(债券和股票)的初始价格向量。

2

第一组标准正态分布随机数。

3

第二组标准正态分布随机数。

4

带有强度为 lambda 的泊松分布随机数集合。

5

给定三组随机数,在时间 T 模拟股票价格值。

6

计算模拟股票价格的折现均值。

ftwp 0502

图 5-2. 默顿(1976)股票价格模拟值的频率分布

在股票价格中添加最大函数,蒙特卡洛模拟避免负值(参见 图 5-3):

In [92]: ST = np.maximum(S0 * (
             np.exp((r - rj - sigma ** 2 / 2) * T +
                    sigma * math.sqrt(T) * z[0]) +
             (np.exp(mu + delta * z[1]) - 1) * y
         ), 0)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [93]: plt.figure(figsize=(10, 6))
         plt.hist(ST, bins=35, label='frequency')  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
         plt.axvline(ST.mean(), color='r', label='mean')
         plt.axvline(ST.mean() + ST.std(), color='y', label='sd up')
         plt.axvline(ST.mean() - ST.std(), color='y', label='sd down')
         plt.legend(loc=0);

1

最大函数…

2

…避免股票价格为负值。

ftwp 0503

图 5-3。Merton(1976)中股价的模拟值(截断)

最后一步是通过蒙特卡洛估计法和近似复制方法定价欧式看涨期权:

In [94]: K = 105

In [95]: CT = np.maximum(ST - K, 0)

In [96]: C0 = math.exp(-r * T)  * np.mean(CT)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [97]: C0  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[97]: 10.306374338651601

In [98]: M = np.array((BT, ST)).T

In [99]: phi = np.linalg.lstsq(M, CT, rcond=-1)[0]  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [100]: phi  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[100]: array([-0.41827,  0.51847])

In [101]: np.mean(np.dot(M, phi) - CT)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[101]: 1.1823431123048067e-15

In [102]: np.dot(M0, phi)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[102]: 10.020157308565008

1

欧式看涨期权价格的蒙特卡洛估计法。

2

近似复制组合。

3

最优组合的复制误差。

4

根据最优组合的套利价格。

通过跳跃引起的不完备性

尽管 Black-Scholes-Merton(1973)模型在狭义上是完备的,但在 Merton(1976)跳跃扩散模型中添加跳跃组分使其在广义上不完备。这意味着即使引入额外的金融资产,也不能使其完备。跳跃组分可以取无限多个值,这要求引入无限多个额外的金融资产才能使模型完备。

代表性代理定价

再假设现在是由代表性、预期效用最大化的代理构成的一般静态经济。该代理在今天具有初始财富w >0,其偏好可以用效用函数表示u : c , u ( c ) ln c。形式上,代理的问题与第四章中的相同:

max ϕ 𝐄 P u ( · ϕ ) w = 0 · ϕ

不同之处在于现在可能存在更多的未来状态和更多的交易金融资产。

此外,假设完整的 Arrow-Debreu 证券集合,每种证券的净供应量为一,被交易,K = I市场支付矩阵为:

= 1 0 . . . 0 0 1 . . . 0 . . . . . . . . . . . . 0 0 . . . 1

无约束形式的优化问题根据拉格朗日定理给出:

max ϕ,λ f ( ϕ , λ ) = 𝐄 P u ( · ϕ ) - λ · ( 0 · ϕ - w )

对于所有投资组合头寸 ϕ i , i = 1 , 2 , . . . , I 的一阶条件—其中 i 指的是在状态 ω i 下支付的 Arrow-Debreu 证券—为:

f ϕ i = P ( ω i ) - λ · S 0 i = 0 , i = 1 , 2 , . . . , I

S 0 i 是支付状态为 ω i 的 Arrow-Debreu 证券的价格。因此,所有 Arrow-Debreu 证券之间的相对价格由各自支付状态发生的概率来确定:

S 0 i S 0 j = P(ω i ) P(ω j ) , ω i , ω j Ω

修正 w = 1 ,则得到绝对价格为:

S 0 i = P ( ω i )

换句话说,支付状态为 ω i 的 Arrow-Debreu 证券的价格等于此状态发生的概率 P ( ω i )

这个小分析表明,在解决代表性代理人问题以进行定价方面,一般静态经济与 第四章 的简单经济基本相同。

结论

本章涵盖了具有潜在大量状态的一般静态经济—例如,Black-Scholes-Merton(1973)模型模拟中假设了 10,000 种不同的状态。引入的额外形式主义效果相当不错,因为它允许更加现实的模型应用于实践中,例如,对股票指数或单个股票的欧式看跌或看涨期权进行估值。

Python 与 NumPy 结合,对比以前看到的规模更大的市场回报矩阵的建模具有强大的实力。通过向量化技术,蒙特卡罗模拟也可以高效快速地完成。在这种情况下,使用最小二乘回归技术可以有效地推导出近似复制投资组合。

然而,静态经济本身在金融领域中可以建模的内容方面存在限制。例如,像在美式期权背景下看到的提前行权特征是无法考虑在内的。这个缺陷将在扩大时间点的相关集合—从而在下一章中迈出到动态经济的自然步骤—时被克服。

更多资源

本章引用的论文有:

  • Black, Fischer 和 Myron Scholes. 1973. “期权定价与公司负债的定价.” Journal of Political Economy 81 (3): 638–659.

  • Harrison, Michael 和 David Kreps. 1979. “多期证券市场中的鞅与套利.” Journal of Economic Theory (20): 381–408.

  • Harrison, Michael 和 Stanley Pliska. 1981. “连续交易理论中的鞅和随机积分.” Stochastic Processes and their Applications (11): 215–260.

  • Merton, Robert. 1973. “Rational Option Pricing Theory.” Bell Journal of Economics and Management Science (4): 141–183.

  • Merton, Robert. 1976. “股票回报不连续情况下的期权定价.” Journal of Financial Economics 3 (3): 125–144.

本章引用的书籍:

  • Aleskerov, Fuad, Hasan Ersel, 和 Dmitri Piontkovski. 2011. 经济学家的线性代数. Heidelberg: Springer.

  • Delbaen, Freddy 和 Walter Schachermayer. 2006. 套利的数学. Berlin: Springer Verlag.

  • Duffie, Darrell. 1988. 证券市场—随机模型. San Diego: Academic Press.

  • Jacod, Jean 和 Philip Protter. 2004. 概率基础. Berlin 和 Heidelberg: Springer.

  • Milne, Frank. 1995. 金融理论与资产定价. New York: Oxford University Press.

  • Pliska, Stanley. 1997. 数学金融导论. Malden 和 Oxford: Blackwell Publishers.

¹ 这里的符号从 i 变为 r,以强调短期利率

第六章:动态经济

证券市场的多期模型比单期模型更加真实。事实上,在金融行业中,它们被广泛用于实际目的。

Stanley Pliska(1997)

尽管市场在任何一个时间点上都不完全,但从某种意义上说,它们在动态上是完全的,因为任何消费过程都可以通过交易给定的一组金融证券来融资,随着时间的推移调整投资组合,因为不确定性逐步解决。

Darrell Duffie(1986)

实际上,量化信息(如股票价格或利率的变化)会随着时间逐渐显露出来。尽管静态模型经济学是引入金融基本概念的一种优雅方式,但现实的金融模型需要对金融世界进行动态表示。

为了正确地建模动态经济,需要更多的形式化工具,这在本章中无法完全详细说明。然而,本章可以介绍基于离散时间动态的两个最重要的动态模型经济:Cox-Ross-Rubinstein(1979)二叉期权定价模型和 Black-Scholes-Merton(1973)期权定价模型的离散蒙特卡罗模拟版本。在这种情况下,“离散时间”意味着相关日期集从仅两个扩展到更大但仍有限的数字,比如说,五个或五十个。

本章使用的工具与以前大致相同:线性代数,概率论,以及像前一章一样的随机元素来实现蒙特卡罗模拟。Duffie(1988)和 Pliska(1997)是离散时间动态金融建模的优秀资源。Glasserman(2004)是金融中蒙特卡罗模拟方法的全面参考书。

本章涵盖的主题包括随机过程,动态完全市场中的期权定价,二叉期权定价,Black-Scholes-Merton(1973)动态模拟,早期行权和美式期权定价,以及最小二乘蒙特卡罗(LSM)期权定价。

下表概述了本章发现的金融、数学和 Python 主题:

金融 数学 Python
不确定性,基于树结构 随机过程,二叉树 NumPy, ndarray
不确定性,基于模拟 随机过程,蒙特卡罗模拟 NumPy, ndarray, rng.standard_normal
欧式期权定价 内在价值,反向归纳,风险中性期望 NumPy, ndarray, np.maximum
美式期权定价 内在价值,继续价值,OLS 回归,反向归纳,风险中性期望 NumPy, ndarray, np.polyval, np.polyfit, np.where

如同第五章,本章的主要目标是泛化。虽然第五章泛化了状态空间,本章旨在泛化时间上的离散的相关点,这些点在新信息揭示和经济行动发生时。虽然需要一些额外的形式主义来实现这一点,但本章则较少形式化,因为它只专注于两个特定的模型,并不试图为离散时间中的动态经济提供一般框架。这样的一般框架,包括许多 Python 实现的例子,可以在 Hilpisch (2015)中找到。

二项式期权定价

1979 年发布后,二项式期权定价模型立即流行起来——既作为计算欧式期权和美式期权的数值高效方法,也作为教学工具。虽然 Black-Scholes-Merton (1973)模型依赖于连续时间金融和随机微积分,但二项式期权定价模型在某种意义上是 BSM 模型的离散时间版本,可以完全通过基础数学理解。

在 Cox-Ross-Rubinstein (1979)模型中,有两种交易金融资产:一种风险的,称为股票,一种无风险的,称为债券。该模型经济在一个有限日期集合 𝒯 { t 0 = 0 , t 1 , t 2 , . . . , t M = T } 中进行,其中包含 M + 1 , M > 1 个元素。

给定股票价格为 S t i ,股票在下一个日期 S t i+1 只能取两个不同的值:

S t i+1 = S t i · u S t i · d

u 代表向上移动d 代表向下移动

为了简化日期处理,假设时间网格均匀分布,长度为 M 个时间间隔,每个间隔长度为 Δ t = T M 。那么有限的日期集合可以写成 𝒯 { t 0 = 0 , t 1 = Δ t , t 2 = 2 Δ t , . . . , T } 。此外,定义:

u e σΔt d e -σΔt = u -1

结果表明,这一定义的一个后果是性质 u · d = 1 ,这在创建所谓的可重组二项树时非常方便。 σ >0 表示常数波动率因子

假设无风险、恒定的短期利率由 r ≥0 给定。给定债券价格为 B t i ,则债券在一期后的价格为

B t i+1 = B t i · e r·(t i+1 -t i )

或者

B t+Δt = B t · e r·Δt

对于一些 t 𝒯 T

基于上述假设推导出的一个重要数值参数是任何给定节点上向上移动的鞅概率。鉴于每个节点只有两个分支,向下概率也因此被确定。用 q >0 ,0<q<1 表示鞅概率向上移动。从股票价格的鞅性质可以得出:

S t = e -rΔt 𝐄 Q ( S t+Δt ) = e -rΔt q S t u + ( 1 - q ) S t d 1 = e -rΔt q u + ( 1 - q ) d q = e rΔt -d u-d

这表明鞅测度在每个节点以及整个树上都是固定的。

二项期权定价模型的基础很容易转化为 Python 代码:¹

In [1]: import math
        import numpy as np

In [2]: S0 = 36.  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
        K = 40.  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
        r = 0.06  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
        T = 1.0  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
        sigma = 0.2  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [3]: m = 4  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
        dt = T / m  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
        df = math.exp(-r * dt)  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
        up = math.exp(sigma * math.sqrt(dt))  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)
        down = 1 / up  ![9](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/9.png)

In [4]: q = (1 / df - down) / (up - down)  ![10](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/10.png)

1

初始股票价格值。

2

期权的行使价格。

3

常数无风险短期利率。

4

时间跨度和期权到期时间。

5

恒定波动率因子。

6

时间间隔的数量。

7

每个时间间隔的结果长度。

8

固定时间间隔的折现因子。

9

上涨和下跌因子。

10

上涨移动的马丁格尔概率。

该模型中股票价格过程的模拟和期权估值稍微复杂。以下展示了两种不同的实现方式:一种基于Python 循环,可能更容易理解;另一种基于向量化的NumPy代码,更为简洁高效,但一开始可能更难理解。

基于 Python 循环的模拟和估值

即使本小节的实现使用了 Python 循环,基本数据结构是NumPyndarray对象:

In [5]: S = np.zeros((m + 1, m + 1))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
        S  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[5]: array([[0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.]])

In [6]: S[0, 0] = S0  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
        S  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[6]: array([[36.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.]])

In [7]: z = 1  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
        for t in range(1, m + 1):  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
            for i in range(0, z):  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
                S[i, t] = S[i, t - 1] * up  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
                S[i + 1 ,t] = S[i, t - 1] * down  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
            z += 1  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)

In [8]: np.set_printoptions(formatter=
                {'float_kind': lambda x: '%7.3f' % x})

In [9]: S  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/8.png)
Out[9]: array([[ 36.000,  39.786,  43.970,  48.595,  53.706],
               [  0.000,  32.574,  36.000,  39.786,  43.970],
               [  0.000,   0.000,  29.474,  32.574,  36.000],
               [  0.000,   0.000,   0.000,  26.669,  29.474],
               [  0.000,   0.000,   0.000,   0.000,  24.132]])

1

初始化ndarray对象。

2

设置左上角的初始股票价格值。

3

将计数器z设为 1。

4

1m+1迭代,即从 0 后的所有时间步。

5

迭代给定时间步骤的相关节点。

6

计算上涨和下跌值,并在ndarray对象中设置它们。

7

将计数器增加 1 以包括下一步中更多相关节点。

8

结果的再组合二项树。

欧式期权定价

根据可用股票价格过程对欧式期权进行估值是通过计算期权在到期时的内在价值,并应用反向归纳来实现的。这基本上意味着从末尾开始,逐步向前移动到现在,在每个节点重复应用风险中性定价范式,正如在第二章中介绍的简单静态双状态经济中。

以下 Python 代码假设欧式看跌期权的支付:

In [10]: h = np.zeros_like(S)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [11]: z = 1
         for t in range(0, m + 1):
             for i in range(0, z):
                 h[i, t] = max(K - S[i, t], 0)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
             z += 1

In [12]: h  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[12]: array([[  4.000,   0.214,   0.000,   0.000,   0.000],
                [  0.000,   7.426,   4.000,   0.214,   0.000],
                [  0.000,   0.000,  10.526,   7.426,   4.000],
                [  0.000,   0.000,   0.000,  13.331,  10.526],
                [  0.000,   0.000,   0.000,   0.000,  15.868]])

In [13]: V = np.zeros_like(S)
         V[:, -1] = h[:, -1]
         V
Out[13]: array([[  0.000,   0.000,   0.000,   0.000,   0.000],
                [  0.000,   0.000,   0.000,   0.000,   0.000],
                [  0.000,   0.000,   0.000,   0.000,   4.000],
                [  0.000,   0.000,   0.000,   0.000,  10.526],
                [  0.000,   0.000,   0.000,   0.000,  15.868]])

In [14]: m
Out[14]: 4

In [15]: # European option pricing
         z = 0
         for t in range(m - 1, -1, -1):
             for i in range(0, m - z):
                 V[i, t] = df * (q * V[i, t + 1] +
                             (1-q) * V[i + 1, t + 1])  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
             z += 1

In [16]: V  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[16]: array([[  3.977,   2.190,   0.784,   0.000,   0.000],
                [  0.000,   6.299,   3.985,   1.771,   0.000],
                [  0.000,   0.000,   9.344,   6.830,   4.000],
                [  0.000,   0.000,   0.000,  12.735,  10.526],
                [  0.000,   0.000,   0.000,   0.000,  15.868]])

In [17]: V[0, 0]  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[17]: 3.9771456941187893

1

内部值的ndarray对象。

2

这计算了相关节点的内在价值。

3

通过应用风险中性定价进行节点估值。

4

结果的现值二项树。

5

欧式看跌期权的现值。

美式期权定价

二项式期权定价模型的主要特点之一是美式期权与其欧式对应物一样容易估值。美式期权可以在到期日之前的任何时间行使。向后估值算法需要进行的调整很简单:只需检查美式期权在任何给定节点的内在价值是否高于继续价值,即不行使期权的现值。如果是这样,则行使该期权,并将美式期权的价值设置为内在价值。形式上,可以得到

V t = max h t , e -rΔt 𝐄 Q ( V t+Δt )

其中h t是时间t的内在价值,而e -rΔt 𝐄 Q ( V t+Δt )是继续价值。

在 Python 中,只需添加一行代码:

In [18]: # American option pricing
         z = 0
         for t in range(m - 1, -1, -1):
             for i in range(0, m-z):
                 V[i, t] = df * (q * V[i, t + 1] +
                           (1 - q) * V[i + 1, t + 1])
                 V[i, t] = max(h[i, t], V[i, t])  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
             z += 1

In [19]: V  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[19]: array([[  4.540,   2.307,   0.784,   0.000,   0.000],
                [  0.000,   7.426,   4.249,   1.771,   0.000],
                [  0.000,   0.000,  10.526,   7.426,   4.000],
                [  0.000,   0.000,   0.000,  13.331,  10.526],
                [  0.000,   0.000,   0.000,   0.000,  15.868]])

In [20]: V[0, 0]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[20]: 4.539560595224299

1

此行检查是否应提前行权,并在内在价值高于继续价值时将内在价值作为美式期权价值。

2

美式看跌期权现值的结果二项树。

3

今天的美式看跌期权现值显著高于不提前行权时的价值。

基于向量化代码的模拟和估值

随后的算法实现系统地利用了NumPy的向量化能力。该实现逐步呈现,还包括一些示例性代码行,这些行不是算法实现本身所需的:

In [21]: u = np.arange(m + 1)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         u  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[21]: array([0, 1, 2, 3, 4])

In [22]: u ** 2  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[22]: array([ 0,  1,  4,  9, 16])

In [23]: 2 ** u  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[23]: array([ 1,  2,  4,  8, 16])

In [24]: u = np.resize(u, (m + 1, m + 1))  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
         u
Out[24]: array([[0, 1, 2, 3, 4],
                [0, 1, 2, 3, 4],
                [0, 1, 2, 3, 4],
                [0, 1, 2, 3, 4],
                [0, 1, 2, 3, 4]])

In [25]: d = u.T  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
         d  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[25]: array([[0, 0, 0, 0, 0],
                [1, 1, 1, 1, 1],
                [2, 2, 2, 2, 2],
                [3, 3, 3, 3, 3],
                [4, 4, 4, 4, 4]])

In [26]: (u - 2 * d)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[26]: array([[ 0,  1,  2,  3,  4],
                [-2, -1,  0,  1,  2],
                [-4, -3, -2, -1,  0],
                [-6, -5, -4, -3, -2],
                [-8, -7, -6, -5, -4]])

1

为从0m的向上运动次数创建ndarray对象。

2

使用向量化操作计算向量的平方。

3

使用u对象作为向量指数计算 2 的幂。

4

u对象从一维调整为二维。现在每行中存储向上运动的次数。

5

转置u对象以获得二维ndarray对象d,其中每列中的下降运动次数。

6

ud对象组合起来,得到向上和向下移动的净数目。例如,+2表示“比向下移动多两次向上移动”或-1表示“比向上移动少一次向下移动”。²

配备有包含二叉树中净移动次数的矩阵,股票价格过程的仿真归结为单行代码:

In [27]: S = S0 * np.exp(sigma * math.sqrt(dt) * (u - 2 * d))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         S  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[27]: array([[ 36.000,  39.786,  43.970,  48.595,  53.706],
                [ 29.474,  32.574,  36.000,  39.786,  43.970],
                [ 24.132,  26.669,  29.474,  32.574,  36.000],
                [ 19.757,  21.835,  24.132,  26.669,  29.474],
                [ 16.176,  17.877,  19.757,  21.835,  24.132]])

1

股票价格过程的向量化仿真(二叉树)。

2

与之前一样,只有对角线及以上的数字才相关。

对欧式和美式看跌期权的估值在某种程度上也进行了向量化。仅需对时间步长进行一次循环:

In [28]: h = np.maximum(K - S, 0)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         h  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[28]: array([[  4.000,   0.214,   0.000,   0.000,   0.000],
                [ 10.526,   7.426,   4.000,   0.214,   0.000],
                [ 15.868,  13.331,  10.526,   7.426,   4.000],
                [ 20.243,  18.165,  15.868,  13.331,  10.526],
                [ 23.824,  22.123,  20.243,  18.165,  15.868]])

In [29]: V = h.copy()  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)

In [30]: # European option pricing
         for t in range(m - 1, -1, -1):  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
             V[0:-1, t] = df * (q * V[:-1, t + 1] +
                            (1-q) * V[1:, t + 1])  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)

In [31]: V[0, 0]  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[31]: 3.977145694118792

In [32]: # American option pricing
         for t in range(m - 1, -1, -1):  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
             V[0:-1, t] = df * (q * V[:-1, t + 1] +
                            (1-q) * V[1:, t + 1])  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
             V[:, t] = np.maximum(h[:, t], V[:, t])  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

In [33]: V
Out[33]: array([[  4.540,   2.307,   0.784,   0.000,   0.000],
                [ 10.526,   7.426,   4.249,   1.771,   0.000],
                [ 15.868,  13.331,  10.526,   7.426,   4.000],
                [ 20.243,  18.165,  15.868,  13.331,  10.526],
                [ 23.824,  22.123,  20.243,  18.165,  15.868]])

In [34]: V[0, 0]  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/7.png)
Out[34]: 4.5395605952243

1

此次完全向量化的看跌期权内在价值的计算。

2

与之前一样,只有对角线及以上的数字才相关。

3

创建h对象的副本。

4

部分向量化的欧式看跌期权估值算法。

5

欧式看跌期权的现值。

6

部分向量化的美式看跌期权估值算法。

7

美式看跌期权的现值。

欧美期权

Cox、Ross 和 Rubinstein(1979)的(再组合)二叉期权定价模型之美不仅在于其简单性,还在于其能够高效且精确地对欧式期权和美式期权进行估值的事实。在极限情况下,时间步长无限小,该模型收敛于 Black-Scholes-Merton(1973)模型,这是另一个优点。

速度比较

向量化代码不仅使 Python 代码更简洁,而且通常可以显著提高速度。以下代码片段实现了前述算法,用于基于更大、更现实的时间步长进行速度比较。首先,需要调整基本数值参数:

In [35]: m = 500  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         dt = T / m
         df = math.exp(-r * dt)
         up = math.exp(sigma * math.sqrt(dt))
         down = 1 / up
         q = (1 / df - down) / (up - down)
         q
Out[35]: 0.5044724639230862

1

将时间间隔增加到一个现实水平,得出相当精确的数值期权价值。

函数binomial_looping()集成了对美式看跌期权的仿真和估值算法的基于循环的实现的所有要素:

In [36]: def binomial_looping():
             # stock price simulation in binomial tree
             S = np.zeros((m + 1, m + 1))
             S[0, 0] = S0
             z = 1
             for t in range(1, m + 1):
                 for i in range(0, z):
                     S[i, t] = S[i, t - 1] * up
                     S[i + 1 ,t] = S[i, t - 1] * down
                 z += 1
             # inner value calculation
             h = np.zeros_like(S)
             z = 1
             for t in range(0, m + 1):
                 for i in range(0, z):
                     h[i, t] = max(K - S[i, t], 0)
                 z += 1
             # American option pricing
             V = np.zeros_like(S)
             V[:, -1] = h[:, -1]
             z = 0
             for t in range(m - 1, -1, -1):
                 for i in range(0, m - z):
                     V[i, t] = df * (q * V[i, t + 1] +
                               (1 - q) * V[i + 1, t + 1])
                     V[i, t] = max(h[i, t], V[i, t])
                 z += 1
             return V[0, 0]

作者电脑上执行速度不到 200 毫秒:

In [37]: %time binomial_looping()
         CPU times: user 190 ms, sys: 4.69 ms, total: 194 ms
         Wall time: 190 ms

Out[37]: 4.486374777505983

In [38]: %timeit binomial_looping()
         173 ms ± 2.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

函数binomial_vectorization()集成了对美式看跌期权的仿真和估值算法的向量化实现的所有要素:

In [39]: def binomial_vectorization():
             u = np.arange(m + 1)
             u = np.resize(u, (m + 1, m + 1))
             d = u.T
             # stock price simulation
             S = S0 * np.exp(sigma * math.sqrt(dt) * (u - 2 * d))
             # inner value calculation
             h = np.maximum(K - S, 0)
             # American option pricing
             V = h.copy()
             for t in range(m-1, -1, -1):
                 V[0:-1, t] = df * (q * V[:-1, t + 1] +
                                (1-q) * V[1:, t + 1])
                 V[:, t] = np.maximum(h[:, t], V[:, t])
             return V[0, 0]

这种实现比基于循环的实现快约 40 倍,这充分展示了向量化实现方法在性能改进方面的强大力量:

In [40]: %time binomial_vectorization()
         CPU times: user 4.67 ms, sys: 2.39 ms, total: 7.07 ms
         Wall time: 8.73 ms

Out[40]: 4.486374777506075

In [41]: %timeit binomial_vectorization()
         4.7 ms ± 252 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

基础设施和性能

所有这里报告的绝对时间都取决于所使用的硬件和软件配置。例如,您可以在 Intel 处理器系统上使用NumPy英特尔数学核心库(MKL)的组合。这种组合可以显著加快数值运算速度。在不同基础设施上,相对时间和加速比应大致相似。

Black-Scholes-Merton 期权定价

Black-Scholes-Merton(1973 年)模型的静态仿真版本用于期权定价,在第五章中进行了讨论。本节介绍了他们开创性的期权定价模型的动态仿真版本。有关该模型的更多背景信息,请参阅第五章。

Black-Scholes-Merton(1973 年)经济的随机微分方程如下

d S t = r S t d t + σ S t d Z t

在时间t t >0处的股票价格,其中r ≥0是恒定的短期利率,σ >0是恒定的波动率因子,Z t是算术布朗运动(参见 Glasserman(2004 年,第三章)和 Hilpisch(2018 年,第十二章))。

蒙特卡洛模拟股价路径

假设时间𝒯 { t 0 = 0 , t 1 , t 2 , . . . , t M = T }中有限的相关点,具有M + 1 , M > 1,以及固定的时间间隔长度Δ t。给定前一股票价格S t-Δt,则股票价格S t , 0 < t T可以按照差分方程进行模拟。

S t = S t-Δt · exp r - σ 2 2 Δ t + σ Δ t z

其中z是标准正态分布的随机变量。这种方案称为欧拉离散化。已知它能确保随着Δ t趋于 0,离散时间过程收敛于连续时间过程。

动态蒙特卡洛模拟在静态模拟的背景知识支持下(参见第五章)在 Python 中易于实现。图 6-1 显示了 10 条模拟股价路径:

In [43]: S0 = 36.  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         K = 40.  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         r = 0.06  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         T = 1.0  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         sigma = 0.2  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [44]: M = 100  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
         I = 50000  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)

In [45]: dt = T / M  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
         dt  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[45]: 0.01

In [46]: df = math.exp(-r * dt)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
         df  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[46]: 0.9994001799640054

In [47]: from numpy.random import default_rng
         rng = default_rng(100)

In [48]: rn = rng.standard_normal((M + 1, I))  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
         rn ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[48]: array([[ -1.160,   0.290,   0.780, ...,   1.890,   0.050,  -0.760],
                [  0.460,  -1.400,   0.140, ...,  -1.350,   0.150,  -0.530],
                [  0.200,  -0.040,  -0.730, ...,   2.140,   0.170,  -0.340],
                ...,
                [ -0.220,  -1.310,   0.730, ...,  -0.820,  -0.600,  -0.400],
                [ -2.130,  -1.240,   0.580, ...,   0.960,   0.890,   0.780],
                [  2.130,  -0.410,   0.710, ...,   1.190,   0.100,  -0.520]])

In [49]: S = np.zeros_like(rn)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
         S[0] = S0  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
         S  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
Out[49]: array([[ 36.000,  36.000,  36.000, ...,  36.000,  36.000,  36.000],
                [  0.000,   0.000,   0.000, ...,   0.000,   0.000,   0.000],
                [  0.000,   0.000,   0.000, ...,   0.000,   0.000,   0.000],
                ...,
                [  0.000,   0.000,   0.000, ...,   0.000,   0.000,   0.000],
                [  0.000,   0.000,   0.000, ...,   0.000,   0.000,   0.000],
                [  0.000,   0.000,   0.000, ...,   0.000,   0.000,   0.000]])

In [50]: for t in range(1, M + 1):
             S[t] = S[t - 1] * np.exp((r - sigma ** 2 / 2) * dt +
                                    sigma * math.sqrt(dt) * rn[t])  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [51]: S  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)
Out[51]: array([[ 36.000,  36.000,  36.000, ...,  36.000,  36.000,  36.000],
                [ 36.349,  35.023,  36.114, ...,  35.056,  36.119,  35.633],
                [ 36.508,  35.009,  35.602, ...,  36.601,  36.259,  35.402],
                ...,
                [ 42.689,  39.760,  40.681, ...,  37.516,  47.893,  42.846],
                [ 40.921,  38.804,  41.175, ...,  38.260,  48.769,  43.534],
                [ 42.716,  38.499,  41.782, ...,  39.200,  48.884,  43.103]])

In [52]: from pylab import mpl, plt
         plt.style.use('seaborn')
         mpl.rcParams['font.family'] = 'serif'
         mpl.rcParams['savefig.dpi'] = 300

In [53]: plt.figure(figsize=(10, 6))
         plt.plot(S[:, :10]);  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)

1

金融参数与之前相同。

2

这些是蒙特卡洛模拟的参数(路径、时间步长、时间间隔长度、单个时间间隔的折现因子)。

3

生成了一个适当大小的标准正态分布随机数的二维ndarray对象。

4

另一个相同形状的二维ndarray对象被实例化,并设置了单只股票价格路径的初始值。

5

基于初始股票价格、随机数矩阵和几何布朗运动的差分方程,模拟了单只股票价格路径。

6

绘制前 10 条模拟路径。

ftwp 0601

图 6-1. Black-Scholes-Merton(1973 年)模拟股价路径

与静态情况一样,股票期末价值可以以直方图形式可视化(参见 图 6-2):

In [54]: ST = S[-1]
         plt.figure(figsize=(10, 6))
         plt.hist(ST, bins=35, color='b', label='frequency');
         plt.axvline(ST.mean(), color='r', label='mean')
         plt.axvline(ST.mean() + ST.std(), ls='--', color='y', label='sd up')
         plt.axvline(ST.mean() - ST.std(), ls='-.', color='y', label='sd down')
         plt.legend(loc=0);
In [55]: S0 * math.exp(r * T)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[55]: 38.22611567563295

In [56]: ST.mean()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
Out[56]: 38.25248936738523

1

数学期望值为 S T

2

所有模拟值 ST 的平均值。

ftwp 0602

图 6-2. Black-Scholes-Merton (1973) 模型模拟期末股票价格频率分布

欧式看跌期权的蒙特卡洛估值

欧式看跌期权价格的蒙特卡洛估计量是

P 0 = e -rT 1 I i=1 I max ( K - S T ( i ) , 0 )

其中 I 是模拟价格路径的数量。在这种背景下,欧式看跌期权定价仅涉及几行 Python 代码,仅需给定模拟股价路径。图 6-3 显示了到期内在价值的模拟直方图:

In [57]: h = np.maximum(K - ST, 0)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
         h  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)
Out[57]: array([  0.000,   1.501,   0.000, ...,   0.800,   0.000,   0.000])

In [58]: plt.figure(figsize=(10, 6))
         plt.hist(h, color='b', bins=35);  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
In [59]: math.exp(-r * T) * h.mean()  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
Out[59]: 3.818117261795047

1

以向量化方式计算内在价值。

2

绘制了到期内在价值的频率分布,说明典型的期权高度不对称回报。

3

计算所有内在价值的平均值并对其现值折现。

ftwp 0603

图 6-3. 欧式看跌期权到期内在价值模拟频率分布

美式看跌期权的蒙特卡洛估值

基于蒙特卡洛模拟的美式(看跌)期权定价稍显复杂。在这方面最流行的算法是 Longstaff 和 Schwartz (2001) 的最小二乘蒙特卡洛(LSM)算法,因为在数值和计算角度上相对简单高效。本章的范围不允许深入讨论,但可以呈现一种简明扼要、高度向量化的 Python 实现。有关应用于 Black-Scholes-Merton (1973) 模型经济学的 LSM 算法的详细处理,包括 Python 代码,请参阅 Hilpisch (2015, 第七章)。

下面的 Python 代码实现了 LSM 算法用于美式期权定价:

In [60]: h = np.maximum(K - S, 0)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/1.png)

In [61]: # Least-Squares Monte Carlo Valuation (LSM algorithm)
         V = h[-1]  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/2.png)
         for t in range(M - 1, 0, -1):  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/3.png)
             reg = np.polyfit(S[t], df * V, deg=5)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
             C = np.polyval(reg, S[t])  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/4.png)
             V = np.where(h[t] > C, h[t], df * V)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/5.png)

In [62]: df * V.mean()  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/fin-thr-py/img/6.png)
Out[62]: 4.454837750511421

1

计算完整股价路径 ndarray 对象的内在价值。

2

将初始模拟的美式期权价格值设定为到期内在价值。

3

该算法还基于反向归纳法,从 T - Δ t 开始,并在 Δ t 处停止。

4

这是算法的核心步骤,在此步骤中,根据当前模拟期权价值对股价水平进行 OLS 回归,估计(近似)继续价值。

5

如果内在价值高于估计(近似)的继续价值,就进行行权,否则不行权。

6

当前值被计算为基于 LSM 算法导出的在t = Δ t时刻的美式期权价格向量的平均值,并对剩余的时间间隔到当前t = 0进行折现。

提前行权和蒙特卡洛模拟

直到 1990 年代末,基于蒙特卡洛模拟的具有提前行权特征的期权和衍生产品的有效定价一直是一个主要未解决的问题。直到 2000 年初,研究人员才能够提出在模拟环境中处理提前行权的计算有效算法。在科学和金融中,一旦有了这样的算法——比如 LSM 算法——实现和应用几乎显得相当自然。毕竟,仅仅需要几行 Python 代码就能够基于模拟准确地估值本节中的美式看涨期权。然而,LSM 算法必须被视为金融计算时期的一个重大突破(见第一章)。

结论

本章以比较非正式的方式介绍了两种流行的、动态完备的金融模型。第一种是由考克斯-罗斯-鲁宾斯坦(1979 年)提出的所谓再组合二叉树模型。其美妙之处在于其简单性,它使人能够以高中数学为基础以一种数值高效的方式实现欧式期权和美式期权定价。与需要高级随机微积分的连续时间金融模型相比,它还是一个很好的“教学和理解”工具。

第二种模型是 Black-Scholes-Merton(1973 年)连续时间期权定价模型的动态蒙特卡洛模拟版本。使用NumPy模拟技术,动态蒙特卡洛模拟也可以以数值高效的方式实现。即使是包含耗时 OLS 回归步骤的 Longstaff 和 Schwartz(2001 年)的计算要求较高的最小二乘蒙特卡洛算法,基于向量化技术实现时也相当快速。

总之,NumPy凭借其强大的向量化能力再次证明,它不仅可以编写简洁的算法代码,而且可以实现快速的执行时间——即使在更加现实和复杂的动态模型经济环境下也是如此。

进一步资源

本章引用的论文有:

  • Black, Fischer 和 Myron Scholes. 1973. “期权定价与公司负债。” 政治经济学杂志 81 (3): 638–659.

  • Cox, John, Stephen Ross 和 Mark Rubinstein. 1979. “期权定价:一种简化方法。” 金融经济学杂志 7 (3): 229–263.

  • Duffie, Darrell. 1986. “随机均衡:存在性、跨度数及金融交易无预期收益假设。” 计量经济学 54 (5): 1161–1183.

  • Longstaff, Francis 和 Eduardo Schwartz. 2001. “模拟法估值美式期权:一种简单的最小二乘方法。” 金融研究评论 14 (1): 113–147.

  • Merton, Robert. 1973. “理性期权定价理论。” 贝尔经济与管理科学杂志 (4): 141–183.

本章引用的书籍:

  • Duffie, Darrell. 1988. 证券市场—随机模型. 圣迭戈: Academic Press.

  • Glasserman, Paul. 2004. 金融工程中的蒙特卡洛方法. 纽约: Springer Verlag.

  • Hilpisch, Yves. 2018. Python 金融学. 第二版. Sebastopol: O’Reilly.

  • Hilpisch, Yves. 2015. Python 衍生品分析. Wiley Finance.

  • Pliska, Stanley. 1997. 数学金融导论. Malden 和 Oxford: Blackwell Publishers.

¹ 本章假设的参数来自 Longstaff 和 Schwartz(2001 年,表 1)。

² 需要注意只有对角线及以上的数字是相关的。忽略对角线以下的数字,这些数字是在ndarray对象上实现的特定向量化操作的结果。

³ 此处,正如在实践中经常见到的,有大量情况是期权无价值到期,即回报为 0。

第七章:Where to Go from Here?

An investment in knowledge pays the best interest.

Benjamin Franklin

Politics is for the present, but an equation is for eternity.

Albert Einstein

Congratulations. You have reached the final chapter of the book. If you have followed the chapters diligently, you have already encountered many important ideas and concepts in both financial theory and Python programming. That is great. The topics covered in this book, both with regard to breadth and depth, represent good starting points for exploring the exciting and fast-changing world of computational finance. However, there is much more to explore and learn. This final chapter provides suggestions for moving on and going deeper in one or several directions in Python for finance.

Mathematics

This book makes use of different mathematical tools and techniques, such as from linear algebra, probability theory, and optimization theory. The tools and techniques applied to financial problems are fairly standard and do not require advanced mathematical skills to be put to beneficial use with Python. However, modern finance can be considered an applied mathematics discipline, with some areas relying heavily on advanced mathematics—such as option pricing or financial risk management.

The following list provides references for several standard textbooks that can be used to improve your mathematical skills for finance:

  • Aleskerov, Fuad, Hasan Ersel and Dmitri Piontkovski. 2011. Linear Algebra for Economists. Heidelberg: Springer Verlag.

  • Bhattacharya, Rabi and Edward Waymire. 2007. A Basic Course in Probability Theory. New York: Springer Verlag.

  • Jacod, Jean and Philip Protter. 2004. Probability Essentials. Berlin and Heidelberg: Springer Verlag.

  • Pemberton, Malcolm and Nicholas Rau. 2016. Mathematics for Economists—An Introductory Textbook. 4th ed. Manchester and New York: Manchester University Press.

  • Protter, Philip. 2005. Stochastic Integration and Differential Equations. 2nd ed. Berlin and Heidelberg: Springer Verlag.

  • Rudin,Walter. 1987. Real and Complex Analysis. 3rd ed. London: McGraw-Hill.

  • Sundaram, Rangarajan. 1996. A First Course in Optimization Theory. Cambridge: Cambridge University Press.

  • Williams, David. 1991. Probability with Martingales. Reprint 2001. Cambridge: Cambridge University Press.

Financial Theory

金融是一个广阔的领域,涵盖许多不同的专业领域。本书涵盖了一些最重要和流行的金融模型,如均值-方差投资组合理论、资本资产定价模型以及 Black-Scholes-Merton 期权定价模型。更广义地说,它涵盖了简单和更现实的静态模型经济(仅有两个时间点)以及动态模型经济,允许不确定性随时间逐渐解决。然而,有些在数学金融中的领域并未涵盖,比如需要额外、更高级数学工具的期权定价连续时间模型。本书也未讨论诸如有效市场假说(EMH)等重要的金融主题。

以下列表提供了几本基础金融书籍,可用于更广泛地了解金融理论主题及其在经济学中的基础:

  • Copeland, Thomas, Fred Weston and Kuldepp Shastri. 2005. 金融理论与企业政策. 第四版. Boston: Addison Wesley.

  • Eichberger, Jürgen and Ian Harper. 1997. 金融经济学. New York: Oxford University Press.

  • Markowitz, Harry. 1959. 投资组合选择—有效分散投资. New York: John Wiley & Sons.

  • Milne, Frank. 1995. 金融理论与资产定价. New York: Oxford University Press.

  • Pliska, Stanley. 1997. 数学金融导论. Malden and Oxford: Blackwell Publishers.

  • Rubinstein, Mark. 2006. 投资理论史. Hoboken: Wiley Finance.

  • Varian, Hal. 1992. 微观经济分析. 第三版. New York and London: W.W. Norton & Company.

对于那些希望深入研究金融中的高级数学建模的人,以下是一些关于数学金融的高级教材列表:

  • Baxter, Martin and Andrew Rennie. 1996. 金融微积分—衍生品定价导论. Cambridge: Cambridge University Press.

  • Björk, Tomas. 2004. 连续时间套利理论. 第二版. Oxford: Oxford University Press.

  • Delbaen, Freddy and Walter Schachermayer. 2006. 套利的数学. Berlin: Springer Verlag.

  • Duffie, Darrell. 1988. 证券市场—随机模型. San Diego: Academic Press.

  • Duffie, Darrell. 2001. 动态资产定价理论. 第三版. Princeton: Princeton University Press.

  • Elliot, Robert and Ekkehard Kopp. 2005. 金融市场数学. 第二版. New York: Springer Verlag.

  • Glasserman, Paul. 2004. 金融工程中的蒙特卡洛方法. New York: Springer Verlag.

毫无疑问,阅读那些金融模型和理论的原始文章也常常是有益且启发性的。您会发现许多这些文章令人惊讶地易于理解。下面的列表列出了这些文章,选择受到本书涵盖的主题和方法的启发:

  • Black, Fischer 和 Myron Scholes. 1973. “期权定价和公司负债.” 政治经济学杂志 81 (3): 638–659.

  • Boyle, Phelim. 1977. “期权:蒙特卡罗方法.” 金融经济学杂志 4 (4): 322–338.

  • Cox, John 和 Stephen Ross. 1976. “备选随机过程的期权定价.” 金融经济学杂志 (3): 145–166.

  • Cox, John, Jonathan Ingersoll 和 Stephen Ross. 1985. “利率期限结构的理论.” 计量经济学 53 (2): 385–407.

  • Cox, John, Stephen Ross 和 Mark Rubinstein. 1979. “期权定价:一种简化方法.” 金融经济学杂志 7 (3): 229–263.

  • Duffie, Darrell. 1986. “随机均衡:存在性、跨度数和金融交易没有预期收益假设.” 计量经济学 54 (5): 1161–1183.

  • Harrison, Michael 和 David Kreps. 1979. “多期证券市场中的鞅和套利.” 经济理论杂志 (20): 381–408.

  • Harrison, Michael 和 Stanley Pliska. 1981. “连续交易理论中的鞅和随机积分.” 随机过程及其应用 (11): 215–260.

  • Heston, Steven. 1993. “具有随机波动率的期权的封闭形式解法及其在债券和货币期权中的应用.” 金融研究评论 6 (2): 327–343.

  • Longstaff, Francis 和 Eduardo Schwartz. 2001. “通过模拟对美式期权进行估值:一种简单的最小二乘法方法.” 金融研究评论 14 (1): 113–147.

  • Markowitz, Harry. 1952. “投资组合选择.” 金融杂志 7 (1): 77–91.

  • Merton, Robert. 1976. “当基础股票回报不连续时的期权定价.” 金融经济学杂志, 3 (3): 125–144.

  • Perold, André. 2004. “资本资产定价模型.” 经济展望杂志 18 (3): 3–24

  • Protter, Philip. 2001. “金融资产定价理论的部分介绍.” 随机过程及其应用 (91): 169–203.

  • Sharpe, William. 1964. “资本资产价格:在风险条件下市场均衡的理论.” 金融杂志 19 (3): 425–442.

对于那些寻找单一、全面参考资料的人来说,市场风险分析图书系列可能值得仔细研究:

  • Alexander, Carol. 2008. 市场风险分析 I—金融定量方法. Chicester: John Wiley & Sons.

  • Alexander, Carol. 2008. 市场风险分析 II—实用金融计量经济学. Chicester: John Wiley & Sons.

  • Alexander, Carol. 2008. 市场风险分析 III—定价、对冲和交易金融工具. Chicester: John Wiley & Sons.

  • Alexander, Carol. 2008. 市场风险分析 IV—风险价值模型. Chicester: John Wiley & Sons.

Python 编程

如今,有大量的资源可供学习 Python 编程。以下书籍对我来说非常有用。当涉及到成为更好的 Python 程序员,并且您只想从列表中挑选一本书时,您应该选择 Ramalho(2021)的书籍,该书深入探讨了 Python 编程语言本身:

  • Harrison, Matt. 2017. Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works. http://hairysun.com.

  • McKinney, Wes. 2017. Python for Data Analysis. 2nd ed. Sebastopol: O’Reilly.

  • Ramalho, Luciano. 2021. Fluent Python. 2nd ed. Sebastopol: O’Reilly.

  • Ravenscroft, Anna, Steve Holden, and Alex Martelli. 2017. Python in a Nutshell. 3rd ed. Sebastopol: O’Reilly.

  • VanderPlas, Jake. 2016. Python Data Science Handbook. Sebastopol: O’Reilly.

Python for Finance

这本书是我关于 Python 应用于金融的第六本书。您可能会想:“为什么最基础的入门教材要排在其他五本更高级的教材之后?” 对此可能没有一个简短而简单的答案。然而,编写这本书《Python 金融理论》的动机来自于读者对其他书籍以及我们的在线培训项目的请求。许多人都在寻找一个既介绍金融又介绍 Python 编程的入门教材,这样就可以补充其他书籍。¹ 因此,《Python 金融理论》从零开始介绍了这两个主题,从而弥补了最初的差距,例如开始使用书籍《Python 金融理论》,读者预期在金融和编程方面有一些背景。

我的其他五本书是:

  • Hilpisch, Yves. 2020. Artificial Intelligence in Finance: A Python-Based Guide. Sebastopol: O’Reilly.

  • Hilpisch, Yves. 2020. Python for Algorithmic Trading: From Idea to Cloud Deployment. Sebastopol: O’Reilly.

  • Hilpisch, Yves. 2018. Python for Finance: Mastering Data-Driven Finance. 2nd ed. Sebastopol: O’Reilly.

  • Hilpisch, Yves. 2017. Listed Volatility and Variance Derivatives: A Python-Based Guide. Wiley Finance.

  • Hilpisch, Yves. 2015. Derivatives Analytics with Python: Data Analysis, Models, Simulation, Calibration and Hedging. Wiley Finance.

金融数据科学

数据科学已经成为几乎每个行业中一个重要的学科和功能。同样地,金融数据科学 已经发展成为金融中一个核心学科和功能。不断增长的数据量使得应用更先进和复杂的数据物流和管理方法变得必要。Excel 电子表格显然已经不再足够。我的书 Python for Finance 主要讲述的是 Python 在金融数据科学中的应用。该书第二部分和第三部分涵盖的相关主题包括:数据类型和结构,使用 NumPy 进行数值计算,使用 pandas 进行数据分析,面向对象编程,数据可视化,金融时间序列,输入/输出操作,高性能 Python,数学工具,随机过程和统计学(包括基本机器学习)。在你完成了 金融理论与 Python 后,书 Python for Finance 就成为提升你的金融 Python 技能的自然下一步。

算法交易

系统化或算法交易不仅成为对冲基金的标准,甚至对许多散户交易者也是如此。强大的 API 的普及,甚至使得预算较小的散户交易者在几乎所有资产类别中都能实现算法交易策略的繁荣。虽然一般较大的金融机构在交易过程的每一个步骤都有专门的团队 — 从数据分析、研究、回测到部署、监控和风险管理 — 散户交易者通常需要独自完成所有这些工作。

几年前对单个人来说可能看起来几乎不可能的事情,现在由于 Python 强大的生态系统,可以相对轻松地实现。具备 Python 编程技能的散户交易者原则上可以在几周甚至几天内建立起一个算法交易操作。我的书 Python for Algorithmic Trading 涵盖了这一背景下所需的主要 Python 技能,并引导读者从数据管理和创意生成到策略回测及其在云端的自动部署。

Python for Finance 的第四部分也涵盖了 Python 中算法交易的关键技能。虽然没有 Python for Algorithmic Trading 那么详细,但基于 Python for Finance 中的自包含资源,读者仍然应能够有效生成和部署自动交易策略。

对于 Python for Algorithmic Trading 书籍以及 Python for Finance 的第四部分,读者事先学习 Financial Theory with PythonPython for Finance(第一、二、三部分)虽然有帮助,但不一定是必需的。

计算金融

定量和计算金融长期以来一直被编译型编程语言如 C 或 C++所主导。这是因为时常复杂的数值计算和模拟的执行速度至关重要,特别是当大型金融机构需要可扩展性时。虽然纯 Python 可能实施起来确实太慢,比如计算密集型的模拟算法,但是像NumPypandas这样的包在适当使用时可以大大提高执行速度。这些包提供高级别的编程 API,其功能通常是用高性能 C 代码实现的。与纯 Python 代码相比,这通常可以加快速度 10 到 30 倍,使得 Python 加上专业包成为当前计算金融的有效替代方案。

我的书《Python 衍生品分析》介绍了定价和对冲衍生品所需的主要数学和金融概念,以市场为基础的定价模型。该书提供了一个独立的 Python 代码库,从头开始实现所有算法和技术,充分利用了NumPy的功能。那些已经阅读过《金融理论与 Python》和《Python 金融分析》(第一、二、三部分)的人,已经具备了通过《Python 衍生品分析》深化他们的数学和计算金融知识的良好基础。

第五部分的《Python 金融分析》开发了一个简化版的我的衍生品定价库DX Analytics。它展示了如何利用《Python 衍生品分析》中的概念、方法和数值方法来创建基于蒙特卡洛模拟的灵活强大的定价库。那些需要额外模型和更多功能——比如风险测量和管理——当然可以使用 DX Analytics 开源包本身。

近年来,作为一种资产类别的波动性变得非常重要。无论是为了管理风险还是生成额外的α收益,列出的波动性和方差衍生品在全球范围内以系统化的方式使用。《列出的波动性和方差衍生品》介绍了交易和定价此类金融工具的主要概念,并提供了一个独立的 Python 代码库,以易于复制的方式展示所有概念——比如方差的无模型复制或者计算波动性指数。

人工智能

可以肯定的是,人工智能(AI)未来在金融领域将扮演主导角色,就像它已经在许多其他行业中做的那样。基本上每家金融机构都已启动项目,探索 AI 提升运营效率、节约成本、生成 Alpha 等潜力。来自机器学习、深度学习和强化学习的算法已经在金融各个领域进行了测试并投入使用。研究人员和学者也在以越来越快的速度发表涉及 AI 和金融交汇点的论文。

我的书金融人工智能第一部分提供了关于 AI 及其成功案例的背景和历史信息。第二部分讨论了传统金融理论及其近期进展,如数据驱动金融和 AI 优先金融。第二部分还讨论了机器学习作为一个过程。本书的第三部分介绍和讨论了来自深度学习的主要模型和算法,如密集神经网络(DNNs)、循环神经网络(RNNs)和强化学习(Q-learning)。本书的第四部分说明了通过算法交易可以经济地利用金融市场的统计效率低下,即通过交易机器人,后者基于 Q-learning 算法交互地学习如何进行交易。本书的第五部分讨论了 AI 优先金融对金融行业竞争格局的影响。它还讨论了金融奇点的可能性——即存在一个人工金融智能(AFI),它可以(几乎)完美地预测未来市场价格的时刻。

书籍金融人工智能可以被视为书籍Python 量化交易的补充,因为它详细讨论了基于 AI 的算法交易策略的制定、回测和风险管理。读者在深入探索金融 AI 的迷人世界之前不必先读过算法交易的书籍。但是,通过本书以及Python 金融的第一部分到第三部分,对 Python 在金融领域的扎实理解是有帮助的。

其他资源

你可能已经注意到,本节仅讨论了我个人关于 Python 金融的书籍。本节的目的正是引导已经完成本书的读者了解我的其他作品。当然,今天有许多其他以书籍形式存在的资源,涵盖了与金融相关的 Python 主题或应用于金融的机器学习算法。虽然其他作者也提供有价值的内容和指导,但喜欢本书的读者可能也会喜欢我的其他书籍,因为它们在风格和方法上相似。

虽然一些读者最有效地使用书籍和相关代码进行学习,其他人则喜欢更互动、引导式的学习体验。我的公司 The Python Quants GmbH 多年来提供了全面的在线培训计划,以系统化、结构化的方式教授从我的书籍中学到的技能以及更多内容。截至撰写本文时,有三种不同的在线培训计划可供选择:

这三个项目也可以合并成一个项目,适合那些从 所有核心主题 中受益的人。

结语

祝贺再次。通过 Python 金融理论,您已经为在金融领域使用 Python 迈出了下一个激动人心的步伐奠定了基础。本章为您提供了丰富的资源以供探索。如果您将 Python 金融视为一项需要定期、认真和系统训练的技能,您很可能很快就会达到黑带水平。这样的成就不仅在个人上有所回报,而且还会保证您在未来的成功,因为 Python 金融毫无疑问已成为金融行业的关键技能。愿 Python 之力与您同在。

¹ 我喜欢将这本书比作 J.R.R. 托尔金的 霍比特人 对其 指环王 三部曲的关系。当然,这里并没有文学上的比较意味。

posted @   绝不原创的飞龙  阅读(39)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示