> On Nov 14, 2021, at 6:15 AM, Lionel Élie Mamane <lio...@mamane.lu> wrote:
> 
> On Sat, Nov 13, 2021 at 10:24:33PM -0800, john wrote:
>>> On Nov 13, 2021, at 8:41 PM, Lionel Élie Mamane <lio...@mamane.lu> wrote:
> 
>>> 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.
> 
> 
>> Sorry I didn't intervene sooner. You need to read through
>> https://bugs.gnucash.org/show_bug.cgi?id=797796
>> <https://bugs.gnucash.org/show_bug.cgi?id=797796> before doing any
>> more work because your approach doesn't support the GAAP/IAS
>> requirements. Much of the rest of GnuCash doesn't either, but
>> there's no point in doing a lot of work that doesn't move us in the
>> direction of being legal.
> 
> 
>> 4a. The GAAP/IAS requirement is that all transactions get valued in
>> the book's home currency on the day of the transaction using either
>> an actual exchange rate if funds were converted that day or an
>> average rate for the day if they weren't. One of the participants in
>> bug 797796, CDB-Man, is a licensed accountant. The discussion on
>> that bug is quite comprehensive and I won't attempt to summarize
>> it. It's actually a pretty substantial simplification over what
>> you've planned.
> 
> I'm not aware that GnuCash has a concept of "book's home currency", so
> I used "currency of ancestor account" as a proxy for that, in line
> with the currency silently/invisibly chosen for transactions entered
> in a "shares" type ledger.
> 
> I meant for my design to get as close as possible with what you
> describe, given the data structures in GnuCash now. The other software
> that I've had professional contact with deals with that by always
> recording two amounts in each split: the amount in "native commodity"
> and the amount in "book's home currency". GnuCash doesn't do that.
> 
> So, again with the current GnuCash data structures, my code uses the
> price database as proxy for "actual exchange rate if funds were
> converted that day or an average rate for the day".
> 
> 
> From a first quick analysis, it seems to me my code will need only two
> adaptation the day the rest of GnuCash is ready:
> 
> 1) In cap-gains.c, in xaccSplitComputeCapGains, replace
>   capgain_currency = gnc_account_get_currency_or_parent(split->acc);
>   by
>   capgain_currency = book's home currency
> 
> 2) In gnc-lot.c, in gnc_lot_get_balance_before, replace:
> 
>   tmpval = xaccSplitGetValue (s);
>   tmpval = xaccAccountConvertBalanceToCurrencyAsOfDate(
>               s->acc,
>               tmpval,
>              ts->common_currency,
>              currency,
>              ts->date_posted);
> 
>   by
> 
>   tmpval = xaccSplitGetValueInBookCurrency (s);
> 
>   (and then the currency argument to that function becomes
>    unused / obsolete / to be removed)
> 
> 
> The overall algorithm stays the same.
> 
> Where it does get simpler is that my "point number 5" does not arise.
> 
> 
> My understanding is that with the exception of using the price
> database instead of actual transaction exchange rate, and assuming the
> price database is well-maintained, if all securities accounts are
> children of an account denominated in the currency intended to be the
> "book's home currency", my code will do what GAAP/IAS requires in its
> area of responsibility. Meaning it *allows* a setup that follows
> GAAP/IAS (with the exception noted), getting closer to it than the
> current code, while also allowing generalised "other behaviours", as
> GnuCash seems to tend to do (e.g. in allowing different "common
> currency" for each transaction instead of a single book-wide common
> currency, use trading accounts instead of periodic reevaluation
> transactions on the income/expenses accounts, ...).
> 
> If you want to go further in the direction of GAAP/IAS compliance, the
> cross-currency lot-based capital gains computation could use the
> actual exchange rate against capgain_currency in the transaction, in
> cases where:
> 
> - the transaction's common_currency is not equivalent to
>   capgain_currency (if it is, the point is moot, there is no
>   conversion rate at all, or seen otherwise it is exactly 1 by
>   definition)
> 
> - The "other split" is denominated in capgain_currency
> 
> This would give subtly different semantics depending on what currency
> is used to pay for the security; so could be confusing for the user.
> 
> 
> If, as https://bugs.gnucash.org/show_bug.cgi?id=797796#c203 lists as a
> possibility, GnuCash switches to "all transaction's common_currency is
> the same across the whole book", then both the current code and my new
> code will do the right thing, won't they? They will not "see"
> cross-currency stuff anymore.
> 
> 
>> 3. There's already a struct combining commodity with gnc_numeric
>> amount called gnc_monetary, declared in
>> libgnucash/engine/gnc-commodity.h.
> 
> Oh, great, I didn't find it, asked on IRC and was told there was
> none.
> 
>> 4c. Apropos the book property proposal, do you know about and
>> understand Trading Accounts? Enabling use of trading accounts
>> changes the behavior of the register in multi-commodity
>> transactions. Neither cap-gains.c nor dialog-lot-viewer.c check for
>> using trading accounts; perhaps they should.
> 
> I've seen the trading accounts feature. I've not understood all
> consequences of it. On the one hand, it sounds like it would subsume
> (replace) lots-based capital gains computation (and one should not do
> the two at the same time), but on the other hand, I fail to see how
> one would choose between FIFO / LIFO / average cost / ... policies
> with trading accounts. The documentation talks about "currency trading
> accounts", but GnuCash uses them for non-currency commodities, too.
> 
> Anyway, Trading Accounts are an optional feature, turned off by
> default. Unless they are "pushed" as the only way to deal with capital
> gains, shouldn't lot-based capital gains be enhanced?
> 
>> 5. I'm not sure what you mean here.
> 
> I mean "the patch is not fully finished and ready to be committed to a
> release version / release-track branch; one of the things that I have
> not looked at, and thus probably missing, is dealing with
> recomputation of capital gains in the case were the capital gains
> currency changes".
> 
>> First, it will be far more productive for both of us if you'll
>> resubmit your patch as a Github pull request.
> 
> OK, I will set it up as a github fork... if it makes sense in the face
> of your "do nothing or do full GAAP/IAS compliance / don't add
> technical debt" comments?
> 
> If you prefer github pull requests, it should be clearly written in
> the instructions.
> https://wiki.gnucash.org/wiki/Development#Submitting_Patches
> is quite neutral on which one is used.
> 
> 
>> No patch containing commented code is acceptable.
> 
> I quickly pushed v2 to the bug tracker before going to bed. Sorry that
> is not up to your standards for discussion drafts. It is a "work in
> progress" dump for early discussion. Yes, removing that one
> commented-out loop that is replaced by a call to
> gnc_account_get_currency_or_parent needs to happen before commit.
> 
>> As evidenced by bug 797796 and the bugs you've created and commented
>> on in the last few days this problem is quite a bit bigger than just
>> the lot scrubber. Addressing it piecemeal, particularly with
>> piecemeal design goals, will just add to the huge amount of
>> technical debt we have already.
> 
> Well, not if the piecemeal design goals fit in the longer agenda /
> overall design goal :)

