Problem 1

Consider the following Ledger journal:

2019-07-01 Opening balances
    Assets:Current:Cash at Bank             $1000.00
    Equity:Opening Balances

2019-07-02 Application
    Assets:Current:International Account      100.00 EUR @ $1.10
    Assets:Current:Cash at Bank

2019-08-02 Application
    Assets:Current:International Account      100.00 EUR @ $1.05
    Assets:Current:Cash at Bank

2019-09-02 Redemption
    Assets:Current:Cash at Bank               $57.50
    Assets:Current:International Account      -50.00 EUR {$1.10} @ $1.15
    Income:Capital Gains

P 2019-10-01 00:00:00 EUR $1.30

After this journal, the balance of International Account should be 50.00 EUR {$1.10} + 100.00 EUR {$1.05}. Capital Gains should be ($1.15 − $1.10) × 50 = $2.50. Unrealized Gains should be ($1.30 − $1.10) × 50 + ($1.30 − $1.05) × 100 = $35.00. Per double-entry bookkeeping, all accounts should balance.

When we instruct Ledger to price accounts at market value, the difference between all accounts adds up to the unrealized gain as expected:

$ ledger balance -X $
            $1037.50  Assets:Current
             $842.50    Cash at Bank
             $195.00    International Account
           $-1000.00  Equity:Opening Balances
              $-2.50  Income:Capital Gains
--------------------
              $35.00

However, when we instruct Ledger to compute unrealized gains for us to get the balance sheet to balance, we find it does not:

$ ledger balance -X $ --unrealized
            $1037.50  Assets:Current
             $842.50    Cash at Bank
             $195.00    International Account
           $-1037.50  Equity
           $-1000.00    Opening Balances
             $-42.50    Unrealized Gains
               $5.00    Unrealized Losses
              $-2.50  Income:Capital Gains
--------------------
              $-2.50

Notice that Ledger has incorrectly calculated the net unrealized gain as $37.50. In other words, Ledger has failed to pick up that $2.50 of the unrealized gain was already realised and charged to Capital Gains. This results in a balance sheet which does not balance.

Problem 2

Consider further the following Ledger journal:

2019-07-01 Opening balances
    Assets:Current:Cash at Bank             $1000.00
    Equity:Opening Balances

2019-07-02 Application
    Assets:Current:International Account      100.00 EUR @ $1.10
    Assets:Current:Cash at Bank

2019-08-02 Expenditure
    Expenses:Travel                            20.00 EUR {$1.10}
    Assets:Current:International Account

P 2019-10-01 00:00:00 EUR $1.30

After this journal, the balance of the International Account should be 80.00 EUR {$1.10}. Travel expenditure should be $1.10 × 20 = $22.00. Unrealized Gains should be ($1.30 − $1.10) × 80 = $16.00. Again, all accounts should balance.

Ledger, however, produces some bizarre output:

$ ledger balance -X $ --unrealized
             $994.00  Assets:Current
             $890.00    Cash at Bank
             $104.00    International Account
           $-1020.00  Equity
           $-1000.00    Opening Balances
             $-20.00    Unrealized Gains
              $26.00  Expenses:Travel
--------------------
                   0

Ledger incorrectly reports the balance of Travel expenditure as $26.00. This is because Ledger has seen that 20.00 EUR {$1.10} was charged to travel, and has revalued that commodity based on market prices, whereas the expenditure should have been recorded at historical cost. This has accordingly thrown off the Unrealized Gains computation.

We can instruct Ledger to value commodities at historical cost:

$ ledger balance -X $ --historical
             $978.00  Assets:Current
             $890.00    Cash at Bank
              $88.00    International Account
           $-1000.00  Equity:Opening Balances
              $22.00  Expenses:Travel
--------------------
                   0

However, this of course now fails to account for the appreciation of the commodities in the International Account.

In general, there is no good way to tell Ledger to value assets at market value and revenues/expenses at historical cost (pursuant to AASB 121/IAS 21 para 39). This is natural, since Ledger is a very general-purpose tool and agnostic to what an ‘asset’ or ‘expense’ even is. This, however, means that generating trial balances and related reports can become very cumbersome.

In order to combat these two issues, and simplify the generation of well-formatted accounting reports, I developed ledger-pyreport.