ledger / ledger

Double-entry accounting system with a command-line reporting interface
https://www.ledger-cli.org
Other
5.23k stars 495 forks source link

Currencies with Many Decimal Places #1795

Open JP-Ellis opened 5 years ago

JP-Ellis commented 5 years ago

Although most currencies have 2 decimal places and perhaps up to 4 when trading, a large number of cryptocurrencies have a very large number of decimal places. Bitcoin for example has 8, and Ethereum (and a large number of coins based on Ethereum) have 18 decimal places. This is handled fine internal by Ledger; however, there are certain formatting issues.

Here is an example ledger:

commodity USD
    note United States Dollar
    format USD 1,000.00
commodity BTC
    note Bitcoin
    format BTC 1,000.00000000
commodity ETH
    note Ether
    format ETH 1,000.000000000000000000

2019-01-01 * Opening balance
    Equity:Adjustment
    Assets:Bank                                   USD 1,000.00

2019-01-02 * Buy ETH with USD
    Assets:Crypto                                     ETH 1.23 @ USD 200.00
    Assets:Bank

2019-01-03 * Buy BTC with ETH
    Assets:Crypto                                     BTC 0.34 @ ETH 1.98
    Assets:Crypto

Note that although ETH handles 18 decimal places of precision (and all transactions ultimately have this precision), various exchanges will differ in what precision they use/round to.

Here are a few issues what arise from such a large number of decimal places

These are the only two places I've seen an issue so far, though I have not looked for many other places yet.

asheidan commented 5 years ago

Would using Commodity equivalences (https://www.ledger-cli.org/3.0/doc/ledger3.html#Commodity-equivalences) be a feasible solution for this?

JP-Ellis commented 5 years ago

No, it wouldn't in general.

In the above example I don't use all decimal places and thus I could just not use the full precision (which would be equivalent to ignore the cents in all USD transactions).

But if for example I changed the ETH balance changed from ETH 0.556800000000000000 to ETH 0.556800000000000001, then defining a new subdivision would not change the fact that I need such a large number of digits.