UP | HOME

The beans manual

Table of Contents

1 About beans

beans is a plain text accounting tool in the tradition of ledger, hledger and beancount.

1.1 Project goals

1.1.1 Built-in file importers

The greatest pain of plain text accounting is to import financial statements from financial service providers such as banks and credit cards. beans strives to include importers for known formats.

1.1.2 Automatic categorization

beans provides a Bayesien inference (machine learning) engine to automatically assign accounts based on your existing ledger.

1.1.3 beans always balances

beans aims to make it simple to do at-market valuations of your assets, while maintaining correctness of the balance. Instead of converting aggregated account data and adding valuation as an afterthought, beans applies valuation directly at the transaction level. For example, if you choose to display a balance at market prices, beans will transparently insert valuation transactions to reflect gains and losses due to price changes.

1.1.4 Transcode to beancount

Translate your beans journal into a beancount-compatible format to make use of the great tooling universe of beancount, such as the Fava web interface.

1.1.5 Simple implementation

beans is written in Haskell, an excellent language for concise and beautiful code. Also, while beans adopts concepts from other tools, compatiblity is not an objective.

1.2 Changes (if you used a previous version)

  • The previous rules engine got replaced by a Bayesian inference mechanism, which in practice is much less work.
  • The file format changed: no more indentation, for friendlier editing
  • Multi-column reports
  • Some more importers
  • Lots of changes under the hood

2 Getting beans

2.1 Obtaining the source

beans' source code can be found on github. For the moment, you have to build from source.

Make sure you have git installed and run:

git clone https://github.com/sboehler/beans.git

2.2 Installing beans

2.2.1 Using Stack

stack is probably the easiest option on most platforms to get started quickly. First, follow the instructions here to install stack for your platform. Then:

cd beans
stack install

This will install the beans binary in $HOME/.local/bin/beans. Add this directory to your path and you're good to go:

export PATH=~/.local/bin:$PATH

Please file a bug if you encounter problems using stack.

2.2.2 Using Nix

Make sure you have the nix package manager installed for your platform. Then:

cd beans
nix-build --attr beans release.nix

The beans binary will be made available locally in ./result/bin/beans and can be run from there. I am using nix to develop beans, so this option is the one that is supported best.

2.2.3 Using Cabal

If you intend to develop beans or run the test suite. Make sure cabal and hpack are installed:

cd beans
cabal new-build

The beans binary will be made available in ./dist/build/beans/beans and can be run from there.

2.3 Getting help

This guide is incomplete and might be out of date. To get an overview of your possibilities, beans has a built-in help command:

beans --help
beans

Usage: beans COMMAND
  A plain text accounting tool

Available options:
  -h,--help                Show this help text

Available commands:
  balance                  Print a generic balance
  fetch                    Fetch latest prices
  import                   Import transactions
  infer                    Infer accounts
  transcode                Transcode to beancount

3 Working with beans

beans is a command line tool and has some self-documenting features. Run the following command to get started:

beans --help
beans

Usage: beans COMMAND
  A plain text accounting tool

Available options:
  -h,--help                Show this help text

Available commands:
  balance                  Print a generic balance
  fetch                    Fetch latest prices
  import                   Import transactions
  infer                    Infer accounts
  transcode                Transcode to beancount

Use beans <command> --help to get further help on available options.

3.1 Importing data

beans offers assistance with importing bank account statements, the most tiring process in plain text accounting.

3.1.1 Importers

In a first step, bank account statements need to be parsed. The following is what a statement from my bank might look like.

