Professional Documents
Culture Documents
Python 金融实战
Python for Finance
[美] Yuxing Yan著
张少军严玉星译
人民邮电出版社
北京
图书在版编目 (C I P) 数据
Python金融实战/(美)严玉星著,张少军, 严玉
星译 -- 北京:人民邮电出版社, 2017. 7
ISBN 978-7-115-45707-3
-
I. (DP … II. CD严
@张… III. …
软件工具 — 程序 CD
设计 应用-金恐-分析IV. (DF830. 41-39
中国版本图书馆CIP数据核字(2017)第100748号
版权声明
Copyright©2014 Packt Publishing. First published in the English language under the title Python for Finance.
• 著 [美) YuxingYan
译 张少军 严玉星
责任编辑 胡俊英
责任印制 焦志炸
• 人民邮电出版社出版发行 北京市丰台区成寿寺路 II 号
邮编 100164 电子邮件 3 I 5@ptpress.com.cn
网址 http://www.ptpress.com.cn
北京市艺辉印刷有限公司印刷
• 开本: 800xl000 1/16
印张: 21.75
字数: 420于字 2017年7月第1版
印数: 1-2 000册 2017年7月北京第1次印刷
著作权合同登记号 图字: 01-2016-3953 号
定价: 79.00元
读者服务热线: (010) 81055410 印装质昼热线: (010) 81055316
反盗版热线: (010) 81055315
\
内容提要
严仲仪(父) 王秀珍(母)
金清(岳父) 阴家菊(岳母)
写给中国读者的几句话:
201 7年 3月于美国水牛城
作者简介
张少军博士,1996 年 7 月毕业千北京清华大学,获应
用数学和计算机技术双学士学位。 自 1996 年 8 月至 2001
年 5 月在美国佛罗里达州立大学继续深造, 先后获得统计
学硕士学位和金融统计学博士学位。现任香港理工大学会
计与金融学院副教授。
审稿人简介
“我要感谢导师们在我初到交易大厅的那段日子里对我的关照和培养 。
”
\
..a.&. .....
削百
为什么选择 Python?
选择 Python 有多种原因。 首先, Python 是开源的, 公众可以免费使用。 Python 可用于
几乎所有的主流操作系统上 , 如 Windows、 Linux/Unix、 OS/2、 Mac 和 Amiga, 等等。 学
习和使用免费软件有众多的好处。 毕业以后, 学生 可以把他们所学到的 Python 编程技能用
在任何工作岗位, 包括在金融领域。 与 此相反, 收费软件如 SAS 和 MATLAB 取决于公司
或单位是否订购。 其 次, Python 功能强大、 灵活、简单易学。 它能够解决几乎所有的金融
和经济方面的计量问题。 第三, Python 有处理大数据的能力。 Dasgupta (2013) 认为 R 和
Python 是当前最流行的两个用于数据分析的开源软件。 第四, Python 有许多有用的模块。
模块是为完成 一个特殊的任务 而开发的。 在本书中, 我们将学习 NumPy、 SciPy、 Matplotlib 、
Statsmodels 和 Pandas 等模块。
这是一本由金融学教授撰写的编程图书
毫无疑问, 大多数的编程图书是由计算机专业的教授和专家撰写的。 由一 位金融学教
授撰写 本书来介绍 一 门编程语言似乎十分奇怪。 其 实不然, 本书的重点和众多由计算机专
家所写的书完全不 同。 计算机专家们会把重点放在 Python 语言本身, 而正如本书的书 名所
示, 本书的重点是介绍 Python 在金融领域的应用。 作者希望为读者提供一 本将 Python 与
金融紧密结合的书。
2 前言
侧重短小而实用的 Python 程序
作者曾经在多所世 界 著名 大学任教, 包括加拿大的麦吉尔大 学和劳里埃大学、 新加坡
的南洋理工大 学 、 美国的Loyo al 大学、UMUC、Hofstra 大学、水牛城大学和 Ca nisi us学院。
他还在美国的沃顿商学院从事过 8年的技术咨 询工作。 丰富的教学和咨询经验告诉他, 大
多数金融专业的学生需要掌握编写 短 小 的程序以完成某些特 定 的任务。 大 多数编程类图书
只提供 了 几 个完整但复 杂的程序, 但对于循序渐进的学习过程而言, 程序的数 目 远远不足,
这将导致两 种后果。 首先, 读者往往淹没千 复 杂程序的细 节之中, 从 而产生 畏惧心理, 最
终 失 去学习计算机语言的任何兴趣。 其 次, 他们不知道 如何灵活运用 编程语言来解 决金融
领域的一 系列 问题, 例如, 如何用 1 99 0年�2013年的数据和资 本资 产定价模型 ( CAP M )
来估计 I BM 的 市场风险系数。 本书提供了大 约 300 个与许多金融领域相 关的 P ytho n 程序 。
使用 真实数据
编程类 的 图 书 往往有 一 个 共 同点, 就是它们常 常 使用虚构 的数据。 本书 将 大 乱 使用与
各种金融 课题相 关的真实数据 。 例如, 不仅仅只是介绍资 本资 产定价模型 CAP M 和市场风
险系数( 贝 塔值或 p), 读者学习如何利 用 实 际 数据来估计 I BM、 苹果和沃 尔 玛等公司的贝
塔值, 而不仅仅只是讲 解用来估 算投资组合的收益和风险的数学公式 。 本书会给出 P ytho n
程 序来从 互 联网 上 直接下载实时的交易数据, 构造不 同的股票组合, 然 后计算其 收益和风
险, 包括在险价值 ( VaR)。
本书的主要 内 容
第 1 章简短地介绍 P ytho n 并讨论如何安装、启 动和退出 P ytho n, 以及 一 些相关的问题。
第 7 章通过 mat p lot ilb 模 块绘制 金融相关的图形, 展 示 如 何 利 用 mat p lot ilb 模 块绘制不
同颜色和大小 的 图表和图形来生动地解释有 关的金融概念。
读 完 本 书 后 有 什 么收获 ?
我们通过 一 些具体 的例子来说 明 本书可能带给读者 的 收获。 首先, 本书的前两 章能够
帮助读者使用 Python 来计算现值、 未来值、年金现值、内部收益率, 以及 许多其他常 用 的
金融公式 。 也就是说, 我们 可以使用 Pyth on 作为一 个普通计算器来解决不少与金融相 关的
问题。 其次, 第 3 章能够 帮助读者把几十 个短小 的 Pyth on 程序结合成 一 个大的 Pyth on 模
块, 从 而用 Pyth on 完成 金融专业计算器的功能 。 这 自 制 的 模块与其他 Pyth on 模 块 一 样使
用。 第 三, 读者学习 如何编写 Pyth on 程序来下载和处理 各类开源数据, 包括雅虎财经网站、
谷歌财经网 站 、 美联储 的数据库 和 F re nch教授的在线数据库 等。 第 四 , 读者 将理解与模块
相关的基本概念。 模块是指由专家、 其他用户或 自 己编写 的 用 于 特定用途的 程序包。 第 五 ,
在了解了 mat p lot ilb 模块的特性 后, 读者可以制作各种图表。 例如, 通过绘制图形展示不同
股票和期权的交易策 略 的 收益I利润函数。 第 六, 读者将能够下 载 I BM 的 每 日 交易价格、
市场指数 ( S&P 5 00)、 雅虎财经网站的数据和运用CAP M 估计市场风险系数 ( 贝 塔值)。 亦
可以用 不 同的证券 ( 如国 债 券 、 企业债券和 股 票 、 构建投 资组合), 并且 应用马 科维茨 的 均
值-方 差模 型来优化 自 己 的投资组合。 此外, 读者会知道如何估计 其投 资 组 合 的 在险价值
( V aR)
。 第 七, 读者应该能够应用 B al ck-Sch ole s-Me rt on 期 权定价模型和蒙特 卡 罗 模 拟为欧
式或美式期权定价。 最后, 读者 能够学习 量度波动率 的 几种方法, 特 别 是 自 回 归 条件异方
差 ( ARCH )和广 义 自 回 归 条件异方差 ( GARCH )模型。
4 前言
本书 的 目 标读者
本书面向金融相关专业的从 业人士 , 尤其 是计算金融 、 金融建模 、 金融工程和商业分
析等专业方向的读者 , 会发现本 书大有裨益 。 对金融领域感兴趣的读者 也可以通过本书学
习 Python , 并把它用千许多金融项 目之中。 个人投 资者也能从 本书 受益。
约定
本书用不同的文本样式 区分不 同种 类的内容 。 下面给出 一 些 例子 , 帮助认 识这些 样式
并 了 解它们的意义。
任何命令行输入或输出如下所示:
按 钮, 然后启动所有程序 。
”
前言 5
使 用 本书 的 两 种方式
读者反馈
读者反馈 是 我们 一 直期盼的。 请 让 我们知道你对本书的意见, 包括喜欢或不喜欢的地
方。 我们渴 望读者从 本 书得到最大 的收获。 因此, 你的反馈意见至关重要。 请 把反馈意见
以电子 邮件发送至 feedback@packtpub.com , 并在邮件的主题里
包括本书的书名。
客 户 支持
作为 Packt 出版物的拥有者, 你应当感到 自 豪, 同时也会获得 我们在多方面提供的服务。
下 载示例代码
下载书 中 的 彩 色 插 图
勘误表
关千盗 版行为
读者疑 问
目录
1 .4 运 行 Python 的 3 种方式 … … … … … .. 4
2.6 删 除 或取 消 变量 · · · · · · · · · · · · · · · · · · · · · · · · · … 1 7
. 找到 一 个 已安装的模块 的
5. 28 6.18 利 用 种子 ( seed)生成 可重复
目 录 位置 ....... . .......... . . . . . . . . . . . . . . . . 71 的随机数 ....................... . . . . ........... 93
5.2 .9 有关模块 的更多信 息 … … … … … · 72 6.19 在导入的模 块里查找函数 … … .... 94
5.2. 1 0 查找某个未安装的模块 \… … … 72 6.20 简介 .... … ......... ... ......... .. 95
优化算 法
5.3 模块之间 的相互 依 赖性 … … … … .... 73 6.21 线性 回 归和资 本资 产定价模型
小 结 .............. .................................. 74
5. 4 CCAP M ) .................................... 9 5
练习题 ..................................... . ............... 75 6.22 从 文本文件(. txt)输入数 据:
loadtxt()和 getfr omtxt()函 数 . … · 96
第6章 NumPy 和 SciPy 模块 简介 … … .. 76
6.23 独立安装 N urnPy 模块 … … … … · … 9 7
6.1 安装 N umPy 和 SciPy 模块 … … … .. 77 6.24 数据 类型简介 ........ .. . . … … . . . . . . . . … · 9 7
6.2 从 A n ac ond a启动 Pyth on … … … … ·· 77 6.25 1J、 结 ··········· · ··· ········ · ··· · · · · · · · · · · · · · · · · · · · 98
6.2. 1 使用 NwnPy 的示例 … … … … … .. 73 练习题 · · · · · · · · ·· · · · · · · · · ········ · · · · · ·· · · · · · · · · · · · · · · · · · · · · 98
6. 2 .2 使用 Sc iPy 的示 例 … … .. … … … … 79
6.3 显示 N umPy 和 SciPy包含的所有 第7章 用 matplotlib 模块 绘 制 与 金 融
相 关 的 图 形 ....... ... ..................... 101
函数 . . . . . . . .................... . . . . . . ............... 3 2
6.4 关于某 个函数的详 细 信 息 … …… .. 33 7.1 通过 Ac tivePyth on 安装 m at p lot ib l
6.5 理解列 表数据 类型 … … … … … … … …83 模 块 . . . . . ........................ .................1 02
6.6 使用 全 一 矩 阵 、 全零矩阵和 7.2 通过 A n ac ond a安装 m at p lot ibl
单位 矩 阵 ····· · · · · · · · · · ·· · · · · · · · · · · · · · · · · · · · · · · · 84
· 模块 . . . . ........ ......... . . . . . . ............. ......103
6. 7 执行数组操作 · · ··· ··· · · · · · · · · · · ··········· ···84 7.3 m at pl ot ibl 模 块简介 … … … … … … … 103
6.8 数组的加、 减 、 乘、 除 … … … … · · · 8 · 5 7.4 了 解 简单利 率和复利利率 … … . . . .106
6.8.1 进 行 加减 运算 .. . . . .......... ...... . . ... . g 5 7.5 为 团 形添 加文字 ..... ..... ........... .....1 0 7
6.8.2 执行矩 阵乘法运算 … … · …… … …85 7.6 杜邦 等式 的图示 . . .. … ....... … .........1 09
6.8.3 执行 逐项相乘 的乘 法运算 … ..... 3 6 7. 7 净现值图示 曲 线 .. … … … … … … … … 110
6.9 x. sum(函数
) . . ............ ............ .......... 3 7 7. 7.l 有效地使用 颜色 … · …… … … … . . 113
6.10 遍历数组的循环 语句 … … … … … …87 7. 7.2 使用 不同 形状 . . ........ . . . . . . . ..... … 114
6.11 使用 与 模块相关的帮助 … … … ..... 3 7 78
. 图形演 示分散投资 的效果 … … … · 115
6.12 SciPy 的一 系列 子函数包 …… … …88 7.9 股票的数 目和投资组合风险 …… 11 7
6.13 累 积标准正 态分布 … … … … … … … 89· 7.1 0 从 雅虎财经网站下载历史
6.1 4 与 数组相关 的逻辑关 系 .. … … … … 9 0 价格数据 .............. ...................... 119
6.15 SciPy 的统计子模块 C st at s) … .. 9 0 7. 1 0. l 用 直 方 图显 示收益率分布 … · 1 20
6.16 SciPy 模块的插值方法 … … … … … · 91 7.10.2 比较单只 股票的 收益和
6.1 7 使用 SciPy 求 解线性方程 … … … · · 92 市场 收 益 .................. . ............122
4 Python 金 融 实 战
本章主要 内 容 如下 。
• Python简介
• 如何安 装 Python
• 错误提示
• Python 是区分大 小写的
• 变量的初始化
• 查看 自 己的 Python 版本
1 .1 Pytho n 简介
1 .2 如何安装 Python
采取以下两 个步骤来安装 Pyth on 。
I . 访问 Pyth on 的官方 网站下载 。
• 从 Pyth on 命 令行 。
• 从 DOS 命令行窗 口 。
1 .3 Python 的 不 同 版本
有关 Pyth on 安装最常见的问题之 一是: 我们应该下载哪 个版本? 在这 个阶段, 任何最
新的版本都可以。 换言之, 对于 初学者而言版本并不重要, 原因有三 。
4 第 1 章 Python 简介 及 安 装
• 卸 载 旧 的版本和安装新的版本易如反掌。
1 .4 运行 Python 的 3 种方式
以下介绍启 动 Python 的 3 种方式。
P汴hon 33
f7' lDLE (Python GUI)
rt' Module Docs
r' Python (com 叩 nd line)
酴 P灿on Manuals
侍 Unin申II Python
图 1 -1
图 1 -2
计算未来现金流的现值的公式如下 。
FV
P V= ( 1-1 )
( l + RY
»> 1 0 0 / ( 1 + 0 . l )
]
90 . 9090909090909
>>>
I . 单击开始菜单, 展开 所有程序 选项 。
“ ”
2 . 生戈至IJ Python 3 .3 。
Python 33
(?• [OLE (Python GUI)
fr> Module Docs
占 Python (command line)
酴 环hon M-,nu沁
弱 Unin寸:all Python
图 1 -3
,:,;i C:\Pytho函\p如hon 赵e
----,.日
丘匠卫
图 1 -4
cmdl X
妒雪遭仁勤瑾 图 1 -5
2 . 输入 cd c : \ pytho n 3 3 移动 到相应的 目录 。
3 . 输入 PY七hon 命令来运行软件, 如图 1 -6 所示 。
图 1 -6
1 .5 如何退 出 Python
以下 是退 出 Python 的几种常用方法。
• 按 Ctrl+D 组合键。
• 按 Ctrl+Q 组合键。
1 .6 错误提示
对 千 前面的例 子 , 如果 1 00 美元在 两 年 后 获 得 , 输 入 1 0 0 / ( 1 + 0 . 1 ) " 2 而 不 是
1 0 0 / ( 1 + 0 . 1 ) * * 2 , 会看到下面的出 错信息。 它告诉我们 , 不 支 待 ^ 运算符号。
» > 1 0 0 / ( 1 +0 . 1 ) " 2
T raceback (mo s t recent call_l a s t ) :
File " <psyhe l l # l > , line 1 , in <modul e >
1 0 0 / ( 1+0 . 1 ) " 2
T ype E rror : unsupported operand t ype ( s ) for " : ' f loat ' and ' in七 '
>>>
下载示例代码
可 以 从 网 站 http : / /www . pac ktpub . com 上的账户
沁)
下 栽所有 已 购 买 的 书 籍 , 包括的 示 例 代码 。 如 果 你 在
其 他 地 方 购 买 了 这 本 书 , 可 以 访 问
http : / / www . pac ktpub . com/ s uppo rt 并 注 册 ,
这样含有的代码文件通过电子邮件直接发送给你 。
>>>x = 2
>>>X
Traceback (most recent cal l l a s t ) :
File "<pyshe l l # l > " , l ine 1 , in <module>
X
NameError : name ' X ' is not de fined
>>>
1 .8 变量 的 初始化
1 .9 寻找在 线 帮 助
\
启 动 Python 之后 , 输入 help ( ) 打 开 在 线 帮 助 ( 如 以 下代码所示 ) 。 在 线 帮 助 的 提 示
符 是 h e l p > 。 只 需 按 一 次 回 车 键或输入 qu i t 就 可 以 退 出 在线帮 助 。 退 出 之 后 , Python 提
示符>>>将 再 次 出 现 。
>>> hel p ( )
Welcome to Python 3 . 3 ! This i s the interactive help u t i l i 七 y .
I f this i s your f i r s t t ime us ing Python , you shou ld defini 七 e l y check out
the tuto rial on the In 七 ernet at http : / / docs . python . o rg / 3 . 3 / tutorial / .
Ente r the name o f any modu l e , keyword, or top i c to get help on writing
Python programs and usi ng Python modu l e s . To qu it this help u t i l i ty and
re 七 urn to the interprete r , j us t type " qu i t " .
To get a l i s t o f ava i l able modul e s , keywords , or 七 opi c s , t ype "modu l e s " ,
" keywords " , or " topics " . Each modul e also comes with a one - l ine summa ry
o f what i t does ; to list the modu les who se summa r i e s con 七 a i n a given word
such as " spam " , type "modu l e s spam" .
help>
输入 keywo rds 后 , 将 得 到 如 下 信 息 。
>>>help> keywords
Here i s a l i s t of the Python ke ywords . Enter any keyword to get mo re help .
Fal s e de f if raise
None de l import return
True elif in try
and else is wh ile
as except Lambda Wi 七 h
assert final l y Nonlocal Yield
break for Not
class f rom Or
continue g l obal Pass
help >
另 外 , 输入 topics 后 , 将 会 看 到 许多 关键词 , 如 图 1 -7 所 示 。
1 0 第 1 章 Python 简 介 及 安 装
help> cop工cs
Here i,s a li,st of available topic,i . Enter any topic n釭正 to get more help .
伈 lp >
图 1 -7
1 .10 查找 学 习 手册和教程
执行以下步骤来得到已经安装在电脑里的资 料 。
l . 单击开始菜单, 然后展开 “ 所有程序 ” 选项 。
I 丛 Python33
� IDLE (Python GUI)
� Module Docs '
, 研on (command fine)
啦 Python Manuals
创 Uninstall Python
图 1 -8
1 . 1 0 查找 学 习 手 册 和 教 程 1 1
立
ci
屯 臣l .,
辱5
^g
心 !«a•
仁 饮b心
nu 心心血屯 妇 八
寸一
知
Tutorial
SI
Extending and Embedding
tutortal tor C'Ctt programmers
S1annere
D 心勺and lJcen的
Pythonic API
Library Reference reterer心 归 CJC++ programmer.I
keep 伽SU心 ryour,-
Installing Python Modules
Language Reference intormar/Ofl tor ,心劝爬rs & 3)'$-识勿uns
戊劝杞ssyn啦 andlanguage elements
Distributino Pvthon Modules
图 1 -9
http://docs.python.org/3.2/download.html
。 http://docs.python.org/3/tutorial/
。 http://docs.python.org/2/tutorial/
• PDF version (424pages):
。 http://www.tutorialspoint.com/python/python_pdf_version .htm
12 第 1 章 Python 简 介 及 安 装
。 http://anh.cs.luc.edu/python/hands-on/3. I /Hands-onPythonTutorial.pdf
1 .1 1 如 何 找 出 Python 的版本
>>>import sys
>>>sys . vers ion
' 3 . 3 . 2 ( v3 . 3 . 2 : d0 4 7 9 2 8 ae3 f 6 , May 1 6 2 0 1 3 , 0 0 : 03 : 4 3 ) [ MSC v . 1 6 0 0 32 bit
( Int e l ) ] '
>>>
1 . 1 2 小结
练习题
\
4 . Python 是 否 区 分大小写 ?
5 . 是否可以不定义就使用 一 个变量 ?
一
6 . 是否可以不给 个变量赋值就使用它 呢 ?
8 . 有哪几种方式可以运行 Python ?
12 . 如何赋值给 一 个新的变扯 ?
13. 如何能找到与 Python 有关的 一 些示例 ?
• 变量的赋值
• 显 示 一 个变量的值
• 错误提示
• 选择有意义的变量 名
• 使用 dir ( ) 来查找变量和函数
• 删 除或取消变量
• 基本的数学运算: 加 、 减、 乘、 除
. 幕函数 、 取整和余数函数
• 选择合适的精度
• 找出指定的 内 置函数的详细 信息
• 如何导入数学模块
• pi、 e、 对数和指数函数
• 元组数据类型简介
2. 1 变量的赋值 及显示
\
赋值给 一个 Python 变量非常简单。 我们不 需要定义 一个变量就 可以给它赋值 。 这 一 点
与其他语言 , 如 C开或 FORTRAN 不 同。
>>>pv= 22
>>>pv +2
24
一
可以同时给儿个变量赋予同样的值。 在 下 面的例子中 , 次给 3 个变量 x、 y 和 z 赋
值 1 0 0。
>>>x = y=z = l O O
>»pv= l O O
>>>pv
100
>>>R=O . l
>>>R
0.1
2.2 错误提 示
>>>s qrt ( 3 )
Traceback (most recent call l a s t ) :
File " <pyshe l l # l 7 > " , line 1 , in <module>
sqrt ( 3 )
Name E rror : name ' sqrt ' is not def ined
>>>abc de
Traceback (mo s t recent call l a s 七 ) :
File " <pyshe l l # O> " , line 1 , i n <module >
abcde
NameError : name ' abcde ' i s not defined
>>>
C
PV(永久年金 ) = — ( 2-1 )
R
100
2.5 使 用 dir()来查找变量和 函 数
>> >pv= l O O
>>>r = O . l
> > > n= S
>>>dir ( )
[ ' bui l tins ', ' do c ', ' name ', ' package ', 'n' , ' pv ' , 'r' )
>>>
2.6 删 除或取消 变量
一 一
以 上 出 错信 息 最 后 句 告 诉我们 , 变 量 rate 没有 被 定 义 。 如 果 需要 次 删 除 儿 个变
量 , 可 以 用 逗 号 把它们 分 隔 , 例 如 :
>>>pv= l O O
>>>r = 0 . 8 5
>>>dir ( )
[ ' builtins ' doc ', ' name ' pa c ka ge ', ' pv ' , ' r' l
>>>del pv , r
»>dir ( )
[ ' built ins ' doc ', ' name ' pac kage ']
2.7 基本数学运算 : 加 、 减 、 乘 、 除
Python 中 基 本 的 数 学 运算 采 用 传 统 的 数 学运 算 符 : + ( 加 ) 、 - ( 减 ) 、 * ( 乘 ) 、 I ( 除 )
一
运算 。 下 面 行代码包括所有这些运算符 。
>>>3 . 0 9+2 . 1 * 5 . 2 - 3 / 0 . 5 6
8 . 652857142857144
一
如 果 意外地输 入除 号 两 次 ( // ) , 会 得 到 个奇怪的 结 果 。 双斜杠II代表整 数 除 法 , 运算
一
结 果 是给 出 个 比商 数 小 的 最 大 整 数 。 7 除 以 3 的 结 果 为 2 . 3 3 , 2 是 比 2 . 3 3 小 的 最大整
数。 例如 :
>>>7 . / 3
2 . 3333333333333335
在 Python 2 .x 版 本 下 , 7 / 3 可 能 是 2 , 而 不 是 2 . 3 3 3 。 因 此 , 我 们 必 须 小心 。 在金融
计 算 中 较 少使用 整 数 除法 。 为 了 避 免 整 数 除 法 , 可 以 使用 7 . / 2 或 7 / 2 . , 即 这两 个数 中 至
一
少有 个 是真 正 的 浮 点 数 。
>»7 / / 3
2 2.8 幕 函 数 、 取整和余数 函 数 19
>>>x = 7 . / 3
>>>x
2 . 3333333333333335
>>>i n t ( x )
2
2.8 幕 函 数 、 取整和余数 函 数
FV
PV = ( 2- 3 )
(l + RY
»> 1 0 0 / ( 1 +0 . 1 ) * * 2
8 2 . 6 4 4 62 8 0 9 9 1 7 3 5 4
1 C
P V ( 永久年金 , 第1 笔现金流发生m周期末 ) = (2-4 )
(l + Rf- I R
20 第2章 用 Python 完 成 普 通 计 算 器 的 功 能
» > 1 0 / 0 . 0 8 / ( 1 + 0 . 0 8 ) * * ( 9- 1 )
67 . 5 3 3 6 1 0 5 62 7 4 696
2.9 一个真正 的 幕 函 数
FV=PV( l +Rt ( 2 -5 )
>>>pv= l O O
>>>r = O . l
>>>n= l
>>>pv* ( l + r ) * * n
ll0 . 00000000000001
>>>pow ( 2 , 3 )
8
>> > l O O * pow ( ( l + O . 1 ) , 1 )
110 . 00000000000001
>>>he l p (pow)
Help on bu i l t - i n func t i on pow i n modul e bu i l 七 ins :
2. 10 选择 合 适 的 数 值 精度 21
pow ( . . . )
pow ( x , y [ , z ] ) -> number
With two a rguments , equivalent to x * * y . With three ar guments ,
equival en t to ( x * * y ) % z , but may be mor e e f f i c i en t ( e . g . for l ong s ) .
根据上述的 内 容 , 可 以 这 样 使用 该 函 数 。
>>>pow ( 3 , 1 0 , 4 )
1
>>>3 * * 1 0 % 4
1
>> > 3 * * 1 0
59049
>»5 9 0 4 9 % 4
1
Python 所谓 的 LEGB 规 则 与 局 部 变量 和 全 局 变 量 有关 。 该 规 则 如 表 2- 1 所示 。
勹::
表 2-1
变 益 的 变益
二 二二二二
二
:二二
G 全局 的 , 是指那 些在模块 的 顶 部 定 义 的 变 量 , 或在 函 数 中 ( def) 定 义成全局变量 的 变盘
2. 1 0 选择合 适 的 数值精度
Python 的 默 认 精 度 为 1 6 位 小 数 , 例 如 :
>>>7 /3 .
2 . 3333333333333335
对 大 多 数 与 金 融 有 关 的 问 题或研究这样 的 精 度 足够 高 了 , 可 以 使用 round ( ) 函 数 来 改
变精度 。
>> >payme n t l = 3 / 7 .
>>>payment l
0 . 42857142857142855
>>>payment2=r ound ( payment l , 5 )
22 第2章 用 Python 完 成 普 通 计 算 器 的 功 能
>>>payment2
0 . 42857
>>>payment l * l 0 * * 6
42857 1 . 4285714285
>>>payment2 =round (paymen 七 1 , 2 )
>>>payme nt2
0 . 43
>>>paymen t2 * 1 0 * * 6
430000 . 0
2. 1 1 找 出 某个 内 置 函 数 的 详细信息
一
要 了 解某 个 数 学 函 数 的 详 细 信 息 , 可 以 使 用 h e l p ( ) 函 数 , 比 如 help ( r oun d ) ,
如 以 下代码所 示 。
>>>help ( round)
Help on buil 七 - i n function round i n modu le buil tins :
round ( . . . )
round ( numbe r [ , ndi g i t s ] ) -> number
Round a number to a given precis ion in decimal
digits ( de fault O digit s ) . This returns an int when
cal le d with one argument , othe rwi se the s ame t ype as
the numbe r . ndigits may be negative .
2. 1 2 列 出 所有 内 置 函 数
为 了 找 出 所 有 内 置 函 数 , 采 取 以 下 两个 步 骤 。 首 先 , 我们用 d i r ( ) 列 出 代表所有 内 置
函 数 的 默 认名 称 , 即 bu 辽 t i n s 。 注 意该名 称 有 两 个 下 划 线 为 前缀和 另 外两 个 下 划 线
为后缀。
\
>» di r ( )
[ ' bui l t i ns ' doc ', ' name I pack age I ' I X I l
然 后 , 输入 di r ( bu 旦 巨 n s ) , 第 1 行 和 最 后 几行 的输 出 结 果 如 下 。
2. 1 3 导 入 数 学模 块 23
>>>di r ( bu i l t in s )
[ ' Ar ithme t i c E r ror ' , ' As s e r t i onError ' , ' At tr ibuteEr r o r ' ,
' Bas eExcep t i o n ' , ' B lockingIOError ' , ' BrokenPipeE r ror ' ,
' Bu f fe rE r r o r ' , ' BytesWarning ' , ' Chi ldProc e s s E r ro r ' ,
' range ' , ' repr ' , ' reve r s ed ' , ' round ' , ' s e t ' , ' s etattr ' ,
' s lice ' , ' s or 七 ed ' r I S 七 aticme 七 hod ' , ' str ' , ' s um ' ,
' s upe r ' , ' tupl e ' , ' t yp e ' , ' var s ' , ' z ip ' ]
2. 1 3 导入数学模块
使 用 金 融 市 场 的 实 际数据解答 许 多 问 题 , 比 如 从雅虎财经 网 站 下 载 数据 , 构 建 最 佳 的
一
投 资 组 合 , 估计个股或股票组合 的波动 率 , 找 出 最 佳 组合 。 针对每 个 问 题 , 有关专家开
发 了 相 应 的模 块 。 必 须 将 其 导 入 Python , 然 后 才 能 使用 它 。 例 如 , 可 以 用 import math 导 入
一
常 用 的 数 学 函 数 。 下 面 的代码用来计算 个数值的平方根。
>>>import math
>>>math . s qrt ( 3 )
l . 732050807568772
为 了 找 出 数 学模块 中 包含 的 所有 函 数 , 再 次 调 用 d江 ( ) 函 数如 下 。
>>>import math
>>>di r (math )
[ ' doc ' , ' name ' pac kage ' acos ' , ' a cosh ' , ' a s in ' , ' as i nh ' ,
' a tan ' , ' a 七 an2 ' , ' a tanh ' , ' c e i l ' , ' copys i gn ' , ' cos ' , ' cos h ' , ' degree s ' , ' e ' ,
' e rf ' , ' e rfc ' , ' exp ' , ' expm l ' , ' fabs ' , ' fac 七 oria l ' , ' f l oo r ' , ' fmod ' ,
' frexp ' , ' fsum ' , ' gamma ' , ' h ypot ' , ' i s inf ' , ' i snan ' , ' l dexp ' , ' l gamma ' ,
' '
' l og ' , ' log l O ' , ' l o g lp ' , ' modf ' , ' pi ' , ' pow ' , ' radians ' , ' s in ' , ' s .1.nh ' ,
' sqrt ' , ' tan ' , ' t anh ' , ' trunc ' )
>>>import ma th a s m
>>>m . sqrt ( S )
2 . 2 3 6067 9 7 7 4 9 9 7 9
24 第2章 用 Python 完 成 普 通 计 算 器 的 功 能
2. 1 4 冗 、 e 、 对数和指数 函 数
兀 C 3 . 1 4 1 59265 , 在 Python 程序中用 " pi " 表示) 和 e ( 2.7 1 828 ) 是数学的常量, 用以
下 代码显示它们的值。 第 1 个命令导入 math 模块。 现阶段, 初学者只 需要记住这些 命令,
暂时不需要了解它们的含义。 以后有 4 章内容 详 细 解释 模块的用 途。
>>>dir ( )
[' builtins ' doc ' , ' name ' , ' packag e ' , ' acos ' , ' acosh ' ,
' a s in ' , ' a s i nh ' , ' a tan ' , ' atan2 ' , ' atanh ' , ' ce i l ' , ' c opys i gn ' , ' co s ' ,
' cos h ' , ' degree s ' , ' e ' , ' e rf ' , ' er f c ' , ' exp � , ' e xprn l ' , ' fabs ' , ' factor i al ' ,
' f loor ' , ' fmod ' , ' frexp ' , ' f sum ' , ' gamma ' , ' h ypot ' , ' i s in f ' , ' i snan ' ,
' l dexp ' , ' l gamma ' , ' l og ' , ' logl O ' , ' l oglp ' , ' rnodf ' , ' pi ' , ' pow ' , ' radians ' ,
' s in ' , ' s i nh ' , ' s qr 七 ' , ' t an ' , ' t anh ' , ' 七 rune ' ]
的。 例如:
>>>pi
3 . 1 4 1 5 92 65 3 5 8 97 9 3
>>>math . pi
Tr aceback (most recent call l a s 七 ) :
F i l e " <pyshel l # 2 5 > " , l i ne 1 , i n <modu l e >
math . pi
NameE r r o r : name ' math ' i s not de f i ned
>> pi
3 . 1 4 15 9 2 6 5 3 5 8 97 93
>>>p i = l O
>>>pi
10
>>>dir ( )
[ ' bu i l t ins ' do c ', ' name ' pa ckage 'l
>>>
在导入后:
2. 1 6 一些常 用 的 函 数
2.16. 1 print()函数
有时, 需要在屏幕上显示一 些 内 容 。 一
种方法是应用 p r i nt ( 函
) 数, 例如:
26 第2章 用 Python 完 成 普 通 计 算 器 的 功 能
2.16.2 type()函数
在 Python 中, 七 ype ( ) 函数告 诉 我们一 个变量的类型, 例如:
>>>pv= l 0 0 . 2 3
>>> typ e ( pv)
< c l a s s ' f l oat ' >
>>>n = l O
>>> type ( n )
< c l a s s ' i nt ' >
>>>
2.16.3 下划线_
在交互 模 式中, 下划线符号 " _ " 代表前面最后一 个表达式的结果。
>>>x = l . 5 6
>>> y = S . 7 7
>>>x+y
7 . 33000000000000000001
>>>9+
1 6 . 32999999999999998
>>>r ound ( _ , 1 )
16. 3
2.16.4 结合两个字符串
可以通过 多种方式使用字符 串 。 有以下两 种方式为字符变量赋值。
>>>x+y
2. 1 6 一些常用 的 函 数 27
可以把赋值操作和 s t r i p ( ) 函数连起来用。
此命令的输 出 结 果 如下。
>>>dir ( I I )
[ ' add ' , ' c l a s s ' , ' contains ' , ' de l a 七 t r ' , ' doc ' ,
' eq ' , ' f ormat ' , ' ge ' , ' getattribute ' , ' get i tem ' ,
. .
' getnewargs ' , ' ge t s l ice ' , ' gt ' , ' ,hash . ' , ' in 工 t I I
le ' , ' l en ' , ' 1 t ' , ' mod ' , ' mul " ' , ' ne ' , ' ' new '
reduce ' , ' reduce e x ' , ' repr rmod ' , ' rmul
setattr ' ,.. s 1. ze o f. . ' , ' s t r ' , . ,subclas shook ,
' _formatter_fiel d_name_spl i t ' , ' _formatter_parser ' , ' capi t a l i z e ' ,
' c ente r ' , ' coun 七 ' , ' dec ode ' , ' encode ' , ' endswith ' , ' expand tab s ' , ' f ind ' ,
' format ' , ' i nde x ' , ' i s a l num ' , ' i s a lpha ' , ' i sdig it ' , ' i s l owe r ' , ' is space ' ,
, i s t i t l e ' , ' i s upper ' , ' j o in ' , ' l j us t ' , ' l owe r ' , ' l s 七 r ip ' , ' parti t i on ' ,
' r eplac e ' , ' r f i nd ' , ' r i ndex ' , ' r j ust ' , ' rparti tion ' , ' r spli t ' , ' rs 七 ri p ' ,
I spl i t I ' I sp l i 七 l i nes ' , ' s tarts wi th ' , ' strip ' , ' swapcase ' , ' t i t l e ' ,
28 第2章 用 Python 完 成 普 通 计 算 器 的 功 能
upper ( . . . )
S . uppe r ( ) - > s t r i n g
Re七urn a copy o f t h e st r i n g S conve r七ed to upp e r ca s e .
capi ta l i z e ( . . . )
S . cap i t a l i z e ( ) - > s 七 ri n g
Re七urn a copy o f 七he s 七 r ing S with o n l y i t s f i r s t character
cap i ta l i zed .
>>>
2. 1 7 元组数据类型
> > > i nves 七ment= ( ' NPV ' , 1 0 0 , ' R= ' , 0 . 0 8 , ' ye ar ' , 1 0 )
>>> 1nve s tment ( l ]
100
> > > i nvestment ( l ] =3 4 5
Traceback ( mo s t recent c a l l l as t ) :
F i l e " <pyshe l l # 3 > " , l ine 1 , i n <modu le>
inve s trnent [ l ] = 3 4 5
TypeError : ' tuple ' obj ect does no七 suppor七 i t em a s s i gnmen t
2. 1 8 小结
练习题
l . 展示
变量是否存在和显示它们的值之间有什 么 差异 ?
3. 内置函数的定义是什么 ?
4 . 元组是什么 ?
>>>abc = ( 11 John 11 )
6 . 如何改变 一 个元组的值 ?
2 2
<Yn-day <Yn-day = na-daily
1 7 . 符号/和II有何区别 ?
>>> x = S . 5 6 6
>>> round ( x , 2 )
>>>
5 . 57
C
PV(增长型永 续年金) =
R-g
第3章
用 Python 编 写 一 个金融计算器
• 编写不需要保存的 Python函数
• 输 入函数参数值的 3 种方式及它们的预设值
• 利用 d江 ( ) 检查刚完成的
函数是否存在
• 保存 自 写 的 pv_f ( )函数
• 生成 自 制的模块
• 两 种 注释方法
• if (函
) 数
• 计算年金
• 利率换算和连续复利利率
• 数据 类型: list
• 显示在某 个 目 录下的指定文件
• 用 Pyth on 编写 一 个金融计算器
3. 1 编 写 不 需要保存的 Python 函 数
从 编写 一 个最
简单的 Pyth on函数开始 。 以下 是计算未来现金的现值的数学公式 。
FV
PV = C 3- l )
( 1 + R) "
>>> de f pv_f ( fv , r , n ) :
r e t u rn fv/ ( l + r ) * * n
>>>
>» pv_f ( l 0 0 , 0 . 1 , 1 )
90 . 9090909090909
>>> pv_f ( B 0 , 0 . 0 5 , 6 )
5 9 . 697231730930 1 9
如 果 函 数 的 输 入 参 数 没 有 预 设 值 , 调 用 函 数 时 就 需 要 提 供 参 数值 , 否 则 会得到 出 错 的
信息 。
一 一
缩进格式在 Python 语 言 中 非 常 重 要 。 以 下 是 个用 R 语言编 写 的 计算现值 的 函 数 ,
一
对 花括 弧定 义 了 该 函 数 的 主体语 句 , 每 行 语 句 是 否 有 缩进 并 不 重 要 。
一
Python 函 数 用 缩 进来定 义 函 数 的 主 体 , 由 具 有 同 样大 小 缩进 的 语 句 构 成 同 个函数。
def pv_f ( fv , r , n ) :
pv = fv/ ( l + r ) * * n
return pv
可 以用 3 种 方 式输入 函 数 的 参 数 值 。
C l ) 如 上 例 所 示 , 调 用 函 数 p v_f ( l 0 0 , 0 . 1 , 1 ) 直 接输入 3 个 参 数 值 1 0 0 、 0 . 1 和
1 。 依 据 3 个 参 数 出 现 的 顺序可 以 判 定 1 0 0 是 未 来 现 金 董 , 0 . 1 是 每期 折现率 , l 是 未 来
多少期。
( 2 ) 采用 参 数 的 关 键词 , 不 需 要 依 据 固 定 的顺序输入参数 , 如 下 面 的 例 子所 示 。 这种
方 式 的 好 处 是避 免 因 为 忘 记参数顺 序 而 带 来 的 错 误 , 这 在 使 用 由 不 同 的 开发人 员 编 写 的 函
数 时 尤其有用 。
( 3 ) 混合使用 前 两 种 方 式 。
3.5 在 Python 编辑器里 定义 函 数 35
3.4 检查 自 己编 写 的 函 数是否存在
»>di r ( )
[ ' bui ltins ' ''
', ' doc ', ' name ', ' package ' , ' pv . f ' ]
,
分两步保存函数。
def pv_f ( fv , r , n ) :
return fv/ ( l + r ) * * n
>>>dir ( )
,
[ ' bu i l t ins ', ' doc ', ' file ', ' l o ade r ', ' n ame ',
, package ' , 1 PV fI ]
>>>
>>> pv_f ( l 0 0 , 0 . 1 , 1 )
90 . 9 0 9 0 9 0 9 0 9 0 9 0 9
>>> import t e s t O l
» > dir ( )
[ ' buil t i n s ' , ' doc ' , ' file ', ' l oader ', ' name ',
' package ' , ' t e s 七 0 1 ' J
>>> t e s t O l . pv_f ( l 0 0 , 0 . 1 , 1 )
90 . 9090909090909
以 下 的 函 数语 句 有 一 个 明 显 的 错 误 : 第 1 行 以 小 写 字 母 r 代表输入 参 数 , 但第 2 行却
用 大 写字母 R 来 使 用 该 参 数 。
def pv_f ( fv , r , n ) :
return fv/ ( l+ R ) * * n # a t ypo o f r
3.8 调 用 pv_f() 函 数 的 两 种 方 法
在使用包含在 t e s t O l . p y 中 的 pv_f ( ) 函 数 时 , 可 以 用 i mport t e s t O l 或 f rom
t e s t O l imp o r t * 。 显然 , 使 用 pv_ f ( ) 比 t e s t O l . pv_f ( ) 要 简 单得 多 。 例 如 :
3.9 生成 自 制 的模块
C
PV(永 久 年金) = —
R
0-2 )
return fv* ( l +r ) * * n
3. 1 0 两种 注释方法
3.10.1 第 1 种注释方法
Python 语言 用符 号#来标识注释 。 每 一 行语句中#之后的字符就是注释, 不会对语 句 的
执行产生影 响 。
在 函数的定义中加入注释来说 明 函数的参数及用法 。
3.10.2 第 2 种注释方法
使用#号便于添加单行注释,但不利 于添加多行的注释 。 Python 语言的第 2 种注释方法
1 1 1 1 11
是用一对重复 3 次的双 引 号 ( 即 ) 来界定注释 。 下面用此方法为 pv_f ( ) 函数加入多行
的注释 。
de f pv_f ( fv , r , n ) :
40 第3章 用 Python 编 写 一 个 金 融 计 算 器
11 11 1 1
return fv / ( l + r ) * * n
3. 1 1 查找有关 pv_f() 函 数 的 信 息
pv_f ( fv , r , n )
Obj ect i ve : e s t imate p r e s e n t value
fv : future value
r : d i s count periodic rate
n : number of p e r i ods
f o rmu l a : f v / ( l + r ) * * n
e.g. /
>>>pv f ( l 0 0 , 0 . 1 , 1 )
90 . 9090909090909
> >>pv_f ( r=O . l , fv=l O O , n= l ) ,
90 . 9090909090909
>> >pv f ( n = l , fv= l O O , r=O . l )
90 . 9090909090909
3. 1 2 条件 函 数 : if()
以下公式用于 计算增长型永久年金的现值 。
P V( 永久年金) = C 3-3)
R-g
C
de f pv_growing_pe rpetu i t y ( c , r , g ) :
if ( r<g) :
p r i n 七 ( " r<g ! ! ! ! " )
el s e :
re 七 urn ( c / ( r - g ) )
3. 1 3 计算年金
PMT l
P V( annuity) = C 3-4 )
· [1 - ( l + R Y
R ]
PMT I
P V (annu 句1 due) = [1 - l + 1 + R) C 3-5)
· R ( R )" }
PMT
FV ( annU lty
. )= [ ( 1 + R) " - I ] ( 3-6 )
R
PMT
F V( annuity due) = [ O + R )" - l ] ( I + R ) C 3- 7)
R
P V(grow;ng annu;ty) 1-
=: :[ 严 (::;J ]
( 3-8 )
计 算 增长型年金的未来值的公式如下。
PMT
F V( growing
. annui.ty ) = [ (1 + R )" - (1 + g f C 3-9 )
R -g ]
3. 1 4 利 率换算
假设 A 银行提供按半年复利年利率为 5%的贷款, B银行提供按季复利年利 率为 5.1%
的贷款 。 为了获得较低的利率, 我们应该从 哪 家银行借钱 ? 这个例子涉及不 同利 率之间的
转换 。 首先看 看用给定年利 率 ( annual perc entage rate , APR ) 计算 有效
年利率 ( effective annual
rate , EAR ) 的公式 。
EA R = ( I + A= r 习 C 3-10)
R
>>> ( 1 + 0 . 0 5 / 2 ) * * 2 - 1
0 . 05062499999999992
»> ( 1+0 . 0 5 1 / 4 ) * * 4 - 1
0 . 0 5 1 9 8 3 6 92 1 1 4 0 6 66 1 5
芯ti龙 = 竺
0-1 1 )
或者可以写 出下面的公 式 。
APR, P
(I + r = ( I + A R, J
m1 m2
0- 1 3 )
APR,
R'f;'"" = ( I + t -l
mi
0- 1 4 )
»>r= ( 1 + 0 . 0 5 / 2 ) * * ( 2 / 1 2 ) - 1
>>>r
44 第3章 用 Python 编 写 一 个 金 融 计 算 器
0 . 0 0 4 1 2 3 9 1 5 4 65 1 4 42 3 4 5
> >>pv = 3 0 0 0 0 0
>>>n= 3 0 * 1 2
>>>pm 七 =pv * r / ( 1 - 1 / ( l+r ) * * n )
> >>pm t
1 6 0 1 . 072 0 3 6 4 2 62 6 65
>>>
3. 1 5 连续 复 利 利 率
Re = m * In ( 1 + A=勹 0-1 5 )
第 4 章中看涨期权的计算公式 使用的无风险利率必须是连续复利 。
3.17 净 现值 和 净 现 值 法 则 45
3. 1 6 数据类型 : 列 表
>>>len ( record)
>>>record [ O ]
4
, John '
>>>record [ 2 : ]
[ ' Engineer ' , 3 ]
3. 1 7 净现值和 净现值法则
如 果 直接计算净现值 , 可 以 用 如 下 的 代 码 。
>>>r=0 . 0 5
>>>- 1 0 0 + 2 0 / ( l + r ) + 4 0 / ( l + r ) * * 2 + 5 0 / ( l + r ) * * 3 + 2 0 / ( l + r ) * * 4 + 1 0 / ( l + r ) * * 5
2 2 . 8 0 9 9 8 92 7 3 0 37 0 7
一 一
个更好的方法是编写 个 NPV 函 数 , 通过输入折现率 和 所 有 的 现金流 , 包括今天的
支 出 以 及 未 来 的 收 入 来计算 NPV。 启 动 Python 后 , 单 击 FilelNew Window 命令( 或按 Ctrl+N
一
组合键 ), 然 后 输 入 以 下 代码。 单 击 RunlRun Module 5 命 令 。 注 意 , 如 果 要 求输入 个文件
名 , 可 以 输入 npv_f . py 。
>>>r=0 . 0 5
>>>cashf lows= [ - 1 0 0 , 2 0 , 4 0 , 5 0 , 2 0 , 1 0 )
>>>npv_f ( r , c a s h f l ows )
3. 1 9 内部收益率和 内部收益率法则 47
22 . 8 0 9 9 8 9 2 7 3 0 3 7 0 7
3. 1 8 投资 回 收期和投资 回 收期 法则
» > 4 0 / 5 0 +2
2.8
3. 1 9 内 部收益率和 内 部收益率 法则
内部收益率 ( internal rate of return , IRR ) 是使得净现值为零的折现率 。 IRR 法则是指,
如果项 目的内部收益 率比资 本成本大, 就接受这 个项 目, 否则拒绝它, 如下所示。
f o r i i n range ( l , interations+ l ) :
rat e * = ( l- npv_f ( r ate , cash f l ows ) / i nvestme n t )
return rate
对 于 初 学 者 , 这个程序 显 得 有 些 过 于 复 杂 。 如 果 不 能 完全理解 , 并 不 会 影 响 对 本 章 其
余 部 分 的 学 习 。 range C l , 1 0 0 + 1 ) 语 句 给 出 1 � 1 0 1 的 区 间 。 变 量 l 取值为 1 � 1 0 1 。 换
句 话 说 , 第 5 行代码将重复执行 1 0 1 次 。 第 5 行 基 于 的 假 设 是 , R 和 NP V 是 负 相 关 的 。 换
句 话 说 , 增加折现率 R 导 致较 小 的 NP V。
为 了 帮 助 理解 最 关键 的 第 5 行 , r a t e * = ( l -npv_f ( r a t e , c a s h f l ows ) /
i nv e s tmen 七 ) 。 可 以把 它 简 单 地看作 以 下 等 式 。
>>>cashfl ows= ( - 1 0 0 , 2 0 , 4 0 , 5 0 , 2 0 , 1 0 ]
>>>x=IRR_f ( c ashfl ows )
>>>x
0 . 1360125939440155
由 此 可 见 , 如 果 资 本 成 本 是 5%, 我们会接受这个项 目 。 可 以 把 它 作为 折现 率 并 使 用
npv_f ( ) 函 数验证上述结 果 , 代码如 下 。
也可以编写 一 个 名为 d江2 ( ) 的
函数来模 仿 d江 ( 函
) 数。 所不同的是, di r ( 函
) 数列
出了 内 存里的
变量和函数, 而 d i r 2 ( 函
) 数显示在 一 个给定 目录中的+文件。 因此, d江 ( )
函数不需要输入参数, 而 d i r 2 ( 函
) 数需要一 个输入值, 就是需要检 查的 目 录, 如以下代
码所示。
de f dir2 (path) :
f rom os import l i s tdir
print ( l i stdi r (path) )
de f f in l O l ( ) :
l ) Ba s i c func tions :
PV : pv_f , pv_annuity, pv_pe rpe tur it y
FV : fv_f , fv_annuity, fv_annuity_due
2 ) How to use pv_f ?
> > >hel p ( pv_f )
5 . 用以下的代码来调用这 个
函数。 假 设 f i n l O l . py 文件包括 3 个函数: pv_f ( ) 、
fv f ( ) 禾0 f i n l O l ( ) 。
import sys
myFolder = "C : \ \Yan\ \Teaching \ \ Python_for_Fi nance\\codes_chapters "
i f myFolder not in sys . path :
sys . path . append (myFolde r )
• P V 为 现值
• FV 是 未 来 值
• R 是 每 期 有 效 利 率 ( 折现率 )
• n 是周期的数 目
• C 是 一 个永久年金 或 定 期 年 金 的 每 期支付
• g 是一 个 增 长 型 永 久 年 金 ( 定 期 年 金 ) 的 增 长 率
• APR 是 年 利 率
• R e 是连续 复 利 利 率
• m 是每年复利 次数
一
需要注 意 的 是 C、 R 和 n 应 该 是 致 的 , 也 就 是 具 有 相 同 的 频率 ( 或单 位 时 间 ) 。 Python
金融计算器用 到 的 公 式 如 下 。
表 3-1
FV
FV=PV(l + R)" PV =
(I + R)"
C
PV( 永久年金)=— 假设第 l 次现金流批发生在第 1 期 的 结尾
R
P
PV( 定期年金)= MI' [ I - I
] 假设第 1 次现金流狱发生在第 1 期的结尾
R (I + R)"
PMT Cl
FV( 定期年 金 )= [ + R)" - 1 ] 假设第 1 次现金流篮发生在 第 1 期 的 结 尾
R
续表
• EAR : 有 效 年 利 率
EAR = ( I 十 宁 ) - 1 • APR : 年 利 率
• m : 每年复 利 次数
把 一 个 年 利 率转换 为 另 一 个年利率
例如 , 已知 A PR 1 、 mi 和 mi, 求 出 A PR2 (, +
A PR
m1
J'' = ( , +
AP
m 勹
,
把 一 个有效年利 率转换 为 另 一 个 有 效 年 利 率 ( l + R111effe,ctil'e r, , 111'
= ( 1 + Rm'fl,ecm· )
把 一 个年利率转换为连续复利利率 Re R" = m * ln ( I + 气
把连续 复利利率 凡 转换为年利率 生 - 1)
APR = m * ( 矿
3.23 小结
本章 学 习 了 如 何编 写 简 单 的 函 数 , 用 来 计 算 未 来现金流量 的 现值 , 现 金 的 未 来价值 、
年 金 的 现值和 年 金 终值 、 永 久 年 金 的 现值 、 债 券 的 价 格 、 内 部 收 益 率 ( IRR ) 等 。 显然 ,
单独调 用 几 十 个 小 函 数 是 困 难和 费 时 的 。 如 何把 许 多 小 函 数集成到
一
个 Python 文件是本章
的 重 点 。 我们 的 目 标 是 创 建 个 称 为 fin l O l .py 的 Python 模 块 , 并 用 它 作 为 个金融计算
一 一
练 习题
l . 如 何 编 写 一 个 不 需要保存 的 Python 程序 ? 如 何 编 写 二 个 函 数 来 计 算 输 入 值 的 3
倍数 。
练习题 53
FV
PV =
(l + RY
6 . 如何有效地测试 一 个 Python 程序 ?
算未来现金流量的现值而另 一 个公式计算
年金的现值 ?
9. 有多 少种 类型的注释 ? 如何有效地使用它们?
10 . 如 何 把 尽 量 多 的 函 数 放在 同 一 个 f i n l O l . py 文 件 里 , 包 括 pv_f ( ) 、
pv_pe rpetuity ( ) 、 pv_p e rpetui ty_due ( ) 、 dpv_annu i t y ( ) 、 dpv_annu i t y_
du e ( ) 、 fv_annu i t y ( ) 等 ?
1 1 . 假设 f i n l O l . p y 文件
包括若 千 小 函数。 调用函数的两 个命令 : imp o r t f i n l O l
和 f rom f i n l O l impo r t * , 有什么 区 别 ?
但是, 下列 函数却有错误, 为什 么 ?
de f di r 3 ( path) :
from o s imp o r t l i s td i r
l istdi r (pa 七 h )
»>dir ( )
[ ' IRR f ' , ' bu i l t i n s ' , ' doc ' , ' name ' , ' package ' , ' g l ob ' , ' npv f ' ]
>>>I RR_f ( 0 . 0 4 , [ - 1 0 0 , 5 0 , 5 0 , 5 0 ) )
Tr acebac k (most recent call l a s t ) :
File " <pyshe l l # 2 2 > " , l i ne 1 , in <module> IRR_f ( 0 . 0 4 , ( - 1 0 0 , 5 0 , 5 0 , 5 0 ) )
F i l e " C : \ Python 3 2 \ i rr—f . py " , l ine 3 , i n IRR_f inves tment = cashf l ows [ O J
T ypeError : ' fl oa t ' obj e c 七 i s not sub
1 6 . 如 果折现率 为 每 年 7.7% , 贴现 回 收 期 是 多 少 年 ? 注 : 贴 现 回 收 期 着 眼 于 如 何 用 未
来现金流量 的 现值之和 收 回 初 始投 资 。
>>>import glob
>>>glob . g l ob ( " c : \python 3 3 \ * . py" )
一
编写 个 以 字符 串 变量 为 输入 参 数 的 Python 函 数 , 称 为 d i r 2 ( ) , 用 来实现这个 功 能 。
以命令 d i r 2 ( " c : \python 3 3 \ * . p y " ) 来调 用 它 。
一
1 8 . 编 写 一 个 Python 程序把给 定 复 利 频 率 的 年利 率转 换 为 个有效 利 率 。
( 1 + m 『 = (l 十 m 『
三 五
1 2
一 一
1 9 . 编 写 Python 程序结合下面 的 公 式把 个 利 率 转换 为 另 个 有 效利 率 。
加
A
[ 1 + A=尸1 r = [ l + =� )
e R, = ( } + 气咒
20 . 基 于 以 下 代 码 , 编 写 一 个 Python 程 序 , 把 指 定 目 录 添 加 到 搜 索 路 径 上 , 如
addPath ( ' c : \my_p r o j e c t ' ) :
练习题 55
21 . 假 设 有 1 0 个项 目 文件分别存放在 10 个 目 录下 , 如 c : \ te a ch i n g \python \ 、
c : \proj ects \python\ 、 c : \proj ect s \portfol io\禾IJ c : \proj ects\ inve s tment s \ 。
创建 一 个 Pyth on 模 块 , 包括 10 个 函 数 , 分 别 以 这 10 个 目 录 为 默 认 参 数值 。 运行第 1 个 函
数后 , 第 1 个 项 目 的 目 录将被添加到 搜索路径上 , 以此类推 。
第4章
编 写 Python 程序计算看涨期 权价格
期权理论对于许多读者来说就像是高深的火箭科学。 为了 不让深奥的期权理论成为读
者学习的障碍, 本 章 没有详细介绍期权理论及相关的数学公式, 而是把重点放在用 1 3 行
Python 代码计算看涨期权的价格。 看 涨 期权的买方支付 期权费, 以获得在未来某个指定 日
期买入股票的权利, 而期权的卖方收到期权费并承担把股票卖给期权买方的义务。 欧式期
权只 能在期权到 期时行使, 而美式期权可以在到期 日或之前的任意 一 天行使。
本章将 重 点 讨论以下 内 容 。
• 使用注释法编写 一个 复 杂的 Python 程序
• 如何调试他人写的程序
\
de f CND ( X ) :
( a l , a2 , a3 , a 4 ,
aS ) = ( 0 . 3 1 93 8 1 5 3 , - 0 . 3 5 6 5 6 3 7 8 2 , l . 7 8 1 4 7 7 9 37 , - l . 8 2 1 2 5 5 9 7 8 , l . 3 3 0 2 7 4 4 2 9 )
L = abs ( X )
K= l . 0 / ( l . 0 + 0 . 2 3 1 6 4 1 9 * L )
w= l . 0 - l . 0 /s gr t ( 2 * pi ) * e xp ( - L * L / 2 . ) * ( a l * K+a2 * K * K+a3 *pow ( K , 3 ) +
a4 *pow ( K , 4 ) + aS * pow ( K , 5 ) )
i f X<O :
w = 1 . 0-w
return w
>> >bs ca l l ( 4 0 , 4 2 , 0 . 5 , 0 . l , 0 . 2 )
2 . 2777859030683096
4. 1 用 空 壳 法 编 写 一 个程序
de f CND ( x ) :
re 七 urn x
>> >CND ( l )
1
5. 在空壳程序中添加如下 行代码。
一
de f CND ( x ) :
( a l , a2 , a 3 , a 4 , a5 ) = ( 0 . 3 1 9 3 8 1 5 3 , - 0 . 3 5 6 5 6 3 7 8 2 , 1 . 7 8 1 4 7 7 9 3 7 , - 1 .
8 2 1 2 5 5 97 8 , 1 . 3 3 0 2 7 4 4 2 9 )
return a l
> > > ==== = ======R E START ==== = ==== === =====
7. 可以输入任意值测试这个程序 。 例如:
»>CND ( l )
0 . 31938153
=
- l . 8 2 1 2 5 5 97 8 , 1 . 3 3 02 7 4 4 2 9 )
L abs ( X )
K= l . 0 / ( 1 . 0 + 0 . 2 3 1 6 4 1 9 * 1 )
4.2 用 注释法编写 一个程序 59
\
9 . 因为 我们的 CND()函数 使用了包含在数学模块中的 s q rt ( )函数, 所以需要
f r omma 七 hirnp o r t * 这
一
行代码 。 可以按如下 步骤用不 同的输入值来测试此函数 。
»>CND ( 0 )
0 . 5000000005248 0 8 6
»>CND ( -2 . 3 2 2 9 )
0 . 010092238515047591
»>CND ( l . 6 4 7 )
0 . 9 5 0 2 2 0 9 9 3 3 62 7 8 1 7
图 4- 1
4.2 用 注释法编 写 一 个 程序
de f bs_c a l l ( S , X , T , r , s i gma ) :
return ( X )
>>>===========RESTART ========== �- -- -
5. 使用任意输入值测试这 个
函数。
>>>bs_ca l l ( 4 0 , 4 0 , 0 . 5 , 0 . l , 0 . 2 )
40
>>>bs_c a l l ( 4 0 , 4 2 , 0 . 5 , 0 . l , 0 . 2 )
42
注意输出值等于 第 2 个输入
变量 的值, 正如 我们设计的那样。
de f bs_ca l l ( S , X , T , r , s i gma ) :
dl = ( l o ( S /X ) + ( r+ s i gma * s i gma / 2 . ) * T ) / ( s i gma * s qrt ( T ) )
d2 = d l - si gmasqrt ( T )
retu r n S * CN D ( d l ) -X* exp ( - r * T ) * CND (d2 )
return ( x )
>>>bs_c a l l ( 4 0 , 4 0 , 0 . 5 , 0 . l , 0 . 2 )
Traceback ( mo s t recent c a l l l a s t ) :
F i l e " <pyshe l l # 5 2 > " , l ine 1 , i n <modu l皊
b s_call ( 4 0 , 4 0 , 0 . 5 , 0 . l , 0 . 2 )
F i l e " <pyshel l # 4 9 > " , l i n e 2 , in bs_c a l l
d l = ( l o ( S /X ) + ( r + s igma * s igma /2 . ) * T ) / ( s i gma * s q工七 ( T ) )
Name E r ror : g l ob a l name ' lo ' i s not def i ned
练习题 61
4.3 使用 和调试他人编 写 的 程序
\
在开始为 自 己的项 目编写程序时, 我们往往会以已有的程序作为起点。 这些 程序可能
是 我们的研究 伙伴, 其他研究 员编写的, 也可能来 自 互 联网的开源软件, 或者是 我们用过
的程序 。 我们首先需要知道这些 程序是否
包含错 误 。 上述两 种方法可以用来检验这些 程序 。
第 2 种方法, 即注释法, 应 当是首选, 因为可以帮 我们节省 一 些 打字的时间 。 调试程序的
关键在于 找出程序错在哪里。 这里有一 个非常有用的从 雅 虎财经网站获取数据的 Pyth on 代
码文件: http : / / ca n i s i u s . edu / - yany/python / y s t o c kquote . tx七 。 初学者可以
下载该文件并试一试其 中包含的一 些 小程序 。
4.4 小结
练习题
目前的做法:
( al , a2 , a3 , a4 ,
a S ) = ( 0 . 3 1 9 3 8 1 5 3 , - 0 . 3 5 6 5 6 3 7 8 2 , l . 7 8 1 4 7 7 9 37 , - l . 8 2 12 5 5 9 7 8 , l . 3 3 0 2 7 4 4 2 9 )
另 一种方法:
al=0 . 31 9 3 8 153
a2=- 0 . 3 5 6 5 6 3 7 8 2
a3=1 . 7 8 1 4 7 7 937
a 4 =- l . 8 2 1 2 5 5 9 7 8
aS=l . 33 0 2 7 4 4 2 9
9 . 使用他人编写的程序有什么 优点和缺点?
10 . 如何调试他人编写的程序 ?
11 . 写 一 个 Pyth on 程序将任意给定的每年复利 m 次的年利率 ( AP R)转换为连续复利
利率。
1 2 . 如何提高累积正态分布函数的精确度 ?
14 . 一
只 股 票当前股价为 52.34 美元 。 如 果行权价和 目前的股价相同, 离到期 日 有
半年, 年 回 报 率 的波动率是 16% , 无风险利 率为 3.1% C 连 续 复利), 它的看 涨 期权价格
是多少 ?
1 6 . 以图形方式演 示第 15 题的结论。
练习题 63
注: *
表示 难度较高的问题。
第5章
模块简介
本章将重点讨论以下内容 。
• 什 么 是模块? 如何导入模块
• 显示 导入的模块包含的所有函数
• 为导入的模块取 个
简称
• 删 除已经导入的模块
• 从模块加 载指定的函数
• 找出所 有 的内置模块和当前所有可用的模块
• 找到特定的但未安装的模块
• 找到已安装的模块的 目 录位置
• 模块之 间 的 相 互 依 赖性
• 包括许多模块的超级包
• 在 网 上 搜索 模块和如何安装模块的视频
\
5. 1 什么是 模块
5.2 导入模块
>>>sqrt ( 3 )
S yntaxError : inva l id s yntax
>>>
>>>import math
>>>x=math . s qrt ( 3 )
>>> round ( x , 4 )
1 . 7321
>> >di r ( )
[ ' builtins ', ' doc ', ' name ', ' package ' , ' ma 七 h ' l
图 5- 1
使用模块的
简称来调用包含在该模块中的指定函数, 比如:
5.2.4 删除 已经导人的模块
de l 命 令 可以用来删 除 已经导入的模块, 代码 如 下 。
>>>import ma th
» >di r ( )
[ ' bui ltins ' doc , name ' package ' math ' )
> > >de l math
>>>dir ( )
[ ' buil tins ' do c ', ' name ' pac kage 'l
>>>
68 第 5 章 模块简介
5.2.5 导人几个指定的函 数
第 4 章用到 3 个函数: l o g ( ) 、 e xp ( ) 和 s q r t ( ) 来计算看涨期权的价格。 若 要 使用
这 3 个函数, 就需要用 f rom ma七h i mport * 命 令导入包含这些函数的 math 模块。 这
个命令发出后, math 模 块包含的所有函数都可以调用了, 代码如下。
0 . 8329
>>> round ( s qrt ( 3 . 7 ) , 4 )
1 . 92 3 5
5.2 导 入 模块 69
图 5-2
图 5-3
图 5-4
_...........
,:,- ,,.1,t " .. 1,,,,、,,, ' i I , ,,., ,,,』,' I、 ,- I"' '、 ,
1i:,, 1、 1 ,,..., ,- 1• 1,,., ' " ,'" ' ,, l, J , I 1 .. , I
I,,.:,,, 1,,,i,
ii. · i , , , , , , I I , , , , "' 1 ,· I '
,
I '
I
11, i ., \, .., , !.,·, ..., ,., '
!J,, , ;-: M1.1-: ,·, :., , '" , , I"' r . ,
I I I' ! i, ' , ,.;· 1 ..., 1 1,
II , i i I , , ,. ',,•• i : " ' ' ,,., I ,,
ii i i • 1, I ,, ,,,,, ' ' ,1.,、, I ' r . ' I ' ,. ,,,.,
图 5-5
图 5-6
要 查 找 某 个 特 定 的模块, 只 需 要输 入 modu l e s 和 该 模 块 的 名字 。 如 果 想 了 解
rnatp l o t l i b 模 块, 可 以 在 帮 助 窗 口 使用 modul e s rnatplot 巨b 。 前 提 条 件 是 ,
rnatplotl ib 模 块 已 经 预 装 了 。 如 果 没 有 , 就 会得到 一
个出错 信息 。 发出
rnodu l e srnatp lo七巨b 命 令 后的结果如图 5- 7所示。
5.2 导 入模块 71
图 5-7
>>>np . f i l e
' C : \Anaconda \ l i b \ s i te-packages \numpy\_i nit_ . p y '
(3 ) 在导入模块后, 只 需输入 np 。
>>>np
<modu l e ' numpy ' from ' c : \Anaconda \ l ib \ s i te-packages \numpy\�init� . py ' >
5.2.9 有关模块的更多信息
执行以下步骤来获取有 关模块的更多信息。
秽 Unin式a l l Python
啪 Python M a n u a ls
Class Browser Alt+ C
Path Browser
图 5-8 图 5-9
所示。
言巨亏
7矗 P或hBrows«
3 �
PY'ho" 3 p
;�
collections: package
concurren七 package
ctypes: pac lca扣
curs心 package
dbm: pac.lca尹
cf哎utils: pac.lca扣
email: package
encodin宇 package
html: package
http: package
图 5- 1 0
5.2. 10 查找某个未安装的模块
>>>import quant
T raceba c k (most recent call l a s t ) :
5.3 模 块之 间 的 相 互 依 赖 性 73
2 . 在该网站上 , 浏 览所有的软件
包。
3 . 选 择 编 程 语 言 Pyth on ( h七tp s : / / pypi . python . org/pyp 立 % 3Aac巨on =
b rowse ) 。
4 . 选择金融保险业( ht七ps : / /pyp i . python . org/pyp 立 % 3Aac巨on= br owse ) 。
7. 最后找到该模块, 如图 5 - 11 所示。
表 5-1
模块名 描述
Quant 金融蜇化分析的企业级架构
Finance 经过优化的金融风险计算模块
5.4 小结
练习题
1 . 什么 是模块?
5 . 在哪里可以找到某 个模块的使用 手 册 ?
6 . 如何删 除模块?
函数, 怎 么 只导入这几 个
7. 如果只需要 math 模块里的几 个 函数 ?
简单的模块?
10. 初学者如何编写 一 个
1 1 . Python 目前包含有 多 少模块? 如何找到 一 个完整列 表?
1 2 . 找 出与 z ip import 模块相关的主要内容 。
第6章
NumPy 和 SciPy 模块简 介
• NumPy 和 S c i P y 模块的安装
• 使用 NumPy 和 s 立 P y 的示例
• 显 示 NumPy 和 S c i P y包含的所有 函数
• 获取某 个函数的更多信息
• 理解列 表数据 类型
• x . sum ( )函数
• 通过循环遍历一 个数组
• S c i P y 模块的子
包列 表
• 累积标准正 态分布
\
• 随机数的生成
• S c i Py包含的统计子 模块 C s ta区 )
• 插值、 线性方程组和优化
6.2 从 Anaconda 启 动 Python 77
• 线性 回 归 和资 本资 产定价模型 C CAPM )
• 从 外部文本文件读取数据
• 如何独立安装 NumPy 模块
\
• 数据类型简介
6. 1 安装 NumPy 和 Sci Py 模块
第 5 章讨论了模块之间 的 依 赖性并提到依赖性可能增加安装一 个模块的难度。 幸运的
是 , 有些 超级软件包, 比如 An a conda 和 E nthought Canoy, 可以同时安装多 个模块。
这本书用到了 Ana conda , 因为它同时包含 NumPy 和 S c i Py 这两 个模块 。 执行以下两 个
步骤来安装它。
1 . 访问 http : / / c o n t i nuum . i o /down l oads 。
2 . 根据你 的计算机, 选择适当的软件下载, 如图 6- 1 所示 。
Anaconda 4.2.0
For Windows
钮°"""' K 8SD IK<咄妞炉,心“平m出心、to 叩 归O心
..-..,,.u,.,.,,.. ,..
沁戊江心
32 BIT INSTALLER (33�沁
图 6- 1
匾匾圈圈圈一i�I 图 6-2
实 数 的 类 型 是 f l oa t 6 4 , 任意数值变 量 的 默 认 类型 也 是 f l oa t 6 4 。 在 以 上 的 例 子 中 ,
一
可 以 看到 , np . a r r a y ( ) 函 数 把 个 包 含 整 数 型 数 值 的 列 表转换 为 数 组 。 如 果 想 改 变数据
的类型 , 可 以 用 第 2 个 参 数 指 定 数 据 的类 型 。
>>>x = [ l , 2 , 3 , 2 0 )
> > > y=np . a rray ( x , dtyp e = f l o a t )
>>>y
array ( [ 1 . , 2 . , 3 . , 20 . ) )
一
在 以 上 的 例 子 中 , dtype 是 指 定 数 据类 型 的 关 键 字 。 个列表可 以包含不同类型的数
一
据 , 而 不 会 引 起 任 何 问 题 。 但 是 , 将含有不 同 数据类 型 的 列 表转 换 成 个 数 组 时 , 会得到
如 下 的错误信息 。
E F G H
50 40 20 10 50
图 6-3
>»c = [ l O O ]
>>sp . npv ( O . l , c )
100 . 0
一
基于这个理解 , 如 果 有 笔 初 始 的现金支 出 , 金 额 为 1 00 , 结 果 如 下 。
>>>cas h f l ows= [ - 1 0 0 , 5 0 , 4 0 , 2 0 , 1 0 , 5 0 ]
>>>x=sp . npv ( O . l , cashflows )
>> >r ound ( x , 2 )
31. 41
sp.pmt( )函 数 用 来 解 答 以 下 问 题 : 假 定 年 利 率 ( A PR ) 是 4.5% , 每 月 复利 。 每 个 月 需
一
要 支 付 多 少来偿还 笔 为 期 30 年 , 金 额 为 250 000 美 元 的 按 揭 贷 款 ?
»>payment=sp . pmt ( 0 . 0 4 5 / 1 2 , 3 0 * 1 2 , 2 5 0 0 0 0 )
>>> round ( payment , 2 )
-1266 . 7 1
效利 率 、 周 期 的 数 目 和现值。
�1 sp . pv ( ) 函 数 模 仿 Excel 中 的 PY 函 数 。 调用
图 6-4
sp . pv ( ) 的 格 式 是 sp . pv C rate , nper , pmt ,
fv=O . 0 , when= ' en d ' ) 。 rate 是 贴现 率 , nper 为 周 期 数 , fv 是 未 来现金量 , 其默认值为
一
0。 最后 个 输 入 参 数 指 定 现金流是在每个 时 间 段 的 开 始或结 束 完 成 ; 如 果 缺省 , 则意 味着
在每 个 时 间 段 的 结 束 时 支 付 。 调 用 该 函 数 的 命 令 如 下 。
sp . fv ( ) 函 数类 似 于 sp . pv ( ) 函 数 。 给 定 n 个 数值 X1 , X2 , X3, … , 用 下 面 的 公 式估计
算术平均值和 几何平均 值 :
I x;
闰
算 术平 均 值 = ( 6- 1 )
n
n l / ll
几何平均值 = ( Q x; ) ( 6-2)
»> ( 2 +3+ 4 ) / 3 .
3.0
>>>ge o_rnean= ( 2 * 3 * 4 ) * * ( 1 . / 3 )
>>> round ( geo_rne a n , 4 ) 2 . 8 8 4 5
当有 n 个 回 报率 时 , 计 算 其 算 术 平 均 回 报 率 使用 相 同 的 公 式 , 但 是 其 几 何 平 均 回 报 率
的计算公式 不 同 , 如下所示。
沪,
算 术平均值 = ( 6-3 )
/;l
11
1/n
几何平均值 = [ CT ( 1 + R; )] -1 ( 6-4 )
sp . prod ( ) 函 数计 算所有数据 项 的 乘 积 。 可 以 用 它 来 计 算 回 报 率 的 几 何平 均 值 。
>>>import s c ipy as s p
>>>ret=sp . array ( [ 0 . 1 , 0 . 0 5 , - 0 . 0 2 ] )
>>>sp . mean ( re t ) # ari· thmetic mean 0 . 0 4 3 3 3
> >>pow ( sp . prod ( re t + l ) , 1 . /l e n ( re 七 ) ) - 1 # geometric mean 0 . 0 4 2 1 6
82 第6章 NumPy 和 SciPy 模块简介
>>>sp . un i qu e ( [ 2 , 3 , 4 , 6 , 6 , 4 , 4 ] )
Arr a y ( [ 2 , 3 , 4 , 6 ] )
>>>sp . median ( [ 1 , 2 , 3 , 4 , 5 ] )
3.0
>>>import s c ipy a s sp
>>>round ( sp . pv ( 0 . 1 , 5 , 0 , 1 0 0 ) , 2 )
-62 . 0 9
>>>round ( sp . pv ( 0 . 1 , 5 , 0 , - 1 0 0 ) , 2 )
62 . 0 9
>>>import numpy as np
>>>di r ( n p )
为 了 节 省 空 间 , 只 在 图 6-5 显 示 输 出 的最初儿行 。
图 6-5
一 一
个更好 的 方 法 是 把所 有 函 数 的 名 字输 出 并储存在 个 数组 中 。
输 出 显示如 图 6-6 所 示 。
, · , · · · · · · · · ", . I
6.5 理 解 列 表 数据类 型 83
I 图 6-6
>>>import scipy as sp
1
图 6-7
_ 一
使用 d江 ( np ) 命 令 可列 出所有函数, 其 中 包括 s t d ( )函数。 要查找有 关 s 七d ( )函数
一
的信息时, 使用 help ( np . st d ) 。 部分输出如图 6-8所示。
1•1•1111•11111111111111111111!mtttnmt111111
N .. ... ,,.1 .. ' I' . I , ,. ,..11,,, 1· , I ,. .
, I .,, , I ,,, I" , •i <• ,I ,. j
、 ,,,..
; , , , ,.,, , i.- , .,. i ,, ,I ,,, , , · I '"" · , ,. , ,.,., .,f I /p· I"、,- .,,! " ' ., ,!1 1 1'11" ' ' 1"『, .
, , 1 ..- , , 1 , " , I ,. , , . ., , I ,,. , ,.,,1 .,,.,1 ,1,., , .,1 ; ,.,, i ""'I" ' ' ,·,I I ,,,
I I ., • ' , ,., i .. ,. 1·., · !,, ,1, I "' I • " , lw "" 1 , ,,..,. 1· I j,, I"'' ,! 1 ,.,f , . 1 .
;· , ,、 ''" ! ' I、
. ,.,、 , ,, i r J ,
, I. " I ' I ' I I" • .'"I ' '.'I 'I . ., ' . ' ' " " " ; t ,.. ' " ., I'"
" I . " l'I I " •
f! . I . I ,, ,, , i,., J. • I,, ! ,,,.1 ,;·,I ,1, " I , r j,,,, I , "『,I'" , ,. ,I . 1 1 ..- ,I,·I ., " I 1 ,
1,, , " ''I" ' ' ,. I J., I ,,,,J ,,.,1 ,I,.._, f,d I ,11 .. 1 I t,,. J 1,,1 I o•[l,•1I ,>i'I、 ,,, .
图 6-8
6.5 理解 列 表数据类型
一
个列 表变量通过一 对方括号 []来定 义, 并且 可以包含不 同 类型的数据。 可以用不同
的方式来使用某 个数据项。 调用不 同数据项的命令如下。
>>>x
( 1 , 2 , ' John ' , ' M ' , ' S tudent ' J
>>>x [ l )
2
> > >x [ 2 : ]
[ ' John ' , ' M ' ' ' S tudent ' ]
6.7 执行数组操作
我们 有时候需要改变一 个矩 阵或数组的大小。 比 如把 组 1 00 个随机数
一
变成 一 个 20X
6.8 数组的加 、 减、 乘 、 除 85
»>pv= np . array ( [ [ l 0 0 , 1 0 , 1 0 . 2 ) , ( 3 4 , 22 , 3 4 ) ) ) # 2 b y 3
>>>x=pv . fl a 七 ten ( ) \ # ma t r i x become s a vector
>>>vp2 = np . r e s hape ( x , [ 3 , 2 ) ) # 3 by 2 now
6.8 数组的加 、 减 、 乘 、 除
数组 的 加 和 减 运算 容 易 理 解 。 然 而 , 乘法和 除 法 有 不 同 的 定 义 。 以 乘 法 为 例 , A X B 可
以有两个 含 义 : A 和 B 相 同 位置 的 数 据 项 相 乘 ( A 和 B 应 该具有相 同 的 维 数 , 都 为 n 行 m
列 ) 或矩阵乘法 ( A 的 列 数 等于 B 的 行 数 , 也 就 是 说 , A 是 n X k 矩 阵而 B 为 k X m 矩 阵 ) 。
6.8. 1 进行加减运算
增 加 或减去两个数组时 , 它 们 必 须 具 有相 同 的 大小 , 也就是 , 两 者 的 维 数都是 n X m 。
一
如果 它们有不 同 的 大 小 , 将得到 个 出 错信息 。 例 如 , 两 个现金流数 组 的 和 :
6.8.2 执行矩阵乘法运算
对 千 矩 阵 乘 法 A X E, 矩 阵 A 和 B 的 维 数 应 该 分 别 是 n X k 和 k X m 。 假 设矩 阵 A 和 B
分别有以下公式。
、
、
(
(
bl
b1 ·: b II
:
a
al
.
. .
.
.
. .
.
_. .
k
1
. .
.
A
B
=
.
•••
·:
=
.
. .
. an
( 6-5 )
bn
.
an
\
.
.
.
.
..
.
\
.
k
k
1
、
x
将
阵
的
大
矩
是
B
A
n
.
厂
.
:
.
I
、」
-
CIm…
A•B�C� ( 6-6 )
cnm
丿
其 中 的 各 个 数 据 项 Cp
; 将 由 以 下 公 式得到 。
86 第6章 Nu1nPy 和 SciPy 模块简介
ciJ = LLLa;A,1
n m k
>>>xl=np . arr ay ( [ ( 1 , 2 , 3 ] , ( 4 , 5, 6 ] ] , f l o at )
>>>x 2 =np . ma t r i x ( x l ) # from array to ma七rix
>>>x 3=np . arra y ( x 2 ) # from mat r i x t o array
6从3 执行逐项相乘的乘法运算
当两 个 阵 列 具有相同的维数时, x*y 将执行逐项相乘的乘法运算。 当 A 和 B 都具有相
同的维数, 如 nX m 时, 逐项相乘的乘积将有 以下形式。
cij = LLaiij
II m
( 6-7 )
i=l }=1
例如:
>>>x= np . arr ay ( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ] , f l o a t )
> > > y=np . a rray ( [ [ 2 , 1 , 2 ] , [ 4 , O , S J ] , fl oa七 )
>>>x * y
Array ( [ [ 2 . , 2 . , 6., l , [16. , 0., 30 . ] ] \)
6. 1 1 使用 与 模块相关 的 帮 助 87
6.9 x.sum() 函 数
变量 x 被 定 义 为 一 个 NumPy 的数组后 , 可 以 使用 x . f u n c t i o n ( ) 进行相 关操作 。
x . s um ( ) 的 用 法 如 下 。
。
>>>cashFlows . ar gmin ( )
6. 1 0 遍历数组的 循环语句
一
用 下 面 的 for 循环语句遍历数组 , 依 次 打 印 数组 包 含 的 每 个数值。
6. 1 1 使用 与模块相 关 的 帮 助
» >he l p ( )
help>n umpy
输 出 的 前 几行如 图 6-9 所 示 。
图 6-9
同样可 以 在 帮 助 窗 口 了 解 Sc iPy 的 更 多 信 息 。
>>>help ( )
help> s c i py # to s ave space , the output i s not shown
6. 1 2 Sci Py 的 一 系 列 子 函 数包
SciPy 大约 有十几个 子 函 数包 , 表 6-1 列 出 了 SciPy 的 子 函 数包 。
表 6-1
子 函 数包 描述
Cluster 聚类算法
Constants 物理和数学常揽
Fftpack 快速傅里叶变换
Io 输入与输出
6. 1 3 累 积标 准 正 态 分布 89
续表
子函数包 描述
Linalg 线性代数
Signal 信号处理
Sparse 稀疏矩阵和相关的算法
Spatial 空 间 数据结构和算法
Special 特殊 函 数
Stats 概 率 分 布 函 数和统计分析
6. 1 3 累积标准 正态分布
在第 4 章中,我们 自 己 编 写 累 积标准正态分布 函数来给看涨期权定价 。 SciPy 的 一个子
模块提供了 累积标准 正态分布 函数 。 例 如, 累积标准正态分布 函数在零点的取值 如 下 。
现在, 输入 一 组值调用函数 b s - c a l l 。
>>>pri ce=bs_cal l ( 4 0 , 4 0 , l , 0 . 0 3 , 0 . 2 )
>>> round ( p r i ce , 2 )
3 . 77
90 第6章 NumPy 和 SciPy 模 块 简 介
6. 1 4 与 数组相 关 的逻辑关 系
有 的 数 据 取 值为 真 ( True ) 或假 ( False ) 这两者之 一 , 这种 数 据 类 型称 为 布 尔 数 。
有些逻辑 函 数 , 如 l o g i c a l an d ( ) 、 l o g i c a l o r ( ) 和 l o g i ca l not ( ) 函 数 , 可
以对每个数据项进行 比 较 。 另 外 , 可 以 保存逻辑 比 较 的 结 果 , 为 后 面 的代码所用 。
>>>cashFlows=np . a rray ( [ 一 1 0 0 , 5 0 , 4 0 , 3 0 , 1 0 0 , - 5 ) )
>>>index = ( cashFlows > O ) # index i s a Boolean va riable
>>>ca shFlows [ i nde x ) # re 七 r i eve po s i tive cash f l ows
Arr a y ( [ 5 0 . , 4 0 . , 3 0 . , 1 0 0 . ) )
为 了 节 省 空 间 , 图 6- 1 0 只 显 示 了 最初 的 几 行 。
一
从 d江 ( s ta t s ) 的 输 出 中 , 可 以 找到 个 t t e s t_l s amp ( ) 函 数 ( 不 过 该 函 数 没有
显 示在 图 6- 1 0 中 ) 。 随 机 生 成 服 从 标 准 正 态 分 布 的 1 00 个 随 机 数 , 然 后 使 用 ttest_ I samp()
函 数进 行 单 样 本 t-检 验 , 以 测 试均 值 是否 为 0 。 基 千 t 值 C 1 . 1 8 ) 和 p 值 ( 0.24 ) , 不 能 拒
绝零假 设 , 这 说 明 我们 的 样 本 来 自 均 值 为 0 的 分 布 。 代 码如 下 。
—
I门
.ttr
,.
II
l 11
l ll I
,·
·1 1�I
:几' an rut·
”jd
,
I -
-
2l“
1.l
l·
,'
图 6- 1 0
>>>impor 七 nurnpy as np
>>>s = np . randorn . s tanda rd_t ( l O , s i z e = l O O O ) # from s tandard- T , df = l O
>>>x=np . r andom . uni form ( l ow= O . O , hi gh=l . O , s i z e=l O O ) # uni form
>>>stocks=np . r andom . random_i ntege r s ( l , 5 0 0 , 2 0 )
>>>stocks
array ( [ 3 7 1 , 1 5 , 1 5 8 , 4 6 8 , 2 9 9 , 4 7 0 , 2 5 7 , 4 8 1 , 7 6 , 1 9 6 , 3 5 5 , 3 8 6 , 4 3 8 ,
4 8 4 , 4 1 , 3 9 , 2 2 2 , 37 7 , 4 5 5 , 4 6 ] )
6. 1 6 SciPy 模块 的插值方法
>>>import nurnpy a s np
>>>import rnatp l o 七 l ib . pyp l o t as p l t
>>>from s c ipy . inte rpolate import interp ld
>>>x = np . l i n space ( O , 1 0 , 1 0 )
>>>y = np . exp ( - x / 3 . 0 )
92 第6章 NumPy 和 SciPy 模 块 简 介
以上 代码使用 np . l i n space ( 函
) 数来生成 0�10 均 匀 间 隔 的 40 个值 。 相关的输出如
图 6- 1 1 所示。
0.6
0.4 •·
02
o.o�
2
图 6- 1 1
6. 1 7 使用 SciPy 求解线性方 程
假设有以下 3 个方程:
{;勹言 昙°
( 6-8)
2x + 3y + 8z = 5
定义 A 和 B 如下。
A{ ; !] B� ff] ( 6-9)
6. 1 8 利 用 种 子 ( seed ) 生 成 可 重 复 的 随 机数 93
以下 公式给 出 该方程组的答案 。
A
� [� ; �
( 6- 1 0 )
] s{ ]
[:]�A一' 'b ( 6- 1 I )
计算答 案的 Python 代码 如 下 。
>>>importscipy as sp
>>>x=sp . random . rand ( l O ) # 1 0 r andom numb e r s f rom [ 0 , 1 ]
> >>y=sp . random . rand ( S , 2 ) # random numb e r s 5 by 2 array
>>> z=sp . random . rand . norm ( l O O ) # from a s tandard norma l
>>>
一
以上代码随机生成 一 组数字 。 不过, 有时需 要 组 固定的随机数, 用来重复测试我们
的模型和代码 , 教学时尤其 如 此 。 以下代码利用 一 个给定的种子来产生 可以重 复获得的随
机数 。
>>>importscipy a s sp
>>>sp . random . s e ed ( 1 2 4 5 6 )
>>>sp . random . rand ( S )
[ 0 . 8 9 2 8 6 5 8 6 0 . 6 1 8 5 6 52 0 . 5 8 8 7 3 52 3 0 . 7 61 3 7 60 1 0. 74499103)
94 第6章 NumPy 和 SciPy 模 块 简 介
图 6- 1 2
6. 1 9 在导入 的模块里查找 函 数
uni codeO
uni code
unionld
unique
6.2 1 线 性 回 归 和 资 本 资 产 定 价 模 型 ( CAPM ) 95
6.20 优化算法简介
一
在 金 融领域 , 许 多 问 题需 要 用 优化 算 法 来 解 决 , 比 如 给 定 目 标 函 数和 组 约 束 条件选
择最佳投资 组合 。 可 以 使用 s 立 Py 模块包含 的 名 为 s cipy . opt imi z e 的优化子模块来解
2
决这些 问 题 。 假 设 要 计 算 满足方程 y=3 +x 并且使 y 取最 小 值的 x 值 。 很 显 然 , 正 确 答 案 是
当 x 等 于 0 时 y 达到 最 小 值 。
y = a +f] *x ( 6- 1 3 )
一
下面 是估计这个线性 回 归 模 型 的 个示例 。
> > > f=open ( " c : \ \data \ \ibm . csv" , " r " )
>> >da 七 a = f . readl i n e s ( )
>>>type ( da t a )
<class ' l i s t ' >
点 是 自 动 把 不 能 识 别 的 值 , 如 3 .5 % 设 置 为 NA ( Pyth on 的 缺 失 代码 ) 。
\
执 行 以 下 两 个 步 骤 来 独 立 安 装 NumPy 模 块 。
2. 选 择 合 适 的 软 件 包 下 载 和 安 装 , 如 numpy-MKL - l . 7 . l . wi n 3 2 - p y 3 . 3 . e xe 。
大 部 分 的 数 据 类 型 如 表 6-2 所示 。
表 6-2
数据类型 描述
int64 64 位 整 数 ( 取值 范 围 为 9 223 3 7 2 036 854 7 7 5 808-9 223 372 036 854 7 7 5 807 )
unit8 无 符 号 8 位整 数 ( 取 值 范 围 为 0-255 )
un i 七 1 6 无符号 1 6 位 整 数 ( 取值 范 围 为 0-65 5 3 5 )
float 64 位 浮 点 数
floa七32 单精度 32 位 浮 点 数
float64 64 位 浮 点 数
98 第 6 章 NumPy 和 SciPy 模 块 简 介
续表
数据类型 描述
complex 1 28 位复数
compl e x 6 4 64 位 复 数 ; 两个 32 位浮点数分别代表实部和虚部
complexl 2 8 1 28 位复数; 两个 64 位浮点 数分别代表实部和虚部
6.25 小结
练习题
1 . 什 么 是模块依赖性?
2. 为什么 独立安装 N u mPy 比较困 难 ?
3. 编写 一个 依赖于其 他模块的模块有何好处和不利之处?
6 . 以下命令哪里错了 ?
>>>x = [ l , 2 , 3 ]
>>>x . sum ( )
7. 如何 打 印 给定数组中的所有数据项 ?
8. 以下命 令 哪里错了 ?
>>> import np
练习题 99
9 . 如何遍历一 个数组?
13 . 有以下的联立方程, X, y 和 z 分别 等于多少?
厂亿 3
一x + 2.9 y + l 8
2
. z = 3.1
:::/
>>>import scipy as sp
>>>ret = np . array ( [ O . O S , 0 . 1 1 , - 0 . 0 3 ) )
>>>pow ( np .prod ( re 七 + l ) , l / len ( re t ) ) - 1
16 . 使用回报率的标准差来衡量证券或投资组合的风险水平。 根据雅虎财经网站上最
近 5年的每 日 股票 价格, 计算 I BM 的 风险水平。 需要注意的是, 用下面的公式 把 日 回报率
的方差转化为年回报率的方差。
吐ual = 252CY� ly
印
19 . 以下 命令哪里错了 ?
>>>c = 2 0
>>>npv=np .npv ( O . l , c )
22 . 编写 一 个与 E xce l的 NPV()函数相同的函数。
R - RI
sh arpe =
。
R 是单只 股 票的预期回报的均值, 凡 是无风险利 率的均值 。 6 是该股票 回报率的标准
方差, 也称为波动率。 利用最近 5年的月度回报率, 计算 I B M 、DELL 、C iti 和 WMT( Walmart)
的夏普 比率 。
\
第7章
\
用 mat plot l ib 模块 绘制 与
金融相 关 的 图 形
• 安装 m at pl otl ib 模块的几种方式
• 使用 m at lp otlib 模块的简单例子
• 净现值 (NP V)的图示、 杜邦等式、 股票收益率和直方图
• 整体风险、 市场风险和非系统风险
• 股票之 间 的联动度和相关系数
• 分散投资 风险
• 绘制交易量和价格
变动的图形
• 儿只股票的回报率和风险坐标图
• 使用 m at lp otlib 模块的复杂例子
1 02 第7章 用 matplotlib 模块绘制 与 金 融 相 关 的 图 形
7. 1 通过 ActivePython 安装 matplotlib 模块
安装 matplotlib 模块的第 1 个办法是使用 ActivePython 软件。 首先安装 ActivePython
软件, 然后安装 matplotlib 模块。 在安装 matplotlib 模块的过程中 , NumPy 模块会 自 动 安装,
因为 matplotlib 模块依赖于 NumPy 和 SciPy 这两 个模块。 整 个过程有如下 4 个步骤。
1 . 转到 http://www.activestate.com/activepython/downloads 。
2 . 选择适合的可执行文件进行下载。
、
Micro:; o f t \J ind1n1,; (Ue r:; ion (, . l . 'i1,l'll l
;cop w
• i•1 ht ( 1 ,'.l1W.' M i c ,、(,: 11( 1. Ci,1·1,1< 1·.<1 iu11 . 11 1 1 1· 1 ·1 l1i , 1'•令 , ,.,, ,, ,! .
C : ,II:; Ci-:; '-'J'"' '·' )c ,I·, l'vt ho11'.c '/
,1C : ,Pvt. hon?.?)
,
图 7- 1
\ 图 7-2
@ A.,ctivePython Documentation
rl IDLE (Python GUij
rl Python Interactive Shell
面 Python Package M anager (PyP M)
侍 Unin式all ActivePython
图 7-4
2 . 选择合适的包 下 载 并安装。
7 .3 matplotlib 模块简 介
通过学习一 些 例子可以很快掌握如何使用 matplotlib 模块。 首先举 一 个可能是最
简单的
例子, 因为它仅有3行 Python 代码 。 这 个例子的任务是在二 维坐标图上 绘制 给定的几 个点
之间 的连线 。 默认情况下, matplotlib 模块假定 x 轴的起点为 o, 单位为 1 。 下面的命 令行
利用了 matplotlib 模块的默认情况。
仑00 十 名 01 11 石
10
9
6
4
2
2� 30
图 7-5
结果 如 图 7-6 所示。
10 --y figu re
-m
I
9
I
,
8
i 6
5
>
E
�� 2.5 3.0
图 7-6
>>>from p y l ab import *
>>>x = np . l i nspace ( - np . p i , np . p i , 2 5 6 , endpo int=True )
>>>C , S = np . cos ( x ) , np . s in ( x )
>>>plot ( x , C ) , pl o t ( x , S )
\
>>> show ( )
以上用到的 linspace(函数有
) 4 个输入参数: start、 stop、 nurn 和 endpoint。 在这 个例子
里, 选取-3 . 1 4 1 5 9 1 6,..__, 3 . 1 4 1 592 6 的 2 5 6 个数, 包括两 个端点在内 。 通常情况下, num 的默
认 值是 5 0 。 两 个三角函数的图形如图 7-7 所示。
LO
0.5
0.0
-0.5
-1.0L
-4 3 4
图 7-7
..
2
1
。
-1
-2
-3
。
3
2
� -3 -2 ' -1
图 7-8
1 06 第7章 用 matplotlib 模 块 绘 制 与 金 融 相 关 的 图 形
7.4 了 解简单利 率 和 复利 利 率
对应的复利利率的未来值的计算公式如下:
FV( 复利利率)=P V( l +R r C 7-2 )
import numpy a s np
from matp lotlib . pyplot import *
from pylab import *
pv= l O O O
r=0 . 0 8
\
n=lO
t=l inspace ( O , n , n )
y l =np . ones ( l en ( t ) ) *pv # this is a ho ri zontal l i ne
y2=pv* ( l + r * t )
y3 =pv* ( l + r ) * * t
7.5 为 图 形添加文字 1 07
\
plot ( 七 , y l , ' b- ' )
plot ( t , y2 , ' g- - ' )
plo七 ( t , y3 , ' r - ' )
sho w ( )
2200
Sl�le vs. c,ompou� tntei;est rate
2000
1800
1600
1400
1000
。
10
800
4 6 8
即m归 rA yurs
图 7-9
7.5 为 图 形添 加 文 字
下面的例子展示如何
简单地在图形上添加文字。 注意 figtextO函数中 x 和 y 的取值范 围
为 0�1。
以 上 代码生 成 的 图 形 如 图 7- 1 0 所 示 。
6.0
l
S.5 ·
4.5
4.0
3.S
3.0
图 7- 1 0
表 7-1
7.6 杜邦等 式 的 图 示
在 金 融领域 , 人们 从 公 司 的 财 务寸队 表 , 如 年 度 损 益 表 、 资 产 负债表和现 金流量表 , 发
掘 有 用 的 信 息 。 比 率 分 析 是 常 用 的 工 具 之 一 , 常 常用 来 比较 不 同 企业之 间 以 及 同 一 公 司 历
年 来 的 表 现 。 杜邦等式 ( DuPont Identity ) 是 比 率 分 析 的 一 种 。 杜邦等式把股本回报率 ( ROE )
分 为 3 个 比 率 : 毛 利 率 、 资 产 周 转 率 和 权益 乘 数 。
下 面 的 代码将使用 不 同 的 颜色显示这 3 个 比 率 。 表 7- 2 给 出 3 家 公 司 的 财 务 信 息 。
表 7-2
December3 1 ,
IBM 0.8804 0. 1 589 0.8766 6.3209
20 1 2
February I ,
DELL 0.222 1 0.04 1 7 1 . 1 977 4.45 1 3
20 1 3
January3 1 ,
WMT 0.2227 0.0362 2.3099 2.6604
20 1 3
import numpy a s np
import panda s as pd
import matp lot l ib . pyplot as p l t
#
ticke r= ' T icker '
name l = ' profitMa r gin '
name2= ' ass etTur nover '
name 3= ' equ itMul tipl i e r '
scale=7 # scale the 1 s t ratio
#
raw_data = { 七 i c ke r : [ ' I BM ' , ' DE LL ' , ' WMT ' ] ,
narne l : [ 0 . 1 5 8 9 * s c a l e , 0 . 0 4 1 7 * sc a l e , 0 . 0 3 6 * s ca l e ] ,
name 2 : ( 0 . 8 7 6 6 , 1 . 1 9 7 7 , 2 . 3 1 ] ,
110 第7章 用 matplotlib 模 块 绘 制 与 金 融 相 关 的 图 形
n ame 3 : [ 6 . 3 2 , 4 . 4 5 , 2 . 6 60 4 ) )
df = pd . DataFrame ( raw_da ta , c o l umn s = [ t i c ke r , narne l , narne2 , name 3 ] )
f , axl = p l t . subp l ots ( l , f i g s i ze= { l 0 , 5 ) )
w= 0 . 7 5
x= [ i + l f o r i i n range ( len ( d f [ name l ) ) ) )
#
七 i c k_pos = [ i + (w/2 . ) for i in x )
axl . bar ( x , df [ name l ) , width=w , labe l =name l , a lpha=0 . 5 , c o l or= ' b l ue ' )
a x l . ba r ( x , df [ name 2 ] , width=w , bo七tom=df [ name l ) , l abe l =name 2 , alpha=0 . 5 ,
c o l o r= ' red ' )
a x l . bar ( x , df [ name 3 ] , width=w , bottom= [ i + j for i , j i n z i p ( d f [ n ame l ) ,
df [ name2 ) ) ) , label=name 3 , a lpha=0 . 5 , color= ' green ' )
p l t . x t i c k s ( t i c k_pos , df [ ti c k e r ) )
pl t . y l abe l ( " Dupoint Identity " )
pl t . x l abe l ( " Di f fe r ent t i c k e r s " )
p l t . l egend ( l oc= ' upper r i ght ' )
plt . t i t l e ( " DuPont Identity for 3 fi rms " )
p l t . x l im ( [ mi n ( t i c k_pos ) -w , max ( ti c k_p os ) +w ) )
p l 七 . show ( )
) 数在 x-y 位 置 添 加了 文字, x 和 y 两
在上 面的代码中, p l t . f i gt e xt(x,y, " 文本 " 函
者的取值 范 围 均为 0� 1 。 p l t . bar ( 函
) 数用来生成 3 个柱状 图, 如图 7- 1 1 所示 。
口企“真 一 应 ] firms
0g
5i
.
l
S
.
`
,
图 7- 1 1
7.7 净现值 图 示 曲 线
下面的代码用来展示净现值和折现率之 间 的负相关关系。
import scipy as sp
from matp l o t l ib . pyp l ot impor七 *
cashflows= ( - 2 0 0 , 8 0 , 9 0 , 1 0 0 ]
rat e = [ l
npv= [ ]
x= ( 0 , 0 . 7 )
y= ( 0 , 0 )
for i in range ( l , 7 0 ) :
rate . append ( O . O l * i )
npv . append ( s p . npv ( 0 . 0 1 * i , cash f l ows ) )
#
plo七 ( r ate , npv )
plo t ( x , y )
sho w ( )
"
。
- 100
。a.-.
-150I -· 豆 石 o.� 0.5 0,6 07
图 7- 1 2
一
项 目 , 我们 不 知 道 是 否 只 有 一 个 内 部 收 益 率 。 以 下 代码说 明 有 时 可 能 出 现 多 于 个 内 部 收
益率。
该代码的输 出 如 图 7- 1 3 所 示 。
0
1。
5
-5
图 7- 1 3
>>>import numpy as np
7.7 净 现值 图 示 曲 线 113
>>>c ashflows = [ 5 0 4 , - 4 3 2 , - 4 3 2 , - 4 3 2 , 8 3 2 )
>>>np . i r r ( cashf l ows )
0 . 08 949087
7.7.1 有效地使用颜色
\
使用不 同的颜色可以使图形或线 条更加抢 眼 。 假 设从雅虎财经获得沃尔玛和戴尔这两
家公司在 4年里的每股收益 C EP S, 扣 除 非经常性项 目的每 股收益)。 可以使用下面的代码
通过不 同的颜色来比较它们的每股收益 。
8
蠡》
隘
-2
图 7-1 4
表 7-3
字母 颜色 字母 颜色
'b ' Blue ( 蓝色 ) I m, Magenta ( 品 红 色 )
I
gI Green C 绿 色 ) ' y' Yel l ow ( 黄 色 )
I I r Red ( 红色 ) 'k' Black ( 黑 色 )
I
C
I
Cyan ( 青色 ) ,w , White ( 白 色 )
表 7-4
字符 说明 字符 说明
Hf_Ill
实线
1113 Ill
三角 菱 形 向 左
Ill--Ill
虚线 "' "'
4 三角菱形向右
Ill Ill
点划线 Ill
s Ill
正方形
'" · "' 虚点线 Ht
p
!It
五角 形
ti! tit
点标记 "'* "' 星形
7.8 图形演示分散投资的效果 115
续表
字符 说明 字符 说明
Ill 111
六边形 1 号
"'h Ill
像素标记
Ill 。 Ill
圈
III H "'
六边形 2 号
三角 向 下 加号
IllV I ll '"+"'
111/\111 "'X111
三角 向 上 交叉
"'<"' 三角向左 "'D "' 钻石形
三角 向 右 小钻石形
"'>lft "'d'"
三菱 向 下 垂直线
!If
l Ht '"I"'
1112 "' 三菱向上 tit Ill
水平线
表 7-5
年份 股票 A 股票 B
2009 0. 1 02 0. 1 062
20 1 0 -0.02 0.23
20 1 1 0.2 1 3 0.045
20 1 2 0. 1 2 0.234
20 1 3 0. 1 3 0. 1 1 3
>>>round ( np . mean ( ret_A ) , 3 ) , round ( np . mean ( ret_B ) , 3 ) , round (np . mean (port_EW) , 3 )
( 0 . 109, 0 . 1 46, 0 . 127 )
>>>round ( np . s td ( re七_A) , 3 ) , round ( np . s 七d ( ret_B ) , 3 ) , r ound ( np . s td ( por t_EW) , 3 )
( 0 . 07 4 5 , 0 . 07 4 , 0 . 027 )
import numpy as np
import matp l o t l ib . pyp l o t a s p l t
year= [ 2 0 0 9 , 2 0 1 0 , 2 0 1 1 , 2 0 1 2 , 2 0 1 3 )
ret _A=np . a r r a y ( [ 0 . 1 0 2 , - 0 . 0 2 , 0 . 2 1 3 , 0 . 1 2 , 0 . 1 3 ) )
r et_B=np . ar r a y ( [ 0 . 1 0 6 2 , 0 . 2 3 , 0 . 0 4 5 , 0 . 2 3 4 , 0 . 1 1 3 ) )
#
port EW= ( r e七 A+ r e t B ) /2
p l t . f i gtex七 ( 0 . 2 , 0 . 6 5 , " S tock A" )
p l t . f i gtext ( 0 . 1 5 , 0 . 4 , " S tock B " )
p l t . x l abe l ( " Year " )
p l t . y l abe l ( " Return s " )
p l t . p l ot ( year , r e t_A, lw=2 )
p l t . p l ot ( ye a r , r e t_B , l w=2 )
p l t . plot ( ye a r , port_EW , lw = 2 )
plt . t i 七 l e ( " Indiviudal s t ocks vs . an e qual - weighted 2 - s t ock portf l i o " )
p l t . anno七a七e ( ' Equa l -weighted Po r t f o l i o ' , xy= ( 2 0 1 0 , 0 . 1 ) ,
xytext = ( 2 0 1 1 . , 0 ) , a r rowprops = dict ( facec o l o r= ' b lack ' , shrink = 0 . 0 5 ) , )
plt . y l im ( - 0 . 1 , 0 . 3 )
p l t . show ( )
这段代码绘制的图形如图 7- 1 5 所示。
\
Equal-weighted 氏rtfollo
- - -
-o.1y,1。 - 0.5 LO -1.5 2.0 2.5 3.0 3.5 4.0
妇 +2.009e3
图 7- 1 5
7.9 股 票 的 数 目 和 投 资 组 合风险 117
7.9 股 票 的 数 目 和 投 资 组合风险
表 7-6
" 。匾p
。霓p
。曾p 生
(TI (jI
续表
up
n ap
� n (1'p
(j I uI
以下是 我们 的代码 。
show ( )
仁
R血' between n and portfolio risk
0.心
I :l
To�I p«tlolio ri,k
t \ �
o•f
, •�•�'
'-
" -
-------
一
I Noedi,e<Sffiabl,
二
-- ----.....- ---
汕 功 -
岫 IIDCb ln._a
叫 - 勿
图 7- 1 6
7. 1 0 从雅虎财经 网 站下载历史价格数据
>>>len ( r ) 9 8 9
>>> r [ 0 : 4 )
rec . ar ray ( [ ( datetime . date ( 2 0 1 3 , 1 , 2 ) , 1 9 4 . 0 9 , 1 9 6 . 3 5 , 1 9 3 . 8 , 1 9 6 . 3 5 ,
4234100 , 1 92 . 61 ) ,
( datetirne . date ( 2 0 1 3 , 1 , 3 ) , 1 9 5 . 6 7 , 1 9 6 . 2 9 , 1 9 4 . 4 4 , 1 9 5 . 2 7 ,
36447 0 0 , 191 . 55 ) ,
( date七ime . date ( 2 0 1 3 , 1 , 4 ) , 1 9 4 . 1 9 , 1 9 4 . 4 6 , 1 92 . 7 8 , 1 9 3 . 9 9 ,
3 3 8 02 0 0 , 1 9 0 . 3 ) ,
( datetime . date ( 2 0 1 3 , 1 , 7 ) , 1 9 3 . 4 , 1 9 3 . 7 8 , 1 9 2 . 3 4 , 1 9 3 . 1 4 ,
2 8 62 3 0 0 , 1 8 9 . 4 6 ) l ,
dtype = [ ( ' date ' , ' O ' ) , ( ' open ' , ' < £ 8 ' ) , ( ' h i gh ' , ' < f B ' ) , ( ' l ow ' ,
' <fB ' ) , ( ' close ' , ' <fB ' ) , ( ' vo l ume ' , ' <i4 ' ) , ( ' adj _c l o s e ' , ' <fB ' ) ] )
>>>
enddate = ( 2 0 1 3 , 1 1 , 9 )
p = quotes_hi storica l_yahoo_ochl ( ti c k e r , begdate , enddate , a sob j e c t=T rue ,
adj u s ted=T rue )
ret = ( p . a c l o s e [ l : ] - p . aclose [ : - 1 ] ) /p . a c l o s e [ l : ]
[ n , b in s , patches ] = h i s t ( re t , 1 0 0 )
7. 1 0 从雅虎 财 经 网 站 下 载 历 史 价格 数据 121
mu = np . mean ( re t )
s i gma = np . s td ( re 七 )
2 5 •-
.uuanbay
20 15
10 1·
5
图 7- 1 7
下 一 段代码使得交易 日 较均 匀 地分布。
r = m l ab . csv2rec ( p r i ce ) ; p r i c e . close ( )
r . sort ( )
r = r [ - 3 0 : ] # ge 七 the l a s t 3 0 days f i g ,
a x = pl t . subp l o t s ( )
pl t . p l o t ( r . date , r . adj _cl o s e , ' o - ' )
p l t . t i t l e ( ' Fi g . 1 : I BM last 3 0 days with gaps on wee kends ' )
# fi g . auto fmt_xdate ( )
N = len ( r )
ind = np . a r ange ( N ) # the eve n l y spaced p l o t i ndi ces
de f f ormat_date ( x , pos =None ) :
thi s i nd = np . c l ip ( i nt ( x+ 0 . 5 ) , 0 , N- 1 )
re 七 u r n r . date [ t his i nd ] . s t r f 七 ime ( ' 毛Y- 毛m-沧d ' )
#
f i g , ax = p l t . subplots ( )
plt . p l o t ( i nd, r . adj_c l o s e , ' o- ' )
p l t . x l abe l ( "Every Monda y shown " )
ax . set_t i t l e ( ' Fi g 2 : I BM l a s t 3 0 days evenl y spaced p l o t indices ' )
ax . xa x i s . set_maj or_ f o rmatte r ( ti c ke r . FuncForma 七 t e r ( f orma t—dat e ) )
f i g . auto fmt_xdate ( )
p l t . show ( )
绘制的第二张图如图 7- 1 8 所示 。
182
空2: IBM 正 30 血” “如ly
180
178
17•
174 •-
172
170
1611
归 ,_
. 一心
-"� -,r> �1
164
企 ,»v 1少 1 记t � 1少 1企
. 心 少
、“
lo 令 妒 -,r>\. 令 -,r>\. 令
图 7- 1 8
\
begdate = ( 2 0 1 3 , l , l )
enddate = ( 2 0 1 3 , 2 , 9 )
retl=ret_f { ' IBM ' , be gdate , e nddat e )
ret2= ret_f ( ' " GS PC ' , begdate , enddate )
n=min ( l en ( re t l ) , l en ( re t2 ) )
s = np . ones ( n ) * 2
t=range ( n )
l i ne = np . zeros ( n )
plot ( t , retl [ O : n ) , ' r o ' , s )
plot ( t , r e t2 [ 0 : n ] , ' bd ' , s )
plot ( t , l ine , ' b ' , s )
f i gtext ( 0 . 4 , 0 . 8 , " Red f o r IBM , Blue for S & P S O O " )
x l im ( 1 , n )
ylirn ( - 0 . 0 4 , 0 . 0 7 )
t i t l e ( " Cornparions between stock and mar ket re七un s " )
x l abel ( " Day " )
ylabel ( " Returns " )
sho w ( )
0.04
.
O.o2
. .....
.
•
• •
•
o.ool • • •• •• • •
-0.02
J心 五
图 7- 1 9
1 24 第7章 用 matplotlib 模 块绘 制 与 金 融 相 关 的 图 形
7. 1 1 了解现金 的 时 间 价值
输出如图 7-20 所示 。
\
7. 1 2 用 烛 台 图 展 示 IBM 的 每 日 收 盘 价 1 25
.ed
Today's value of $100 received today
Today's value of $100 received in 2 years
received in 6 years
/
. ars
。ye
.
r
e
c
e
'
v
,
,0
10
,
-2 立
Time (number of years)
2 4 6 8
图 7-20
7. 1 2 用 烛 台 图 展 示 I BM 的每 日 收盘价
f i g , ax = plt . subplots ( )
f i g . subplot s_adj u s t (bot七om=0 . 2 )
ax . xax i s . s e 七_ma j o r_locator (monda y s )
ax . xax i s . s et_mi nor_locat or ( a l ldays )
ax . xaxi s . set_maj or_formatter ( wee kFo rmatte r )
ax . xaxis . s e 七_mi nor_formatte r ( dayFormatte r )
plot_day_summary_oclh ( a x , quo七 e s , t i c k s i z e=3 )
_candl e s t i c k ( ax , quote s , width=0 . 6 )
ax . xaxi s_date ( )
ax . autosca le_view ( )
p l t . se tp ( pl t . gca ( ) . ge 七_xt i c klabe l s ( ) , rota七ion = 8 0 ,
hori zontal al i gnment= ' r i gh七 I )
plt . f igtex t ( 0 . 3 5 , 0 . 4 5 , ' 1 0 /2 9 : Ope n , H i gh , Low , Close ' )
p l t . f i gtext ( 0 . 3 5 , 0 . 4 2 , ' 1 7 7 . 62 , 1 8 2 . 3 2 , 1 7 7 . 5 0 , 1 8 2 . 1 2 ' )
p l t . f i gtext ( 0 . 3 5 , 0 . 3 2 , ' B lack == > Close > Open ' )
plt . figtext ( 0 . 3 5 , 0 . 2 8 , ' Red ==> C l o s e < Open ' )
plt . t i t l e ( ' Candl e s t i c k s for I BM from 1 0 / 2 0 / 2 0 1 3 七Q 1 1 / 1 0 / 2 0 1 3 I )
pl七 . ylabel ( ' Pr i ce ' )
pl t . xlabel ( ' Date ' )
plt . show ( )
1•!血 +,
。立 竺, 邮 fn,n, 10/功'2013 llo 11/J吵13
1821,
,l
1801
',
俨
,.,., , ,
17 8十
l70U-
2
平
图 7-2 1
\
7. 1 3 用 图 形展示价 格变化
import da 七 e time
import matp l o t l ib . pyp l o t as p l t
from matpl o t l i b . dates impor \ Mon 七 hLocator , DateFormat 七 e r
from ma 七p l o t l i b . finance import quotes_h i s t o r i c al_yahoo_ochl as get Data
#
t i c k e r = ' AAPL '
begda 七 e= date t ime . date ( 2 0 1 2 , 1 , 2 )
enddate = datetime . date ( 2 0 1 3 , 1 2 , 4 )
months = MonthLocator ( range ( l , 1 3 ) , bymonthday= l , inte rval = 3 )
# every 3 r d month
monthsFmt = DateFormatter ( " %b ' %Y " )
x = getData ( t i c ke r , begdate , enddate )
#
i f l e n ( x ) == 0 :
print ( ' Found no quotes ' )
raise SystemExit
dat es = [ q [ O ] for q i n x]
closes = [ q [ 4 ] f o r q i n x ]
f i g , ax = p l t . subplots ( )
ax . pl ot_date (dat e s , c l o ses , ' - ' )
ax . xaxis . se t_maj or_locator ( mon 七 hs )
ax . xaxi s . set_ma j o r_forma 七 ter ( monthsFm 七 )
ax . autosca l e_view ( )
ax . g r i d ( True )
f i g . auto fmt_xdat e ( )
plt . show ( )
700
650
600
550
500
450
· .
叩F
图 7-22
1 28 第7章 用 matplotlib 模 块 绘 制 与 金 融 相 关 的 图 形
import numpy as np
import pandas as pd
import datet ime as dat e t ime
import matp l ot l ib . pyplot as p l t
t i c ker = ' AAPL '
path = ' ht 七p : //www . googl e . com/ fi nance /getpr i c e s ? q= t t t & i = 6 0 &p = ld&f=d, o , h ,
l , c,v'
p=np . array ( pd . read_csv (path . replace ( ' ttt ' , ticker) , s kiprows=7 , header =None ) )
#
dat e = [ l
for i in np . aran ge ( O , len ( p ) ) :
i f p [ i ] [ 0 ] [ 0 ] == I a I :
t= datetime . datetime . fromtimes tamp ( i nt ( p [ i ] [ O J . replac e ( ' a ' , ' ' ) ) )
date . append ( t )
else :
date . append ( t +da 七 etime . t imede lta (minutes = int ( p [ i ] [ O J ) ) )
#
final=pd . DataFrame ( p , index=dat e )
f i n a l . col umns = [ ' a ' , ' Open ' , ' High ' , ' Low ' , ' Clos e ' , ' Vol ' ]
de l final [ ' a ' ]
#
x = final . index
y=final . C l ose
#
p l 七 . 七 itle ( ' I n t raday p r i ce pattern for t tt ' . replace ( ' t t t ' , t i c ke r ) )
pl 七 . x labe l ( ' P r i ce o f s tock ' )
p l t . ylabel ( ' I nt ro-day price pa 七 t e rn ' )
pl t . pl o 七 ( x , y )
p l t . show ( )
显 示 结 果 如 图 7-23 所 示 。
可 以 在 http://matplotlib.org/examples/pylab_examples/finance_work2.html 找到 一 个绘制
日 价格 图 形 的 更 复 杂 的 代 码 。 与 之 相 比 , 我 们 的 代码较为 简 单 。 为 了 节 省 空 间 , 这 里 省 略
\
了 生 成 图 7-24 所 示 图 形 的 Python 代 码 。
7.14 同 时 展 示 收 盘 价和 交 易 量 1 29
566
r
I:!.
\
牢
·� 562 ,.
f-
口.
560
558
图 7-23
IBM daily
RSI (14)
200
160
120
80
-5
-1 0
图 7-24
7. 1 4 同 时展示收盘价和 交 易 量
显示结 果 如 图 7-25 所 示 。
200
180
2心
1心
uo
100
|—
2.S
Volume I
20
15
1.0
心、..
05
心, 、.,
-IP"'
-,,.9
0.0
心心 夕
、令
飞0
Data
图 7-25
7.14. 1 在图形上添加数学公式
金融计算经 常 用 到 许 多 数 学 公 式 。 有 时 候 , 需要把 个 数 学 公 式 添加 到 图 形上 。 下面
一
的 代 码 利 用 matplotlib 模块来实现计算看涨期权价格 的 数 学 公 式 。
import numpy as np
import matplot l i b . ma thtext as mathtext
impor 七 ma tpl o t l ib . pyplot a s p l t
import matp l o t l i b
#
fig = p l t . f i gure ( )
fig . figimage ( r l . as type ( f l oat ) / 2 5 5 . , 1 0 0 , 1 0 0 )
f i g . figimage ( r 2 . astype ( f loat ) / 2 5 5 . , 1 0 0 , 2 0 0 )
f ig . f igimage ( r 3 . as type ( fl oa七) / 2 5 5 . , 1 0 0 , 3 0 0 )
plt . s how ( )
c = Bo N估
J ) ---Ke-rT N(d.i )
) +(r+tr /2)T
"1 - = 叫 /K
· 歹
"'2 = 叫�fl(J
贮 '+ {1'-tr 几汀
r .. = d1 - 0' 汀
型
图 7-26
7.14.2 在图形上添加简单的图像
假设把 Python 的标志保存在 c:\temp 目录下 。 下 面的代码 可以在 http://canisius.edu/
-yany/python_logo.png 网 站下载该标志 :
绘制的图形如图 7-28所示。
12
10
8
6
4
2
。 LO
3
2
5
4
图 7-28
如 果 代码 不 指 定 一 个 特 定 的路 径 , 这 一 图 形 文 件 将 在 当前工作 目录下, 通 常 是
c:\ yt
p h on2 7。
7. 1 5 比较个 股 的 表现
import numpy a s np
import ma 七plotl ib . p yplot as p l t
import matp l ot l ib . pyplot as p l t ; p l t . rcdefa u l t s ( )
from matp lot l ib . f inance impo rt quotes_h i storical_yahoo_ochl as getData
#
7. 1 6 比较 多 只 股 票 的 收益 率 与 波 动 率 1 33
s tocks =( ' I BM ' , ' DELL ' , ' WMT ' , 'C' , ' AAPL ' )
begdate= ( 2 0 1 3 , 1 , 1 )
enddate = ( 2 0 1 3 , 1 1 , 3 0 )
#
de f re 七 _annual ( t i c k e r } :
X = ge 七 Data ( t i c ke r , begda t e , e nddat e , a s ob j e c 七 =True , adj u s t ed=Tru e )
绘制的柱状图如图 7-29 所示 。
Perfonnance compafisons (annual return)
AA.PL ,-
C卜
WMT •·
OEU
吨10
Annual n如ms
-0.05 0.00 0.05 0.10 0.15 0 20 0 2S 0.30 0.3S
图 7-29
7. 1 6 比 较 多 只 股票 的收益率 与 波 动 率
import numpy as np
1 34 第7章 用 matplotlib 模 块 绘 制 与 金 融 相 关 的 图 形
0.3 I GE c
• .
.从
02
0 WMT
.,1
1
i 01
J PL
IB M
-01 I -
图 7-30
7. 1 7 查找学 习 手册 、 示 例 和 有 关视频
• http://www.youtube.com/watch?v=0fumUp3hZmQ
• http://www.activestate.com/activepython/python-financial-scientific-modules (5 m, 37s)
下面的视频介绍如何通过视觉方式 分 析财务报表。
• http://www.youtube.com/watch?v= OfumUp3hZmQ
1 36 第 7 章 用 matplotlib 模 块 绘 制 与 金 融 相 关 的 图 形
7. 1 8 独立安装 matplotlib 模块
通过两 个步 骤来安装该模块。
I . 转到 http://matplotlib.org/downloads.html 。
7. 1 9 小结
练 习题
I . matplotlib 模块的潜在用途是什 么 ?
2 . 如何安装 matplotlib 模块?
4. 编写 一 个 Python函数用来绘制一组给定现金流的净现值 曲 线 。
>>>A= [ O . 0 9 , 0 . 0 2 , - 0 . 1 3 , 0 . 2 0 , - 0 . 0 9 , - 0 . 0 3 ]
>>> B= [ 0 . 1 0 , - 0 . 3 , -0 . 02 , 0 . 1 4 , - 0 . 1 3 , 0 . 2 3 ]
> > >C= [ 0 . 0 8 , - 0 . 1 6 , 0 . 0 3 3 , - 0 . 2 4 , 0 . 0 5 3 , - 0 . 3 9 ]
>>>port_EW= ( A+ B ) / 3 .
8. 如何计算给定的一组股票的滑动时间窗 口 里的贝 塔值 ?
11 . 什 么 是资 本市场线 ? 如何以视觉方式展示这个概 念 ?
1 2 . 什么是证券市场线 ? 如何以视觉方式展示这个概 念 ?
或每 日 数据 。
1 5 . 如何展示风险和回报率 之间的关系?
YAF IH N CE.
NAOO ! 二一
叶�SEI OlX NIFTY
Recent 'I(, s AD.JI Dow Jones lndustnal Average
AAPL �o 5 1 % AGSPC S&P 500
DELL 0.邓 •IX!C NASDAQ Compostte
IBM �o 19% AVJX VOLATILITY S&P 500
IBM L 0.00% AJKSE Composite Index
WMT -0 97% •NOX NASOA0-100
•N225 M1kke1 225
心SPC -0 43%
ATf'll( CBOE Interest Rate 10-Year T-No
'OJI -0 43%
•HSI HAJ�G SENG INDEX
-0 51%
图 7-3 1
1 38 第7章 用 matplotlib 模 块 绘 制 与 金 融 相 关 的 图 形
21 . 找出下面代码中的错误并改正。
22 . 本章讨论了有 关杜邦等式的
一
些 问题。 戴尔和沃尔玛这两 家公司的净资 产收益 率
ROE 同为 0.22。 然而, 图 7-32 中对应的柱状图 却有不 同的高度 。 原因是净资 产收益率 ROE
是 3 个量的乘积, 而不是求和。 找到 一 个方法来解决这个问题, 使得代表这两 家公司的柱
状 图有相同的高度。
DuPont Iden汛y ror 3 ftnns
9
一的
- profitMargin
皂I - assetTurnover
ultMultlpl1er
6
.
i
S
3
C5d8
`
`_
2
图 7-32
第8章
\
时 间 序列 的统计分析
• 使用 Panda s 和 s tatsmode l s 模块
• 利率的期限 结构
• 基于 52 周 最高和最低的交易策略
• 一
月 效应 、 规模效应和工作 日 效应
• 从谷歌 金融和 TORQ 数据库获取高频数据
图 8-2
图 8-3
1 42 第8章 时 间 序 列 的 统计分析
一
参 匀声 n>,tl叩 立
If )(
还口 三
I 竺 ·Cc� 2\� 8 X ct下.. .呜已血
-: .. .........,. 口 Objod l;
No docume,,口tJon ..啦le
J Sp)der Edito<
曷
s ,,,., t仑盲叩'•"Y ur,ot j ll• 1' located nor«
6 C: \U>•r汃y•••y\ , ,o,d,r>\, t•"P• PY
�
1 ...
8
i 空 …口擘
凶芒竺丁如吐 忐;;;- . . -
c,,,.;.. • /J X
立;;;_ , 13 I ...,1玉 '丘 儿
Python l. 7 . S I An,cc心• l . 1 . 1 (32-0it ) I (default, Jul l 2813, 12:'1 :SS) [吹 v
图 8-4
x= l O
print (x) # f o r Python2 . 7 print x
图 8-S
8.2 Pandas 和 statsmodels 模块简介 1 43
>>>import numpy as np
>>>import pandas a s pd
>>>dates = pd . date_range ( ' 2 0 1 3 0 1 0 1 ' , per iods = S )
>>>np . random . s e ed ( l 2 3 4 5 )
>>>x=pd . DataFrame (np . random . rand ( S , 2 ) , i ndex = dat e s , columns= ( ' A ' , ' B ' ) )
>>> x
A B
2013-01-01 0 . 929616 0 . 316376
2013-01-02 0 . 1 83919 0 . 20 4 5 60
2 0 1 3 - 0 1 - 0 3 0 . 5 67 7 2 5 0 . 595545
2 0 1 3- 0 1 - 0 4 0 . 9 64 5 1 5 0 . 653177
2 0 1 3 - 0 1 -05 0 . 7 4 8 907 0 . 653570
>>>x . de scribe ( )
A B
count 5 . 000000 5 . 000000
mean 0 . 678936 0 . 484646
std 0 . 318866 0 . 209761
min 0 . 183919 0 . 2 0 4 5 60
25% 0 . 5 67 7 2 5 0 . 3 16376
1 44 第8章 时 间 序 列 的 统计分析
。
1
0 . 100
0 . 02 0
2 -0 . 030
3 NaN
4 0 . 130
5 0 . 125
d七ype : f loat 6 4
> >>m = np . mean ( x )
> > > round ( m , 4 )
0 . 069
> > > y=x . f i l lna (m)
>>> y
0 0 . 100
1 0 . 02 0
2 -0 . 030
3 0 . 0 6 9 # nan i s rep l a ced with the mean
4 0 . 130
5 0 . 12 5
dtype : f loat 6 4
>>>
y = a +f3Xx+&1 C8-1 )
输出显示如下 。
8.3 开源数据
表 8-1
名称 网页
续表
名称 网页
美 国 人 口 普查数据
3 . 单击历史价格。
4 . 选择开始 和 结束 日 期后单击 “
获取价格
”
按钮。
5. 转到页面底部, 单击 下 载到电子表格 。
“ ”
以下给出下载的电子表格的开始和 结尾的几行数据记录。
1 9 6 2 - 0 1 - 0 9 , 5 5 2 . 0 0 , 5 6 3 . 0 0 , 5 52 . 0 0 , 5 5 6 . 0 0 , 4 9 1 2 0 0 , 2 . 4 3
1 9 62 - 0 1 -0 8 , 5 5 9 . 5 0 , 5 5 9 . 5 0 , 54 5 . 0 0 , 5 4 9 . 5 0 , 5 4 4 0 0 0 , 2 . 4 0
1 9 6 2 - 0 1 - 0 5 , 57 0 . 5 0 , 5 7 0 . 5 0 , 5 5 9 . 0 0 , 5 6 0 . 0 0 , 3 6 3 2 0 0 , 2 . 4 4
8 .4 用 Python 代 码 输 入 数 据 1 47
1 9 6 2 - 0 1 - 0 4 , 5 7 7 . 0 0 , 5 7 7 . 0 0 , 57 1 . 0 0 , 5 7 1 . 2 5 , 2 5 6 0 0 0 , 2 . 4 9
1 9 6 2 - 0 1 - 0 3 , 5 7 2 . 0 0 , 5 7 7 . 0 0 , 57 2 . 0 0 , 57 7 . 0 0 , 2 8 8 0 0 0 , 2 . 5 2
1 9 62 - 0 1 - 0 2 , 5 7 8 . 5 0 , 5 7 8 . 5 0 , 5 7 2 . 0 0 , 5 7 2 . 0 0 , 3 8 7 2 0 0 , 2 . 5 0
8.4. 1 从剪贴板输人数据
下面两行代码 。
>>>import pandas as pd
>> >data=pd . read_c l ipboard ( )
>>>data
X y
1 2
3 4
5 6
8.4.2 从雅虎财经网站下载历史价格数据
执行下面 5 行代码可以从 雅虎财经网站获取 DELL 的历史 价格数据 。
一
可 以 使用 七 ype ( ) 和 s i z e ( ) 函 数 来进 步 了 解变 量 p 的 属 性 。 图 8-6 为 它 开 始 和 结 尾
一
的 几 行 。 p [ 0 ] 代 表 数组 的 第 1 个观 测 值 , P [ - 1 ] 则 是最后 个。
>>>type ( p )
< c l a s s ' numpy . core . records . r ec a r ray ' >
>>>size (p) 209
» > p(0: 3 ]
rec . arra y( [ (datetime . d ate(2013, 1, 2 ) , 2013, 1, 2 , 734870 . 0 , 1 0 . 146067415730338, 1 0 . 5 , 1 0 . 5196
62921348315, 1 0. 126404494382024, 26421700 . 0, 10 . 5 ) ,
( datetime . date(2013, 1, 3 ) , 2013, 1 , 3, 734871.0, 10.435557586837295, 1 0 . 75 , 11. 13322669
1042047, 10 . 40607861060329 1 , 38131300 . 0, 10 . 7 5 ) ,
( datetime . date ( 2013 , 1 , 4) , 2013, 1 , 4, 73487 2 . 0, 1 0 . 740692798541476, 1 0 . 78 , 1 0 . 87826800
3646307 , 10 . 622771194165907, 18706400 . 0, 10 . 78 ) ] ,
dtype�[ ( ' date ' , ' O ' ) , ( ' year ' , ' < i2 ' ) , ( ' month ' , ' il ' ) , ( ' d ay ' , ' i l ' ) , ( ' d ' , ' <f8 ' ) , ( ' op
en ' , ' <f8 ' ) , ( ' close ' , ' <f8 ' ) , ( ' h igh ' , ' <f8 ' ) , ( ' low ' , ' <f8 ' } , ( ' volume ' , ' < f8 ' ) , ( ' aclose ' , '
<f8 ' ) ] )
>»
图 8-6
使用 h e l p ( re ad_tab l e ) 命 令 可以得到关千这 个
函数的更多信息, 如下所示。
read_table ( f i l epath_or_bu f f e r , sep = ' \ t ' , dialect = None , comp r e s s ion = None ,
doub lequote = True , es capechar = None , quo techar = ' " ' , quot i n g = O ,
s ki p i n i t i a l space = Fal s e , l i n e t e rmi nator =None , heade r = ' i n f er ' , i ndex_
col = Non e , name s =Non e , pre f i x = Non e , s k iprows = None , s kipfooter = None ,
s k ip_footer = O , n a_values = None , true_val u e s = None , false_va l u e s =Non e ,
de limiter = None , c onve r t e r s = Non e , d七 ype=None , u s e c o l s = None , engine = ' c ' ,
de肛m_whitespace = Fa l s e , as_r e c a r ray= Fal s e , na_f i l te r =True , compact_
ints = Fal s e , us e_uns igned= Fal s e , l ow_memory = True , b u f f e r_l i n e s = None ,
warn bad l ines = T rue , e r r o r bad l i n e s = True , keep de f a u l t na = T rue ,
thous ands = None , commen 七 = None , dec imal = ' . ' , pars e_date s=Fa l s e , keep_
date_col = Fal s e , dayf i r s t = Fal s e , date_parser =None , memor y_map = Fa l s e ,
nrows=None , i t e r a 七 or = Fal s e , chunks i z e =None , verbose = Fal s e , e ncoding =Non e ,
squeeze = Fa l s e )
Read general de l imited f i l e i n 七 o Da 七 aFrame
read_ t a b l e ( ) 函 数 最 重 要 的 参 数包 括 s k i p ro w s 、 s e p 、 i n dex c o l 和
doub l e qu o t e 。 本章的后面会对它们 做进一 步解释 。
A """'""''一"""" ,.
B ., 恤.,.一,.
幛
C
1 1/1/2013 0.1 0.3
2 I 1/2/2013 0.2 0.4
图 8-7
0 1 2
0 2013-01-01 00 : 0 0 : 00 0.1 0.3
1 2 013-01-02 00 : 00 : 00 0.2 0.4
>>>
8.4.6 从网页下载数据
也可以用 pd . re ad_c s v ( 函
) 数从 雅 虎财经网站直接获取股票的价格数据 。
Adj C l o s e
count 13837 . 000000
mean 42 . 316260
std 51. 321150
min 1 . 2 0 9 637
25告 5 . 8 5 4 63 6
50号 15. 980850
75% 70 . 854336
max 1 93 . 603554
>>>
>>>x [ 0 : 5 )
Da七e Open H i gh Low Close Volume
0 1 2 3 4
Adj C l o s e
0 1 2 3 4
166 . 729996
168 . 020004
168 . 509995
168 . 289993
165 . 500000
>>>
日 期 和 调 整 后 的 收 盘 价 , 可 以 用 usecols 参数来选取它们 。 因 为 共有 7 列 , 其 中 日 期 在第 1
一
列 而 调 整 后 的 价格在最后 列 , 所 以它们的列编号分别为 0 和 6。
>>>impor 七 pandas a s pd
>>>url= ' h ttp : / / char 七 . yaho o . com/ 七 able . c sv ? s = IBM '
>>>x =pd . r ead_c sv ( u r l , u s e c o l s = [ 0 , 6 ] )
>>>x [ 0 : 5 ]
Date Adj C l o s e
0 1 2 3 4
2 0 1 6- 1 2 - 1 6 1 6 6 . 7 2 9 9 9 6
2 0 1 6- 1 2 - 1 5 1 6 8 . 0 2 0 0 0 4
2 0 1 6- 1 2 - 1 4 1 6 8 . 5 0 9 9 9 5
2 0 1 6- 1 2 - 1 3 1 6 8 . 2 8 9 9 9 3
2 0 1 6- 1 2 - 1 2 1 6 5 . 5 0 0 0 0 0
>>>
8.5 几个重要 的 函 数
20 13-01-01 0 . 77 6 670
2 0 1 3 - 0 1 - 02 0 . 12 8 904
20 13-01-03 -0 . 0 6 4 60 1
2 013-01-04 0 . 988347
\
2013-01-05 0 . 4 5 9587
Freq : D , dtype : f l o a t 6 4
>>>data . ta i l ( )
201 3-09-05 - 0 . 1 67 5 9 9
20 13-09-06 0 . 530 8 64
2 0 13-09-07 1 . 378951
2 0 1 3- 0 9- 0 8 - 0 . 7 2 97 0 5
2013-09-09 1 . 414596
Freq : D , dtype : f l oat 6 4
>>>
8丘2 使用 日 期变量
Adj C l o s e
Date
2 0 1 6- 1 2 - 1 6 166. 729996
2 0 1 6- 168 . 020004
2 0 1 6- 1 2 - 1 4 168 . 509995
2 0 1 6- 1 2 - 1 3 168 . 28 9993
1 54 第8章 时 间 序列 的 统计分析
2 0 1 6- 1 2 - 1 2 1 65 . 5 0 0 0 0 0
>>>
8 丘3 使用 DataFrame 数据类型
第 1 个例子生成只有 1 列的 DataFrame 数据 。
Date Adj C l o s e
2 013-11-21 184 . 13
2 0 1 3-1 1-20 185 . 1 9
2013-11-19 185 . 25
2 0 1 3- 1 1 - 1 8 184 . 47
2013-11-15 183 . 19
要 查 找 有 关 pd.DataFrame() 函 数 的 更 多 信 息 , 可 以 使用 help(pd.DataFrame)命 令 。
Parameters
8.6 计算 回 报率
使用下面的代码计算回报率:
>>>re 七= ( p [ 1 : ] -p [ : - 1 ] ) /p [ : - 1 ]
>>>p r i n t ret
[ 0.1 -0 . 1 8 1 8 1 8 1 8 0 . 1 6666667 ]
» > r e t = ( p [ : - 1 ] -p [ l : ] ) /p [ l : ]
> > >p r i n t r e t
(-0 . 09090909 0 . 2 2 2 2 2 2 2 2 - 0 . 1 4 2 8 57 1 4 ]
>>>
ret= ( x . ac l o s e [ l : ] - x . ac lose [ : - 1 ] ) / x . a c l o s e [ : - 1 ]
>>>x . date [ 0 : 3 ]
array ( [ datet ime . date ( 2 0 1 3 , 1 , 2 ) , date t ime . date ( 2 0 1 3 , 1 , 3 ) ,
date 七 ime . da 七 e ( 2 0 1 3 , 1 , 4 ) ] , dtype=ob j e c t )
>>>x . aclose [ 0 : 3 ]
array ( [ 1 9 2 . 6 1 , 191 . 55, 1 90 . 3 ] )
>>>re 七 ( 0 : 2 ]
array ( [ - 0 . 0 0 5 5 0 3 35 , - 0 . 0 0 6 5 2 5 7 1 ] )
»> ( 1 9 1 . 5 5 - 1 9 2 . 6 1 ) / 1 9 2 . 6 1
-0 . 005503348 7 35 7 8 7 3 5 4
>>>
结 果 验 证我们 得 到 的 第 1 个 回 报 率 是 正 确 的 。
这个月 的对数回报率的 定 义 如下 。
百 分 比 回报率和对数回报率之 间 的关系如 下 。
然后, 对数回报率的总和 如下 。
i mport numpy as np
import pandas as pd
f rom matp l o t l ib . f i nance impor t quote s_hi s t o r i c a l_yahoo_ochl a s getData
t i c ke r = ' I BM '
begdate = ( 2 0 1 3 , l , l )
enddate= ( 2 0 1 3 , l l , 9 )
x = getData ( t i c ke r , begdate , endda t e , a s ob j ec t=Tru e , adj us ted=Tru e )
l o g r e t = np . l og ( x . a c l o s e [ l : ) / x . ac l o se [ : - 1 ) )
yyy ymrn= [ l
dO=x . date
for i i n r ange ( O , np . s i z e ( l ogre t ) ) :
yyyymrn . append ( ' ' . j o in ( [ d O [ i ) . s t r f t ime ( " 毛 Y " ) , dO [ i ] . s 七 r f t ime ( " %m" ) l ) )
y pd . DataF rame ( l ogre t , yyyymm, co lumns = [ ' ret_mon th l y ' ) )
=
图 8-8
变量。
日期
»> dO [ O J
date 七 ime . date ( 2 0 1 3 , 1 , 2 )
> >>dO [ O ] . s tr f time ( " 毛 Y " )
' 2013 '
\
>>>dO [ O J . s t r f t ime ( " %m" )
' 01 '
>>> ' ' . j o i n ( [ dO [ O J . s t r f t ime ( " 毛 Y " ) , dO [ O J . s trft ime ( " %m" ) ) )
I 201301 '
>>>
显示月回报率的几 个值如下。
>>>ret_monthly
re t_monthly
201301 0 . 043980
2 0 1 302 -0 . 0 0 6 8 8 0
201303 0 . 045571
201304 -0 . 061913
201305 0 . 050327
201306 -0. 088366
201307 0 . 023441
2 0 1 30 8 -0 . 057450
2 0 1 30 9 0 . 013031
201310 -0 . 039109
201311 0 . 009602
>>>
8心2 从 日 回报率计算年回报率
p r i nt ( ret_annual . 七 a i l ( ) )
ret annual
2008 -0 . 1508 1 3
2009 0 . 546113
2010 0 . 134778
2011 0 . 2 8 4 65 1
2012 0 . 0 4 5 4 52
8.7 按 日 期 合并数据集
通常用 日 回 报率来计算 贝 塔值, 以衡量 一家公司的市场风险。 以IBM为例, 需要 I BM
的价格、 市场回报率和无风险利率来估计资 本资 产定价模型 (CAPM)。 以下的代码用来下
载这些 数据。
8.8 构建 n 只股票 的 投 资 组合
以下的代码生成 一个包含 S & P500 指数和 3 只股票的回报率的数据集 。
8.9.1 检验方差是否 相等
接 下 来 , 检验 IBM 和 DELL 在 20 1 3 年 的 方 差 是 否 相 等 。 sp . s ta t s . b a rt l e t t ( ) 函
数采用 Bartlett 方法来检验 多 个 样 本 集 的 方 差 是 相 等 的 这个 零假 设 , 通 常 称 为 F-检验 , 该 函
数输出 t 值和 p 值 。
impor t scipy as sp
f rom matplotl i b . finance import quotes_h i storical_yahoo_ochl a s ge 七 Da 七 a
begdate = ( 2 0 1 3 , 1 , 1 )
enddate = ( 2 0 1 3 , 1 1 , 9 )
pva lue = 0 . 0 1 5 6 8 6 6 6 5 5 0 1 2 6 5 3 6 8 )
8 从 2 测试 ” 一月 效应 ”
t i c ke r = ' 工 BM '
begdate = ( 1 9 6 2 , 1 , 1 )
endda七e= ( 2 0 1 3 , 1 1 , 2 2 )
x =ge tData ( t i c k e r , begda七e , endda七 e , asobj ect=True , adj us ted=T rue )
logret = s p . l o g ( x . ac l o s e [ l : ] /x . ac l o s e ( : - 1 ] )
date = [ l
dO=x . date
for i i n range ( O , sp . s i z e ( l ogr e t ) ) :
t l = ' ' . j o in ( [ d O [ i ] . s t r f t ime ( " % Y " ) , dO [ i ] . s t r ftime ( " %m" ) ] )
date . appe nd ( datetime . s t rpt ime ( t l , " %Y%m " ) )
8. 1 0 金融研究和 实 战 的 应 用 举例
8.10.1 基于 52 周最高价和最低价的交易策略
一些 投资 者/研究人员建议采用基于 52 周 最高价和最低价的交易策略, 当某 只股票今
天的价格接近过 去 52 周 达到的最高价格, 卖出该股 票 ; 当其 今天的价格接近过去 5 2 周 达
到的最低价格, 则买入该股票 。 下面的 Python 程序输出这 52 周 的价格范 围和今天价格的
相对位置。
相应的输出如图 8- 1 0 所示。
图 8- 1 0
S = 2 妒cov (M, 凶江 ) ( 8- 7 )
s
¾spread = — ( 8-8 )
p
这里 , S 为买卖价差, P,为股票在第 t 天的收盘价, P 是在一 段时间内每 日 收盘价的平
均值。 Roll 的方法有一 个缺陷, 某些 股票在一定时间内的 自 相关系数可能是正的, 这样等
式 (8-7) 中的平方根号下的数值是 负 的 。 在这种情况下, 需要把 S 设 置为 0 。 可以用下面
的代码来估 计 R 和 P,-1 之 间 的协方差 。 下面的 Python 代码从 雅虎财经下 载 DELL 这只股票
在最近 一年 252 个交易 日 的 日 回报率 , 并利用 Roll 的方法来估计 DELL 的买卖价差 。
相应的输 出 如图 8- 1 1 所示。
图 8- 1 1
R,
l = \ \
i liq, (8-9)
P, X �
import numpy as np
import statsmode l s . api as sm
fr om matplot巨b . f inance import quotes_h i s t o r i c a l_yahoo_ochl as getData
begdate= ( 2 0 1 3 , 1 0 , l )
enddate= ( 2 0 1 3 , 1 0 , 3 0 )
t i c ker = ' I BM '
这里, Yi 是 超 额 股 票 回 报 率 , X 1 ,1 是 市 场 回 报 率 , X2,1 是 带 符 号 的美 元 交 易 额
C x2,1 =sign(Rr -R1,1) X Pr X volumer ) , R1 为股票第 t 天的回报率, R1,1为无风险利 率 , Pr 是股票
价格, volume, 是交易额。 这 个 回 归 模 型用每 个月的 日 回报率来估计,也就是说, 每 个 月 得到
一 个 伤 的估计值 。 Pastor 和 Stambaugh ( 2003 ) 把 /J2 作为流动性指 标 。
图 8- 1 2
假 设 要 利 用 从雅虎财经下载的 每 日 数 据 来 估 计 IBM 的 市 场 风 险 ( 贝 塔 值 ) 。 下 面 的 线
性 回 归 定 义 了 贝 塔值 。
灼 = a + /3.凡,kt,t + 6, ( 8- 1 2 )
impor 七 numpy as np
impo rt s tatsmodel s . api as sm
f rom matp l o t l ib . f inance import quotes h i s t o r i c a l yahoo ochl as getData
begdate= ( 2 0 1 3 , 1 , 1 )
enddate= ( 2 0 1 3 , 1 1 , 9 )
输出结果如图8- 13所示。
Warnings:
11 Standard Errors assume that the covariance matrix ofthe errors is correctly specified.
图 8- 1 3
2
险溢价将增加 0.74% 。 20 1 3 年 共 有 2 1 6 个 观 察 值 , 调 整 后 的 R 是 1 8.7% 。 另 外 , 细 心 的 读
者会发 现更 多 的 信 息 , 比 如 Durbin-Watson 统计量和 Jarque-Bera 统计量 , 等 等 。 在讨论如
一
何运行 Fama-French 三 因 素 模 型 前 , 介 绍 如 何 把 Fama-French 数据保存在 个特殊 格 式 的
一
数据集里 。 每 个 Pandas 对象都有 内联 函 数 , 它 把 数据 以 Pickle 模 块 的 数 据 结 构 形式按照
给 定 的 名 称保存到指 定 的 目 录下 , 代码 如下 。
>>>impo rt pandas as pd
>>> import numpy as np
>>>np . random . seed ( l 2 3 4 )
>>>a = pd . DataFrame ( r andn ( 6 , 5 ) )
>>>a . to_p i c k l e ( ' c : / temp /a . pi c k l e ' )
>>>k=l oad ( " c : / temp / a . pickl e " )
一
在 以 上代码 中 , 如 果 只 需 要 产 生 任 意 组 6 行 5 列 的 随机数 , 就 不 需 要 np .random. seed
一
( 1 234 ) 。 使用 这 个 函 数 保证 每 次 运 行 上述代 码 , 都 可 以 获 得 同 样 的 组随机数 。 另 外 , 输
一
出 文 件 的 扩展 名 不 定 是.pickle, 任何扩展名 都 可 以 ( 即 使没有扩展 名 也 可 以 ) 。
>>>print ( k )
>>>
。 0 . 471435
。 -1 . 1 90976
1
1 . 432707
2
-0 . 3 1 2 652
3
-0 . 72058 9
4
201306
Mkt Rf
-0 . 0121
SMB
0 . 0123
HML
-0 . 0045
Rf
。。
。。。
20 1307 0 . 0 5 65 0 . 0185 0 . 0079
201308 -0 . 0269 0 . 0028 - 0 . 02 4 6
201309 0 . 0376 0 . 0285 -0 . 0152
201310 0 . 0417 - 0 . 0 1 52 0 . 0139
>>>
七 i c ke r = ' 工 BM '
8. 1 0 金融研究和实战 的应用 举例 1 73
begdate = ( 2 0 0 8 , 1 0 , l )
enddate = ( 2 0 1 3 , 1 1 , 3 0 )
const 0.001440
MKT_RF 0.803794
SMB 0. 1 04695
HML -0.336957
dtype: float64
图 8- 1 4
import pandas a s pd
n = 252
np . randorn . seed ( 1 2 3 4 5 ) begdat e=da 七 et ime ( 2 0 1 3 , 1 , 2 )
dateRange = pd . date_range ( be gdate , per io ds=n )
xO= pd . DataFrame ( np . random . randn ( n , 1 ) , column s = [ ' ret ' ) , index = dateRange )
yO=pd . S e r i e s ( np . random . randn ( n ) , index = dat eRange )
print pd . o l s ( y=yO , x=x O )
用以下的代码来估计 Fama-MacBeth 回 归。
data = {
' A ' : ma keDataFrame ( ) ,
' B ' : ma keDataFrame ( ) ,
' c ' : makeDataFrame ( )
Y = makeData Frame ( )
print ( pd . fama_macbeth ( y= Y , x=data ) )
8.10.7 滚动式估算市场风险系数
以下 代码使用 pd.ols 函数和参数值 window=252 来滚动式估算市场风险系数( 贝 塔值 )。
import numpy a s np
import s t at smode l s . ap i as sm
耳nport pandas as pd
from matp l o t l ib . f inance import quotes h i s torical yahoo ochl as getData
begdate = ( l 9 6 2 , 1 , 1 )
enddate = ( 2 0 1 3 , 1 1 , 9 )
yO=pd . S e r i e s ( r e t_f ( ' 工 BM ' , be gd ate , enddat e ) )
x O = pd . S e r i e s ( r et_f ( ' " GSPC ' , begda t e , enddate ) )
mode l = pd . ol s ( y = yO , x = x O , wi ndow = 2 5 2 )
print (mode l . be t a . he ad ( ) )
可以用下面的代码查 看得到的贝塔值。
L5
。心。
I.S
。 2000 - 4000
6000--- 8QllO --10000
—
立000 lAOOO
图 8- 1 5
1 76 第 8 章 时 间 序列 的统计分析
import numpy a s np
impo rt pandas as pd
impo r t stat smode l s . ap i as sm
fr om matp l ot l i b . finance impor七 qu otes h i s 七o r i c a l yahoo ochl as getData
be gdate= ( l 9 62 , 1 , 1 )
enddate= ( 2 0 1 3 , 1 1 , 9 )
yO =pd . S e r i e s ( r et_f ( ' I BM ' , begdate , enddat e ) ) xO=pd . S e r i e s ( r et_f ( ' " GSPC ' ,
begdate , e nddate ) )
d=getData ( ' " GSPC ' , begdate , endda t e , asobj e c t=True , adj ust ed=True ) .
date [ 0 : - 1 )
l a g_year=d [ O ) . s t r f time ( " 毛 Y " )
yl= [ )
xl= [ )
beta= [ ]
indexO= [ )
for i i n range ( l , l e n ( d ) ) :
yea r=d [ i ) . s t r f time ( " 毛 Y " )
i f ( year == l a g_ye a r ) :
x l . append ( xO [ i ) )
y l . append ( yO [ i ) )
else :
model =pd . o ls ( y=pd . S e r i e s ( y l ) , x=pd . S e r i e s ( x l ) )
p r i n t ( l ag_yea r , round (mode l . beta [ 0 ) , 4 ) )
beta . append (model . be七a [ O J )
i ndex O . append ( l a g_yea r )
xl= [ )
yl= [ )
lag_year=year
\
下面给出最初 几年的 贝 塔值 。
( ' 1 9 65 ' , 1 . 04 9 )
( ' 1966 ' , 1 . 27 5 )
( ' 1 967 ' , 1 . 3 92 7 )
( ' 1968 ' , 1 . 5419)
( ' 1969 ' , 1 . 235)
(
I
1970 I I 1 . 3438)
8.10.8 在险价值简介
我们 常用几种方 法来 评 估 单 个公司 、证券或组合的风险, 如标准 偏 差 、 方 差、 贝 塔
值或夏 普比率。 许多企业的决 策者更喜欢用 一 个
简单 明 了 的金额来量度风险。 在险价值
C V aR)是被广泛采用的指 标之 一 , 它代表在给定的置 信水 平 于 一 段时间内的可能蒙受的
损 失 。 图8-16 基于标准 正 态分布 演 示在险价值这 个概念。
0.45
VaR based on the standard normal distribution
0.40
0.35
0.30
0.10
0.05
。
-3 -2 -1
Z-values
图 8- 1 6
VaR = p X z X a C 8- 1 5 )
import numpy as np
impor七 pandas a s pd
f r om s c i p y . stats impor t norm
fr om matp l ot巨b . 丘nance impo rt quote s_hi st orical_yaho o_ochl as getDa迳
n shares = S O # input 1
conf idence l eve l 0 . 9 9
= # input 2
n_da ys = l O # i npu七 3
z=norm . pp f ( conf idence l evel )
ticker = ' WMT '
be gdate = ( 2 0 12 , l , l )
enddate = ( 2 0 1 2 , 1 2 , 3 1 )
x = ge七Data ( t i c k e r , begdate , enddate , a sobj ect = True , adj usted = True )
ret = x . a c l o s e [ l : ] / x . ac l o s e [ : - 1 ) - 1
po s i t i on=n_shares * x . close [ O ]
VaR=po s i 七 i on * z * np . s七d ( re 七 ) * np . sqrt ( n_days )
p r int ( " Ho l ding = " , po s i t ion , "VaR= " , round ( VaR, 4 ) , " i n " , n_da ys , " Days " )
( ' Ho l ding= ' , 2 6 5 0 . 3 0 7 0 4 9 9 9 9 9 9 9 9 , ' VaR= ' , 2 0 0 . 1 9 1 4 , ' i n ' , 1 0 , ' Days ' )
8. 1 1 构 建有效组合边界
一
构 建 有 效 组 合 边 界 是 金 融领域 个 非 常 有 挑 战性 的 工 作 。 如 何 利 用 实 际 的 数据构建有
效 组 合边界难度 更 大 。 本 节 将 重 点 讨 论 如 何 从 雅 虎 财 经 下 载 历 史 数据 来估计方差-协方差矩
阵 , 找 到 最优投 资 组合 和 构 建 有 效 组 合边 界 。
8.1 1. 1 估计方差-协方差矩阵
一
假 定 几 只 股 票 的 回报率保存在 个 数 组 里 , 可 以 用 这个 数 组 来 计算这几 只 股 票 的方 差-
8. 1 1 构 建 有 效 组 合边界 1 79
n
T台
RI n
( 8-16 )
-R
=
I(R; - 时
(J' = (8- 1 7 )
n-1
, a=品
2
a:,1 = w; 忒 + w回 + 2 w1 w2 a,.2 = w; 忒 + w;a, + 2 w, (1 - w2 ) pa, a2 ( 8-19 )
I ( RIJ - 瓦 )( R2,; - 困 )
= 旦 C 8-20)
<Y1 ,2 n-I
吐, i=I j=I
丿
W = (W1 , W2 , W3 , · · · , Wm ) C 8-23 )
以下公式用矩 阵形式表示投资组合的预期收益率 。
相对应的投资组合的方差为
al.I · · · a1 ,m
a1,2 · · · 生,m
.E = ( 8- 2 5 )
CY • • · CY
n,1 n,m
CYporr = W X L X W I C 8-2 6 )
2
import numpy as np
ret=np . mat r i x ( np . array ( [ [ 0 . 1 , 0 . 2 ] , [ 0 . 1 0 , 0 . 1 0 7 1 ] , [ - 0 . 0 2 , 0 . 2 5 ] ,
[ 0 . 0 1 2 , 0 . 0 2 8 ] , [ 0 . 0 6 , 0 . 2 62 ] , [ 0 . 1 4 , 0 . 1 1 5 ] ] ) )
p r i n t ( " re t u rn mat ri x " , r e t )
covar_=re七 . T * ret
we i ght=np . ma t r i x ( np . array ( [ 0 . 4 , 0 . 6 ] ) )
p r i n t ( " weight ve cot " , weigh 七 )
print ( we i gh 七 * covar_*weight . T )
[ 0. 1 4 , 0.1 1 5 ]]))
('weight vecot', matrix([[ 0.4, 0.6]]))
[[ 0. 1 05559 1 5] ]
图 8- 1 7
8. 1 1 构建有效组合边界 1 81
8.1 1 .2 优化 - 最小化
y = 2 + ax ( 8-2 7)
2
\
很显然, 当 x 等于 0 时, y 的值最小 。 以下代码用来找到 使 y 的值 最小的解 。
8.1 1 .3 构建一个最优投资组合
金融总是在风险与 收益之间寻求平衡 。 夏普比率 是衡量风险与收益是否对等的一 个重
要指标。 其 定义如下 。
E(R ) - R1
Sharpe = ( 8-28)
erp
import numpy a s np
import scipy a s sp
import pandas a s pd
from scipy . optimi ze import fmin
f rom matpl o t l i b . f inance import quotes_h i s t o r i ca l_yahoo_ochl a s getData
1 82 第8章 时 间 序 列 的 统计分析
第 3步调用 frnin()函数找到最优的投资组合。
n = l e n ( 七 i c ke r ) # number o f s to c k s
x2 = ret_annual ( t i c ke r [ O ] , begdate , endda t e )
for i i n range ( l , n ) :
x_ = ret_annua l ( t i c k e r [ 辽 , begdate , endda t e )
x2 =pd . me r g e ( x2 , x_, l e f t_\ndex = True , r i gh七_index = True )
图 8- 1 8
import numpy a s np
import s c ipy a s sp
import pandas as pd
import matp l o t l ib . p yp l o t as p l t
fr om numpy . l i na l g import i n v , pinv
from matp lotl i b . f i nance impor t quotes h i s t o r i c a l yahoo ochl as getData
# Step 2 : de f i ne 2 func t i o n s
de f re t_mont h l y ( t i c ker ) : # functio n 1
X = ge 七 Data ( t i c ke r , (begYear , 1 , 1 ) , ( e ndYe a r , 1 2 , 3 1 ) , as obj ect = Tr ue ,
adj us ted=True )
l ogret = np . log ( x . ac l o s e [ l : ) / x . ac l o se [ : - 1 ) )
date = [ )
dO=x . date
for i i n range ( O , np . s i z e ( l ogre t ) ) :
date . append ( ' ' . j o i n ( [ dO [ i ) . s t r ft ime ( " % Y " ) , dO [ i ) . s 七 r ftime
( " %m" ) ) ) )
y=pd . DataFrame ( l ogret , da 七 e , c o l umns = [ ti c ke r ) )
return y . groupby ( y . index) . sum ( )
输 出 的 图 形 如 图 8- 1 9 所 示 。
-0.010
0 01
- · 6.o4 0.06 0.08 0.10 0.12 0.14 0.16 0.18
图 8- 1 9
1 86 第 8 章 时 间 序 列 的 统计分析
8. 1 2 插值法简介
>>>impor 七 pandas as pd
>>>impor 七 numpy as np
>>>x=pd . Series ( [ l , 2 , np . nan , np .nan , 6 ] )
>>>x .inte rpolate ( )
0 1 . 000000
1 2 . 000000
3 4 . 6 6 6 6 67
2 3 . 333333
4 6 . 000000
y-y y -y
= '
。 。
x -x 。 。 ( 8-29)
X1 - X
求解以上方程得出 y 值的计算公式为
(x - x。)Y1 - (x - x。 ) y。
y = y。 十
X1 -�。 ( 8-30)
表 8-2
到期 收益率 昨天 上周 上月
续表
到期 收益率 昨天 上周 上月
8. 1 3 输 出 数据到外部文件
本节将讨论用来存储数据的几种方法 , 如 保存数据或结果 到 一个文本文件或二进制文
件等。
>> >endda 七 e = ( 2 0 1 3 , 1 1 , 9 )
>>>p = quotes_h i s to r i c al_yahoo_ochl ( t i c ke r , begdate , enddate ,
a s obj ect=True , adj usted=True )
> > > x 2 = re . s ub ( ' [ \ ( \ ) \ { \ } \ . < > a - zA- Z ) ' , ' ' , x )
> > >out fi l e . write ( x2 )
>>>out f i l e . c l o s e ( )
8.13.3 从二进制文件读取数据
假设用以上 代码生成 了 一 个名为 C:\temp\tmp.bin 的二进制 文件, 该文件仅包含 1 、 2
和 3 这 3 个数字。 下面的代码可以从 该文件读取这几 个数字。
高频数据。
8. 1 4 用 Python 分 析 高 频 数 据 并 计 算 买 卖 价 差 1 89
以上 代码用到两 个 输入
变量: 股 票交易代码 和 文件存储路径。 使用含有字 符 串 " ttt "
的路径名, 然后 用 string .replace()函数来把它 替换成所需 的股 票交易代码。 用 hea d ( ) 和
tail ( ) 函数显示所获得的数据文件的首 5 行和最后 5 行如下 。
>>>df . head ( )
0 1 2 3 4 5
0 1 2 3 4
748
。
»>df . t a i l ( )
898
1
52 5 . 4 5 0 525 . 500
2
524 . 990
3 4
52 5 . 1 4 0 113120
5
。。
750 900 525 . 460 525 . 680 525 . 37 0 525 . 660 1 0639
751 901 525 . 548 525 . 557 525 . 200 5 2 5 . 37 0
752 902 525 . 420 525 . 58 0 5 2 5 . 2 65 525 . 545
>>>
谷 歌 财 经 网 站提 供 高 频 数 据 的 相 关 网 页 位 于 h t tp : / /www . g o o gl e . com/
f i n a n c e / getp r i ce s ? q=AAPL & i = 3 0 0 & p= l 0 d & f=d , o , h , l , c , v 。 该文件的首 1 0 行
内 容 如下 。
522 . 5 8 , 5 1 9 . 75 , 521 . 37
2 , 5 1 9 . 4 4 , 5 22 . 8 9 , 5 1 8 . 8 1 , 522 . 4 9
3 , 520 . 36, 520 . 98 , 519 . 1 901, 519 . 4 9
以下代码用来添加 一个 日 期
变量 。
date = [ J
for i i n np . a range ( O , l en ( x ) ) :
i f X [ i ) [ Q ) [ Q ) == 1 a 1 ;
t= datet ime . datetime . f romtime s t amp ( int ( x [ i ) [ O J . r ep lace ( ' a ' , ' ' ) ) )
p r i n 七 t i c ke r , t , x [ i ) [ 1 : )
date . append ( 七 )
else :
da七e . append ( t +datetime . t imede l t a ( minu七es = i n t ( x [ i ) [ O J ) ) )
图 8-20
用 head ( ) 和 t a i l ( 函
) 数来查 看数据的首几行和最后几行。
>>>import pandas as pd
>>>c t=pd . read_p i c k l e ( ' c : / t emp /TORQct . pk l ' )
用 head ( ) 和 tai l ( 函
) 数来查看首几行和最后几行。
>>>ct . head ( )
8
7 0 0 0
1
5
N M M M N
AC 19901101 10 : 39 : 06 13 100
AC 19901101 10 : 39 : 36 13 100
AC 19901101 10 : 3 9 : 38 13 100
AC 19901101 10 : 39 : 41 13 100
9
1
1
5
AC 19901101 10 : 41 : 38 13 300
>>>ct . t ail ( )
da 七 e t ime price SlZ gl27 tseq c ond ex
s ymbol
0 0 0 0 O
N N N N T
5 1 1 1 2
AC 1 9901101 9 : 30 : 44 12 . 875 1 3 . 12 5 10
AC 1 9901101 9 : 30 : 47 12 . 750 13 . 250 12
AC 1 9901101 9 : 30 : 51 12 . 7 50 13 . 250 12
AC 1 9901101 9 : 30 : 52 12 . 7 5 0 13 . 250 12
AC 1 9901101 10 : 40 : 13 12 . 750 13 . 125 12
>»cq . ta i l ( )
date t ime bid ofr b i ds i z ofrs i z mode qs eq
s ymbol \
0 0 9 0 0
1 1 1 1 1
1 1 1 1 1
1 1
2 2 3 2 3
Z NT 19910131 13 : 31 : 06 12 . 3 7 5 12 . 875
Z NT 19910131 13 : 31 : 06 12 . 37 5 12 . 875
6
Z NT 19910131 1 6 : 08 : 49 12 . 3 7 5 12 . 875
Z NT 1 9910131 1 6 : 16 : 54 1 2 . 37 5 12 . 875
8. 1 4 用 Python 分 析 高 频 数 据 并 计 算 买 卖 价 差 1 93
\
>>>x . head ( )
da 七e time bid ofr bids i z ofrsiz mode qseq
symbo l
MO 1 9 90 1 1 0 1 9 : 3 0 : 3 3 47 . 000 47 . 125 10
1
0
0 1 1 1 0
0 0 0 0 1
4 1 1 1 3
5
MO 19901 1 0 1 9 : 30 : 35 46. 750 4 7 . 37 5 12
MO 19901101 9 : 30 : 38 4 6 . 87 5 47 . 750 12
MO 1 990110 1 9 : 30 : 40 4 6 . 875 47 . 250 12
MO 19901101 9 : 30 : 47 47 . 000 47 . 125 12
5
1
O
检 查 首 几 行数 据 是 一 个 好 习惯 。 以 上 的 第 行 数 据 显 示 买 卖 价 差 应为 0. 1 25
( 47 . 1 25-47.000 ) 。
用以下代码来计算平 均价差和平均相对价差。
impor七 pandas as pd
cq= l oad ( ' c : / temp/TORQcq . p i c k l e ' )
x=cq [ c q . index== ' MO ' )
spread=mean ( x . o f r-x . b id)
rel_spread=mean ( 2 * ( x . o f r - x . bid) / ( x . o f r + x . bid) )
print round ( s p r ead , 5 )
print round ( re l_spread , 5 )
0 . 39671
0 . 00788
n-
• f 、 还气,t
斗
广, d
hh
lid 心
哼 之
.,
,妇 -C:\ttti,n廿如2.py
�
飞 '!ll_froo归_n_s缸尥Pv n
l .
2 •••
、,.,, ' .,
fl
图 8-2 l
...
二
.Run
一
� � �r;� 二已二 子 ct
图 8-22 图 8-23
C:\Yan\Te忒切,gV,ython_forJ斤口心1)rog'MIS
月 ei,plor"白
\
matplotlib File Folder 11/9/2013 2:24:16 PM
_init_. py 51 byt己 py File 9/19/2006 1:35:22 PM
� 30_plot.py 293 byt己 py File 7/17几013 5:58:42 PM
4打5_06_22_int.,rpolat"·PY 78 byt己 py File 11/9/2013 1:38:37 PM
c!J 4375_06_22_scipy_interpolate.py 349 byt己 py File 11/9几013 1:32:07 PM
� 4375_06_22_scipy_interpolate_not_working,py 351 byt已 py File 11/9/2013 1:38:01 PM
� 4375_07_04_npv_ profief2.py 287 byt己 py File 11/9/2013 9:50:45 AM
� 4375_07_05_Ya hoo_price.py 295 bytes py 印e 11/9/2013 11:59:09 AM
� 4375_07.:_06 .py 100 byt•s py File 11/9/2013 3:22:54 PM
邑 4375_07_06_n一vs_port_vol.py 1 KB py File 11/11/2013 10:48:48 AM
� 4375_07_07,py 138 bytes py File 11/9/2013 3:24:36 PM
.!) 4375_07_07_s叹efig, py 76 byt已 py File 11/9/2013 3:09:47 PM
图 8-24
8. 1 6 -个有用 的数据集
>>>impo rt pandas as pd
>>>df=pd . re ad_p i c k l e ( " c : / t emp / yanMonthl y . p kl " )
>>> t=uni qu e ( np . array ( d f . inde x ) )
相应的输出如图8-2 5 所示。
1 96 第 8 章 时 间 序 列 的 统计 分 析
>» t
array ( [ ' 000001 . SS ' , ' A ' , ' AA ' , ' AAP L ' , ' BC ' , ' BC F ' , ' C ' , ' CIK ' , ' COH ' ,
' CPI ' , ' DE LL " , ' GE ' , ' GOLDPRICE " , ' GV ' , ' GVT ' , ' HI ' , ' HML ' , ' HPS ' ,
, HY ' , ' IBM ' , ' ID ' , ' IL ' , ' IN ' , ' INF ' , ' ING ' , ' ItlY ' , ' IO ' , ' I S L ' ,
' IT ' , ' J ' , ' JKD ' , ' JKE ' , ' JPC ' , ' KB ' , ' KCC ' , ' KF T ' , ' KIE ' , ' KO ' ,
, KOF ' , ' LBY ' , ' LCC ' , ' LCM ' , ' LF ' , ' LG ' , ' lM ' , 飞 , ' MA ' , · �认A ' '
, MD ' , ' MF L ' , ' t-t-1 ' , ' MPV ' , '田 ' ' 'Mkt Rf ' , ' N EV ' , · �no · , ' NP ' , ' NU ' ,
' NVF ' , ' OI ' , ' OPK ' , ' PAF ' , ' PFO ' , ' PSJ ' , ' PZZA ' , ' Q ' , ' RH ' , ' RLV ' ,
' Rf ' , ' R uss3000 E D ' , ' R uss3000 E X ' , ' S , ' S BR ' , ' SC D ' , ' SE F ' , ' SI ' ,
' S KK ' , ' SMB ' , ' S干C ' , ' T ' , ' TA ' , ' TBAC ' , ' TEN ' , ' TK ' , ' TLT ' , ' TOK ' ,
' TR ' , ' TZ E ' , ' UHS ' , ' U I S ' , ' U RZ ' , ' US DEBT ' , ' US GDP 2009dollar '
, us GDP 2013dollar ' , ' V ' , 'VC ' , ' VG ' , ' VGI ' , ' VO ' , 'W ' , ' \-JG ' ,
' WI F I ' , ' \-.MT ' , ' WR ' , ' XL I ' , ' XON ' , ' Y ' , ' YANG ' , ' Z ' , ' "AORD ' ,
, "B S ESN ' , ' " CC S I ' , ' " CSE ' , ' " FCHI ' , ' " FTSE ' , ' " G S PC ' , ' 心 S PTSE ' ,
' 哗I ' , ' A IBEX ' , ' AI S EQ ' , ' "JKS E ' , ' AK LS E ' , ' AK S ll ' , ' "MXX ' ,
, A NZ50 ' , ' "OMX ' , ' ASTI ' , ' ASTOXX50 E ' , ' "飞 II ' ] , dtype=object )
» > le n ( t )
129
牢
图 8-25
8. 1 7 小 结
本章详细 讨论了与统计分析相关的许多概念和内 容, 包括如何 由雅虎财经下 载历史数
练习题 1 97
练习题
l . P and as 模块的主要作用是什 么 ?
2 . s t atsrnode l s 模块的主要作用是什么 ?
3. 如何安装 Pandas 和 s ta t srnode l s 模块?
10. 编写 Pyt
h on 程序来逐年估算 一 只 股 票 的 贝 塔 值 。 用它来计算 IBM 在 1962 年至
2013年 间 每年的 贝 塔 值 。
11 . 假设从 h ttp/
: /www.fed re arl se
e rv .eg ov/r el es
as
e/h15/d a at. h tm联邦储备委员 会的数据库
中下 载最优惠利率的历史数据 。 以下 给出所下 载文件的首 几行 。 编写 Pyth on 程序读取数据
并使用第 1 列 作为索 引 。
Un i t : P e r cent
Mu l t ip l i e r : 1
Currency : NA
Unique Identi f i e r : H 1 5 / H 1 5 /RIFSP PFAAD3 0 N . B
Time P e r i od R I F S P P FAAD 3 0 N . B
1/2/1997 5 . 35
1/3/1 997 5 . 34
12 . 哪 个 政 党 能 更 好 地管 理股 市 ? 根 据 h 七 tp : / / www . e n c h a n t e dl e a r n i n g .
表 8-3
( 2 ) 估 计 市 场 收 益 率 ( 超额 市 场 收 益 率 加 上无风险 利 率 ) 。
( 4 ) 检验这 两 组 市 场 收 益 率 的 均 值是 否 相 等 , 即
RDemocratic = RRepublican
注 : 如 何 下 载 和 估 计 市 场 收 益率 ?
( 1 ) 用 日 回 报 率 计 算 自 1 989 年 1 月 1 日 � 20 1 2 年 1 2 月 3 1 日 的 累 积 收 益 ?
( 2 ) 用 月 回 报 率 计 算 自 1 989 年 1 月 1 日 � 20 1 2 年 1 2 月 3 1 日 的 累 积 收 益 ?
( 3 ) 它们 的 值 相 等吗 ? 如 果 不 相 等 , 为 什 么 ?
200 第 8章 时 间 序 列 的 统 计分析
表 8-4
Aaa/AAA 14 16 27 40 56 68 90
A a l /AA+ 22 30 31 48 64 77 99
Aa2/AA 24 37 39 54 67 80 1 03
Aa3/AA - 25 39 40 58 71 8[ 1 09
A l /A+ 43 48 52 65 79 93 117
A2/A 46 51 54 67 81 95 121
A3/A- 50 54 57 72 84 98 1 24
Baa2/BBB 65 80 88 97 1 28 151 1 77
Baa3/BBB- 72 85 90 1 02 1 34 1 59 1 83
• 欧式与美式期权
• 期权平价关系及其图形表示
• 一步和两 步 二 叉 树 模 型的图形表示
• 使用二叉树法为欧式和美式期权定价
• 套期保值策略
202 第 9 章 Black-Scholes-Merton 期 权定 价 模 型
。 假设 3
这里, Sr是到期 日 ( T)的股票价格, X 是执行价(在这个例子里 X 等 于 30)
个月后股价是 25 美元, 我们将不会使用看涨期权以 30 美元购买股票, 因为 我们可以在公
开市场上 以 25 美元购买 同样的股 票。 另 一方面, 如果 3个月 后股价是 4 0 美元, 我们将使
用看涨期权以 30 美元 买股票, 转手在市场上以 4 0 美元售出, 从 而获得 I O 美元的收益。 以
下 代码给出看涨期权收益的函数:
>>>def payoff_ca l l ( s T , x) :
return ( s T-x+abs ( sT-x ) ) / 2
简单 易用, 代码如下 。
这个收益函数
>>>import numpy as np
>>>x = 2 0
>>>s T=np . arange ( l 0 , 5 0 , 1 0 )
>>>s T
array ( [ l O , 2 0 , 3 0 , 4 0 ] )
>>>payof f_ca l l ( sT , x)
array ( [ 0 . , 0 . , 1 0 . , 2 0 . ] )
>>>
\
用以下代码来绘制看涨期权的收益函数 曲线。
import nurnpy as np
impor t rnatplotlib . pyplot as plt
9. 1 看 涨 期 权和看跌期 权 的 收 益 和 利 润/损 失 函 数 203
s = np . arange ( l 0 , 8 0 , 5 )
x= 3 0
payoff= ( abs ( s - x ) + s -x ) /2
plt . yl im ( - 1 0 , 5 0 )
p l t . plot ( s , payoff)
plt . show ( )
\
绘制的收益函数曲 线 如图 9-1 所示 。
so
40
30
20
10
。
- 10
10 20 30 40 SO 的 70 80
图 9- 1
看涨期权买方的利润/损 失 由以下公式计算。
import scipy as s p
import ma tplo 七 lib . pyplo 七 as p l t
s = sp .arange ( 3 0 , 7 0 , 5 )
x=4 5 ; ca l l =2 . 5
profit= ( abs ( s - x ) +s-x) /2 -call
y2=sp . zeros ( l en ( s ) )
204 第9章 Black-Scholes-Merton 期 权 定 价 模 型
y l im ( - 3 0 , 5 0 )
plot ( s , p r o f i t )
p l o t ( s , y2 , ' - . ' )
p l o t ( s , -pro f i t )
t i t l e ( " P r o f i t /Loss func t i o n " )
x l abel ( ' S tock p r i c e ' )
ylabel ( ' P r o f i t ( lo s s ) ' )
p l t . anno 七 ate ( ' Ca l l option buye r ' , x y= ( S S , 1 5 ) , x ytext= ( 3 5 , 2 0 ) , ar rowprops=
dict ( f a c e c o l o r = ' bl ue ' , s h r i n k = 0 . 0 1 ) , )
p l t . annotate ( ' Ca l l opt i o n s e l l e r ' , x y= ( S S , - 1 0 ) , xytext= ( 4 0 , - 2 0 ) ,
ar rowprops = dict ( f a c e c o l o r = ' red ' , s h r i n k= 0 . 0 1 ) , )
sh ow ( )
- 10 • ·
-2 0 ,.
-30
30 35 40 心 丈 印 65
图 9-2
import s c ipy as sp
import ma 七p l o t l ib . pyplot a s p l t
9.2 欧式期权与 美式期权 205
s = sp . arange ( 3 0 , 7 0 , 5 )
x=4 5 ; p=2 ; c=2 . 5
y=c- ( abs ( x- s ) +x- s ) / 2
y2=sp . zeros ( len ( s ) )
x3= [ x , x ]
\
y3= [ - 3 0 , 1 0 ]
p l t . yl im ( - 3 0 , 5 0 )
p l t . plot ( s , y )
p l t • plot ( 5 f y2 f I - • I )
p l t . pl ot ( s , - y )
p l t . p l o t ( x 3 , y3 )
plt . t i t l e ( " P rofit /Loss function for a put opt i on " )
pl t . x l abel ( ' Stock price ' )
p l 七 . y label ( ' Profit ( l o s s ) ' )
plt . annotate ( ' Pu t option buyer ' , xy= ( 3 5 , 1 2 ) , xytex七= ( 3 5 , 4 5 ) , arrowprops=
die七 ( facecolor= ' r ed ' , s hrink=0 . 0 1 ) , )
plt . annotate ( ' Pu t option s e l l e r ' , xy= ( 3 5 , - 1 0 ) , xy七e x七= ( 3 5 , - 2 5 ) , ar rowprops=
dict ( facecol or= ' blue ' , shrink= 0 . 0 1 ) , )
p l 七 . annotate ( ' Exercise price ' , x y= ( 4 5 , - 3 0 ) , xytext= ( 5 0 , - 2 0 ) , arrowp rops=
dict ( facecolor = ' black ' , shrink=0 . 0 1 ) , )
p
pl t . show ( )
l
50
.
,
b
p
t
t
y
e r
u
n
u
30
! 它20
10。
足
足
- 10
-20
-3
Q30 L 35 40 45- 50 55 60 65
Stock price
阳 9-3
9.2 欧式期权与美式期 权
一 个 重 要 的区 别 是 欧 式 期 权 的定 价公式 可 以 有 一 个 解 析表达 式 , 比 如
B al c k - Sch oel s-Mert on 期权模型, 而美式期权的价格不可以用一 个解析表达式来计算。 不过,
我们有其他方法来给美式期权定价。 本章将介绍如何使用二叉树方法(也称为 CRR 方法)
为美式期权定价。
9.3 现金流 、 不 同 类型 的 期 权 、 权利 和 责任
表 9-1
f (x) = e
l 一二
压2 ( 9-8 )
雪
这里, µ是均值, 6 是标准方 差 。 \ 当µ为 o, (1 为 1 时, 正态分布密度函数称为标准正态
分布 , 其 密度
函数如下 。
_:::_
f( x) = e 2
1
( 9-9 )
尽
以下代码生成标准 正 态分布的 曲 线 。 SciPy 模块的 stats.norm.pdf()函数用于 标准正态分
布, 其 默认 设置为零均 值和单位标准方差, 即 标准正态密度函数。
0.40
0.35
0.30
0.25
0.20
0.15
0.10
0.05
0. 00-3
1::: -2 -1 。 1
团 9-4
一
择 个数 0 . 3 2 5 , 赋予变量 Z, 称 其 为 z 值 。 标 准 正 态 密 度 函 数 曲 线 下 在 z 值左侧 的 阴 影
面 积 就 是 累 积 标 准 正 态 分 布 函 数在 z 点 的 取值 。
import numpy as np
from scipy import exp , s qr t , s ta t s
from matp l o t l ib import pyp l o t as pl 七
z=O . 3 2 5 It user can change 七 his number
de f f ( 七 ) :
re 七 urn st ats . norm . pdf ( t )
plt . y l im ( 0 , 0 . 4 5 )
x = np . arange ( - 3 , 3 , 0 . 1 )
yl=f ( x )
p l t . plot ( x , y l )
x2= np . arange ( - 4 , z , 1 / 4 0 . )
sum= O
de l t a = 0 . 0 5
s = np . ar ange ( - 1 0 , z , de l t a )
f o r i in s :
sum+ = f ( i ) *delta
plt . annotate ( ' area i s ' + s t r ( r ound ( s um, 4 ) ) , x y= ( - 1 , 0 . 2 5 ) , xytext = ( - 3 . 8 , 0 . 4 ) ,
ar rowprops = dict ( facecolor= ' red ' , shrink = 0 . 0 1 ) )
plt . annotate ( ' z = ' + s tr ( z ) , x y= { z , 0 . 0 1 ) )
p l t . f i l l_be tween ( x 2 , f ( x2 ) )
p l t . show ( )
\
上 述 代码计 算 的 阴 影面 积 如 图 9-5 所 示 。
。
0.45
a
a
re
6
2
0.40
.
IS
,t', .一
0 0
3530
0.25
0.20
0 15
0. 10
0.05
。
0.00
-4 -3 -2
2
-1
图 9-5
下 面 的代码使用 s t a t s . n o rm . c d f ( ) 函 数计 算 累 积标准正 态 分 布 的 结 果 。
9.5 不 分红 股 票 的 期 权 定 价 模 型 209
import numpy as np
f rom scipy imp o r 七 exp , sqrt , s ta t s , a range , ones
f rom matp l o t l i b import pyplot a s p l t
z=0 . 3 2 5
def f ( x ) :
return stats . no rm . cdf ( x )
x = arange ( - 3 , 3 , 0 . 1 )
y l=f ( x )
y2=ones ( l en ( x ) ) * 0 . 5
x3= [ 0 , 0 )
y3 = [ 0 , 1 )
p l t . p l o t ( x , yl )
p l t . plot ( x , y2 , ' b - ' )
plt . p l o t ( x3 , y3 )
p l t . annotate ( ' f ( z ) = f ( ' +s tr ( z ) + ' ) i s ' + str ( np . round ( f ( z ) , 4 ) ) , x y= ( z , f ( z ) ) ,
xytext = ( z - 3 , f ( z ) ) , ar rowp rops=di ct ( facecolor= ' red ' , shrink= 0 . 0 1 ) )
p l 七 . annotate ( ' z i s ' +s tr ( z ) , xy= ( z , O ) , xytext= ( l . 5 , 0 . 3 ) , ar rowprops=di ct
( facecolor= ' blue ' , shr ink=O . 0 1 ) )
p l t . show ( )
以上代码绘制 的 图 形如 图 9-6 所示 , 由 于 正 态 分 布 是 对称 的 , 所 以 累 积 标 准 正 态 分 布
函 数 在零点 的值 为 0.5 。
1.0
0 8 ,-
0.4
z is 0.325
0 2 •·
。
0. �
2
图 9-6
d, = m ( � ) + ( r+ ½ 叶
6行
C 9- 1 0 )
d尸
气门勹产
; = d1 - 崎
忒
。
c = S N(dl ) - xe-rT N(d2 )
p = Xe-rr N(-心 - S0 N(-di )
>>>c=bs_cal l ( 4 0 . , 4 2 . , 0 . 5 , 0 . 0 1 5 , 0 . 2 )
>>>round ( c , 2 )
1. 56
de f bs_cal l ( S , X , T , r f , si gma ) :
from s c ip y i mport log , exp , s qr t , sta七S
dl= ( l og ( S /X ) + ( r f + s i gma * s igma /2 . ) * T ) / ( s i gma * s qrt ( T ) )
d2 = d l - s i gma * s qr t ( T )
return S * s 七 a t s . n o rm . cdf ( d l ) - X * exp ( - r f * T ) * s tats . n orm . cdf ( d2 )
以下程序使用二项式模型对看涨期权定价。
de f b i nomial_g r i d ( n ) :
import networ k x as nx
import matp l o t l ib . pyplot as p l t
G=nx . Graph ( )
for i i n range ( O , n+l ) :
for j i n range ( l , i +2 ) :
i f i<n :
G . add_edge ( ( i , j ) , ( i + 1 , j ) )
G . add_edge ( ( i , j ) , ( i + l , j + l ) )
posG= { } # di c tionary with node s p o s i t i on
for node i n G . nodes ( ) :
posG [ node ] = ( node [ O ] , n + 2 +node [ 0 ] -2 * node [ l ] )
n x . draw ( G , p o s =posG)
de f de lta_ca l l ( S , X , T , r f , s i gma ) :
from sc ipy i mport l o g , exp , sqrt , stats
dl= ( l og ( S / X ) + ( r f+s i gma * s igma / 2 . ) * T ) / ( s i gma * s qrt ( T ) )
return ( s tats . norm . cdf ( d l ) )
de f de l t a_put ( S , X , T , r f , s i gma ) :
f rom sc ipy import log , exp , sqrt , stats
dl= ( l og ( S /X ) + ( rf+s i gma * s i gma /2 . ) * T ) / ( s igma * s qrt ( T ) )
re七urn ( s ta七s . norm . cdf ( d l ) 一 1 )
>>> impor t o s
>>>print ( o s . ge tcwd ( ) )
。
S = S - e-rr, d ( 9- 1 1 )
n
d, = I ( 轩 (r + 巨 厂 ( 9- 1 2 )
6 行
d, �
In 门 (r _
X
_!_ 矿 T
2
) � d, - 顽 ( 9- 1 3 )
硕
c = S x N( d1 ) - X x e- rT N( d2 ) ( 9- 1 4 )
p = X x e- rT N( d2 ) - S X N( -d1 ) C 9- 1 5 )
一
在前 节 讨 论 的 例 子 中 , 如 果 已 知 该股票在 一 个 月 后 支 付 1 .5 美 元 的 红 利 , 那 么 看涨
期 权 的 价 格 是 多 少 ? 可 以 用 以 下 的方法来计 算 。
>>>import p 4 f
>>> s 0 = 4 0
>>>d= l . 5
>>>r = 0 . 0 1 5
>>>T= 6 / 1 2
>>>s=s0- exp ( - r * T * d )
>>>x = 4 2
>>>sigma = 0 . 2
>>>round ( p 4 f . bs_ca l l ( s , x , T , r , s i gma ) , 2 )
1 . 18
9.8 多 种 交易 策略 213
代 码 的 第 1 行 导 入 p4f 模 块 , 其 中 包 含 计 算 期 权 价 格 的 函 数 。 结 果 显 示 , 看 涨 期 权
的 价 格 为 1 . 1 8 美 元 , 低 千 之 前 的 价 格 C 1 . 56 美 元 ) 。 这 主 要 是 因 为 标 的 股 票 的 价 格 将 在
一 个 月 后 大 约 降 低 1 .5 美 元 , 超 过 42 美 元 的 可 能 性 降 低 , 因 此 行 使 看 涨 期 权 的 机 率 将
会 更 小 。 以 上 的 办 法 同 样适 用 于 在 到 期 日 T 之 前 多 次 分 红 的 股 票 , 即 以 S = S z: e- rT, d; 。-
代 替 S胪
9. 8 多 种 交 易 策 略
表 9-2 总 结 几 种 常 见 的 涉 及 各 种 类 型 期 权 的 交 易 策 略 。
表 9-2
名称 描述 期权费流向 预期未来价格变化
买入执行价为 X1 的 看跌 期权 , 卖 出 执行价
看跌期权的 牛 市 多 空套利 收取期权费 价格上涨
为 X2 的 看 跌 期权 ( x,< x2 )
买 入 执 行 价 相 同 的 两 个 看 跌期 权 和 一 个 价格下跌的概率大
熊市跨式期权组合 ( Strip ) 付 出 期权 费
看涨期权 千上涨的概率
买入执行价为 Xi 和 X3 的看涨期权, 卖 出 两
蝶式看涨期权组合 付 出 期权费 价格在 X2 附近
个执行价为 X2 的看涨期权 < x2=( x 广 X3)/2 )
买入执行价为 x , 和 X3 的看跌期权, 卖 出 两
蝶式看跌 期权组合 付 出 期权 费 价格在 Xz 附近
个执行价为 X2 的看跌期权 (x2=( x1+ x3 )/2 )
214 笫9章 B lack-Scho Jes-Merton 期 权定 价 模 型
续表
名称 描述 期权费流向 预期 未来价格变化
卖 出 到 期 日 为 T1 的看涨期权, 买 入 到 期 日
日 历套利组合 付 出 期权 费
为 T2 的 看涨期权, T1 <T2
9.8. 1 股票多头和看涨期权空头的组合
假 设 我们 购 买 公 司 A 的 股 票 1 00 股 , 每 股 价 格 为 1 0 美 元 , 总 成 本 是 l 000 美 元 。 如 果
一 一
同 时卖 出 个看涨期权合 同 , 每 个 合 同 对应 标 的 股 票 1 00 股 , 每 个 看涨期权 的价格为 20
一
美 元 。 因 此 , 我们 的 总 支 出 将 减 少 20 美元 。 进 步 假 设 行 使 价 为 1 2 美 元 , 可 以 用 以下代
码绘制损 益 函 数 的 图 形 。
import numpy a s np
import matp l o t l ib . pyplot as p l t
s T = np . arange ( 0 , 4 0 , 5 )
k= 1 5 ; s 0= 1 0 ; c=2
yO=np . zeros ( l en ( s T ) )
yl=sT-s0 # s to c k o n l y
y2= ( abs ( s T - k ) + s T - k ) / 2 - c # l ong a c a l l
y3=yl -y2 # cove r ed- c a l l
p l t . ylim ( - 1 0 , 3 0 )
p l 七 . plo七 ( s T , y l )
p l t . plot ( s T , y2 )
plt . plot ( s T , y3 , ' red ' )
p l t . plot ( s T , y O , ' b - . ' )
plt . plot ( [ k, k] , ( - 1 0 , 1 0 ] , ' black ' )
p l t . 七itle ( ' Cove red cal l ( l ong one share and short one cal l ) ' )
pl t . x l ab e l ( ' Stock p r i c e ' )
pl t . y l abel ( ' P r o f i t ( l o s s ) ' )
p l 七 . annotate ( ' Stock o n l y ( l ong one share ) ' , x y= ( 2 4 , 1 5 ) , xytext= ( l 5 , 2 0 ) ,
ar rowprops=di c t ( facecolor= ' b l ue ' , shrink=0 . 0 1 ) , )
p l t . annotate ( ' Long one share , short a c a l l ' , x y= ( l 0 , 4 ) , x ytex七= ( 9 , 2 5 ) ,
arrowprops=di c 七 ( facecol or= ' r ed ' , s hrink=0 . 0 1 ) , )
plt . annotate ( ' Exercise price= ' + s t r ( k ) , xy= ( k+ 0 . 2 , - 1 0 + 0 . 5 ) )
p l t . show ( )
\
30
Covered call (long one share and short one call)
15
\
j_,L
10
一》
。
一5
亟k price
图 9-7
import numpy a s np
impor t matpl o t l ib . pyplot a s p l t
sT = np . arange ( 3 0 , 8 0 , 5 )
x=S O ; c=2 ; p= l
straddle= ( ab s ( s T- x ) +sT- x ) / 2 - c + ( ab s ( x - s T ) + x - s T ) / 2 -p
yO=np . zeros ( l en ( s T ) )
plt . ylim ( - 6 , 2 0 )
pl t . x l im ( 4 0 , 7 0 )
p l t . plot ( sT , yO )
pl t . plot ( s T , s t r addl e , ' r ' )
p l t . p l o 七 ( [ x , x ] , [ - 6 , 4 ] , ' g- . ' )
p l t . 七 i t l e ( " Pr o f i t - l o s s for a S t raddl e " )
p l t . x l abel ( ' S t o c k p r i c e ' )
plt . ylabel ( ' P r o f i t ( l o s s ) ' )
p l t . annotate ( ' P o i n t l = ' + s 七 r ( x- c - p ) , x y= ( x-p- c , O ) , xytext = ( x -p-c , 1 0 ) ,
ar rowprops =dict ( facecolor = ' r ed ' , s h r i n k=0 . 0 1 ) , )
p l t . annotate ( ' Point 2 = ' +s t r ( x+ c +p) , xy= ( x+p+ c , 0 ) , xytext = ( x +p+ c , 1 3 ) ,
arrowpr ops=di c t ( facecolor = ' bl u e ' , s h r i n k=0 . 0 1 ) , )
pl t . annotate ( ' e x e r c i s e p r i c e ' , xy= ( x + l , - 5 ) )
216 第9章 Black-Scholes-Merton 期 权 定 价 模 型
p l t . anno 七 ate ( ' Buy a c a l l and buy a put with the s ame exercise
price ' , x y= ( 4 5 , 1 6 ) )
pl t . show ( )
以上 代码绘制的图形如图 9-8所示。
20
Profit-lo巧 for a Straddle
Buy a call and buy a put with the same exericse pri
15
Point 2=53
Point 1=47
0
1
(
SSO
一
一拦0
5
K
。
• exercise price
5 40
L
心 50 55 60 65 70
StodcJ!rt�
图 9-8
9.8.3 日 历套利 组合
impor 七 p 4 f
import numpy a s np
耳nport matp l o t l ib . pyp lot as p l t
sT = np . ar ange ( 2 0 , 7 0 , 5 )
s = 4 0 ; x=4 0 ; T l = 0 . 5 ; T2 = l ; s igma = 0 . 3 ; r=0 . 0 5
\
以上 代码绘制的图形如图 9- 9 所示。
20
Calendar spread with calls
、 . -·
Buy a call with TlOand sell a call with r2
15 where Tl <T2
=
足
�
0 t . . .. . ... .'. . . . �
-5 •.
-10 ,.
-15 •·
\ ' """""�'" ""' ' ""'' -
Calendar spread
-20 1
20 25 30 35 心 45 · 50 55 切
Stock 口七e at matl.lf'切 <sT>
图 9-9
21 8 第9章 Black-Scholes-Merton 期 权定 价 模 型
9.8.4 蝶式看涨期权组合
蝶式 ( butterfly ) 组合是指买入执行价格分别为 m 和 X3 的看涨期权并卖出执行价格为
X2 的两 个看涨 期权, 其 中 x2= ( x 什X3 ) /2 , 并且它们 的标的股票 和 到 期 日 都相同 。 其 损 益函
数可以 由以下 代码计算得到。
import numpy as np
import matpl o t l i b . pyp l o 七 as p l t
s T = np . ar ange ( 3 0 , 8 0 , 5 )
x l =5 0 ; cl=lO
x2=5 5 ; c2=7
x3 = 6 0 ; c3=5
y l = ( abs ( s T - x l ) + s T - x l ) / 2 - c l
y2= ( ab s ( s T-x2 ) + s T -x2 ) / 2 - c 2
y3= ( ab s ( sT-x3 ) + s T - x 3 ) / 2 - c 3
bu七ter_fl y=yl +y3 - 2 * y2
yO=np . z e r o s ( l en ( s T ) )
plt . ylim ( - 2 0 , 2 0 )
plt . x l im ( 4 0 , 7 0 )
plt . plot ( s T , yO )
plt . plot ( sT , y l )
p l t . pl o t ( s T , - y2 , ' - . ' )
p l t . p l o 七 ( s T , y3 )
p l t . plot ( s T , butter_fl y , ' r ' )
p l 七 . t i t l e ( " P r o f i t - l o s s f o r a Bu七ter f l y " )
plt . x l abe l ( ' S 七 o c k pric e ' )
pl七 . ylabe l ( ' Pro f i t ( l o s s ) ' )
pl t . anno七ate ( ' Butter f l y ' , xy= ( 5 3 , 3 ) , xytext= ( 4 2 , 4 ) , a r rowprops=dict
( f acecolor= ' r ed ' , s h r i n k=0 . 0 1 ) , )
p l t . annotate ( ' Buy 2 ca l l s with x l , x3 and s e l l 2 ca l l s w i th x2 ' , xy= ( 4 5 , 1 6 ) )
p l t . anno七a七e ( ' x2= ( x l + x 3 ) /2 ' , xy= ( 4 5 , 1 4 ) )
plt . annotate ( ' x l = 5 0 , x2=5 5 , x 3= 6 0 ' , xy= ( 4 5 , 1 2 ) )
p l t . annotate ( ' c l = l 0 , c2=7 , c3=5 ' , xy= ( 4 5 , 1 0 ) )
p l t . show ( )
-令
一
-5
- 10
-1 5
-2 0
40 45 50 55 60 65 70
Stock price
图 9- 1 0
9.9 期权价格和输入参数之 间 的 关 系
impo rt numpy as np
import p 4 f a s p f
import matp l o t l ib . pyp l o t a s p l t
s 0= 3 0 ; T 0 = 0 . 5 ; s i gma 0 = 0 . 2 ; r 0 = 0 . 0 5 ; x 0 = 3 0
s i gma=np . ar ange ( 0 . 0 5 , 0 . 8 , 0 . 05 )
T=np . arange ( 0 . 5 , 2 . 0 , 0 . 5 )
cal l_O=p f . bs_ca l l ( s O , xO , T O , r O , s i gma O )
c a l l_s i gma=pf . b s_cal l ( s O , x O , T O , rO , s i gma )
c a l l_T=p f . bs_c a l l ( s O , xO , T , r O , s igma O )
plt . p l o t ( s i gma , c a l l_s i gma , ' b ' )
p l t . plot ( T , c a l l_T )
p l t . show ( )
9. 1 0 与期权相 关 的 希腊字母
ac
�=— ( 9- 1 6 )
as
我们可以基于 del t a值设计 一 个套期保值策略。 假设标 的股票在有效期不分红, 它的欧
式看涨期权的 delt a 由如下公式计算。
�call
=
N (d, ) ( 9- 1 7 )
>>>from p 4 f import *
>>> round ( del ta_call ( 4 0 , 4 0 , l , O . l , 0 . 2 ) , 4 )
0 .7 2 5 7
ilput = N ( di ) - l C 9- 1 8 )
>>>from p 4 f import *
>>> round ( delta_put ( 4 0 , 4 0 , l , O . l , 0 . 2 ) , 4 )
-0 . 2 74 3
r = ,a.ii. C 9- 1 9 )
as
为了实施有效的 del t a 对冲, 必须不断更新持有的标的股票的头寸, 因为 del t a与标的
股票的价格相关。 因此, 如果 g amm a值比较小, 就不必频 繁地改变持 有的标的股票的头 寸。
欧式看涨期权 (或看跌期权 ) 的 g amm a值 由如下公 式计算。
(
I' = N ' d1 ) ( 9-20)
。
s 6行
9. l l 期 权平价关 系 及其 图 形表 示 221
这里, N '(x) = e 2
1 工
o
>>>x = 2 0 *exp ( - 0 . 0 5 * 3 / 1 2 )
>>>round ( x , 2 )
>>>
1 9 . 75
C + Xe-ri = p + S 。 ( 9-2 1 )
T
import pylab as p l
222 第9章 B lack-Scholes-Merton 期 权 定 价 模 型
import numpy as np
x=lO
s T = np . arange ( 0 , 3 0 , 5 )
payo f f_c a l l = ( abs ( sT - x ) + sT- x ) /2
payof f_put = ( abs ( x - s T ) + x - s T ) / 2
cash = np . z e ros ( l en ( s T ) ) +x
de f graph ( t ext , text2= ' ' ) :
pl . x t i c k s ( ( ) )
p l . y七 i c ks ( ( ) )
p l . x l im ( O , 3 0 )
p l . ylim ( 0 , 2 0 )
pl . p l o t ( [ x , x ] , [ 0 , 3 ) )
p l . text ( x , -2 , " X " ) ;
pl . t e x t ( 0 , x , " X " )
p l . t e x t ( x , x * l . 7 , text , ha = ' center ' , va= ' center ' , s i z e = l O , a lpha = . 5 )
p l . text ( - 5 , 1 0 , text 2 , s i ze=2 5 )
pl . f i gure ( f i g s i ze = ( 6 , 4 ) )
p l . subplot ( 2 , 3 , l ) ; gr aph ( ' Payo f f of cal l ' ) ; pl . p l o t ( s T , payoff_ca l l )
p l . subp l o t ( 2 , 3 , 2 ) ; gr aph ( ' c as h ' , ' + ' ) ; pl . p l o t ( s T , c a s h )
pl . s ubpl ot ( 2 , 3 , 3 ) ; graph ( ' P o r f o l i o A ' , ' = ' ) ; pl . p l o t ( s T , cas h+payo f f
ca l l )
pl . subplot ( 2 , 3 , 4 ) ; graph ( ' Payo f f o f put ' ) ; pl . plot ( s T , payo f f_pu t )
p l . s ubplot ( 2 , 3 , 5 ) ; gr aph ( ' S t o ck ' , ' + ' ) ; p l . pl o t ( s T , s T )
pl . subp l o t ( 2 , 3 , 6 ) ; graph ( ' P o r 七 f o l i o B ' , ' ' ) ; p l . plot ( s T , s T+payo ff_pu t )
=
pl . s how ( )
产生的图形如图 9-11 所示 。
cash
图 9- 1 1
9. 1 2 二 叉 树 法 及其 图 形 表 示 223
9. 1 2 二 叉树法及 其 图 形表 示
SU
s
Sd
图 9- 1 2
一
步 树 叉 显 然 是 最 简 单 的 二 叉 树法 。 假 设 今 天 的 价 格 是 1 0 美元 , 行 使 价 是 1 1 美 元 ,
看涨期权将在 6 个 月 后 到 期 。 此外 , 假 设 未 来 的 价格 只 有两 个 结 果 , 价格增加 ( u = 1 . 1 ) 或
减 小 ( d = 0.9 ) 。 换句 话 说 , 未 来 的 价格 是 1 1 美 元 或 9 美 元 。 基 千 这 样 的 信 息 , 有 图 9- 1 3
一
所示的 步二叉树。
一
图 9- 1 2 中 的 步 树叉 由 以 下 代 码 生 成 。
import networkx a s nx
import matplot l ib . pypl o t as p l t
224 第9章 Black-Scholes-Merton 期 权 定 价 模 型
图 9- 1 3
一
以 上 的 代码 定 义 了 个 b i n ornial_g r i d ( ) 函 数 , 本章将在后 面 多 次用 到 这 个 函 数 。
一
由 于事 先 知 道 未 来 只 有 两 个 结 果 , 所 以 可 以 选 择 个 股 票 和 看 涨 期 权 的 组合 使 得 该 组 合 的
一
未 来 结 果 是 我们所 需 的 。 假 设选择数量为 delta 的 标 的 股票 和 个 看 涨 期 权 在 未 来 具有相 同
-.
的 价值 , 也 就 是 , L1 X 1 1 .5- 1 =9L1, 即 L1= 1 /( 1 1 .5-9)=0.4 。 这 意 味 着 如 果 持 有 0.4 股和卖空
个 看涨 期 权 , 当 股价增加 时 , 这 个组 合 的 未 来价值等牛 0.4 X 1 1 .5- 1 =3.6 , 或者 当 股 价 减 小
一
时 , 其 未 来 价值 也 等 于 0.4 X 9=3 .6。 进 步 假 设 连续复利 的 无风 险 价 值 是 0. 1 2% , 那 么 投 资
组 合 的 价值将等于未来值 3.6 在 今 天 的 现 值 , 即 0.4 X 1 0-c=pv 0.6 ) 。 使用 Python 可 以 得
到 以下结果 。
9. 1 2 二 叉 树法及其 图 形表 示 225
1 . 绘制一 个 n 步树。
a-d
p= C 9-26 )
u-d
V; = p凡 + (1 - p) v� l 十
( 9-27 )
import p 4 f
f rom math import sqr t , e xp
impor t matplot l ib . pyplot as p l t
s = l 0 ; r=0 . 0 2 ; s i gma=0 . 2 ; T= 3 . / 1 2 ; x= l 0
n=2 ; de l t aT=T /n ; q= O
u = exp ( s i gma * s qr t (del 七 aT ) ) ; d= l /u
a = exp ( ( r - q ) *deltaT)
p = ( a -d ) / ( u-d )
su=round ( s * u , 2 ) ;
suu = round ( s * u * u , 2 )
sd= round ( s * d, 2 ) ;
sdd= round ( s *d*d, 2 )
sud= s
p l t . f i gtext ( 0 . 0 8 , 0 . 6 , ' S tock ' +s tr ( s ) )
p l t . f i gtext ( 0 . 3 3 , 0 . 7 6 , " S tock price = $ " + s t r ( su ) )
p l t . f igtext ( 0 . 3 3 , 0 . 2 7 , ' Stock p ri ce= ' + s t r ( sd) )
plt . figtext ( 0 . 7 5 , 0 . 9 1 , ' S tock p r i ce = $ ' + s tr ( s uu ) )
p l t . figtext ( 0 . 7 5 , 0 . 6 , ' S tock p r i c e = $ ' + s t r ( sud) )
p l t . figtext ( 0 . 7 5 , 0 . 2 8 , " S t ock p r i ce = " + s t r ( sdd) )
p 4 f . binomial_grid ( n )
p l t . s how ( )
\
9. 1 2 二 叉树法及其 图 形 表 示 227
Stock price=Sll.5
Stock price=Sl0.73
Stock 10
图 9- 1 4
impor七 p 4 f
f r om numpy imp o r t exp , sqrt , l o g
import matplo t l i b . pyp l o t as p l t
s = l O ; x = l O ; r=0 . 05 ; s i gma=0 . 2 ; T=3 . / 1 2 . ; n=2 ; q= O # q i s dividend y i e l d
de l t aT = T / n # s tep
u =exp ( s i gma* sqrt ( de l 七 aT ) )
d= l/ u
a = exp ( ( r-q) * de l ta T )
p = ( a-d) / ( u- d )
s_d ol l a r = ' S = $ '
c_do l l a r = ' c = $ '
p2 = round ( p , 2 )
p l t . figtext ( 0 . 1 5 , 0 . 9 1 , ' No t e : x = ' + s t r ( x ) + ' , r = ' +s t r ( r ) + ' , de l 七aT = ' + s 七 工
( de l taT ) + ' , p= ' + str ( p2 ) )
plt . f igtext ( 0 . 3 5 , 0 . 6 1 , ' p ' )
p l t . f ig七ex七 ( 0 . 6 5 , 0 . 7 6 , ' p ' )
plt . f igtext ( 0 . 6 5 , 0 . 4 3 , ' p ' )
p l t . f i gtext ( 0 . 3 5 , 0 . 3 6 , ' 1 -p ' )
pl t . f i gtext ( 0 . 6 5 , 0 . 5 3 , ' 1 -p ' )
p l t . figtex七 ( 0 . 65 , 0 . 2 1 , ' 1 -p ' )
# at level 2
su=round ( s * u , 2 ) ;
suu=round ( s * u * u , 2 )
sd= round ( s * d , 2 ) ;
sdd=round ( s * d*d, 2 )
sud=s
c suu=round (max ( suu-x , 0 ) , 2 )
c_s =round ( max ( s-x , O ) , 2 )
228 第9章 Black-Scholes-Merton 期 权 定 价模 型
图 9- 1 5
>>>p
0 . 5 2 6 62 5 3 3 9 0 0 6 8 3 6 2 \
>>>de ltaT
0 . 12 5
>>>v= ( p* l . 52 + ( 1 - p ) * O ) * exp ( - r *de l t a T )
>>> round ( v , 2 )
0 . 80
>>>
9. 12.1 为欧式期权定价的二叉树法
一
以 下 代码编写 个 函 数 bi nom i a l Ca l l ( ) 来 用 二叉树法 为 欧 式期权 定 价 。
以 下 输 入 一 组 参 数 值 来 调 用 该 函 数 , 同 时 计 算 Black-Scholes-Merton 模 型给 出 的 期 权 价
格作为 比 较 。
>>> binomia1Ca l l ( 4 0 , 4 2 , 0 . 5 , 0 . 1 , 0 . 2 , 1 0 0 0 )
2 . 2 7 8 1 94 4 0 4 57 3 1 3 4 2
>>>bs_cal l ( 4 0 , 4 2 , 0 . S , 0 . 1 , 0 . 2 )
2 . 2777803294555348
>>>
9. 12.2 为美式期权定价的二叉树法
230 第9章 Black-Scholes-Merton 期 权 定价模 型
9. 1 3 套期保值策 略
卖 出 欧 式 看 涨 期 权后 , 可 以 持 有 数 量 为 4 的 标 的 股 票 来 对 冲 看 涨 期 权 空 头 的 风 险 。 这
个 策 略 称 为 delta 对冲 。 由 于 delta ( L1 ) 是 标 的 股 票 的 价 格 C S ) 的 函 数 , 为 了 保 证 有 效
的 对 冲 , 我们 必 须 不 断 调 整 股 票 的 持仓 量 , 因 而 称 为 动 态套 期 保 值 。 投 资 组 合 的 delta 是
一
投 资 组 合 中 各 个 证券 的 delta 的 加 权平 均 。 需 要 注 意 的 是 , 如 果 卖 空 只 证 券 , 其权重将
为负。
9. 1 4 小结 231
.1port = L卫 ( 9-28)
i=I
。
In S
(叶 r r
(d- l 勹叶
1
C 9-29 )
6行
di =
m ( �} ( 片
- rf + ½ 叶
d, = 丑 行 ( 9-30)
6行
- (J'
c = S X N( dl ) - X X e-rT N( d2 )
。 C 9-31 )
9. 1 4 小结
练习题
1 . 欧式看涨期权与美式看涨期权之 间有什么 区 别 ?
2 . B lac k - Sc h oel s-M ert on 期权模型中无风险利率 YJ的单位是多少?
5 . 对欧式看涨期权进行定价时, 如何处理预先确定的现金股利 ?
6 . 为什 么美式 看涨期权比欧式看涨期权更值钱 ?
impo rt p 4 f
import matpl o t l ib . pyp l o t a s p l t
pl t . f i gtext ( 0 . 0 8 , 0 . 6 , " S tock p r i c e= $2 0 " )
pl t . f igtext ( 0 . 0 8 , 0 . 5 6 , " cal 1 = 7 . 4 3 " )
p l t . figtext ( 0 . 3 3 , 0 . 7 6 , " S t o c k price=$ 67 . 4 9 " )
234 第9章 B lack-Scholes-Merton 期 权 定 价 模 型
以下是其 相关图形。
Stock price=S91.ll
Option pnce=O
按照以下的示例来
简化之前的代码 。
imp o r t p 4 f
p l 七 . f i g t e x t ( " S t o c k p r i c e= $ 2 0 " )
p l t . f i gtext ( " ca l l = 7 . 4 3 " )
p l t . f i g t e x七 ( " S 七o c k p r i c e=$ 6 7 . 4 9 " )
plt . f igtext ( "Opt i o n p r i c e = 0 . 93 " )
plt . f i gtext ( " Stock p r i c e = $ 37 . 4 0 " )
pl 七 . fi g t e x t ( "Op 七 ion p r i c e = l 4 . 9 6 " )
p l t . f i gtext ( " S tock p r i c e = $ 9 1 . l l " )
p l t . f i gtext ( " Opt i on p r i c e = O " )
plt . f i g t e x t ( " Stock p r i c e=$ 5 0 " )
p l t . figtext ( " Opti on p r i c e = 2 " ) ,
p l t . figtext ( " S tock p r i c e = $ 2 7 . 4 4 " )
p l t . f i gtext ( " Op 七 i on p r i c e = 2 4 . 5 6 " )
n = 2 ; p 4 f . bi nomial_gr id ( n )
• 什么是隐含波动率
• 隐含波动率计算的逻辑
• 嵌套 (多重) 循环
• 多个 I RR 的估计
• 二分搜索方法的原理
• 计算美式看涨期权的隐含波动率
• 以图形表示看跌期权和看涨期权的比率
236 第 1 0 章 Python 的 循 环 语 句 和 隐含 波 动 率 的 计 算
1 0. 1 隐含波动率的定义
输入一 组 5 个值 后, 可以得到看涨期权的价格如下。
>>>bs call ( 4 0 , 4 0 , 0 . 5 , 0 . 0 5 , 0 . 2 5 )
3 . 30400172 84767735
fo r 循环是许多计算机语言中最常见的循环之 一 。 图 1 0- 1 中的
流程图演示 了循环 语句如何工作。 通常从 一 个初始值开始测试循环
变量是否满足某 个条件, 如果条件不成立, 则循环停止 ; 当 条件成
立时, 执行一组命令, 改
变循环变量的值并再次测试该条件。
下面给出 一 个
简单的例子。
>>>n = l O
> > > fo r i i n range ( l , n+ l ) :
print ( i )
" " " Ob j ect ive : e s t imate c a l l for stock w i 七h one known dividend
S : current s tock p r i c e
T : maturi t y date i n y e a r s r : r i s k - f re e rate
s i gma : vo l a t i l i t y
一
可 以 把 b s c a l l ( ) 函 数 放 在 个 主 程 序 文 件 ( 如 p 4 f . py ) 中 。 这 样 , 更 便 于 调 用 该
函 数 , 也使代码 更 简 单 易 懂 。 例 如 :
import p 4 f
S=4 0 ; K=4 0 ; T=0 . 5 ; r= 0 . 0 5 ; c=3 . 3 0
for i in range ( 2 0 0 ) :
s i gma=0 . 0 0 5 * ( i+ l )
d i f f=c-p4 f . bs_cal l ( S , K , T , r , s igma )
i f abs ( d i f f ) <=0 . 0 1 :
p r i n t ( i , s i gma , di f f )
一 一
以 上 的 代码使用 与 前 个示例相 同 的 组 参 数 值 , 因 此 隐 含 波 动 率 应 当 是一样 的 , 即
0.25 。 这 个 程 序 的 逻 辑 是 使 用 试 错 法 来 为 Black-Scholes-Merton 期 权 模型提供许 多 不 同 的
sigma ( 波动 率 ) 。 对 于 给 定 的 一 个 sigma 值 , 如 果 计 算 得 到 的 看涨 期 权价格和给 定 的 看涨
期权价格之 间 的 绝对 差值 小 于 0. 0 1 , 就停止计 算 。 那 个 sigma 值 就 是 隐含 波 动 率 。 以上程
序的输 出 结 果 如 下 。
( 4 9 , 0 . 2 5 , - 0 . 0 0 40 0 607 9737 2 8 8 2 8 1 7 )
10.2.2 欧式期权的隐含波动率
一
最后 , 可 以 编写 个 函 数 来 估 计 基 于 欧 式 看 涨 期 权 的 隐含波动 率 。 为 了 节 省 空 间 , 从
程序 中 删 除 所 有注 释 。
1 0.2 for 循 环 简 介 239
de f imp l i ed_vol_cal l ( S , X , T , r , c ) :
f r om s cipy import log , exp , sqrt , stats
for i i n range ( 2 0 0 ) :
s igma=O . O O S * ( i+ l )
dl= ( l og ( S / X ) + ( r + s i g�a * s i gma / 2 . ) * T ) / ( s i gma * sqrt ( T ) )
d2 = dl - s i gma * sqrt ( T )
di f f=c 一 ( S * stats . norm . cdf ( d l ) - X * exp ( - r * T ) * s tats . norm . cdf ( d2 ) )
i f abs ( d i f f ) <=0 . 0 1 :
return i , s igma , di f f
使用 一 组输入值, 可以方便地使用以上代码, 如 下 所 示 。
>>>imp l i ed_vol_cal l ( 4 0 , 4 0 , 0 . 5 , 0 . 0 5 , 3 . 3 )
( 4 9 , 0 . 2 5 , - 0 . 0 0 4 0 0 6 0 7 9 7 37 2 8 8 2 8 1 7 )
10.2.3 看跌期权的隐含波动率
可以基于期权模型估计欧式看跌期权的隐含波动 率 。 在以下的程序中 , 编写 一个 名 为
imp 辽 e d_vo l_put_m i n ( ) 的函数。 这个 函数和前
一
节的函数有几 点 区 别 。 首先,这个函
数计算看跌期权的隐含波动率, 而 不 是 看 涨期权的隐含波动 率 。 因 此, 最后 一个输入值是
看跌期权的价格, 而 不 是看涨期权的价格。 其次, 收敛标准是估 计的期权价格和给定的看
跌期权价格的绝对价差最小 。 在前 一 节的函数中 , 收敛标准是 当绝对价差 小 于 0.01 时 。 因
一
此 , 这个函数将保证 一 定 可以得到 个隐含波动 率的估计值, 而 前 一 节的函数不 能保证。
可 以 生成 一 些 中 间 值 来 缩 短 计 算 所 需 的 时 间 。 例 如 , 在 以 上 的 代 码 中 , 需 要计算 ln(S/X)
一
共 1 0 000 次 。 可 以 定 义 一 个 新 的 变量 l o g_S_o ve r_X 等 于 ln(S/X) , 只 需 要 计 算 它 的 值
次, 然后重复使用 1 0 000 次 。 同 样 的 办 法 也 可 以 用 于 s i gma * s i gma / 2 . 0 和
s i gma * s qrt ( T ) 。
10.2.4 enumerate()函数简介
当 编 写 计 算 净现值 的 函 数 NPV() 时 , 需要 依 照 以 下 公 式 计 算 未 来 和 现 在 的 所有现金流
量 的 现值 。
NPV = I
n cashjlow;
(I 0- I )
i=O ( 1 + RY
一
每 笔现金流 由 两个 值来 决 定 : 发 生 的 时 间 i 和 在 时 间 l 产 生 的 现金 流量 。 下 面 的 NPV
函 数显 示 如 何 应 用 enume r a t e ( ) 函 数 来处理这种数据 。
return total
一
enume ra七e ( ) 函 数将 生 成一 个从 0 开 始 的 索 引 以 及 对应的 值 。 可 以输入折现率和 组
现金流量 的 值 来 调 用 以上 的 函 数 , 结 果 如 下 。
»>c = [ - 1 0 0 . 0 , 6 0 . 0 , 6 0 . 0 , 6 0 . 0 ]
>>>r = O . l
> > >npv=npv_f ( r , c )
> > > round ( npv , 2 )
49.21
1 0.3 用 for 循 环 计 算 内 部 收 益 率 及 多 个 内 部 收 益 率 241
>>>cashfl ows = [ - 1 00 , 5 0 , 6 0 , 2 0 , 5 0 )
242 第 10 章 Python 的 循 环语句 和 隐 含 波 动 率 的 计 算
>>>x=IRR_f ( ca s h f l ows )
>>>round ( x , 3 )
0 . 304
>>>
import s c ipy a s s p
de f npv_f ( ra 七 e , cashflows ) :
total = 0 . 0
for i , cash f l ow i n enume rate ( ca s h f l ows ) :
total += cash f l ow / ( 1 + rat e ) * * i
r e t u rn to 七 a l
de f I RRs f ( cash f l ows ) :
n= l O O O
r=range ( l , n )
eps i l on=abs ( sp . mean ( ca s h f l ows ) * 0 . 0 1 )
irr= [ ]
npv= [ ]
for i i n r :
npv . append ( O )
l a g_s ign=sp . s i gn ( npv_f ( r [ 0 ] * l . 0 / n * l . 0 , cash_f l ows ) )
for i i n range ( l , n - 1 ) :
interest=r [ i ] * l . 0 /n * l . O
npv [ i ] =npv_f ( i n t e re s t , cash_f l ows )
s=sp . s ign ( npv [ i ] ) \
i f s * lag_s ign<O :
l ag s i gn=s
i r r . append ( inte re s t )
return i r r
1 0.4 while 循 环 简 介 243
可以调用该函数轻松地找到两 个IRR 。
>>>cas h f l ows= [ 5 5 , - 5 0 , - 5 0 , - 50 , 1 0 0 ]
>>>IRRs_f ( ca s h f l ows )
[ 0 . 072 , 0 . 3 3 7 )
\
>>>
i=l
whi l e ( i <= 4 ) :
prin t ( i )
i+=l
while 循环的关键是退出条件应该至少满足
一
次, 否 则将进入 一 个无 限循环(死循环 ) 。
比如, 运行以下代码将 进入 一 个无限循环。 这种情况发生时, 可以按 Ctrl+c组合键停止它。
i=l
whi le (i ! =2 . 1) :
prin t ( i )
i+=l
斐波纳契序列 I , 1 ,2,3,5,8, 1 3, … …
de f f i b ( n ) :
" '"' Print a Fibonacci s e r i e s up to n .
a, b = 0, 1
wh i l e a < n :
prin t ( a )
a , b = b , a+b
244 第 10 章 Python 的 循 环 语 句 和 隐 含 波 动 率 的 计 算
当 n 为 I 000 时 , 得 到 以 下 结 果 。
>>>fib ( 1 0 0 0 )
0 1 1 2 3 5 8 13 2 1 34 55 8 9 144 233 377 610 987
1 0.4.1 使用键盘命令停止无限循环
一
有 时 , 由 于 各 种 原 因 , 代码运行可 能会进入 个 无 限循环 ( 参 见 以 下 程序 ) 。 我们 的 目
的 是 打 印 1 �4 这 4 个数字 。 然 而 , 由 于 忘记在每次打 印 之后 增 加 变 量 i, 退 出 条件永远不
一
会被满足 , 也 就 是 说 , 它进入 个 无 限循环 。 对 于 这 种 情 况 , 可 以 按 Ctrl+C 或 Ctrl+Enter
组合键来终止循环 。
i=l
whi le i < S :
prin七 ( i )
de f bs_put ( S , X , T , r f , s i grna ) :
f rom s c ipy i mport l o g , exp , sqrt , s t ats
dl= ( l og ( S /X ) + ( r f + s i gma * s i gma /2 . ) * T ) / ( s i gma * s qrt ( T ) )
d2 = d l - s i gma * s qrt ( T )
return X * e xp ( - r f * T ) * s tats . norm . cdf ( - d2 ) - S * s tats . no rm . cdf ( - dl )
输入
一
组 s、 X、 T 、 rf 和 s i gma 的 参数 值来 调 用 该 函 数 , 结 果 如 下 。
>>>p u 七 =bs_put ( 4 0 , 4 0 , 0 . 5 , 0 . 0 5 , 0 . 2 )
> >>rou nd (put , 2 )
1 . 77
\
impor t p 4 f
1 0.4 while 循 环 简 介 245
import s c ipy as sp
S=4 0 ; K= 4 0 ; T=0 . 5 ; r=0 . 0 5 ; p=l . 7 7
di f f = l ; i = l ; s i gma_o ld= 0 . 0 0 5
si gn_l=sp . s i gn ( p -p4 f . bs_put ( S , K , T , r , si gma_old) )
wh i l e ( 1 ) :
\
s i gma = O . O O O l * ( i + l )
si gn_2=sp . s i gn ( p-p4 f . bs_put ( S , K , T , r , s i gma ) )
i+=l
if s i gn l * s i gn 2 < 0 :
break
else :
s i gma_ol d= s i gma
print ( ' i , imp l i ed-vol , d i f f ' )
print ( i , ( s i gma_old+s igma) /2 , di f f )
i , imp l i ed-vol , di f f
(2002, 0 . 20015, 1)
import p 4 f
S= 4 0 ; K=4 0 ; T=0 . 5 ; r=0 . 0 5 ; p=l . 7 7
di f f= l ; i = l ; s i gma_old= 0 . 0 0 5
sign_ l=s ign ( p-bs_put ( S , K , T , r , s i gma_old) )
whi le ( l ) :
s i gma=O . O O O l * ( i + l )
s i gn_2 = s i gn ( p-p4 f . bs_put ( S , K , T , r , s i gma ) )
i+=l
i f s i gn l * s i gn 2 < 0 :
break
else :
s i gma_old= s i gma
print ( ' i , imp l i ed-vol , di f f ' )
print ( i , ( s i gma_o l d + s i gma ) /2 , d i f f )
如果输入值大于 1 , s i gn ( 函
) 数的返 回 值等千 l 。 如果输入值 小 于 o, 返 回值 则等于
246 第 10 章 Python 的 循 环 语 句 和 隐含 波 动 率 的 计 算
- 1 。 s i gn ( ) 函 数 的 示例 如 下 。
>>>import sc ipy a s sp
>>>sp . s ign ( - 2 )
-1
>>>sp . s ign ( 2 )
1
。
>>>sp . s ign ( O )
n l =2
n2=3
for x i n xrange ( l , n l + l ) :
for y i n xrange ( l , n2+ 1 ) :
print ' % d * %d = % d ' % ( x , y , x * y )
一 一
可 以 使 用 两 个 wh 辽 e 循环或者 个 fo r 循环和 个 wh i l e 循环 的 组合来完 成 同 样 的
任务。
以 下 代码用 来计算美式看涨期权 的 价 格 。
import time
start = time . c lo c k ( )
n=l O O O O O O O
for i i n range ( l , n ) :
k=i+ i + 2 ; di f f= ( t ime . c l o c k ( ) - star 七 )
print ( round ( di f f , 2 ) )
上面这个循环 完成运行所需的时间约为 1 .5 9s 。
248 第 10 章 Python 的 循 环 语 句 和 隐含 波 动 率 的 计 算
1 0.7 二分搜 索 的原 理
以 下 代码生成 一 份来 自 圣经 的 单 词 列 表 , 然 后 采 用 二 分搜索法找到 一 个 给定 词 的 位 置 。
首 先 , 从 网 页 https://canisius.edu/-yany/doc/AV l 6 1 l Bible.txt 下载圣经 的 文 本文 件 , 并把该
文 件保存在 C :\temp\ 目 录下 。
\
( I J - 0 1 2 3 4 5 67 8 9 ' )
、
[\\) A
i f word . star tswi 七 h ( 1 _ I ) ;
word = wor_d . replace ( ' - ' , ' ' )
i f len ( word) :
word_f req [ wo r d ) = word_f千eq . get ( word, 0 ) + 1
keys = s o r te d ( word_f req . keys ( ) )
x = pd . Da 七 aFrame ( keys )
x . to_pickle ( ' c : / temp /uniqueWords . pi c k l e ' )
一
这 一 次, 我们用下 面的代码查找 个字 符 串 而不是 一 个数值 。
>>>x . i loc ( 6 0 0 ]
0 Ba kba kkar
Name : 6 1 0 , dtyp e : obj e c t
impor t pandas as pd
x =pd . read_p i c kl e ( " c : /t emp / uniqueWords . pk l " )
pr int ( x . iloc [ 6 1 0 ] )
1 0.8 顺序 访 问 与 随机访 问
一
可以用不 同的模式保存每 日 的股票数据 。 种方法是将它 们 保存为股票 ID 、 日 期、 日
250 第 10 章 Python 的 循 环 语 句 和 隐含 波 动 率 的 计 算
1 0.9 通过循环访 问 数组 的 元素
import numpy as np
x = np . arange ( l O ) . re shape ( 2 , 5 )
for y in np . ndi ter ( x ) :
pr int ( y )
一
从 http : / / canisius . edu / - yany/ yanMonthly . pickle 下 载 个 名 为
一
yanMonthl y . pi ckle 的数据集, 用来展示遍历访 问的另 个例子。 假定下载的数据集保存
一
在 C : \ temp \ 下, 可以使用下面的代码来检索数据集并运行 个循环来打 印 出股票的代号。
import pandas as pd
x=pd . read_pickle ( ' c : / ternp /yanMonth l y . pkl ' )
stocks =x . i ndex . unique ( )
for item in s to c ks [ : 1 0 ) :
print i tem
# add your codes here
以上代码的结果 如 下 。
0 0 0 0 0 1 . SS
A
\
AA
AAPL
BC
BCF
C
1 0.9 通过循 环 访 问 数 组 的 元 素 251
CNC
COH
CPI
>>>stocks [ 0 : 1 0 ]
array ( [ ' O O O O O l . S S ' , ' A ' , ' AA ' , ' AAPL ' , ' BC ' , ' BCF ' , 'C' , ' CN C ' , ' COH ' ,
' CP I ' ] , dtype = obj ect )
>>>
以下代码 将多个值分配给变量 。
10从 2 通过循环访问词典的元素
下面是 一 个与字 典有关的示例。
252 第 10 章 Python 的 循 环 语 句 和 隐 含 波 动 率 的 计 算
>>>mar ke t_cap = { " IBM" : 2 0 0 . 9 7 , "MSFT " : 3 1 1 . 3 0 , " WMT " : 2 5 3 . 9 1 , "C" : 158 . 5 0 )
以下 代码 演 示 如何利用循环遍历字典。
>>>ma r k e t_cap= { " 工 BM" : 2 0 0 . 9 7 , "MSFT " : 3 1 1 . 3 0 , " WMT " : 2 5 3 . 9 1 , "C" : 158 . 5 0 )
> > > for k , v i n mar ket_cap . i tems ( ) :
print k , v
C 158 . 5
工BM 2 0 0 . 9 7
MSFT 3 1 1 . 3
1 0. 1 0 从 CBOE 网 站下载期权数据
表 1 0-1
December 1 5, 20 1 3@ I 0:30ET Bid 1 72.5 1 Ask 1 72.8 Size 2x6 Vol 4 1 84836
。 。
50.3
import numpy a s np
import pandas as pd
x=pd . read csv ( ' c : / temp /QuoteDa 七 a . da t ' , s k iprows = 2 , header = ' infer ' )
y= np . array ( x )
n=len ( y )
用 以 下 代码显示最 前 和 最 后 几 行 。
>>>print y [ 0 : 2 )
[ [ ' 1 3 Dec 1 2 5 . 0 0 ( 工 BM1 3 1 3 L l2 5 ) ' 0 . 0 0 . 0 4 6 . 7 5 5 0 . 0 OL O L
' 1 3 D e c 1 2 5 . 0 0 ( I BM1 3 1 3 X l 2 5 ) ' 0 . 0 0 . 0 0 . 0 0 . 0 3 O L O L nan ]
[ ' 1 3 Dec 1 2 5 . 0 0 ( I BM1 3 1 3 L l 2 5 - 4 ) ' 0 . 0 0 . 0 4 6 . 4 5 5 0 . 4 5 O L O L
254 第 10 章 Python 的 循 环语句 和 隐含 波 动 率 的 计算
1 0. 1 1 从雅虎财经 网 页 下载期权数据
3 . 单击 Options 的选项 。
y�氐沪
Floam Hom,
归 O <- l><>d•
。『'•'""' ...,..
. �"'
•....,., ""'"" 正hoolo;y Mukm
一
臼<-Co酝" "" a ............ i:> 七- ··一 石 _.. . ....
lnau,订,.. My '"""'"
一
M, PoNtollo
Cail• 幻 上心芍6 如1
.蕨八. “呵沁心硐, U\11节冷 .:,,. (.I': cr..i.心 ` 3帜蟾一心 _,., , ...
,
••
,., 心
"·'""
吧u110,0110沪“比如
Ie-.tr ro, 心劝 又如
1325
12U
1360
117�...!AO$
u 30 穴 '2
0 00,,
、
91 Ol
图 1 0-2
要检索 其他有效 期 的 期 权 , 需 要 指 定 到 期 日 的 月 份和 年份 。 首 先 , 看 看 不 同 有 效 期 的 期 权
所 在 的 网 页 http://finance.yahoo.com/quote/lBM/options?p=IBM , 如 图 1 0-3 所 示 。
介 Add
International Business Machines Corporation (IBM)
阶SE 小 HYSE R的T叩ePoee C 中虹 i 1n 1JSO
叩n
January 20 2017
January 27, 2017
气l
L
Fe即ary 3, 2017 伈出K>ns Sta沁氏 , Pron;, F,nanc,a� Opuons
Fellfuary 10. 2017
Fe!lfuary 17 20 17 �
February 24 2017
Ma兀n 11, 2011
I AprII 21 . 2017
June 16. 2017
Ju灯 21 2017
January 1 9 201e ,
January 18. 2019 j
January 5. 2017 • I In The Mon勺 Show List S叩心
图 1 0-3
10. 1 1 .2 从雅虎财经网页下载当前价格
使用 以 下 Python 代码可 以 检 索 给 定 股 票 的 当 前 价 格 。
import da tetime
impor 七 s c ipy as sp
fr om ma tplot l i b . finance import quotes_h i s to r i c a l_yahoo—o chl as getData
s tocks = [ ' ibm ' , ' ms f t ' , ' goog ' J
begdate= ( 2 0 1 7 , 1 , 1 )
endda te= datet ime . date . 七 oday ( )
n=l e n ( sto cks )
for i i n sp . arange ( n ) :
p=getData ( s 七 ocks [ i ) , begdate , enddate , as obj e ct=True , adj u s 七 ed=True )
pri ce=round ( p [ ' cl o s e ' ) [ 0 ) , 4 )
print ( " For " , s 七 ocks [ i ) . upper ( ) , " the price i s " , price )
#
假 如 在 20 1 7 年 3 月 3 日 运行 以 上代码 , 输 出 结 果 如 下 。
1 0. 1 2 看跌期权和看涨期 权 的 比 率及其短期趋势
看 跌 期 权 和 看 涨 期权 的 比 率 ( put-call 比 率 ) 反 映 了 投 资 者 对未来 的 看法 。 如 果 预 期 未
256 第 JO 章 Python 的 循 环 语 句 和 隐 含 波 动 率 的 计 算
1. 转到 http ://www.cboe.com/data/putcallratio.aspx 。
2. 单击菜单栏 中 的 " Quotes & Data " 按钮 。
3. 单击 " CBOE Volume & Put/Call Ratio " 按钮。
4. 单击 " CBOE Total Exchange Volwne and Put/Call Ratios ( 1 1 -0 1 -2006 to present) " 按钮。
import pandas as pd
impor 七 s cipy as sp
from matp l o t l i b . pyp l o t import *
data =pd . re ad_csv ( ' c : /temp / totalpc . c sv ' , s k iprows = 2 , index_co l = O , parse_da te
s = True )
data . c o l umn s = ( ' Ca l l s ' , ' Put s ' , ' Total ' , ' Ra七io ' )
x = data . index; y = da 七 a . Ratio; y2 = s p . o n e s ( l en ( y ) )
七 i 七 le ( ' P u t - c a l l ratio ' ) ; xlabel ( ' Date ' ) ; y l ab e l ( ' Put-cal l ratio ' )
y l im ( 0 , l . 5)
p l o t ( x , y , ' b- ' )
plot ( x , y2 , ' r ' )
show ( )
Put-call ratio
II ii ,I ' ' I
1.4
1.2
1.0
启� 0. 8
弓 0.6
�
0..
0.4
\
02
00 '
. 2007 2008 2009 2010 2011 2012 2013
Date
图 1 0-4
10. 1 2 看 跌 期 权 和 看 涨 期 权 的 比 率及其短期 趋势 257
data . column s= ( ' C a l l s ' , ' Put s ' , ' Total ' , ' Ratio ' )
begda te=datet ime ( 2 0 1 3 , 6 , 1 )
enddate=datetime ( 2 0 1 3 , 1 2 , 3 1 )
data2=data [ ( data . i ndex>=begdate ) & ( data . index<=enddate ) ]
x = data2 . index; y =data2 . Ra tio
x2=range ( len ( x ) ) ; x3 = sm . add_constant ( x 2 )
mode l sm . OLS ( y , x 3 )
=
resul 七 s=model . f i t ( )
#print results . s ummary ( )
alpha = round ( r e s u l t s . params [ 0 ] , 3 )
s l ope=round ( re s u l t s . pa rams [ l ] , 3 )
y3=alpha+sp . do 七 ( s l ope , x2 )
y2=sp . ones ( l en ( y ) )
t i t l e ( ' Put - c a l l r a t io ' ) ; x l abel ( ' Dat e ' ) ; ylabel ( ' Put- c a l l r a t i o ' )
yl im ( 0 , 1 . 5 )
plot ( x , y , ' b- ' )
plot ( x , y2 , ' r - . ' )
plot ( x , y3 , ' y+ ' )
plt . fi gtext ( 0 . 3 , 0 . 3 5 , ' Trend : i n te rcept= ' + s t r ( al pha ) + ' , s l ope = ' + str ( s lope ) )
sho w ( )
绘制的图形如图 10-5 所示 。
Put-call ratio
1.4
0之U _
c5 0
8
_
eY3
6
Z
0.2
o.o
,..1 2013 A叩 2013父p 2013 OCt 2013 Nov 20130ec 2013
Date
图 1 0-5
258 笫 L O 章 Python 的 循 环语 句 和 隐 含 波 动 率 的 计 算
1 0. 1 3 小结
练 习题
9 . 是 否 有 必 要 使 用 二叉树方法来估计 隐 含 波 动 率 ?
对于 给 定 的 某 些输入值 , 我 们 可 能 得不 到 输 出 结 果 , 请参考 以 下 示 例 。
>>>imp l i ed_vol_cal l ( 2 5 , 4 0 , l , 0 . 0 5 , 3 . 3 )
>>>impl i ed_vol _c a l l ( 2 5 , 2 6 , l , 0 . 0 5 , 3 . 3 )
>>>imp l i e d_vo l_c a l l ( 4 0 , 4 0 , 5 , 0 . 0 5 , 3 . 3 )
找 出 原 因 并 对此程序做 出 相 应 的 修 改 。
1 1 . 本 章 学 习 了 如 何 使用 以 下 程 序 根 据 Black-Scholes-Merton 期 权 模 型 来 估 计 隐 含 波
动率。
de f impl ied_vol_put_min ( S , X , T , r , p )- :
from s cipy import l o g , exp , sqr t , s tats
imp l i ed_vo l = l . O
min_value = l O O . O
for i i n range ( l , 1 0 0 0 0 ) :
s i gma = O . O O O l * ( i + l )
d l = ( log ( S /X ) + ( r + s i grna * s i grna/2 . ) * T ) / ( si gma* s qrt ( T ) )
d2 = dl-s i gma * s qrt ( T )
put=X * e xp ( - r * T ) * s tats . no rrn . c df ( - d2 ) - S * sta 七 s . norm . cdf ( 一 d l )
abs_di ff=abs ( put-p)
if abs d i f f <min value :
min va l ue=abs d i f f
imp l i ed_vol = s i gma
k=i
put_out=put
print ' k, imp l i e d_vo l , pu t , abs_di f f ' return k , imp 巨 ed_vo l ,
put_out , min_value
260 第 J O 章 Python 的 循 环语 句 和 隐含 波 动 率 的 计算
12 . 以下程序有什 么 问题?
i=l
def whi l e less than n ( n , k=l ) :
i=l
whi l e True :
i f i<n :
else :
print i 丘=k
return ' done '
(1) 转到 http://www.cboe.com/ 。
• 产生服从 标准正态分布和正态分布的随机数
• 产生服从 均 匀分布的随机数
• 利用蒙特 卡 罗 模 拟估算亢的值
• 产生服从 泊 松分布的随机数
• 可重 复和不可重复的随机取样
• 模 拟股票价格
变动路径及终端价格
• 寻 找有效的投资组合和有效组合的边界
. 使用蒙特 卡 罗 模 拟计算欧式期权价格
• 路径独立与路径依赖期权
• 预测长期回报率
• 奇异期权
简介
• 具有浮动执行价格的回 望式期权的定价
262 第 11 章 蒙 特 卡 罗 模 拟 和 期 权定 价
• Sobo l 序 列
>>>impor 七 scipy as sp
>>>x=sp . r andom . s tandard_normal ( s i z e = l O )
>>>pri nt ( x [ 0 : 5 ] )
( - 0 . 5 5 0 62594 -0 . 5 1 3 38547 -0 . 04208367 -0 . 66432268 0 . 49461661 ]
>>>
也 可 以 使 用 以下 代 码 来 产 生 标准 正 态 分 布 的 随机 数 。
>>>irnpor 七 s c ipy as s p
>>>x = sp . r andorn . norrnal ( s i ze=l O )
这 个语 句 与 下 面 语 句 的作 用 相 同 。
一
random.normal() 函 数 的 第 l 个输入 参 数 是 均 值 , 第 2 个输入参 数 是标 准 方 差 , 最后
个 是 随机数 的 个 数 , 也 就 是 数 据 集 的 大 小 。 均 值 和 标 准 方 差 的 默 认 值 为 0 和 1 。 可 以 使用
help() 函 数 来 了 解 输 入 参 数 的 定 义 。 为 了 节 省 空 间 , 以 下 只 显 示 help() 函 数输 出 结 果 的 前
几行 。
产生服从 ( 高斯 ) 正态分布的随机样本
040
0 35
030
0.25
D.20
0 15
010
o.os ,.
0.00
-3 -2 -1 0 1 2 3
图 1 1-1
标准正态分布的密度函数由以下的数学公式来表达 。
f(x) =
1 _£.
C ll-1 )
尽
1 1 . 1 .2 利用种子 ( seed ) 生成相同的随机数
1 1. 1.3 产生 n 个服从正态分布的随机数
e
(x-µ)2
f (x) = 1 2u2
( 1 1 -2 )
卢
1 1.1 .4 正态分布样本的直方图
直方图是用来分析一组数据的统计特征的常用工具。 使用以下代码绘制一组服从 给定
均值和标准方差的正态分布的随机数的直方图。
>>>import s c ipy as sp
>>> import matp lot l ib . pyp l o t as p l t
>>>sp . random . seed ( 1 2 3 4 5 )
>>>x=sp . r andom . normal ( 0 . 0 8 , 0 . 2 , 1 0 0 0 )
>>>plt . hi s t ( x , 1 5 , normed=True )
>>>pl t . show ( )
绘制的结果如图 1 1 -2 所示。
2.0
1.5
LO
0.5
图 1 1 -2
1 1 .1 产 生 服 从 标 准 正 态 分 布 的 随机数 265
\
1
C l l -3)
2
(ln(x)-µ)
f( x; µ, cr) = e 芷
泣尽
。
1.8
Lo_g_norrnal distribution
a
n_
m
.
l
=
9
u
SI
l l l l 0 0 0 0
6 4 2 0 8 6 4 2
-l
uo1
1nq亡lS!
P Al/
SUap 1
eE JOU601
图 1 1 -3
1 1 .1.6 产生服从泊松分布的随机数
为了研究私有信息对股票 价格的影响 , Easley 、 Kiefer、 O' Hara 和 Paperman ( 1 996 ) 提
出 了 一个称为知情交易概率 ( PIN ) 的指标 。 这个指标 需 要 利 用 一 天 内 由 买方发起的交易个
数和 由 卖方发起的交易个数来计算 , 它的基本假设 是 一 天的交易个数服 从泊 松分布 。 生成
服 从 泊松分布的随机数的代码 如 下 。
import scipy as sp
import numpy as np
import matp l o t l ib . pyplot as plt
x=sp . random . po i s s on ( lam= l , s i z e= l O O )
a = 5
n = 1000
s = np . random . powe r ( a , n )
count, bi n s , ignored = p l t . h i s t ( s , bins=3 0 )
x = np . li nspace ( O , 1 , 1 0 0 )
y = a*x* * ( a-1 . )
normed_y = n * np . di f f (bins ) [ O ] * y
p l t . plot ( x , normed_y )
p l t . show ( )
>»print ( x [ 0 : 5 ] )
[ 30 . 3 2 7 4 9 0 2 1 20 . 58006409 2 . 43703988 7 6 . 1 5 66 1 2 9 3 7 5 . 069290 8 4 ]
>>>
一
通过蒙特 卡 罗 模 拟 计 算7t 的 近似值 是 个很好 的 练 习 。 考虑 一 个边 长 为 2R 的 正 方 形 。
这 个 正 方 形 里 可 以 放 入 的 最 大 的 圆 形 的 半 径 为 R 。 这 两 个 形 状 的 面 积可 以 由 以 下 公 式 计 算 。
scircle = pi x R 2
( 1 1 -4 )
将 公 式 C l l -4 ) 和 公 式 C l l -5 ) 的 结 果 相 除 , 可 以 得到 以 下 结 果 。
Scircle pi
q11are 4
值 可 以 用 以 下 公 式估计 。
图 1 1 -4 显示这些随机产 生 的 点 落 在 正 方 形和 圆 形之 内 。
268 第 11 章 蒙 特 卡 罗 模 拟 和 期 权 定价
图 1 1-4
import s c ipy as sp
n=l O O O O O
x = sp . random . uni form ( l ow= O , high = l , s i ze=n )
y=sp . random . u n i f o rm ( l ow=O , high = l , s i z e = n )
dis t=sp . s qrt ( x * * 2 + y * * 2 )
in_c i r c l e =dist [ d i s t < = l )
our pi = l e n ( in c i r c l e ) * 4 . / n
print ( ' p i = ' , our_p i )
print ( ' e r r o r ( % ) = ' , ( our_p i - s p . p i ) /sp . pi )
( ' pi = ' , 3 . 1 4 5 92 )
( ' err or ( % ) = ' , 0 . 0 0 1 3 7 7 4 3 7 1 4 3 3 1 0 7 3 3 5 )
>>>
1 1 .3 从 n只股票 中 随机选择 m 只
以下的代码从 500 只 股票中随机选择 20 只 。这是研究任意几 只股票如何影响投资组合
的波动率的一 个重要步 骤 。
import s c ipy a s sp
n stocks ava i l able= S O O
1 1 .3 从n只 股 票 中 随 机选择 m 只 269
n stocks = 2 0
x=sp . random . uni form ( low= l , hi gh=n_s tocks_avai l able , s i z e = n_s tocks )
y= [ ]
for i i n sp . arange ( n_stocks ) :
y . append ( i n t ( x [ i ] ) )
f i n a l = sp . u n i que ( y )
print ( f inal )
print ( l en ( f i n al ) )
import pandas a s pd
impor t sc ipy as sp
import numpy as np
n stocks=l O
x =pd . read p i c k l e ( ' c : /temp/yanMonth l y . pkl ' ) x2 = sp . unique ( np . a 工 ray ( x . i ndex) )
x3 = x2 [ x2 < ' Z Z Z Z ' ] # r emove a l l i n d i c e s
sp . random . seed ( 1 2 3 4 5 6 7 )
nonStocks = [ ' GOLDPRICE ' , ' HML ' , ' SMB ' , ' Mkt_Rf ' , ' Rf ' , ' Ru s s 3 0 0 0E_D ' , ' US_DEBT ' ,
' Russ 3 0 0 0E_X ' , ' US_GDP2 0 0 9do l l ar ' , ' US_GDP 2 0 1 3do l l a r ' )
x4=list (x3)
for i in range ( l en ( no n S t o c ks ) ) :
x4 . remove ( nonStocks [ i ) )
k=sp . random . u n i form ( low= l , h i gh= l e n ( x4 ) , s i z e=n_s t o c k s )
y, s= [ ) , [ ]
for i i n range ( n_stocks ) :
index = i nt ( k [ i ) )
y . append ( i ndex )
s . append ( x 4 [ i nd e x ) )
f inal=sp . u n i que ( y )
p r i n t ( fi n a l )
print ( s )
图 1 1 -5
该代码的输出如图 1 1 -6 所示。
.[ [ [ [ [ 、,
.
.7 8 4 2 7 >
.
8 3 7 4 6
3 7 108 2
4 5 3 3 1
6 2 9 1 3
9 4 1 6 9
1 6 6 9 5
2 1 8 lolo
1
0 9 2 5 4
5 0 5 7 8
一·
_
i: :..、
数, 第 3 个表示是否可重复选取数据。 图 1 1 -6
1 1 .5 年 收 益 率 的 分布 271
de f boots f ( da 七 a , n ob s , replacement=None ) :
impor 七 numpy as np
n=len ( da t a )
i f ( n< n_ob s ) :
print " n i s l e s s thah n obs "
else :
i f rep l a c ement==None :
y=np . random . permu tati on ( data )
return y [ O : n_obs )
else :
y= [ )
for i in range ( n_obs ) :
k=np . random . pe rmutat ion ( data )
y . append ( k [ O J )
return y
1 1 .5 年收益率 的分布
# s 七 ep 1 : input area
ti cker= ' MSFT ' # i nput value 1
begdate = ( 1 9 2 6 , 1 , 1 ) # inpu t value 2
endda 七 e= ( 2 0 1 3 , 1 2 , 3 1 ) # i nput value 3
n s imu lation = S O O O # input value 4
logret = sp . l og ( x . a c l o s e [ l : ) / x . aclos e ( : - 1 ) )
# step 5 : g raph
pl t . title ( ' Mean return dis 七 r ibution : number of s imu lations = ' + str
( n s imu l a t i on ) )
p l t . x l ab e l ( ' Mean return ' )
pl t . y l ab e l ( ' Frequency ' )
mean_annual =round ( np . mean ( np . array ( r et_annua l ) ) , 4 )
plt . figtex 七 ( 0 . 63 , 0 . 8 , ' mean annual= ' +str (mean_annua l ) )
p l t . hi s t ( f i na l , 5 0 , normed=True )
p l t . show ( )
绘制的样本分布图如图 1 1 - 7所示 。
1 1 .6 模拟股 价 变 化 273
mean annual=0.3461
6
Au
uanba.y
4
00
1
图 1 1 -7
1 1 .6 模拟股 价变化
S, +I = S, exp (( 三矿 J t:..t + CY E 气 C l l -8 )
import s c ipy as sp
import matpl otlib . pyplo七 as p l t
p l 七 . fi gtext ( 0 . 2 , 0 . 8 , ' S O = ' + s t r ( S [ O ] ) + ' , mu= ' + s t r (mu ) + ' , s i gma= ' + s 七 r ( s i gma ) )
p l 七 . f i gtext ( 0 . 2 , 0 . 7 6 , ' T = ' + s 七 r ( T ) + ' , s 七 ep s = ' + s 七 r ( i nt ( n_steps ) ) )
plt . t i 七 l e ( ' Stock price ( number o f s imulations = %ct ' % n_s imulation + ' ) ' )
plt . xlabe l ( ' Total number of s teps = ' + s 七 r ( i n七 ( n_steps ) ) )
pl t . ylabe l ( ' s tock price ' )
plt . show ( )
为 了 增 加 图 形 的 可读 性 , 图 1 1 -8 只 绘制 了 5 条 模拟 出 的 价 格 曲 线 。 由 于使用 了 seed( )
函 数 , 所 以 可 以 再 次 运 行 上 面 的 代 码 来 完 全 复 制 图 1 1 -8 。
6
。 20 40 的
Total num�r 9fH�杆气l的
80 100
图 1 1-8
1 1 .7 图 形展 示 期 权 到 期 日 的 股 票 价 格 的 分 布 275
我们在之前 提 到 欧 式 期 权 的 价 值与 到 期 前 的 股 票 价 格 无 关 , 仅 仅 取 决 于 到 期 日 的 股票
价 格 。 因 此 , 需 要 知 道 到 期 日 的股票价格 的概率分布才能给期权 定 价 。 以 下 代码可 以 依据
一
给定的 组参 数 来 模 拟 期 权 到 期 日 的 股 票 价格 : so ( 初始 股 票 价 格 ) 、 n_simulation ( 模 拟
的 次 数 ) 、 T C 以 年 计 的 有 效 期长度 ) 、 n—steps C 步数 ) 、 mu ( 年 回 报率 的 期望值 ) 和 sigma
( 年 回 报 率 的 标 准 方差 , 又 称波动率 )
dt =T/n_s teps
S = sp . zeros ( [ n_simulation ] , dtype=float )
x = range ( O , i n t ( n_s 七 eps ) , 1 )
for j i n sp . arange ( n_s imu l a t i on ) :
t t=S O
for i i n sp . arange ( n_steps ) :
e=sp . random . normal ( )
t t+=tt* ( ( mu- 0 . 5 * s igma * * 2 ) *dt + s i gma *sp . s qrt ( d t ) * e ) ;
s [ j l =tt
期权 到期 日 的 股 票 价 格 的 直方 图 如 图 1 1 -9 所 示 。
276 第 11 章 蒙特卡 罗 模 拟 和 期 权定价
300
50=9.15,mu=0.15,sigma=0.2
2
5
0
T=l.O, ste s=lOO
Number otterminal prices 1000
sa它anba.J
司
2
0
0
1
0
5
J JJO 史1EnN
0
1
0
0
5
6 8 10 12 14 16 18 20
图 1 1 -9
Y2 = px, 十二 ( 1 1-1 1 )
import numpy as np
import s cipy as sp
import pandas as pd
f rom da 七 e time import datet ime as d 七
import matp l o t l ib . pyp lot a s p l t
1 1 .8 寻找有效 的投资组合 和有效边界 277
bounds=b )
i f not resu l t . succes s : # handle e r r o r
r a i s e BaseException ( re s u l t . me s sage )
plt . plot ( np . array ( std_O ) , np . array ( s to c kMean ) , ' o ' , marke r s i ze=B )
pl 七 . p lot (out_s 七 d , out_mean , ' - - ' , l i newidth= 3 )
p l t . show ( )
0.28
o o 0 0 0 0
262422201816
o-
l
o芒 25Po}
三
s-z,1
41i
oEaau
0·13
.os 0.10 0.12 0.14 0.16 0.18 0.20 0.22
Standard Deviation of the 2-Slock Portfolio (Risk)
图 1 1-10
impor 七 numpy as np
import sc ipy as sp
impor t pandas as pd
f rom datetime import datet ime as dt
L 1 .8 寻找有效的投资组合和有效边界 279
# Step 1 : inp 七 a r e a
mean_0 = ( 0 . 1 5 , 0 . 2 5 ) # mean returns for 2 stocks
\
std_O = ( 0 . 1 0 , 0 . 2 0 ) # s tandard devi a 七 ions for 2 sotcs
n= l O O O # number o f s imua t i ons ( returns ) for each s t o c k
corr_= ( 0 . 1 , 0 . 5 , 0 . 8 )
.. . .
0Easj
。
o.18
. oe
图 ll-11
1 1 .8 寻找有效的投 资组合和 有效边界 281
1 1 .8.2 构建 n 只股票的有效边界
任意 n 只 股 票之 间 共有 n * (n - l )/2 个相 关 系 数 , 因 此 当 股 票 数 量 n 增 加 时 , 股 票 之 间
的相 关 系 数 的 个 数迅速增 加 。 比 如 I Q 只 股 票之 间 的 相 关 系 数 已经有 45 个 。 以 下 代 码 随 机
生成两两相 关 的 股 票 回 报 率 。
import numpy a s np
import sc ipy as s p
import pandas a s pd
from datet ime import datetime as dt
f rom s c ipy . optimi ze impor t minim i z e
import matplotl ib . pyp l o t as p l t
R= np . ar ra y ( R )
产生的图 形 如 图 1 1 - 1 2 所 示 。
1 1 .9 算 术 平 均 值 与 儿何平均值 283
0.20
Simulation for an Efficient Frontier: 10 stocks
.
-
_
a
旦0芒
e
_
S
畴
t
.
s
s
.
·
.
_
.
.
多
R三
010005000吵
8l
\
,,
S,
,
za七 j
,
.
詹-
'
ouI
`、
mau
、、
.
.
-0. 18.
。
、
。
一
o s
1
0.20 0.25
图 1 1-12
1 1 .9 算术平均值与几何平均值
.`
C ll-12)
=
.
th
n
an
n
e
c
l
1 -n
nrr I
-
l
-
l
R
R,
。erne
、丿
+
( 1 1-13)
tnc
g
.
-l
de f geomean_ret ( return s ) :
product = 1
for ret in r e t u rn s :
p r oduct * = ( l + r e t )
return product * * ( 1 . 0 /l e n ( return s ) ) - 1
284 第 II 章 蒙特卡 罗 模 拟 和 期 权定价
给定 一 组 回 报 率 , 计算它们 的 算 术和 几 何平均值如 下 。
>>>import sc ipy as sp
>>>returns = [ 0 . 0 1 , 0 . 0 2 , - 0 . 0 3 , 0 . 0 1 5 , 0 . 1 0 )
>>>geornean_re t ( r eturn s )
0 . 0 2 2 1 4 0 0 4 0 7 7 4 62 3 9 4 8
>>>sp . rnean ( retu rns )
0 . 02 3
1 1 .10 预测长期 回 报率
许 多 研究 人 员 和 从 业者认 为 采 用 历 史 回 报 率 的 算 术平均值会 高 估 未 来 的 长 期 回 报 率 ,
而 采 用 历 史 回 报 率 的 几何平均值会低 估 未 来 的 长 期 回 报 率 。 Jacquier、 Kane 和 Marcus ( 2 003 )
使用 80 年 的 历 史 回 报 率 预 测 未 来 2 5 年 的 回 报 率 , 建议采用 以 下 加 权 算 法 。
25 80 - 2 5
long - term forecast g Rgeometnc. +
=—
O SO
Rari小rnetic C l 1-14)
以下代码采用 了 公 式 ( 1 1 - 1 4 )。
impor 七 numpy as np
impor 七 pandas as pd
f rom matp l o 七 l i b . finance import quo 七 es_h i s t o r i c a l_yahoo_ochl a s getData
#
t i cker= ' I BM ' # i nput value 1
begdate= ( 1 9 2 6 , 1 , 1 ) # input value 2
endda te= ( 2 0 1 3 , 1 2 , 3 1 ) # i nput va lue 3
n foreca s t = 1 5 # input v a l u e 4
#
de f geomean_re t ( return s ) :
product = 1
for ret in retu rns :
p roduct * = ( l + r e t )
return p rodu ct * * ( 1 . 0 /l e n ( r eturns ) ) - 1
#
x= getData ( 七 i c ke r , begdate , enddate , as ob j e c \=True , adj u st ed=Tr u e )
l o g r e t = np . log ( x . ac l o s e [ l : ] / x . a c l ose [ : - 1 ] )
da 七 e= [ ]
dO = x . date
for i in range ( O , np . s i z e ( l ogre 七 ) ) :
date . append ( d O [ i ] . s t r ftime ( " % Y " ) )
1 1 .1 1 用 模 拟 法 为 看 涨 期 权定 价 285
#
y=pd . DataFrame ( l ogret , date , co lumns = [ ' logret ' ] , dtype=floa七 )
ret_annual = np . e xp ( y . gr oupby ( y . inde x ) . s um ( ) ) - 1
ret_annual . column s = [ ' ret_annual ' ]
n history= len ( ret annual )
a_me an= np . mean ( np . array ( re t_annua l ) )
g_mean=geomean_ret ( np . array ( ret_annu a l ) )
w = n forecast/n h i story
future_ret=w* g_mean+ ( l -w) * a_mean
print ( ' Ar i 七 hme t r i c mean = ' , round ( a_me an , 3 ) , ' Geomean = ' , round ( g_mean , 3 ) ,
' forecast = ' , futu re_r e t )
r =O . 05 # r i s k-free rate
s i gma = 0 . 2 # volati l i ty ( annua l )
=
n steps l O O . # number o f steps
sp . random . seed ( l 2 3 4 5 ) # f i x those random numbers
n s imula巨on = 5 0 0 0 # number of simula巨on
#
dt =T /n_steps
call = z e ros ( [ n_simulation ] , dtype=float)
x = range ( O , int ( n_steps ) , 1 )
for j in range ( O , n_s imulat ion ) :
sT=S 0
for i i n x [ : - 1 ] :
e = sp . random . normal ( )
sT* =sp . exp ( ( r - 0 . S * s igma* s igma ) *dt+ s igma * e * s qrt ( d七 ) )
call [ j ] =max ( s T-X , 0 )
亚式均价看跌期权的收 益 函数 如 下 :
import s cipy as sp
s 0=4 0 . # today stock p r i ce
x= 4 0 . # e x e r c i s e price
T=0 . 5 # ma 七 urity in years
r=0 . 0 5 # r i s k- f r e e rate
s i gma = 0 . 2 # vo lat i l i t y ( an nua l i z ed )
n_s imulation = l O O # number o f s imu l a t ions
n_steps = l O O # number o f s tepts
dt=T/n_steps
call=sp . zeros ( [ n_simulation ) , d七 ype=float )
for j i n range ( O , n_simu lation ) :
sT = s O ; total = O
for i in range ( O , int ( n_steps ) ) :
e = sp . random . normal ( )
s T * =sp . e xp ( ( r - 0 . S * s i gma * s i gma ) * dt+s i gma * e * sp . sqrt ( d t ) )
total+=sT
price_a verage = total / n_s teps
ca l l [ j ) =max ( p r i ce_ave rage - x , 0 )
call_p rice =sp . mean ( ca l l ) * sp . exp ( - r * T )
prin 七 ( ' ca l l p r i c e = ' , round ( ca l l_price , 3 ) )
288 第 11 章 蒙特卡 罗 模 拟和 期 权定价
import s cipy as sp
impor 七 p 4 f
de f up and out c a l l ( s 0 , x , T , r , s i gma , n s imu l a tion , ba r r i er ) :
n_steps = l O O .
dt=T/n_steps
total=O
for j i n range ( O , n_s imulation ) :
sT = s 0
out=Fa l s e
for i i n range ( O , int ( n_s tep s ) ) :
e = sp . random . norma l ( )
sT*= sp . exp ( ( r - 0 . S * si gma * s i gma ) *dt+s igma * e * sp . sqrt ( dt ) )
i f sT>ba r r i e r :
out = True
if out==Fa l s e :
\
t o t a l + = p4 f . bs_cal l ( s 0 , x , T , r , s i gma )
return tota l / n s imu l a t i on
模 拟股票价格的
变化路径 n 次, 如 100 次。 每次模 拟假定股票价格在给定时间段内有
I1.13 障 碍 式 期 权 的 平价 关 系 及其 图 形 演 示 289
s 0 =4 0 . # today s t o c k p r i c e
x= 4 0 . # exe r c i s e p r i c e
b a r r i e r = 4 2 # b a r r i e r l evel
T=0 . 5 # mat u r ity in yea r s
r = 0 . 0 5 # r i s k- free rate
s i gma= 0 . 2 # volati l i t y ( annua l i zed)
n_simulation l O O # numb e r o f simu l a tions
=
以下 代码计算 一个 向 下触发有效的障碍式看跌期权的价格 。
s 0= 4 0 . # today stock p r i ce
x 40 .
= # exercise price
barrier = 4 2 # barrier level
T= 0 . 5 # ma 七 u r i t y in years
r=0 . 0 5 # ris k - f re e rate
s i gma = 0 . 2 # vo l at i lit y ( annu a l i z e d )
n s imulation= l O O # number o f s imul at i ons
upOutCa l l , upi nCa l l = up_c a l l ( s O , x , T , r , s i gma , n_s imulati on , ba r r i e r )
print ' upOutCa l l = ' , round ( upOu 七 Cal l , 2 ) , ' upinCa l l = ' , round (up i nCal l , 2 )
print ' Bl a c k- S choles c a l l ' , round ( p4 f . bs_cal l ( s 0 , x , T , r , s i gma ) , 2 )
1 1 .13 障 碍 式 期 权 的 平价 关 系 及 其 图 形 演 示 291
以下输出结果证 明 了前面所述的等价关系。
upCa l l = 0 . 8 upinCa l l= 1 . 9 6
Blac k-Scho l e s c a l l 2 . 7 6
dt = T / n_s 七 eps
S = sp . zeros ( [ n_steps ] , dtype=float)
time_= range ( O , int ( n_s 七 eps ) , 1)
c = p4 f . bs_c a l l ( s 0 , x , T , r , s i gma )
sp . random . seed ( l 2 4 )
outTo 七 a l , inTotal= 0 . , 0 .
n out , n i n = 0 , 0
是 0 . 63 美元。 有 一 条模 拟
模 拟的股票 价格曲 线如图 1 1 - 1 3 所示。 普通看涨期权的价格
曲 线 中 股票价格达到触发价格, 向上 触发无效的欧式看涨期权的价格
是 4/5 X 0 .6 3 , 而向上
触发有效的欧式看 涨期权的价格是 1 /5 X 0.63 。
11.0
1
0
二 :>OlS
9
5
9.0
8,5
10 15 30
8.0
s
0
Total number of ste_!l_s =30
20 25
图 1 1-13
1 1 . 14 具有浮动 执行价格 的 回 望 式 期权 的 定价 293
下 面 的 Python 代 码 计 算 具 有浮 动 执 行 价 格 的 回 望 式 期 权 的 价 格 。
以 上 的 函 数 需 要用 到 SciPy 和 p4f 模块 , 必 须 在 调 用 函 数之 前 导 入 这 两 个 模块 , 代码
如下。
>>>import sc ipy as sp
>>>import p 4 f
>>>s= 4 0 . # today s to c k price
>>>T=0 . 5 # maturity i n years
>>>r = 0 . 0 5 # r i s k- f ree rate
>>>sigma=0 . 2 # vol a t i l i t y ( annua l i z e d )
>>>n_s imulation= l O O O # number o f s imu la 七 ions
>>>result=l ookback_min_pri ce_as_s t r i ke ( s , T , r , s igma , n_simu l a t ion )
>>>print ( ' lookback min price as s t r i ke = ' , round ( re s u l t , 3 ) )
一
运 行 以 上代码 次的结果如下。
294 第 11 章 蒙 特 卡 罗 模 拟 和 期 权定 价
lookback m i n p r i c e as s 七 r i ke = 5 . 3 0 4
1 1 . 1 5 使 用 Sobol 序 列 来提高效率
1 1 . 1 6 小结
练习题
2 . 调 试 以 下 代码 。
import s c i p y as sp
S O = 9 . 1 5 ; T =l ; n_s teps = l O ; mu = O . l S ; s i gma = 0 . 2
n s imu l a t i on = 1 0 ; dt =T /n_s teps
S = sp . zeros ( [ n_s 七eps ] , dtype = f l o a t )
x = range ( O , i n t ( n—steps ) , 1 )
for j i n range ( O , n_s imu l a t i o n ) :
S [ O] = SO
for i i n x [ : - 1 ] :
e=sp . random . normal ( )
S [ i +l ] =S [ i , j ] + S [ i ] * (mu- 0 . 5 *pow ( s i gma , 2 ) ) * d 七 + s i gma * S [ i ] * sp . s q r t ( d七 ) *e
plot ( x , S )
figtext ( 0 . 2 , 0 . 8 , ' S O = ' + s 七 r ( S O ) + ' , mu = ' + s t r (mu ) + ' , s i gma = ' + s t r ( s i gma ) )
figtext ( 0 . 2 , 0 . 7 6 , ' T = ' + str ( T ) + ' , s t ep s = ' + str ( i nt ( n_steps ) ) )
t i t l e ( ' S t o c k price ( number o f s imu la七ions = % d ' % n s imula七ion + ' ) ' )
x l abel ( ' To 七 a l number o f steps = ' + str ( n_step s ) ) )
ylabel ( ' s 七ock p r i c e ' ) ; show ( )
• 基于正 态 假 设 下波动率的度量
• 检验正态分布假 设
• Sortino ( 1 983) 提出的下偏标准方差 ( LPSD)
• 检验两 个时期段的波动率是否相等
• Breuscb 和 Pagan C l 979) 的异方差检验
. 计算波动率微笑 曲 线 的斜度和偏度
• 自 回 归 条 件异方差 (ARCH) 模型
\
• 模 拟 ARCH C l ) 时间序列
• 广义 自 回 归 条件异方差 CGARCH ) 模型
12.2 检验正 态 分 布 297
• 模 拟 GARCH C 1 , 1 ) 时间序列
1 2. 1 传统 的风险测度 - 标准方差
import numpy a s np
from matp lotl i b . f inance impo rt quotes_h i st orical_yahoo_ochl as getData
#
t i c ke r = ' I BM '
begdate= ( 2 0 0 9 , 1 , 1 )
enddate = ( 2 0 1 3 , 1 2 , 3 1 )
p =getData ( t ic ker , begdate , enddate , as obj e c t=True , adj u s t e d =True )
ret = p . a c l o s e [ l : ] /p . a c l o s e [ : - 1 ) - 1
std_annu a l =np . s td ( ret ) * np . sqrt ( 2 5 2 )
print ( ' vo l a t i l i t y ( s td) = ' , round ( s 七 d_annual , 4 ) )
1 2.2 检验正态分布
begdate= ( 2 0 0 9 , l , l )
enddate= ( 2 0 1 3 , 1 2 , 3 1 )
p =getData ( t icker , begdate , enddate , asobj ect=True , adj ust ed=True )
ret = p . a c l o s e [ l : ] /p . aclose [ : - 1 ] - l
结 果 如 图 1 2- 1 所 示 。
图 1 2- 1
Gumbel 分 布 等 。 调 用 该 函 数 并 打 印 测 试 结 果 , 显 示 如 下 。
( 1 2- D
n
其 ( 样 本 ) 方差 由 以 下 等 式 定 义 。 标准方 差是方差 的 平 方 根 。
1 2 .2 检验正 态分布 299
f (R; 一 时
i=I
a- = ( 1 2-2 )
n-1
由 以 下 公 式 定 义 的 偏 度 表 示 分 布 是否倾斜到左边或右边 。 对 称 分 布 的 偏度等于 0 。
L (R; - 时
i=I
skew = ( 1 2-3 )
( n - 1)矿
峰度 反 映 了 极 值 的 影 响 。 以 下 公 式 给 出 了 计 算 峰 度 的两种 定 义 , 区 别在 千 是 否 减 去 3 。
在等式 ( 1 2-5 ) 中 减 去 3 的 原 因 是 , 所 有 正 态 分 布 的 峰度 值等 于 3 。
L (R; 一 对
i=l
kurtosis = 0 2-4 )
( n - 1)矿
I (R; - 时
( excess)kurtosis = -3 ( 1 2-5 )
(n - 1)矿
ret=random . n ormal ( 0 , 1 , 5 0 0 0 0 )
print ( ' mean = ' , np . mean ( re t ) )
print ( ' s td = ' , np . std ( re t ) )
print ( ' s kewness = ' , stats . s kew ( re t ) )
print ( ' kur 七 o s i s = ' , s tats . kur t o s i s ( re t ) )
ret = p . a c l o s e [ l : ] /p . a c l o s e ( : - 1 ] - 1
print ( ' S & P S O O n = ' , l en ( r e t ) )
图 1 2-3
1 2.3 下偏标准方差
使用 回报率的标准方差来衡量风险的 一 个问题
是把正向的回 报 率也视为风险。 第 2 个
问题是以平均 值为中心来考虑偏差, 而 不是从 一 个固定的基准, 如无风险利率。 为了克服
这些缺点, S orti n o (1983)提出了下偏标准方差, 它定义为偏离无风险利 率的距 离平方 的
平 均值, 如下 式所示。
1 2.3 下 偏 标 准 方 差 301
L (R; - R/ )
2
i=I
LPSD = ' 其 中 R; - R1 > 0 C l 2-6 )
n-1
import numpy as np
import pandas a s pd
from s cipy import s tats
from ma七pl o t l i b . f i n ance impo rt quotes h i s t o r i c a l yahoo ochl as getData
302 第 12 章 波 动 率 和 GARCH 模 型
#
t i c k e r = ' I BM '
begdate = ( 2 0 0 9 , 1 , 1 )
enddate = ( 2 0 1 3 , 1 2 , 3 1 )
p =getData ( t i c ke r , begdate , enddate , a s obj ect = True , adj usted=True )
r e t = p . a c l o s e [ l : ) /p . a c l o s e [ : - 1 ) 一 1
date_=p . date
x=pd . DataFrame ( data=ret , index=date [ 1 : ) , co l umns = [ ' re t ' ) )
#
f f=pd . read主 i c k l e ( ' c : /七emp / f f Dai l y . pkl ' )
final=pd . me r ge ( x , f f , l e f t—index = True , r i ght_index = T rue )
#
k=final . re t - fi n a l . RF
k2=k [ k< O ]
LPS D=np . std ( k2 ) * np . sqr七 ( 2 5 2 )
prin七 ( " LP S D= " , L P S D )
p r i n t ( ' L P S D ( annua l i z ed) for ' , t i c k e r , ' i s ' , round ( L P S D , 3 ) )
( ' LPSD (annualized) for ', ' IBM', 'is ', 0. 1 46)
图 1 2-4
import numpy as n p
import s c ipy as sp
耳np o r t pandas as pd
f rom matp l ot l i b . finance import quotes —hi s \o r i c a l —yahoo_ochl as getData
#
# i nput a rea
ticker= ' F ' # stock
begdat e l = ( l 9 8 2 , 9 , l ) # s t a r t ing date for p e r i od 1
endda t e l = ( 1 9 8 7 , 9 , 1 ) # ending date f o r pe r i od 1
1 2 .5 利 用 Breusch 和 Pagan ( 1 979 ) 方 法 检 验 异 方 差 303
图 1 2-5
2
。
B, = y + r1 x, + v, ( 1 2-8 )
304 第 12 章 波 动 率 和 GARCH 模 型
1 n
BP = — IJv: ( 12-9 )
2 i=I
y, = x + errorl ( 12-11 )
3. 选择一 个 附近的服务器。
4. 单击屏幕左侧的包列 表。
import numpy as np
import s cipy as sp
import s tat smode l s . api as sm
#
de f breusch_pagan_te st ( y , x ) :
resul 七 s = sm . OLS ( y , x ) . f i t ( )
resid=r e s u l ts . re s i d
1 2.5 利 用 Breusch 和 Pagan ( 1 979 ) 方 法 检 验 异 方 差 305
n = l e n ( re s i d )
s i gma2 = sum ( r e s i d * * 2 ) /n
f = r e s i d * * 2 /s igma2 - 1
r e s u l t s 2 = sm . OLS ( f , x ) . fi t ( )
fv= r e s u l ts 2 . fi ttedvalues \
bp=0 . 5 * sum ( fv* * 2 )
df=resu l t s 2 . df mode l
p_va l ue = l - sp . s tats . chi . cdf ( bp , df )
return round ( b p , 6 ) , d f , round ( p_value , 7 )
#
sp . random . seed ( l 2 3 4 5 )
n= l O O
x= [ )
error l=sp . random . normal ( O , l , n )
e rror2=sp . random . norma l ( 0 , 2 , n )
for i in range ( n ) :
i f i % 2 == 1 :
x . append ( l )
else :
x . append ( - 1 )
#
yl=x+np . ar ray ( x ) + e r r o r l
y2=sp . ze r o s ( n )
#
for i in range ( n ) :
i f i 号 2==1 :
y2 [ i ) = x [ i ] + e r r o r l [ i )
else :
y2 [ i ] =x [ i ] +e rr o r 2 [ i )
图 1 2-6
import pandas a s pd
c a l l s =pd . r ead_p i c k l e ( " c : /temp / c a l ls Feb2 0 1 4 . pk l " )
p r i n t ( cal l s . head ( ) )
puts =pd . r ead_pick le ( " c : /t emp /puts Feb 2 0 1 4 . pk l " )
print ( put s . head ( ) )
输出结果 如 下 。
S t r i ke S ymbol Chg Bid Ask Vol Ope n Int
0 1 2 3 4
1 50 . 0 I BM1 4 0 2 2 2 C 0 0 1 5 0 0 0 0 0 . 00 2 8 . 20 3 1 . 8 5 2 17
1 60 . 0 I BM1 4 0 2 0 7 C 0 0 1 6 0 0 0 0 0 . 0 0 1 8 . 2 5 2 2 . 2 5 1 1
1 60 . 0 I BM 1 4 0 2 2 2 C O O 1 6 0 0 0 0 0 . 0 0 1 9 . 1 5 2 1 . 5 0 2 64
1 65 . 0 I BM 1 4 0 2 2 2C 0 0 1 6 5 0 0 0 0 . 0 0 1 4 . 6 5 1 6 . 65 1 57
170 . 0 I BM1 4 0 2 1 4 C 0 0 1 7 0 0 0 0 2 . 3 8 9 . 90 1 0 . 4 0 1 1 0 10
S 七 r i ke S ymbo l Chg B i d A s k Vol Open Int
0 1 2 3 4
1 00 . 0 I BM1 4 0 2 2 2 P0 0 1 0 0 0 0 0 0 . 0 NaN O . 03 16 16
1 05 . 0 I BM1 4 0 2 2 2 P 0 0 1 0 5 0 0 0 0 . 0 NaN O . Q.3 10 10
115. 0 I BM 1 4 0 2 2 2 P0 0 1 1 5 0 0 0 0 . 0 NaN O . 0 3 20 22
120 . 0 I BM1 4 0 2 2 2 P0 0 1 2 0 0 0 0 0 . 0 NaN O . 0 4 10 20
1 30 . 0 I BM1 4 0 2 2 2 P 0 0 1 3 0 0 0 0 0 . 0 NaN O . 0 4 68 203
格式 的数据集 。
import pandas a s pd
c a l l s = pd . read_table ( " c : / temp / i bmCa l l s 2 7 j an2 0 1 7 . t xt " )
p r i n t ( c a l l s . head ( ) ) \
c a l l s . to_p i c kl e ( " c : /temp/ ibmCal l s 2 7 j an2 0 1 7 . p kl " )
以下为输 出 结果。
S t r i ke S ymbo l Chg Bid As k Vol Open In七
0 150 . 0 I BM1 4 0 2 2 2 C 0 0 1 5 0 0 0 0 0 . 00 2 8 . 20 3 1 . 8 5 2 17
1 1 60 . 0 I BM1 4 0 2 0 7 C 0 0 1 6 0 0 0 0 0 . 0 0 1 8 . 2 5 2 2 . 2 5 1 1
2 1 60 . 0 I BM1 4 0 2 2 2 C 0 0 1 6 0 0 0 0 0 . 0 0 1 9 . 1 5 2 1 . 5 0 2 64
3 165 . 0 I BM1 4 0 2 2 2 C 0 0 1 6 5 0 0 0 0 . 0 0 1 4 . 6 5 1 6 . 6 5 1 57
4 170 . 0 I BM1 4 0 2 1 4 C 0 0 1 7 0 0 0 0 2 . 3 8 9 . 90 1 0 . 40 l l O 10
S七rike S ymbol C h g B i d As k Vo l Open I n 七
0 1 2 3 4
1 2.7 波 动 率 的 微笑 曲 线和 斜度
c= ( ca l l s . B i d [ i ] +call s . As k [ i ] ) /2 . 0
if C >0 :
p r i n t ( ' i= ' , i , ' , c= ' , c )
i f x ! =x o l d :
vol = imp l i e d_vol_cal l_mi n ( s , x , T , r , c )
\
s t r i ke . append ( x )
imp l i ed_vo l . append ( vo l )
ca1 1 2 . append ( c )
p r i n 七 x , c , vo l
x o ld=x
#
# S tep 5 : draw a smile
p l t . t i t l e ( ' S kewn e s s smi l e ( s kew) ' )
pl t . x l ab e l ( ' Exe r c i s e P r i c e ' )
pl t . ylabel ( ' Imp l ied Vol a t i l i t y ' )
pl t . plot ( s t r i k e , impl ied_vol , ' o ' )
plt . show ( )
LO
Skewness smile (吐如)
09
.
0.8
右 0.7
.
I
06
Jo
s .
o., ,. ..
... . .
l
o.坛
160 170 180
Ex<IKIH Pric 愈
190 200 210
图 1 2-7
1 2.8 波动率集聚效应 的 图 形表 示
股票 价格的
变化有一 个普遍存在的现象, 被称为波动率的集聚效应, 它是指价格
变化
310 第 12 章 波 动 率 和 GARCH 模 型
impor 七 numpy as np
import matp lo t l ib . pyplot a s p l t
from matpl o 七 l ib . fi nance import quotes historica l yahoo ochl as getData
#
t i c ke r= ' " GSPC '
begdate= ( l 9 8 7 , l l , l )
endda te= ( 2 0 0 6 , 1 2 , 3 1 )
#
p = getData ( 七 i c ke r , begda t e , enddate , a s ob j ect =True , adj u s ted=True )
x=p . date [ l : ]
re七 = p . aclose [ l : ] /p . a c l o s e [ : - 1 ] - l
#
p l t . t i t l e ( ' I l l ustr at ion o f v o l a t i l i t y cluster i ng ( S & P S O O ) ' )
pl t . y l abe l ( ' D a i l y returns ' )
pl 七 . xlab e l ( ' Date ' )
pl t . plot ( x , r e 七 )
pl 七 . show ( )
以 上代码绘制 的 图 形如 图 12-8 所 示 。
0.06
Illustration of volatility clustering (S&PSOO)
0.04
o o -
0200020406
sEn1
a,�l
o -
!•O
o -
o
图 1 2-8
误差项的平方, q 是误差项的阶数。 当 q 为 1 时, 有最
简单的 ARCH C l ) 过程如下。
a,-, = a + a, e,一 1
。 ( 1 2- 1 4 )
2
import s c i py as sp
import matplo 七 l ib . pyplot as p l t
#
sp . random . seed ( l 2 3 4 5 )
n= l O O O # n i s the number of obs ervations
nl=lOO Jt we need to drop the f i r s t seve ral observations
n2=n+nl Jt sum of two numbers
#
a = ( 0 . 1 , 0 . 3 ) # ARCH ( 1 ) coe f fi cients alphaO and a lpha l , see Equation ( 3 )
er rors=sp . random . normal ( O , l , n2 )
t=sp . z eros ( n 2 )
七 [ O ] =sp . random . no rma l ( O , sp . sqrt ( a [ 0 ) / ( 1 -a [ l ) ) ) , l )
for i i n range ( l , n2 - l ) :
t [ i ) =err ors [ i ) * sp . s qr t ( a [ O ) +a [ l ) * t [ i - 1 ) * * 2 )
y=t [ n l - 1 : - 1 ] # drop the f i r s t n l obse rvat ions
#
plt . t i t l e ( ' ARCH ( 1 ) process ' )
x=range ( n )
plt . plot ( x , y )
plt . show ( )
1.5
ARCH (l) process
1.0 卜
0.5
0. 0
-0.5
-1.0
-1.5
200 400 600 800 1000
图 1 2-9
1 2. 1 0 GARCH ( 广义 ARCH ) 模型
广义 自 回 归 条件异方差 ( GARCH ) 是 ARCH 的重要扩展, 由 Bollerslev ( 1 986 ) 提 出 。
GARCH(p,q)模 型 的 数 学 公 式 如 下 。
q p
式 =a 。 + Ii=I ai 斗 +Li=I fJi=I CY,2一 l ( 1 2- 1 5 )
aI = aO + aI E1 - 1 +/30-,2一l
2 2
( 1 2- 1 6 )
import s c ipy as sp
import matp l o 七 l ib . pyp l o t a s plt
#
sp . random . s e ed ( 1 2 3 4 5 )
n= l O O O # n i s 七 he number o f obs e rvations
nl=lOO # we need to drop the f i r s 七 seve r a l obs e rvations
n2=n+nl # sum of two numbers
#
1 2. 1 0 GARCH ( 广 义 ARCH ) 模 型 31 3
a= ( 0 . 1 , 0 . 3 ) it ARCH co e f f i c i e n t
alpha= ( 0 . 1 , 0 . 3 ) it GARCH ( 1 , 1 ) coe f f i c i e n t s alphaO a n d alpha l , s e e
it Equatio n ( 3 )
beta=0 . 2
e r rors=sp . random . n o rmal ( 0 , lv n2 )
t=sp . z eros ( n 2 )
七 [ O ) =sp . random . normal ( O , s p . sqrt ( a [ 0 ] / ( 1 - a [ l ] ) ) , 1 )
#
for i in range ( 1 , n2 - 1 ) :
t [ i ) =e r rors [ i ) * s p . sqrt ( al pha [ O ] +a lpha [ l ] * e r r o r s [ i - 1 ) * * 2 + b e t a * t
[ 七 1 ) * *2 )
#
y=t [ n l - 1 : - 1 ] it drop the f i r s t n l obs e rvations
plt . t i t l e ( ' GARCH ( 1 , 1 ) process ' )
x=ran ge ( n )
p l t . plot ( x , y )
p l t . show ( )
GARCH ( 1 . 1 ) process
。
-l
-2
-3
0 200 400 600 800 1000
图 1 2- 1 0
包下的CRAN 。
2 . 单击下 载软 件
3. 选择一 个 离 得近的服务 器 。
314 第 12 章 波 动 率 和 GARCH 模 型
4 . 单击屏 幕左侧的包列 表。
import scipy as sp
import numpy as np
import matp l ot l i b . pyplot as p l t
#
sp . random . seed ( 1 2 3 4 5 )
m= 2
n = l O O # n i s the number o f obs e rvations
nDrop=l O O # we need to drop 七he f i r s 七 s eve r a l observations
de l ta = 2
omega= l e - 6
a lpha= ( 0 . 0 5 , 0 . 0 5 )
#
beta = 0 . 8
mu , ma , a r = 0 . 0 , 0 . 0 , 0 . 0
gamma = ( 0 . 0 , 0 . 0 )
or der_ar = s p . s i z e ( a r )
orde r_ma=sp . s i z e (ma )
order_be七a=sp . s i z e ( beta)
#
order_a lpha =sp . s i z e ( a lpha )
z O =sp . random . s t andard_norma l (n +nDrop )
de lt ainv= l /delta
spec_l =np . a r ra y ( [ 2 ] )
spe c_2 = np . a r ray ( [ 2 ] )
spec_3=np . ar r ay ( [ 2 ] )
z = np . h s t a c k ( ( spec_l , z O ) )
t = np . z e r o s ( n +nDrop )
h = np . hstack ( ( spec_2 , 七 ) )
y = np . hstack ( ( spec_3 , t ) )
eps O = h * * de l tainv * z
for i in r ange ( m+ l , n +nDrop+m- 1 ) :
t l = s um ( alpha [ : : - l ] * ab s ( eps O [ i -2 : i ] ) ) # reve r s e
\
al pha =alpha [ : : - 1 ]
t2=eps 0 [ i - orde r_a lpha - 1 : i-1 ]
t 3=t 2 * t 2
t 4 =np . dot ( gamma , t 3 . T )
tS=sum (beta* h [ i- orde r_beta : i - 1 ] )
h [ i ] = omega+t l - t 4 + t S
12. 1 0 GARCH ( 广 义 ARCH ) 模 型 315
\
s i gma = h [ nDrop+l : ] * * 0 . 5
eps = epsO [ n Drop + l : ]
x=range ( l , l en ( garch) + l )
#
plt . plot ( x , garch, ' r ' )
p l t . p l ot ( x , s i gm a , ' b ' )
pl t . t i t l e ( ' GARCH ( 2 , 1 ) proce s s ' )
p l t . figtext ( 0 . 2 , 0 . 8 , ' omega = ' + s 七 r ( omega ) + ' , alpha = ' +s t r ( a lpha ) + ' , beta= '
+ s 七 r (beta ) )
p l 七 . f i gtext ( 0 . 2 , 0 . 7 5 , ' gamma = ' + s 七 r ( gamma ) )
p l t . f i gtext ( 0 . 2 , 0 . 7 , ' mu = ' + s 七 r (mu) + ' , ar = ' + s t r ( a r ) + ' , ma = ' +s 七 r ( ma ) )
pl t . show ( )
GARCH(2,l) process
-l
-2
衬 20 40 60 80 100
图 1 2- 1 1
式 = w + a吐 + 如嘉 + r 弘 1,-1 0 2- 1 7 )
impor七 numpy as np
from numpy . linalg import i nv
import matp l o t l ib . pyp l o t as p l t
fr om matp l o t l i b . mlab import csv2rec
from s c ipy . optimi ze import fmin_s l s qp
from numpy import s i z e , log , p i , s um , d i f f , a r r a y , zeros , diag, dot , mat ,
asarray, s qr t
#
de f gj r_garch_ l i k e l ihood ( parameters , data , s i gma2 , ou七=None ) :
mu = pa ramet e rs [ O ]
omega = parame 七e rs [ l ]
al pha = pa rameters [ 2 ]
gamma = parameters [ 3 ]
beta = p a ramete rs [ 4 ]
T = s i z e ( data , 0 )
eps = data-mu
for t in xr ange ( l , T ) :
s igma2 [ t ] = ( omega+alpha * eps [ t - 1 ] * * 2 +gamma * ep s [ 七 一 1 ] * * 2 * ( eps [ t- 1 ]
< O ) +beta * s i gma2 [ t - 1 ] )
logl i k s = O . S * ( l og ( 2 * p i ) + log ( s i gma2 ) + eps * * 2 / s igma2 )
l o g l i k = sum ( l ogl i k s )
i f out i s None :
return logl i k
else :
return l og l i k , logl i k s , copy ( s i gma2 )
#
de f g j r constraint ( paramet e r s , data , s i gma2 , ou七 = Non e ) :
al pha = pa ramet e r s [ 2 ]
gamma = parameters [ 3 ]
beta = parameters [ 4 ]
return arra y ( [ 1 -a lpha-gan订na / 2 -beta ] ) # Constraint a lpha+gamma / 2 +beta<=l
#
K = s i ze ( thet a , O )
h = np . diag ( h )
fp = z e r o s ( K )
fm = zeros ( K)
for i i n xr ange ( K ) : \
fp [ i ] = fun ( t heta+h [ i ) , * args )
fm [ i ) = fun ( theta-h [ i ) , * a r g s )
fpp = z e ros ( ( K , K ) )
fmm = z e ro s ( ( K , K ) )
for i in xra nge ( K ) :
for j i n x r ange ( i , K ) :
fpp [ i , j ] = fun ( theta + h [ i ] + h [ j ] , * a r g s )
fpp [ j , i ) = fpp [ i , j )
fmm [ i , j ) = fun ( theta-h [ i ) -h [ j ) , * a rgs )
fmm [ j , i J = fmm [ i , j J
hh = ( diag ( h ) )
hh = hh . re shape ( ( K , 1 ) )
hh = dot ( hh , hh . T )
H = z e r o s ( ( K , K) )
for i i n xra nge ( K ) :
for j i n xrange ( i , K ) :
H [ i, j ) = ( fpp [ i , j ) - fp [ i ) - fp [ j ) + f+ f - fm [ i ) - fm [ j ) + fmm [ i , j ) ) /hh
[ i , j J /2
H [j , i) = H [ i , j )
return H
编写 一 个 名为 GJR_GARCH() 的 函 数 , 用 来 包 含 所 有 初 始 值 、 约 束 和 边 界 条件 , 代
码如下。
de f GJR_GARCH ( r e t ) :
import numpy as np
import scipy . op豆m i z e as op
s t a rtV=np . a rray ( [ r e t . mean ( ) , ret . var ( ) * O . 0 1 , 0 . 0 3 , 0 . 0 9 , 0 . 9 0 ] )
f i nfo=np . f i n fo ( np . f l oa t 6 4 )
t= ( 0 . 0 , 1 . 0 )
bounds= [ ( - 1 O * ret . mean ( ) , l O * ret . mean ( ) ) , ( f in f o . eps , 2 * r e t . va r ( ) ) ,
七, t, t]
T = np . s i z e ( r e t , O )
s i gma2 = np . repeat ( re七 . var ( ) , T )
inV= ( ret , s i gma2 )
return op . fmi n_s l s qp ( g j r_garch_l i ke l ihood , s t a r tV, f_i eqc o n s =gj r_
con s t r a i n七 , bounds =bounds , a rgs = inV)
31 8 第 12 章 波 动 率 和 GARCH 模 型
sp . r andom . s e e d ( 1 2 3 4 5 )
returns = sp . random . uni form ( - 0 . 2 , 0 . 3 , 1 0 0 )
tt=GJR_GARCH ( r eturns )
函数的运算结果 如图 1 2- 1 2
GJR_GARCH() 所示。
print(tt)
Optimization terminated successfully. (Exit mode 0)
Current function value: -54.0664733 1 28
Iterations: 1 2
Function evaluations: 94
Gradient evaluations: 1 2
图 1 2- 1 2
这 5 个输出结果的含义如表 1 2- 1 所示。
表 1 2-1
#
含义
描述优化程序的 退 出 模式
2
目 标 函 数 的最终值
3
迭代次数
4
目 标 函 数 计 算次数
5
梯 度 函 数 计算 次 数
表 1 2-2
退 出 模式 说明
。
-I 需要 计算梯度 函 数 Cg 和 a )
优化 已成功终止
需 要 计 算 目 标 函 数 (f和 c)
2
续表
退 出 模式 说明
不等式约 束条件不兼容
6 在 L S Q 子程序 中 矩 阵 C 是奇异矩阵
8 线搜索 中 方 向 导 数 为 正
9 超 过 了 迭代次数 的 限 制
最终的运算结果如下 。
>>>pr int tt
[ 7 . 7 3 95 8 5 8 3 e - 0 2 6 . 65856138e-03 1 . 0 0 3 8 6 1 5 6e - 1 2 -1 . 671 15250e-12
6 . 6 1 9 4 7 97 7 e- 0 1 ]
>>>
1 2. 1 1 小结
练习题
1 . 波动率的定义是 什么 ?
2 . 如何衡量风险(波 动 率 ) ?
320 第 12 章 波 动 率 和 GARCH 模 型
3. 标准方差 被广泛用来衡量风险是否有不当之处?
5 . 下偏标准方差如何定义 ? 有什么应用?
6. 选择 5 只 股票, 如 DEL
L、I BM、 微软 ( M SFT )、 花旗集团 (C)和沃尔玛 (WMT)
,
并使用过去 3年的每 日数据比较它们的标准方差与LP SD 。
7. 股票的波 动 率是否随时间变化 ?
8. 使用 Breu sch-P ag an ( 1 9 79)方法来检验 I BM 日 回报率的分布是否随时间变化 。
9 . 如何检验股票的波 动 率是否随时间改变?
1 1 . 如何下 载 期权数据 ?
缅写一个适用千个人理财和公司财务的金融计算器;
从网站抓取股票历史价格和其他经济金融数据 ;
计算个股或组合的 回 报率 、 方差和在险价值等
统计量 ;
构邃最优的投资组合;
计算隐含波动 率井绘制波动率的 微 笑 曲 线 ;
估计波动率的时间序列模型 ;
计算买卖价差等流动性指标 。
。
7
8
7
1
1—
5,
4—
5
7
7
3
1
s
B—
N
-11
0'
',_冒
,',
',
。
5
7
7
9
3
7
8
7
1
1
4
5