Inventory Booking - A Proposal for an Improvement on Command-Line Bookkeeping

448 views
Skip to first unread message

Martin Blais

unread,
Jun 23, 2014, 2:03:00 AM6/23/14
to ledger-cli
Dear Ledgerians,

I've been doing some thinking about improving the booking method used in Beancount. In the following document, I summarize the issues with inventory booking and list some unsatisfied use cases, identify current shortcomings in both Beancount and Ledger (with specific examples), list a set of requirements for a better inventory booking method and outline a design proposal for an improved method:

https://docs.google.com/document/d/1F8IJ_7fMHZ75XFPocMokLxVZczAhrBRBVN9uMhQFCZ4/

It's probably not bedtime reading, but I would really appreciate your comments if you have the energy to read through this (in the margins, right-click and leave comments - best if you are logged in to your Google account as you will appear under your name). This design will form the basis for my next implementation of booking methods in Beancount, and it could also be useful input in improving booking in Ledger or other implementations.

Thank you,

Stefano Zacchiroli

unread,
Jul 13, 2014, 1:12:20 PM7/13/14
to ledge...@googlegroups.com
On Mon, Jun 23, 2014 at 02:02:57AM -0400, Martin Blais wrote:
> I've been doing some thinking about improving the booking method used
> in Beancount. In the following document, I summarize the issues with
> inventory booking and list some unsatisfied use cases, identify
> current shortcomings in both Beancount and Ledger (with specific
> examples), list a set of requirements for a better inventory booking
> method and outline a design proposal for an improved method:
>
> https://docs.google.com/document/d/1F8IJ_7fMHZ75XFPocMokLxVZczAhrBRBVN9uMhQFCZ4/

I've finished going through it only now. I'm affected by one of the
problems you describe, namely the inability to book against the average
cost lot (your "{*}" syntax), and I've found the solution you propose
quite elegant. Ditto for the mechanisms of specifying lots and
resolving incomplete (or "ambiguous", if you wish) lot specifications.

[ In passing: the only way I've found with Ledger to actually find out
the average lot price is to first do
"ledger bal Stocks -l 'commodity == XXX'", then redo the same adding
"-B", and finally do the division myself. If there is a better way,
I'd be glad to learn about it. ]

I'm left wondering whether average cost basis should be a per account
property, rather than (or maybe: in addition to) something that
auto-magically happen the first time you post using "{*}".

Your main example for average cost basis are tax sheltered accounts. By
definition that is an example of an account-specific property. If that
is a common use case for average cost basis, then it'd make sense to
allow user to declare accounts (or account/commodity pairs, as we
discussed in the customizable rounding thread) as average cost basis.
Those accounts will have the property that they always contain a single
lot, whose cost is updated every time you post something to it,
computing the new average cost.

I wouldn't mind having both the ability to declare accounts as average
cost basis and, for other accounts, automatic fusion at the first
occurrence of "{*}".

I've also added other (minor/editorial) comments to the document itself.

Cheers.
--
Stefano Zacchiroli . . . . . . . za...@upsilon.cc . . . . o . . . o . o
Maître de conférences . . . . . http://upsilon.cc/zack . . . o . . . o o
Former Debian Project Leader . . @zack on identi.ca . . o o o . . . o .
« the first rule of tautology club is the first rule of tautology club »

Martin Blais

unread,
Jul 13, 2014, 1:27:33 PM7/13/14
to ledger-cli
On Sun, Jul 13, 2014 at 1:12 PM, Stefano Zacchiroli <za...@upsilon.cc> wrote:
On Mon, Jun 23, 2014 at 02:02:57AM -0400, Martin Blais wrote:
> I've been doing some thinking about improving the booking method used
> in Beancount. In the following document, I summarize the issues with
> inventory booking and list some unsatisfied use cases, identify
> current shortcomings in both Beancount and Ledger (with specific
> examples), list a set of requirements for a better inventory booking
> method and outline a design proposal for an improved method:
>
> https://docs.google.com/document/d/1F8IJ_7fMHZ75XFPocMokLxVZczAhrBRBVN9uMhQFCZ4/

I've finished going through it only now.  I'm affected by one of the
problems you describe, namely the inability to book against the average
cost lot (your "{*}" syntax), and I've found the solution you propose
quite elegant.  Ditto for the mechanisms of specifying lots and
resolving incomplete (or "ambiguous", if you wish) lot specifications.

[ In passing: the only way I've found with Ledger to actually find out
  the average lot price is to first do
  "ledger bal Stocks -l 'commodity == XXX'", then redo the same adding
  "-B", and finally do the division myself. If there is a better way,
  I'd be glad to learn about it. ]

That might even be incorrect, I'm not sure. I believe Ledger does not reduce lots, it seems to be matching positive and negative lots by "grouping" only at the reporting level (I'm not entirely sure about this, Zach make a comment on the doc this morning pointing out the --lot-prices and --lot-date options, and the behavior seems to point that way, e.g., you can "reduce" a lot that does not exist. I should go dig in the source code to find out). So if you have some past history of lot additions and reductions, they might affect the average cost you end up with using your method, whereas the current inventory may not include all the lots that are being used.


I'm left wondering whether average cost basis should be a per account
property, rather than (or maybe: in addition to) something that
auto-magically happen the first time you post using "{*}".

Yes, and I like that too. I think I mentioned adding an attribute to the Open directive somewhere in order to let the user specify the default booking method. I'll add a more explicit section in the proposal about this, with an example.


Your main example for average cost basis are tax sheltered accounts. By
definition that is an example of an account-specific property. If that
is a common use case for average cost basis, then it'd make sense to
allow user to declare accounts (or account/commodity pairs, as we
discussed in the customizable rounding thread) as average cost basis.
Those accounts will have the property that they always contain a single
lot, whose cost is updated every time you post something to it,
computing the new average cost.

I wouldn't mind having both the ability to declare accounts as average
cost basis and, for other accounts, automatic fusion at the first
occurrence of "{*}".

Yes, you're understanding everything right. That is exactly the proposal: let a user provide the default booking method, while leaving the possibility open for manual overrrides.



I've also added other (minor/editorial) comments to the document itself.

Thanks Stefano! :-)



Martin Blais

unread,
Jul 13, 2014, 1:29:12 PM7/13/14
to Martin Blais, ledger-cli
On Sun, Jul 13, 2014 at 1:27 PM, Martin Blais <bl...@furius.ca> wrote:

I'm left wondering whether average cost basis should be a per account
property, rather than (or maybe: in addition to) something that
auto-magically happen the first time you post using "{*}".

Yes, and I like that too. I think I mentioned adding an attribute to the Open directive somewhere in order to let the user specify the default booking method. I'll add a more explicit section in the proposal about this, with an example.

Stefano Zacchiroli

unread,
Jul 13, 2014, 7:12:06 PM7/13/14
to ledge...@googlegroups.com
On Sun, Jul 13, 2014 at 01:27:30PM -0400, Martin Blais wrote:
> That might even be incorrect, I'm not sure. I believe Ledger does not
> reduce lots, it seems to be matching positive and negative lots by
> "grouping" only at the reporting level (I'm not entirely sure about
> this, Zach make a comment on the doc this morning pointing out the
> --lot-prices and --lot-date options, and the behavior seems to point
> that way, e.g., you can "reduce" a lot that does not exist. I should
> go dig in the source code to find out). So if you have some past
> history of lot additions and So if you have some past history of lot
> additions and reductions, they might affect the average cost you end
> up with using your method, whereas the current inventory may not
> include all the lots that are being used.

I've already witnessed first hand that Ledger does allow you to reduce
lots that do not exist (going negative). So I'm still not seeing the
risk of incorrect calculation that you hinted at; if you think it's
real, can you try to build one? (or give me some extra hints so that I
can try building it).

> > I'm left wondering whether average cost basis should be a per account
> > property, rather than (or maybe: in addition to) something that
> > auto-magically happen the first time you post using "{*}".

On Sun, Jul 13, 2014 at 01:29:10PM -0400, Martin Blais wrote:
> Actually, there already is one, right here:
> https://docs.google.com/document/d/1F8IJ_7fMHZ75XFPocMokLxVZczAhrBRBVN9uMhQFCZ4/edit#heading=h.k18hdhviv191

Your comments made me realize two things:

