Hledger: stricter/more correct handling of unbalanced multicommodity transactions

Created on 16 Jan 2020  Â·  38Comments  Â·  Source: simonmichael/hledger

It is suggested in the docs at https://hledger.org/1.14/journal.html under the "Transaction Prices" section that one can record an FX transaction thusly in the journal:

2009/1/1
  assets:euros     €100          ; one hundred euros purchased
  assets:dollars  $-135          ; for $135

and this works. But it ought not to. The balance sheet no longer balances because neither commodity posting has a contra. hledger should never allow this as the basic double entry check that one's accounts are in order is that the balance sheet sums to zero in all currencies (and securities and commodities.) Anyone doing FX in this way loses this most basic of accountancy checks, that every transaction balances in every currency.

The correct way to post the above is something like the following:

2009/1/1
  assets:euros     €100          ; one hundred euros purchased
  assets:dollars  $-135          ; for $135
  control:fx

Then the balancing postings automatically get done for you by hledger, and the balance sheet continues to balance.

If one believes that the invention of double entry bookkeeping was a great thing then hledger should prevent an imbalance being created in the balance sheet for FX transations just as it does for all other transactions.

Possibly helpful details:

  • a minimal reproducible example: see above
  • related documentation: referenced above
  • my hledger version: 1.14
  • installation: apt-get
  • platform: devuan (i.e. vanilla debian but without systemd)
A WISH bounty journal code design

Most helpful comment

Some updates/next steps related to this:

  • I wrote a newer https://hledger.org/investments.html tutorial touching on this issue
  • Let's implement conversion rate inference from a balanced @-free transaction - it seems possible and would allow -B and --infer-value to work without the need for @ notation
  • Let's try changing how we store @ entries, adding "equity:conversion" postings where needed, so that they are just syntactic sugar for the balanced @-free form. Perhaps print --explicit would show the balanced form. This could be quite disruptive but let's explore it.
  • Let's clarify whether we need separate notations for expressing current conversion rate and original cost basis, like Ledger/Beancount's @ and {}, or some improvement on that, and/or if we can do something simpler using accounts as in the above tutorial.
  • All help welcome. I have some bounty money which I'll apply here too.

All 38 comments

Thanks for the report and clear advice. We also have #758 open for this. I would be fine with this personally, but it would be a breaking change in very long-established behaviour so I think a clear consensus and favourable community discussion of this are required.

I now see this has been reported long ago. It is the same issue as #115 and #86. I very much like the solution proposed in #115 and would like to re-emphasise that the basic rules of double entry book-keeping should be enforced by any good accounting system. The alternative of memorandum style (single entry) book-keeping is available to "accountants" but note that it is not allowed by hledger on transactions with postings only in one currency. Every transaction must balance in every commodity, and if this rule is not followed then the balance sheet will not sum to zero, the most standard basic check that one's books are in order. Repeating myself, I know.

One doesn't allow a transaction with only one posting for the purchase of a pencil. One has to find a place for the contra, there are two entries, one in expenses and another in the cashbook. There is no difference, purchase of a pencil, and purchase of FX. If one wants to account for pens as a commodity then that too can be done, but there are 4 postings. You post to stationarycupboard and assets in the "pencil" commodity, and you post to cashbook and expenses for the currency. Same with FX: You need to find somewhere to post the contras, most obviously the contras are posted to the reserves or equity account (because one is actually changing the reserves when one does FX), or some FX control account.

To muddy the waters as does the hledger docs by considering what one is using the FX for is not a good idea. In real life one does the FX transaction and the foreign purchase in two separate independent transactions, one at the bank and the other with the seller. The same should be true in your book-keeping. You can choose either to keep the books completely ignorant of the FX currency and post everything in local currency equivalents, or you can choose to post the FX to the books. If you post the FX to the books then the FX currency postings must balance. What hledger and Ledger before it seem to have supported is the halfway house which allows memorandum accounting, not double entry, for FX. And the breaking of double entry rules which protect the integrity of your accounts.

@psb777 , may I disagree with your suggestion. I consider they way hledger works now in fact balance and respect the double entry principle.

It is better said that in your example, the transaction doesn't explicit balance, but if you consider it is implicit that one EUR equal 1.35 USD, it does indeed balance, at least in the default currency.

I guess you may be tracking only currency transactions. Because people usually works with 2 or 3, balancing like you are suggesting makes sense. But if you are tracking investments, you will end up with a bunch of commodities, and your balance report will be unreadable if you want to see all commodities balancing in one shot.

This is how I think your example should be written:

D USD 1,000.00

P 2009-01-01 EUR USD 1.350
2009/1/1
  assets:euros                 EUR 100 @@ 135 USD          ; one hundred euros purchased
  assets:dollars               USD -135                                 ; for $135

Balance in USD

