Decimal Precision

391 views
Skip to first unread message

William Bean

unread,
Jul 25, 2022, 4:49:07 PM7/25/22
to Beancount
I've been struggling with the best way to produce beancount results with a specific number of decimal places. Really this comes about when I need to perform math via plugin (or fava extension), which generates decimals carried out many digits. I reviewed the display_context.py file, but it does not seem to have a rounding or trimming functionality to a specific amount of decimal places in it (unless I am misinterpreting the precision property).

Is there a good way to trim down decimal places within beancount's features or is this typically accomplished with python functionality to sort of brute force what you want to see?

Martin Blais

unread,
Jul 25, 2022, 10:30:24 PM7/25/22
to Beancount
Search the list for various discussion of the current limitations of the stable branch.
See also the discussion here (v3 doc):
https://docs.google.com/document/d/1qPdNXaz5zuDQ8M9uoZFyyFis7hA0G55BEfhWhrVBsfc/edit#heading=h.vy9jgsdfwj8e

By "producing" it would be useful to know what you mean; what the different tools may render and what is actually stored may differ.  Tools that produce reports may round in different ways. I'm not sure what you refer to.



On Mon, Jul 25, 2022 at 4:49 PM William Bean <wbe...@gmail.com> wrote:
I've been struggling with the best way to produce beancount results with a specific number of decimal places. Really this comes about when I need to perform math via plugin (or fava extension), which generates decimals carried out many digits. I reviewed the display_context.py file, but it does not seem to have a rounding or trimming functionality to a specific amount of decimal places in it (unless I am misinterpreting the precision property).

Is there a good way to trim down decimal places within beancount's features or is this typically accomplished with python functionality to sort of brute force what you want to see?

--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/55feb139-e42d-4bd6-be82-7a4596992933n%40googlegroups.com.

William Bean

unread,
Jul 26, 2022, 1:49:01 PM7/26/22
to bean...@googlegroups.com
Thanks Martin. That's very helpful. I'm going to digest it a little bit and gather my thoughts. I have 2 use cases which have come up, one for reporting and the other for mathematically calculated posting amounts. I'll put together some examples of the use cases when I get a little more time.

Side note, thank you for your hard work putting Beancount together. It's truly fantastic software and I love customizing it to suit my needs. I've been using it for 2 years now and it's hard to remember how I did my finances beforehand.

You received this message because you are subscribed to a topic in the Google Groups "Beancount" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/beancount/qqCyu-8Zbmw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/CAK21%2BhMEHFATg0tT81e%2BvgXvtWdV4S%2BzwjfszGDw%3D4ofM5bepw%40mail.gmail.com.

William Bean

unread,
Jul 26, 2022, 5:26:23 PM7/26/22
to bean...@googlegroups.com
Just closing the loop on this. I combed through all the information you posted links to, which was extremely helpful and thorough. Thank you. Turns out my use cases were pretty explicitly discussed in the historical notes portion of your precision documentation. In case others find it helpful here were my findings:

1. Results from queries were outputting many decimal places due to not using display context. This was solved and merged into the master in April 2022. My install is older than that, so an update should solve this without issue.

2. Results from printer were also outputting many decimal places. The above referenced notes indicate this is on purpose for round tripping reasons. Thus, I can just solve this by quantizing my decimals as part of my script to get the desired results.

fin

unread,
Mar 2, 2023, 9:54:15 AM3/2/23
to bean...@googlegroups.com
Martin Blais wrote:
...
> Search the list for various discussion of the current limitations of the
> stable branch.
> See also the discussion here (v3 doc):
> https://docs.google.com/document/d/1qPdNXaz5zuDQ8M9uoZFyyFis7hA0G55BEfhWhrVBsfc/edit#heading=h.vy9jgsdfwj8e

i'm trying to wade through all these various docs and
mentions about precision because i'm trying to figure out
why certain transactions do not balance (and fava complains).