GnuCash does have a home currency, it's the (invisible) root account currency. 
It is set explicitly on the second page of the New Account Hierarchy Setup 
assistant on the third page; you can run the assistant on an existing book with 
Actions>New Account Hierarchy. You're correct that it is not currently used as 
the common currency for all transactions. As you noted I proposed that on bug 
797796, but it needs further discussion with the users before we implement it 
as it will for some be a significant change in the way GnuCash works. Until 
then the 'value' of the split is denominated in the transaction's  
common_currency, a.k.a. "transaction currency".

GnuCash currently sets the transaction currency as the currency of the account 
from which register the transaction is created in a register and the from 
account's currency if the transaction is created using the Transfer Dialog. As 
you know in either case the nearest currency-denominated parent account is used 
if the account in question is denominated in a non-currency commodity.

AFAICT your code privileges the lot opening transaction's currency which may or 
may not be the one in which capital gains should be calculated. Whether or not 
it is depends entirely on the user's selection of accounts when creating the 
transaction. In fact if the user is careful to always start stock transactions 
in the same account your additional code will never run. It's also risky to 
assume that the pricedb contains the exchange rate you need close enough before 
the time that you need it.  Note that 
xaccAccountConvertBalanceToCurrencyAsOfDate() uses nearest-before with a 
timestamp. Date posted (and yes, that's the date you want; date entered could 
be years later for someone who's back-filling transactions as part of starting 
to use GnuCash) is always 10:59 AM UTC. One could get an end-of-day exchange 
rate that would be later that day but would be ignored in favor of a previous 
day's rate. It also will do a one-level-indirect rate lookup if it can't find a 
direct one and the dates of the two exchange rates need not be the same. If it 
doesn't find a rate it returns 0/1 and so you'll get a returned value of 0/1. 

If all security accounts are parented by accounts in the book currency and the 
user always starts the transactions in the security accounts then the opening 
and closing splits will always be valued in the same currency and your changes 
will never run. The case that your code seeks to address is when one of the 
transactions is initiated from the cash-source account or the Transfer Dialog 
so that the transaction currency is different. In any case that's not the 
use-case you're working on: In that case the security account's parent is in a 
different currency from the home currency. Of course it's also possible to have 
some third currency involved: You might use a London broker whose account is 
denominated in GBP to buy a stock priced in USD, but you still need to figure 
out your cap gains in EUR to pay your taxes.

If/once we implement transaction currency = book currency then the lot scrubber 
will work correctly as-is, your changes will never run. That's also the only 
solution I can see to the n-currency problem.

Trading accounts are generally recommended for users doing multiple currencies 
and the lot scrubber without your proposed changes is written for users doing 
only one currency. The lot scrubber only knows how to do FIFO, nobody ever 
implemented other policies. Trading accounts are sort of average-cost as long 
as there aren't too many commodities involved.

Don't be offended by the admonition about commented-out code, it's just a 
reminder that it makes the proposed commit harder to understand. That's 
especially true when it's all-new code as in this snippet from your patch:
+       split_currency = split->parent->common_currency;
+    }
+
+    capgain_currency = gnc_account_get_currency_or_parent(split->acc);
+    /* if (capgain_currency == NULL) */
+    /* { */
+    /*         // LEM TODO: do we want to do that? */
+    /* I didn't manage to #include the declaration of gnc_default_currency() 
anyway*/
+    /*         capgain_currency = gnc_default_currency(); */
+    /* } */
+    if (capgain_currency == NULL)
+    {
+       PERR("commodity account has no currency-denominated ancestor and no 
default currency set.");
+       return;

Regards,
John Ralls



_______________________________________________
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to