Datum von:;2017-05-23
Buchungsart:;Alle Buchungen
Konto:;CHXXXXXXXXXXXXXXXXXXX
Währung:;CHF
Buchungsdatum;Avisierungstext;Gutschrift;Lastschrift;Valuta;Saldo
2017-06-01;"Acme Corp";;-135.00;2017-06-01;
2017-05-31;"FOOBAR COMMUNICATIONS";;-52.60;2017-05-31;
2017-05-29;"Transfer 01-45-06 Bigbank";;-1040.00;2017-05-29;36096.54
2017-05-26;"Cleaning Service";;-300.00;2017-05-24;37136.54
2017-05-26;"Supermarket Fine Foods";;-115.20;2017-05-26;
2017-05-26;"Bank Nextgen ";;-250.00;2017-05-26;
2017-05-26;"Tire Car Sales";;-95.85;2017-05-26;

Disclaimer:
Dies ist kein durch PostFinance AG erstelltes Dokument. PostFinance AG ist nicht verantwortlich für den Inhalt.

This is a kind of a CSV format, but then not really, so this is difficult to parse with a general parser. beans strives to have built-in support for as many file formats as possible. Currently, the following parsers are available:

  • us.interactivebrokers
  • ch.postfinance
  • ch.supercardplus
  • ch.cumulus
  • ch.swissquote

3.1.2 Importing data

If you are lucky enough that the format of your bank is supported, converting the bank account statement to transactions is a simple command:

beans import -i ch.postfinance -a Assets:Checking examples/postfinance.csv

import outputs a simple list of transactions to stdout, in a format parseable by beans and with unknown accounts marked as TBD. It is up to the user to pipe them into a journal or a temporary file for further editing.

2017-05-26 "Cleaning Service"
Assets:Checking -300 CHF
TBD 300 CHF

2017-05-26 "Supermarket Fine Foods"
Assets:Checking -115.2 CHF
TBD 115.2 CHF

2017-05-26 "Bank Nextgen "
Assets:Checking -250 CHF
TBD 250 CHF

2017-05-26 "Tire Car Sales"
Assets:Checking -95.85 CHF
TBD 95.85 CHF

2017-05-29 "Transfer 01-45-06 Bigbank"
Assets:Checking -1040 CHF
TBD 1040 CHF

2017-05-31 "FOOBAR COMMUNICATIONS"
Assets:Checking -52.6 CHF
TBD 52.6 CHF

2017-06-01 "Acme Corp"
Assets:Checking -135 CHF
TBD 135 CHF

3.1.3 Assigning accounts

Previous version of beans used to feature a DSL to specify rules, but this still involved too much thinking and writing.

beans now has a built-in Bayesien inference (a.k.a. machine learning) tool. Run beans infer to automatically replace TBD accounts in a target file based on the existing transactions in your ledger. Sounds magic, but works very well in practice. You need to get it started by assigning accounts manually for a few weeks.

3.2 Creating a journal

3.2.1 Journal files

Most commands in beans are based on a journal. beans journals uses a format largely similar to beancount, with the exception that beans neither requires nor allows indentation:

; -*- mode: Org; eval: (beancount-mode 1); -*-

option "operating_currency" "USD"

** Accounts

2018-01-01 open Equity:Valuation
2018-01-01 open Equity:Val
2018-01-01 open Equity:OpeningBalance
2018-01-01 open Income:Salary
2018-01-01 open Expenses:Rent
2018-01-01 open Expenses:Groceries
2018-01-01 open Expenses:Books
2018-01-01 open Equity:Gains

2018-01-01 open Assets:Checking
2018-01-01 open Assets:Portfolio
2018-01-01 open Assets:Wallet

** Some Transactions

*** Initial balances

2018-01-01 "Opening balance"
Assets:Checking 15000 USD
Equity:OpeningBalance


*** Checking account

2018-01-02 "Rent January"
Assets:Checking -2000 USD
Expenses:Rent

2018-01-10 "Food"
Assets:Checking -300 USD
Expenses:Groceries

2018-01-25 "Salary January"
Assets:Checking 4000 USD
Income:Salary

2018-02-01 "Rent February"
Assets:Checking -2000 USD
Expenses:Rent

2018-01-12 "Hungry again"
Assets:Checking -200 USD
Expenses:Groceries

