[GNC-dev] bug 798366 - cross-currency capital gains
Lionel Élie Mamane
lionel at mamane.lu
Sat Nov 13 23:41:00 EST 2021
Hi,
I've started work on adding support to compute capital gains in
multi-currency situations; that is, when a lot from a
security-denominated account contains transactions with different
common currencies.
I have a "it works" patch in bugzilla
https://bugs.gnucash.org/show_bug.cgi?id=798366
Not very thoroughly tested in many scenarios, and see point 5 below.
1) It contains naked asserts, peeking at the rest of the code, I guess
I should replace them with g_assert
2) It changes the declaration (argument list / return type) of
xaccSplitGetCapGains
gnc_lot_get_balance_before
These had only one caller in the GnuCash code each.
I'm not sure if those are considered public stable API? The Debian
packaging doesn't have separate libgnucash / libgnucash-dev
packages, and the .so files seem not to be soname-versioned? So
there is no concept of stable API at all in libgnucash?
3) Since the capital gain is not anymore in the same currency as every
split it is computed over, xaccSplitGetCapGains now needs to return
not only a value (a gnc_numeric), but also the associated currency.
I created a struct for that, but I'm unhappy with the name. Any
better idea? And where to declare it? It sounds like it could
potentially be useful "throughout the code"? I'd call it "value_t"
or "amount_t" or some such (because a number without
unit/currency/commodity is meaningless, so in my mind a "value" or
an "amount" is with commodity), but this does not find with the how
these terms are used throughout the code...
struct amount_s
{
gnc_numeric amount;
gnc_commodity *commodity;
};
typedef struct amount_s amount_commodity;
4) The design choice is that the capital gain is _always_ computed in
the currency of the first currency-denominated ancestor of the
security-denominated account, even when all the splits in the lot
are otherwise in a single other currency. This lets the user
control the behaviour through the account hierarchy:
All investments under a EUR-denominated "investments" account: all
capital gains are in EUR, to follow the tax rule.
Want to track different portfolios under different currencies
(e.g. because they belong to different branches in different
countries, or because that's more important than computing the
right capital gains according to tax rules)? Create a placeholder
account for each portfolio, denominated in the chosen currency, and
put the securities accounts as subaccounts of this one.
This will _change_ _behaviour_ from previous versions in the
aforementioned case (all the splits in the lot are otherwise in a
single other currency). I think making an exception, and computing
capital gains in the common currency of the splits in the lot (or
the whole account) when there is one, and in another currency when
there is no common currency in the lot, would be too messy
semantics, and a too "unstable" behaviour. By "unstable" I mean too
big behaviour changes in response to small changes in data. It
would also fail to serve the above scenarios which I have in mind.
OTOH, the change of behaviour between versions is also not
attractive.
What to do? Does GnuCash have a mechanism to mark files as
backwards-incompatible (e.g. a "minimum version needed" tag)? We
could then mark it so as soon as a capital gain is computed in a
currency different than any of the splits in the lot.
Or, we could make the behaviour a per-file option, with:
- The default for _new_ files being the new better behaviour.
- Any file where the option is not set (that is, an older file), is
considered as having the option set for the old behaviour.
- Any file that doesn't have the option set, the setting is _not_
written on save (so as not to confuse older versions with an XML
tag they don't know).
This keeps backwards and upwards compatibility; it does have the
disadvantage that all existing users must explicitly opt in to the
better behaviour. Maybe we could automatically opt in any file
where all already computed capital gains are in the currency that
the new behaviour would choose, too?
5) Quite possibly my patch doesn't 100% deal correctly with scenarios
where the currency of the ancestor account changes; the code that
decides to mark capital gains as "dirty" needs to be made
currency-aware, and the code that changes the capital gains split
should reset the income account of the capital gains
transaction. Haven't looked into that yet. TOOD.
Best Regards,
Lionel
More information about the gnucash-devel
mailing list