Rounding in the price db.

Mike Alexander mta at umich.edu
Sun Aug 9 19:29:51 EDT 2015


--On August 9, 2015 at 8:35:04 PM +0100 John Ralls <jralls at ceridwen.us> 
wrote:

> A recent IRC conversation and a discussion (face to face!) with a
> user got me thinking about the prices entered from the transfer
> dialog into the price db. The current situation is that when the user
> creates a transaction between accounts with differing currencies and
> commodities, the transfer dialog comes up to get either a price or
> the value in the “other” currency. The user duly enters a number
> and GC does the appropriate calculation, rounding the value to the
> max denominator for the “other” account’s currency/commodity,
> then recalculating the “true” price without the rounding and
> saves the result in the price db. The user could do several entries
> with the same nominal exchange rate and get a different exact
> fraction for each because of the rounding of the value.
>
> Does that really make sense? Should we round the price we store in
> the price db to some reasonable fraction? What fraction? The smallest
> commodity unit (scu) of the “value” currency/commodity seems
> reasonable to me. For example, if the entry is of  how many US
> Dollars buys a Euro or a share of Ford stock, the price should be
> rounded to the scu of US Dollars, i.e. cents. OTOH some mutual funds
> price in mils ($.0001), so perhaps we should round the price db
> entries to

No, that doesn't make sense.  I've been bothered by this for some time.

However, I don't think rounding to the SCU of either commodity is 
correct.  Suppose the SCU of A and B is 2 and the official exchange 
rate from A to B is 1.500555 (my bank quotes rates to 6 decimal places 
when I buy foreign currency).  If I first convert 2.00 A to 3.00 B by 
entering this exchange rate in the transfer dialog it would record an 
exchange rate of 1.50.  Later a value of 2000 A would be converted by 
default to 3000 B, not 3001.11.  I think you need to record more digits 
than the SCU.  Ideally you should record exactly what is entered in the 
transfer dialog if the user enters a price rather than a destination 
value.  If they enter a destination value then you probably should 
record at least 6 places after the decimal point.

Things get tricky if the ratio is very small.  The current rate for USD 
per Sao Tomean Dobra per USD is 0.0000444615.  if you rounded this to 
0.000044, you lose a lot of precision.  If someone enters a transaction 
of 1000 Dobra to USD .04 (unlikely, but valid) then the recorded rate 
to 2 places would be zero which is clearly a bad idea.

I solved this problem in the Advanced Portfolio report by recording 
prices derived from transactions with 8 decimal places.  This seemed 
large enough to avoid losing precision for very small prices, but small 
enough to avoid overflows in computations.  Perhaps we should do that 
for the price DB too.

> Related but somewhat separate, does it make sense to record more than
> one price per day in the price db? If so, should we suppress saving
> the price if it’s unchanged, perhaps within some tolerance, of the
> previous entry on the same day? If not, do we keep the first entry or
> overwrite every entry so that we end up with the last (entered) entry
> for a particular day?
>
> The point would be to not store a bunch of data that we don’t use
> and to present users with more useful defaults in the transfer dialog
> when they’re entering a bunch of transactions for the same day and
> the same currencies/commodities. What are the possible bad impacts,
> particularly in reports, especially the Advanced Portfolio Report?

Recording only one price per day probably is a good idea.  I think 
there may already be code that won't record a price if the same price 
is there on the same day, but I'm not sure what the definition of 
"same" is.

         Mike
 



More information about the gnucash-devel mailing list