reporting currencies & integrity

linas@linas.org linas@linas.org
Tue, 23 Jan 2001 18:42:56 -0600 (CST)


Hi Bill,
It's been rumoured that Bill Gribble said:
> 
> On Tue, Jan 23, 2001 at 10:22:59AM -0600, Linas Vepstas wrote:
> > Store a single global 'reporting currency'.  The chart of accounts
> > will use this currency to report account totals.  (its e.g. the
> > euro).
> 
> I think you are saying 'the Chart of Accounts and reports will use
> this currency to report monetary values, in addition to the "native"
> denomination of the value'.  If so, I agree.  

Yes, that's it.

> However, that's not a complete solution; you still have to know how to
> convert the amounts to the reporting currency.  To do this correctly,
> we need to implement at least a subset of the FASB 59 standards for
> conversion of amounts to a reporting currency and allow the user to
> select which method they wish to use.  In short, for each value in a
> "foreign" (WRT the reporting currency) currency, you have to decide
> whether to convert the amount at the current exchange rate, whether to
> convert component amounts at their historical exchange rate and sum
> them, or to use a weighted-average exchange rate for the entire
> reporting period.  You need to make this decision on a per-account
> basis based on the type of the account.

Yes, that is correct.  That is what the FIFO Queue code in the engine
was starting to do.  I'd hoped that someone would volunteer to write
more methods, but no one has.

Note that its not just foreign curencies, its also stocks, bonds, and
depreciation.   The FIFO was meant to be one acceptable way of 
doing cost-basis accounting to keep the IRS happy.  Depreciation
schedules are another thing that can be handled that same way 
as far as the software is concerned.

Actually, I'm confused, .. I can't find code that's using Queue.c
anywhere, so I am not sure how the ... never mind ... we no longer
have a functional cost-basis report ...

> > -- The user is allowed to create transactions whose 'valuation currency'
> >    is different than the 'reporting currency'.  However, if this is
> >    done, then a GUI window pops up with a question "how should this
> >    transaction be valued in 'reporting currency'"?  User types in
> >    some number, lets call it the 'valuation'.  This number, the
> >    'valuation', is stored in the price database, (where its specially 
> >    identified as being a valuation price, maybe by storing the
> >    transaction guid with it).  When preparing reports, it is used,
> >    from then-on-out, to compute the valuation for reports.
> 
> I disagree with most of this.  

I think you misunderstand.

> I think the right approach is to store
> the valuation in the transaction currency with the split.  

You could choose to value the transaction in a dozen currencies.
You want to store a dozen values with each split?  

> Right now,
> each split stores 2 monetary values: the 'damount' denominated in the
> account's security and the 'value' denominated in the account's
> currency.  What Dave and I were talking about is eliminating the
> 'currency' from the account, moving it into the Transaction structure,
> and having each split have a 'damount' (still in the account's
> security) and a 'value', now in the Transaction's currency.

Yes, I have already made this change to the engine. The "transaction
valuation currency" aka "common currency" is stored in the  
"common_currency" field in TransactionP.h.  It is not is not really
'used' anywhere, but it is set, and tested, and a warning is printed
if it gets out of sync with the "IsCommonCurrency()" routines.

> I think the problem you are trying to address with your mention of the
> reporting currency is how to find values for all these things at
> report-generation time in terms of the reporting currency.  It's a
> real problem, but I don't think you're making a 100% solution.

Re-read the note. I'm proposing several things.   One of them is 
what to do if the "transaction valuation currency" is not equal
to the "reporting currency".   This is one of the showstoppers
for the change-over, as you yourself had pointed out earlier.

> I agree that we want to make an entry in the price database for any
> user-specified exchange rates (between Account security and
> Transaaction currency) 

Yes, but its not just 'some price', its an explicitly auditable
price.  I think that's a critically important part of it.

> but that doesn't really solve the reporting
> problem, because you could specify after the fact that you want to use
> a valuation strategy that requires different exchange rates than the
> ones you enter at the time of the transaction (i.e. you might want to
> use current-value for all cash assets, and that's value as of report
> generation time), or in fact a different reporting currency entirely.

Yes, but you can scan the data and determine this at report-gen time.

> We'll need the ability to go out and fetch currency quotes for
> historical dates at report generation time.

Sure.  

> In any case, if we have a Transaction currency that's not the
> reporting currency (pretty likely) that means we have to ask the user
> for possibly two different exchange rates for a single entered value
> (one for the value of the split in the Transaction currency, one for
> the value of the split in the reporting currency) and that's way too
> much to ask.  

I think you are painting yourself into a corner with your choice of
language, which is why I'm trying to be careful with the names that
I'm choosing.  Its not actually this bad.  Here's how it works:

