Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


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 :)


Another Ledger to Beancount converter






No releases published


No packages published