1) what I actually had in mind was the ability to declare *mandatory*
average cost posting for a given account, inhibiting usage of other
booking methods on it. That was not entirely clear to me when I wrote
my previous message, so thanks for making me realize that :)

What it is currently supported by your proposal is only setting the
*default* booking method, but that does not stop others methods from
being used. The invariant I've mentioned in the previous post
(ensuring that only one lot exists) can be guaranteed only by
mandatory booking method.

[ Aside: upon re-reading the above section, the AVERAGE option is
kinda confusing. My understanding of the FIFO and LIFO options is
that they are limited to disambiguating among the lots that have
been selected by your matching algorithms, i.e., they are not
LIFO/FIFO across all lots. OTOH AVERAGE makes sense only when
computed across all lots. So discussing FIFO/LIFO together with
AVERAGE is puzzling. If that is really what you want, this "detail"
should be communicated more clearly, IMHO. ]

2) in terms of design, it'd probably be better to enforce the constraint
of having a single lot as some sort of post-booking check, rather
than overloading even more the expressivity of account declaration
options. (Note: I'm not a Beancounter user, so it's not clear to me
if you've enough expressivity in your checks to encode this. But that
sounds like a better place where to put this.)

Martin Blais

unread,
Jul 13, 2014, 8:08:08 PM7/13/14
to ledger-cli
On Sun, Jul 13, 2014 at 7:12 PM, Stefano Zacchiroli <za...@upsilon.cc> wrote:
On Sun, Jul 13, 2014 at 01:27:30PM -0400, Martin Blais wrote:
> That might even be incorrect, I'm not sure. I believe Ledger does not
> reduce lots, it seems to be matching positive and negative lots by
> "grouping" only at the reporting level (I'm not entirely sure about
> this, Zach make a comment on the doc this morning pointing out the
> --lot-prices and --lot-date options, and the behavior seems to point
> that way, e.g., you can "reduce" a lot that does not exist. I should
> go dig in the source code to find out). So if you have some past
> history of lot additions and So if you have some past history of lot
> additions and reductions, they might affect the average cost you end
> up with using your method, whereas the current inventory may not
> include all the lots that are being used.

I've already witnessed first hand that Ledger does allow you to reduce
lots that do not exist (going negative). So I'm still not seeing the
risk of incorrect calculation that you hinted at; if you think it's
real, can you try to build one? (or give me some extra hints so that I
can try building it).

Sure.
I've attached two Ledger input files which are nearly identical.

The first one has two transactions:

2014/06/01 Deposit some cash
  Equity:OpeningBalances
  Assets:Investing:Cash        $20000

P MSFT $520

2014/07/02 Buy one lot
  Assets:Investing:Stocks       5 MSFT @ $530
  Assets:Investing:Cash

2014/07/02 Buy one lot
  Assets:Investing:Stocks       5 MSFT @ $540
  Assets:Investing:Cash

P MSFT $550

If you use your method to calculate the number of shares and the cost basis, you get the correct results:

mandarine [default]:~/p/beancount$ ledger -f /home/blais/p/ledger-experiments/avgcost1.lgr --no-color bal Stocks
             10 MSFT  Assets:Investing:Stocks
mandarine [default]:~/p/beancount$ ledger -f /home/blais/p/ledger-experiments/avgcost1.lgr --no-color bal Stocks -B
               $5350  Assets:Investing:Stocks

So the average cost is 5350 $ / 10 MSFT = 535.00 $/MSFT.
This is correct.

Now add some past history of another transaction in the same commodity, being bought and sold at a different price, so it's gone back to zero by the time we replicate the transactions above:

2014/06/01 Deposit some cash
  Equity:OpeningBalances
  Assets:Investing:Cash        $20000

2014/06/02 Buy one lot
  Assets:Investing:Stocks       10 MSFT @ $500
  Assets:Investing:Cash

2014/06/03 Sell the lot
  Assets:Investing:Stocks      -10 MSFT @ $510
  Assets:Investing:Cash

P MSFT $520

2014/07/02 Buy one lot
  Assets:Investing:Stocks       5 MSFT @ $530
  Assets:Investing:Cash

2014/07/02 Buy one lot
  Assets:Investing:Stocks       5 MSFT @ $540
  Assets:Investing:Cash