hledger b -B
                   0  assets
        USD -135.000    dollars
         USD 135.000    euros
--------------------
                   0

balance in EUR

hledger b -X EUR
                   0  assets
            EUR -100    dollars
             EUR 100    euros
--------------------
                   0

This way your transaction is balancing in each currency. In your suggestion, you create an account that is not Asset, Liability, Income not Expense. It will be difficult to explain that to a new user

I follow what you say but you are not correct. What you describe is a mix'n'match of memorandum (single entry) bookkeeping with double entry. So fundamental is the following in double entry:

_(We assume signed amounts in all the following where CR is -ve and DR is +ve. This can all be restated in CR and DR with positive only numbers if reqd.)_

(1) Assets + Reserves + Liabilities = 0, and this is true for each commodity in which one posts.

(2) Each transaction preserves (1) above and this requires that the amounts in each commodity sum to zero in each transaction.

When one opens one's accounts for an existing business one would make many postings and for the GBP current account one posts that to an ASSET:CASH account - representing what is yours at the bank, and one posts a contra to the RESERVES:CASH account representing what belongs to the shareholders of the business, should the business pay out its assets, or should the business close. If the business has a USD account then should the business close then what the business will own to the shareholders will be the USD in that account. Therefore there must be a balancing USD entry in RESERVES:CASH if there is ASSETS:CASH entry in USD.

The fundamental rules of accounting say if you have an ASSET then it must appear in the RESERVES (and if you have a LIABILITY it too must appear in the RESERVES). If you insist on having a USD balance anywhere in ASSETS (or LIABILITIES) then there MUST be a corresponding USD balance in RESERVES.

That's why this is INCORRECT:

2020/02/02: Convert some of our GBP to USD
    assets:cash:Barclays       -100 GBP
    assets:cash:Citibank         130 USD

but this is CORRECT

2020/02/02: Convert some of our GBP to USD
    assets:cash:Barclays       -100 GBP
    reserves:cash                    100 GBP
    assets:cash:Citibank         130 USD
    reserves:cash                    -130 USD

There is one other correct way, and that is to post everything in your reporting currency GBP (say) and have no USD postings at all. That will require FX P&L postings from time to time but it works.

What does not work is the half way house nonsense of a USD posting in ASSETS (or LIABILITIES) not balanced by a RESERVES USD posting. What that would do is create a set of accounts which breaks the A+L=R equation which has two consequences. The first is a technical but important that an imbalance doesn't immediate inform one of a problem with the accounts; the second is that it MISREPRESENTS the position to the shareholders.

@edkedk99 : Your misunderstanding seems to arise or you justify from the balancing postings going to "fx:control". Of course that account is an EQUITY (or RESERVES) account as it is neither in ASSETS nor in LIABILITIES. The account could be better named. It could be EQUITY:CONTROL:FX accumulated to period end when the balances are posted to EQUITY:CASH or they could be posted to EQUITY:CASH immediately.

As explained above, when you set up a new accounting system for an existing business you debit the cash at bank to ASSETS:CASH (or a sub-account of that) as that is owed to the business by the bank and you credit the contra to the RESERVES:CASH account because that is what the business owes the shareholders. When you switch your ASSETS from one currency to another the same MUST happen in the RESERVES.

@psb777,

The naming convention in your post confused me, but know it is clear that 'control:fx' or 'reserves:cash' means 'Equity:Capital'

I will insist in my point, even considering you are correct in the "double entry principles". The problem I see on how you are doing your accounting is on having a **multi-currency EQUITY account". I am not an accountant, so please correct me if I am wrong, but the convention is that EQUITY, and more broadly a BALANCE SHEET is always in one single currency. I have never seen, even in public companies listed in exchanges to post its balance sheets like you propose. AFAIK regular accounting software doesn't allow that to happen.

I think Hledger was not designed with focus 100% to be this multi-currency/commodity tool you expect, but rather to allow you to do single-currency accounting with some helpers that allows you to follow the price evolution of your assets, and that is not part of a strict accounting software. In my view, you use hledger to do strict accounting or to follow your asset evolution. Expecting hledger to be both at the same time will cause many problems or will get too complicated.

But anyway, this is just different opinions, one more strict than the other. Some days before seeing your post, I realized 'hledger-iadd' followed you understanding in this topic. I filled an issue at 'hledger-iadd' repository, defending that because if 'hledger' allows this entry, 'hledger-iadd' should allow too. They accepted my reasoning and adjusted their software.

I suggest you to check the addon 'hledger-check.hs'. It will allow you to do the check you think it is missing. I think there is a low probability that hledger developers make the change you propose because it could break the journal for existing users

it could break the journal for existing users

We could help with migration, or it could be an option, eg part of --strict mode.

@simonmichael ,