2018-01-20 "Something to read"
Assets:Checking -100 USD
Expenses:Books


2018-02-25 "Salary February"
Assets:Checking 4000 USD
Income:Salary

2018-03-01 "Rent March"
Assets:Checking -2000 USD
Expenses:Rent

2018-03-02 "Yet more food"
Assets:Checking -200 USD
Expenses:Groceries

2018-03-20 "More food"
Assets:Checking -400 USD
Expenses:Groceries

2018-03-25 "Salary March"
Assets:Checking 4000 USD
Income:Salary

*** Investments

2018-01-10 "Investing in stock"
Assets:Portfolio +10 AAPL
Assets:Checking -1700 USD
Equity:Gains


** Prices

2018-01-01 price BTC 13412 USD
2018-02-01 price BTC 9052 USD
2018-03-01 price BTC 10907 USD
2018-04-01 price BTC 6816 USD
2018-05-01 price BTC 9067 USD
2018-06-01 price BTC 7518 USD
2018-07-01 price BTC 6347 USD
2018-08-01 price BTC 7603 USD
2018-09-01 price BTC 7192 USD
2018-10-01 price BTC 6578 USD
2018-11-01 price BTC 6358 USD

2018-01-01 price AAPL 169 USD
2018-02-01 price AAPL 167 USD
2018-03-01 price AAPL 175 USD
2018-04-01 price AAPL 166 USD
2018-05-01 price AAPL 169 USD
2018-06-01 price AAPL 190 USD
2018-07-01 price AAPL 185 USD
2018-08-01 price AAPL 201 USD
2018-09-01 price AAPL 227 USD
2018-10-01 price AAPL 225 USD
2018-11-01 price AAPL 222 USD

2018-01-14 "I want to be part of this!"
Assets:Wallet 0.25 BTC
Assets:Checking -3500 USD
Equity:Gains

I am using Emacs with org-mode to manage my journal in one large file (org-mode titles are treated as comments), however there is an include directive as well which allows for splitting a journal in different files.

3.2.2 Conventions

  • Accounts must be opened (and closed, if so desired) explicitly. They can be open for all commodities (default) or restricted to a list of them
  • Account names must start with "Assets", "Liabilities", "Equity", "Expenses" or "Income", depending on their type.
  • Transactions need not be ordered, beans automatically orders them by date.
  • Transactions with only one commodity can have a 'wildcard' booking, which is automatically assigned the total of the other bookings (this is the same as in other plain-text accounting tools)
  • Unlike beancount, beans uses the convention that balance directives refer to balances at the end of the given date. This is congruent with standard practices in the financial industry.

3.3 Balancing

3.3.1 Global balance

In addition to the predefined reports, beans has a generic balancing command:

beans balance -j examples/example.bean

This outputs a balance for all accounts without currency conversions, on the first and last day of the ledger

|------------------+------------+------------|
| Account          | 2018-01-01 | 2018-11-01 |
|------------------+------------+------------|
| Assets           |            |            |
|   Checking       |            |            |
|     USD          |   15000.00 |   14600.00 |
|   Portfolio      |            |            |
|     AAPL         |            |      10.00 |
|   Wallet         |            |            |
|     BTC          |            |       0.25 |
|------------------+------------+------------|
| Equity           |            |            |
|   Gains          |            |            |
|     AAPL         |            |     -10.00 |
|     BTC          |            |      -0.25 |
|     USD          |            |    5200.00 |
|   OpeningBalance |            |            |
|     USD          |  -15000.00 |  -15000.00 |
|------------------+------------+------------|
| Income           |            |            |
|   Salary         |            |            |
|     USD          |            |  -12000.00 |
|------------------+------------+------------|
| Expenses         |            |            |
|   Books          |            |            |
|     USD          |            |     100.00 |
|   Groceries      |            |            |
|     USD          |            |    1100.00 |
|   Rent           |            |            |
|     USD          |            |    6000.00 |
|------------------+------------+------------|
| Total            |            |            |
|   AAPL           |            |            |
|   BTC            |            |            |
|   USD            |            |            |
|------------------+------------+------------|

