inventory and position when no investments involved

122 views
Skip to first unread message

Chary Chary

unread,
Feb 3, 2023, 3:14:23 PM2/3/23
to Beancount
Dear all,

can somebody explain please in simple terms what is the meaning of inventory and position in the situation, when no investment is involved and when I only track expenses and incomes in different currencies?

I understand what is transaction and posting,  but for instance the description in the help of beanquery still remains cryptic for me 


  'SUM(Inventory)': Calculate the sum of the inventories. The result is an
    Inventory.
  'SUM(Position)': Calculate the sum of the position. The result is an
    Inventory.

Daniele Nicolodi

unread,
Feb 3, 2023, 3:45:38 PM2/3/23
to bean...@googlegroups.com
On 03/02/23 21:14, Chary Chary wrote:
> Dear all,
>
> can somebody explain please in simple terms what is the meaning of
> *inventory *and *position *in the situation, when no investment is
> involved and when I only track expenses and incomes in different currencies?
>
> I understand what is *transaction *and *posting*,  but for instance the
> description in the help of *beanquery *still remains cryptic for me

An Amount is a number with attached a currency (also referred sometimes
as commodity).

A Position is an Amount with attached a Cost specification.

A Posting associated an Amount and an optinal Cost ton an Account.

An Inventory is a container for Positions. When you sum Positions (or
Amounts) not necessarily all of them are in the same currency /
commodity or have the same Cost associated.

I would have guessed that this is explained somewhere in the Beancount
documentation, but I would not be able to pinpoint where now.

Cheers,
Dan

Chary Chary

unread,
Feb 4, 2023, 6:24:56 AM2/4/23
to Beancount
Dan,

OK, thanks. But just some clarification.


If I look at the following  simple Transaction:

2000-01-02 * "Buying something in Euro"
    Assets:NL:ING:Payment               -100 EUR
    Expenses:Misc                                100 EUR

Then does it have position or not?

In Python after loading in beancount it looks like this

Transaction(meta={'filename': 'C:\\_code\\py\\mybean\\experiments\\simpleSimulation\\simpleSimulation.bean',
                  'lineno': 30,
                  '__tolerances__': {}},
            date=datetime.date(2000, 1, 2),
            flag='*',
            payee=None,
            narration='Buying something in Euro',
            tags=frozenset(),
            links=frozenset(),
            postings=[Posting(    account='Assets:NL:ING:Payment',
                                units=-100 EUR,
                                cost=None,
                                price=None,
                                flag=None,
                                meta={    'filename': 'C:\\_code\\py\\mybean\\experiments\\simpleSimulation\\simpleSimulation.bean',
                                        'lineno': 31}),
                     Posting(    account='Expenses:Misc',
                                units=100 EUR,
                                cost=None,
                                price=None,
                                flag=None,
                                meta={    'filename': 'C:\\_code\\py\\mybean\\experiments\\simpleSimulation\\simpleSimulation.bean',
                                        'lineno': 32})])


I can see tarnsaction, postings, units, but I do not see a position

However if I use beanquery, then beanquery does see the position:

beancount> select date, narration, position

   date            account                        narration                  position
---------- ----------------------- --------------------------------------- ------------
2000-01-02 Assets:NL:ING:Payment   Buying something in Euro                 -100    EUR
2000-01-02 Expenses:Misc           Buying something in Euro                  100    EUR


So, the position here is   100    EUR,  however in Python data structure, it does not have a cost, which is, per your definition, is not a position.

So, once again, what is the definition of a position then?

Daniele Nicolodi

unread,
Feb 4, 2023, 7:46:35 AM2/4/23
to bean...@googlegroups.com
On 04/02/23 12:24, Chary Chary wrote:
> Dan,
>
> OK, thanks. But just some clarification.
>
>
> If I look at the following  simple Transaction:
>
> 2000-01-02 * "Buying something in Euro"
>     Assets:NL:ING:Payment               -100 EUR
>     Expenses:Misc                                100 EUR
>
> Then does it have position or not?

Transactions do not have positions. Transactions contain postings. Each
posting has an account and a position (although they are not spelled out
like that in the data structure, see below).

> I can see *tarnsaction, postings*, *units*, but I do not see a *position*
>
> However if I use beanquery, then beanquery does see the position:

There is not alway a 1:1 mapping between the Beancount data model and
the tables definitions used by beanquery. In this case, the 'position'
column is obtained from the units and cost fields in the Posting object.

https://github.com/beancount/beanquery/blob/f224aa8161495b9fddb7c7f712e5103b8b8b59e3/beanquery/query_env.py#L1054-L1058

I don't know why it was chosen to have a 'position' column but not an
'amount' column in beanquery. Most likely because a position without a
cost is pretty much equivalent to an amount from a beanquery point of view.

> So, the position here is  100    EUR,  however in Python data structure,
> it does not have a cost, which is, per your definition, is not a position.
>
> So, once again, what is the definition of a *position *then?

I forgot an "optional" in the definition of Position:

A Position is an Amount with attached an /optional/ Cost specification

I think
https://beancount.github.io/docs/beancount_query_language.html#data-types
does quite good job in explaining the data types used in BQL and what
they represent.

Cheers,
Dan

Martin Blais

unread,
Feb 4, 2023, 9:30:06 AM2/4/23
to bean...@googlegroups.com
On Sat, Feb 4, 2023 at 7:46 AM Daniele Nicolodi <dan...@grinta.net> wrote:
On 04/02/23 12:24, Chary Chary wrote:
> Dan,
>
> OK, thanks. But just some clarification.
>
>
> If I look at the following  simple Transaction:
>
> 2000-01-02 * "Buying something in Euro"
>      Assets:NL:ING:Payment               -100 EUR
>      Expenses:Misc                                100 EUR
>
> Then does it have position or not?

Transactions do not have positions. Transactions contain postings. Each
posting has an account and a position (although they are not spelled out
like that in the data structure, see below).

That's right. 
A position is roughly (units, cost-basis)
A posting is roughly position + (account, price)
In inventories we track positions (potentially across accounts)
Price is only used for conversions within the transactions.
So when accumulating postings, account and price can be dropped, thus position.

I'm sure there are many other ways to design data structures for aggregation but that's what I chose at the time.



> I can see *tarnsaction, postings*, *units*, but I do not see a *position*
>
> However if I use beanquery, then beanquery does see the position:

There is not alway a 1:1 mapping between the Beancount data model and
the tables definitions used by beanquery. In this case, the 'position'
column is obtained from the units and cost fields in the Posting object. 

https://github.com/beancount/beanquery/blob/f224aa8161495b9fddb7c7f712e5103b8b8b59e3/beanquery/query_env.py#L1054-L1058

I don't know why it was chosen to have a 'position' column but not an
'amount' column in beanquery. Most likely because a position without a
cost is pretty much equivalent to an amount from a beanquery point of view.

Which amount? 
There's a units amount, but a position can be reduced to its cost amount by applying the cost basis to its units.
You can either
- aggregate the positions and then reduce to cost, or
- reduce all positions to their cost amount and then aggregate them
I think both work.

select parent(account), cost(sum(position)) ...
select parent(account), sum(cost(position)) ...


> So, the position here is  100    EUR,  however in Python data structure,
> it does not have a cost, which is, per your definition, is not a position.
>
> So, once again, what is the definition of a *position *then?

I forgot an "optional" in the definition of Position:

A Position is an Amount with attached an /optional/ Cost specification

I think
https://beancount.github.io/docs/beancount_query_language.html#data-types
does quite good job in explaining the data types used in BQL and what
they represent.

Thanks!
Eventually I'll document those from a public API perspective, e.g. in v3 there is
In v3 it will be nice to break out the booking into its individual parts and let users play with those with an import like

  import beancount as bn
  inv = bn.Inventory(...)
...


Cheers,
Dan

--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/d3508404-780f-c55b-9b81-ba0e8fdd65c0%40grinta.net.

fin

unread,
Feb 4, 2023, 10:42:04 AM2/4/23
to bean...@googlegroups.com
Martin Blais wrote:
...
> Eventually I'll document those from a public API perspective, e.g. in v3
> there is
> https://github.com/beancount/beancount/blob/master/beancount/api.py
> In v3 it will be nice to break out the booking into its individual parts
> and let users play with those with an import like
>
> import beancount as bn
> inv = bn.Inventory(...)
> ...

lot numbers, fifo and lifo trading would be nice for
stock/etc transactions. :)


fin

Martin Blais

unread,
Feb 4, 2023, 11:29:50 AM2/4/23
to bean...@googlegroups.com
Yes, I'd like to expose all that.

 


  fin


--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.

Chary Chary

unread,
Feb 4, 2023, 4:07:01 PM2/4/23
to Beancount
Martin, Dan,

thanks

Regarding:

* A position is roughly (units, cost-basis)
* A Position is an Amount with attached a Cost specification.

Question: what is then the formal definition of the cost, especially  in the situation, when 

units=100 EUR,
cost=None,

As I understand, the cost will be 100 Euro. But what is the formal definition of the cost in the beancount world?

Martin Blais

unread,
Feb 4, 2023, 4:58:41 PM2/4/23
to bean...@googlegroups.com

Chary Chary

unread,
Feb 5, 2023, 5:46:28 AM2/5/23
to Beancount
On, thanks, and the definition of the cost function would be something like this:

def COST(position):
    if position.cost:
        return position.cost
    else:
        return position.utits

Correct?

Martin Blais

unread,
Feb 5, 2023, 10:42:44 AM2/5/23
to bean...@googlegroups.com
On Sun, Feb 5, 2023 at 5:46 AM Chary Chary <char...@gmail.com> wrote:


On Saturday, February 4, 2023 at 10:58:41 PM UTC+1 bl...@furius.ca wrote:

On, thanks, and the definition of the cost function would be something like this:

def COST(position):
    if position.cost:
        return position.cost
    else:
        return position.utits

Correct?


No, the cost of a position is units * cost, if there's a cost; otherwise it's just units.


 

Chary Chary

unread,
Feb 6, 2023, 7:58:27 AM2/6/23
to Beancount
Martin,

thanks. This is clear now. 

Regards.
Reply all
Reply to author
Forward
0 new messages