P MSFT $550

Notice that ALL I've done is insert the purchase and sale on 6/2 and 6/3. Everything else is exactly the same.
Now try calculating the average cost using your method:

mandarine [default]:~/p/beancount$ ledger -f /home/blais/p/ledger-experiments/avgcost2.lgr --no-color bal Stocks
             10 MSFT  Assets:Investing:Stocks
mandarine [default]:~/p/beancount$ ledger -f /home/blais/p/ledger-experiments/avgcost2.lgr --no-color bal Stocks -B
               $5250  Assets:Investing:Stocks

Oops... now the average cost basis is 5250 $/MSFT.
A bit of a difference, don't you think?
I'm not sure if Martin's patch would affect the outcome.
This is a real problem with the way you're computing your cost basis.

After my experiments with Ledger, I've come to think its model of calculation is incorrect.
Here's what needs to be done to fix it:

(1) Inventory booking is not a feature that needs to be carried out at reporting time. Matching inventory lots need to be done only once, with no options, needs to be unambiguous, as part of the processing of the flow of transactions. When a position is reduced, a single and appropriate matching position must be selected.

(2) In order to carry this out properly, a distinction needs to be drawn between currency conversions and commodities held at cost, because being able to enforce booking correctly means that you will now force the user to specify cost for all these currency conversion, and your currency conversions would become a pain in the blank to do (nobody cares about the cost basis of price conversions).

Of course I'm more than a little biased: this is the model I've implemented in Beancount.
A nice side-effect of (1) is that I'm able to output a list of inventory reductions, a list of "trades."
I used to have this report in the first version, but have removed it. I'll bring it back shortly after my next release.
(Some reporting authorities require you to provide the detail of your trades, so that's a practically useful report to generate.)


> > I'm left wondering whether average cost basis should be a per account
> > property, rather than (or maybe: in addition to) something that
> > auto-magically happen the first time you post using "{*}".

On Sun, Jul 13, 2014 at 01:29:10PM -0400, Martin Blais wrote:
> Actually, there already is one, right here:
> https://docs.google.com/document/d/1F8IJ_7fMHZ75XFPocMokLxVZczAhrBRBVN9uMhQFCZ4/edit#heading=h.k18hdhviv191

Your comments made me realize two things:

1) what I actually had in mind was the ability to declare *mandatory*
   average cost posting for a given account, inhibiting usage of other
   booking methods on it. That was not entirely clear to me when I wrote
   my previous message, so thanks for making me realize that :)

   What it is currently supported by your proposal is only setting the
   *default* booking method, but that does not stop others methods from
   being used.  The invariant I've mentioned in the previous post
   (ensuring that only one lot exists) can be guaranteed only by
   mandatory booking method.

So if you never select a particular lot, how is just using a default different than imposing it?
Are you worried about making mistakes and would like to detect it?
Or is it that you would prefer the inventory _always_ only include a single lot for that commodity, somehow?

If so... why? The cost basis of the aggregation should always sum to the same value, many lots of just-one-lot.
From a software implementation perspective, it's nice to just enforce one lot, but in terms of the calculations, it will make no difference.
Leaving the multiple lots to hang around until the next aggregation time _does_ provide the opportunity for a user to book differently.

I'm not so sure I understand your concern. Please be specific (this is subtle).
If you use {} to specify the cost, e.g., 

  ...    -10 MSFT {}

this is only unambiguous in the case the inventory has a single lot for that commodity, so that degenerates to the same as the average cost (the average cost of one lot is ... just the cost of that lot).
Otherwise, you'd have to use {*} everywhere there might be ambiguity:

  ...    -10 MSFT {*}

In which case every lot reduction triggers an aggregation. 

Besides, after a single aggregation of multiple lots takes place, a user will have little idea of the actual per-unit cost basis, so it's rather unlikely he will specify that oddball cost.



   [ Aside: upon re-reading the above section, the AVERAGE option is
     kinda confusing. My understanding of the FIFO and LIFO options is
     that they are limited to disambiguating among the lots that have
     been selected by your matching algorithms, i.e., they are not
     LIFO/FIFO across all lots. OTOH AVERAGE makes sense only when
     computed across all lots. So discussing FIFO/LIFO together with
     AVERAGE is puzzling. If that is really what you want, this "detail"
     should be communicated more clearly, IMHO. ]

