Value expression ("define" expressions) from ledger3 to beancount

82 views
Skip to first unread message

Stefano Merlo

unread,
Feb 12, 2026, 10:15:04 AMFeb 12
to Beancount
Hello,
    is there anything (plugin, importer, converter) that can read a ledger file containing user-defined expressions, and convert into values to be ingested in beancount?

Reason/background: I am a long time beancount user and I have about 10 years of data in double-entry text format. In December, I migrated the beancount format to ledger format to leverage the emacs-mode integration and the plain-text reporting capabilities. 

While I achieved some goals (e.g. better integration with my workflows in ingesting and processing documents), I struggle to conduct exploratory analysis on my data. As example, I harmonized my chart of accounts to a structure that allows a comparison with official data from the national statistics, but I need some charting capabilities to view trends and relative shares. I tried running reports in ledger and piping to gnuplot: results are OK-ish but I lack interactivity. Tools like Fava, Fava dashboard and Beangrow gave me immediate answers to my needs.

My latest rabbit hole was trying to integrate depreciation of my car: in ledger I am forced to write a transaction for each period, as the automatic transactions does not work for this case. However, a transaction per year is not enough: I have an outlier month, and 11 months not including the depreciation, screwing up the stats by month and the integration with seasonality of other expenses. In Beancount, I had my python custom script that ran at runtime (and there are plugins out there too) and where I can change parameters like depreciation methods very quickly.

On the other side, the ability of user-defined in ledger is very helpful in some cases: as example, I have a defined function that calculates the different taxes (capital gains, other taxes) automatically for dividends, verifying expected figures with bank statements.

Example (note that I use aliases, so expenses/income prefixes are missing from the screenshot):

define round_cents(val) = (floor((val * 100) + €0.5) / 100)

;; taxable_quote_of_equity
define tqeq(gross) = (round_cents(gross * 0.70))
;; taxable_quote_of_fixed_income
define tqfi(gross) = (round_cents(gross * 1.00))

;; equity_capital_gain_tax
define eqcgtax(taxable) = (round_cents(taxable) * 0.25)
;; fixed_income_capital_gain_tax
define ficgtax(taxable) = (round_cents(taxable) * 0.25)

;; equity_solid_tax
define eqstax(taxable) = (round_cents(eqcgtax(taxable) * 0.055))
;; fixed_income_solid_tax
define fistax(taxable) = (round_cents(ficgtax(taxable) * 0.055))


2021-02-05 XEIN Advanced lump sum tax on capital gain
    ; isin: LU0290358224
    ; type: yield
    ; commodity: XEIN
    (assets:taxes:accumulated-advance-tax-gross:XEIN)             €64.86
    used-tax-free-allowance                                       €27.34
    assets-annual-tax-free-allowance                             €-27.34  = €0
    taxes:capitalgain:XEIN                (ficgtax(tqfi(€64.86) - €27.34))
    taxes:solidtax:XEIN                    (fistax(tqfi(€64.86) - €27.34) - €0.01)
    * bank                                                        €-9.89



My plan is to try to stay in ledger format, for the integration in my workflows, but have the possibility to convert it on the spot to beancount and launch fava if needed. I tried ledger2beancount but it does not support inline math.

Any help, comment, critic, suggestion would be appreciated.

--Stefano

Simon Michael

unread,
Feb 17, 2026, 4:08:37 AMFeb 17
to bean...@googlegroups.com
On 2026-02-12 05:15, Stefano Merlo wrote:
> Hello,
>     is there anything (plugin, importer, converter) that can read a
> ledger file containing user-defined expressions, and convert into values
> to be ingested in beancount?
...
> My plan is to try to stay in ledger format, for the integration in my
> workflows, but have the possibility to convert it on the spot to
> beancount and launch fava if needed. I tried ledger2beancount but it
> does not support inline math.

Hi Stefano,

The only thing that will evaluate those expressions reliably is Ledger.
So first you need to persuade ledger print to print the final calculated
amounts. Hopefully that's possible, if not I recommend to open an issue
or PR, as it would be valuable.

After that, pipe the output to hledger -If- print -o foo.beancount.
hledger is good at converting h/ledger journals to beancount these days.

Best

Martin Michlmayr

unread,
Feb 22, 2026, 8:24:20 AM (13 days ago) Feb 22
to bean...@googlegroups.com
* Stefano Merlo <trepr...@gmail.com> [2026-02-12 07:15]:
> I tried ledger2beancount but it does not support inline math.

Maybe a nitpicky correction but it supports simple inline math.

I don't see how complex expressions like yours could be supported
as they are not supported in beancount. If there's anything
ledger2beancount could do to make this easier, I'm open for
suggestions but I don't see how.

--
Martin Michlmayr
https://www.cyrius.com/

Stefano Merlo

unread,
Feb 26, 2026, 6:24:23 AM (9 days ago) Feb 26
to Beancount
Thanks community.

Sorry I wasn't clear, I agree beancount supports inline math, I was refering to the missing support of the complex 'define' expressions by ledger2beancount. I do not think that it makes sense to support them by design in ledger2beancount when the ledger 'print' command is not converting them (by design I believe, as printing is different than reporting) and beancount also is not supporting them, again I believe by design being beancount very good in extendability by python scripts. I converted all of them in hardcoded values: they were merely 'nice to have', nothing that could not be replaced by some notes in the transaction.

I also use virtual postings in ledger, to separate two different charts of accounts: one aligned with my personal expense structure, that I recently aligned with the national statistics for benchmarking, and one that allows me to produce the tax statement in Germany using the EÜR numbers. As virtual postings are not supported in beancount, these cannot be reported using fava, but this should not be a problem as for this reporting ledger report is robust enough.

Example (again using aliases) where I split the landline between home usage and professional usage (allowed up to 20% in Germany), allocating an extra virtual amount to the parallel chart of account used in the EÜR declaration:

2025-01-24 * 1&1 Telecom GmbH
    home-landline                   (€37.98 * 0.8)
    Expenses:Business:Landline      (€37.98 * 0.2)
    (EÜR-Pos:280)                   (€37.98 * 0.2)
    bank                            €-37.98

I am now testing this hybrid workflow of using ledger for bookkeeping and fava for analysis, bridged by ledger2beancount: I must say that it seems complex but that might be attenuated by some hooks and automation. I will post feedbacks here if this is something sustainable.

--Stefano
Reply all
Reply to author
Forward
0 new messages