You want a multi-column balance?

beans balance -j examples/example.bean --interval quarterly
|------------------+------------+------------+------------+------------+------------|
| Account          | 2017-12-31 | 2018-03-31 | 2018-06-30 | 2018-09-30 | 2018-12-31 |
|------------------+------------+------------+------------+------------+------------|
| Assets           |            |            |            |            |            |
|   Checking       |            |            |            |            |            |
|     USD          |            |   14600.00 |   14600.00 |   14600.00 |   14600.00 |
|   Portfolio      |            |            |            |            |            |
|     AAPL         |            |      10.00 |      10.00 |      10.00 |      10.00 |
|   Wallet         |            |            |            |            |            |
|     BTC          |            |       0.25 |       0.25 |       0.25 |       0.25 |
|------------------+------------+------------+------------+------------+------------|
| Equity           |            |            |            |            |            |
|   Gains          |            |            |            |            |            |
|     AAPL         |            |     -10.00 |     -10.00 |     -10.00 |     -10.00 |
|     BTC          |            |      -0.25 |      -0.25 |      -0.25 |      -0.25 |
|     USD          |            |    5200.00 |    5200.00 |    5200.00 |    5200.00 |
|   OpeningBalance |            |            |            |            |            |
|     USD          |            |  -15000.00 |  -15000.00 |  -15000.00 |  -15000.00 |
|------------------+------------+------------+------------+------------+------------|
| Income           |            |            |            |            |            |
|   Salary         |            |            |            |            |            |
|     USD          |            |  -12000.00 |  -12000.00 |  -12000.00 |  -12000.00 |
|------------------+------------+------------+------------+------------+------------|
| Expenses         |            |            |            |            |            |
|   Books          |            |            |            |            |            |
|     USD          |            |     100.00 |     100.00 |     100.00 |     100.00 |
|   Groceries      |            |            |            |            |            |
|     USD          |            |    1100.00 |    1100.00 |    1100.00 |    1100.00 |
|   Rent           |            |            |            |            |            |
|     USD          |            |    6000.00 |    6000.00 |    6000.00 |    6000.00 |
|------------------+------------+------------+------------+------------+------------|
| Total            |            |            |            |            |            |
|   AAPL           |            |            |            |            |            |
|   BTC            |            |            |            |            |            |
|   USD            |            |            |            |            |            |
|------------------+------------+------------+------------+------------+------------|

