forked from domokane/FinancePy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_FinBond.py
169 lines (125 loc) · 5.85 KB
/
test_FinBond.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
##############################################################################
# Copyright (C) 2018, 2019, 2020 Dominic O'Kane
##############################################################################
from financepy.utils.frequency import FrequencyTypes
from financepy.utils.day_count import DayCountTypes
from financepy.utils.date import Date
from financepy.utils.math import ONE_MILLION
from financepy.products.bonds.bond import Bond
from financepy.products.bonds.bond import YTMCalcType
def test_bondtutor_example():
# EXAMPLE FROM http://bondtutor.com/btchp4/topic6/topic6.htm
accrualConvention = DayCountTypes.ACT_ACT_ICMA
y = 0.062267
settlement_date = Date(19, 4, 1994)
issue_date = Date(15, 7, 1990)
maturity_date = Date(15, 7, 1997)
coupon = 0.085
face = ONE_MILLION
freq_type = FrequencyTypes.SEMI_ANNUAL
bond = Bond(issue_date, maturity_date,
coupon, freq_type, accrualConvention, face)
full_price = bond.full_price_from_ytm(settlement_date, y)
assert round(full_price, 4) == 108.7696
clean_price = bond.clean_price_from_ytm(settlement_date, y)
assert round(clean_price, 4) == 106.5625
accrued_interest = bond._accrued_interest
assert round(accrued_interest, 4) == 22071.8232
ytm = bond.yield_to_maturity(settlement_date, clean_price)
assert round(ytm, 4) == 0.0622
bump = 1e-4
priceBumpedUp = bond.full_price_from_ytm(settlement_date, y + bump)
assert round(priceBumpedUp, 4) == 108.7395
priceBumpedDn = bond.full_price_from_ytm(settlement_date, y - bump)
assert round(priceBumpedDn, 4) == 108.7998
durationByBump = -(priceBumpedUp - full_price) / bump
assert round(durationByBump, 4) == 301.1932
duration = bond.dollar_duration(settlement_date, y)
assert round(duration, 4) == 301.2458
assert round(duration - durationByBump, 4) == 0.0526
modified_duration = bond.modified_duration(settlement_date, y)
assert round(modified_duration, 4) == 2.7696
macauley_duration = bond.macauley_duration(settlement_date, y)
assert round(macauley_duration, 4) == 2.8558
conv = bond.convexity_from_ytm(settlement_date, y)
assert round(conv, 4) == 0.0967
def test_bloomberg_us_treasury_example():
settlement_date = Date(21, 7, 2017)
issue_date = Date(15, 5, 2010)
maturity_date = Date(15, 5, 2027)
coupon = 0.02375
freq_type = FrequencyTypes.SEMI_ANNUAL
accrual_type = DayCountTypes.ACT_ACT_ICMA
face = 100.0
bond = Bond(issue_date,
maturity_date,
coupon,
freq_type,
accrual_type,
face)
clean_price = 99.7808417
yld = bond.current_yield(clean_price)
assert round(yld, 4) == 0.0238
ytm = bond.yield_to_maturity(settlement_date, clean_price,
YTMCalcType.UK_DMO)
assert round(ytm, 4) == 0.0240
ytm = bond.yield_to_maturity(settlement_date, clean_price,
YTMCalcType.US_STREET)
assert round(ytm, 4) == 0.0240
ytm = bond.yield_to_maturity(settlement_date, clean_price,
YTMCalcType.US_TREASURY)
assert round(ytm, 4) == 0.0240
full_price = bond.full_price_from_ytm(settlement_date, ytm)
assert round(full_price, 4) == 100.2149
clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
assert round(clean_price, 4) == 99.7825
accrued_interest = bond._accrued_interest
assert round(accrued_interest, 4) == 0.4324
accddays = bond._accrued_days
assert round(accddays, 4) == 67.0
duration = bond.dollar_duration(settlement_date, ytm)
assert round(duration, 4) == 869.0934
modified_duration = bond.modified_duration(settlement_date, ytm)
assert round(modified_duration, 4) == 8.6723
macauley_duration = bond.macauley_duration(settlement_date, ytm)
assert round(macauley_duration, 4) == 8.7764
conv = bond.convexity_from_ytm(settlement_date, ytm)
assert round(conv, 4) == 0.8517
def test_bloomberg_apple_corp_example():
settlement_date = Date(21, 7, 2017)
issue_date = Date(13, 5, 2012)
maturity_date = Date(13, 5, 2022)
coupon = 0.027
freq_type = FrequencyTypes.SEMI_ANNUAL
accrual_type = DayCountTypes.THIRTY_E_360_ISDA
face = 100.0
bond = Bond(issue_date, maturity_date,
coupon, freq_type, accrual_type, face)
clean_price = 101.581564
yld = bond.current_yield(clean_price)
assert round(yld, 4) == 0.0266
ytm = bond.yield_to_maturity(settlement_date, clean_price,
YTMCalcType.UK_DMO)
assert round(ytm, 4) == 0.0235
ytm = bond.yield_to_maturity(settlement_date, clean_price,
YTMCalcType.US_STREET)
assert round(ytm, 4) == 0.0235
ytm = bond.yield_to_maturity(settlement_date, clean_price,
YTMCalcType.US_TREASURY)
assert round(ytm, 4) == 0.0235
full_price = bond.full_price_from_ytm(settlement_date, ytm)
assert round(full_price, 4) == 102.0932
clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
assert round(clean_price, 4) == 101.5832
accddays = bond._accrued_days
assert accddays == 68
accrued_interest = bond._accrued_interest
assert round(accrued_interest, 4) == 0.51
duration = bond.dollar_duration(settlement_date, ytm)
assert round(duration, 4) == 456.5778
modified_duration = bond.modified_duration(settlement_date, ytm)
assert round(modified_duration, 4) == 4.4722
macauley_duration = bond.macauley_duration(settlement_date, ytm)
assert round(macauley_duration, 4) == 4.5247
conv = bond.convexity_from_ytm(settlement_date, ytm)
assert round(conv, 4) == 0.2302