On Mon, Oct 6, 2014 at 10:57 PM, Nathan Grigg <[email protected]> wrote:
> 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. > I'm not sure what that means... there is no need for any precision on units of FUND, the balance amount of that leg is in USD calculated as 11.27534 x 1.2357. In USD. The balance residual is 11.27534 x 1.2357 + -13.93. The only precision that matters is that of USD. Does it use the precision inferred on units of FUND in any way? If so, how? Which brings up an interesting option for inferring the precision: the maximum number of digits from all legs without cost/price conversions. And this should be calculated for each group of postings whose "balance amounts" are in a common commodity. That sounds right to me. > > 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". > Why? Because you fear not having a minimum will create pathological cases where a user will insert a balance against an integer number of dollars and make a mistake on the cost that will go undetected? 2014-09-09 * Assets:Invesments ... Assets:Cash -1000 USD Just curious. What cases do you see as problematic? > >> *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. > I've put it in the TODO. You've convinced me to tackle this before tagging the next release - I'm curious to compute my own residuals now actually - so I'll try to work on this soon and include that change in the next release. > > 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. > -- --- 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.
