Beancount getting started

Webgui looks awesome ( https://beancount.github.io/fava/ )
Demo: https://fava.pythonanywhere.com/example-with-budgets/income_statement/

I also found another ledger/beancount tool, but this one has a postfinance and interactive brokers parser: https://github.com/sboehler/beans

I found some importer for beancount:

DKB

ING-DiBa

Commerzbank

N26

I’m using beancount for a while and I’m really happy!!
I started with imports, etc
and finished doing passing all to CSV, from there to Numbers or Excel and
 adding unique identifiers after each field to copy and paste everything to a power text editor, kind of Visual Code where I format in beancount format.

It’s long and I don’t have time to explain the complete method but is something like that: You have:

10.10.2019. “Buy in COOP” 123 CHF

I put. In excel columns like:

10.10.2019 * ###_### “Buy in COOP” —- Expenses:Groceries 123 CHF

Copy and paste to Visual Code and find all the “special” fields to make a global “enter” and spaces
etc
 you edit a line but you are editing the thousand of lines that have your file
 I don’t know if is clear.

Takes time, I know, but is much more quicker than finding an importer :wink:

You can use this https://sboehler.github.io/beans/ , it provides parsing for:

us.interactivebrokers ( Interactive Brokers )
ch.postfinance ( Postfinance )
ch.supercardplus ( Supercard Plus )

"The importing functionality of beans can of course also be used if you use another plain-text accounting tool. beancount’s syntax is largely compatible with beans. "

4 Likes

Do we have a beancount expert or python coder here?
I’m new to beancount and need an importer for revolut and cashback creditcards.
Some example files:
https://www.dropbox.com/sh/yrpjw2tvmo8uszk/AAB00B6XAoe2UGWeMOGiGCGwa?dl=0

I pay you a beer or coffee :wink:

@nugget
I posted a parser for postfinance ( https://sboehler.github.io/beans/ ) , works perfect with beancount :slight_smile:


19

With the csv you can parse it and use it with beancount.
You can edit the “examples.rules” for the matching:


description =~ “Mintos Marketplace” -> Assets:DE:Mintos:Investments
description =~ “Wohnungsmiete.*” -> Expenses:Home:Rent


And parse your csv file with beans:
./beans import -i ch.postfinance -c example.rules -a Assets:CH:Postfinance:Shared postfinance20191102.csv >> myfile.beans

1 Like

ahahah i never scrolled down that page to realize the export-button. thanks for pointing out!

thanks for posting the command too, i’m quit new to unix and it always takes ages to figure out the next command :smiley:

1 Like


 anyone looked at beancount.io and furious.ca? seems to me the author removes some content and moves towards a paid solution. what u think?

I’m not even sure it’s from the same author:

Beancount.io is not affiliated with beancount · GitHub but uses Fava under MIT license

The source code is still available from the bitbucket repo but the doc on furius.ca seems to be gone, weird.

yes exactly, i find alot of dead links recently

Anyone got the

beancount.price

stock quote fetching running?

[edit] yes! yahoo works, now working on google:

bean-price -e USD:yahoo/VTI
2019-11-19 price VTI 158.73 USD
bean-price -e USD:google/NYSEARCA:VTI
ERROR : Could not fetch for job: DatedPrice(base=‘NYSEARCA:VTI’, quote=‘USD’, date=None, sources=[PriceSource(module=<module ‘google’ (namespace)>, symbol=‘NYSEARCA:VTI’, invert=False)])

I always put both Google and yahoo, I’m not sure if Google is still working.

could you share your explicit line of code? thanks :slight_smile:

Google API is not maintained/available for a while

Yahoo or Alphavantage are your best alternatives.
I’ve been using Yahoo with Beancount for months without any problem.

Some other ideas:

An advice for people starting with beancount:

  • Install VS Code, is a free ASCII editor available in all the platforms. Is very well done.
  • Install a extension named: VSCode-Beancount and follow the instructions about how to organise the files!!!

https://marketplace.visualstudio.com/items?itemName=Lencerf.beancount

You’ll love beancount after that :wink:

Tino.

I think I got exactly to this solution - by some chance :joy::joy:
no idea on how cruel it is if I started doing stuff with nano (i am new to ubuntu
) :smiley:

thanks for mentioning :smiley:

I got help from the beancounts maillinglist for revolut import.

The code for the importer:

from dateutil.parser import parse
from io import StringIO
from beancount.ingest import importer
from beancount.core import data
from beancount.core import amount
from beancount.core.number import D
from beancount.ingest.importers.mixins import identifier
import csv

  class Importer(identifier.IdentifyMixin,
  importer.ImporterProtocol):
      """An importer for Revolut CSV files."""
  
      def __init__(self, regexps, account, currency):
          identifier.IdentifyMixin.__init__(self, matchers=[
              ('filename', regexps)
          ])
          self.account = account
          self.currency = currency
  
      def name(self):
          return super().name() + self.account
  
      def file_account(self, file):
          return self.account
  
      def extract(self, file, existing_entries):
          entries = []
  
          with StringIO(file.contents()) as csvfile:
              reader = csv.DictReader(csvfile, ['Date',
  'Reference','PaidOut', 'PaidIn', 'ExchangeOut', 'ExchangeIn',
  'Balance', 'Category', 'Notes'], delimiter=';',
  skipinitialspace=True)
              next(reader)
              for row in reader:
                  metakv = {
                      'category': row['Category'].strip(),
                  }
                  exchangeIn = row['ExchangeIn'].strip()
                  exchangeOut = row['ExchangeOut'].strip()
                  if exchangeIn and exchangeOut:
                      metakv['originalIn'] = exchangeIn
                      metakv['originalOut'] = exchangeOut
                  elif exchangeIn:
                      metakv['original'] = exchangeIn
                  elif exchangeOut:
                      metakv['original'] = exchangeOut
  
                  meta = data.new_metadata(file.name, 0, metakv)
                  entry = data.Transaction(
                      meta,
                      parse(row['Date'].strip()).date(),
                      '*',
                      '',
                      (row['Reference'].strip() + ' ' +
  row['Notes'].strip()).strip(),
                      data.EMPTY_SET,
                      data.EMPTY_SET,
                      [
                          data.Posting(self.account,
  amount.Amount(D(row['PaidIn'].strip()) -
  D(row['PaidOut'].strip()), self.currency), None, None, None,
  None),
                      ]
                  )
                  entries.append(entry)
          return entries`

config.py:

`from dateutil.parser import parse
from io import StringIO
from beancount.ingest import importer
from beancount.core import data
from beancount.core import amount
from beancount.core.number import D
from beancount.ingest.importers.mixins import identifier
import csv

  class Importer(identifier.IdentifyMixin,
  importer.ImporterProtocol):
      """An importer for Revolut CSV files."""
  
      def __init__(self, regexps, account, currency):
          identifier.IdentifyMixin.__init__(self, matchers=[
              ('filename', regexps)
          ])
          self.account = account
          self.currency = currency
  
      def name(self):
          return super().name() + self.account
  
      def file_account(self, file):
          return self.account
  
      def extract(self, file, existing_entries):
          entries = []
  
          with StringIO(file.contents()) as csvfile:
              reader = csv.DictReader(csvfile, ['Date',
  'Reference','PaidOut', 'PaidIn', 'ExchangeOut', 'ExchangeIn',
  'Balance', 'Category', 'Notes'], delimiter=';',
  skipinitialspace=True)
              next(reader)
              for row in reader:
                  metakv = {
                      'category': row['Category'].strip(),
                  }
                  exchangeIn = row['ExchangeIn'].strip()
                  exchangeOut = row['ExchangeOut'].strip()
                  if exchangeIn and exchangeOut:
                      metakv['originalIn'] = exchangeIn
                      metakv['originalOut'] = exchangeOut
                  elif exchangeIn:
                      metakv['original'] = exchangeIn
                  elif exchangeOut:
                      metakv['original'] = exchangeOut
  
                  meta = data.new_metadata(file.name, 0, metakv)
                  entry = data.Transaction(
                      meta,
                      parse(row['Date'].strip()).date(),
                      '*',
                      '',
                      (row['Reference'].strip() + ' ' +
  row['Notes'].strip()).strip(),
                      data.EMPTY_SET,
                      data.EMPTY_SET,
                      [
                          data.Posting(self.account,
  amount.Amount(D(row['PaidIn'].strip()) -
  D(row['PaidOut'].strip()), self.currency), None, None, None,
  None),
                      ]
                  )
                  entries.append(entry)
          return entries`

Run with command:
bean-extract config.py Revolut-CHF.myname.csv

2 Likes

Hi!

I know my way well around Linux but use a Windows PC for personal stuff. Have some VMs with Linux though where, among other things, I run Python scripts to update Gnucash’s stock prices database.

I’m looking into transitioning to beancount. My main goal is to be able to edit the bean files easily from my Windows PCs. I’m guessing that’s not a problem per se.

But I also don’t want to waste time setting stuff up. Now that you all seem to have gotten the gist of things and knowing that I know absolutely nothing about beancount, how would you recomend I start? Docker images on Windows? Any tutorial?

I can also spin up a VM just for this, but seems inconvenient. If you find it easier, please let me know as well.

Thanks, guys!

If you’re familiar with docker, that’s the way I would go. Otherwise maybe the easiest way for s to use wsl.

My seutp is, and i am mosly very happy:

  • WSL Ubuntu 18.04, with a win10 host
  • VScode for text editing & transaction checking. awesome beancount plugin available!
  • miniconda for python encapsulation
  • private github repo for version control & backup
  • git-crypt to encrypt that repo before pushing (once set up it disappears from the typical git workflow)
  • beancount, smart-importer, tariochbctools for revolut importer, fava
  • lots of time to get started, but very satisfied in the end

in the beginning i also tried docker, but it was too much of new stuff at the time. you can read up about it further up in the thread :grin: among others I had the problem of accessing the localhost fava webapp through the docker container shell.

unfortuanately a good tutorial for getting started is not available to my knowledge. there is a section in the documentation, but the author and all the beancount community suffer heavily from the Curse of knowledge

some sources I used:

Beancount - Syntax Cheat Sheet - Google Docs
Beancount - Index - Google Docs
Beancount Google Groups
Awesome Beancount | awesome-beancount
Command-line Accounting in Context — Beancount 2.0b3 documentation
Alex Johnstone - Managing my personal finances with beancount
Vince Cima
Docker Container on Windows host system: how to access mapped ports? - Docker Desktop for Windows - Docker Forums
Browsable & searchable Documentation for Beancount — Beancount 2.0b3 documentation
beancount-import/ofx.py at master · jbms/beancount-import

my tutorial would be: start as simple as possible (bare beancount & fava) and add your taste as you go. don’t try to do everything at once. Read the google doc documentation, but don’t be disappointed if it doesnt help very much when you look for something specific.

In the end I made it and I don’t think in a glorious way xD so any IT-person should be able to do so too. And with me there is one more person willing to answer question :slight_smile:

1 Like