If that is feasible, it is a solution. I personally struggle with the concept of having a multi-currency balance sheet, because this is not an accounting standard, but on the other side, I am new to hledger.

I also worry how this new way of balance check will add in complexities for a new user who drops in hledger.org and tries to understand the commodity concept, which even today is not that easy.

In my view, if hledger maintains an historic compatibility with the also incorrect Ledger then it is that compatibility mode which requires a command line flag, not the proper implementation of double entry which hledger does so effortlessly, but not being documented, is not done the easy way by many.

I am not trying to create work but save everyone work. It really is easier and more readily understood the proper way. Please read on but first let me address some issues raised.

Equity, Reserves and Capital are equivalent words from a double entry accounting perspective and mean effectively the same thing for different styles of business. I see that hledger docs see Equity and Reserves as equivalent.

Multi-currency and multi-commodity and multi-security double entry bookkeeping is done routinely in financial firms where they must properly account for assets, liabilities and reserves which have long since been dematerialised (to use a jargon word) and turned into debt and options and futures and derivatives just as cash was long ago. It is far from unusual, indeed mandatory in any City firm.

However, regulatory reporting and tax reporting often requires that everything be reported in one designated base reporting currency. In such circumstance there can be ZERO balances denominated anywhere in the accounts except in the specified currency. That's where the hledger -V and -X xxx options come in very useful. However, there are also ZERO circumstances where the sum of the ASSETS, LIABILITES and RESERVES is not zero. hledger unfortunately allows this last eventuality. But you cannot usually present books to your auditor or the taxman or the regulator where the A+L+E=0 rule is broken. At the very least your auditor will have to fix your books before signing them off.

There is in most circumstances for almost all business little need to post in anything other than the base currency, as I have explained elsewhere you take the FX out of the books when you buy or sell something in another currency and you report the cost or proceeds in the local currency.

It is far easier to do FX (if one must) the proper way than the way hledger documents and which @edkedk99 favours. An example which persuasively demonstrates this follows subsequent posting:.

Read this file:
explain.txt
You'll have to rename the following two files removing the .txt suffix.
memo.journal.txt
dbl.journal.txt

Paul, thanks for the explanations, background and especially the nice clear examples. Are you an accountant ? Our wheels often grind slowly, so if you see no response for while don't think it means disagreement. It takes free brain cycles to digest and work on this, so your input is helpful and will be [re]read later if not immediately. By the way, we don't expect you to do all the work, but if you would be interested in working on a pull request, that can be very effective, since folks can try it out and report issues.

With current hledger, I think I'm right in saying there's nothing stopping anyone from using more correct and disciplined journal entries, yes ? Stricter behaviour gives more error checking possibilities, but in practice I think we can detect errors pretty easily by other means. So I don't feel any burning urgency on this.

We have always planned a strict mode where we can apply more strict rules. This will be an optional extra at first, which is good for experimentation. Questions of changing default behaviour will come later, once we have more experience.

I think I'll inline your example above, to encourage folks to try it out. (If you prefer to edit your comment, I'll delete this one.). Here's your

memo.journal (the old "wrong" way):

D USD 1,000.
commodity USD 1,000.
commodity EUR 1,000.

2008/1/1 opening balance
  assets:dollars         USD  100 
  equity:cash

P 2009-01-01 EUR USD 0.667

2009/1/1 FX purchase
  assets:euros           EUR  150 @@ 100   
  assets:dollars         USD -100         

P 2010-01-01 EUR USD 0.750

P 2011-01-01 EUR USD 0.800

2011/1/1 FX sale
  assets:euros           EUR -150 @@ 120  
  assets:dollars         USD  120

P 2012-01-01 EUR USD 0.950

dbl.journal (the new "right" way) (with comments added to show differences):

D USD 1,000.
commodity USD 1,000.
commodity EUR 1,000.

2008/1/1 opening balance
  assets:dollars         USD  100 
  equity:cash

P 2009-01-01 EUR USD 0.667

2009/1/1 FX purchase
  assets:euros           EUR  150  ; <-- no price
  assets:dollars         USD -100         
  equity:cash                      ; <-- extra posting

P 2010-01-01 EUR USD 0.750

P 2011-01-01 EUR USD 0.800

2011/1/1 FX sale
  assets:euros           EUR -150  ; <-- no price
  assets:dollars         USD  120
  equity:cash                      ; <-- extra posting

P 2012-01-01 EUR USD 0.950

and explain.txt (discussion of the above):

I wish to attempt to demonstrate conclusively why the style of FX dealing
or commodity exchange as documented in hledger and as permitted by hledger
is

1) is not just a less purist way way of doing things,
2) is not an easier way, it's more difficult,
3) produces less meaningful reports and
4) is just wrong.

Attached are two files.

The memo.journal file does the FX as per the hledger documentation, using
memorandum style accounting weirdly allowed by hledger only for commodity
trading.

