Python 金融编程第二版(GPT 重译)(三)(1)

简介: Python 金融编程第二版(GPT 重译)(三)

第六章:面向对象编程

软件工程的目的是控制复杂性,而不是创建它。

Pamela Zave

介绍

面向对象编程(OOP)是当今最流行的编程范式之一。正确使用时,它与过程式编程相比提供了许多优势。在许多情况下,OOP  似乎特别适用于金融建模和实施金融算法。然而,也有许多对 OOP 持批评态度的人,对 OOP  的单个方面甚至整个范式表示怀疑。本章对此持中立态度,认为 OOP  是一个重要的工具,可能不是每个问题的最佳解决方案,但应该是程序员和从事金融工作的量化人员的手头工具之一。

随着 OOP 的出现,一些新的术语也随之而来。本书和本章的最重要术语是(更多细节如下):

对象类的抽象定义。例如,一个人类。

属性

类的特性(类属性)或类的实例(实例属性)的一个特征。例如,是哺乳动物或眼睛的颜色。

方法

可以在类上实现的操作。例如,行走。

参数

一个方法接受的输入参数以影响其行为。例如,三个步骤。

对象

类的一个实例。例如,有蓝眼睛的 Sandra。

实例化

创建基于抽象类的特定对象的过程。

转换为 Python 代码,实现人类示例的简单类可能如下所示。

In [1]: class HumanBeing(object):  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
            def __init__(self, first_name, eye_color):  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
                self.first_name = first_name  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
                self.eye_color = eye_color  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
                self.position = 0  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
            def walk_steps(self, steps):  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
                self.position += steps  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/7.png)


类定义语句。


在实例化时调用的特殊方法。


名字属性初始化为参数值。


眼睛颜色属性初始化为参数值。


位置属性初始化为 0。


使用steps作为参数的步行方法定义。


给定steps值后改变位置的代码。

根据类定义,可以实例化并使用一个新的 Python 对象。

In [2]: Sandra = HumanBeing('Sandra', 'blue')  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [3]: Sandra.first_name  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[3]: 'Sandra'
In [4]: Sandra.position  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[4]: 0
In [5]: Sandra.walk_steps(5)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
In [6]: Sandra.position  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
Out[6]: 5


实例化。


访问属性值。


调用方法。


访问更新后的position值。

有几个人类方面可能支持使用 OOP:

自然的思考方式

人类思维通常围绕着现实世界或抽象对象展开,比如汽车或金融工具。面向对象编程适合模拟具有其特征的这类对象。

降低复杂性

通过不同的方法,面向对象编程有助于降低问题或算法的复杂性,并逐个特征进行建模。

更好的用户界面

在许多情况下,面向对象编程可以实现更美观的用户界面和更紧凑的代码。例如,当查看NumPyndarray类或pandasDataFrame类时,这一点变得显而易见。

Python 建模的方式

独立于面向对象编程的优缺点,它只是 Python 中的主导范式。这也是“在 Python 中一切皆为对象。”这句话的由来。面向对象编程还允许程序员构建自定义类,其实例的行为与标准 Python 类的任何其他实例相同。

也有一些技术方面可能支持面向对象编程:

抽象化

使用属性和方法可以构建对象的抽象、灵活的模型——重点放在相关的内容上,忽略不需要的内容。在金融领域,这可能意味着拥有一个以抽象方式模拟金融工具的通用类。这种类的实例将是由投资银行设计和提供的具体金融产品,例如。

模块化

面向对象编程简化了将代码拆分为多个模块的过程,然后将这些模块链接起来形成完整的代码基础。例如,可以通过一个类或两个类来建模股票上的欧式期权,一个用于基础股票,另一个用于期权本身。

继承

继承指的是一个类可以从另一个类继承属性和方法的概念。在金融领域,从一个通用的金融工具开始,下一个级别可能是一个通用的衍生金融工具,然后是一个欧式期权,再然后是一个欧式看涨期权。每个类都可以从更高级别的类中继承属性和方法。

聚合

聚合指的是一个对象至少部分由多个其他对象组成,这些对象可能是独立存在的。模拟欧式看涨期权的类可能具有其他对象的属性,例如基础股票和用于贴现的相关短期利率。表示股票和短期利率的对象也可以被其他对象独立使用。

