Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for commodities / units / currencies #124

Open
hrj opened this issue Jan 5, 2017 · 7 comments
Open

Support for commodities / units / currencies #124

hrj opened this issue Jan 5, 2017 · 7 comments

Comments

@hrj
Copy link
Owner

hrj commented Jan 5, 2017

No description provided.

@hrj hrj added the enhancement label Jan 5, 2017
@jaa127
Copy link
Contributor

jaa127 commented Jan 31, 2017

I stumbled to Unit library written in scala Squants. It seems to be doing lot of stuff which would be handy with units / currencies.

In any case, it would be good to be able support at least following use cases:

  1. "units" where there is constant conversion between units e.g.:

    • centimeters to inches
    • liters to gallons
    • centimeters to meters or kilometers
    • seconds to hours, and to days
      • special case: what to do with leap seconds? Is time actually "currency" with exchange rate to hours and days?
  2. currencies which are possible to convert between each other, but exchange rate varies, and typically exchance rate is not know at the time of transaction. Probably these should be handled via currency accounts, where exchange rate can be recorded as it happened, and day-to-day value of currency account could be "exchanged" based on current rates.

    • Are stocks and other financial instruments "currencies" e.g. can they be handled via same mechanism, or do they need own category/type?
  3. Commodities which doesn't have conversion nor value. These are plain values, as Abandon values are at the moment.

@hrj
Copy link
Owner Author

hrj commented Jan 31, 2017

Agreed @jaa127

My design notes:

  • Currencies / units / commodities can be implemented as normal accounts with a special name. For example, USD income could be represented by Income:_USD. The underscore at the front of the name indicates that it's a currency / unit / commodity.
  • Any account with an underscore prefixed before it is "strongly typed". You can only transfer amounts if the names match. For example, you can only transfer between two _USD accounts.
  • When transferring amounts between two different types, say between _USD and _INR, a conversion has to be made. The conversion can be either implicit or explicit.
    • explicit conversion: for example, Income:_INR 100 @ 50 \n Assets:Bank:_USD would convert 100 INR to 2 USD (at the rate of 50 INR per USD).
    • implicit conversion: If explicit rate is not specified and there is a function named INR_to_USD in the current scope, it is used to automatically convert from INR to USD.

Optional

  • Syntax sugar for specifying the unit. For example Income INR 50 would be shorthand for Income:_INR 50.
  • Constraint: Prefixed accounts can't have children; they have to be leaf nodes (this constraint is not necessary and can be relaxed later).

@jaa127
Copy link
Contributor

jaa127 commented Feb 1, 2017

How about if there is formal account definition at the begin of parsing process (e.g. begin of ledger file or provided by config-file). This would allow to assing all kind of metadata to accounts (e.g. #108, #60), and define default unit / commodity per account.

It would also be handy, if you could mix commodities inside account. For example you could have cash in multiple currencies, and to have multiple cash accounts to be able handle multiple currencies is kind of inconvenient. It should also be desided how mixed commodities (tree) balances are handled in case of different commodities.

@hrj
Copy link
Owner Author

hrj commented Feb 1, 2017

How about if there is formal account definition at the begin of parsing process (e.g. begin of ledger file or provided by config-file). This would allow to assing all kind of metadata to accounts (e.g. #108, #60), and define default unit / commodity per account.

Agreed; though I think we can build this later, once the core support for currencies is in place.

It would also be handy, if you could mix commodities inside account. For example you could have cash in multiple currencies, and to have multiple cash accounts to be able handle multiple currencies is kind of inconvenient. It should also be desided how mixed commodities (tree) balances are handled in case of different commodities.

I think all this is handled by my idea of using special account names. Basically, we already have a tree structure, and currencies can be just represented as children. It seems simpler from both user's and developer's point of view. It avoids the need to create a separate structure inside every account. I am not sure why you think it would be inconvenient. If you can give an example in a .ledger format, it would be useful to me.

@jaa127
Copy link
Contributor

jaa127 commented Feb 1, 2017

I am not sure why you think it would be inconvenient. If you can give an example in a .ledger format, it would be useful to me.

The main reason is that there is need to maintain multiple separate accounts just for commodities.

Real example: There is car trip from Finland to Norway via Sweden. Finland is Euro (EUR), Sweden is Krona (SEK) and Norway is Krone (NOK). In each country I byu fuel and some other car related stuff.

If this is done without commodities as leaf accounts, then it could be something like this:

2017-02-01 car stuff in finland
    e:car      1 EUR ; general purpose car stuff
    e:car:fuel    20 EUR ; fuel
    a:cash

2017-02-01 car stuff in sweden
    e:car        10 SEK    ; general purpose car stuff
    e:car:fuel    200 SEK ; fuel
    a:cash

2017-02-01 car stuff in norway
    e:car       10 NOK   ; general purpose car stuff
    e:car:fuel  200 NOK ; fuel
    a:cash

If commodities are leaf accounts, then this gets really messy. Especially if I didn't know that I will visit Norway and Sweden by car, when Chart of Accounts was established....

@hrj
Copy link
Owner Author

hrj commented Feb 2, 2017

Chart of Accounts is a good point. Out of curiosity, how do you define it in abandon currently? Or is it a concern for the future? Perhaps we can make currency accounts exempt from Chart of Account?

Hmm, from your example, I have another doubt:

2017-02-01 car stuff in sweden
    e:car        10 SEK    ; general purpose car stuff
    e:car:fuel    200 SEK ; fuel
    a:cash

What if a:cash has a balance of 100 SEK? Should abandon

  1. deduct 100 SEK from a:cash and try to deduct the remaining 110 SEK by converting from another currency?
  2. Or should it just allow the amount of a:cash to get negative?
  3. Or should it flag an error?

With the currency-as-leaf-account design the answer is 2. If there is an always-positive constraint set for a:cash it would result in 3.

@hrj
Copy link
Owner Author

hrj commented Feb 2, 2017

Answering my own doubt:

If 1 is desired, then the transaction entry can be:

2017-02-01 car stuff in sweden
    e:car        10 SEK    ; general purpose car stuff
    e:car:fuel    200 SEK ; fuel
    a:cash    -100 SEK
    a:cash:_EUR

(balance adjustment would be done from EUR currency).

This will work with any design (leaf-currency-account or otherwise).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants