I’ve pushed a feature branch, single-price, to my Github repo 
(https://github.com/jralls/gnucash) which covers most of what we’ve discussed 
here. I’m still wrestling with the math of how to sensibly handle rounding 
itself, so what’s there still uses the hard-coded 10^6 denom. The branch is 
from maint because I’d like to put these changes in 2.6.8.

The actual changes are explained in the commit notes. In my limited testing it 
appears to work and to provide stability when doing multiple transactions with 
the same exchange rate. Please test some more; I’m sure I didn’t think of every 
possible variation.

As for the math, here’s the conundrum: I proposed earlier to base the rounding 
on what would make a 1 scu change in the “to” commodity. The problems with that 
idea are that it depends entirely on the amount in the “from” commodity and 
that prices are often quoted in fractions of a scu. For example, the Wall 
Street Journal website quotes the Yen at 120.98 to the USD. The Yen’s scu is 1, 
and the change in the rate to make a 1¥ change in the value is different if the 
USD amount is $10 from what it would be if the amount was $1000. Carry that to 
its illogical conclusion and we need infinite precision, and that’s ignoring 
the fact that we need infinite precision to exactly represent a lot of rational 
fractions, but since all the real money systems use decimal math nowadays 
that’s not really germane.

So I have a new proposal: If the commodities are both currencies, store 
exchange rates in the direction where the rate > 1, set the denominator to 
1000, and round-half-up. The price retrieval code already checks in both 
directions. If only one of the commodities is a currency then it’s a price and 
we store it in the currency with the denominator = the currency’s scu * 10000.

That leaves commodity-commodity prices. The most common example in modern life 
is stock-for-stock exchanges resulting from mergers or spin-offs. These tend to 
be one-offs, so no rounding required. Barter exchange, where one exchanges one 
commodity for another (e.g. two bushels of corn for a cow), is similarly 
fractional rather than decimal, so again not rounding is appropriate. The third 
case is the problem: Bitcoin and similar pseudo-currencies. For maint I think 
we’re going to have to leave those prices unrounded as well, but perhaps for 
master we should consider creating a separate commodity category so that users 
can create commodities that GnuCash treats as currencies.

Regards,
John Ralls


_______________________________________________
gnucash-devel mailing list
[email protected]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to