The dbl.journal file does the FX correctly, properly doing double entry in
all the commodities all the time.

All will readily see there is practically the same amount of typing involved.
Or even less for the dbl file as for the memo file because the memo file
still requires extra adjustments to later fix the reserves, and I have not
provided suggestions for those messy fixes.

To illustrate why the memorandum style of FX accounting is so unsatisfactory
you just need to dirstly understand what each file identically models - a
conversion from dollars to euros and back again later at a different price -
and then run and contrast these two sets of balance reports.

hledger bal -f memo.journal   -X EUR
hledger bal -f memo.journal   -B
hledger bal -f memo.journal   -V
hledger bal -f memo.journal   

hledger bal -f dbl.journal   -X EUR
hledger bal -f dbl.journal   -B
hledger bal -f dbl.journal   -V
hledger bal -f dbl.journal   

You may wish to run these reports in intermediate dates too using the
following each in turn on both the memo and dbl examples.

--end=2008/07/01
--end=2009/07/01
--end=2010/07/01
--end=2011/07/01
--end=2012/07/01

Note that in the reports from the "memo" accounting even though a profit is
made by the buying and selling of currency this is not reflected in the
equity/reserves. 

Note how naturally everthing flows through with the "dbl" style, no effort at
all, and that the profit is reflected in the reserves, and there is no weird
hangover of non-existent extraneous balances.

I'm going to practice the new style (what name communicates it - "balanced conversions" ?) in my 2020 journals to get some experience with it. I'd welcome reports from any other PTA users, especially if you convert an old journal.

hledger is first and foremost an accounting tool, but not only that. There's a long tradition of PTA users tracking time, calories, inventory and what not. We'll keep support for that kind of flexibility one way or another.

Here's a vague misgiving I've had: "sure, we added an extra posting so the conversion amounts go there instead of on the main postings. But that can hold anything, so it doesn't really add any error checking (that hledger could report), does it ?"

If you write all the equity amounts explicitly, ok now it's explicit. But at the end of the year you have this equity account containing a zillion currencies, and does its balance tell you anything useful ? Is there really more error checking ?

Even now, still blissfully inexperienced with the new style, I do see some advantages.

  • It keeps the main accounts simple, involving just their native currency.
  • There's no need for @ transaction prices or the -B flag. (Ever ? Or, when are those still appropriate ?)
  • It gathers the balancing amounts from currency/commodity conversions into a single account, which you can exclude from reports, or inspect to get an overview of all conversions (and perhaps we can learn other useful things from it ?)

Technically we have not added an extra posting. We take advantage of a
short-cut feature of hledger to make TWO extra postings. I know you know
that, but nevertheless, it's important.

So what we actually post in real life ought most fully properly be this:

2020/01/01 FX
assets:cash:Citibank -11 USD
equity:cash 11 USD
assets:cash;Westpac 14 AUD
equity:cash -14 AUD

Why are the equity:cash posting important other than for the technical
reason that they allow the bookkeeping rule A+L+E=0 to be kept?

It's because it is not a technical rule, it's a real important legal rule!
The equity/reserves/capital ledger shows what is the property of the
shareholders/partners/householder. The assets ledger shows what is owed to
the business/entity for which the accounts are being performed. The 14 USD
isn't in our possession, it's at the bank! The 11 USD is no longer owed us
by the bank. Hence the posting in the assets ledger. Why the postings in
the equity ledger? Well, why any postings in the equity ledger? It shows
what the enterprise owes its owners. Well, what the enterprise owes its
owners is 11 USD less than it did before, and 14 AUD more than it did
before. And as long as you book USD OR BoeingCommonStock or IBM as a
commodity in the Assets ledger you MUST reflect that in the equity ledger.

A way around this is to only book the USD value of the stocks and
currencies in the assets ledger. But then how will you automatically book
P&L upon a price change, you will have to do it manually. Whereas, as per
my example, if we swap back from AUD into USD at an improved price thusly

2020/01/01 FX
assets:cash:Citibank 13 USD
equity:cash -13 USD
assets:cash;Westpac -14 AUD
equity:cash 14 AUD

then our USD 2 profit is plainly shown in increased assets at Citibank
matched by an increased liability to our shareholders in the equity ledger.
That is how it should be. The business no longer owns any AUD, and the AUD
balance has disappeared from the books everywhere.

But say it had not. Say we didn't sell the AUD, or that we bought more, or
sold half, then the noise/nonsense postings are neither noise nor nonsense,
they reflect the ongoing change in the reserves position of the business.
It's not noise, it's information!

You ask what do you do with the accumulating FX postings in the equity
ledger. The same as you do with the accumulating postings in the expenses
ledger. At some point you post the balance to a year-end account, or you do
what I do: I leave them exactly where they are: The accounts are a record
of your business.

I haven't been using hledger long. I will probably put all the postings in
a 2020.journal file which I will include from the main hledger.journal
file. This will have several advantages. It will mean I won't mistakenly
make changes to historical data, and it keeps the current file short.

I really like hledger, by the way! Thank you.

[email protected]

On Tue, 4 Feb 2020 at 01:03, Simon Michael notifications@github.com wrote:

Here's a vague misgiving I've had: "sure, we added an extra posting so the
conversion amounts go there instead of on the main postings. But that can
hold anything, so it doesn't really add any error checking (that hledger
could report), does it ?"

If you write all the equity amounts explicitly, ok now it's explicit. But
at the end of the year you have this equity account containing a zillion
currencies, and does its balance tell you anything useful ? Is there really
more error checking ?

Even now, still blissfully inexperienced with the new style, I do see some
advantages. It keeps the main accounts simple, involving just their native
currency. There's no need for @ transaction prices or the -B flag. (Ever ?
Or, when are those still appropriate ?) It gathers the balancing amounts
from currency/commodity conversions into a single account, which you can
exclude from reports, or inspect to get an overview of all conversions (and
perhaps we can learn other useful things from it ?)

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/simonmichael/hledger/issues/1177?email_source=notifications&email_token=ABXVLL3HNHW4LVKGTW7UHILRBC5HTA5CNFSM4KHVV562YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKV7C2Y#issuecomment-581693803,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABXVLL63OW57FRSOGOCZBOLRBC5HTANCNFSM4KHVV56Q
.

What does the accumulation of posting in the equity:cash account tell you?
The balance of each currency tells you how much of each currency is owed
the shareholders/partners/householders should you wind the
firm/business/marriage up.

What is the error checking? The std double entry error checking, but in
addition the auditors will check that the assets are in the bank, the
vault, the aircraft hangar, at the share custodian, and that the
liabilities similarly, and that the shareholders are happy with the value
of the company, this is the size of the reserve ledger.

For extra paractical error checking from time to time you put a dated
reconciled balance assertion in for all the main accounts within assets and
liabilities and reserves and if anyone makes a backdated posting then
hledger will tell you.

I'm unsure it's a good think that hledger let's you not type the amount
twice. Any typo should go detected. I try and make all my postings explicit
as its best to force detection of a typo: I like it that this is rejected.

2222/22/22
xx:yy 12.34
zz:aa -12.35

[email protected]

On Tue, 4 Feb 2020 at 01:03, Simon Michael notifications@github.com wrote:

Here's a vague misgiving I've had: "sure, we added an extra posting so the
conversion amounts go there instead of on the main postings. But that can
hold anything, so it doesn't really add any error checking (that hledger
could report), does it ?"

If you write all the equity amounts explicitly, ok now it's explicit. But
at the end of the year you have this equity account containing a zillion
currencies, and does its balance tell you anything useful ? Is there really
more error checking ?

Even now, still blissfully inexperienced with the new style, I do see some
advantages. It keeps the main accounts simple, involving just their native
currency. There's no need for @ transaction prices or the -B flag. (Ever ?
Or, when are those still appropriate ?) It gathers the balancing amounts
from currency/commodity conversions into a single account, which you can
exclude from reports, or inspect to get an overview of all conversions (and
perhaps we can learn other useful things from it ?)

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/simonmichael/hledger/issues/1177?email_source=notifications&email_token=ABXVLL3HNHW4LVKGTW7UHILRBC5HTA5CNFSM4KHVV562YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKV7C2Y#issuecomment-581693803,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABXVLL63OW57FRSOGOCZBOLRBC5HTANCNFSM4KHVV56Q
.

Great! I'm learning. For most-correct accounting, maintain the accounting equation within each commodity. Thanks Paul!

I'm a software techie, or was, many years ago. We ran a business writing
systems for stockbrokers and the systems had at their heart a
multi-security double entry accounting system. I've thought more about the
technical aspects of bookkeeping, about bookkeeping as maths and logic,
than most accountants.

Hledger incorporates so much of what we did, and it does it so well. We
used relational databases (we needed multi-user concurrency) but hledger is
perfect for my own purposes, managing my investments and a few foreign bank
accounts.

I love the idea of getting my head around Haskell but GitHub I'm unsure
I'll ever be able to cope with.

I'm not sure I'll be able to do any Haskell programming but there are many
ways to contribute and I hope I do, I haven't pissed you off. Yet!

:-)

On Tue, 4 Feb 2020, 12:21 am Simon Michael, notifications@github.com
wrote:

Paul, thanks for the explanations, background and especially the nice
clear examples. Are you an accountant ? Our wheels often grind slowly, so
if you see no response for while don't think it means disagreement. It
takes free brain cycles to digest and work on this, so your input is
helpful and will be [re]read later if not immediately. By the way, we don't
expect you to do all the work, but if you would be interested in working on
a pull request, that can be very effective, since folks can try it out and
report issues.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/simonmichael/hledger/issues/1177?email_source=notifications&email_token=ABXVLL7BCKNQQLXU6YTM3IDRBCYINA5CNFSM4KHVV562YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKV4S5Y#issuecomment-581683575,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABXVLL7T7D3JDKLLMF7HZW3RBCYINANCNFSM4KHVV56Q
.

Oh, fantastic! Welcome.

@psb777

I ran your examples and detected you are not following hledger's website instructions in your memo.journal file, and this mistake causes your reports to print wrong results.

The '@' or '@@' symbol doesn't mean 'at', as it is commonly understood in common language. In PTA context, '@' means costing.

So, in 2011, you should have informed that your cost for those EUR 150 was USD 100, and not USD 120.

So, to follow hledger's official instructions, memo.ledger should be like below

D USD 1,000.
commodity USD 1,000.
commodity EUR 1,000.

2008/1/1 opening balance
  assets:dollars         USD  100 
  equity:cash

P 2009-01-01 EUR USD 0.667

2009/1/1 FX purchase
  assets:euros           EUR  150 @@ 100   
  assets:dollars         USD -100         

P 2010-01-01 EUR USD 0.750

P 2011-01-01 EUR USD 0.800

2011/1/1 FX sale
  assets:euros           EUR -150 @@ 100  ; Cost is 100, not 120  
  assets:dollars         USD  120
  Income:Fx Income                        ; The difference is your FX profit

P 2012-01-01 EUR USD 0.950

If you ran the suggested reports now, they will both give the same results. The difference seems to be that in memo.journal's case, the Income is explicit, while in db.journal the equity automatically increase or decrease.

Even arriving to the correct result, db.journal approach should not be suggested because it also changes the meaning of the '@' symbol, from cost to price, which is hard to spot in the file because those values are implicit.

I would say that memo.journal again is more compliant with accounting standards, which demands explicit income in the Balance Sheet. In db.journal, you would need to calculate manually the difference by looking at the evolution

Thank you @edkedk99, very interesting also. I always pronounce @/@@ as "at", but you make it clear that it can be used to mean two different things:

  1. when buying or selling: the cost or sale price in the current transaction, ie https://hledger.org/journal.html#transaction-prices

or

  1. when selling: the cost at which this asset/liability was acquired, ie its cost basis

In hledger, that is; I think Ledger has different syntax for each case (@/@@ vs. {= }, or something similar).

I'm not sure this is made clear anywhere on hledger.org - if it is, please point me to it ?

If you ran the suggested reports now, they will both give the same results.

I won't believe that until I see your commands and output. :) I get different results from all three journals here.

$ hledger bal -f memo2.journal -BV
hledger: "/b1/home/psb/PsbPrivate/hledger/tutfx/memo2.journal" (lines 19-21)
could not balance this transaction (real postings are off by USD 20)
2011/01/01 FX sale
assets:euros EUR -150 @@ USD 100
assets:dollars USD 120

[email protected]

On Tue, 4 Feb 2020 at 12:38, edkedk99 notifications@github.com wrote:

@psb777 https://github.com/psb777

I ran your examples and detected you are not following hledger's website
instructions in your memo.journal file, and this mistake causes your
reports to print wrong results.

The '@' or '@@' symbol doesn't mean 'at', as it is commonly understood
in common language. In PTA context, '@' means costing.

So, in 2011, you should have informed that your cost for those EUR 150 was
USD 100, and not USD 120.

So, to follow hledger's official instructions, memo.ledger should be like
below

D USD 1,000.
commodity USD 1,000.
commodity EUR 1,000.

2008/1/1 opening balance
assets:dollars USD 100
equity:cash

P 2009-01-01 EUR USD 0.667

2009/1/1 FX purchase
assets:euros EUR 150 @@ 100
assets:dollars USD -100

P 2010-01-01 EUR USD 0.750

P 2011-01-01 EUR USD 0.800

2011/1/1 FX sale
assets:euros EUR -150 @@ 100 ; Cost is 100, not 120
assets:dollars USD 120
Income:Fx Income ; The difference is your FX profit

P 2012-01-01 EUR USD 0.950

If you ran the suggested reports now, they will both give the same
results. The difference seems to be that in memo.journal's case, the Income
is explicit, while in db.journal the equity automatically increase or
decrease.

I would say that memo.journal again is more compliant with accounting
standards, which demands explicit income in the Balance Sheet. In
db.journal, you would need to calculate manually the difference by looking
at the evolution

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/simonmichael/hledger/issues/1177?email_source=notifications&email_token=ABXVLL4RCPRPOU3FODQ6YP3RBFOVDA5CNFSM4KHVV562YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKXPLMY#issuecomment-581891507,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABXVLL5PTCFTDY3R3572A43RBFOVDANCNFSM4KHVV56Q
.

@psb777

You forgot the the last line -> Income:Fx Income

2011/1/1 FX sale
  assets:euros           EUR -150 @@ 100  ; Cost is 100, not 120  
  assets:dollars         USD  120
  Income:Fx Income                        ; The difference is your FX profit

@simonmichael

My modified memo.journal

D USD 1,000.
commodity USD 1,000.
commodity EUR 1,000.

2008/1/1 opening balance
  assets:dollars         USD  100 
  equity:cash

P 2009-01-01 EUR USD 0.667

2009/1/1 FX purchase
  assets:euros           EUR  150 @@ 100   
  assets:dollars         USD -100         

P 2010-01-01 EUR USD 0.750

P 2011-01-01 EUR USD 0.800

2011/1/1 FX sale
  assets:euros           EUR -150 @@ 100  ; Cost is 100, not 120  
  assets:dollars         USD  120
  Income:Fx Income                        ; The difference is your FX profit

P 2012-01-01 EUR USD 0.950


hledger bal -f memo.journal -X EUR

             EUR -21  Income:Fx Income
             EUR 126  assets:dollars
            EUR -105  equity:cash
--------------------
                   0

hledger bal -f memo.journal -B

             USD -20  Income:Fx Income
             USD 120  assets:dollars
            USD -100  equity:cash
--------------------
                   0

hledger bal -f memo.journal -V

             USD -20  Income:Fx Income
             USD 120  assets:dollars
            USD -100  equity:cash
--------------------
                   0

hledger bal -f memo.journal

             USD -20  Income:Fx Income
             USD 120  assets:dollars
            USD -100  equity:cash
--------------------
                   0

@simonmichael

I'm not sure this is made clear anywhere on hledger.org - if it is, please point me to it ?

I think documentation makes it clear. One problem is that the symbol '@' means 'at' in regular speech, so a regular user when adding a transaction may relate the symbol to the usual meaning, and not the docs meaning. Maybe we could emphasize this difference in the docs

See in https://hledger.org/track-investments.html

You end up with the correct amount in your depot. At some point, however, you will have to report the capital gain that you realized with your sale. This gain is currently invisible. In fact, we have violated the double-entry principle and created money out of nowhere.

Let’s report our sale in a different way.

2017/1/4 sell shares at $250
  assets:shares         -10 TSLA @ $200  ; cost basis (must be tracked by user!)
  assets:depot          $2500            ; cash proceeds
  revenue:capital_gains                  ; deduce profit

See: cost basis (must be tracked by user!)

@edkedk99 it's not critical, but if you have time, for the sake of clarity, could you show what you meant by "If you ran the suggested reports now, they will both give the same results." Here I show my results with your journal and @psb777's.

~/src/hledger/examples/pb-1177$ hledger bal -f edk.journal -X EUR
             EUR -21  Income:Fx Income
             EUR 126  assets:dollars
            EUR -105  equity:cash
--------------------
                   0
~/src/hledger/examples/pb-1177$ hledger bal -f edk.journal -B
             USD -20  Income:Fx Income
             USD 120  assets:dollars
            USD -100  equity:cash
--------------------
                   0
~/src/hledger/examples/pb-1177$ hledger bal -f edk.journal -V
             USD -20  Income:Fx Income
             USD 120  assets:dollars
            USD -100  equity:cash
--------------------
                   0
~/src/hledger/examples/pb-1177$ hledger bal -f edk.journal 
             USD -20  Income:Fx Income
             USD 120  assets:dollars
            USD -100  equity:cash
--------------------
                   0
~/src/hledger/examples/pb-1177$ hledger bal -f dbl.journal -X EUR
             EUR 126  assets:dollars
            EUR -126  equity:cash
--------------------
                   0
~/src/hledger/examples/pb-1177$ hledger bal -f dbl.journal -B
             USD 120  assets:dollars
            USD -120  equity:cash
--------------------
                   0
~/src/hledger/examples/pb-1177$ hledger bal -f dbl.journal -V
             USD 120  assets:dollars
            USD -120  equity:cash
--------------------
                   0
~/src/hledger/examples/pb-1177$ hledger bal -f dbl.journal
             USD 120  assets:dollars
            USD -120  equity:cash
--------------------
                   0

See in https://hledger.org/track-investments.html

That's a useful doc, thanks. (Tier 2 doc, could use an update, but explains the two meanings nicely.)

@simonmichael ,

If you ran the suggested reports now, they will both give the same results.

It means that in the 4 reports if you sum 'equity:cash' and 'Income:Fx Income' in edk.journal, the value is the same as in 'equity.cash' from dbl.journal alone.

In fact, I should have said that equity will be the same after you transfer profits to accumulated profits in an equity subaccount