3.3.2 Balancing options

  1. Flattening the account structure

    There are some formatting options available:

    beans balance -j examples/example.bean --format flat
    
    |-----------------------+------------+------------|
    | Account               | 2018-01-01 | 2018-11-01 |
    |-----------------------+------------+------------|
    | Assets:Checking       |            |            |
    |   USD                 |   15000.00 |   14600.00 |
    |-----------------------+------------+------------|
    | Assets:Portfolio      |            |            |
    |   AAPL                |            |      10.00 |
    |-----------------------+------------+------------|
    | Assets:Wallet         |            |            |
    |   BTC                 |            |       0.25 |
    |-----------------------+------------+------------|
    | Equity:Gains          |            |            |
    |   AAPL                |            |     -10.00 |
    |   BTC                 |            |      -0.25 |
    |   USD                 |            |    5200.00 |
    |-----------------------+------------+------------|
    | Equity:OpeningBalance |            |            |
    |   USD                 |  -15000.00 |  -15000.00 |
    |-----------------------+------------+------------|
    | Income:Salary         |            |            |
    |   USD                 |            |  -12000.00 |
    |-----------------------+------------+------------|
    | Expenses:Books        |            |            |
    |   USD                 |            |     100.00 |
    |-----------------------+------------+------------|
    | Expenses:Groceries    |            |            |
    |   USD                 |            |    1100.00 |
    |-----------------------+------------+------------|
    | Expenses:Rent         |            |            |
    |   USD                 |            |    6000.00 |
    |-----------------------+------------+------------|
    | Total                 |            |            |
    |   AAPL                |            |            |
    |   BTC                 |            |            |
    |   USD                 |            |            |
    |-----------------------+------------+------------|
    
    
  2. Valuation at market prices

    Valuation at market (i.e. latest available prices) is always an option:

    beans balance -j examples/example.bean --val USD
    
    |------------------+------------+------------|
    | Account          | 2018-01-01 | 2018-11-01 |
    |------------------+------------+------------|
    | Assets           |            |            |
    |   Checking       |   15000.00 |   14600.00 |
    |   Portfolio      |            |    2220.00 |
    |   Wallet         |            |    1589.50 |
    |------------------+------------+------------|
    | Equity           |            |            |
    |   Equity         |            |    1233.50 |
    |   Gains          |            |     157.00 |
    |   OpeningBalance |  -15000.00 |  -15000.00 |
    |------------------+------------+------------|
    | Income           |            |            |
    |   Salary         |            |  -12000.00 |
    |------------------+------------+------------|
    | Expenses         |            |            |
    |   Books          |            |     100.00 |
    |   Groceries      |            |    1100.00 |
    |   Rent           |            |    6000.00 |
    |------------------+------------+------------|
    | Total            |            |            |
    |------------------+------------+------------|
    
    
  3. Restricting dates and periods

    We can also analyze changes in the balance between specific dates:

    beans balance -j examples/example.bean --val USD --from 2018-06-30 --to 2018-10-30
    
    |------------------+------------+------------|
    | Account          | 2018-06-30 | 2018-10-30 |
    |------------------+------------+------------|
    | Assets           |            |            |
    |   Checking       |   14600.00 |   14600.00 |
    |   Portfolio      |    1900.00 |    2250.00 |
    |   Wallet         |    1879.50 |    1644.50 |
    |------------------+------------+------------|
    | Equity           |            |            |
    |   Equity         |    1263.50 |    1148.50 |
    |   Gains          |     157.00 |     157.00 |
    |   OpeningBalance |  -15000.00 |  -15000.00 |
    |------------------+------------+------------|
    | Income           |            |            |
    |   Salary         |  -12000.00 |  -12000.00 |
    |------------------+------------+------------|
    | Expenses         |            |            |
    |   Books          |     100.00 |     100.00 |
    |   Groceries      |    1100.00 |    1100.00 |
    |   Rent           |    6000.00 |    6000.00 |
    |------------------+------------+------------|
    | Total            |            |            |
    |------------------+------------+------------|
    
    
  4. Analyzing changes in valuation

    Using filtering, we can eliminate the effect of income and expenses and track valuation changes over the entire period:

    beans balance -j examples/example.bean --account-filter Equity --val USD
    
    |------------------+------------+------------|
    | Account          | 2018-01-01 | 2018-11-01 |
    |------------------+------------+------------|
    | Assets           |            |            |
    |   Checking       |   15000.00 |    9800.00 |
    |   Portfolio      |            |    2220.00 |
    |   Wallet         |            |    1589.50 |
    |------------------+------------+------------|
    | Equity           |            |            |
    |   Equity         |            |    1233.50 |
    |   Gains          |            |     157.00 |
    |   OpeningBalance |  -15000.00 |  -15000.00 |
    |------------------+------------+------------|
    | Total            |            |            |
    |------------------+------------+------------|
    
    

    How about bitcoin?

    beans balance -j examples/example.bean --val BTC
    
    |------------------+------------+------------|
    | Account          | 2018-01-01 | 2018-11-01 |
    |------------------+------------+------------|
    | Assets           |            |            |
    |   Checking       |       1.12 |       2.30 |
    |   Portfolio      |            |       0.35 |
    |   Wallet         |            |       0.25 |
    |------------------+------------+------------|
    | Equity           |            |            |
    |   Equity         |            |      -1.34 |
    |   Gains          |            |       0.01 |
    |   OpeningBalance |      -1.12 |      -1.12 |
    |------------------+------------+------------|
    | Income           |            |            |
    |   Salary         |            |      -1.11 |
    |------------------+------------+------------|
    | Expenses         |            |            |
    |   Books          |            |       0.01 |
    |   Groceries      |            |       0.09 |
    |   Rent           |            |       0.55 |
    |------------------+------------+------------|
    | Total            |       0.00 |       0.00 |
    |------------------+------------+------------|
    
    

    beans derives arbitrary commodity conversions between all commodities, as long as there is at least one path (possibly over several links) from one commodity to another. For example, conversion from SomeStock in CHF is possible when prices of SomeStock in USD and CHF in USD is available. Inverted rates are derived automatically.

    At the moment, beans offers either no valuation or valuation at market prices. Valuation at cost is yet to be implemented.

