hledger-1.20.3: Hledger/Cli/Commands/Balance.txt
balance, bal, b
Show accounts and their balances.
_FLAGS
The balance command is hledger's most versatile command. Note, despite
the name, it is not always used for showing real-world account balances;
the more accounting-aware balancesheet and incomestatement may be more
convenient for that.
By default, it displays all accounts, and each account's change in
balance during the entire period of the journal. Balance changes are
calculated by adding up the postings in each account. You can limit the
postings matched, by a query, to see fewer accounts, changes over a
different time period, changes from only cleared transactions, etc.
If you include an account's complete history of postings in the report,
the balance change is equivalent to the account's current ending
balance. For a real-world account, typically you won't have all
transactions in the journal; instead you'll have all transactions after
a certain date, and an "opening balances" transaction setting the
correct starting balance on that date. Then the balance command will
show real-world account balances. In some cases the -H/--historical flag
is used to ensure this (more below).
This command also supports the output destination and output format
options The output formats supported are (in most modes): txt, csv,
html, and json.
The balance command can produce several styles of report:
Single-period flat balance report
This is the default for hledger's balance command: a flat list of all
(or with a query, matched) accounts, showing full account names.
Accounts are sorted by declaration order if any, and then by account
name. Accounts which have zero balance are not shown unless -E/--empty
is used. The reported balances' total is shown as the last line, unless
disabled by -N/--no-total.
$ hledger bal
$1 assets:bank:saving
$-2 assets:cash
$1 expenses:food
$1 expenses:supplies
$-1 income:gifts
$-1 income:salary
$1 liabilities:debts
--------------------
0
Single-period tree-mode balance report
With the -t/--tree flag, accounts are displayed hierarchically, showing
subaccounts as short names indented below their parent. (This is the
default style in Ledger and in older hledger versions.)
$ hledger balance
$-1 assets
$1 bank:saving
$-2 cash
$2 expenses
$1 food
$1 supplies
$-2 income
$-1 gifts
$-1 salary
$1 liabilities:debts
--------------------
0
For more compact output, "boring" accounts containing a single
interesting subaccount and no balance of their own (assets:bank and
liabilities here) are elided into the following line, unless --no-elide
is used. And accounts which have zero balance and no non-zero
subaccounts are omitted, unless -E/--empty is used.
Account balances in tree mode are "inclusive" - they include the
balances of any subaccounts. Eg, the assets $-1 balance here includes
the $1 from assets:bank:saving and the $-2 from assets:cash. (And it
would include balance posted to the assets account itself, if there was
any). Note this causes some repetition, and the final total (0) is the
sum of the top-level balances, not of all the balances shown.
Each group of sibling accounts is sorted separately, by declaration
order and then by account name.
Multi-period balance report
Multi-period balance reports are a very useful hledger feature,
activated if you provide one of the reporting interval flags, such as
-M/--monthly. They are similar to single-period balance reports, but
they show the report as a table, with columns representing one or more
successive time periods. This is the usually the preferred style of
balance report in hledger (even for a single period).
Multi-period balance reports come in several types, showing different
information:
1. A balance change report: by default, each column shows the sum of
postings in that period, ie the account's change of balance in that
period. This is useful eg for a monthly income statement:
$ hledger balance --quarterly income expenses -E
Balance changes in 2008:
|| 2008q1 2008q2 2008q3 2008q4
===================++=================================
expenses:food || 0 $1 0 0
expenses:supplies || 0 $1 0 0
income:gifts || 0 $-1 0 0
income:salary || $-1 0 0 0
-------------------++---------------------------------
|| $-1 $1 0 0
2. A cumulative end balance report: with --cumulative, each column
shows the end balance for that period, accumulating the changes
across periods, starting from 0 at the report start date:
$ hledger balance --quarterly income expenses -E --cumulative
Ending balances (cumulative) in 2008:
|| 2008/03/31 2008/06/30 2008/09/30 2008/12/31
===================++=================================================
expenses:food || 0 $1 $1 $1
expenses:supplies || 0 $1 $1 $1
income:gifts || 0 $-1 $-1 $-1
income:salary || $-1 $-1 $-1 $-1
-------------------++-------------------------------------------------
|| $-1 0 0 0
3. A historical end balance report: with --historical/-H, each column
shows the actual historical end balance for that period,
accumulating the changes across periods, and including the balance
from any postings before the report start date. This is useful eg
for a multi-period balance sheet, and when you want to see balances
only after a certain date:
$ hledger balance ^assets ^liabilities --quarterly --historical --begin 2008/4/1
Ending balances (historical) in 2008/04/01-2008/12/31:
|| 2008/06/30 2008/09/30 2008/12/31
======================++=====================================
assets:bank:checking || $1 $1 0
assets:bank:saving || $1 $1 $1
assets:cash || $-2 $-2 $-2
liabilities:debts || 0 0 $1
----------------------++-------------------------------------
|| 0 0 0
Note that --cumulative or --historical/-H disable --row-total/-T, since
summing end balances generally does not make sense.
With a reporting interval (like --quarterly above), the report start/end
dates will be adjusted if necessary so that they encompass the displayed
report periods. This is so that the first and last periods will be
"full" and comparable to the others.
The -E/--empty flag does two things in multicolumn balance reports:
first, the report will show all columns within the specified report
period (without -E, leading and trailing columns with all zeroes are not
shown). Second, all accounts which existed at the report start date will
be considered, not just the ones with activity during the report period
(use -E to include low-activity accounts which would otherwise would be
omitted).
The -T/--row-total flag adds an additional column showing the total for
each row.
The -A/--average flag adds a column showing the average value in each
row.
Here's an example of all three:
$ hledger balance -Q income expenses --tree -ETA
Balance changes in 2008:
|| 2008q1 2008q2 2008q3 2008q4 Total Average
============++===================================================
expenses || 0 $2 0 0 $2 $1
food || 0 $1 0 0 $1 0
supplies || 0 $1 0 0 $1 0
income || $-1 $-1 0 0 $-2 $-1
gifts || 0 $-1 0 0 $-1 0
salary || $-1 0 0 0 $-1 0
------------++---------------------------------------------------
|| $-1 $1 0 0 0 0
(Average is rounded to the dollar here since all journal amounts are)
The --transpose flag can be used to exchange the rows and columns of a
multicolumn report.
When showing multicommodity amounts, multicolumn balance reports will
elide any amounts which have more than two commodities, since otherwise
columns could get very wide. The --no-elide flag disables this. Hiding
totals with the -N/--no-total flag can also help reduce the width of
multicommodity reports.
When the report is still too wide, a good workaround is to pipe it into
less -RS (-R for colour, -S to chop long lines). Eg:
hledger bal -D --color=yes | less -RS.
Depth limiting
With a depth:N query, or --depth N option, or just -N, balance reports
will show accounts only to the specified depth. This is very useful to
hide low-level accounts and get an overview. Eg, limiting to depth 1
shows the top-level accounts:
$ hledger balance -N -1
$-1 assets
$2 expenses
$-2 income
$1 liabilities
Accounts at the depth limit will include the balances of any hidden
subaccounts (even in flat mode, which normally shows exclusive
balances).
You can also drop account name components from the start of account
names, using --drop N. This can be useful to hide unwanted top-level
detail.
Colour support
In terminal output, when colour is enabled, the balance command shows
negative amounts in red.
Sorting by amount
With -S/--sort-amount, accounts with the largest (most positive)
balances are shown first. For example, hledger bal expenses -MAS shows
your biggest averaged monthly expenses first.
Revenues and liability balances are typically negative, however, so -S
shows these in reverse order. To work around this, you can add --invert
to flip the signs. Or, use one of the sign-flipping reports like
balancesheet or incomestatement, which also support -S. Eg:
hledger is -MAS.
Percentages
With -% or --percent, balance reports show each account's value
expressed as a percentage of the column's total. This is useful to get
an overview of the relative sizes of account balances. For example to
obtain an overview of expenses:
$ hledger balance expenses -%
100.0 % expenses
50.0 % food
50.0 % supplies
--------------------
100.0 %
Note that --tree does not have an effect on -%. The percentages are
always relative to the total sum of each column, they are never relative
to the parent account.
Since the percentages are relative to the columns sum, it is usually not
useful to calculate percentages if the signs of the amounts are mixed.
Although the results are technically correct, they are most likely
useless. Especially in a balance report that sums up to zero (eg
hledger balance -B) all percentage values will be zero.
This flag does not work if the report contains any mixed commodity
accounts. If there are mixed commodity accounts in the report be sure to
use -V or -B to coerce the report into using a single commodity.
Customising single-period balance reports
You can customise the layout of single-period balance reports with
--format FMT, which sets the format of each line. Eg:
$ hledger balance --format "%20(account) %12(total)"
assets $-1
bank:saving $1
cash $-2
expenses $2
food $1
supplies $1
income $-2
gifts $-1
salary $-1
liabilities:debts $1
---------------------------------
0
The FMT format string (plus a newline) specifies the formatting applied
to each account/balance pair. It may contain any suitable text, with
data fields interpolated like so:
%[MIN][.MAX](FIELDNAME)
- MIN pads with spaces to at least this width (optional)
- MAX truncates at this width (optional)
- FIELDNAME must be enclosed in parentheses, and can be one of:
- depth_spacer - a number of spaces equal to the account's depth,
or if MIN is specified, MIN * depth spaces.
- account - the account's name
- total - the account's balance/posted total, right justified
Also, FMT can begin with an optional prefix to control how
multi-commodity amounts are rendered:
- %_ - render on multiple lines, bottom-aligned (the default)
- %^ - render on multiple lines, top-aligned
- %, - render on one line, comma-separated
There are some quirks. Eg in one-line mode, %(depth_spacer) has no
effect, instead %(account) has indentation built in. Experimentation may
be needed to get pleasing results.
Some example formats:
- %(total) - the account's total
- %-20.20(account) - the account's name, left justified, padded to 20
characters and clipped at 20 characters
- %,%-50(account) %25(total) - account name padded to 50 characters,
total padded to 20 characters, with multiple commodities rendered on
one line
- %20(total) %2(depth_spacer)%-(account) - the default format for the
single-column balance report
Budget report
There is also a special balance report mode for showing budget
performance. The --budget flag activates extra columns showing the
budget goals for each account and period, if any. For this report,
budget goals are defined by periodic transactions. This is very useful
for comparing planned and actual income, expenses, time usage, etc.
For example, you can take average monthly expenses in the common expense
categories to construct a minimal monthly budget:
;; Budget
~ monthly
income $2000
expenses:food $400
expenses:bus $50
expenses:movies $30
assets:bank:checking
;; Two months worth of expenses
2017-11-01
income $1950
expenses:food $396
expenses:bus $49
expenses:movies $30
expenses:supplies $20
assets:bank:checking
2017-12-01
income $2100
expenses:food $412
expenses:bus $53
expenses:gifts $100
assets:bank:checking
You can now see a monthly budget report:
$ hledger balance -M --budget
Budget performance in 2017/11/01-2017/12/31:
|| Nov Dec
======================++====================================================
assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
expenses || $495 [ 103% of $480] $565 [ 118% of $480]
expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]
expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]
expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]
income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]
----------------------++----------------------------------------------------
|| 0 [ 0] 0 [ 0]
This is different from a normal balance report in several ways:
- Only accounts with budget goals during the report period are shown,
by default.
- In each column, in square brackets after the actual amount, budget
goal amounts are shown, and the actual/goal percentage. (Note:
budget goals should be in the same commodity as the actual amount.)
- All parent accounts are always shown, even in flat mode. Eg assets,
assets:bank, and expenses above.
- Amounts always include all subaccounts, budgeted or unbudgeted, even
in flat mode.
This means that the numbers displayed will not always add up! Eg above,
the expenses actual amount includes the gifts and supplies transactions,
but the expenses:gifts and expenses:supplies accounts are not shown, as
they have no budget amounts declared.
This can be confusing. When you need to make things clearer, use the
-E/--empty flag, which will reveal all accounts including unbudgeted
ones, giving the full picture. Eg:
$ hledger balance -M --budget --empty
Budget performance in 2017/11/01-2017/12/31:
|| Nov Dec
======================++====================================================
assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
expenses || $495 [ 103% of $480] $565 [ 118% of $480]
expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]
expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]
expenses:gifts || 0 $100
expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]
expenses:supplies || $20 0
income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]
----------------------++----------------------------------------------------
|| 0 [ 0] 0 [ 0]
You can roll over unspent budgets to next period with --cumulative:
$ hledger balance -M --budget --cumulative
Budget performance in 2017/11/01-2017/12/31:
|| Nov Dec
======================++====================================================
assets || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]
assets:bank || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]
assets:bank:checking || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]
expenses || $495 [ 103% of $480] $1060 [ 110% of $960]
expenses:bus || $49 [ 98% of $50] $102 [ 102% of $100]
expenses:food || $396 [ 99% of $400] $808 [ 101% of $800]
expenses:movies || $30 [ 100% of $30] $30 [ 50% of $60]
income || $1950 [ 98% of $2000] $4050 [ 101% of $4000]
----------------------++----------------------------------------------------
|| 0 [ 0] 0 [ 0]
For more examples and notes, see Budgeting.
Budget report start date
This might be a bug, but for now: when making budget reports, it's a
good idea to explicitly set the report's start date to the first day of
a reporting period, because a periodic rule like ~ monthly generates its
transactions on the 1st of each month, and if your journal has no
regular transactions on the 1st, the default report start date could
exclude that budget goal, which can be a little surprising. Eg here the
default report period is just the day of 2020-01-15:
~ monthly in 2020
(expenses:food) $500
2020-01-15
expenses:food $400
assets:checking
$ hledger bal expenses --budget
Budget performance in 2020-01-15:
|| 2020-01-15
==============++============
<unbudgeted> || $400
--------------++------------
|| $400
To avoid this, specify the budget report's period, or at least the start
date, with -b/-e/-p/date:, to ensure it includes the budget goal
transactions (periodic transactions) that you want. Eg, adding
-b 2020/1/1 to the above:
$ hledger bal expenses --budget -b 2020/1/1
Budget performance in 2020-01-01..2020-01-15:
|| 2020-01-01..2020-01-15
===============++========================
expenses:food || $400 [80% of $500]
---------------++------------------------
|| $400 [80% of $500]
Nested budgets
You can add budgets to any account in your account hierarchy. If you
have budgets on both parent account and some of its children, then
budget(s) of the child account(s) would be added to the budget of their
parent, much like account balances behave.
In the most simple case this means that once you add a budget to any
account, all its parents would have budget as well.
To illustrate this, consider the following budget:
~ monthly from 2019/01
expenses:personal $1,000.00
expenses:personal:electronics $100.00
liabilities
With this, monthly budget for electronics is defined to be $100 and
budget for personal expenses is an additional $1000, which implicitly
means that budget for both expenses:personal and expenses is $1100.
Transactions in expenses:personal:electronics will be counted both
towards its $100 budget and $1100 of expenses:personal , and
transactions in any other subaccount of expenses:personal would be
counted towards only towards the budget of expenses:personal.
For example, let's consider these transactions:
~ monthly from 2019/01
expenses:personal $1,000.00
expenses:personal:electronics $100.00
liabilities
2019/01/01 Google home hub
expenses:personal:electronics $90.00
liabilities $-90.00
2019/01/02 Phone screen protector
expenses:personal:electronics:upgrades $10.00
liabilities
2019/01/02 Weekly train ticket
expenses:personal:train tickets $153.00
liabilities
2019/01/03 Flowers
expenses:personal $30.00
liabilities
As you can see, we have transactions in
expenses:personal:electronics:upgrades and
expenses:personal:train tickets, and since both of these accounts are
without explicitly defined budget, these transactions would be counted
towards budgets of expenses:personal:electronics and expenses:personal
accordingly:
$ hledger balance --budget -M
Budget performance in 2019/01:
|| Jan
===============================++===============================
expenses || $283.00 [ 26% of $1100.00]
expenses:personal || $283.00 [ 26% of $1100.00]
expenses:personal:electronics || $100.00 [ 100% of $100.00]
liabilities || $-283.00 [ 26% of $-1100.00]
-------------------------------++-------------------------------
|| 0 [ 0]
And with --empty, we can get a better picture of budget allocation and
consumption:
$ hledger balance --budget -M --empty
Budget performance in 2019/01:
|| Jan
========================================++===============================
expenses || $283.00 [ 26% of $1100.00]
expenses:personal || $283.00 [ 26% of $1100.00]
expenses:personal:electronics || $100.00 [ 100% of $100.00]
expenses:personal:electronics:upgrades || $10.00
expenses:personal:train tickets || $153.00
liabilities || $-283.00 [ 26% of $-1100.00]
----------------------------------------++-------------------------------
|| 0 [ 0]