Python金融大数据分析——第13章 面向对象 笔记

第13章 面向对象和图形用户界面

13.1 面向对象

13.1.1 Python类基础知识

class ExampleOne(object):
    pass


class ExampleTwo(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b


c = ExampleTwo(1, 'text')
c.a
# 1
c.b
# 'test'
c.a = 100
c.a
# 100


# 对象的属性可以在实例化之后定义


c = ExampleOne()
c.first_name = 'Jason'
c.last_name = 'Bourne'
c.movies = 4
print(c.first_name, c.last_name, c.movies)


# Jason Bourne 4

class ExampleThree(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def addition(self):
        return self.a + self.b


c = ExampleThree(10, 15)
c.addition()
# 25
c.a += 10
c.addition()
# 35

# 继承
class ExampleFour(ExampleTwo):
    def addition(self):
        return self.a + self.b


c = ExampleFour(10, 15)
c.addition()
# 25


# Python 允许多重继承。然而,应该小心处理可读性和可维护性,特别是供其他人使用时
class ExampleFive(ExampleFour):
    def multiplication(self):
        return self.a * self.b


c = ExampleFive(10, 15)
c.addition()
# 25
c.multiplication()
# 150


# 自定义方法定义不一定要包含在类定义中。 它们可以放在其他位置, 只要它们处于全局命名空间, 就可以在类定义中使用
def multiplication(self):
    return self.a * self.b


class ExampleSix(ExampleFour):
    multiplication = multiplication


c = ExampleSix(10, 15)
c.addition()
# 25
c.multiplication()
# 150

class ExampleSeven(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.__sum = a + b

    multiplication = multiplication

    def addition(self):
        return self.__sum


c = ExampleSeven(10, 15)
c.addition()
# 25

# 不能直接访问私有属性sum。但是, 通过如下语法仍然可以做到:
c._ExampleSeven__sum
# 25

c.a += 10
c.a
# 20

c.multiplication()
# 300


class sorted_list(object):
    def __init__(self, elements):
        self.elements = sorted(elements)  # sorted list object

    def __iter__(self):
        self.position = -1
        return self

    def __next__(self):
        if self.position == len(self.elements) - 1:
            raise StopIteration
        self.position += 1
        return self.elements[self.position]


name_list = ['Sandra', 'Lilli', 'Guido', 'Zorro', 'Henry']
for name in name_list:
    print(name)
# Sandra
# Lilli
# Guido
# Zorro
# Henry

sorted_name_list = sorted_list(name_list)
for name in sorted_name_list:
    print(name)

# Guido
# Henry
# Lilli
# Sandra
# Zorro

type(sorted_name_list)
# __main__.sorted_list

13.1.2 简单的短期利率类

在连续折现的固定短期利率世界中,日期 t>0 时的未来现金流与当前日期 t=0 之间的折现因子定义为: D 0 ( t ) = e r t

import numpy as np


def discount_factor(r, t):
    """
    Function to calculate a discount factor.
    :param r: float
    positive, constant short rate
    :param t: float
    future date(s), in fraction of years:;
    e.g. 0.5 means half a year from now
    :return:float
    discount factor
    """
    # use of NumPy universal function for vectorization
    df = np.exp(-r * t)
    return df


import matplotlib.pyplot as plt

# 不同短期利率在5年内的折现因子
t = np.linspace(0, 5)
for r in [0.01, 0.05, 0.1]:
    plt.plot(t, discount_factor(r, t), label='r= %4.2f' % r, lw=1.5)
plt.xlabel('years')
plt.ylabel('discount factor')
plt.grid(True)
plt.legend(loc=0)

不同短期利率在5年内的折现因子

上图展示了5年内不同固定短期利率下折现因子的表现。t=0时的折现因子都等于1;也就是说, 当日现金流 “没有折现”。如果短期利率为10%, 5 年后到期的现金流将被折算为略高于0.6个货币单位(即60%)。

# 基于类的实现方法
class short_rate(object):
    """
    Class to model a constant shrot rate object.
    """

    def __init__(self, name, rate):
        """
        :param name: string
        name of the object
        :param rate: float
        positive, constant short rate 
        """
        self.name = name
        self.rate = rate

    def get_discount_factors(self, time_list):
        """
        获取折现因子
        :param time_list: list/array-like
        :return:
        """
        time_list = np.array(time_list)
        return np.exp(-self.rate * time_list)


sr = short_rate('r', 0.05)
sr.name, sr.rate
# ('r', 0.05)

# 包含年分数的时间列表
time_list = [0.0, 0.5, 1.0, 1.25, 1.75, 2.0]
sr.get_discount_factors(time_list)
# array([1.        , 0.97530991, 0.95122942, 0.93941306, 0.91621887,
#        0.90483742])

# 生成图表
for r in [0.025, 0.05, 0.1, 0.15]:
    sr.rate = r
    plt.plot(t, sr.get_discount_factors(t), label='r=%4.2f' % sr.rate, lw=1.5)
plt.xlabel('year')
plt.ylabel('discount factor')
plt.grid(True)
plt.legend(loc=0)

不同短期利率在5年内的折现因子

通常, 折现因子 “ 只是” 达到某种目的的手段。例如, 你可能想要用它们计算未来现金流的现值。利用我们的短期利率对象, 在已知现金流和出现日期 / 时间的情况下, 这是很容易做到的。 考虑如下现金流示例, 在例子中包含今天的负现金流和经过一年及两年之后的正现金流, 这可能是某种投资机会的现金流配置:

sr.rate = 0.05
cash_flows = np.array([-100, 50, 75])
time_list = [0.0, 1.0, 2.0]
# 折现因子
disc_facts = sr.get_discount_factors(time_list)
disc_facts
# array([1.        , 0.95122942, 0.90483742])

# 现金流乘以折现因子就可以得到所有现金流的现值
disc_facts * cash_flows
# array([-100.        ,   47.56147123,   67.86280635])

投资理论中的典型决策原则之一是,决策者应该在给定(短期)利率(表示投资的机会成本)下净现值(NPV)为正数的项目上投资。在我们的例子中, NPV就是简单地加总单个现值:

# net present value
np.sum(disc_facts * cash_flows)
# 15.424277577732667

sr.rate = 0.15
np.sum(sr.get_discount_factors(time_list) * cash_flows)
# -1.403234627618268

显然, 在短期利率为5%时应该做出投资。 对于15%的利率,此时NPV 变成负数, 不应该进行投资。

13.1.3 现金流序列类

定义一个现金流序列的模型。这个类提供方法,返回给定现金流系列(即现金流价值和日期/时间)现值和净现值的列表数

class cash_flow_series(object):
    """
    Class to model a cash flow series.
    """

    def __init__(self, name, time_list, cash_flows, short_rate):
        """
        :param name: string
         name of the object
        :param time_list: list/array-like
        list of (positive) year fractions
        :param cash_flows: list/array-like
        corresponding list of cash flow values
        :param short_rate: instance of short_rate class
        short rate object used for discounting
        """
        self.name = name
        self.time_list = time_list
        self.cash_flows = cash_flows
        self.shrt_rate = short_rate

    def present_value_list(self):
        df = self.shrt_rate.get_discount_factors(self.time_list)
        return np.array(self.cash_flows) * df

    def net_presnt_value(self):
        return np.sum(self.present_value_list())


sr.rate = 0.05
cfs = cash_flow_series('cfs', time_list, cash_flows, sr)
cfs.cash_flows
# array([-100,   50,   75])
cfs.time_list
# [0.0, 1.0, 2.0]
cfs.present_value_list()
# array([-100.        ,   47.56147123,   67.86280635])
cfs.net_presnt_value()


# 15.424277577732667

# 定义新类,提供计算不同短期利率下NPV的方法——即敏感度分析
# 从cash_flow_series类继承:
class cfs_sensitivity(cash_flow_series):
    def npv_sensitivity(self, short_rates):
        npvs = []
        for rate in short_rates:
            sr.rate = rate
            npvs.append(self.net_presnt_value())
        return np.array(npvs)


cfs_sens = cfs_sensitivity('cfs', time_list, cash_flows, sr)
# 定义一个包含不同短期利率的列表, 就可以轻松地比较结果NPV
short_rates = [0.01, 0.025, 0.05, 0.075, 0.1, 0.125, 0.15, 0.2]
npvs = cfs_sens.npv_sensitivity(short_rates)
npvs
# array([23.01739219, 20.10770244, 15.42427758, 10.94027255,  6.64667738,
#         2.53490386, -1.40323463, -8.78945889])

plt.plot(short_rates, npvs, 'b')
plt.plot(short_rates, npvs, 'ro')
plt.plot((0, max(short_rates)), (0, 0), 'r', lw=2)
plt.grid(True)
plt.xlabel('short rate')
plt.ylabel('net present value')

不同短期利率下的现金流列表净现值

扫描二维码关注公众号,回复: 2144817 查看本文章

13.2 图形用户界面

用的比较少,这里就不再赘述。参考 traits

猜你喜欢

转载自blog.csdn.net/weixin_42018258/article/details/81003076
今日推荐