-
-
Notifications
You must be signed in to change notification settings - Fork 306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unbalanced entries from commodity exchange #2051
Comments
The problem can arise with particular amounts and output precisions. Eg with this example it happens with two decimal places but not with one or three:
I'm not immediately sure how to fix this, any ideas ? |
I think ideally it would print with the target commodity's display precision, but also add just enough extra decimals to show a balanced entry, when needed. But will there be entries which can never be rendered as a balanced entry when valued, because of infinitely repeating/recurring decimals ? |
Here's the example again, and the results of printing with display precisions 0-10. In this case precisions 2, 4 and 5 cause unbalanced output.
|
If we don't round at all, hledger shows the Decimal library's maximum 255 decimal places, and the amounts still do not balance (these valuations seem to be irrational numbers):
|
I suppose we are hitting a limitation of our valuation approach: it is currently done with simple arithmetic, whereas (more) serious financial software probably considers currency's smallest subunit and avoids splitting those. So I think fixing this requires specifying and implementing subunit-aware valuation, or just document that print -X can show unbalanced entries, which you can usually fix by experimenting with different display precisions. |
If we accept the information loss in the conversion we could try to work around it. What about having So, in my example the output would be something like
Sketchy, but one could still use the Another idea is to allow the user to specify some "overfill" account where the ±unit would be lost? Similar to
Don't know if |
I personally don't think this is a 'bug' in the software (though it is a problem to be dealt with by the user) as this is a problem inherent in multi-currency accounting. Perhaps the simplest solution is to do what is currently being done: to flag an error and allow the user to solve it, This way, at least, a valid journal isn't replaced by an invalid journal via Here's some discussion on how beancount handles tolerances and precision: |
These are helpful ideas, thanks! I agree with the principle that print should never produce unparseable output. I also think it should never fail [(once it has successfully read the input)]; anyone could get into this situation Keeping implicit amounts, or forcing one to be implicit if there are Adding a tolerance for imprecision (3) is what we currently do - Adding an extra equity posting to catch the imbalance (4) is also possible, Calculating value in a subunit-aware way, that avoids generating I think I need to spend some more time reviewing hledger/Ledger/BC's handling of 3. Other comments welcome. |
PS I'm going to call this an enhancement not a bug, since it's the next step in our long quest to print always-valid journal output. |
Well, still at least a documentation bug. Ok. |
Problems with adding an imbalance posting (4):
|
Related: #1964 |
Some more notes: Essentially a balanced transaction is one where the amounts sum to zero. But it's more complicated in practice. There are two kinds of transaction balancing, mostly independent. Currently, "Input balancing" is done by hledger at read time, converting each journal entry to a complete and balanced transaction in memory (see Transaction type). A balanced Transaction is one that that appears balanced when amounts are rendered with their commodities' display precisions, ie imprecisions not visible when displayed are ignored (see isTransactionBalanced function). "Output balancing" is done by the print command at output time, converting each Transaction to a balanced journal entry. A balanced journal entry can be read successfully by hledger, but also its amounts appear to the human eye to sum to zero exactly (no imprecision allowed), and all amounts must be displayable with all of their decimal places (to support print's --explicit/-x flag). (#1964 is about input balancing, #2051 is about output balancing.) hledger uses a decimal number representation internally, with up to 255 decimal places (see Decimal). Amounts in hledger's input always have a finite number (<= 255) of decimal places. But certain hledger operations (using division) can generate amounts with excessively many or infinitely periodic decimal places, which I'll call "long decimals". Eg converting to value with an inferred reverse market price (see https://hledger.org/dev/hledger.html#finding-market-price) can generate long decimals (1 / 72.35 in an example above has a repeating cycle of 1446 decimals).
Journal entries require finite, preferably short, decimals. So generating a balanced journal entry requires (among other things) getting rid of long decimals. (And if numbers were stored internally as ratios (fractions) like Ledger, these would need to be converted to finite decimals.) |
PS I've had some help with my math terminology.. in fact these are not irrational numbers - wherever I've used that term, I mean "periodically repeating decimals" or just "too many decimals". I've edited the comment above. |
Since hledger 1.32,
So I think this has been fixed. |
From https://groups.google.com/g/hledger/c/QwDqPO8nepA/m/UXS_fgBFAAAJ.
It appears using
--exchange COMM
can lead to unbalanced entries. For example with the inputrunning
hledger print -X NOK
results inwhich is unbalanced.
According to #931, and more specifically to #1430, seems like this was fixed at some point, but as of version 1.30 on Linux it does not work.
The text was updated successfully, but these errors were encountered: