On Thu, Jun 12, 2014 at 10:27 AM, Martin Michlmayr <[email protected]> wrote:

> * Martin Blais <[email protected]> [2014-06-12 02:05]:
> > I don't understand how it works in your example. You're entering
> > the positions with price conversion, using the @ sign:
> >
> > 2014-01-01 Details for shares
> >    Assets:Investments:Stocks:Share A    15 ShareA @ 20€
> >    Assets:Investments:Stocks:Share B    5 ShareB @ 100€
> >    Equity:Opening Balance
> >
> > But his sale is using the "cost" syntax (with {}):
> ...
> > How does this work under the covers?
>
> When you specify a cost with @, ledger internally keeps this cost
> around.  You'll have 15 ShareA {€20}.  You can see this with
> --lot-prices:
>      15 ShareA {€20}    Share A
>      5 ShareB {€100}    Share B
>
> So when you sell, what you do by saying 5 ShareB {€100} @ €120 is that
> you're selling the 5 particular ShareB with a cost of €100.
>
> Consider you bought 5 ShareB at 100€ and 5 at 110€.  Then you'd have:
>
>      5 ShareB {€100}
>      5 ShareB {€110}    Share B
>
> So which one are you selling?  You indicate that by using the {..}
> syntax.
>

This is just like Beancount, except that Ledger price conversions are the
same as "at-cost conversions."  That's what I thought: if I understand
correctly, Ledger *always* tracks converted units with their cost, even
when they're just price conversions. I think this will cause problems down
the road.  Beancount treats these two cases differently on purpose; I
believe this reflects the semantics of the operation closer and it allows
me to solve the multi-currency conversion problem (more detail below about
this).



> The price/rate is used to balance the transaction but the units are
> > deposited in the account without associated cost. This is what you
> > would do, for instance, if you were making a withdrawal in a foreign
> > country, e.g. in JPY and then spend it locally: you never think of
> > these yen in your wallet as "being held at such and such" exchange
> > rate, once converted, they have no "cost" to them anymore, all the
> > bills are just "yen".
>
> I think I actually disagree with this particular example.  When I get
> JPY out of an ATM, I'd say that a very clear exchange rate is attached
> to those JPY (because you know exactly how much you paid in your local
> currency).
>

It is true that this is a choice. Let's say you like in the US but you
infrequently travel to Europe. You *could* attempt to book all your EUR
expenses to lots at a particular cost. In practice, if you had to specify
the particular lot each time, this would be a impractical and a major PIA,
not even taking into account that that's not how you think about these
euros (they're just EUR when you spend them, you never think "oh I'll spend
my euros from the first withdrawal because I got a better rate on them".
The bills all look the same in your wallet. And they are indeed fungible.).
I'll argue that even if you build in an easy way to automatically choose a
lot - say you don't specify which lot of your EUR you're spending when you
subtract from an account - you really could build in a mechanism that
selects a random lot by default, or a specific method, such as FIFO, it's
still confusing to do so. What if you have 3 or more currencies?



But let's imagine you travel to Japan twice and you still have some
> JPY left over from the previous trip.  And now you go to the ATM
> again.  Then you have, let's say:
>
>  20000 JPY {$0.0090}
>  10000 JPY {$0.0098}  Assets:Cash
>
> So now things get complicated.  The best solution would probably be to
> just calculate the average cost and use that.
>

The best solution IMHO models how you think about the world.  They're just
JPY to me.

What would do if you have accounts in two countries, in two different
currency units, and you make withdrawals in JPY from these two accounts?
Now you have "JPY held in USD" and "JPY held in EUR", for instance.
Madness. And what happens if you make a conversion in the other direction?
I do this all the time: I live in the US but have some remaining non-liquid
assets in Canada. For a while I was doing transfers out from CAD to USD,
but sometimes, in order to pay a tax liability to the Canadian govt, I
might have a cash flow problem, I might have to make some temporary
transfers the other way around from USD to CAD in order to make the
payment. So now what... I have "USD in CAD" and "CAD in USD"?  No way...
that's just not how I think about it and that's also not how I want to
track it.



I suspect most people don't handle this correctly (me included :)
> When you use --lot-prices, you actually see what's going on.  I
> suspect most people do something like this:
>
> 2014-03-01 * Buy JPY
>    Assets:Cash                10000 JPY @@ $98
>    Assets:Cash
>
> 2014-03-02 * Spend JPY
>    Expenses:Foo               10000 JPY
>    Assets:Cash               -10000 JPY
>
> And now ledger will say: ledger -f ~/e bal  ets:cash
>                 $-98  Assets:Cash
>
> So everything *looks* great.  But if you add --lot-prices, you see
> that it's a mess:
>
>                 $-98
>           -10000 JPY
>  10000 JPY {$0.0098}  Assets:Cash
>

This is scary confusing to me. Imagine you have a realistic scenario with
10's of transfers in all directions? How can you check that the numbers
even make any sense?



>
> You have -10000 JPY and 10000 JPY {$0.0098}.  This is because you
> didn't specify the cost.  You should have done:
>
> 2014-03-02 * Spend JPY
>    Expenses:Foo               10000 JPY {$0.0098}
>    Assets:Cash               -10000 JPY {$0.0098}
>
> But who does that?
>

Nobody (I hope).



> (In fact, if you're homed in multiple countries and hold assets in
> > many places, holding currencies at cost creates incredible
> > unnecessary complexities, I'm quite certain this is not what's
> > happening).
>
> Yes, I agree.  Unfortunately, this situation applies to me and I
> struggle with this all the time.
>

So I believe I've cracked that problem in my code rewrite last year, and it
took me a long, long while to figure out an elegant solution that works
without a currency home. My solution - and i'm always open to new ideas for
a better one, a better one *may* exist, I'm not claiming that this is the
only solution - is to treat the two types of conversions differently. The
price conversions (using @) do not attach cost to the units, only
conversions at cost, (i.e., using {}). The cost is forgotten in the
resulting balance (the transaction still has the price attached to it, of
course). The resulting balancing algorithm for a transaction is simple:
https://hg.furius.ca/public/beancount/file/0a5f9bba3085/src/python/beancount/core/balance.py#l21

The problem that arises with this solution is that if you sum up the
balance of all the transactions, such as you do when you compute balances
for a balance sheet, the total amounts does not necessarily balance to
zero. Instead, what you'll find is the inverse of the sum of all price
conversions. That is, if you convert all of these amounts to a single
currency in order to zero them out, the rate at which you would have to do
so is the weighted average weight of all the conversion amounts (there's
something elegant about that fact actually).

So how do I zero out the balance sheet so that it is *precisely* exact?
Like everything else in Beancount: I add a transaction. This is an
automatically inserted transaction that shows up in the journal, BTW, the
user can see it, and it books to Equity:Conversions. I had a design choice
to make here: Let's see I have 3 conversion amounts to zero out, in 3
different currencies. I could have (a) chosen one currency as "special" and
converted all the other amounts to this currency at some set of rates which
makes the whole transaction balance. This has the advantage that it results
in a regular-looking transaction, albeit all to Equity accounts. (Note that
figuring out the rates to do this is not a trivial problem given the
general problem of N currencies to zero out - it admits many solutions -
but I think it's possible to come up with one solution using the history of
rate conversions and an optimization routine.) Or, (b) refuse to identify
any of the legs as "special" and balance all of these legs at a degenerate
"0 exchange rate."  (B) is a bit ugly, because in a sense it is really just
patching up the balance to sum up to zero. "We want it to be zero so let's
make it zero." Not super nice, but...  this is the one and only place where
such a funny kludge appears in the balance calculation, and it holds the
advantage that the resulting system truly is currency-agnostic and I don't
have to play tricks to find workable rates. I like that better.

So I chose solution (b).  It's here:
https://hg.furius.ca/public/beancount/file/0a5f9bba3085/src/python/beancount/ops/summarize.py#l187

In practice, it has never failed me and does not even cause weirdness. If
you draw out a balance sheet, you see two conversion entries: one to
account for all the conversions occurring before the beginning of the
exercise, and another one to account for the conversions during the period
of exercise. I'm even finding these entries useful now, because they report
on the sum total of the flow of currencies between all accounts during
those periods. The numbers produced are useful.

This is a complicated topic. I'd be really interested to hear about other
alternatives, perhaps better solutions.

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"Ledger" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to