That's an interesting point. From an implementor's point-of-view, it makes all the sense in the world to speak of these together. But from a user's point-of-view, it does raise questions. The question is: Will an average Beancount user be required to understand the inventory booking methods well enough to use them? If so, it would make little difference to discuss it together. I'm not sure.

In any case, your bringing it up tells me I need to discuss the subtlety in the final documentation. I'll have to discuss the possibility of merging methods and probably warn against it.

 

2) in terms of design, it'd probably be better to enforce the constraint
   of having a single lot as some sort of post-booking check, rather
   than overloading even more the expressivity of account declaration
   options. (Note: I'm not a Beancounter user, so it's not clear to me
   if you've enough expressivity in your checks to encode this. But that
   sounds like a better place where to put this.)

Yes, this is a good idea. In general I like to perform checks in separate stages, it makes the code a lot nicer and opens up the possibility to shove this check into a plugin that you could enable only if you want it. An easy way to do this without a syntax extension would be to specify a AVERAGE_ONLY booking type, that would barf if the user attempts to use a non-average method and that might trigger the aggregation on additions as well.

I'll update the proposal doc.

Thanks a lot for putting some effort in understanding and discussing this long proposal Stefano.



avgcost1.lgr
avgcost2.lgr

Martin Blais

unread,
Jul 13, 2014, 9:03:34 PM7/13/14
to ledger-cli
On Sun, Jul 13, 2014 at 8:08 PM, Martin Blais <bl...@furius.ca> wrote:
On Sun, Jul 13, 2014 at 7:12 PM, Stefano Zacchiroli <za...@upsilon.cc> wrote:
On Sun, Jul 13, 2014 at 01:27:30PM -0400, Martin Blais wrote:2) in terms of design, it'd probably be better to enforce the constraint
   of having a single lot as some sort of post-booking check, rather
   than overloading even more the expressivity of account declaration
   options. (Note: I'm not a Beancounter user, so it's not clear to me
   if you've enough expressivity in your checks to encode this. But that
   sounds like a better place where to put this.)

Yes, this is a good idea. In general I like to perform checks in separate stages, it makes the code a lot nicer and opens up the possibility to shove this check into a plugin that you could enable only if you want it. An easy way to do this without a syntax extension would be to specify a AVERAGE_ONLY booking type, that would barf if the user attempts to use a non-average method and that might trigger the aggregation on additions as well.

I'll update the proposal doc.

Stefano Zacchiroli

unread,
Jul 14, 2014, 4:35:10 PM7/14/14
to ledge...@googlegroups.com
On Sun, Jul 13, 2014 at 08:08:04PM -0400, Martin Blais wrote:
> > I've already witnessed first hand that Ledger does allow you to
> > reduce lots that do not exist (going negative). So I'm still not
> > seeing the risk of incorrect calculation that you hinted at; if you
> > think it's real, can you try to build one? (or give me some extra
> > hints so that I can try building it).

[ answering only this part of your email for now, more later ]

> I've attached two Ledger input files which are nearly identical.

Thanks.

> 2014/06/03 Sell the lot
> Assets:Investing:Stocks -10 MSFT @ $510
> Assets:Investing:Cash

So, this looks incorrect to me --- or, better, I've learned from
folklore and first hand experience that with ledger-cli you should never
reduce without specifying the lot price (or, even better, I should
probably state that the semantics of what happens if you do *not*
specify lot price is unclear to me).

So I've changed this part of your example in:

2014/06/03 Sell the lot
Assets:Investing:Stocks -10 MSFT {$500} @ $510
Assets:Investing:Cash

see attached avgcost3.lgr

> I'm not sure if Martin's patch would affect the outcome. This is a
> real problem with the way you're computing your cost basis.

Yes, this is a very serious problem, not only with my method of
computing cost basis, but with cost computation in general. Thanks for
pointing it out. OTOH, the problem is fixed by Martin's patch for #713
[1], at least on the few examples I've tried, including yours.

[1]: http://bugs.ledger-cli.org/show_bug.cgi?id=713
fixed in Git's branch "713-cost"

