hledger icon indicating copy to clipboard operation
hledger copied to clipboard

What is the best transaction-balancing behaviour ?

Open simonmichael opened this issue 2 years ago • 0 comments

How precise should transaction balancing be ? This is related to https://github.com/simonmichael/hledger/issues/1962 . This mainly concerns transactions/journal entries where perfect balancing is not possible because of a long or infinite decimal part, as in most currency conversions or investment transactions involving unit costs.

hledger's balancing behaviour is different from Ledger's, causing problems reading some Ledger files. Eg, https://github.com/simonmichael/hledger/blob/master/hledger/test/ledger-compat/collected/balancing-precision.j:

; In this journal, $'s precision is 2 in txn1, 4 in txn2, and 4 globally.
; Ledger checks transaction balancedness using local precisions only,
; so it accepts txn1's $-0.00045312 imbalance.

2022-01-01 txn1
    expenses                                 AAA 989.02 @ $1.123456  ; $1111.12045312
    checking                                  $-1111.12

2022-01-02 txn2
    expenses                                      $0.1234
    checking

We always balance transactions using the global commodity precisions (canonical display styles inferred from the whole journal, commodity directives, -c options etc.). Whereas Ledger always balances transactions using the local precisions (inferred only from the amounts in the transaction's journal entry).

Which is best ? There are pros and cons to both:

Global-precision balancing (hledger)

In effect, commodity directives/-c options control both balancing precision and display precision (for each commodity).

Pro:

  • print output is both pretty (using canonical display styles) and guaranteed parseable (sufficiently balanced). And a transaction hledger considers balanced also appears balanced to a human when displayed. (Update: except when converted to value, if that generates irrational decimals, see #2051)

Con:

  • You can't freely increase the display precision, because pretty soon some of your transactions will stop balancing.
  • You can't read some Ledger files (without extra steps).

Local-precision balancing (Ledger)

Each entry is balanced based only on local information, unaffected by global display styles. There is less "interaction at a distance".

Pro:

  • Individual entries can be balanced more sloppily than otherwise, when precision is not needed.
  • Existing Ledger files are written this way, and this behaviour allows reading them.

Con:

  • print output can be either pretty, or guaranteed parseable, but not both (because if the global styles are more precise, the entry is altered and can become unbalanceable). Ledger's print command has two modes for this reason (print vs print --raw).

Beancount's balancing

To read: https://docs.google.com/document/d/1lgHxUUEY-UVEgoF6cupz2f_7v7vEF7fiJyiSlYYlhOo/edit#heading=h.wy6dx7k2mxkr

What to do ?

Workarounds:

Ledger files like the example above can be parsed by hledger, if you restrict the global precision enough that all entries can balance (eg add -c $0.00). That precision may or may not be the one you wanted displayed.

Sloppily-balanced journal entries can be made more precise, so that hledger can still balance them when displaying at higher precision. Often this requires adding extra decimal places to a unit cost price. It's a tedious process, and the more digits you want to display, the more effort required. Typically you won't build in excess precision to journal entries when you record them, or be aware of exactly how precisely they balance; so when suddenly you want to see a report with more precision, there will be an unknown number of entries to improve.

Tools could warn when they detect an entry where the local balancing precision is less than the global display precision.

None of these are ideal:

  • requiring extra workarounds to read ledger files
  • having balancing precision (affecting input) and display precision (affecting output) complected together
  • needing two print modes, one of them unparseable
  • needing to think/work hard to make sufficiently balanced journal entries

simonmichael avatar Dec 21 '22 22:12 simonmichael