@@ -148,4 +148,79 @@ post_date label amount capital intere
148148 () => schedule.prettyPrint (convention: convention), prints (expected));
149149 });
150150 });
151+
152+ group ('Calculator ad-hoc calculations' , () {
153+ test ('solve payment using a different interest frequency, leap day start' , () async {
154+ // This test is to check correct handling of month rolling
155+ // where a series starts on the last day of Feb - see series.dart
156+ // lines 175-183
157+ final calculator = Calculator ()
158+ ..add (SeriesAdvance (
159+ numberOf: 1 ,
160+ label: 'Loan' ,
161+ amount: 10000 ,
162+ postDateFrom: DateTime .utc (2024 , 1 , 31 ),
163+ ))
164+ ..add (SeriesPayment (
165+ numberOf: 36 ,
166+ label: 'Instalment' ,
167+ amount: null ,
168+ isInterestCapitalised: false ,
169+ postDateFrom: DateTime .utc (2024 , 2 , 29 )//leap year
170+ ))
171+ ..add (SeriesPayment (
172+ numberOf: 12 ,
173+ label: 'Interest' ,
174+ amount: 0.0 ,
175+ isInterestCapitalised: true ,
176+ frequency: Frequency .quarterly,
177+ postDateFrom: DateTime .utc (2024 , 4 , 29 )
178+ ));
179+ final convention = US30U360 ();
180+ final startDate = DateTime .utc (2026 , 1 , 31 );
181+
182+ final pmt = await calculator.solveValue (
183+ convention: convention, interestRate: 0.1 , startDate: startDate);
184+ final irr = await calculator.solveRate (
185+ convention: convention, startDate: startDate);
186+ expect (pmt, closeTo (322.27 , 0.01 ));
187+ expect (irr, closeTo (0.09999676 , 1e-8 ));
188+ });
189+ test ('solve payment using a different interest frequency, non-leap day start' , () async {
190+ // This test is to check correct handling of month rolling
191+ // where a series starts on the last day of Feb - see series.dart
192+ // lines 175-183
193+ final calculator = Calculator ()
194+ ..add (SeriesAdvance (
195+ numberOf: 1 ,
196+ label: 'Loan' ,
197+ amount: 10000 ,
198+ postDateFrom: DateTime .utc (2026 , 1 , 31 ),
199+ ))
200+ ..add (SeriesPayment (
201+ numberOf: 36 ,
202+ label: 'Instalment' ,
203+ amount: null ,
204+ isInterestCapitalised: false ,
205+ postDateFrom: DateTime .utc (2026 , 2 , 28 )
206+ ))
207+ ..add (SeriesPayment (
208+ numberOf: 12 ,
209+ label: 'Interest' ,
210+ amount: 0.0 ,
211+ isInterestCapitalised: true ,
212+ frequency: Frequency .quarterly,
213+ postDateFrom: DateTime .utc (2026 , 4 , 28 )
214+ ));
215+ final convention = US30U360 ();
216+ final startDate = DateTime .utc (2026 , 1 , 31 );
217+
218+ final pmt = await calculator.solveValue (
219+ convention: convention, interestRate: 0.1 , startDate: startDate);
220+ final irr = await calculator.solveRate (
221+ convention: convention, startDate: startDate);
222+ expect (pmt, closeTo (322.27 , 0.01 ));
223+ expect (irr, closeTo (0.09999676 , 1e-8 ));
224+ });
225+ });
151226}
0 commit comments