# 第15章 估值框架

## 15.2 风险中立折现

### 15.2.1 日期建模和处理

import datetime as dt

dates = [dt.datetime(2018, 1, 1), dt.datetime(2018, 7, 1), dt.datetime(2019, 1, 1)]

(dates[1] - dates[0]).days / 365
# 0.4958904109589041

(dates[2] - dates[1]).days / 365
# 0.5041095890410959

fractions = [0.0, 0.5, 1.0]
# dates 和 fraction 定义（大致）等价

import numpy as np

# 获取年分数
def get_year_deltas(date_list, day_count=365.):
"""
Return vector of floats with day deltas in years.
Initial value normalized to zero.
:param date_list: list or array
collection of datetime objects
:param day_count: float
number of days for a year
:return:
delta_list:array
year fractions
"""
start = date_list[0]
delta_list = [(date - start).days / day_count for date in date_list]
return np.array(delta_list)

import datetime as dt

dates = [dt.datetime(2018, 1, 1), dt.datetime(2018, 7, 1), dt.datetime(2019, 1, 1)]
get_year_deltas(dates)
# array([0.        , 0.49589041, 1.        ])

### 15.2.2 固定短期利率

class constant_short_rate(object):
"""
Class for constant short rate discounting
"""

def __init__(self, name, short_rate):
"""

:param name:string
name of the object
:param short_rate:float(positive)
constant rate for discounting
"""
self.name = name
self.short_rate = short_rate
if short_rate < 0:
raise ValueError('Short rate negative.')

def get_discount_factors(self, date_list, dtobjects=True):
"""
get discount factors given a list/array of datetime objects or year fractions
"""
if dtobjects is True:
dlist = get_year_deltas(date_list)
else:
dlist = np.array(date_list)
dflist = np.exp(self.short_rate * np.sort(-dlist))
return np.array((date_list, dflist)).T

import datetime as dt

dates = [dt.datetime(2018, 1, 1), dt.datetime(2018, 7, 1), dt.datetime(2019, 1, 1)]
csr = constant_short_rate('csr', 0.05)
csr.get_discount_factors(dates)
# array([[datetime.datetime(2018, 1, 1, 0, 0), 0.951229424500714],
#        [datetime.datetime(2018, 7, 1, 0, 0), 0.9755103387657228],
#        [datetime.datetime(2019, 1, 1, 0, 0), 1.0]], dtype=object)

deltas = get_year_deltas(dates)
csr.get_discount_factors(deltas, dtobjects=False)
# array([[0.        , 0.95122942],
#        [0.49589041, 0.97551034],
#        [1.        , 1.        ]])

## 15.3 市场环境

# 建立由常量、 列表和曲线组成的市场环境模型的类
class market_environment(object):
def __init__(self, name, pricing_date):
self.name = name
self.pricing_date = pricing_date
self.constants = {}
self.lists = {}
self.curves = {}

self.constants[key] = constant

def get_constant(self, key):
return self.constants[key]

self.lists[key] = list_object

def get_list(self, key):
return self.lists[key]

self.curves[key] = curve

def get_curve(self, key):
return self.curves[key]

for key in env.constants:
self.constants[key] = env.constants[key]
for key in env.lists:
self.lists[key] = env.lists[key]
for key in env.curves:
self.curves[key] = env.curves[key]

import datetime as dt

dates = [dt.datetime(2018, 1, 1), dt.datetime(2018, 7, 1), dt.datetime(2019, 1, 1)]
csr = constant_short_rate('csr', 0.05)
me_1 = market_environment('me_1', dt.datetime(2018, 1, 1))
me_1.get_list('symbols')
# ['AAPL', 'MSFT', 'FB']

me_2 = market_environment('me_2', dt.datetime(2018, 1, 1))
me_2.get_curve('short_rate')
# <__main__.constant_short_rate at 0x1a226781cc0>

me_1.get_curve('short_rate')
# <__main__.constant_short_rate at 0x1a226781cc0>

me_1.constants
# {'volatility': 0.2}

me_1.lists
# {'symbols': ['AAPL', 'MSFT', 'FB']}

me_1.curves
# {'short_rate': <__main__.constant_short_rate at 0x1a226781cc0>}

me_1.get_curve('short_rate').short_rate
# 0.05