Can we please merge this into master? Using ledger-cli for stock
accounting without this patch seems reckless to me.

FWIW, I've also tried a slightly difference example (see avgcost4.lgr),
where I reduce using average cost basis, and in particular I reduce a
lot that doesn't exist. It still works correctly with Martin's patch.

> After my experiments with Ledger, I've come to think its model of
> calculation is incorrect.
> Here's what needs to be done to fix it:

For the very little that that is worth, I'm convinced by your analysis.
avgcost3.lgr
avgcost4.lgr

Martin Blais

unread,
Jul 14, 2014, 5:07:22 PM7/14/14
to ledger-cli
On Mon, Jul 14, 2014 at 4:34 PM, Stefano Zacchiroli <za...@upsilon.cc> wrote:
On Sun, Jul 13, 2014 at 08:08:04PM -0400, Martin Blais wrote:
> 2014/06/03 Sell the lot
>   Assets:Investing:Stocks      -10 MSFT @ $510
>   Assets:Investing:Cash

So, this looks incorrect to me --- or, better, I've learned from
folklore and first hand experience that with ledger-cli you should never
reduce without specifying the lot price (or, even better, I should
probably state that the semantics of what happens if you do *not*
specify lot price is unclear to me).

So I've changed this part of your example in:

  2014/06/03 Sell the lot
    Assets:Investing:Stocks      -10 MSFT {$500} @ $510
    Assets:Investing:Cash

see attached avgcost3.lgr

I had also tried this before I sent out my email. 
The result is the same (without the patch).

Martin Michlmayr

unread,
Jul 14, 2014, 5:13:22 PM7/14/14
to ledge...@googlegroups.com
* Stefano Zacchiroli <za...@upsilon.cc> [2014-07-14 22:34]:
> So, this looks incorrect to me --- or, better, I've learned from
> folklore and first hand experience that with ledger-cli you should never
> reduce without specifying the lot price (or, even better, I should
> probably state that the semantics of what happens if you do *not*
> specify lot price is unclear to me).

I'm behind email and haven't read the thread yet, but what happens is
that you end up with negative lots. You can see what's going on
behind the scenes by adding --lot-prices:

10 MSFT {$500}
-10 MSFT {$510} Assets:Investing:Stocks

> [1]: http://bugs.ledger-cli.org/show_bug.cgi?id=713
> fixed in Git's branch "713-cost"
>
> Can we please merge this into master? Using ledger-cli for stock
> accounting without this patch seems reckless to me.

Yes, will do.

--
Martin Michlmayr
http://www.cyrius.com/

Stefano Zacchiroli

unread,
Jul 14, 2014, 5:19:52 PM7/14/14
to ledge...@googlegroups.com
On Mon, Jul 14, 2014 at 05:07:19PM -0400, Martin Blais wrote:
> > 2014/06/03 Sell the lot
> > Assets:Investing:Stocks -10 MSFT {$500} @ $510
> > Assets:Investing:Cash
>
> I had also tried this before I sent out my email.
> The result is the same (without the patch).

Yes, that's "right".
My point is that the above example does work *with* the patch.

Martin Blais

unread,
Jul 14, 2014, 5:46:40 PM7/14/14
to ledger-cli
On Mon, Jul 14, 2014 at 5:13 PM, Martin Michlmayr <t...@cyrius.com> wrote:
* Stefano Zacchiroli <za...@upsilon.cc> [2014-07-14 22:34]:
> So, this looks incorrect to me --- or, better, I've learned from
> folklore and first hand experience that with ledger-cli you should never
> reduce without specifying the lot price (or, even better, I should
> probably state that the semantics of what happens if you do *not*
> specify lot price is unclear to me).

I'm behind email and haven't read the thread yet, but what happens is
that you end up with negative lots.  You can see what's going on
behind the scenes by adding --lot-prices:

      10 MSFT {$500}
     -10 MSFT {$510}  Assets:Investing:Stocks

The core of all the problems you're encountering in correctly accounting for lots in Ledger is exactly what you are pointing out: negative lots should never be allowed in the first place (or more precisely, a more permissive and equally useful rule would be to disallow a mix of positive and negative lots of the same commodity in order to allow for short positions to take place; if you implemented this, you would catch a ton of problems in the user's data entry early on...).


