Skip to content
Another Ledger to Beancount converter
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



Another ledger-to-beancount converter.

N.B. Maintenance on this project is likely to be minimal. If this
program doesn't support some ledger syntax that you use, consider using instead.

plaintextaccounting contains a link to a Github gist called It's not bad for what it does, but what it does is kind of incomplete. It works by asking ledger for transactions, and then formats the transactions. This means it doesn't include anything that isn't a transaction, namely a comment or a balance assertion. In my ledger use, these are both quite important, and I don't want to lose them or have to copy them over by hand.

To address these concerns, we take a very different approach. Rather than introspect on parsed ledger data, we examine a "raw" file and do a crude syntactic translation from Ledger syntax to Beancount syntax. This means we have to do some extra work to parse everything, as well as handling aliases ourselves, but gives us access to everything in the original Ledger file.


$ pip install git+

Run with:

$ ledger-to-beancount <ledger file>


Run with py.test.


Given a .ledger file like this:

2010-02-04 Purchasing new shoes
    Expenses:Clothing       $100
    Liabilities:Credit Card

2010-02-05 ! Buying dinner at a Thai place
    Liabilities:Credit Card  $40
    Assets:Cash             $10   ; for the tip

2010/2/6 Investing
    Assets:Investment     10 DJIA @ $13.01

2010-02-08 Reaping the gains
    Assets:Investment    -10 DJIA @ $14.01

2010-02-10 Balance assertion
    Assets:Investment   = $1000

The converter outputs:

* Accounts
2010-01-01 open Assets:Cash
2010-01-01 open Assets:Investment
2010-01-01 open Expenses:Clothing
2010-01-01 open Expenses:Restaurant
2010-01-01 open Liabilities:CreditCard
* Transactions
2010-02-04 * "Purchasing new shoes"
  Expenses:Clothing        100 USD

2010-02-05 ! "Buying dinner at a Thai place"
  Liabilities:CreditCard      40 USD
  Assets:Cash        10 USD   ; for the tip

2010-02-06 * "Investing"
  Assets:Investment        10 DJIA {13.01 USD}

2010-02-08 * "Reaping the gains"
  Assets:Investment        -10 DJIA @ 14.01 USD

2010-02-10 balance Assets:Investment   1000 USD

In other words:

  • Dates are converted automatically to ISO8601 format.
  • Currency is automatically converted.
  • Transactions are converted to beancount format, i.e. with payees quoted (and escaped if necessary).
  • Flags are preserved, but since every transaction has to have a flag, we default to the "*" flag for any unflagged transactions.
  • Comments are preserved, even in tricky cases like at the end of a posting.
  • Spacing is made uniform. (Two spaces for postings, eight spaces between an account and its amount, and three spaces after the account in a balance assertion.)
    • FIXME: It would be really neat to align monetary amounts in postings!
  • Balance assertions are converted to beancount format. Note that the semantics of balance assertions in Ledger and Beancount are subtly different -- in Ledger, an assertion applies to any transaction that came earlier in the file, but in Beancount it applies to transactions up to but not including that day. You may have to adjust your balance assertions manually.
  • Purchases, but not sales, of all assets are converted to cost bases.
    • FIXME: This may not be correct if you do a lot of foreign currency exchange.
    • This may cause bean-check to complain on sales, since the cost bases are missing. Unfortunately, we have no way to generate this information. Consider the errors to be a helpful way to locate transactions :)
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.