@edkedk99, I really don't mind how anybody does their accounting, I'm
merely arguing (1) hedger should not by default allow the double entry
bookkeeping rules to be broken and (2) that the official documentation
should promote the better and correct method, the one which always leaves
the balance sheet in balance.

Comparing the documented method, which I perhaps unfairly call "your"
method, with the rules compliant method, which I unfairly call "my" method,
how would we choose one over the other? What are the pros and cons, one
method over the other? I cannot think of any advantage of "your" method
save that that is how some people use hledger, and we ought to provide a
compatibility option so as to continue to support the documented method,
even if the documentation is to change. The other way, "my" way, has these
advantages, minor and major:

(1) Character count. Your method requires " @@ 100.00" twice, plus
"income:fx" once, 29 characters. My method requires "income:fx" twice, 18
characters.

(2) Your method requires that you go and look up what you paid for the
commodity when you sell it. This is an unnecessary step in my method. When
selling a proportion of it you will need to calculate the cost, if it is
the "@@" convention you've used.

(3) In your method the balance sheet remains out of balance, breaking the
most important rule in double entry bookkeeping, A+L+E=0, forever, or until
exactly the entire amount of the FX is sold, which will not ordinarily
happen, the FX having been obtained for some purpose other than
speculation. A+L+E will never, in practical terms, ever be zero again.

(4) As the price of the FX purchased changes over time the unrealised
profit does not appear anywhere easily reported by hledger except as the
un-named imbalance in the balance sheet. You cannot drill down into this
imbalance in the UI. And ever so weirdly the display of

hledger-ui -f your-way-with-equity-fx-not-income-fx.journal --end=2010/07/01 -V

is this:

assets:dollars 0
assets:euros USD 112
equity:cash USD -100
equity:fx 0

whereas this command

hledger-ui -f my-way-using-equity-fx-not-equity-cash.journal --end=2010/07/01 -V

displays this:

assets:dollars         0
assets:euros     USD 112
equity:cash       USD -100
equity:fx            USD -12

Paul

@psb777

I came to the conclusion that we are discussing different approaches. I don't expect my report to balance with -V option, only with -B. But that is my personal take. As you mentioned earlier, you are new to hledger, so am I. Let's see what the developer and other users think about all of this.

Probably a good next step from this will be a concise faq/how-to on hledger.org, showing these different approaches and summarising pros/cons.
Next after that, I'd be in favour of a -s/--strict flag that disables the automatic commodity conversion that happens somewhere around here.

Yes, I agree with you both, @edkedk99 and @simonmichael. It's what works for you that counts, There is nothing wrong with hledger as it stands in version 1.16 save for my view that it should require a --compatible flag to work the old way rather than a --strict flag to behave, according to me, correctly. Hledger is great, very happy to have found it. Maybe an intermediate fix is a dispassionate documentation enhancement as suggested.

Suggestion: That there is an imbalance introduced by the @@ method ought generate a WARNING.

One question I have is how @psb777 's method interacts with the -B flag. It may very well be that this flag is not a wise way to display the desired information in any case, but given the following transaction

2000-01-01 Buy widgets
  expenses:widgets   1.00 USD @@ 1.50 CAD
  assets:cash       -1.50 CAD

how would you generate a report in which widget expenses were 1.50 CAD after converting it to this form?

2000-01-01 Buy widgets
  expenses:widgets   1.00 USD
  assets:cash       -1.50 CAD
  equity:fx         -1.00 USD
  equity:fx          1.50 CAD

Good question @Xitian9. -B or --value=cost use the posting's "transaction price". How do we infer the transaction price for each posting in the journal entry above ? And in general ?

(Maybe we already do that ? print -x on a bunch of such entries should be informative.)

Some updates/next steps related to this:

  • I wrote a newer https://hledger.org/investments.html tutorial touching on this issue
  • Let's implement conversion rate inference from a balanced @-free transaction - it seems possible and would allow -B and --infer-value to work without the need for @ notation
  • Let's try changing how we store @ entries, adding "equity:conversion" postings where needed, so that they are just syntactic sugar for the balanced @-free form. Perhaps print --explicit would show the balanced form. This could be quite disruptive but let's explore it.
  • Let's clarify whether we need separate notations for expressing current conversion rate and original cost basis, like Ledger/Beancount's @ and {}, or some improvement on that, and/or if we can do something simpler using accounts as in the above tutorial.
  • All help welcome. I have some bounty money which I'll apply here too.
Was this page helpful?
0 / 5 - 0 ratings

Related issues

hackeryarn picture hackeryarn  Â·  7Comments

Timonsc picture Timonsc  Â·  4Comments

MisterY picture MisterY  Â·  9Comments

cwarden picture cwarden  Â·  4Comments

simonmichael picture simonmichael  Â·  8Comments