my assumption is that using the Decimal Python type should
remove a lot of internal conversion issues since because the
data is starting out as strings that any calculations should
be as accurate as possible given those strings to start with.

is there a way right now to tell beancount to only use
Decimal internally?


my test data, importer and fava tells me that this doesn't balance:


2000-01-01 * "Split 2 FOR 1"
input: "01/01/2000,20000101-001,Split 2 FOR 1,,INTC,,,,,,,"
transId: "20000101-001"
lot: "43.5 USD, 1999-01-01"
Assets:SB:WHS:INTC -25 INTC {43.5 USD, 1999-01-01} @ 43.5
Assets:SB:WHS:INTC 50 INTC {43.5 USD, 1999-01-01} @ 21.75


i use this at the front of my ledger file:


option "operating_currency" "USD"
option "inferred_tolerance_default" "*:0.001"
option "inferred_tolerance_multiplier" "1.2"
option "infer_tolerance_from_cost" "TRUE"
option "account_rounding" "Equity:RoundingError"


where am i screwing up? :)


fin

Daniele Nicolodi

unread,
Mar 2, 2023, 12:15:06 PM3/2/23
to bean...@googlegroups.com
On 02/03/23 15:53, fin wrote:
> i'm trying to wade through all these various docs and
> mentions about precision because i'm trying to figure out
> why certain transactions do not balance (and fava complains).

Your example below does not balance for 1087.5 USD. Why do you think it
due to precision or rounding?

> my assumption is that using the Decimal Python type should
> remove a lot of internal conversion issues since because the
> data is starting out as strings that any calculations should
> be as accurate as possible given those strings to start with.
>
> is there a way right now to tell beancount to only use
> Decimal internally?

Beancount uses Decimal everywhere.

> my test data, importer and fava tells me that this doesn't balance:
>
>
> 2000-01-01 * "Split 2 FOR 1"
> input: "01/01/2000,20000101-001,Split 2 FOR 1,,INTC,,,,,,,"
> transId: "20000101-001"
> lot: "43.5 USD, 1999-01-01"
> Assets:SB:WHS:INTC -25 INTC {43.5 USD, 1999-01-01} @ 43.5
> Assets:SB:WHS:INTC 50 INTC {43.5 USD, 1999-01-01} @ 21.75

Combining prices and costs is tricky. See
https://beancount.github.io/docs/how_inventories_work.html#price-vs-cost-basis
and https://beancount.github.io/docs/trading_with_beancount.html

The problem with the transaction above is that the cost annotation for
one of the two postings above must be wrong: you cannot sell 25 INCT at
43.5 USD, and buy 50 INTC at 43.5 USD without having 1087.50 USD come
from somewhere.

Cheers,
Dan

fin

unread,
Mar 2, 2023, 1:29:08 PM3/2/23
to bean...@googlegroups.com
Daniele Nicolodi wrote:
> On 02/03/23 15:53, fin wrote:
>> i'm trying to wade through all these various docs and
>> mentions about precision because i'm trying to figure out
>> why certain transactions do not balance (and fava complains).
>
> Your example below does not balance for 1087.5 USD. Why do you think it
> due to precision or rounding?

because i'm working from a combinations of examples and
don't really understand them well enough yet. :)

i'm trying to use the dated lot signification and then
also working from the split description and then also your
noted link below about trading. i did read through them
but misunderstood something. i'll figure it out eventually
now that i know the error is indeed something i did wrong
and not the error/rounding issue.

somehow i messed up and don't know how yet to fix it to
preserve the original lot date.

also, i really should know more about bean-doctor and
thanks for reminding me about that. using fava is not
always the quickest way for me to learn but i'm too used
to clicking these days...


>> my assumption is that using the Decimal Python type should
>> remove a lot of internal conversion issues since because the
>> data is starting out as strings that any calculations should
>> be as accurate as possible given those strings to start with.
>>
>> is there a way right now to tell beancount to only use
>> Decimal internally?
>
> Beancount uses Decimal everywhere.

