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.
