On Oct 6, 2014, at 8:30 PM, Martin Blais <[email protected]> wrote:
> I like the idea that the tolerance can be inferred automatically from the 
> smallest digit in the input instead of using a fixed value. I should 
> implement that in Beancount as well, there's no reason it couldn't do it.This 
> should be a very easy change to make.
> 
> At the moment Beancount uses "0.005" regardless of unit... this is a known 
> pending issue (I don't have any Japanese users yet I suppose). I've been 
> thinking that a per-commodity tolerance could be selected instead, i.e., a 
> map of commodity to tolerance value, but while better, this is also 
> unsatisfying.
> 
> I wonder if inferring like Ledger works in all cases though; consider this 
> case:
> 
>     Assets:Fidelity:Fund        11.27534 FUND {1.2357 USD}
>     Assets:Fidelity:Cash       -13.93 USD
> 
> The precise cash amount is 13.932937638 USD.
> How many digits should this use?

Ledger would infer 2 digits of precision for USD and 5 for FUND. The price 
portion does not affect precision. Ledger also has a D directive to specify the 
minimum precision per currency.

> The debited cash is 13.93, this would be the _actual_ amount debited by the 
> fund manager, so it can't be anything else.
> In this example, I would argue that you would want the _minimum_ number of 
> digits to be used.
> (But certainly not the minimum if you're using an integer number of shares...)
> 
> If we can come up with a rule that works well in all cases I'll implement it.

To be honest, I would prefer to explicitly specify precision, although this 
makes it harder to work correctly "out of the box". 

>> 
>> Case 2: Multiple currencies.
>> 
>> 2014-01-01 * buy AAA
>>      Assets:Investments  2 AAA @ 10.1234 EUR
>>      Assets:Bank  -20.25 EUR
>> 
>> The 2 AAA and the -20.25 EUR are actual amounts. The quoted rate may have 
>> been 10.1234, but the truth is, you bought at 10.125 EUR (sucker!)
>> 
>> Note that this need to adjust price due to rounding does not arise solely 
>> from overprecise pricing, but also when you purchase fractional shares.
>> 
>> 2014-01-01 * buy VPMCX
>>      Assets:Investments  9.66 VPMCX @ 103.52 USD
>>      Assets:Bank  1000.00 USD
>> 
>> Again, the $1000 and the 9.66 shares are exact quantities. They do not 
>> represent something that has been rounded. You do not have an extra, 
>> invisible 0.0032 USD lying around. It is the $103.52 that is wrong.
> 
> But is it wrong, really?  Is the cost basis calculated with 103.52 USD or 
> 103.519668737 USD?  
> Correct or not, I think the bank and govt assume a cost basis calculated 
> using 103.52 USD, so that's the correct one.
> 
> Also, when you calculate your capital gains later, which of the prices should 
> you use?
> Again, I think 103.52 is what you're supposed to use.

I agree that 103.52 is what the bank will use and what you are "supposed" to 
use. 

>> So one solution is to simply record the share price you paid instead of the 
>> share price you were quoted. This is the same as Martin Machlmayr’s 
>> suggestion to use ‘@@' instead of ‘@'. But as Martin also pointed out, there 
>> is value in using ‘@‘, namely, your cost basis can match the bank’s report, 
>> the pricedb gets an accurate market price, and you get an extra check that 
>> you haven’t mistyped a number.
>> 
>> A different solution is for the program to replace the cost basis that you 
>> specify with the true cost, as long as it is close enough. But this doesn’t 
>> solve the problem that you might want to attach the bank-reported cost to 
>> the posting, or see it in reports. 
> 
> Both of these worry me, as per my other email, because that propagates cost 
> basis that is unexpectedly exact. I'd rather use the rounded, inexactly 
> calculated cost basis.

I'm pretty sure I agree. 

> 
> 
>> One final solution, and what I have settled on for now, is a rounding 
>> account. I insert one manually (with elided amount), but the program could 
>> easily do this for you. It sweeps away whatever is left over, and has 
>> accumulated 0.12 USD (in expenses) for me so far this year. The alternative 
>> is that my double-entry accounting ledger is out of balance by 12 cents per 
>> year. (Maybe not a big deal, but it bugs me.)
>> 
>> The point is, no matter how you decide to round the amounts, you have to 
>> account for the rounding in some way or accept the fact that your system is 
>> out of balance.
>> 
>> Note that either of these automated solutions could probably be implemented 
>> using beancount plugins.
> 
> Yes, you could. 
> 
> However, using a plugin you would have to compute each transaction's balance 
> amounts sum twice, which is somewhat expensive, so if this is a great 
> solution, I would consider adding it in the interpolation routine itself to 
> avoid the cost and use the one already computed. I'm not convinced this 
> should always be done though. (See at the end of this message.)
> 
> 
> 
> 
>> Weird things happening
>> 
>> If you don’t require each transaction to balance, you easily drift away from 
>> overall balance. In Ledger:
>> 
>> D 1.00 USD
>> 2014-01-01 Test
>>     assets  1 CAD @ 1.005 USD
>>     liabilities
>> 2014-01-02 Test
>>     assets  1 CAD @ 1.005 USD
>>     liabilities
>> 
>> % ledger bal liabilities
>> 2014-01-01 Test                 liabilities               -1.00 USD    -1.00 
>> USD
>> 2014-01-02 Test                 liabilities               -1.00 USD    -2.01 
>> USD
>> 
>> Here is another:
>> 2014-01-01 Test
>>     assets  1 CAD @ 1.005 USD
>>     liabilities  -1.00 USD
>> 2014-01-02 Test
>>     assets  1 CAD @ 1.005 USD
>>     liabilities  -1.00 USD
>> 2014-01-03 Test
>>     assets  1 CAD @ 1.005 USD
>>     liabilities  -1.005 USD
>> 
>> % ledger bal -B
>>            3.015 USD  assets
>>           -3.005 USD  liabilities
>> --------------------
>>            0.010 USD
>> 
>> This second example is curious because if you put the third transaction at 
>> the beginning, the other two now fail to balance, because the precision 
>> becomes 3 decimal points before they are read, whereas before the precision 
>> switched from 2 to 3 partway through.
> 
> Now that... is something that would really bother me. If anything should be 
> inferred from the precision of the numbers in the input, its effects should 
> always be only _local_ IMO. 
> 

>> Eliding postings
>> 
>> Once you have what it means to balance figured out, it is easy to complete a 
>> transaction with an elided posting. Simply choose the value that minimizes 
>> the error. (And then either roll the error into an adjusted price or add a 
>> rounding transaction.) Obviously, to do this, you would need rules about 
>> precision, per currency and possibly per account. If you really want to, you 
>> can have custom rounding rules. 
>> 
>> In my experience, though, you will often still get the number wrong, because 
>> at the end of the day, the bank will do what it does for its own reasons. 
>> (In my 401k, for example, I contribute a fixed $X to buy Y fractional shares 
>> at price Z, but X - Y*Z has been as big as 2.5 cents because strictly 
>> speaking the bank is setting Y = round(X/Z, 3), even though I would never 
>> think of it that way, or record it that way in my ledger.)
> 
> Alright, so here's what I propose:
> 
> - I could add an option for the user to insert the name of a rounding account.
> - This option would be empty by default, and the current behaviour would not 
> change.
> - However, if you set an account for it, all transactions with an inexact 
> balance will receive the balance amount (and perhaps have a new leg inserted 
> on them automatically).
> 
> Would that be a reasonable compromise? 
> With no account, you get 0.005 looseness (or whatever this becomes if 
> inference is implemented).
> With an account, you get precise balances throughout, but no manual input is 
> required.
> 
> Thoughts?

This is my favorite solution.

Nathan 

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"Ledger" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to