Coverage for tests / test_deposits.py: 99%
105 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-27 14:36 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-27 14:36 +0000
1import math
2from unittest import main, TestCase
4from matplotlib.dates import relativedelta
5from rivapy.marketdata.curves import DiscountCurve
6from rivapy.pricing.deposit_pricing import DepositPricer
7from rivapy.tools.datetools import DayCounter, Schedule, _term_to_period, calc_end_day
8from rivapy.tools.holidays_compat import EuropeanCentralBank as _ECB
9from rivapy.instruments.deposit_specifications import DepositSpecification
10from rivapy.tools.enums import DayCounterType, InterpolationType, ExtrapolationType
11from rivapy.tools.enums import InterpolationType, RollConvention, SecuritizationLevel, DayCounterType, Currency
12from rivapy.pricing import DeterministicCashflowPricer, price
13from rivapy.marketdata import DiscountCurveParametrized, ConstantRate
14import datetime as dt
17class DepositSpecificationTests(TestCase):
19 def test_deposit_specification(self):
20 ccy = "EUR"
21 ref_date = dt.datetime(2023, 1, 2)
22 issue_date = ref_date
23 maturity_date = dt.datetime(2024, 1, 26)
24 dcc = "Act360"
25 rate = 0.03
26 notional = 1000.0
28 deposit_spec = DepositSpecification(
29 obj_id="dummy_id",
30 issuer="",
31 currency=ccy,
32 issue_date=issue_date,
33 maturity_date=maturity_date,
34 notional=notional,
35 rate=rate,
36 day_count_convention=dcc,
37 roll_convention="NONE",
38 payment_days=5,
39 spot_days=5,
40 )
42 self.assertEqual(deposit_spec.obj_id, "dummy_id")
43 self.assertEqual(deposit_spec.issuer, "")
44 self.assertEqual(deposit_spec.notional.get_amount(), notional)
45 self.assertEqual(deposit_spec.currency, ccy)
46 self.assertEqual(deposit_spec.maturity_date, maturity_date)
47 self.assertEqual(deposit_spec.issue_date, issue_date)
48 self.assertEqual(deposit_spec.rate, rate)
49 self.assertEqual(deposit_spec.day_count_convention, dcc)
50 self.assertEqual(deposit_spec.roll_convention, "NONE")
51 self.assertEqual(deposit_spec.payment_days, 5)
52 self.assertEqual(deposit_spec.spot_days, 5)
53 self.assertEqual(deposit_spec.securitization_level, "NONE")
54 self.assertEqual(deposit_spec.ins_type().value, "DEPOSIT")
55 self.assertEqual(deposit_spec.get_end_date(), maturity_date)
56 # holiday calendars may be represented differently across `holidays` versions
57 # compare a known holiday entry instead of relying on object equality
58 self.assertIn(dt.date(2023, 1, 1), deposit_spec.calendar)
59 self.assertEqual(deposit_spec.calendar[dt.date(2023, 1, 1)], _ECB()[dt.date(2023, 1, 1)])
60 self.assertEqual(deposit_spec.adjust_start_date, True)
61 self.assertEqual(deposit_spec.adjust_end_date, False)
62 self.assertEqual(deposit_spec.frequency, "389D")
63 self.assertEqual(deposit_spec.dates, [issue_date, maturity_date])
65 dep_dict = deposit_spec.to_dict()
66 self.assertEqual(dep_dict["obj_id"], "dummy_id")
67 self.assertEqual(dep_dict["issue_date"], issue_date.isoformat())
68 self.assertEqual(dep_dict["maturity_date"], maturity_date.isoformat())
69 self.assertEqual(dep_dict["currency"], ccy)
70 self.assertEqual(dep_dict["notional"].get_amount(), notional)
71 self.assertEqual(dep_dict["rate"], rate)
72 self.assertEqual(dep_dict["day_count_convention"], dcc)
73 self.assertEqual(dep_dict["roll_convention"], "NONE")
74 self.assertEqual(dep_dict["spot_days"], 5)
75 self.assertEqual(dep_dict["business_day_convention"], "ModifiedFollowing")
76 self.assertEqual(dep_dict["issuer"], "")
77 self.assertEqual(dep_dict["securitization_level"], "NONE")
78 self.assertEqual(dep_dict["payment_days"], 5)
80 deposit_spec_2 = DepositSpecification(
81 obj_id="dummy_id",
82 issuer="",
83 term="1Y",
84 currency=ccy,
85 issue_date=issue_date,
86 notional=notional,
87 rate=rate,
88 day_count_convention=dcc,
89 roll_convention="NONE",
90 )
91 maturity_date = calc_end_day(issue_date, "1Y", "MODIFIED_FOLLOWING", _ECB())
92 self.assertEqual(deposit_spec_2.maturity_date, maturity_date)
93 self.assertEqual(deposit_spec_2.start_date, dt.datetime(2023, 1, 2))
94 self.assertEqual(deposit_spec_2.spot_days, 2)
96 issue_date = dt.datetime(2023, 1, 1)
97 deposit_spec_3 = DepositSpecification(
98 obj_id="dummy_id",
99 issuer="",
100 term="1Y",
101 currency=ccy,
102 issue_date=issue_date,
103 notional=notional,
104 rate=rate,
105 day_count_convention=dcc,
106 roll_convention="NONE",
107 adjust_start_date=False,
108 )
109 self.assertEqual(deposit_spec_3.issue_date, dt.datetime(2023, 1, 1))
110 self.assertEqual(deposit_spec_3.start_date, dt.datetime(2023, 1, 1))
111 self.assertEqual(deposit_spec_3.end_date, dt.datetime(2024, 1, 1))
112 self.assertEqual(deposit_spec_3.maturity_date, dt.datetime(2024, 1, 2))
114 deposit_spec_4 = DepositSpecification(
115 obj_id="dummy_id",
116 issuer="",
117 term="1Y",
118 currency=ccy,
119 issue_date=issue_date,
120 notional=notional,
121 rate=rate,
122 day_count_convention=dcc,
123 roll_convention="NONE",
124 adjust_start_date=True,
125 )
126 self.assertEqual(deposit_spec_4.issue_date, dt.datetime(2023, 1, 1))
127 self.assertEqual(deposit_spec_4.start_date, dt.datetime(2023, 1, 2))
128 self.assertEqual(deposit_spec_4.end_date, dt.datetime(2024, 1, 2))
129 self.assertEqual(deposit_spec_4.maturity_date, dt.datetime(2024, 1, 2))
131 deposit_spec_5 = DepositSpecification(
132 obj_id="dummy_id",
133 issuer="",
134 term="O/N",
135 currency=ccy,
136 issue_date=issue_date,
137 notional=notional,
138 rate=rate,
139 day_count_convention=dcc,
140 roll_convention="NONE",
141 )
142 self.assertEqual(deposit_spec_5.maturity_date, dt.datetime(2023, 1, 3))
143 self.assertEqual(deposit_spec_5.start_date, dt.datetime(2023, 1, 2))
144 self.assertEqual(deposit_spec_5.end_date, dt.datetime(2023, 1, 3))
145 self.assertEqual(deposit_spec_5.spot_days, 0)
148class DepositPricingTests(TestCase):
150 def test_deposit_pricing(self):
151 """Simple test for yield computation: Fixed rate used to compute pv which is then used to compute yield."""
153 ccy = "EUR"
154 ref_date = dt.datetime(2023, 1, 2)
155 issue_date = ref_date
156 maturity_date = dt.datetime(2024, 1, 26)
157 dcc = "Act360"
158 rate = 0.03
159 notional = 100.0
160 deposit_spec = DepositSpecification(
161 obj_id="dummy_id",
162 issuer="",
163 currency=ccy,
164 issue_date=issue_date,
165 maturity_date=maturity_date,
166 notional=notional,
167 rate=rate,
168 day_count_convention=dcc,
169 roll_convention="NONE",
170 payment_days=5,
171 spot_days=5,
172 )
174 object_id = "TEST_CURVE"
175 flat_rate = 0.025
177 days_to_maturity = [1, 180, 365, 720, 3 * 365, 4 * 365, 10 * 365]
178 dates = [ref_date + dt.timedelta(days=d) for d in days_to_maturity]
180 df = [math.exp(-d / 365.0 * flat_rate) for d in days_to_maturity]
181 dc = DiscountCurve(
182 id=object_id, refdate=ref_date, dates=dates, df=df, interpolation=InterpolationType.LINEAR, extrapolation=ExtrapolationType.LINEAR
183 )
185 self.assertEqual(
186 DeterministicCashflowPricer.get_expected_cashflows(deposit_spec, ref_date),
187 [(dt.datetime(2023, 1, 2, 0, 0), -100.0), (dt.datetime(2024, 1, 31, 0, 0), 3.2416666666666663), (dt.datetime(2024, 1, 31, 0, 0), 100.0)],
188 )
189 self.assertAlmostEqual(DepositPricer.get_implied_simply_compounded_rate(ref_date, deposit_spec, dc), 0.024971370182974097, delta=1e-6)
190 self.assertAlmostEqual(DepositPricer.get_price(ref_date, deposit_spec, dc), 100.4950269333136, delta=1e-6)
192 fair_deposit_spec = DepositSpecification(
193 obj_id="dummy_id",
194 issuer="dummy_issuer",
195 securitization_level="NONE",
196 currency=ccy,
197 issue_date=ref_date,
198 maturity_date=deposit_spec.end_date,
199 notional=deposit_spec.notional,
200 rate=0.024971370182974097,
201 day_count_convention=deposit_spec.day_count_convention,
202 payment_days=deposit_spec.payment_days,
203 spot_days=deposit_spec.spot_days,
204 )
205 df_curve = dc.value_fwd(ref_date, fair_deposit_spec.start_date, fair_deposit_spec.end_date)
206 dcc = DayCounter(fair_deposit_spec.day_count_convention)
207 delta_t = dcc.yf(fair_deposit_spec.start_date, fair_deposit_spec.end_date)
208 df_implied = 1.0 / (1.0 + delta_t * 0.024971370182974097)
210 self.assertAlmostEqual(df_curve, df_implied, delta=1e-10)
213if __name__ == "__main__":
214 main()