ah, good to know. :)


>> my test data, importer and fava tells me that this doesn't balance:
>>
>>
>> 2000-01-01 * "Split 2 FOR 1"
>> input: "01/01/2000,20000101-001,Split 2 FOR 1,,INTC,,,,,,,"
>> transId: "20000101-001"
>> lot: "43.5 USD, 1999-01-01"
>> Assets:SB:WHS:INTC -25 INTC {43.5 USD, 1999-01-01} @ 43.5
>> Assets:SB:WHS:INTC 50 INTC {43.5 USD, 1999-01-01} @ 21.75
>
> Combining prices and costs is tricky. See
> https://beancount.github.io/docs/how_inventories_work.html#price-vs-cost-basis
> and https://beancount.github.io/docs/trading_with_beancount.html

i did read through them but i misunderstood some part(s) of
them.


> The problem with the transaction above is that the cost annotation for
> one of the two postings above must be wrong: you cannot sell 25 INCT at
> 43.5 USD, and buy 50 INTC at 43.5 USD without having 1087.50 USD come
> from somewhere.

i see that now. :) i just do not want to lose the original
lot date and don't know how i would reference that original lot
after the split. currrently in my program i keep the original
designation as the lot string even if the price changes due to
the split (at least that was what i thought i was doing).


if i change that 2nd line to:

Assets:SB:WHS:INTC 50 INTC {21.75 USD, 1999-01-01} @ 21.75
or
Assets:SB:WHS:INTC 50 INTC {21.75 USD, 1999-01-01}

will that preserve the lot date? and will i have to reference it
by the new "21.75 USD, 1991-01-01" or would i still be using the
original "43.5 USD, 1999-01-01"?

i can work with this either way i just want to know which it
is. which syntax works?

thanks for pointing me in the right direction. i was trying
to chase a problem that wasn't there and made little headway
(which is why i asked).


fin

Daniele Nicolodi

unread,
Mar 3, 2023, 3:32:15 AM3/3/23
to bean...@googlegroups.com
On 02/03/23 19:28, fin wrote:
> i'll figure it out eventually
> now that i know the error is indeed something i did wrong
> and not the error/rounding issue.

AFAIK there are never been bugs reported on Beancount regarding
inaccuracies due to rounding or other computing errors. The only issues
somehow related to rounding are about how Beancount decides how many
digits to display.

>>> 2000-01-01 * "Split 2 FOR 1"
>>> input: "01/01/2000,20000101-001,Split 2 FOR 1,,INTC,,,,,,,"
>>> transId: "20000101-001"
>>> lot: "43.5 USD, 1999-01-01"
>>> Assets:SB:WHS:INTC -25 INTC {43.5 USD, 1999-01-01} @ 43.5
>>> Assets:SB:WHS:INTC 50 INTC {43.5 USD, 1999-01-01} @ 21.75
>>

> if i change that 2nd line to:
>
> Assets:SB:WHS:INTC 50 INTC {21.75 USD, 1999-01-01} @ 21.75
> or
> Assets:SB:WHS:INTC 50 INTC {21.75 USD, 1999-01-01}
>
> will that preserve the lot date? and will i have to reference it
> by the new "21.75 USD, 1991-01-01" or would i still be using the
> original "43.5 USD, 1999-01-01"?

I think the question is not well posed. Lots are identified by cost,
date, and an optional label. If no date is present in a cost
specification, Beancount uses the date of the transaction. Lot are
merged only when all these three attributes are the same. See here
https://beancount.github.io/docs/how_inventories_work.html#cost-basis

Therefore, if you change the cost, from the Beancount point of view, you
have a different lot. I think this behavior is the most intuitive one.

Cheers,
Dan


Reply all
Reply to author
Forward
0 new messages