Hledger | How to calculate interest with rate changing in the middle of the year

I’ve got a sample entry of an unpaid amount.

2021-09-10 Alimony Due 2021-09
    Receivable:Alimony    200.00 PLN
    Revenues:Alimony

# All other entries removed to be able to compare with an online calculator
# Last entry added as there was no output without it.
2024-03-10 Alimony Due 2024-03
    Receivable:Alimony    200.00 PLN
    Revenues:Alimony

I run the command with annual-schedule

hledger-interest -f ~/.hledger.alimony \
  --act \
  --annual-schedule='[(2020-10-07,0.056),(2021-10-07,0.06),(2021-11-04,0.0675),(2021-12-09,0.0725),(2022-01-05,0.0775),(2022-02-09,0.0825),(2022-03-09,0.09),(2022-04-07,0.1),(2022-05-06,0.1075),(2022-06-09,0.115),(2022-07-08,0.12),(2022-09-08,0.1225),(2023-09-07,0.115),(2023-10-05,0.1125)]' \
  -s Receivable:Interest \
  -t Receivable:Alimony:Interest \
  Receivable:Alimony                         

This is the result:

2021-09-10 Alimony Due 2021-09
    Receivable:Alimony      200.00 PLN
    Revenues:Alimony       -200.00 PLN

2021-12-31 5.6% interest for 200.00 PLN over 112 days
    Receivable:Alimony:Interest        3.44 PLN
    Receivable:Interest               -3.44 PLN

2022-12-31 7.25% interest for 200.00 PLN over 365 days
    Receivable:Alimony:Interest       14.50 PLN
    Receivable:Interest              -14.50 PLN

2023-12-31 12.25% interest for 200.00 PLN over 365 days
    Receivable:Alimony:Interest       24.50 PLN
    Receivable:Interest              -24.50 PLN

2024-03-10 11.25% interest for 200.00 PLN over 70 days
    Receivable:Alimony:Interest        4.30 PLN
    Receivable:Interest               -4.30 PLN

2024-03-10 Alimony Due 2024-03
    Receivable:Alimony      200.00 PLN
    Revenues:Alimony       -200.00 PLN

The interest are calculated for the full year in 2022 and 2023.

I expected it to be the same as in the online calculator:

from-to days rate amount
11.09.2021 - 06.10.2021 26 5,60% 0,80
07.10.2021 - 03.11.2021 28 6,00% 0,92
04.11.2021 - 08.12.2021 35 6,75% 1,29
09.12.2021 - 04.01.2022 27 7,25% 1,07
05.01.2022 - 08.02.2022 35 7,75% 1,49
09.02.2022 - 08.03.2022 28 8,25% 1,27
09.03.2022 - 06.04.2022 29 9,00% 1,43
07.04.2022 - 05.05.2022 29 10,00% 1,59
06.05.2022 - 08.06.2022 34 10,75% 2,00
09.06.2022 - 07.07.2022 29 11,50% 1,83
08.07.2022 - 07.09.2022 62 12,00% 4,08
08.09.2022 - 06.09.2023 364 12,25% 24,43
07.09.2023 - 04.10.2023 28 11,50% 1,76
05.10.2023 - 21.03.2024 169 11,25% 10,42

How should I change the data/command to achieve the result?

1 Like

I took the liberty of adding an hledger tag to the post.

Is this the most minimal reproducible example? I am sure the less there is, the easier it is to debug for @simonmic & friends!

It changes way too frequently without clear pattern. It seems like it’s going to be best to just do it manually. If you’re doing it annually, it’s not much of a hassle either. Just calculate how much it actually is going to be in a year. If it gets resolved earlier, you’d have to recalculate. But that’s going to be way easier than to write code for this.

What’s going to be a major hassle is writing code for this kind of very specific scenario… It’s not going to be impossible to write for this but it’s going to be a lot of work writing something that can do this kind of stuff.

@zalun so usually hledger-interest works off existing payment transactions and splits them into the principal and interest payments.

In your case, there’s just two payments, which is probably not right . You need to add more payments first (probably once per month, or however often they happen) and then try hledger-interest again?

If there are no transactions that pay back the liability, hledger-interest will just compute the annual interest, which is what seems to be happening in your example.

2 Likes

@f-a The payments are due monthly, and I restricted them to one to compare with the government calculator.

I tried to put in a fake payment, and immediately after adding receivable to reset the amount. Unfortunately the hledger-interest is not picking up:

Fake payment on the date the interest rate changes and interest calculated around it:

# Actual interest rate 09.12.2021 - 04.01.2022 27 days 7,25%

2022-01-04 7.25% interest for 200.00 PLN over 4 days
    Receivable:Alimony:Interest        0.16 PLN
    Receivable:Interest               -0.16 PLN

# Fake payment to force the right interest rate
2022-01-04 Alimony Paid 2022-01
    Revenues:Alimony    200.00 PLN
    Receivable:Alimony
2022-01-04 Alimony Due 2022-01
    Receivable:Alimony    200.00 PLN
    Revenues:Alimony

# Actual interest rate 05.01.2022 - 08.02.2022  35 days 7,75%

2022-02-08 7.25% interest for 200.00 PLN over 35 days
    Receivable:Alimony:Interest        1.39 PLN
    Receivable:Interest               -1.39 PLN