3.4 Transaction-level valuation

beans applies valuation at the level of transactions, which seems unique amongst plain-text accounting tools. In the examples above, if a conversion to a common commodity is desired, beans will:

  • convert all bookings over the entire ledger to that commodity at market value (given by the transitive & reflexive closure of price directives at the transaction date),
  • insert valuation bookings for the accumulated positions of all asset and liability accounts whenever prices change. These adjustment are balanced against an Equity:Valuation account, which is hard-coded for the moment.

Every difference in value of an account over a period is explicitly modeled by corresponding valuation transactions. This greatly facilitates introspection and analysis, as every unit of the valuation commodity can be accounted for explicitly.

4 Developing beans

Development is very much in progress and beans is not really stable yet. It seems though that the basic pipeline (importing - categorizing - balancing) is there, and I am using it to balance my own journal. beans development is at the moment entirely driven by my own needs. It has also been a playground for experiments and lots of refactoring for fun with Haskell.

Use beans at your own risk - at the moment, it is certainly advantageous if you know some Haskell.

4.1 Roadmap

beans still has long way to go. I do this in my spare time and I do not have an explicit road map, but here are some ideas I'd like to be working on in the future:

4.1.1 Shorter term

  • [X] new command to print and filter transactions (as-is or at market value)
  • [ ] provide a more realistic example file
  • [X] multi-period reports (yearly, monthly, weekly, daily, …)
  • [ ] colored output
  • [ ] friendlier command line
  • [ ] more importers (I'll do those that I need personally, but I am happy to receive contributions if they are provided with a sample file / test)
  • [X] export to other tools (beancount / hledger / ledger)

4.1.2 Longer term

  • [ ] general reporting infrastructure
  • [ ] more reports (income statement, cash flow statement)
  • [ ] plotting / graphs
  • [ ] portfolio performance calculation
  • [ ] more UI options (web, terminal)

4.2 Documentation

This manual aims to provide a comprehensive overview of its functionality. It is written in org-mode, please file a pull request against this file if you want to contribute.

4.3 Dev setup

4.3.1 nix / Haskell IDE engine

I am using Emacs and ghcide under Nixos. To setup your development environment and install all dependencies, simply run

nix-shell

if you have the nix package manager installed.

4.3.2 Stack

It should be possible to develop beans with stack. Please file a bug report / pull request if you discover anything that does not work as expected.

4.4 Adding an importer

beans is open to contributions, see the example here how an importer can be implemented. The directory should match the country of the bank. Make a pull request if you want to have it included in beans (preferrably with a test case and an anonymized sample file).

It is still an open question whether importers should be included in the beans repository or whether a more modular system should be adopted. I am open to suggestion.

4.5 Tests

Every importer should have a test and an example file. This being said, test coverage is currently lacking for the existing importers.

5 License

beans is licensed under the BSD-3 license.

Author: Silvio Böhler

Created: 2020-06-04 Do 22:13

Validate