Lets say that our 'reporting currency' is USD.  Lets say we live in
france, and we bought IBM stock with FF.  The user types in the 
shares bought, and the FF paid. (that's our first 'exchange rate').

When user clicks on 'commit', a little GUI dialoge pops up, and says

  'To correctly report this transaction in the main window account
   summary, we need to know the value of this transactin in USD.  The
   last exchange rate we know of for USD is xx.yy FF per USD, which 
   would value the transaction at $zzz USD.  Use this exchange rate, or
   edit?'

Its not obviously burdensome to me. If you still think it is, we can 
talk about strategies for hiding it. (e.g. if this was a EURO-FF-IBM
example, we 'know' that the FF is pegged to the euro, and don't even
have to ask.)

> I think all we need to ask is the value in the
> Transaction common currency, and we figure out the rest at report
> generation time.

?
Yes, but the 'report generation time' is "right now" (you make it
sound like its the distant future or something).  The main gnucash 
window is a kind of report.  When I get done with entering the 
transaction, I expect the main window to instantly update & reflect 
the new value.  So that GUI popup is gonna pop up anyhow, anyway,
in fractions of a sub-second.  I'm not sure that I care if its the 
'register' that caused it to happen, or the 'main window'.   


> > -- (critical side effect proposal for Bill): for *any* multi-currency 
> >    transaction/trade, we should store the 'valuation price' (and maybe 
> >    the transaction guid) in the price database.  Why?  This allows us to
> >    perform the integrity check that Bill has been missing so much.
> 
> I'm not sure what you're talking about here.  What integrity check do
> you mean, and why do you think I'm missing it?  (later) Oh, I see.
> You're talking about the "accounting equation" discussion we had
> several months ago.  I think we resolved that just fine; 

? you grumbled to me about this just yesterday. !!

> we have to
> implement FASB-compliant historical/current valuation policies, and
> make a report that takes unrealized gains/losses into account as part
> of the Equity term of the accounting equation.  We will never be able
> to "check" this during normal operation, because generating the info
> you need to run the accounting equation is more of a pain in the butt
> than you want to incur for normal operation.  It may make sense to
> have this as a "Scrub" type option.

I disagree, and/or you are missing the point.   My point may not be a
good one, but I want you to understand it first before knocking it
down.

I propose that a 'price' be stored in a separate location from 
the transaction & splits.   This 'price' is not only in a separate
table, but its also under separate controls.  When I say 'separate
controls' I mean that it is viewed and edited with a gui other than
the register window.  In the distant future, a multi-user system
may even assign security permissions associated with it.  It might
have its own audit-trail paperwork.

Now, why do this?  After all, there already is an implicit price
in every split: its just 'value/damount'.  Why not just use that? 

The answer is that the current mechanism provides no way of
safe-gaurding that price. A slip of the fingers, and suddenly,
the price of IBM stock is 10,000 dollars.  Gnucash would never know,
you could download stock prices off the net till you're blue in the
face and not notice it. 

By explicitly acknowledging that there is a price, and storing that
price separately from the split, the engine can double-check the
math.  It can explicitly verify that 'value/damount' == 'price'.

And, since the price is is in the price db, you can graph it: 
Although IBM normally trades at $100, that one day where its $10,000
would show up in an obvious way. 

You are free to argue back that this idea is overkill.  But it does
solve the accounting equation problem of 'how do I know that the sum
of the splits ==0 when the splits are in different currencies'.


> >    Q: How do we 'know' that a multi-currency transaction balances?
> >    A: The 'valuation' is in the price database, and a comparison
> >    with that assures us that the transaction balances.  And why
> >    should we beleive the price database? Because these special
> >    'valuation' prices are auditable, are 'important', are verified
> >    by humans, rather than being some random numbers pulled down from
> >    yahoo.  (A 'valuation price' might even have a 'reconciled' or a
> >    'been audited already' flag stored with it).
> 
> The problem with this is that the "valuation" of a transaction is
> always 0.  It's splits that need to have values expressed in the
> Transaction (not reporting) currency, and those values have to add up
> to 0 (well, debits == credits). 

Aww, come ON!  What is this, flame bait?  I wrote the stinkin code!  
Give me some credit!

> > -- same as above, except we store the 'reporting currency' with each
> > account.  (i.e. we do a global search-n-replace of
> > xaccTransGetCurrency to xaccTransGetReportingCurrency.  I really,
> > really think this simple name change will clear up lots of
> > confusion).
> 
> I don't think the reporting currency and the Transaction balancing
> currency are the same thing at all.  

Crap.  

I didn't mean that!

I meant 'change the name of xaccAccountGetCurrency() to 
xaccAccountGetReportingCurrency().  Yikes!!! 

> You can change the reporting
> currency from Euros to Dollars to Yen on the fly and it just changes
> the denomination of the "extra" column in reports and the main window.

I assume that means you prefer Plan X to Plan Y. 

In plan X, there is one (or a collection) of globally-applied
reporting currencies.   In plan Y, there is one (or a collection)
of reporting currencies stored with each account. 

Plan Y is essentially how gnucash works today. 

I claim that Plan Y has a certain advantages, but this email is long
enough already.

--linas