组合

组合与聚合类似,但是这里的单个对象不能独立存在。考虑一个定制的固定利率互换合同和一个浮动利率互换合同。这两个腿不能独立于互换合同本身存在。

多态性

多态性可以呈现多种形式。在 Python 上下文中特别重要的是所谓的鸭子类型。这指的是可以在许多不同类及其实例上实现标准操作,而不需要准确知道正在处理的特定对象是什么。对于金融工具类,这可能意味着可以调用一个名为 get_current_price() 的方法,而不管对象的具体类型是什么(股票、期权、互换等)。

封装

此概念指的是仅通过公共方法访问类内部数据的方法。模拟股票的类可能有一个属性 current_stock_price。封装将通过方法 get_current_stock_price() 提供对属性值的访问,并将数据隐藏(使其私有化)。这种方法可能通过仅使用和可能更改属性值来避免意外效果。但是,对于如何使数据在 Python 类中私有化存在限制。

在更高层面上,软件工程中的两个主要目标可以总结如下:

可重用性

继承和多态等概念提高了代码的可重用性,增加了程序员的效率和生产力。它们还简化了代码的维护。

非冗余性

与此同时,这些方法允许构建几乎不冗余的代码,避免双重实现工作,减少调试和测试工作以及维护工作量。它还可能导致更小的总体代码基础。

本章按如下方式组织:

“Python 对象概览”

下一节将通过面向对象编程的视角简要介绍一些 Python 对象。

“Python 类基础”

本节介绍了 Python 中面向对象编程的核心要素,并以金融工具和投资组合头寸为主要示例。

“Python 数据模型”

本节讨论了 Python 数据模型的重要元素以及某些特殊方法所起的作用。

Python 对象概览

本节通过面向对象编程程序员的眼光简要介绍了一些标准对象,这些对象在前一节中已经遇到过。

int

为了简单起见,考虑一个整数对象。即使对于这样一个简单的 Python 对象,主要的面向对象编程(OOP)特征也是存在的。

In [7]: n = 5  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [8]: type(n)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[8]: int
In [9]: n.numerator  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[9]: 5
In [10]: n.bit_length()  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
Out[10]: 3
In [11]: n + n  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
Out[11]: 10
In [12]: 2 * n  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
Out[12]: 10
In [13]: n.__sizeof__()  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/7.png)
Out[13]: 28


新实例 n


对象的类型。


一个属性。


一个方法。


应用 + 运算符(加法)。


应用 * 运算符(乘法)。


调用特殊方法__sizeof__()以获取内存使用情况(以字节为单位)。¹

列表

list对象有一些额外的方法,但基本上表现方式相同。

In [14]: l = [1, 2, 3, 4]  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [15]: type(l)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[15]: list
In [16]: l[0]  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[16]: 1
In [17]: l.append(10)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
In [18]: l + l  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
Out[18]: [1, 2, 3, 4, 10, 1, 2, 3, 4, 10]
In [19]: 2 * l  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
Out[19]: [1, 2, 3, 4, 10, 1, 2, 3, 4, 10]
In [20]: sum(l)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/7.png)
Out[20]: 20
In [21]: l.__sizeof__()  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/8.png)
Out[21]: 104


新实例l


对象的类型。


通过索引选择元素。


一个方法。


应用+运算符(连接)。


应用*运算符(连接)。


应用标准 Python 函数sum()


调用特殊方法__sizeof__()以获取内存使用情况(以字节为单位)。

ndarray

intlist对象是标准的 Python 对象。NumPyndarray对象是一个来自开源包的“自定义”对象。

In [22]: import numpy as np  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [23]: a = np.arange(16).reshape((4, 4))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
In [24]: a  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[24]: array([[ 0,  1,  2,  3],
                [ 4,  5,  6,  7],
                [ 8,  9, 10, 11],
                [12, 13, 14, 15]])
In [25]: type(a)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[25]: numpy.ndarray


导入numpy


新实例a


对象的类型。

尽管ndarray对象不是标准对象,但在许多情况下表现得就像是一个标准对象——这要归功于下文中解释的 Python 数据模型。