Stefano Zacchiroli

unread,
Jul 16, 2014, 4:06:18 AM7/16/14
to ledge...@googlegroups.com
On Sun, Jul 13, 2014 at 08:08:04PM -0400, Martin Blais wrote:
> On Sun, Jul 13, 2014 at 7:12 PM, Stefano Zacchiroli <za...@upsilon.cc> wrote:
> > 1) what I actually had in mind was the ability to declare *mandatory*
> > average cost posting for a given account, inhibiting usage of other
> > booking methods on it. That was not entirely clear to me when I wrote
> > my previous message, so thanks for making me realize that :)
> >
> > What it is currently supported by your proposal is only setting the
> > *default* booking method, but that does not stop others methods from
> > being used. The invariant I've mentioned in the previous post
> > (ensuring that only one lot exists) can be guaranteed only by
> > mandatory booking method.
>
> So if you never select a particular lot, how is just using a default
> different than imposing it?
> Are you worried about making mistakes and would like to detect it?

Yes, that's it. My specific use case is a stock account in Italy, which
is automatically taxed by the bank, and where I can only sell at average
cost. On that account, reducing a lot which is not the average cost lot
would definitely be a mistake, and I'd like to detect it.

> Or is it that you would prefer the inventory _always_ only include a
> single lot for that commodity, somehow?

I guess it depends what do you mean with "always" here. If you mean
limited to that account, then yes, that is what I want. (I note that
this invariant is only slightly different than inhibit postings to
non-average-cost lots. Is is more powerful, but would be definitely good
enough for me.)

> I'm not so sure I understand your concern. Please be specific (this is
> subtle).
> If you use {} to specify the cost, e.g.,
>
> ... -10 MSFT {}
>
> this is only unambiguous in the case the inventory has a single lot for
> that commodity, so that degenerates to the same as the average cost (the
> average cost of one lot is ... just the cost of that lot).
> Otherwise, you'd have to use {*} everywhere there might be ambiguity:
>
> ... -10 MSFT {*}
>
> In which case every lot reduction triggers an aggregation.

If there is a way to enforce the invariant that there is always only one
lot, then I'd be fine with the {} version. But AFAICT there is no such
way, as when I buy, it will create lots at different prices, right?

So, unless there is a way to automatically trigger lot merge also when
*increasing* a position, it looks like one will have to invariably use
the {*} version because, AFAIU the current state of your spec, lot
merges are performed only when reducing. (Or maybe they also happen upon
increases if you've chosen AVERAGE as the default posting method, but
that was not entirely clear to me upon first read.)

Martin Blais

unread,
Jul 16, 2014, 7:54:54 AM7/16/14
to ledger-cli
On Wed, Jul 16, 2014 at 4:06 AM, Stefano Zacchiroli <za...@upsilon.cc> wrote:

> I'm not so sure I understand your concern. Please be specific (this is
> subtle).
> If you use {} to specify the cost, e.g.,
>
>   ...    -10 MSFT {}
>
> this is only unambiguous in the case the inventory has a single lot for
> that commodity, so that degenerates to the same as the average cost (the
> average cost of one lot is ... just the cost of that lot).
> Otherwise, you'd have to use {*} everywhere there might be ambiguity:
>
>   ...    -10 MSFT {*}
>
> In which case every lot reduction triggers an aggregation.

If there is a way to enforce the invariant that there is always only one
lot, then I'd be fine with the {} version. But AFAICT there is no such
way, as when I buy, it will create lots at different prices, right?

Yes. When you buy, you cannot use {} nor {*} anyway, you have to provide the cost basis.
The question at hand is whether it triggers a merge of the lots right away, or later, on the subsequent reduction.

 

So, unless there is a way to automatically trigger lot merge also when
*increasing* a position, it looks like one will have to invariably use
the {*} version because, AFAIU the current state of your spec, lot
merges are performed only when reducing. (Or maybe they also happen upon
increases if you've chosen AVERAGE as the default posting method, but
that was not entirely clear to me upon first read.)

Auto-trigger lot merge on lot creation is a good idea.
When I implement it I'll see if it fits the paradigm, it might be easy and it might just make sense.

Reply all
Reply to author
Forward
0 new messages