# Fake payment to force the right interest rate
2022-02-08 Alimony Paid 2022-02
    Revenues:Alimony    200.00 PLN
    Receivable:Alimony
2022-02-08 Alimony Due 2022-02
    Receivable:Alimony    200.00 PLN
    Revenues:Alimony

# Actual interest rate 09.02.2022 - 08.03.2022 28 days 8,25%

2022-03-08 7.75% interest for 200.00 PLN over 28 days
    Receivable:Alimony:Interest        1.19 PLN
    Receivable:Interest               -1.19 PLN

I can’t replicate this for some reason, I get no output:

~/src/hledger/2024-03-20$ cat a.j
2021-09-10 Alimony Due 2021-09
    Receivable:Alimony    200.00 PLN
    Revenues:Alimony

# All other entries removed to be able to compare with an online calculator
# Last entry added as there was no output without it.
2024-03-10 Alimony Due 2024-03
    Receivable:Alimony    200.00 PLN
    Revenues:Alimony
~/src/hledger/2024-03-20$ hledger-interest --act --annual-schedule='[(2020-10-07,0.056),(2021-10-07,0.06),(2021-11-04,0.0675),(2021-12-09,0.0725),(2022-01-05,0.0775),(2022-02-09,0.0825),(2022-03-09,0.09),(2022-04-07,0.1),(2022-05-06,0.1075),(2022-06-09,0.115),(2022-07-08,0.12),(2022-09-08,0.1225),(2023-09-07,0.115),(2023-10-05,0.1125)]'  -s Receivable:Interest  -t Receivable:Alimony:Interest Receivable:Alimony
~/src/hledger/2024-03-20$ 

hledger-interest is hard to use, but it’s only about 200 lines of code - would anyone be interested in improving it ?

@zalun I think this PR should fix this issue: Fix rate schedule to handle multiple rate changes during they year by adept · Pull Request #23 · peti/hledger-interest · GitHub . You can see the output on your test in the comment in that PR

If you are willing to try it from source, you could build from my fork at GitHub - adept/hledger-interest: compute interest for hledger accounts

2 Likes

Great!, thank you

Did it solve your problem @zalun ? If so could be worth commenting on the PR and trying to get it released.

@adept
I haven't been able to compile it. Today, I installed the released version, hoping it would include the change...

I guess I need to try again.

➜  Accounting cabal install --lib hledger-lib
Resolving dependencies...
➜  Accounting cd hledger-interest 
➜  hledger-interest git:(master) ✗ cabal install                  
Error: cabal: Could not resolve dependencies:
[__0] trying: hledger-interest-1.6.6 (user goal)
[__1] next goal: hledger-lib (dependency of hledger-interest)
[__1] rejecting: hledger-lib-1.34 (conflict: hledger-interest =>
hledger-lib>=1.26 && <1.33)
[__1] skipping: hledger-lib-1.33.1, hledger-lib-1.33 (has the same
characteristics that caused the previous version to fail: excluded by
constraint '>=1.26 && <1.33' from 'hledger-interest')
[__1] trying: hledger-lib-1.32.3
[__2] next goal: base (dependency of hledger-interest)
[__2] rejecting: base-4.19.1.0/installed-inplace (conflict: hledger-lib =>
base>=4.14 && <4.19)
[__2] skipping: base-4.20.0.1, base-4.20.0.0, base-4.19.1.0, base-4.19.0.0
(has the same characteristics that caused the previous version to fail:
excluded by constraint '>=4.14 && <4.19' from 'hledger-lib')
[__2] rejecting: base-4.18.2.1, base-4.18.2.0, base-4.18.1.0, base-4.18.0.0,
base-4.17.2.1, base-4.17.2.0, base-4.17.1.0, base-4.17.0.0, base-4.16.4.0,
base-4.16.3.0, base-4.16.2.0, base-4.16.1.0, base-4.16.0.0, base-4.15.1.0,
base-4.15.0.0, base-4.14.3.0, base-4.14.2.0, base-4.14.1.0, base-4.14.0.0,
base-4.13.0.0, base-4.12.0.0, base-4.11.1.0, base-4.11.0.0, base-4.10.1.0,
base-4.10.0.0, base-4.9.1.0, base-4.9.0.0, base-4.8.2.0, base-4.8.1.0,
base-4.8.0.0, base-4.7.0.2, base-4.7.0.1, base-4.7.0.0, base-4.6.0.1,
base-4.6.0.0, base-4.5.1.0, base-4.5.0.0, base-4.4.1.0, base-4.4.0.0,
base-4.3.1.0, base-4.3.0.0, base-4.2.0.2, base-4.2.0.1, base-4.2.0.0,
base-4.1.0.0, base-4.0.0.0, base-3.0.3.2, base-3.0.3.1 (constraint from
non-upgradeable package requires installed instance)
[__2] fail (backjumping, conflict set: base, hledger-interest, hledger-lib)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: hledger-lib, base, hledger-interest

The official hledger-interest has had some revisions to bounds so it builds with current hledger. You'll need to mimic those in your copy of hledger-interest.cabal (updating the hledger-lib version there, at least).

Released version still does not have the fix, yet - my PR is still open Fix rate schedule to handle multiple rate changes during the year by adept · Pull Request #23 · peti/hledger-interest · GitHub

No disrespect to overworked maintainers, but if anyone wants to port this into hledger I'd accept it.