In [26]: a.nbytes  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[26]: 128
In [27]: a.sum()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[27]: 120
In [28]: a.cumsum(axis=0)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[28]: array([[ 0,  1,  2,  3],
                [ 4,  6,  8, 10],
                [12, 15, 18, 21],
                [24, 28, 32, 36]])
In [29]: a + a  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
Out[29]: array([[ 0,  2,  4,  6],
                [ 8, 10, 12, 14],
                [16, 18, 20, 22],
                [24, 26, 28, 30]])
In [30]: 2 * a  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
Out[30]: array([[ 0,  2,  4,  6],
                [ 8, 10, 12, 14],
                [16, 18, 20, 22],
                [24, 26, 28, 30]])
In [31]: sum(a)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
Out[31]: array([24, 28, 32, 36])
In [32]: np.sum(a)  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/7.png)
Out[32]: 120
In [33]: a.__sizeof__()  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/8.png)
Out[33]: 112


一个属性。


一个方法(聚合)。


一个方法(没有聚合)。


应用+运算符(加法)。


应用*运算符(乘法)。


应用标准 Python 函数sum()


应用NumPy通用函数np.sum()


调用特殊方法__sizeof__()以获取内存使用情况(以字节为单位)。

DataFrame

最后,快速查看pandasDataFrame对象,因为其行为大多与ndarray对象相同。首先,基于ndarray对象实例化DataFrame对象。

In [34]: import pandas as pd  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [35]: df = pd.DataFrame(a, columns=list('abcd'))  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
In [36]: type(df)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[36]: pandas.core.frame.DataFrame


导入pandas


新实例df


对象的类型。

其次,查看属性、方法和操作。

In [37]: df.columns  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[37]: Index(['a', 'b', 'c', 'd'], dtype='object')
In [38]: df.sum()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[38]: a    24
         b    28
         c    32
         d    36
         dtype: int64
In [39]: df.cumsum()  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[39]:     a   b   c   d
         0   0   1   2   3
         1   4   6   8  10
         2  12  15  18  21
         3  24  28  32  36
In [40]: df + df  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
Out[40]:     a   b   c   d
         0   0   2   4   6
         1   8  10  12  14
         2  16  18  20  22
         3  24  26  28  30
In [41]: 2 * df  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
Out[41]:     a   b   c   d
         0   0   2   4   6
         1   8  10  12  14
         2  16  18  20  22
         3  24  26  28  30
In [42]: np.sum(df)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
Out[42]: a    24
         b    28
         c    32
         d    36
         dtype: int64
In [43]: df.__sizeof__()  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/7.png)
Out[43]: 208


一个属性。


一个方法(聚合)。


一个方法(无聚合)。


应用+运算符(加法)。


应用*运算符(乘法)。


应用NumPy通用函数np.sum()


调用特殊方法__sizeof__()以获取以字节为单位的内存使用情况。


Python 金融编程第二版(GPT 重译)(三)(2)https://developer.aliyun.com/article/1559330

相关文章
|
2天前
|
存储 机器学习/深度学习 关系型数据库
Python 金融编程第二版(四)(5)
Python 金融编程第二版(四)
8 0
|
2天前
|
存储 SQL 数据库
Python 金融编程第二版(四)(4)
Python 金融编程第二版(四)
8 0
|
2天前
|
SQL 存储 数据库
Python 金融编程第二版(四)(3)
Python 金融编程第二版(四)
8 0
|
2天前
|
存储 分布式计算 数据可视化
Python 金融编程第二版(四)(2)
Python 金融编程第二版(四)
10 0
|
2天前
|
存储 SQL 数据可视化
Python 金融编程第二版(四)(1)
Python 金融编程第二版(四)
9 0
|
2天前
|
数据可视化 Python
Python 金融编程第二版(三)(4)
Python 金融编程第二版(三)
12 2
|
2天前
|
存储 索引 Python
Python 金融编程第二版(二)(1)
Python 金融编程第二版(二)
9 2
|
2天前
|
存储 算法 数据建模
Python 金融编程第二版(一)(5)
Python 金融编程第二版(一)
13 2
|
2天前
|
存储 数据可视化 API
Python 金融编程第二版(三)(5)
Python 金融编程第二版(三)
8 1
|
2天前
|
存储 数据可视化 索引
Python 金融编程第二版(三)(3)
Python 金融编程第二版(三)
11 1