Problem in Trial Balance report with stocks and multiple currencies
Sherlock Holmes
sh025622 at gmail.com
Sat Aug 23 23:18:56 EDT 2025
I concur.
There are significant differences in the implementation between
gnc:get-exchange-totals and gnc:get-exchange-cost-totals that I believe
are the root cause of the issue. These differences appear to date back
to May 3, 2019. As a WAG, I modified gnc:get-exchange-cost-totals to
match gnc:get-exchange-totals in the attached patch and the issue you've
raised appears to be resolved. I have not done any further testing,
Regards,
Sherlock
On 8/23/25 2:20 PM, Chang Wang wrote:
> Thanks for the reminder. I'll post to the user list in the future.
> However, in the above example, there is no gain or loss due to
> currency exchange as the exchange rates are set to 1 so no currency
> gain/loss needs to be booked. And the price source is set to be Last
> up through report date instead of average cost. Therefore, I think
> these are different issues.
>
> On Sat, Aug 23, 2025 at 3:51 PM John Ralls <jralls at ceridwen.us> wrote:
>
> Oddly I just told somebody on IRC the same answer:
> https://bugs.gnucash.org/show_bug.cgi?id=797796
>
> Unless you’re willing to submit a PR, this is a user-list topic,
> so in the future please use gnucash-user instead of gnucash-devel.
>
> Regards,
> John Ralls
>
> > On Aug 23, 2025, at 1:43 PM, Chang Wang <wangchang327 at gmail.com>
> wrote:
> >
> > Hi all,
> > I noticed an issue with the Trial Balance report when using
> stock trading and multiple currencies. Even when transactions are
> balanced, the Trial Balance report appears to break due to
> incorrect calculation of unrealized gains.
> >
> > I've attached an uncompressed minimal example to illustrate the
> problem.
> >
> > Steps to reproduce:
> > Open the attached book.
> > Generate a Trial Balance report with reporting currency set to
> USD, price source set to Last up through report date, and enable
> Show Foreign Currencies and Exchange Rates.
> >
> > Observed behavior:
> > The report shows an Unrealized Gain of $20,800, which is incorrect.
> >
> > Expected behavior:
> > The Unrealized Gain should be $200.
> >
> > Explanation:
> > The example contains three transactions:
> > 1) 08/02/2025 - Buy one stock for 10,200 JPY.
> > 2) 08/03/2025 - Exchange 100,000 JPY for 100,000 USD.
> > 3) 08/04/2025 - Buy one stock for 10,400 JPY.
> >
> > The JPY/USD rate is fixed at 1 on all days, so there should be
> no realized or unrealized currency gains. Stock prices are set at
> 10X00 JPY on 08/0X/2025, where X = 1, 2, 3, 4.
> >
> > Therefore, in USD reporting currency, the Trial Balance should
> show unrealized gains as:
> > (10,400 * 2) - 10,200 - 10,400 = 200 JPY = 200 USD
> >
> > Notably, the Balance Sheet report does display the correct
> unrealized gain. And if transaction 3) or transaction 2) is
> removed, the Trial Balance turns out to be correct.
> >
> > I'm not familiar with Scheme, so I wasn't able to locate the
> problem in the source code. I also wasn't able to file a bug on
> Bugzilla, since the registration function appears to be broken.
> >
> > Thanks for your attention,
> > Chang
> > <tb.gnucash>_______________________________________________
>
> _______________________________________________
> gnucash-devel mailing list
> gnucash-devel at gnucash.org
> https://lists.gnucash.org/mailman/listinfo/gnucash-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gnucash.org/pipermail/gnucash-devel/attachments/20250823/c59e7092/attachment-0001.htm>
-------------- next part --------------
--- commodity-utilities.scm.orig 2025-08-23 19:49:25
+++ commodity-utilities.scm 2025-08-23 19:23:32
@@ -526,13 +526,6 @@
(cond
((null? comm-splits)
(gnc:resolve-unknown-comm sumlist report-commodity #:hide-warnings? hide-warnings?))
-
- ;; However skip splits in trading accounts as these counterbalance
- ;; the actual value and share amounts back to zero
- ((eqv? (xaccAccountGetType (xaccSplitGetAccount (car comm-splits)))
- ACCT-TYPE-TRADING)
- (loop (cdr comm-splits)
- sumlist))
;; Go through all splits and add up all value-amounts
;; and share-amounts
@@ -540,10 +533,15 @@
(let* ((a (car comm-splits))
(txn-comm (xaccTransGetCurrency (xaccSplitGetParent a)))
(acc-comm (xaccAccountGetCommodity (xaccSplitGetAccount a)))
- (share-amt (xaccSplitGetAmount a))
- (value-amt (xaccSplitGetValue a)))
+ (share-amt (abs (xaccSplitGetAmount a)))
+ (value-amt (abs (xaccSplitGetValue a))))
(cond
+ ;; Without shares this is not a buy or sell; ignore it.
+ ((zero? share-amt)
+ (loop (cdr comm-splits)
+ sumlist))
+
((assoc txn-comm sumlist)
=> (lambda (comm-list)
(cond
@@ -571,16 +569,16 @@
;; other commodity already exists in comm-list?
((assoc txn-comm (cadr comm-list))
=> (lambda (pair)
- ((caadr pair) 'add (- value-amt))
- ((cdadr pair) 'add (- share-amt))
+ ((caadr pair) 'add value-amt)
+ ((cdadr pair) 'add share-amt)
(loop (cdr comm-splits)
sumlist)))
(else
(let ((pair (list txn-comm (cons (gnc:make-value-collector)
(gnc:make-value-collector)))))
;; And add the balances to the comm-list entry.
- ((caadr pair) 'add (- value-amt))
- ((cdadr pair) 'add (- share-amt))
+ ((caadr pair) 'add value-amt)
+ ((cdadr pair) 'add share-amt)
(loop (cdr comm-splits)
(cons (list (car comm-list) (cons pair (cadr comm-list)))
(alist-delete
More information about the gnucash-devel
mailing list