12093 lines
359 KiB
Groff
12093 lines
359 KiB
Groff
.\"t
|
||
|
||
.TH "HLEDGER" "1" "June 2023" "hledger-1.30.99 " "hledger User Manuals"
|
||
|
||
|
||
|
||
.SH NAME
|
||
.PP
|
||
hledger - robust, friendly plain text accounting (CLI version)
|
||
.SH SYNOPSIS
|
||
.PP
|
||
\f[V]hledger\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger COMMAND [OPTS] [ARGS]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger ADDONCMD -- [OPTS] [ARGS]\f[R]
|
||
.SH DESCRIPTION
|
||
.PP
|
||
hledger is a robust, user-friendly, cross-platform set of programs for
|
||
tracking money, time, or any other commodity, using double-entry
|
||
accounting and a simple, editable file format.
|
||
hledger is inspired by and largely compatible with ledger(1), and
|
||
largely interconvertible with beancount(1).
|
||
.PP
|
||
This manual is for hledger\[aq]s command line interface, version
|
||
1.30.99.
|
||
It also describes the common options, file formats and concepts used by
|
||
all hledger programs.
|
||
It might accidentally teach you some bookkeeping/accounting as well!
|
||
You don\[aq]t need to know everything in here to use hledger
|
||
productively, but when you have a question about functionality, this doc
|
||
should answer it.
|
||
It is detailed, so do skip ahead or skim when needed.
|
||
You can read it on hledger.org, or as an info manual or man page on your
|
||
system.
|
||
You can also get it from hledger itself with
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger --man\f[R], \f[V]hledger --info\f[R] or
|
||
\f[V]hledger help [TOPIC]\f[R].
|
||
.PP
|
||
The main function of the hledger CLI is to read plain text files
|
||
describing financial transactions, crunch the numbers, and print a
|
||
useful report on the terminal (or save it as HTML, CSV, JSON or SQL).
|
||
Many reports are available, as subcommands.
|
||
hledger will also detect other \f[V]hledger-*\f[R] executables as extra
|
||
subcommands.
|
||
.PP
|
||
hledger usually reads from (and appends to) a journal file specified by
|
||
the \f[V]LEDGER_FILE\f[R] environment variable (defaulting to
|
||
\f[V]$HOME/.hledger.journal\f[R]); or you can specify files with
|
||
\f[V]-f\f[R] options.
|
||
It can also read timeclock files, timedot files, or any CSV/SSV/TSV file
|
||
with a date field.
|
||
.PP
|
||
Here is a small journal file describing one transaction:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2015-10-16 bought food
|
||
expenses:food $10
|
||
assets:cash
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Transactions are dated movements of money (etc.)
|
||
between two or more \f[I]accounts\f[R]: bank accounts, your wallet,
|
||
revenue/expense categories, people, etc.
|
||
You can choose any account names you wish, using \f[V]:\f[R] to indicate
|
||
subaccounts.
|
||
There must be at least two spaces between account name and amount.
|
||
Positive amounts are inflow to that account (\f[I]debit\f[R]), negatives
|
||
are outflow from it (\f[I]credit\f[R]).
|
||
(Some reports show revenue, liability and equity account balances as
|
||
negative numbers as a result; this is normal.)
|
||
.PP
|
||
hledger\[cq]s add command can help you add transactions, or you can
|
||
install other data entry UIs like hledger-web or hledger-iadd.
|
||
For more extensive/efficient changes, use a text editor: Emacs +
|
||
ledger-mode, VIM + vim-ledger, or VS Code + hledger-vscode are some good
|
||
choices (see https://hledger.org/editors.html).
|
||
.PP
|
||
To get started, run \f[V]hledger add\f[R] and follow the prompts, or
|
||
save some entries like the above in \f[V]$HOME/.hledger.journal\f[R],
|
||
then try commands like:
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger print -x\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger aregister assets\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger balance\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger balancesheet\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger incomestatement\f[R].
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Run \f[V]hledger\f[R] to list the commands.
|
||
See also the \[dq]Starting a journal file\[dq] and \[dq]Setting opening
|
||
balances\[dq] sections in PART 5: COMMON TASKS.
|
||
.SH PART 1: USER INTERFACE
|
||
.SH Input
|
||
.PP
|
||
hledger reads one or more data files, each time you run it.
|
||
You can specify a file with \f[V]-f\f[R], like so
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f FILE print
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Files are most often in hledger\[aq]s journal format, with the
|
||
\f[V].journal\f[R] file extension (\f[V].hledger\f[R] or \f[V].j\f[R]
|
||
also work); these files describe transactions, like an accounting
|
||
general journal.
|
||
.PP
|
||
When no file is specified, hledger looks for \f[V].hledger.journal\f[R]
|
||
in your home directory.
|
||
.PP
|
||
But most people prefer to keep financial files in a dedicated folder,
|
||
perhaps with version control.
|
||
Also, starting a new journal file each year is common (it\[aq]s not
|
||
required, but helps keep things fast and organised).
|
||
So we usually configure a different journal file, by setting the
|
||
\f[V]LEDGER_FILE\f[R] environment variable, to something like
|
||
\f[V]\[ti]/finance/2023.journal\f[R].
|
||
For more about how to do that on your system, see Common tasks > Setting
|
||
LEDGER_FILE.
|
||
.SS Data formats
|
||
.PP
|
||
Usually the data file is in hledger\[aq]s journal format, but it can be
|
||
in any of the supported file formats, which currently are:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(7.8n) lw(39.5n) lw(22.7n).
|
||
T{
|
||
Reader:
|
||
T}@T{
|
||
Reads:
|
||
T}@T{
|
||
Used for file extensions:
|
||
T}
|
||
_
|
||
T{
|
||
\f[V]journal\f[R]
|
||
T}@T{
|
||
hledger journal files and some Ledger journals, for transactions
|
||
T}@T{
|
||
\f[V].journal\f[R] \f[V].j\f[R] \f[V].hledger\f[R] \f[V].ledger\f[R]
|
||
T}
|
||
T{
|
||
\f[V]timeclock\f[R]
|
||
T}@T{
|
||
timeclock files, for precise time logging
|
||
T}@T{
|
||
\f[V].timeclock\f[R]
|
||
T}
|
||
T{
|
||
\f[V]timedot\f[R]
|
||
T}@T{
|
||
timedot files, for approximate time logging
|
||
T}@T{
|
||
\f[V].timedot\f[R]
|
||
T}
|
||
T{
|
||
\f[V]csv\f[R]
|
||
T}@T{
|
||
CSV/SSV/TSV/character-separated values, for data import
|
||
T}@T{
|
||
\f[V].csv\f[R] \f[V].ssv\f[R] \f[V].tsv\f[R] \f[V].csv.rules\f[R]
|
||
\f[V].ssv.rules\f[R] \f[V].tsv.rules\f[R]
|
||
T}
|
||
.TE
|
||
.PP
|
||
These formats are described in more detail below.
|
||
.PP
|
||
hledger detects the format automatically based on the file extensions
|
||
shown above.
|
||
If it can\[aq]t recognise the file extension, it assumes
|
||
\f[V]journal\f[R] format.
|
||
So for non-journal files, it\[aq]s important to use a recognised file
|
||
extension, so as to either read successfully or to show relevant error
|
||
messages.
|
||
.PP
|
||
You can also force a specific reader/format by prefixing the file path
|
||
with the format and a colon.
|
||
Eg, to read a .dat file as csv format:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f csv:/some/csv-file.dat stats
|
||
\f[R]
|
||
.fi
|
||
.SS Standard input
|
||
.PP
|
||
The file name \f[V]-\f[R] means standard input:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ cat FILE | hledger -f- print
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If reading non-journal data in this way, you\[aq]ll need to add a file
|
||
format prefix, like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ echo \[aq]i 2009/13/1 08:00:00\[aq] | hledger print -f timeclock:-
|
||
\f[R]
|
||
.fi
|
||
.SS Multiple files
|
||
.PP
|
||
You can specify multiple \f[V]-f\f[R] options, to read multiple files as
|
||
one big journal.
|
||
When doing this, note that certain features (described below) will be
|
||
affected:
|
||
.IP \[bu] 2
|
||
Balance assertions will not see the effect of transactions in previous
|
||
files.
|
||
(Usually this doesn\[aq]t matter as each file will set the corresponding
|
||
opening balances.)
|
||
.IP \[bu] 2
|
||
Some directives will not affect previous or subsequent files.
|
||
.PP
|
||
If needed, you can work around these by using a single parent file which
|
||
includes the others, or concatenating the files into one, eg:
|
||
\f[V]cat a.journal b.journal | hledger -f- CMD\f[R].
|
||
.SS Strict mode
|
||
.PP
|
||
hledger checks input files for valid data.
|
||
By default, the most important errors are detected, while still
|
||
accepting easy journal files without a lot of declarations:
|
||
.IP \[bu] 2
|
||
Are the input files parseable, with valid syntax ?
|
||
.IP \[bu] 2
|
||
Are all transactions balanced ?
|
||
.IP \[bu] 2
|
||
Do all balance assertions pass ?
|
||
.PP
|
||
With the \f[V]-s\f[R]/\f[V]--strict\f[R] flag, additional checks are
|
||
performed:
|
||
.IP \[bu] 2
|
||
Are all accounts posted to, declared with an \f[V]account\f[R] directive
|
||
?
|
||
(Account error checking)
|
||
.IP \[bu] 2
|
||
Are all commodities declared with a \f[V]commodity\f[R] directive ?
|
||
(Commodity error checking)
|
||
.IP \[bu] 2
|
||
Are all commodity conversions declared explicitly ?
|
||
.PP
|
||
You can use the check command to run individual checks -- the ones
|
||
listed above and some more.
|
||
.SH Commands
|
||
.PP
|
||
hledger provides various subcommands for getting things done.
|
||
Most of these commands do not change the journal file; they just read it
|
||
and output a report.
|
||
A few commands assist with adding data and file management.
|
||
.PP
|
||
To show the commands list, run \f[V]hledger\f[R] with no arguments.
|
||
The commands are described in detail in PART 4: COMMANDS, below.
|
||
.PP
|
||
To use a particular command, run
|
||
\f[V]hledger CMD [CMDOPTS] [CMDARGS]\f[R],
|
||
.IP \[bu] 2
|
||
CMD is the full command name, or its standard abbreviation shown in the
|
||
commands list, or any unambiguous prefix of the name.
|
||
.IP \[bu] 2
|
||
CMDOPTS are command-specific options, if any.
|
||
Command-specific options must be written after the command name.
|
||
Eg: \f[V]hledger print -x\f[R].
|
||
.IP \[bu] 2
|
||
CMDARGS are additional arguments to the command, if any.
|
||
Most hledger commands accept arguments representing a query, to limit
|
||
the data in some way.
|
||
Eg: \f[V]hledger reg assets:checking\f[R].
|
||
.PP
|
||
To list a command\[aq]s options, arguments, and documentation in the
|
||
terminal, run \f[V]hledger CMD -h\f[R].
|
||
Eg: \f[V]hledger bal -h\f[R].
|
||
.SS Add-on commands
|
||
.PP
|
||
In addition to the built-in commands, you can install \f[I]add-on
|
||
commands\f[R]: programs or scripts named \[dq]hledger-SOMETHING\[dq],
|
||
which will also appear in hledger\[aq]s commands list.
|
||
If you used the hledger-install script, you will have several add-ons
|
||
installed already.
|
||
Some more can be found in hledger\[aq]s bin/ directory, documented at
|
||
https://hledger.org/scripts.html.
|
||
.PP
|
||
More precisely, add-on commands are programs or scripts in your
|
||
shell\[aq]s PATH, whose name starts with \[dq]hledger-\[dq] and ends
|
||
with no extension or a recognised extension (\[dq].bat\[dq],
|
||
\[dq].com\[dq], \[dq].exe\[dq], \[dq].hs\[dq], \[dq].js\[dq],
|
||
\[dq].lhs\[dq], \[dq].lua\[dq], \[dq].php\[dq], \[dq].pl\[dq],
|
||
\[dq].py\[dq], \[dq].rb\[dq], \[dq].rkt\[dq], or \[dq].sh\[dq]), and (on
|
||
unix and mac) which has executable permission for the current user.
|
||
.PP
|
||
You can run add-on commands using hledger, much like built-in commands:
|
||
\f[V]hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]\f[R].
|
||
But note the double hyphen argument, required before add-on-specific
|
||
options.
|
||
Eg: \f[V]hledger ui -- --watch\f[R] or \f[V]hledger web -- --serve\f[R].
|
||
If this causes difficulty, you can always run the add-on directly,
|
||
without using \f[V]hledger\f[R]: \f[V]hledger-ui --watch\f[R] or
|
||
\f[V]hledger-web --serve\f[R].
|
||
.SH Options
|
||
.PP
|
||
Run \f[V]hledger -h\f[R] to see general command line help, and general
|
||
options which are common to most hledger commands.
|
||
These options can be written anywhere on the command line.
|
||
They can be grouped into help, input, and reporting options:
|
||
.SS General help options
|
||
.TP
|
||
\f[V]-h --help\f[R]
|
||
show general or COMMAND help
|
||
.TP
|
||
\f[V]--man\f[R]
|
||
show general or COMMAND user manual with man
|
||
.TP
|
||
\f[V]--info\f[R]
|
||
show general or COMMAND user manual with info
|
||
.TP
|
||
\f[V]--version\f[R]
|
||
show general or ADDONCMD version
|
||
.TP
|
||
\f[V]--debug[=N]\f[R]
|
||
show debug output (levels 1-9, default: 1)
|
||
.SS General input options
|
||
.TP
|
||
\f[V]-f FILE --file=FILE\f[R]
|
||
use a different input file.
|
||
For stdin, use - (default: \f[V]$LEDGER_FILE\f[R] or
|
||
\f[V]$HOME/.hledger.journal\f[R])
|
||
.TP
|
||
\f[V]--rules-file=RULESFILE\f[R]
|
||
Conversion rules file to use when reading CSV (default: FILE.rules)
|
||
.TP
|
||
\f[V]--separator=CHAR\f[R]
|
||
Field separator to expect when reading CSV (default: \[aq],\[aq])
|
||
.TP
|
||
\f[V]--alias=OLD=NEW\f[R]
|
||
rename accounts named OLD to NEW
|
||
.TP
|
||
\f[V]--anon\f[R]
|
||
anonymize accounts and payees
|
||
.TP
|
||
\f[V]--pivot FIELDNAME\f[R]
|
||
use some other field or tag for the account name
|
||
.TP
|
||
\f[V]-I --ignore-assertions\f[R]
|
||
disable balance assertion checks (note: does not disable balance
|
||
assignments)
|
||
.TP
|
||
\f[V]-s --strict\f[R]
|
||
do extra error checking (check that all posted accounts are declared)
|
||
.SS General reporting options
|
||
.TP
|
||
\f[V]-b --begin=DATE\f[R]
|
||
include postings/txns on or after this date (will be adjusted to
|
||
preceding subperiod start when using a report interval)
|
||
.TP
|
||
\f[V]-e --end=DATE\f[R]
|
||
include postings/txns before this date (will be adjusted to following
|
||
subperiod end when using a report interval)
|
||
.TP
|
||
\f[V]-D --daily\f[R]
|
||
multiperiod/multicolumn report by day
|
||
.TP
|
||
\f[V]-W --weekly\f[R]
|
||
multiperiod/multicolumn report by week
|
||
.TP
|
||
\f[V]-M --monthly\f[R]
|
||
multiperiod/multicolumn report by month
|
||
.TP
|
||
\f[V]-Q --quarterly\f[R]
|
||
multiperiod/multicolumn report by quarter
|
||
.TP
|
||
\f[V]-Y --yearly\f[R]
|
||
multiperiod/multicolumn report by year
|
||
.TP
|
||
\f[V]-p --period=PERIODEXP\f[R]
|
||
set start date, end date, and/or reporting interval all at once using
|
||
period expressions syntax
|
||
.TP
|
||
\f[V]--date2\f[R]
|
||
match the secondary date instead (see command help for other effects)
|
||
.TP
|
||
\f[V]--today=DATE\f[R]
|
||
override today\[aq]s date (affects relative smart dates, for
|
||
tests/examples)
|
||
.TP
|
||
\f[V]-U --unmarked\f[R]
|
||
include only unmarked postings/txns (can combine with -P or -C)
|
||
.TP
|
||
\f[V]-P --pending\f[R]
|
||
include only pending postings/txns
|
||
.TP
|
||
\f[V]-C --cleared\f[R]
|
||
include only cleared postings/txns
|
||
.TP
|
||
\f[V]-R --real\f[R]
|
||
include only non-virtual postings
|
||
.TP
|
||
\f[V]-NUM --depth=NUM\f[R]
|
||
hide/aggregate accounts or postings more than NUM levels deep
|
||
.TP
|
||
\f[V]-E --empty\f[R]
|
||
show items with zero amount, normally hidden (and vice-versa in
|
||
hledger-ui/hledger-web)
|
||
.TP
|
||
\f[V]-B --cost\f[R]
|
||
convert amounts to their cost/selling amount at transaction time
|
||
.TP
|
||
\f[V]-V --market\f[R]
|
||
convert amounts to their market value in default valuation commodities
|
||
.TP
|
||
\f[V]-X --exchange=COMM\f[R]
|
||
convert amounts to their market value in commodity COMM
|
||
.TP
|
||
\f[V]--value\f[R]
|
||
convert amounts to cost or market value, more flexibly than -B/-V/-X
|
||
.TP
|
||
\f[V]--infer-equity\f[R]
|
||
infer conversion equity postings from costs
|
||
.TP
|
||
\f[V]--infer-costs\f[R]
|
||
infer costs from conversion equity postings
|
||
.TP
|
||
\f[V]--infer-market-prices\f[R]
|
||
use costs as additional market prices, as if they were P directives
|
||
.TP
|
||
\f[V]--forecast\f[R]
|
||
generate transactions from periodic rules,
|
||
between the latest recorded txn and 6 months from today,
|
||
or during the specified PERIOD (= is required).
|
||
Auto posting rules will be applied to these transactions as well.
|
||
Also, in hledger-ui make future-dated transactions visible.
|
||
.TP
|
||
\f[V]--auto\f[R]
|
||
generate extra postings by applying auto posting rules to all txns (not
|
||
just forecast txns)
|
||
.TP
|
||
\f[V]--verbose-tags\f[R]
|
||
add visible tags indicating transactions or postings which have been
|
||
generated/modified
|
||
.TP
|
||
\f[V]--commodity-style\f[R]
|
||
Override the commodity style in the output for the specified commodity.
|
||
For example \[aq]EUR1.000,00\[aq].
|
||
.TP
|
||
\f[V]--color=WHEN (or --colour=WHEN)\f[R]
|
||
Should color-supporting commands use ANSI color codes in text output.
|
||
\[aq]auto\[aq] (default): whenever stdout seems to be a color-supporting
|
||
terminal.
|
||
\[aq]always\[aq] or \[aq]yes\[aq]: always, useful eg when piping output
|
||
into \[aq]less -R\[aq].
|
||
\[aq]never\[aq] or \[aq]no\[aq]: never.
|
||
A NO_COLOR environment variable overrides this.
|
||
.TP
|
||
\f[V]--pretty[=WHEN]\f[R]
|
||
Show prettier output, e.g.
|
||
using unicode box-drawing characters.
|
||
Accepts \[aq]yes\[aq] (the default) or \[aq]no\[aq] (\[aq]y\[aq],
|
||
\[aq]n\[aq], \[aq]always\[aq], \[aq]never\[aq] also work).
|
||
If you provide an argument you must use \[aq]=\[aq], e.g.
|
||
\[aq]--pretty=yes\[aq].
|
||
.PP
|
||
When a reporting option appears more than once in the command line, the
|
||
last one takes precedence.
|
||
.PP
|
||
Some reporting options can also be written as query arguments.
|
||
.SH Command line tips
|
||
.PP
|
||
Here are some details useful to know about for hledger command lines
|
||
(and elsewhere).
|
||
Feel free to skip this section until you need it.
|
||
.SS Option repetition
|
||
.PP
|
||
If options are repeated in a command line, hledger will generally use
|
||
the last (right-most) occurence.
|
||
.SS Special characters
|
||
.SS Single escaping (shell metacharacters)
|
||
.PP
|
||
In shell command lines, characters significant to your shell - such as
|
||
spaces, \f[V]<\f[R], \f[V]>\f[R], \f[V](\f[R], \f[V])\f[R], \f[V]|\f[R],
|
||
\f[V]$\f[R] and \f[V]\[rs]\f[R] - should be \[dq]shell-escaped\[dq] if
|
||
you want hledger to see them.
|
||
This is done by enclosing them in single or double quotes, or by writing
|
||
a backslash before them.
|
||
Eg to match an account name containing a space:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register \[aq]credit card\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register credit\[rs] card
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Windows users should keep in mind that \f[V]cmd\f[R] treats single quote
|
||
as a regular character, so you should be using double quotes
|
||
exclusively.
|
||
PowerShell treats both single and double quotes as quotes.
|
||
.SS Double escaping (regular expression metacharacters)
|
||
.PP
|
||
Characters significant in regular expressions (described below) - such
|
||
as \f[V].\f[R], \f[V]\[ha]\f[R], \f[V]$\f[R], \f[V][\f[R], \f[V]]\f[R],
|
||
\f[V](\f[R], \f[V])\f[R], \f[V]|\f[R], and \f[V]\[rs]\f[R] - may need to
|
||
be \[dq]regex-escaped\[dq] if you don\[aq]t want them to be interpreted
|
||
by hledger\[aq]s regular expression engine.
|
||
This is done by writing backslashes before them, but since backslash is
|
||
typically also a shell metacharacter, both shell-escaping and
|
||
regex-escaping will be needed.
|
||
Eg to match a literal \f[V]$\f[R] sign while using the bash shell:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance cur:\[aq]\[rs]$\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance cur:\[rs]\[rs]$
|
||
\f[R]
|
||
.fi
|
||
.SS Triple escaping (for add-on commands)
|
||
.PP
|
||
When you use hledger to run an external add-on command (described
|
||
below), one level of shell-escaping is lost from any options or
|
||
arguments intended for by the add-on command, so those need an extra
|
||
level of shell-escaping.
|
||
Eg to match a literal \f[V]$\f[R] sign while using the bash shell and
|
||
running an add-on command (\f[V]ui\f[R]):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger ui cur:\[aq]\[rs]\[rs]$\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger ui cur:\[rs]\[rs]\[rs]\[rs]$
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If you wondered why \f[I]four\f[R] backslashes, perhaps this helps:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
l l.
|
||
T{
|
||
unescaped:
|
||
T}@T{
|
||
\f[V]$\f[R]
|
||
T}
|
||
T{
|
||
escaped:
|
||
T}@T{
|
||
\f[V]\[rs]$\f[R]
|
||
T}
|
||
T{
|
||
double-escaped:
|
||
T}@T{
|
||
\f[V]\[rs]\[rs]$\f[R]
|
||
T}
|
||
T{
|
||
triple-escaped:
|
||
T}@T{
|
||
\f[V]\[rs]\[rs]\[rs]\[rs]$\f[R]
|
||
T}
|
||
.TE
|
||
.PP
|
||
Or, you can avoid the extra escaping by running the add-on executable
|
||
directly:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger-ui cur:\[rs]\[rs]$
|
||
\f[R]
|
||
.fi
|
||
.SS Less escaping
|
||
.PP
|
||
Options and arguments are sometimes used in places other than the shell
|
||
command line, where shell-escaping is not needed, so there you should
|
||
use one less level of escaping.
|
||
Those places include:
|
||
.IP \[bu] 2
|
||
an \[at]argumentfile
|
||
.IP \[bu] 2
|
||
hledger-ui\[aq]s filter field
|
||
.IP \[bu] 2
|
||
hledger-web\[aq]s search form
|
||
.IP \[bu] 2
|
||
GHCI\[aq]s prompt (used by developers).
|
||
.SS Unicode characters
|
||
.PP
|
||
hledger is expected to handle non-ascii characters correctly:
|
||
.IP \[bu] 2
|
||
they should be parsed correctly in input files and on the command line,
|
||
by all hledger tools (add, iadd, hledger-web\[aq]s search/add/edit
|
||
forms, etc.)
|
||
.IP \[bu] 2
|
||
they should be displayed correctly by all hledger tools, and on-screen
|
||
alignment should be preserved.
|
||
.PP
|
||
This requires a well-configured environment.
|
||
Here are some tips:
|
||
.IP \[bu] 2
|
||
A system locale must be configured, and it must be one that can decode
|
||
the characters being used.
|
||
In bash, you can set a locale like this:
|
||
\f[V]export LANG=en_US.UTF-8\f[R].
|
||
There are some more details in Troubleshooting.
|
||
This step is essential - without it, hledger will quit on encountering a
|
||
non-ascii character (as with all GHC-compiled programs).
|
||
.IP \[bu] 2
|
||
your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)
|
||
must support unicode
|
||
.IP \[bu] 2
|
||
the terminal must be using a font which includes the required unicode
|
||
glyphs
|
||
.IP \[bu] 2
|
||
the terminal should be configured to display wide characters as double
|
||
width (for report alignment)
|
||
.IP \[bu] 2
|
||
on Windows, for best results you should run hledger in the same kind of
|
||
environment in which it was built.
|
||
Eg hledger built in the standard CMD.EXE environment (like the binaries
|
||
on our download page) might show display problems when run in a cygwin
|
||
or msys terminal, and vice versa.
|
||
(See eg #961).
|
||
.SS Regular expressions
|
||
.PP
|
||
hledger uses regular expressions in a number of places:
|
||
.IP \[bu] 2
|
||
query terms, on the command line and in the hledger-web search form:
|
||
\f[V]REGEX\f[R], \f[V]desc:REGEX\f[R], \f[V]cur:REGEX\f[R],
|
||
\f[V]tag:...=REGEX\f[R]
|
||
.IP \[bu] 2
|
||
CSV rules conditional blocks: \f[V]if REGEX ...\f[R]
|
||
.IP \[bu] 2
|
||
account alias directive and \f[V]--alias\f[R] option:
|
||
\f[V]alias /REGEX/ = REPLACEMENT\f[R],
|
||
\f[V]--alias /REGEX/=REPLACEMENT\f[R]
|
||
.PP
|
||
hledger\[aq]s regular expressions come from the regex-tdfa library.
|
||
If they\[aq]re not doing what you expect, it\[aq]s important to know
|
||
exactly what they support:
|
||
.IP "1." 3
|
||
they are case insensitive
|
||
.IP "2." 3
|
||
they are infix matching (they do not need to match the entire thing
|
||
being matched)
|
||
.IP "3." 3
|
||
they are POSIX ERE (extended regular expressions)
|
||
.IP "4." 3
|
||
they also support GNU word boundaries (\f[V]\[rs]b\f[R],
|
||
\f[V]\[rs]B\f[R], \f[V]\[rs]<\f[R], \f[V]\[rs]>\f[R])
|
||
.IP "5." 3
|
||
they do not support backreferences; if you write \f[V]\[rs]1\f[R], it
|
||
will match the digit \f[V]1\f[R].
|
||
Except when doing text replacement, eg in account aliases, where
|
||
backreferences can be used in the replacement string to reference
|
||
capturing groups in the search regexp.
|
||
.IP "6." 3
|
||
they do not support mode modifiers (\f[V](?s)\f[R]), character classes
|
||
(\f[V]\[rs]w\f[R], \f[V]\[rs]d\f[R]), or anything else not mentioned
|
||
above.
|
||
.PP
|
||
Some things to note:
|
||
.IP \[bu] 2
|
||
In the \f[V]alias\f[R] directive and \f[V]--alias\f[R] option, regular
|
||
expressions must be enclosed in forward slashes (\f[V]/REGEX/\f[R]).
|
||
Elsewhere in hledger, these are not required.
|
||
.IP \[bu] 2
|
||
In queries, to match a regular expression metacharacter like \f[V]$\f[R]
|
||
as a literal character, prepend a backslash.
|
||
Eg to search for amounts with the dollar sign in hledger-web, write
|
||
\f[V]cur:\[rs]$\f[R].
|
||
.IP \[bu] 2
|
||
On the command line, some metacharacters like \f[V]$\f[R] have a special
|
||
meaning to the shell and so must be escaped at least once more.
|
||
See Special characters.
|
||
.SS Argument files
|
||
.PP
|
||
You can save a set of command line options and arguments in a file, and
|
||
then reuse them by writing \f[V]\[at]FILENAME\f[R] as a command line
|
||
argument.
|
||
Eg: \f[V]hledger bal \[at]foo.args\f[R].
|
||
.PP
|
||
Inside the argument file, each line should contain just one option or
|
||
argument.
|
||
Don\[aq]t use spaces except inside quotes (or you\[aq]ll see a confusing
|
||
error); write \f[V]=\f[R] (or nothing) between a flag and its argument.
|
||
For the special characters mentioned above, use one less level of
|
||
quoting than you would at the command prompt.
|
||
.SH Output
|
||
.SS Output destination
|
||
.PP
|
||
hledger commands send their output to the terminal by default.
|
||
You can of course redirect this, eg into a file, using standard shell
|
||
syntax:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print > foo.txt
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Some commands (print, register, stats, the balance commands) also
|
||
provide the \f[V]-o/--output-file\f[R] option, which does the same thing
|
||
without needing the shell.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -o foo.txt
|
||
$ hledger print -o - # write to stdout (the default)
|
||
\f[R]
|
||
.fi
|
||
.SS Output format
|
||
.PP
|
||
Some commands offer other kinds of output, not just text on the
|
||
terminal.
|
||
Here are those commands and the formats currently supported:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(25.9n) lw(9.1n) lw(9.1n) lw(11.7n) lw(7.8n) lw(6.5n).
|
||
T{
|
||
-
|
||
T}@T{
|
||
txt
|
||
T}@T{
|
||
csv
|
||
T}@T{
|
||
html
|
||
T}@T{
|
||
json
|
||
T}@T{
|
||
sql
|
||
T}
|
||
_
|
||
T{
|
||
aregister
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}
|
||
T{
|
||
balance
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1,2\f[R]
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}
|
||
T{
|
||
balancesheet
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}
|
||
T{
|
||
balancesheetequity
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}
|
||
T{
|
||
cashflow
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}
|
||
T{
|
||
incomestatement
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y \f[I]1\f[R]
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}
|
||
T{
|
||
print
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}
|
||
T{
|
||
register
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}
|
||
.TE
|
||
.IP \[bu] 2
|
||
\f[I]1 Also affected by the balance commands\[aq] \f[VI]--layout\f[I]
|
||
option.\f[R]
|
||
.IP \[bu] 2
|
||
\f[I]2 \f[VI]balance\f[I] does not support html output without a report
|
||
interval or with \f[VI]--budget\f[I].\f[R]
|
||
.PP
|
||
The output format is selected by the \f[V]-O/--output-format=FMT\f[R]
|
||
option:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -O csv # print CSV on stdout
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or by the filename extension of an output file specified with the
|
||
\f[V]-o/--output-file=FILE.FMT\f[R] option:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balancesheet -o foo.csv # write CSV to foo.csv
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The \f[V]-O\f[R] option can be combined with \f[V]-o\f[R] to override
|
||
the file extension, if needed:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Some notes about the various output formats:
|
||
.SS CSV output
|
||
.IP \[bu] 2
|
||
In CSV output, digit group marks (such as thousands separators) are
|
||
disabled automatically.
|
||
.SS HTML output
|
||
.IP \[bu] 2
|
||
HTML output can be styled by an optional \f[V]hledger.css\f[R] file in
|
||
the same directory.
|
||
.SS JSON output
|
||
.IP \[bu] 2
|
||
This is not yet much used; real-world feedback is welcome.
|
||
.IP \[bu] 2
|
||
Our JSON is rather large and verbose, since it is a faithful
|
||
representation of hledger\[aq]s internal data types.
|
||
To understand the JSON, read the Haskell type definitions, which are
|
||
mostly in
|
||
https://github.com/simonmichael/hledger/blob/master/hledger-lib/Hledger/Data/Types.hs.
|
||
.IP \[bu] 2
|
||
hledger represents quantities as Decimal values storing up to 255
|
||
significant digits, eg for repeating decimals.
|
||
Such numbers can arise in practice (from automatically-calculated
|
||
transaction prices), and would break most JSON consumers.
|
||
So in JSON, we show quantities as simple Numbers with at most 10 decimal
|
||
places.
|
||
We don\[aq]t limit the number of integer digits, but that part is under
|
||
your control.
|
||
We hope this approach will not cause problems in practice; if you find
|
||
otherwise, please let us know.
|
||
(Cf #1195)
|
||
.SS SQL output
|
||
.IP \[bu] 2
|
||
This is not yet much used; real-world feedback is welcome.
|
||
.IP \[bu] 2
|
||
SQL output is expected to work at least with SQLite, MySQL and Postgres.
|
||
.IP \[bu] 2
|
||
For SQLite, it will be more useful if you modify the generated
|
||
\f[V]id\f[R] field to be a PRIMARY KEY.
|
||
Eg:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -O sql | sed \[aq]s/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g\[aq] | ...
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP \[bu] 2
|
||
SQL output is structured with the expectations that statements will be
|
||
executed in the empty database.
|
||
If you already have tables created via SQL output of hledger, you would
|
||
probably want to either clear tables of existing data (via
|
||
\f[V]delete\f[R] or \f[V]truncate\f[R] SQL statements) or drop tables
|
||
completely as otherwise your postings will be duped.
|
||
.SS Commodity styles
|
||
.PP
|
||
When displaying amounts, hledger infers a standard display style for
|
||
each commodity/currency, as described below in Commodity display style.
|
||
.PP
|
||
If needed, this can be overridden by a \f[V]-c/--commodity-style\f[R]
|
||
option (except for cost amounts and amounts displayed by the
|
||
\f[V]print\f[R] command, which are always displayed with all decimal
|
||
digits).
|
||
For example, the following will force dollar amounts to be displayed as
|
||
shown:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -c \[aq]$1.000,0\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This option can repeated to set the display style for multiple
|
||
commodities/currencies.
|
||
Its argument is as described in the commodity directive.
|
||
.SS Colour
|
||
.PP
|
||
In terminal output, some commands can produce colour when the terminal
|
||
supports it:
|
||
.IP \[bu] 2
|
||
if the \f[V]--color/--colour\f[R] option is given a value of
|
||
\f[V]yes\f[R] or \f[V]always\f[R] (or \f[V]no\f[R] or \f[V]never\f[R]),
|
||
colour will (or will not) be used;
|
||
.IP \[bu] 2
|
||
otherwise, if the \f[V]NO_COLOR\f[R] environment variable is set, colour
|
||
will not be used;
|
||
.IP \[bu] 2
|
||
otherwise, colour will be used if the output (terminal or file) supports
|
||
it.
|
||
.SS Box-drawing
|
||
.PP
|
||
In terminal output, you can enable unicode box-drawing characters to
|
||
render prettier tables:
|
||
.IP \[bu] 2
|
||
if the \f[V]--pretty\f[R] option is given a value of \f[V]yes\f[R] or
|
||
\f[V]always\f[R] (or \f[V]no\f[R] or \f[V]never\f[R]), unicode
|
||
characters will (or will not) be used;
|
||
.IP \[bu] 2
|
||
otherwise, unicode characters will not be used.
|
||
.SS Paging
|
||
.PP
|
||
When showing long output in the terminal, hledger will try to use the
|
||
pager specified by the \f[V]PAGER\f[R] environment variable, or
|
||
\f[V]less\f[R], or \f[V]more\f[R].
|
||
(A pager is a helper program that shows one page at a time rather than
|
||
scrolling everything off screen).
|
||
Currently it does this only for help output, not for reports;
|
||
specifically,
|
||
.IP \[bu] 2
|
||
when listing commands, with \f[V]hledger\f[R]
|
||
.IP \[bu] 2
|
||
when showing help with \f[V]hledger [CMD] --help\f[R],
|
||
.IP \[bu] 2
|
||
when viewing manuals with \f[V]hledger help\f[R] or
|
||
\f[V]hledger --man\f[R].
|
||
.PP
|
||
Note the pager is expected to handle ANSI codes, which hledger uses eg
|
||
for bold emphasis.
|
||
For the common pager \f[V]less\f[R] (and its \f[V]more\f[R]
|
||
compatibility mode), we add \f[V]R\f[R] to the \f[V]LESS\f[R] and
|
||
\f[V]MORE\f[R] environment variables to make this work.
|
||
If you use a different pager, you might need to configure it similarly,
|
||
to avoid seeing junk on screen (let us know).
|
||
Otherwise, you can set the \f[V]NO_COLOR\f[R] environment variable to 1
|
||
to disable all ANSI output (see Colour).
|
||
.SS Debug output
|
||
.PP
|
||
We intend hledger to be relatively easy to troubleshoot, introspect and
|
||
develop.
|
||
You can add \f[V]--debug[=N]\f[R] to any hledger command line to see
|
||
additional debug output.
|
||
N ranges from 1 (least output, the default) to 9 (maximum output).
|
||
Typically you would start with 1 and increase until you are seeing
|
||
enough.
|
||
Debug output goes to stderr, and is not affected by
|
||
\f[V]-o/--output-file\f[R] (unless you redirect stderr to stdout, eg:
|
||
\f[V]2>&1\f[R]).
|
||
It will be interleaved with normal output, which can help reveal when
|
||
parts of the code are evaluated.
|
||
To capture debug output in a log file instead, you can usually redirect
|
||
stderr, eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
hledger bal --debug=3 2>hledger.log
|
||
\f[R]
|
||
.fi
|
||
.SH Environment
|
||
.PP
|
||
These environment variables affect hledger:
|
||
.PP
|
||
\f[B]COLUMNS\f[R] This is normally set by your terminal; some hledger
|
||
commands (\f[V]register\f[R]) will format their output to this width.
|
||
If not set, they will try to use the available terminal width.
|
||
.PP
|
||
\f[B]LEDGER_FILE\f[R] The main journal file to use when not specified
|
||
with \f[V]-f/--file\f[R].
|
||
Default: \f[V]$HOME/.hledger.journal\f[R].
|
||
.PP
|
||
\f[B]NO_COLOR\f[R] If this environment variable is set (with any value),
|
||
hledger will not use ANSI color codes in terminal output, unless
|
||
overridden by an explicit \f[V]--color/--colour\f[R] option.
|
||
.SH PART 2: DATA FORMATS
|
||
.PP
|
||
.SH Journal
|
||
.PP
|
||
hledger\[aq]s default file format, representing a General Journal.
|
||
Here\[aq]s a cheatsheet/mini-tutorial, or you can skip ahead to About
|
||
journal format.
|
||
.SS Journal cheatsheet
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# Here is the main syntax of hledger\[aq]s journal format
|
||
# (omitting extra Ledger compatibility syntax).
|
||
# hledger journals contain comments, directives, and transactions, in any order:
|
||
|
||
###############################################################################
|
||
# 1. Comment lines are for notes or temporarily disabling things.
|
||
# They begin with #, ;, or a line containing the word \[dq]comment\[dq].
|
||
|
||
# hash comment line
|
||
; semicolon comment line
|
||
comment
|
||
These lines
|
||
are commented.
|
||
end comment
|
||
|
||
# Some but not all hledger entries can have same-line comments attached to them,
|
||
# from ; (semicolon) to end of line.
|
||
|
||
###############################################################################
|
||
# 2. Directives modify parsing or reports in some way.
|
||
# They begin with a word or letter (or symbol).
|
||
|
||
account actifs ; type:A, declare an account that is an Asset. 2+ spaces before ;.
|
||
account passifs ; type:L, declare an account that is a Liability, and so on.. (ALERX)
|
||
alias chkg = assets:checking
|
||
commodity $0.00
|
||
decimal-mark .
|
||
include /dev/null
|
||
payee Whole Foods
|
||
P 2022-01-01 AAAA $1.40
|
||
\[ti] monthly budget goals ; <- 2+ spaces between period expression and description
|
||
expenses:food $400
|
||
expenses:home $1000
|
||
budgeted
|
||
|
||
###############################################################################
|
||
# 3. Transactions are what it\[aq]s all about; they are dated events,
|
||
# usually describing movements of money.
|
||
# They begin with a date.
|
||
|
||
# DATE DESCRIPTION ; This is a transaction comment.
|
||
# ACCOUNT NAME 1 AMOUNT1 ; <- posting 1. This is a posting comment.
|
||
# ACCOUNT NAME 2 AMOUNT2 ; <- posting 2. Postings must be indented.
|
||
# ; \[ha]\[ha] At least 2 spaces between account and amount.
|
||
# ... ; Any number of postings is allowed. The amounts must balance (sum to 0).
|
||
|
||
2022-01-01 opening balances are declared this way
|
||
assets:checking $1000 ; Account names can be anything. lower case is easy to type.
|
||
assets:savings $1000 ; assets, liabilities, equity, revenues, expenses are common.
|
||
assets:cash:wallet $100 ; : indicates subaccounts.
|
||
liabilities:credit card $-200 ; liabilities, equity, revenues balances are usually negative.
|
||
equity ; One amount can be left blank; $-1900 is inferred here.
|
||
|
||
2022-04-15 * (#12345) pay taxes
|
||
; There can be a ! or * after the date meaning \[dq]pending\[dq] or \[dq]cleared\[dq].
|
||
; There can be a transaction code (text in parentheses) after the date/status.
|
||
; Amounts\[aq] sign represents direction of flow, or credit/debit:
|
||
assets:checking $-500 ; minus means removed from this account (credit)
|
||
expenses:tax:us:2021 $500 ; plus means added to this account (debit)
|
||
; revenue/expense categories are also \[dq]accounts\[dq]
|
||
|
||
2022-01-01 ; The description is optional.
|
||
; Any currency/commodity symbols are allowed, on either side.
|
||
assets:cash:wallet GBP -10
|
||
expenses:clothing GBP 10
|
||
assets:gringotts -10 gold
|
||
assets:pouch 10 gold
|
||
revenues:gifts -2 \[dq]Liquorice Wands\[dq] ; Complex symbols
|
||
assets:bag 2 \[dq]Liquorice Wands\[dq] ; must be double-quoted.
|
||
|
||
2022-01-01 Cost in another commodity can be noted with \[at] or \[at]\[at]
|
||
assets:investments 2.0 AAAA \[at] $1.50 ; \[at] means per-unit cost
|
||
assets:investments 3.0 AAAA \[at]\[at] $4 ; \[at]\[at] means total cost
|
||
assets:checking $-7.00
|
||
|
||
2022-01-02 assert balances
|
||
; Balances can be asserted for extra error checking, in any transaction.
|
||
assets:investments 0 AAAA = 5.0 AAAA
|
||
assets:pouch 0 gold = 10 gold
|
||
assets:savings $0 = $1000
|
||
|
||
1999-12-31 Ordering transactions by date is recommended but not required.
|
||
; Postings are not required.
|
||
|
||
2022.01.01 These date
|
||
2022/1/1 formats are
|
||
12/31 also allowed (but consistent YYYY-MM-DD is recommended).
|
||
\f[R]
|
||
.fi
|
||
.SS About journal format
|
||
.PP
|
||
hledger\[aq]s usual data source is a plain text file containing journal
|
||
entries in hledger journal format.
|
||
This file represents a standard accounting general journal.
|
||
I use file names ending in \f[V].journal\f[R], but that\[aq]s not
|
||
required.
|
||
The journal file contains a number of transaction entries, each
|
||
describing a transfer of money (or any commodity) between two or more
|
||
named accounts, in a simple format readable by both hledger and humans.
|
||
.PP
|
||
hledger\[aq]s journal format is compatible with most of Ledger\[aq]s
|
||
journal format, but not all of it.
|
||
The differences and interoperation tips are described at hledger and
|
||
Ledger.
|
||
With some care, and by avoiding incompatible features, you can keep your
|
||
hledger journal readable by Ledger and vice versa.
|
||
This can useful eg for comparing the behaviour of one app against the
|
||
other.
|
||
.PP
|
||
You can use hledger without learning any more about this file; just use
|
||
the add or web or import commands to create and update it.
|
||
.PP
|
||
Many users, though, edit the journal file with a text editor, and track
|
||
changes with a version control system such as git.
|
||
Editor addons such as ledger-mode or hledger-mode for Emacs, vim-ledger
|
||
for Vim, and hledger-vscode for Visual Studio Code, make this easier,
|
||
adding colour, formatting, tab completion, and useful commands.
|
||
See Editor configuration at hledger.org for the full list.
|
||
.PP
|
||
Here\[aq]s a description of each part of the file format (and
|
||
hledger\[aq]s data model).
|
||
.PP
|
||
A hledger journal file can contain three kinds of thing: file comments,
|
||
transactions, and/or directives (counting periodic transaction rules and
|
||
auto posting rules as directives).
|
||
.SS Comments
|
||
.PP
|
||
Lines in the journal will be ignored if they begin with a hash
|
||
(\f[V]#\f[R]) or a semicolon (\f[V];\f[R]).
|
||
(See also Other syntax.)
|
||
hledger will also ignore regions beginning with a \f[V]comment\f[R] line
|
||
and ending with an \f[V]end comment\f[R] line (or file end).
|
||
Here\[aq]s a suggestion for choosing between them:
|
||
.IP \[bu] 2
|
||
\f[V]#\f[R] for top-level notes
|
||
.IP \[bu] 2
|
||
\f[V];\f[R] for commenting out things temporarily
|
||
.IP \[bu] 2
|
||
\f[V]comment\f[R] for quickly commenting large regions (remember
|
||
it\[aq]s there, or you might get confused)
|
||
.PP
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# a comment line
|
||
; another commentline
|
||
comment
|
||
A multi-line comment block,
|
||
continuing until \[dq]end comment\[dq] directive
|
||
or the end of the current file.
|
||
end comment
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Some hledger entries can have same-line comments attached to them, from
|
||
; (semicolon) to end of line.
|
||
See Transaction comments, Posting comments, and Account comments below.
|
||
.SS Transactions
|
||
.PP
|
||
Transactions are the main unit of information in a journal file.
|
||
They represent events, typically a movement of some quantity of
|
||
commodities between two or more named accounts.
|
||
.PP
|
||
Each transaction is recorded as a journal entry, beginning with a simple
|
||
date in column 0.
|
||
This can be followed by any of the following optional fields, separated
|
||
by spaces:
|
||
.IP \[bu] 2
|
||
a status character (empty, \f[V]!\f[R], or \f[V]*\f[R])
|
||
.IP \[bu] 2
|
||
a code (any short number or text, enclosed in parentheses)
|
||
.IP \[bu] 2
|
||
a description (any remaining text until end of line or a semicolon)
|
||
.IP \[bu] 2
|
||
a comment (any remaining text following a semicolon until end of line,
|
||
and any following indented lines beginning with a semicolon)
|
||
.IP \[bu] 2
|
||
0 or more indented \f[I]posting\f[R] lines, describing what was
|
||
transferred and the accounts involved (indented comment lines are also
|
||
allowed, but not blank lines or non-indented lines).
|
||
.PP
|
||
Here\[aq]s a simple journal file containing one transaction:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2008/01/01 income
|
||
assets:bank:checking $1
|
||
income:salary $-1
|
||
\f[R]
|
||
.fi
|
||
.SS Dates
|
||
.SS Simple dates
|
||
.PP
|
||
Dates in the journal file use \f[I]simple dates\f[R] format:
|
||
\f[V]YYYY-MM-DD\f[R] or \f[V]YYYY/MM/DD\f[R] or \f[V]YYYY.MM.DD\f[R],
|
||
with leading zeros optional.
|
||
The year may be omitted, in which case it will be inferred from the
|
||
context: the current transaction, the default year set with a
|
||
\f[V]Y\f[R] directive, or the current date when the command is run.
|
||
Some examples: \f[V]2010-01-31\f[R], \f[V]2010/01/31\f[R],
|
||
\f[V]2010.1.31\f[R], \f[V]1/31\f[R].
|
||
.PP
|
||
(The UI also accepts simple dates, as well as the more flexible smart
|
||
dates documented in the hledger manual.)
|
||
.SS Posting dates
|
||
.PP
|
||
You can give individual postings a different date from their parent
|
||
transaction, by adding a posting comment containing a tag (see below)
|
||
like \f[V]date:DATE\f[R].
|
||
This is probably the best way to control posting dates precisely.
|
||
Eg in this example the expense should appear in May reports, and the
|
||
deduction from checking should be reported on 6/1 for easy bank
|
||
reconciliation:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2015/5/30
|
||
expenses:food $10 ; food purchased on saturday 5/30
|
||
assets:checking ; bank cleared it on monday, date:6/1
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f t.j register food
|
||
2015-05-30 expenses:food $10 $10
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f t.j register checking
|
||
2015-06-01 assets:checking $-10 $-10
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
DATE should be a simple date; if the year is not specified it will use
|
||
the year of the transaction\[aq]s date.
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
The \f[V]date:\f[R] tag must have a valid simple date value if it is
|
||
present, eg a \f[V]date:\f[R] tag with no value is not allowed.
|
||
.SS Status
|
||
.PP
|
||
Transactions, or individual postings within a transaction, can have a
|
||
status mark, which is a single character before the transaction
|
||
description or posting account name, separated from it by a space,
|
||
indicating one of three statuses:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
l l.
|
||
T{
|
||
mark \
|
||
T}@T{
|
||
status
|
||
T}
|
||
_
|
||
T{
|
||
\
|
||
T}@T{
|
||
unmarked
|
||
T}
|
||
T{
|
||
\f[V]!\f[R]
|
||
T}@T{
|
||
pending
|
||
T}
|
||
T{
|
||
\f[V]*\f[R]
|
||
T}@T{
|
||
cleared
|
||
T}
|
||
.TE
|
||
.PP
|
||
When reporting, you can filter by status with the
|
||
\f[V]-U/--unmarked\f[R], \f[V]-P/--pending\f[R], and
|
||
\f[V]-C/--cleared\f[R] flags; or the \f[V]status:\f[R],
|
||
\f[V]status:!\f[R], and \f[V]status:*\f[R] queries; or the U, P, C keys
|
||
in hledger-ui.
|
||
.PP
|
||
Note, in Ledger and in older versions of hledger, the \[dq]unmarked\[dq]
|
||
state is called \[dq]uncleared\[dq].
|
||
As of hledger 1.3 we have renamed it to unmarked for clarity.
|
||
.PP
|
||
To replicate Ledger and old hledger\[aq]s behaviour of also matching
|
||
pending, combine -U and -P.
|
||
.PP
|
||
Status marks are optional, but can be helpful eg for reconciling with
|
||
real-world accounts.
|
||
Some editor modes provide highlighting and shortcuts for working with
|
||
status.
|
||
Eg in Emacs ledger-mode, you can toggle transaction status with C-c C-e,
|
||
or posting status with C-c C-c.
|
||
.PP
|
||
What \[dq]uncleared\[dq], \[dq]pending\[dq], and \[dq]cleared\[dq]
|
||
actually mean is up to you.
|
||
Here\[aq]s one suggestion:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(9.7n) lw(60.3n).
|
||
T{
|
||
status
|
||
T}@T{
|
||
meaning
|
||
T}
|
||
_
|
||
T{
|
||
uncleared
|
||
T}@T{
|
||
recorded but not yet reconciled; needs review
|
||
T}
|
||
T{
|
||
pending
|
||
T}@T{
|
||
tentatively reconciled (if needed, eg during a big reconciliation)
|
||
T}
|
||
T{
|
||
cleared
|
||
T}@T{
|
||
complete, reconciled as far as possible, and considered correct
|
||
T}
|
||
.TE
|
||
.PP
|
||
With this scheme, you would use \f[V]-PC\f[R] to see the current balance
|
||
at your bank, \f[V]-U\f[R] to see things which will probably hit your
|
||
bank soon (like uncashed checks), and no flags to see the most
|
||
up-to-date state of your finances.
|
||
.SS Code
|
||
.PP
|
||
After the status mark, but before the description, you can optionally
|
||
write a transaction \[dq]code\[dq], enclosed in parentheses.
|
||
This is a good place to record a check number, or some other important
|
||
transaction id or reference number.
|
||
.SS Description
|
||
.PP
|
||
A transaction\[aq]s description is the rest of the line following the
|
||
date and status mark (or until a comment begins).
|
||
Sometimes called the \[dq]narration\[dq] in traditional bookkeeping, it
|
||
can be used for whatever you wish, or left blank.
|
||
Transaction descriptions can be queried, unlike comments.
|
||
.SS Payee and note
|
||
.PP
|
||
You can optionally include a \f[V]|\f[R] (pipe) character in
|
||
descriptions to subdivide the description into separate fields for
|
||
payee/payer name on the left (up to the first \f[V]|\f[R]) and an
|
||
additional note field on the right (after the first \f[V]|\f[R]).
|
||
This may be worthwhile if you need to do more precise querying and
|
||
pivoting by payee or by note.
|
||
.SS Transaction comments
|
||
.PP
|
||
Text following \f[V];\f[R], after a transaction description, and/or on
|
||
indented lines immediately below it, form comments for that transaction.
|
||
They are reproduced by \f[V]print\f[R] but otherwise ignored, except
|
||
they may contain tags, which are not ignored.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2012-01-01 something ; a transaction comment
|
||
; a second line of transaction comment
|
||
expenses 1
|
||
assets
|
||
\f[R]
|
||
.fi
|
||
.SS Postings
|
||
.PP
|
||
A posting is an addition of some amount to, or removal of some amount
|
||
from, an account.
|
||
Each posting line begins with at least one space or tab (2 or 4 spaces
|
||
is common), followed by:
|
||
.IP \[bu] 2
|
||
(optional) a status character (empty, \f[V]!\f[R], or \f[V]*\f[R]),
|
||
followed by a space
|
||
.IP \[bu] 2
|
||
(required) an account name (any text, optionally containing \f[B]single
|
||
spaces\f[R], until end of line or a double space)
|
||
.IP \[bu] 2
|
||
(optional) \f[B]two or more spaces\f[R] or tabs followed by an amount.
|
||
.PP
|
||
Positive amounts are being added to the account, negative amounts are
|
||
being removed.
|
||
.PP
|
||
The amounts within a transaction must always sum up to zero.
|
||
As a convenience, one amount may be left blank; it will be inferred so
|
||
as to balance the transaction.
|
||
.PP
|
||
Be sure to note the unusual two-space delimiter between account name and
|
||
amount.
|
||
This makes it easy to write account names containing spaces.
|
||
But if you accidentally leave only one space (or tab) before the amount,
|
||
the amount will be considered part of the account name.
|
||
.SS Account names
|
||
.PP
|
||
Accounts are the main way of categorising things in hledger.
|
||
As in Double Entry Bookkeeping, they can represent real world accounts
|
||
(such as a bank account), or more abstract categories such as \[dq]money
|
||
borrowed from Frank\[dq] or \[dq]money spent on electricity\[dq].
|
||
.PP
|
||
You can use any account names you like, but we usually start with the
|
||
traditional accounting categories, which in english are
|
||
\f[V]assets\f[R], \f[V]liabilities\f[R], \f[V]equity\f[R],
|
||
\f[V]revenues\f[R], \f[V]expenses\f[R].
|
||
(You might see these referred to as A, L, E, R, X for short.)
|
||
.PP
|
||
For more precise reporting, we usually divide the top level accounts
|
||
into more detailed subaccounts, by writing a full colon between account
|
||
name parts.
|
||
For example, from the account names \f[V]assets:bank:checking\f[R] and
|
||
\f[V]expenses:food\f[R], hledger will infer this hierarchy of five
|
||
accounts:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
assets
|
||
assets:bank
|
||
assets:bank:checking
|
||
expenses
|
||
expenses:food
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Shown as an outline, the hierarchical tree structure is more clear:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
assets
|
||
bank
|
||
checking
|
||
expenses
|
||
food
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
hledger reports can summarise the account tree to any depth, so you can
|
||
go as deep as you like with subcategories, but keeping your account
|
||
names relatively simple may be best when starting out.
|
||
.PP
|
||
Account names may be capitalised or not; they may contain letters,
|
||
numbers, symbols, or single spaces.
|
||
Note, when an account name and an amount are written on the same line,
|
||
they must be separated by \f[B]two or more spaces\f[R] (or tabs).
|
||
.PP
|
||
Parentheses or brackets enclosing the full account name indicate virtual
|
||
postings, described below.
|
||
Parentheses or brackets internal to the account name have no special
|
||
meaning.
|
||
.PP
|
||
Account names can be altered temporarily or permanently by account
|
||
aliases.
|
||
.SS Amounts
|
||
.PP
|
||
After the account name, there is usually an amount.
|
||
(Important: between account name and amount, there must be \f[B]two or
|
||
more spaces\f[R].)
|
||
.PP
|
||
hledger\[aq]s amount format is flexible, supporting several
|
||
international formats.
|
||
Here are some examples.
|
||
Amounts have a number (the \[dq]quantity\[dq]):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\&..and usually a currency symbol or commodity name (more on this
|
||
below), to the left or right of the quantity, with or without a
|
||
separating space:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$1
|
||
4000 AAPL
|
||
3 \[dq]green apples\[dq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Amounts can be preceded by a minus sign (or a plus sign, though plus is
|
||
the default), The sign can be written before or after a left-side
|
||
commodity symbol:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
-$1
|
||
$-1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
One or more spaces between the sign and the number are acceptable when
|
||
parsing (but they won\[aq]t be displayed in output):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
+ $1
|
||
$- 1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Scientific E notation is allowed:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
1E-6
|
||
EUR 1E3
|
||
\f[R]
|
||
.fi
|
||
.SS Decimal marks, digit group marks
|
||
.PP
|
||
A \f[I]decimal mark\f[R] can be written as a period or a comma:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
1.23
|
||
1,23456780000009
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
In the integer part of the quantity (left of the decimal mark), groups
|
||
of digits can optionally be separated by a \f[I]digit group mark\f[R] -
|
||
a space, comma, or period (different from the decimal mark):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$1,000,000.00
|
||
EUR 2.000.000,00
|
||
INR 9,99,99,999.00
|
||
1 000 000.9455
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note, a number containing a single digit group mark and no decimal mark
|
||
is ambiguous.
|
||
Are these digit group marks or decimal marks ?
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
1,000
|
||
1.000
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If you don\[aq]t tell it otherwise, hledger will assume both of the
|
||
above are decimal marks, parsing both numbers as 1.
|
||
.PP
|
||
To prevent confusing parsing mistakes and undetected typos, especially
|
||
if your data contains digit group marks (eg, thousands separators), we
|
||
recommend explicitly declaring the decimal mark character in each
|
||
journal file, using a directive at the top of the file.
|
||
The \f[V]decimal-mark\f[R] directive is best, otherwise
|
||
\f[V]commodity\f[R] directives will also work.
|
||
These are described below.
|
||
.SS Commodity
|
||
.PP
|
||
Amounts in hledger have both a \[dq]quantity\[dq], which is a signed
|
||
decimal number, and a \[dq]commodity\[dq], which is a currency symbol,
|
||
stock ticker, or any word or phrase describing something you are
|
||
tracking.
|
||
.PP
|
||
If the commodity name contains non-letters (spaces, numbers, or
|
||
punctuation), you must always write it inside double quotes
|
||
(\f[V]\[dq]green apples\[dq]\f[R], \f[V]\[dq]ABC123\[dq]\f[R]).
|
||
.PP
|
||
If you write just a bare number, that too will have a commodity, with
|
||
name \f[V]\[dq]\[dq]\f[R]; we call that the \[dq]no-symbol
|
||
commodity\[dq].
|
||
.PP
|
||
Actually, hledger combines these single-commodity amounts into more
|
||
powerful multi-commodity amounts, which are what it works with most of
|
||
the time.
|
||
A multi-commodity amount could be, eg:
|
||
\f[V]1 USD, 2 EUR, 3.456 TSLA\f[R].
|
||
In practice, you will only see multi-commodity amounts in hledger\[aq]s
|
||
output; you can\[aq]t write them directly in the journal file.
|
||
.PP
|
||
(If you are writing scripts or working with hledger\[aq]s internals,
|
||
these are the \f[V]Amount\f[R] and \f[V]MixedAmount\f[R] types.)
|
||
.SS Directives influencing number parsing and display
|
||
.PP
|
||
You can add \f[V]decimal-mark\f[R] and \f[V]commodity\f[R] directives to
|
||
the journal, to declare and control these things more explicitly and
|
||
precisely.
|
||
These are described below, but here\[aq]s a quick example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# the decimal mark character used by all amounts in this file (all commodities)
|
||
decimal-mark .
|
||
|
||
# display styles for the $, EUR, INR and no-symbol commodities:
|
||
commodity $1,000.00
|
||
commodity EUR 1.000,00
|
||
commodity INR 9,99,99,999.00
|
||
commodity 1 000 000.9455
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
.SS Commodity display style
|
||
.PP
|
||
For the amounts in each commodity, hledger chooses a consistent display
|
||
style to use in most reports.
|
||
(Exceptions: price amounts, and all amounts displayed by the
|
||
\f[V]print\f[R] command, are displayed with all of their decimal digits
|
||
visible.)
|
||
.PP
|
||
A commodity\[aq]s display style is inferred as follows.
|
||
.PP
|
||
First, if a default commodity is declared with \f[V]D\f[R], this
|
||
commodity and its style is applied to any no-symbol amounts in the
|
||
journal.
|
||
.PP
|
||
Then each commodity\[aq]s style is inferred from one of the following,
|
||
in order of preference:
|
||
.IP \[bu] 2
|
||
The commodity directive for that commodity (including the no-symbol
|
||
commodity), if any.
|
||
.IP \[bu] 2
|
||
The amounts in that commodity seen in the journal\[aq]s transactions.
|
||
(Posting amounts only; prices and periodic or auto rules are ignored,
|
||
currently.)
|
||
.IP \[bu] 2
|
||
The built-in fallback style, which looks like this: \f[V]$1000.00\f[R].
|
||
(Symbol on the left, period decimal mark, two decimal places.)
|
||
.PP
|
||
A style is inferred from journal amounts as follows:
|
||
.IP \[bu] 2
|
||
Use the general style (decimal mark, symbol placement) of the first
|
||
amount
|
||
.IP \[bu] 2
|
||
Use the first-seen digit group style (digit group mark, digit group
|
||
sizes), if any
|
||
.IP \[bu] 2
|
||
Use the maximum number of decimal places of all.
|
||
.PP
|
||
Cost amounts don\[aq]t affect the commodity display style directly, but
|
||
occasionally they can do so indirectly (eg when a posting\[aq]s amount
|
||
is inferred using a cost).
|
||
If you find this causing problems, use a commodity directive to fix the
|
||
display style.
|
||
.PP
|
||
To summarise: each commodity\[aq]s amounts will be normalised to (a) the
|
||
style declared by a \f[V]commodity\f[R] directive, or (b) the style of
|
||
the first posting amount in the journal, with the first-seen digit group
|
||
style and the maximum-seen number of decimal places.
|
||
So if your reports are showing amounts in a way you don\[aq]t like, eg
|
||
with too many decimal places, use a commodity directive.
|
||
Some examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# declare euro, dollar, bitcoin and no-symbol commodities and set their
|
||
# input number formats and output display styles:
|
||
commodity EUR 1.000,
|
||
commodity $1000.00
|
||
commodity 1000.00000000 BTC
|
||
commodity 1 000.
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The inferred commodity style can be overridden by supplying a command
|
||
line option.
|
||
.SS Rounding
|
||
.PP
|
||
Amounts are stored internally as decimal numbers with up to 255 decimal
|
||
places, and displayed with the number of decimal places specified by the
|
||
commodity display style.
|
||
Note, hledger uses banker\[aq]s rounding: it rounds to the nearest even
|
||
number, eg 0.5 displayed with zero decimal places is \[dq]0\[dq]).
|
||
.PP
|
||
.SS Costs
|
||
.PP
|
||
After a posting amount, you can note its cost (when buying) or selling
|
||
price (when selling) in another commodity, by writing either
|
||
\f[V]\[at] UNITPRICE\f[R] or \f[V]\[at]\[at] TOTALPRICE\f[R] after it.
|
||
This indicates a conversion transaction, where one commodity is
|
||
exchanged for another.
|
||
.PP
|
||
(You might also see this called \[dq]transaction price\[dq] in hledger
|
||
docs, discussions, or code; that term was directionally neutral and
|
||
reminded that it is a price specific to a transaction, but we now just
|
||
call it \[dq]cost\[dq], with the understanding that the transaction
|
||
could be a purchase or a sale.)
|
||
.PP
|
||
Costs are usually written explicitly with \f[V]\[at]\f[R] or
|
||
\f[V]\[at]\[at]\f[R], but can also be inferred automatically for simple
|
||
multi-commodity transactions.
|
||
Note, if costs are inferred, the order of postings is significant; the
|
||
first posting will have a cost attached, in the commodity of the second.
|
||
.PP
|
||
As an example, here are several ways to record purchases of a foreign
|
||
currency in hledger, using the cost notation either explicitly or
|
||
implicitly:
|
||
.IP "1." 3
|
||
Write the price per unit, as \f[V]\[at] UNITPRICE\f[R] after the amount:
|
||
.RS 4
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2009/1/1
|
||
assets:euros €100 \[at] $1.35 ; one hundred euros purchased at $1.35 each
|
||
assets:dollars ; balancing amount is -$135.00
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP "2." 3
|
||
Write the total price, as \f[V]\[at]\[at] TOTALPRICE\f[R] after the
|
||
amount:
|
||
.RS 4
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2009/1/1
|
||
assets:euros €100 \[at]\[at] $135 ; one hundred euros purchased at $135 for the lot
|
||
assets:dollars
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP "3." 3
|
||
Specify amounts for all postings, using exactly two commodities, and let
|
||
hledger infer the price that balances the transaction.
|
||
Note the effect of posting order: the price is added to first posting,
|
||
making it \f[V]€100 \[at]\[at] $135\f[R], as in example 2:
|
||
.RS 4
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2009/1/1
|
||
assets:euros €100 ; one hundred euros purchased
|
||
assets:dollars $-135 ; for $135
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.PP
|
||
Amounts can be converted to cost at report time using the
|
||
\f[V]-B/--cost\f[R] flag; this is discussed more in the ˜COST REPORTING
|
||
section.
|
||
.PP
|
||
Note that the cost normally should be a positive amount, though it\[aq]s
|
||
not required to be.
|
||
This can be a little confusing, see discussion at --infer-market-prices:
|
||
market prices from transactions.
|
||
.SS Other cost/lot notations
|
||
.PP
|
||
A slight digression for Ledger and Beancount users.
|
||
Ledger has a number of cost/lot-related notations:
|
||
.IP \[bu] 2
|
||
\f[V]\[at] UNITCOST\f[R] and \f[V]\[at]\[at] TOTALCOST\f[R]
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
expresses a conversion rate, as in hledger
|
||
.IP \[bu] 2
|
||
when buying, also creates a lot than can be selected at selling time
|
||
.RE
|
||
.IP \[bu] 2
|
||
\f[V](\[at]) UNITCOST\f[R] and \f[V](\[at]\[at]) TOTALCOST\f[R] (virtual
|
||
cost)
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
like the above, but also means \[dq]this cost was exceptional, don\[aq]t
|
||
use it when inferring market prices\[dq].
|
||
.RE
|
||
.PP
|
||
Currently, hledger treats the above like \f[V]\[at]\f[R] and
|
||
\f[V]\[at]\[at]\f[R]; the parentheses are ignored.
|
||
.IP \[bu] 2
|
||
\f[V]{=FIXEDUNITCOST}\f[R] and \f[V]{{=FIXEDTOTALCOST}}\f[R] (fixed
|
||
price)
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
when buying, means \[dq]this cost is also the fixed price, don\[aq]t let
|
||
it fluctuate in value reports\[dq]
|
||
.RE
|
||
.IP \[bu] 2
|
||
\f[V]{UNITCOST}\f[R] and \f[V]{{TOTALCOST}}\f[R] (lot price)
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
can be used identically to \f[V]\[at] UNITCOST\f[R] and
|
||
\f[V]\[at]\[at] TOTALCOST\f[R], also creates a lot
|
||
.IP \[bu] 2
|
||
when selling, combined with \f[V]\[at] ...\f[R], specifies an investment
|
||
lot by its cost basis; does not check if that lot is present
|
||
.RE
|
||
.IP \[bu] 2
|
||
and related: \f[V][YYYY/MM/DD]\f[R] (lot date)
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
when buying, attaches this acquisition date to the lot
|
||
.IP \[bu] 2
|
||
when selling, selects a lot by its acquisition date
|
||
.RE
|
||
.IP \[bu] 2
|
||
\f[V](SOME TEXT)\f[R] (lot note)
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
when buying, attaches this note to the lot
|
||
.IP \[bu] 2
|
||
when selling, selects a lot by its note
|
||
.RE
|
||
.PP
|
||
Currently, hledger accepts any or all of the above in any order after
|
||
the posting amount, but ignores them.
|
||
(This can break transaction balancing.)
|
||
.PP
|
||
For Beancount users, the notation and behaviour is different:
|
||
.IP \[bu] 2
|
||
\f[V]\[at] UNITCOST\f[R] and \f[V]\[at]\[at] TOTALCOST\f[R]
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
expresses a cost without creating a lot, as in hledger
|
||
.IP \[bu] 2
|
||
when buying (augmenting) or selling (reducing) a lot, combined with
|
||
\f[V]{...}\f[R]: documents the cost/selling price (not used for
|
||
transaction balancing)
|
||
.RE
|
||
.IP \[bu] 2
|
||
\f[V]{UNITCOST}\f[R] and \f[V]{{TOTALCOST}}\f[R]
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
when buying (augmenting), expresses the cost for transaction balancing,
|
||
and also creates a lot with this cost basis attached
|
||
.IP \[bu] 2
|
||
when selling (reducing),
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
selects a lot by its cost basis
|
||
.IP \[bu] 2
|
||
raises an error if that lot is not present or can not be selected
|
||
unambiguously (depending on booking method configured)
|
||
.IP \[bu] 2
|
||
expresses the selling price for transaction balancing
|
||
.RE
|
||
.RE
|
||
.PP
|
||
Currently, hledger accepts the
|
||
\f[V]{UNITCOST}\f[R]/\f[V]{{TOTALCOST}}\f[R] notation but ignores it.
|
||
.IP \[bu] 2
|
||
variations: \f[V]{}\f[R], \f[V]{YYYY-MM-DD}\f[R],
|
||
\f[V]{\[dq]LABEL\[dq]}\f[R], \f[V]{UNITCOST, \[dq]LABEL\[dq]}\f[R],
|
||
\f[V]{UNITCOST, YYYY-MM-DD, \[dq]LABEL\[dq]}\f[R] etc.
|
||
.PP
|
||
Currently, hledger rejects these.
|
||
.SS Balance assertions
|
||
.PP
|
||
hledger supports Ledger-style balance assertions in journal files.
|
||
These look like, for example, \f[V]= EXPECTEDBALANCE\f[R] following a
|
||
posting\[aq]s amount.
|
||
Eg here we assert the expected dollar balance in accounts a and b after
|
||
each posting:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2013/1/1
|
||
a $1 =$1
|
||
b =$-1
|
||
|
||
2013/1/2
|
||
a $1 =$2
|
||
b $-1 =$-2
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
After reading a journal file, hledger will check all balance assertions
|
||
and report an error if any of them fail.
|
||
Balance assertions can protect you from, eg, inadvertently disrupting
|
||
reconciled balances while cleaning up old entries.
|
||
You can disable them temporarily with the
|
||
\f[V]-I/--ignore-assertions\f[R] flag, which can be useful for
|
||
troubleshooting or for reading Ledger files.
|
||
(Note: this flag currently does not disable balance assignments,
|
||
described below).
|
||
.SS Assertions and ordering
|
||
.PP
|
||
hledger sorts an account\[aq]s postings and assertions first by date and
|
||
then (for postings on the same day) by parse order.
|
||
Note this is different from Ledger, which sorts assertions only by parse
|
||
order.
|
||
(Also, Ledger assertions do not see the accumulated effect of repeated
|
||
postings to the same account within a transaction.)
|
||
.PP
|
||
So, hledger balance assertions keep working if you reorder
|
||
differently-dated transactions within the journal.
|
||
But if you reorder same-dated transactions or postings, assertions might
|
||
break and require updating.
|
||
This order dependence does bring an advantage: precise control over the
|
||
order of postings and assertions within a day, so you can assert
|
||
intra-day balances.
|
||
.SS Assertions and multiple included files
|
||
.PP
|
||
Multiple files included with the \f[V]include\f[R] directive are
|
||
processed as if concatenated into one file, preserving their order and
|
||
the posting order within each file.
|
||
It means that balance assertions in later files will see balance from
|
||
earlier files.
|
||
.PP
|
||
And if you have multiple postings to an account on the same day, split
|
||
across multiple files, and you want to assert the account\[aq]s balance
|
||
on that day, you\[aq]ll need to put the assertion in the right file -
|
||
the last one in the sequence, probably.
|
||
.SS Assertions and multiple -f files
|
||
.PP
|
||
Unlike \f[V]include\f[R], when multiple files are specified on the
|
||
command line with multiple \f[V]-f/--file\f[R] options, balance
|
||
assertions will not see balance from earlier files.
|
||
This can be useful when you do not want problems in earlier files to
|
||
disrupt valid assertions in later files.
|
||
.PP
|
||
If you do want assertions to see balance from earlier files, use
|
||
\f[V]include\f[R], or concatenate the files temporarily.
|
||
.SS Assertions and commodities
|
||
.PP
|
||
The asserted balance must be a simple single-commodity amount, and in
|
||
fact the assertion checks only this commodity\[aq]s balance within the
|
||
(possibly multi-commodity) account balance.
|
||
This is how assertions work in Ledger also.
|
||
We could call this a \[dq]partial\[dq] balance assertion.
|
||
.PP
|
||
To assert the balance of more than one commodity in an account, you can
|
||
write multiple postings, each asserting one commodity\[aq]s balance.
|
||
.PP
|
||
You can make a stronger \[dq]total\[dq] balance assertion by writing a
|
||
double equals sign (\f[V]== EXPECTEDBALANCE\f[R]).
|
||
This asserts that there are no other commodities in the account besides
|
||
the asserted one (or at least, that their balance is 0).
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2013/1/1
|
||
a $1
|
||
a 1€
|
||
b $-1
|
||
c -1€
|
||
|
||
2013/1/2 ; These assertions succeed
|
||
a 0 = $1
|
||
a 0 = 1€
|
||
b 0 == $-1
|
||
c 0 == -1€
|
||
|
||
2013/1/3 ; This assertion fails as \[aq]a\[aq] also contains 1€
|
||
a 0 == $1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
It\[aq]s not yet possible to make a complete assertion about a balance
|
||
that has multiple commodities.
|
||
One workaround is to isolate each commodity into its own subaccount:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2013/1/1
|
||
a:usd $1
|
||
a:euro 1€
|
||
b
|
||
|
||
2013/1/2
|
||
a 0 == 0
|
||
a:usd 0 == $1
|
||
a:euro 0 == 1€
|
||
\f[R]
|
||
.fi
|
||
.SS Assertions and prices
|
||
.PP
|
||
Balance assertions ignore costs, and should normally be written without
|
||
one:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2019/1/1
|
||
(a) $1 \[at] €1 = $1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
We do allow prices to be written there, however, and print shows them,
|
||
even though they don\[aq]t affect whether the assertion passes or fails.
|
||
This is for backward compatibility (hledger\[aq]s close command used to
|
||
generate balance assertions with prices), and because balance
|
||
\f[I]assignments\f[R] do use them (see below).
|
||
.SS Assertions and subaccounts
|
||
.PP
|
||
The balance assertions above (\f[V]=\f[R] and \f[V]==\f[R]) do not count
|
||
the balance from subaccounts; they check the account\[aq]s exclusive
|
||
balance only.
|
||
You can assert the balance including subaccounts by writing \f[V]=*\f[R]
|
||
or \f[V]==*\f[R], eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2019/1/1
|
||
equity:opening balances
|
||
checking:a 5
|
||
checking:b 5
|
||
checking 1 ==* 11
|
||
\f[R]
|
||
.fi
|
||
.SS Assertions and virtual postings
|
||
.PP
|
||
Balance assertions always consider both real and virtual postings; they
|
||
are not affected by the \f[V]--real/-R\f[R] flag or \f[V]real:\f[R]
|
||
query.
|
||
.SS Assertions and auto postings
|
||
.PP
|
||
Balance assertions \f[I]are\f[R] affected by the \f[V]--auto\f[R] flag,
|
||
which generates auto postings, which can alter account balances.
|
||
Because auto postings are optional in hledger, accounts affected by them
|
||
effectively have two balances.
|
||
But balance assertions can only test one or the other of these.
|
||
So to avoid making fragile assertions, either:
|
||
.IP \[bu] 2
|
||
assert the balance calculated with \f[V]--auto\f[R], and always use
|
||
\f[V]--auto\f[R] with that file
|
||
.IP \[bu] 2
|
||
or assert the balance calculated without \f[V]--auto\f[R], and never use
|
||
\f[V]--auto\f[R] with that file
|
||
.IP \[bu] 2
|
||
or avoid balance assertions on accounts affected by auto postings (or
|
||
avoid auto postings entirely).
|
||
.SS Assertions and precision
|
||
.PP
|
||
Balance assertions compare the exactly calculated amounts, which are not
|
||
always what is shown by reports.
|
||
Eg a commodity directive may limit the display precision, but this will
|
||
not affect balance assertions.
|
||
Balance assertion failure messages show exact amounts.
|
||
.SS Posting comments
|
||
.PP
|
||
Text following \f[V];\f[R], at the end of a posting line, and/or on
|
||
indented lines immediately below it, form comments for that posting.
|
||
They are reproduced by \f[V]print\f[R] but otherwise ignored, except
|
||
they may contain tags, which are not ignored.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2012-01-01
|
||
expenses 1 ; a comment for posting 1
|
||
assets
|
||
; a comment for posting 2
|
||
; a second comment line for posting 2
|
||
\f[R]
|
||
.fi
|
||
.SS Tags
|
||
.PP
|
||
Tags are a way to add extra labels or labelled data to transactions,
|
||
postings, or accounts, which you can then search or pivot on.
|
||
.PP
|
||
They are written as a word (optionally hyphenated) immediately followed
|
||
by a full colon, in a transaction or posting or account directive\[aq]s
|
||
comment.
|
||
(This is an exception to the usual rule that things in comments are
|
||
ignored.)
|
||
Eg, here four different tags are recorded: one on the checking account,
|
||
two on the transaction, and one on the expenses posting:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
account assets:checking ; accounttag:
|
||
|
||
2017/1/16 bought groceries ; transactiontag-1:
|
||
; transactiontag-2:
|
||
assets:checking $-1
|
||
expenses:food $1 ; postingtag:
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Postings also inherit tags from their transaction and their account.
|
||
And transactions also acquire tags from their postings (and
|
||
postings\[aq] accounts).
|
||
So in the example above, the expenses posting effectively has all four
|
||
tags (by inheriting from account and transaction), and the transaction
|
||
also has all four tags (by acquiring from the expenses posting).
|
||
.PP
|
||
You can list tag names with \f[V]hledger tags [NAMEREGEX]\f[R], or match
|
||
by tag name with a \f[V]tag:NAMEREGEX\f[R] query.
|
||
.SS Tag values
|
||
.PP
|
||
Tags can have a value, which is any text after the colon up until a
|
||
comma or end of line (with surrounding whitespace removed).
|
||
Note this means that hledger tag values can not contain commas.
|
||
Eg in the following posting, the three tags\[aq] values are \[dq]value
|
||
1\[dq], \[dq]value 2\[dq], and \[dq]\[dq] (empty) respectively:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note that tags can be repeated, and are additive rather than overriding:
|
||
when the same tag name is seen again with a new value, the new
|
||
name:value pair is added to the tags.
|
||
(It is not possible to override a tag\[aq]s value or remove a tag.)
|
||
.PP
|
||
You can list a tag\[aq]s values with
|
||
\f[V]hledger tags TAGNAME --values\f[R], or match by tag value with a
|
||
\f[V]tag:NAMEREGEX=VALUEREGEX\f[R] query.
|
||
.SS Directives
|
||
.PP
|
||
Besides transactions, there is something else you can put in a
|
||
\f[V]journal\f[R] file: directives.
|
||
These are declarations, beginning with a keyword, that modify
|
||
hledger\[aq]s behaviour.
|
||
Some directives can have more specific subdirectives, indented below
|
||
them.
|
||
hledger\[aq]s directives are similar to Ledger\[aq]s in many cases, but
|
||
there are also many differences.
|
||
Directives are not required, but can be useful.
|
||
Here are the main directives:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(39.7n) lw(30.3n).
|
||
T{
|
||
purpose
|
||
T}@T{
|
||
directive
|
||
T}
|
||
_
|
||
T{
|
||
\f[B]READING DATA:\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
Rewrite account names
|
||
T}@T{
|
||
\f[V]alias\f[R]
|
||
T}
|
||
T{
|
||
Comment out sections of the file
|
||
T}@T{
|
||
\f[V]comment\f[R]
|
||
T}
|
||
T{
|
||
Declare file\[aq]s decimal mark, to help parse amounts accurately
|
||
T}@T{
|
||
\f[V]decimal-mark\f[R]
|
||
T}
|
||
T{
|
||
Include other data files
|
||
T}@T{
|
||
\f[V]include\f[R]
|
||
T}
|
||
T{
|
||
\f[B]GENERATING DATA:\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
Generate recurring transactions or budget goals
|
||
T}@T{
|
||
\f[V]\[ti]\f[R]
|
||
T}
|
||
T{
|
||
Generate extra postings on existing transactions
|
||
T}@T{
|
||
\f[V]=\f[R]
|
||
T}
|
||
T{
|
||
\f[B]CHECKING FOR ERRORS:\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
Define valid entities to provide more error checking
|
||
T}@T{
|
||
\f[V]account\f[R], \f[V]commodity\f[R], \f[V]payee\f[R], \f[V]tag\f[R]
|
||
T}
|
||
T{
|
||
\f[B]REPORTING:\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
Declare accounts\[aq] type and display order
|
||
T}@T{
|
||
\f[V]account\f[R]
|
||
T}
|
||
T{
|
||
Declare commodity display styles
|
||
T}@T{
|
||
\f[V]commodity\f[R]
|
||
T}
|
||
T{
|
||
Declare market prices
|
||
T}@T{
|
||
\f[V]P\f[R]
|
||
T}
|
||
.TE
|
||
.SS Directives and multiple files
|
||
.PP
|
||
Directives vary in their scope, ie which journal entries and which input
|
||
files they affect.
|
||
Most often, a directive will affect the following entries and included
|
||
files if any, until the end of the current file - and no further.
|
||
You might find this inconvenient!
|
||
For example, \f[V]alias\f[R] directives do not affect parent or sibling
|
||
files.
|
||
But there are usually workarounds; for example, put \f[V]alias\f[R]
|
||
directives in your top-most file, before including other files.
|
||
.PP
|
||
The restriction, though it may be annoying at first, is in a good cause;
|
||
it allows reports to be stable and deterministic, independent of the
|
||
order of input.
|
||
Without it, reports could show different numbers depending on the order
|
||
of -f options, or the positions of include directives in your files.
|
||
.SS Directive effects
|
||
.PP
|
||
Here are all hledger\[aq]s directives, with their effects and scope
|
||
summarised - nine main directives, plus four others which we consider
|
||
non-essential:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(3.5n) lw(64.1n) lw(2.4n).
|
||
T{
|
||
directive
|
||
T}@T{
|
||
what it does
|
||
T}@T{
|
||
ends at file end?
|
||
T}
|
||
_
|
||
T{
|
||
\f[B]\f[VB]account\f[B]\f[R]
|
||
T}@T{
|
||
Declares an account, for checking all entries in all files; and its
|
||
display order and type.
|
||
Subdirectives: any text, ignored.
|
||
T}@T{
|
||
N
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]alias\f[B]\f[R]
|
||
T}@T{
|
||
Rewrites account names, in following entries until end of current file
|
||
or \f[V]end aliases\f[R].
|
||
Command line equivalent: \f[V]--alias\f[R]
|
||
T}@T{
|
||
Y
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]comment\f[B]\f[R]
|
||
T}@T{
|
||
Ignores part of the journal file, until end of current file or
|
||
\f[V]end comment\f[R].
|
||
T}@T{
|
||
Y
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]commodity\f[B]\f[R]
|
||
T}@T{
|
||
Declares up to four things: 1.
|
||
a commodity symbol, for checking all amounts in all files 2.
|
||
the decimal mark for parsing amounts of this commodity, in the following
|
||
entries until end of current file (if there is no \f[V]decimal-mark\f[R]
|
||
directive) 3.
|
||
and the display style for amounts of this commodity 4.
|
||
which is also the precision to use for balanced-transaction checking in
|
||
this commodity.
|
||
Takes precedence over \f[V]D\f[R].
|
||
Subdirectives: \f[V]format\f[R] (Ledger-compatible syntax).
|
||
Command line equivalent: \f[V]-c/--commodity-style\f[R]
|
||
T}@T{
|
||
N,Y,N,N
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]decimal-mark\f[B]\f[R]
|
||
T}@T{
|
||
Declares the decimal mark, for parsing amounts of all commodities in
|
||
following entries until next \f[V]decimal-mark\f[R] or end of current
|
||
file.
|
||
Included files can override.
|
||
Takes precedence over \f[V]commodity\f[R] and \f[V]D\f[R].
|
||
T}@T{
|
||
Y
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]include\f[B]\f[R]
|
||
T}@T{
|
||
Includes entries and directives from another file, as if they were
|
||
written inline.
|
||
Command line alternative: multiple \f[V]-f/--file\f[R]
|
||
T}@T{
|
||
N
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]payee\f[B]\f[R]
|
||
T}@T{
|
||
Declares a payee name, for checking all entries in all files.
|
||
T}@T{
|
||
N
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]P\f[B]\f[R]
|
||
T}@T{
|
||
Declares the market price of a commodity on some date, for value
|
||
reports.
|
||
T}@T{
|
||
N
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]\[ti]\f[B]\f[R] (tilde)
|
||
T}@T{
|
||
Declares a periodic transaction rule that generates future transactions
|
||
with \f[V]--forecast\f[R] and budget goals with
|
||
\f[V]balance --budget\f[R].
|
||
T}@T{
|
||
N
|
||
T}
|
||
T{
|
||
Other syntax:
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]apply account\f[B]\f[R]
|
||
T}@T{
|
||
Prepends a common parent account to all account names, in following
|
||
entries until end of current file or \f[V]end apply account\f[R].
|
||
T}@T{
|
||
Y
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]D\f[B]\f[R]
|
||
T}@T{
|
||
Sets a default commodity to use for no-symbol amounts;and, if there is
|
||
no \f[V]commodity\f[R] directive for this commodity: its decimal mark,
|
||
balancing precision, and display style, as above.
|
||
T}@T{
|
||
Y,Y,N,N
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]Y\f[B]\f[R]
|
||
T}@T{
|
||
Sets a default year to use for any yearless dates, in following entries
|
||
until end of current file.
|
||
T}@T{
|
||
Y
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]=\f[B]\f[R] (equals)
|
||
T}@T{
|
||
Declares an auto posting rule that generates extra postings on matched
|
||
transactions with \f[V]--auto\f[R], in current, parent, and child files
|
||
(but not sibling files, see #1212).
|
||
T}@T{
|
||
partly
|
||
T}
|
||
T{
|
||
\f[B]Other Ledger directives\f[R]
|
||
T}@T{
|
||
Other directives from Ledger\[aq]s file format are accepted but ignored.
|
||
T}@T{
|
||
T}
|
||
.TE
|
||
.SS \f[V]account\f[R] directive
|
||
.PP
|
||
\f[V]account\f[R] directives can be used to declare accounts (ie, the
|
||
places that amounts are transferred from and to).
|
||
Though not required, these declarations can provide several benefits:
|
||
.IP \[bu] 2
|
||
They can document your intended chart of accounts, providing a
|
||
reference.
|
||
.IP \[bu] 2
|
||
In strict mode, they restrict which accounts may be posted to by
|
||
transactions, which helps detect typos.
|
||
.IP \[bu] 2
|
||
They control account display order in reports, allowing non-alphabetic
|
||
sorting (eg Revenues to appear above Expenses).
|
||
.IP \[bu] 2
|
||
They help with account name completion (in hledger add, hledger-web,
|
||
hledger-iadd, ledger-mode, etc.)
|
||
.IP \[bu] 2
|
||
They can store additional account information as comments, or as tags
|
||
which can be used to filter or pivot reports.
|
||
.IP \[bu] 2
|
||
They can help hledger know your accounts\[aq] types (asset, liability,
|
||
equity, revenue, expense), affecting reports like balancesheet and
|
||
incomestatement.
|
||
.PP
|
||
They are written as the word \f[V]account\f[R] followed by a
|
||
hledger-style account name, eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
account assets:bank:checking
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note, however, that accounts declared in account directives are not
|
||
allowed to have surrounding brackets and parentheses, unlike accounts
|
||
used in postings.
|
||
So the following journal will not parse:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
account (assets:bank:checking)
|
||
\f[R]
|
||
.fi
|
||
.SS Account comments
|
||
.PP
|
||
Text following \f[B]two or more spaces\f[R] and \f[V];\f[R] at the end
|
||
of an account directive line, and/or following \f[V];\f[R] on indented
|
||
lines immediately below it, form comments for that account.
|
||
They are ignored except they may contain tags, which are not ignored.
|
||
.PP
|
||
The two-space requirement for same-line account comments is because
|
||
\f[V];\f[R] is allowed in account names.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon
|
||
; next-line comment
|
||
; some tags - type:A, acctnum:12345
|
||
\f[R]
|
||
.fi
|
||
.SS Account subdirectives
|
||
.PP
|
||
Ledger-style indented subdirectives are also accepted, but currently
|
||
ignored:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
account assets:bank:checking
|
||
format subdirective is ignored
|
||
\f[R]
|
||
.fi
|
||
.SS Account error checking
|
||
.PP
|
||
By default, accounts need not be declared; they come into existence when
|
||
a posting references them.
|
||
This is convenient, but it means hledger can\[aq]t warn you when you
|
||
mis-spell an account name in the journal.
|
||
Usually you\[aq]ll find that error later, as an extra account in balance
|
||
reports, or an incorrect balance when reconciling.
|
||
.PP
|
||
In strict mode, enabled with the \f[V]-s\f[R]/\f[V]--strict\f[R] flag,
|
||
hledger will report an error if any transaction uses an account name
|
||
that has not been declared by an account directive.
|
||
Some notes:
|
||
.IP \[bu] 2
|
||
The declaration is case-sensitive; transactions must use the correct
|
||
account name capitalisation.
|
||
.IP \[bu] 2
|
||
The account directive\[aq]s scope is \[dq]whole file and below\[dq] (see
|
||
directives).
|
||
This means it affects all of the current file, and any files it
|
||
includes, but not parent or sibling files.
|
||
The position of account directives within the file does not matter,
|
||
though it\[aq]s usual to put them at the top.
|
||
.IP \[bu] 2
|
||
Accounts can only be declared in \f[V]journal\f[R] files, but will
|
||
affect included files of all types.
|
||
.IP \[bu] 2
|
||
It\[aq]s currently not possible to declare \[dq]all possible
|
||
subaccounts\[dq] with a wildcard; every account posted to must be
|
||
declared.
|
||
.SS Account display order
|
||
.PP
|
||
The order in which account directives are written influences the order
|
||
in which accounts appear in reports, hledger-ui, hledger-web etc.
|
||
By default accounts appear in alphabetical order, but if you add these
|
||
account directives to the journal file:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
account assets
|
||
account liabilities
|
||
account equity
|
||
account revenues
|
||
account expenses
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
those accounts will be displayed in declaration order:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger accounts -1
|
||
assets
|
||
liabilities
|
||
equity
|
||
revenues
|
||
expenses
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Any undeclared accounts are displayed last, in alphabetical order.
|
||
.PP
|
||
Sorting is done at each level of the account tree, within each group of
|
||
sibling accounts under the same parent.
|
||
And currently, this directive:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
account other:zoo
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
would influence the position of \f[V]zoo\f[R] among
|
||
\f[V]other\f[R]\[aq]s subaccounts, but not the position of
|
||
\f[V]other\f[R] among the top-level accounts.
|
||
This means:
|
||
.IP \[bu] 2
|
||
you will sometimes declare parent accounts (eg \f[V]account other\f[R]
|
||
above) that you don\[aq]t intend to post to, just to customize their
|
||
display order
|
||
.IP \[bu] 2
|
||
sibling accounts stay together (you couldn\[aq]t display \f[V]x:y\f[R]
|
||
in between \f[V]a:b\f[R] and \f[V]a:c\f[R]).
|
||
.SS Account types
|
||
.PP
|
||
hledger knows that accounts come in several types: assets, liabilities,
|
||
expenses and so on.
|
||
This enables easy reports like balancesheet and incomestatement, and
|
||
filtering by account type with the \f[V]type:\f[R] query.
|
||
.PP
|
||
As a convenience, hledger will detect these account types automatically
|
||
if you are using common english-language top-level account names
|
||
(described below).
|
||
But generally we recommend you declare types explicitly, by adding a
|
||
\f[V]type:\f[R] tag to your top-level account directives.
|
||
Subaccounts will inherit the type of their parent.
|
||
The tag\[aq]s value should be one of the five main account types:
|
||
.IP \[bu] 2
|
||
\f[V]A\f[R] or \f[V]Asset\f[R] (things you own)
|
||
.IP \[bu] 2
|
||
\f[V]L\f[R] or \f[V]Liability\f[R] (things you owe)
|
||
.IP \[bu] 2
|
||
\f[V]E\f[R] or \f[V]Equity\f[R] (investment/ownership; balanced
|
||
counterpart of assets & liabilities)
|
||
.IP \[bu] 2
|
||
\f[V]R\f[R] or \f[V]Revenue\f[R] (what you received money from, AKA
|
||
income; technically part of Equity)
|
||
.IP \[bu] 2
|
||
\f[V]X\f[R] or \f[V]Expense\f[R] (what you spend money on; technically
|
||
part of Equity)
|
||
.PP
|
||
or, it can be (these are used less often):
|
||
.IP \[bu] 2
|
||
\f[V]C\f[R] or \f[V]Cash\f[R] (a subtype of Asset, indicating liquid
|
||
assets for the cashflow report)
|
||
.IP \[bu] 2
|
||
\f[V]V\f[R] or \f[V]Conversion\f[R] (a subtype of Equity, for
|
||
conversions (see COST REPORTING).)
|
||
.PP
|
||
Here is a typical set of account type declarations:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
account assets ; type: A
|
||
account liabilities ; type: L
|
||
account equity ; type: E
|
||
account revenues ; type: R
|
||
account expenses ; type: X
|
||
|
||
account assets:bank ; type: C
|
||
account assets:cash ; type: C
|
||
|
||
account equity:conversion ; type: V
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Here are some tips for working with account types.
|
||
.IP \[bu] 2
|
||
The rules for inferring types from account names are as follows.
|
||
These are just a convenience that sometimes help new users get going; if
|
||
they don\[aq]t work for you, just ignore them and declare your account
|
||
types.
|
||
See also Regular expressions.
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
If account\[aq]s name contains this (CI) regular expression: | its type is:
|
||
--------------------------------------------------------------------|-------------
|
||
\[ha]assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash
|
||
\[ha]assets?(:|$) | Asset
|
||
\[ha](debts?|liabilit(y|ies))(:|$) | Liability
|
||
\[ha]equity:(trad(e|ing)|conversion)s?(:|$) | Conversion
|
||
\[ha]equity(:|$) | Equity
|
||
\[ha](income|revenue)s?(:|$) | Revenue
|
||
\[ha]expenses?(:|$) | Expense
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP \[bu] 2
|
||
If you declare any account types, it\[aq]s a good idea to declare an
|
||
account for all of the account types, because a mixture of declared and
|
||
name-inferred types can disrupt certain reports.
|
||
.IP \[bu] 2
|
||
Certain uses of account aliases can disrupt account types.
|
||
See Rewriting accounts > Aliases and account types.
|
||
.IP \[bu] 2
|
||
As mentioned above, subaccounts will inherit a type from their parent
|
||
account.
|
||
More precisely, an account\[aq]s type is decided by the first of these
|
||
that exists:
|
||
.RS 2
|
||
.IP "1." 3
|
||
A \f[V]type:\f[R] declaration for this account.
|
||
.IP "2." 3
|
||
A \f[V]type:\f[R] declaration in the parent accounts above it,
|
||
preferring the nearest.
|
||
.IP "3." 3
|
||
An account type inferred from this account\[aq]s name.
|
||
.IP "4." 3
|
||
An account type inferred from a parent account\[aq]s name, preferring
|
||
the nearest parent.
|
||
.IP "5." 3
|
||
Otherwise, it will have no type.
|
||
.RE
|
||
.IP \[bu] 2
|
||
For troubleshooting, you can list accounts and their types with:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.SS \f[V]alias\f[R] directive
|
||
.PP
|
||
You can define account alias rules which rewrite your account names, or
|
||
parts of them, before generating reports.
|
||
This can be useful for:
|
||
.IP \[bu] 2
|
||
expanding shorthand account names to their full form, allowing easier
|
||
data entry and a less verbose journal
|
||
.IP \[bu] 2
|
||
adapting old journals to your current chart of accounts
|
||
.IP \[bu] 2
|
||
experimenting with new account organisations, like a new hierarchy
|
||
.IP \[bu] 2
|
||
combining two accounts into one, eg to see their sum or difference on
|
||
one line
|
||
.IP \[bu] 2
|
||
customising reports
|
||
.PP
|
||
Account aliases also rewrite account names in account directives.
|
||
They do not affect account names being entered via hledger add or
|
||
hledger-web.
|
||
.PP
|
||
Account aliases are very powerful.
|
||
They are generally easy to use correctly, but you can also generate
|
||
invalid account names with them; more on this below.
|
||
.PP
|
||
See also Rewrite account names.
|
||
.SS Basic aliases
|
||
.PP
|
||
To set an account alias, use the \f[V]alias\f[R] directive in your
|
||
journal file.
|
||
This affects all subsequent journal entries in the current file or its
|
||
included files (but note: not sibling or parent files).
|
||
The spaces around the = are optional:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
alias OLD = NEW
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Or, you can use the \f[V]--alias \[aq]OLD=NEW\[aq]\f[R] option on the
|
||
command line.
|
||
This affects all entries.
|
||
It\[aq]s useful for trying out aliases interactively.
|
||
.PP
|
||
OLD and NEW are case sensitive full account names.
|
||
hledger will replace any occurrence of the old account name with the new
|
||
one.
|
||
Subaccounts are also affected.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
alias checking = assets:bank:wells fargo:checking
|
||
; rewrites \[dq]checking\[dq] to \[dq]assets:bank:wells fargo:checking\[dq], or \[dq]checking:a\[dq] to \[dq]assets:bank:wells fargo:checking:a\[dq]
|
||
\f[R]
|
||
.fi
|
||
.SS Regex aliases
|
||
.PP
|
||
There is also a more powerful variant that uses a regular expression,
|
||
indicated by wrapping the pattern in forward slashes.
|
||
(This is the only place where hledger requires forward slashes around a
|
||
regular expression.)
|
||
.PP
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
alias /REGEX/ = REPLACEMENT
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger --alias \[aq]/REGEX/=REPLACEMENT\[aq] ...
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Any part of an account name matched by REGEX will be replaced by
|
||
REPLACEMENT.
|
||
REGEX is case-insensitive as usual.
|
||
.PP
|
||
If you need to match a forward slash, escape it with a backslash, eg
|
||
\f[V]/\[rs]/=:\f[R].
|
||
.PP
|
||
If REGEX contains parenthesised match groups, these can be referenced by
|
||
the usual backslash and number in REPLACEMENT:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
alias /\[ha](.+):bank:([\[ha]:]+):(.*)/ = \[rs]1:\[rs]2 \[rs]3
|
||
; rewrites \[dq]assets:bank:wells fargo:checking\[dq] to \[dq]assets:wells fargo checking\[dq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
REPLACEMENT continues to the end of line (or on command line, to end of
|
||
option argument), so it can contain trailing whitespace.
|
||
.SS Combining aliases
|
||
.PP
|
||
You can define as many aliases as you like, using journal directives
|
||
and/or command line options.
|
||
.PP
|
||
Recursive aliases - where an account name is rewritten by one alias,
|
||
then by another alias, and so on - are allowed.
|
||
Each alias sees the effect of previously applied aliases.
|
||
.PP
|
||
In such cases it can be important to understand which aliases will be
|
||
applied and in which order.
|
||
For (each account name in) each journal entry, we apply:
|
||
.IP "1." 3
|
||
\f[V]alias\f[R] directives preceding the journal entry, most recently
|
||
parsed first (ie, reading upward from the journal entry, bottom to top)
|
||
.IP "2." 3
|
||
\f[V]--alias\f[R] options, in the order they appeared on the command
|
||
line (left to right).
|
||
.PP
|
||
In other words, for (an account name in) a given journal entry:
|
||
.IP \[bu] 2
|
||
the nearest alias declaration before/above the entry is applied first
|
||
.IP \[bu] 2
|
||
the next alias before/above that will be be applied next, and so on
|
||
.IP \[bu] 2
|
||
aliases defined after/below the entry do not affect it.
|
||
.PP
|
||
This gives nearby aliases precedence over distant ones, and helps
|
||
provide semantic stability - aliases will keep working the same way
|
||
independent of which files are being read and in which order.
|
||
.PP
|
||
In case of trouble, adding \f[V]--debug=6\f[R] to the command line will
|
||
show which aliases are being applied when.
|
||
.SS Aliases and multiple files
|
||
.PP
|
||
As explained at Directives and multiple files, \f[V]alias\f[R]
|
||
directives do not affect parent or sibling files.
|
||
Eg in this command,
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
hledger -f a.aliases -f b.journal
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
account aliases defined in a.aliases will not affect b.journal.
|
||
Including the aliases doesn\[aq]t work either:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
include a.aliases
|
||
|
||
2023-01-01 ; not affected by a.aliases
|
||
foo 1
|
||
bar
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This means that account aliases should usually be declared at the start
|
||
of your top-most file, like this:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
alias foo=Foo
|
||
alias bar=Bar
|
||
|
||
2023-01-01 ; affected by aliases above
|
||
foo 1
|
||
bar
|
||
|
||
include c.journal ; also affected
|
||
\f[R]
|
||
.fi
|
||
.SS \f[V]end aliases\f[R] directive
|
||
.PP
|
||
You can clear (forget) all currently defined aliases (seen in the
|
||
journal so far, or defined on the command line) with this directive:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
end aliases
|
||
\f[R]
|
||
.fi
|
||
.SS Aliases can generate bad account names
|
||
.PP
|
||
Be aware that account aliases can produce malformed account names, which
|
||
could cause confusing reports or invalid \f[V]print\f[R] output.
|
||
For example, you could erase all account names:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2021-01-01
|
||
a:aa 1
|
||
b
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --alias \[aq]/.*/=\[aq]
|
||
2021-01-01
|
||
1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The above \f[V]print\f[R] output is not a valid journal.
|
||
Or you could insert an illegal double space, causing \f[V]print\f[R]
|
||
output that would give a different journal when reparsed:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2021-01-01
|
||
old 1
|
||
other
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --alias old=\[dq]new USD\[dq] | hledger -f- print
|
||
2021-01-01
|
||
new USD 1
|
||
other
|
||
\f[R]
|
||
.fi
|
||
.SS Aliases and account types
|
||
.PP
|
||
If an account with a type declaration (see Declaring accounts > Account
|
||
types) is renamed by an alias, normally the account type remains in
|
||
effect.
|
||
.PP
|
||
However, renaming in a way that reshapes the account tree (eg renaming
|
||
parent accounts but not their children, or vice versa) could prevent
|
||
child accounts from inheriting the account type of their parents.
|
||
.PP
|
||
Secondly, if an account\[aq]s type is being inferred from its name,
|
||
renaming it by an alias could prevent or alter that.
|
||
.PP
|
||
If you are using account aliases and the \f[V]type:\f[R] query is not
|
||
matching accounts as you expect, try troubleshooting with the accounts
|
||
command, eg something like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger accounts --alias assets=bassetts type:a
|
||
\f[R]
|
||
.fi
|
||
.SS \f[V]commodity\f[R] directive
|
||
.PP
|
||
You can use \f[V]commodity\f[R] directives to declare your commodities.
|
||
In fact the \f[V]commodity\f[R] directive performs several functions at
|
||
once:
|
||
.IP "1." 3
|
||
It declares commodities which may be used in the journal.
|
||
This can optionally be enforced, providing useful error checking.
|
||
(Cf Commodity error checking)
|
||
.IP "2." 3
|
||
It declares which decimal mark character (period or comma), to expect
|
||
when parsing input - useful to disambiguate international number formats
|
||
in your data.
|
||
Without this, hledger will parse both \f[V]1,000\f[R] and
|
||
\f[V]1.000\f[R] as 1.
|
||
(Cf Amounts)
|
||
.IP "3." 3
|
||
It declares how to render the commodity\[aq]s amounts when displaying
|
||
output - the decimal mark, any digit group marks, the number of decimal
|
||
places, symbol placement and so on.
|
||
(Cf Commodity display style)
|
||
.PP
|
||
You will run into one of the problems solved by commodity directives
|
||
sooner or later, so we recommend using them, for robust and predictable
|
||
parsing and display.
|
||
.PP
|
||
Generally you should put them at the top of your journal file (since for
|
||
function 2, they affect only following amounts, cf #793).
|
||
.PP
|
||
A commodity directive is just the word \f[V]commodity\f[R] followed by a
|
||
sample amount, like this:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
;commodity SAMPLEAMOUNT
|
||
|
||
commodity $1000.00
|
||
commodity 1,000.0000 AAAA ; optional same-line comment
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
It may also be written on multiple lines, and use the \f[V]format\f[R]
|
||
subdirective, as in Ledger.
|
||
Note in this case the commodity symbol appears twice; it must be the
|
||
same in both places:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
;commodity SYMBOL
|
||
; format SAMPLEAMOUNT
|
||
|
||
; display indian rupees with currency name on the left,
|
||
; thousands, lakhs and crores comma-separated,
|
||
; period as decimal point, and two decimal places.
|
||
commodity INR
|
||
format INR 1,00,00,000.00
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Other indented subdirectives are currently ignored.
|
||
.PP
|
||
Remember that if the commodity symbol contains spaces, numbers, or
|
||
punctuation, it must be enclosed in double quotes (cf Commodity).
|
||
.PP
|
||
The amount\[aq]s quantity does not matter; only the format is
|
||
significant.
|
||
It must include a decimal mark - either a period or a comma - followed
|
||
by 0 or more decimal digits.
|
||
.PP
|
||
A few more examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# number formats for $, EUR, INR and the no-symbol commodity:
|
||
commodity $1,000.00
|
||
commodity EUR 1.000,00
|
||
commodity INR 9,99,99,999.0
|
||
commodity 1 000 000.
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note hledger normally uses banker\[aq]s rounding, so 0.5 displayed with
|
||
zero decimal digits is \[dq]0\[dq].
|
||
(More at Commodity display style.)
|
||
.PP
|
||
Even in the presence of commodity directives, the commodity display
|
||
style can still be overridden by supplying a command line option.
|
||
.SS Commodity error checking
|
||
.PP
|
||
In strict mode, enabled with the \f[V]-s\f[R]/\f[V]--strict\f[R] flag,
|
||
hledger will report an error if a commodity symbol is used that has not
|
||
been declared by a \f[V]commodity\f[R] directive.
|
||
This works similarly to account error checking, see the notes there for
|
||
more details.
|
||
.PP
|
||
Note, this disallows amounts without a commodity symbol, because
|
||
currently it\[aq]s not possible (?)
|
||
to declare the \[dq]no-symbol\[dq] commodity with a directive.
|
||
This is one exception for convenience: zero amounts are always allowed
|
||
to have no commodity symbol.
|
||
.SS \f[V]decimal-mark\f[R] directive
|
||
.PP
|
||
You can use a \f[V]decimal-mark\f[R] directive - usually one per file,
|
||
at the top of the file - to declare which character represents a decimal
|
||
mark when parsing amounts in this file.
|
||
It can look like
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
decimal-mark .
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
decimal-mark ,
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This prevents any ambiguity when parsing numbers in the file, so we
|
||
recommend it, especially if the file contains digit group marks (eg
|
||
thousands separators).
|
||
.SS \f[V]include\f[R] directive
|
||
.PP
|
||
You can pull in the content of additional files by writing an include
|
||
directive, like this:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
include FILEPATH
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Only journal files can include, and only journal, timeclock or timedot
|
||
files can be included (not CSV files, currently).
|
||
.PP
|
||
If the file path does not begin with a slash, it is relative to the
|
||
current file\[aq]s folder.
|
||
.PP
|
||
A tilde means home directory, eg: \f[V]include \[ti]/main.journal\f[R].
|
||
.PP
|
||
The path may contain glob patterns to match multiple files, eg:
|
||
\f[V]include *.journal\f[R].
|
||
.PP
|
||
There is limited support for recursive wildcards: \f[V]**/\f[R] (the
|
||
slash is required) matches 0 or more subdirectories.
|
||
It\[aq]s not super convenient since you have to avoid include cycles and
|
||
including directories, but this can be done, eg:
|
||
\f[V]include */**/*.journal\f[R].
|
||
.PP
|
||
The path may also be prefixed to force a specific file format,
|
||
overriding the file extension (as described in hledger.1 -> Input
|
||
files): \f[V]include timedot:\[ti]/notes/2023*.md\f[R].
|
||
.SS \f[V]P\f[R] directive
|
||
.PP
|
||
The \f[V]P\f[R] directive declares a market price, which is a conversion
|
||
rate between two commodities on a certain date.
|
||
This allows value reports to convert amounts of one commodity to their
|
||
value in another, on or after that date.
|
||
These prices are often obtained from a stock exchange, cryptocurrency
|
||
exchange, the or foreign exchange market.
|
||
.PP
|
||
The format is:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
P DATE COMMODITY1SYMBOL COMMODITY2AMOUNT
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
DATE is a simple date, COMMODITY1SYMBOL is the symbol of the commodity
|
||
being priced, and COMMODITY2AMOUNT is the amount (symbol and quantity)
|
||
of commodity 2 that one unit of commodity 1 is worth on this date.
|
||
Examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# one euro was worth $1.35 from 2009-01-01 onward:
|
||
P 2009-01-01 € $1.35
|
||
|
||
# and $1.40 from 2010-01-01 onward:
|
||
P 2010-01-01 € $1.40
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The \f[V]-V\f[R], \f[V]-X\f[R] and \f[V]--value\f[R] flags use these
|
||
market prices to show amount values in another commodity.
|
||
See Valuation.
|
||
.PP
|
||
.SS \f[V]payee\f[R] directive
|
||
.PP
|
||
\f[V]payee PAYEE NAME\f[R]
|
||
.PP
|
||
This directive can be used to declare a limited set of payees which may
|
||
appear in transaction descriptions.
|
||
The \[dq]payees\[dq] check will report an error if any transaction
|
||
refers to a payee that has not been declared.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
payee Whole Foods
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Any indented subdirectives are currently ignored.
|
||
.SS \f[V]tag\f[R] directive
|
||
.PP
|
||
\f[V]tag TAGNAME\f[R]
|
||
.PP
|
||
This directive can be used to declare a limited set of tag names allowed
|
||
in tags.
|
||
TAGNAME should be a valid tag name (no spaces).
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
tag item-id
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Any indented subdirectives are currently ignored.
|
||
.PP
|
||
The \[dq]tags\[dq] check will report an error if any undeclared tag name
|
||
is used.
|
||
It is quite easy to accidentally create a tag through normal use of
|
||
colons in comments(#comments]; if you want to prevent this, you can
|
||
declare and check your tags .
|
||
.SS Periodic transactions
|
||
.PP
|
||
The \f[V]\[ti]\f[R] directive declares recurring transactions.
|
||
Such directives allow hledger to generate temporary future transactions
|
||
(visible in reports, not in the journal file) to help with forecasting
|
||
or budgeting.
|
||
.PP
|
||
Periodic transactions can be a little tricky, so before you use them,
|
||
read this whole section, or at least these tips:
|
||
.IP "1." 3
|
||
Two spaces accidentally added or omitted will cause you trouble - read
|
||
about this below.
|
||
.IP "2." 3
|
||
For troubleshooting, show the generated transactions with
|
||
\f[V]hledger print --forecast tag:generated\f[R] or
|
||
\f[V]hledger register --forecast tag:generated\f[R].
|
||
.IP "3." 3
|
||
Forecasted transactions will begin only after the last non-forecasted
|
||
transaction\[aq]s date.
|
||
.IP "4." 3
|
||
Forecasted transactions will end 6 months from today, by default.
|
||
See below for the exact start/end rules.
|
||
.IP "5." 3
|
||
period expressions can be tricky.
|
||
Their documentation needs improvement, but is worth studying.
|
||
.IP "6." 3
|
||
Some period expressions with a repeating interval must begin on a
|
||
natural boundary of that interval.
|
||
Eg in \f[V]weekly from DATE\f[R], DATE must be a monday.
|
||
\f[V]\[ti] weekly from 2019/10/1\f[R] (a tuesday) will give an error.
|
||
.IP "7." 3
|
||
Other period expressions with an interval are automatically expanded to
|
||
cover a whole number of that interval.
|
||
(This is done to improve reports, but it also affects periodic
|
||
transactions.
|
||
Yes, it\[aq]s a bit inconsistent with the above.)
|
||
Eg: \f[V]\[ti] every 10th day of month from 2023/01\f[R], which is
|
||
equivalent to \f[V]\[ti] every 10th day of month from 2023/01/01\f[R],
|
||
will be adjusted to start on 2019/12/10.
|
||
.SS Periodic rule syntax
|
||
.PP
|
||
A periodic transaction rule looks like a normal journal entry, with the
|
||
date replaced by a tilde (\f[V]\[ti]\f[R]) followed by a period
|
||
expression (mnemonic: \f[V]\[ti]\f[R] looks like a recurring sine
|
||
wave.):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# every first of month
|
||
\[ti] monthly
|
||
expenses:rent $2000
|
||
assets:bank:checking
|
||
|
||
# every 15th of month in 2023\[aq]s first quarter:
|
||
\[ti] monthly from 2023-04-15 to 2023-06-16
|
||
expenses:utilities $400
|
||
assets:bank:checking
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The period expression is the same syntax used for specifying
|
||
multi-period reports, just interpreted differently; there, it specifies
|
||
report periods; here it specifies recurrence dates (the periods\[aq]
|
||
start dates).
|
||
.SS Periodic rules and relative dates
|
||
.PP
|
||
Partial or relative dates (like \f[V]12/31\f[R], \f[V]25\f[R],
|
||
\f[V]tomorrow\f[R], \f[V]last week\f[R], \f[V]next quarter\f[R]) are
|
||
usually not recommended in periodic rules, since the results will change
|
||
as time passes.
|
||
If used, they will be interpreted relative to, in order of preference:
|
||
.IP "1." 3
|
||
the first day of the default year specified by a recent \f[V]Y\f[R]
|
||
directive
|
||
.IP "2." 3
|
||
or the date specified with \f[V]--today\f[R]
|
||
.IP "3." 3
|
||
or the date on which you are running the report.
|
||
.PP
|
||
They will not be affected at all by report period or forecast period
|
||
dates.
|
||
.SS Two spaces between period expression and description!
|
||
.PP
|
||
If the period expression is followed by a transaction description, these
|
||
must be separated by \f[B]two or more spaces\f[R].
|
||
This helps hledger know where the period expression ends, so that
|
||
descriptions can not accidentally alter their meaning, as in this
|
||
example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; 2 or more spaces needed here, so the period is not understood as \[dq]every 2 months in 2023\[dq]
|
||
; ||
|
||
; vv
|
||
\[ti] every 2 months in 2023, we will review
|
||
assets:bank:checking $1500
|
||
income:acme inc
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
So,
|
||
.IP \[bu] 2
|
||
Do write two spaces between your period expression and your transaction
|
||
description, if any.
|
||
.IP \[bu] 2
|
||
Don\[aq]t accidentally write two spaces in the middle of your period
|
||
expression.
|
||
.SS Auto postings
|
||
.PP
|
||
The \f[V]=\f[R] directive declares a rule for generating temporary extra
|
||
postings on transactions.
|
||
Wherever the rule matches an existing posting, it can add one or more
|
||
companion postings below that one, optionally influenced by the matched
|
||
posting\[aq]s amount.
|
||
This can be useful for generating tax postings with a standard
|
||
percentage, for example.
|
||
.PP
|
||
Note that depending on generated data is not ideal for financial records
|
||
(it\[aq]s less portable, less future-proof, less auditable by others,
|
||
and less robust, since other features like balance assertions will
|
||
depend on using or not using \f[V]--auto\f[R]).
|
||
.PP
|
||
An auto posting rule looks a bit like a transaction:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
= QUERY
|
||
ACCOUNT AMOUNT
|
||
...
|
||
ACCOUNT [AMOUNT]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
except the first line is an equals sign (mnemonic: \f[V]=\f[R] suggests
|
||
matching), followed by a query (which matches existing postings), and
|
||
each \[dq]posting\[dq] line describes a posting to be generated, and the
|
||
posting amounts can be:
|
||
.IP \[bu] 2
|
||
a normal amount with a commodity symbol, eg \f[V]$2\f[R].
|
||
This will be used as-is.
|
||
.IP \[bu] 2
|
||
a number, eg \f[V]2\f[R].
|
||
The commodity symbol (if any) from the matched posting will be added to
|
||
this.
|
||
.IP \[bu] 2
|
||
a numeric multiplier, eg \f[V]*2\f[R] (a star followed by a number N).
|
||
The matched posting\[aq]s amount (and total price, if any) will be
|
||
multiplied by N.
|
||
.IP \[bu] 2
|
||
a multiplier with a commodity symbol, eg \f[V]*$2\f[R] (a star, number
|
||
N, and symbol S).
|
||
The matched posting\[aq]s amount will be multiplied by N, and its
|
||
commodity symbol will be replaced with S.
|
||
.PP
|
||
Any query term containing spaces must be enclosed in single or double
|
||
quotes, as on the command line.
|
||
Eg, note the quotes around the second query term below:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
= expenses:groceries \[aq]expenses:dining out\[aq]
|
||
(budget:funds:dining out) *-1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Some examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; every time I buy food, schedule a dollar donation
|
||
= expenses:food
|
||
(liabilities:charity) $-1
|
||
|
||
; when I buy a gift, also deduct that amount from a budget envelope subaccount
|
||
= expenses:gifts
|
||
assets:checking:gifts *-1
|
||
assets:checking *1
|
||
|
||
2017/12/1
|
||
expenses:food $10
|
||
assets:checking
|
||
|
||
2017/12/14
|
||
expenses:gifts $20
|
||
assets:checking
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --auto
|
||
2017-12-01
|
||
expenses:food $10
|
||
assets:checking
|
||
(liabilities:charity) $-1
|
||
|
||
2017-12-14
|
||
expenses:gifts $20
|
||
assets:checking
|
||
assets:checking:gifts -$20
|
||
assets:checking $20
|
||
\f[R]
|
||
.fi
|
||
.SS Auto postings and multiple files
|
||
.PP
|
||
An auto posting rule can affect any transaction in the current file, or
|
||
in any parent file or child file.
|
||
Note, currently it will not affect sibling files (when multiple
|
||
\f[V]-f\f[R]/\f[V]--file\f[R] are used - see #1212).
|
||
.SS Auto postings and dates
|
||
.PP
|
||
A posting date (or secondary date) in the matched posting, or (taking
|
||
precedence) a posting date in the auto posting rule itself, will also be
|
||
used in the generated posting.
|
||
.SS Auto postings and transaction balancing / inferred amounts / balance assertions
|
||
.PP
|
||
Currently, auto postings are added:
|
||
.IP \[bu] 2
|
||
after missing amounts are inferred, and transactions are checked for
|
||
balancedness,
|
||
.IP \[bu] 2
|
||
but before balance assertions are checked.
|
||
.PP
|
||
Note this means that journal entries must be balanced both before and
|
||
after auto postings are added.
|
||
This changed in hledger 1.12+; see #893 for background.
|
||
.PP
|
||
This also means that you cannot have more than one auto-posting with a
|
||
missing amount applied to a given transaction, as it will be unable to
|
||
infer amounts.
|
||
.SS Auto posting tags
|
||
.PP
|
||
Automated postings will have some extra tags:
|
||
.IP \[bu] 2
|
||
\f[V]generated-posting:= QUERY\f[R] - shows this was generated by an
|
||
auto posting rule, and the query
|
||
.IP \[bu] 2
|
||
\f[V]_generated-posting:= QUERY\f[R] - a hidden tag, which does not
|
||
appear in hledger\[aq]s output.
|
||
This can be used to match postings generated \[dq]just now\[dq], rather
|
||
than generated in the past and saved to the journal.
|
||
.PP
|
||
Also, any transaction that has been changed by auto posting rules will
|
||
have these tags added:
|
||
.IP \[bu] 2
|
||
\f[V]modified:\f[R] - this transaction was modified
|
||
.IP \[bu] 2
|
||
\f[V]_modified:\f[R] - a hidden tag not appearing in the comment; this
|
||
transaction was modified \[dq]just now\[dq].
|
||
.SS Auto postings on forecast transactions only
|
||
.PP
|
||
Tip: you can can make auto postings that will apply to forecast
|
||
transactions but not recorded transactions, by adding
|
||
\f[V]tag:_generated-transaction\f[R] to their QUERY.
|
||
This can be useful when generating new journal entries to be saved in
|
||
the journal.
|
||
.SS Other syntax
|
||
.PP
|
||
hledger journal format supports quite a few other features, mainly to
|
||
make interoperating with or converting from Ledger easier.
|
||
Note some of the features below are powerful and can be useful in
|
||
special cases, but in general, features in this section are considered
|
||
less important or even not recommended for most users.
|
||
Downsides are mentioned to help you decide if you want to use them.
|
||
.SS Balance assignments
|
||
.PP
|
||
Ledger-style balance assignments are also supported.
|
||
These are like balance assertions, but with no posting amount on the
|
||
left side of the equals sign; instead it is calculated automatically so
|
||
as to satisfy the assertion.
|
||
This can be a convenience during data entry, eg when setting opening
|
||
balances:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; starting a new journal, set asset account balances
|
||
2016/1/1 opening balances
|
||
assets:checking = $409.32
|
||
assets:savings = $735.24
|
||
assets:cash = $42
|
||
equity:opening balances
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or when adjusting a balance to reality:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; no cash left; update balance, record any untracked spending as a generic expense
|
||
2016/1/15
|
||
assets:cash = $0
|
||
expenses:misc
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The calculated amount depends on the account\[aq]s balance in the
|
||
commodity at that point (which depends on the previously-dated postings
|
||
of the commodity to that account since the last balance assertion or
|
||
assignment).
|
||
.PP
|
||
Downsides: using balance assignments makes your journal less explicit;
|
||
to know the exact amount posted, you have to run hledger or do the
|
||
calculations yourself, instead of just reading it.
|
||
Also balance assignments\[aq] forcing of balances can hide errors.
|
||
These things make your financial data less portable, less future-proof,
|
||
and less trustworthy in an audit.
|
||
.SS Balance assignments and prices
|
||
.PP
|
||
A cost in a balance assignment will cause the calculated amount to have
|
||
that price attached:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2019/1/1
|
||
(a) = $1 \[at] €2
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --explicit
|
||
2019-01-01
|
||
(a) $1 \[at] €2 = $1 \[at] €2
|
||
\f[R]
|
||
.fi
|
||
.SS Bracketed posting dates
|
||
.PP
|
||
For setting posting dates and secondary posting dates, Ledger\[aq]s
|
||
bracketed date syntax is also supported: \f[V][DATE]\f[R],
|
||
\f[V][DATE=DATE2]\f[R] or \f[V][=DATE2]\f[R] in posting comments.
|
||
hledger will attempt to parse any square-bracketed sequence of the
|
||
\f[V]0123456789/-.=\f[R] characters in this way.
|
||
With this syntax, DATE infers its year from the transaction and DATE2
|
||
infers its year from DATE.
|
||
.PP
|
||
Downsides: another syntax to learn, redundant with hledger\[aq]s
|
||
\f[V]date:\f[R]/\f[V]date2:\f[R] tags, and confusingly similar to
|
||
Ledger\[aq]s lot date syntax.
|
||
.SS \f[V]D\f[R] directive
|
||
.PP
|
||
\f[V]D AMOUNT\f[R]
|
||
.PP
|
||
This directive sets a default commodity, to be used for any subsequent
|
||
commodityless amounts (ie, plain numbers) seen while parsing the
|
||
journal.
|
||
This effect lasts until the next \f[V]D\f[R] directive, or the end of
|
||
the journal.
|
||
.PP
|
||
For compatibility/historical reasons, \f[V]D\f[R] also acts like a
|
||
\f[V]commodity\f[R] directive (setting the commodity\[aq]s decimal mark
|
||
for parsing and display style for output).
|
||
So its argument is not just a commodity symbol, but a full amount
|
||
demonstrating the style.
|
||
The amount must include a decimal mark (either period or comma).
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; commodity-less amounts should be treated as dollars
|
||
; (and displayed with the dollar sign on the left, thousands separators and two decimal places)
|
||
D $1,000.00
|
||
|
||
1/1
|
||
a 5 ; <- commodity-less amount, parsed as $5 and displayed as $5.00
|
||
b
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Interactions with other directives:
|
||
.PP
|
||
For setting a commodity\[aq]s display style, a \f[V]commodity\f[R]
|
||
directive has highest priority, then a \f[V]D\f[R] directive.
|
||
.PP
|
||
For detecting a commodity\[aq]s decimal mark during parsing,
|
||
\f[V]decimal-mark\f[R] has highest priority, then \f[V]commodity\f[R],
|
||
then \f[V]D\f[R].
|
||
.PP
|
||
For checking commodity symbols with the check command, a
|
||
\f[V]commodity\f[R] directive is required
|
||
(\f[V]hledger check commodities\f[R] ignores \f[V]D\f[R] directives).
|
||
.PP
|
||
Downsides: omitting commodity symbols makes your financial data less
|
||
explicit, less portable, and less trustworthy in an audit.
|
||
It is usually an unsustainable shortcut; sooner or later you will want
|
||
to track multiple commodities.
|
||
D is overloaded with functions redundant with \f[V]commodity\f[R] and
|
||
\f[V]decimal-mark\f[R].
|
||
And it works differently from Ledger\[aq]s \f[V]D\f[R].
|
||
.SS \f[V]apply account\f[R] directive
|
||
.PP
|
||
This directive sets a default parent account, which will be prepended to
|
||
all accounts in following entries, until an \f[V]end apply account\f[R]
|
||
directive or end of current file.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
apply account home
|
||
|
||
2010/1/1
|
||
food $10
|
||
cash
|
||
|
||
end apply account
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
is equivalent to:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2010/01/01
|
||
home:food $10
|
||
home:cash $-10
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[V]account\f[R] directives are also affected, and so is any
|
||
\f[V]include\f[R]d content.
|
||
.PP
|
||
Account names entered via hledger add or hledger-web are not affected.
|
||
.PP
|
||
Account aliases, if any, are applied after the parent account is
|
||
prepended.
|
||
.PP
|
||
Downsides: this can make your financial data less explicit, less
|
||
portable, and less trustworthy in an audit.
|
||
.SS \f[V]Y\f[R] directive
|
||
.PP
|
||
\f[V]Y YEAR\f[R]
|
||
.PP
|
||
or (deprecated backward-compatible forms):
|
||
.PP
|
||
\f[V]year YEAR\f[R] \f[V]apply year YEAR\f[R]
|
||
.PP
|
||
The space is optional.
|
||
This sets a default year to be used for subsequent dates which don\[aq]t
|
||
specify a year.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Y2009 ; set default year to 2009
|
||
|
||
12/15 ; equivalent to 2009/12/15
|
||
expenses 1
|
||
assets
|
||
|
||
year 2010 ; change default year to 2010
|
||
|
||
2009/1/30 ; specifies the year, not affected
|
||
expenses 1
|
||
assets
|
||
|
||
1/31 ; equivalent to 2010/1/31
|
||
expenses 1
|
||
assets
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Downsides: omitting the year (from primary transaction dates, at least)
|
||
makes your financial data less explicit, less portable, and less
|
||
trustworthy in an audit.
|
||
Such dates can get separated from their corresponding Y directive, eg
|
||
when evaluating a region of the journal in your editor.
|
||
A missing Y directive makes reports dependent on today\[aq]s date.
|
||
.SS Secondary dates
|
||
.PP
|
||
A secondary date is written after the primary date, following an equals
|
||
sign.
|
||
If the year is omitted, the primary date\[aq]s year is assumed.
|
||
When running reports, the primary (left) date is used by default, but
|
||
with the \f[V]--date2\f[R] flag (or \f[V]--aux-date\f[R] or
|
||
\f[V]--effective\f[R]), the secondary (right) date will be used instead.
|
||
.PP
|
||
The meaning of secondary dates is up to you, but it\[aq]s best to follow
|
||
a consistent rule.
|
||
Eg \[dq]primary = the bank\[aq]s clearing date, secondary = date the
|
||
transaction was initiated, if different\[dq].
|
||
.PP
|
||
Downsides: makes your financial data more complicated, less portable,
|
||
and less trustworthy in an audit.
|
||
Keeping the meaning of the two dates consistent requires discipline, and
|
||
you have to remember which reporting mode is appropriate for a given
|
||
report.
|
||
Posting dates are simpler and better.
|
||
.SS Star comments
|
||
.PP
|
||
Lines beginning with \f[V]*\f[R] (star/asterisk) are also comment lines.
|
||
This feature allows Emacs users to insert org headings in their journal,
|
||
allowing them to fold/unfold/navigate it like an outline when viewed
|
||
with org mode.
|
||
.PP
|
||
Downsides: another, unconventional comment syntax to learn.
|
||
Decreases your journal\[aq]s portability.
|
||
And switching to Emacs org mode just for folding/unfolding meant losing
|
||
the benefits of ledger mode; nowadays you can add outshine mode to
|
||
ledger mode to get folding without losing ledger mode\[aq]s features.
|
||
.SS Valuation expressions
|
||
.PP
|
||
Ledger allows a valuation function or value to be written in double
|
||
parentheses after an amount.
|
||
hledger ignores these.
|
||
.SS Virtual postings
|
||
.PP
|
||
A posting with parentheses around the account name
|
||
(\f[V](some:account)\f[R]) is called a \f[I]unbalanced virtual
|
||
posting\f[R].
|
||
Such postings do not participate in transaction balancing.
|
||
(And if you write them without an amount, a zero amount is always
|
||
inferred.)
|
||
These can occasionally be convenient for special circumstances, but they
|
||
violate double entry bookkeeping and make your data less portable across
|
||
applications, so many people avoid using them at all.
|
||
.PP
|
||
A posting with brackets around the account name
|
||
(\f[V][some:account]\f[R]) is called a \f[I]balanced virtual
|
||
posting\f[R].
|
||
The balanced virtual postings in a transaction must add up to zero, just
|
||
like ordinary postings, but separately from them.
|
||
These are not part of double entry bookkeeping either, but they are at
|
||
least balanced.
|
||
An example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-01-01 buy food with cash, update budget envelope subaccounts, & something else
|
||
assets:cash $-10 ; <- these balance each other
|
||
expenses:food $7 ; <-
|
||
expenses:food $3 ; <-
|
||
[assets:checking:budget:food] $-10 ; <- and these balance each other
|
||
[assets:checking:available] $10 ; <-
|
||
(something:else) $5 ; <- this is not required to balance
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Ordinary postings, whose account names are neither parenthesised nor
|
||
bracketed, are called \f[I]real postings\f[R].
|
||
You can exclude virtual postings from reports with the
|
||
\f[V]-R/--real\f[R] flag or a \f[V]real:1\f[R] query.
|
||
.SS Other Ledger directives
|
||
.PP
|
||
These other Ledger directives are currently accepted but ignored.
|
||
This allows hledger to read more Ledger files, but be aware that
|
||
hledger\[aq]s reports may differ from Ledger\[aq]s if you use these.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
apply fixed COMM AMT
|
||
apply tag TAG
|
||
assert EXPR
|
||
bucket / A ACCT
|
||
capture ACCT REGEX
|
||
check EXPR
|
||
define VAR=EXPR
|
||
end apply fixed
|
||
end apply tag
|
||
end apply year
|
||
end tag
|
||
eval / expr EXPR
|
||
python
|
||
PYTHONCODE
|
||
tag NAME
|
||
value EXPR
|
||
--command-line-flags
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
See also https://hledger.org/ledger.html for a detailed hledger/Ledger
|
||
syntax comparison.
|
||
.PP
|
||
.SH CSV
|
||
.PP
|
||
hledger can read CSV files (Character Separated Value - usually comma,
|
||
semicolon, or tab) containing dated records, automatically converting
|
||
each record into a transaction.
|
||
.PP
|
||
(To learn about \f[I]writing\f[R] CSV, see CSV output.)
|
||
.PP
|
||
For best error messages when reading CSV/TSV/SSV files, make sure they
|
||
have a corresponding \f[V].csv\f[R], \f[V].tsv\f[R] or \f[V].ssv\f[R]
|
||
file extension or use a hledger file prefix (see File Extension below).
|
||
.PP
|
||
Each CSV file must be described by a corresponding \f[I]rules file\f[R].
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
This contains rules describing the CSV data (header line, fields layout,
|
||
date format etc.), how to construct hledger transactions from it, and
|
||
how to categorise transactions based on description or other attributes.
|
||
.PP
|
||
By default hledger looks for a rules file named like the CSV file with
|
||
an extra \f[V].rules\f[R] extension, in the same directory.
|
||
Eg when asked to read \f[V]foo/FILE.csv\f[R], hledger looks for
|
||
\f[V]foo/FILE.csv.rules\f[R].
|
||
You can specify a different rules file with the \f[V]--rules-file\f[R]
|
||
option.
|
||
If no rules file is found, hledger will create a sample rules file,
|
||
which you\[aq]ll need to adjust.
|
||
.PP
|
||
At minimum, the rules file must identify the date and amount fields, and
|
||
often it also specifies the date format and how many header lines there
|
||
are.
|
||
Here\[aq]s a simple CSV file and a rules file for it:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Date, Description, Id, Amount
|
||
12/11/2019, Foo, 123, 10.23
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# basic.csv.rules
|
||
skip 1
|
||
fields date, description, , amount
|
||
date-format %d/%m/%Y
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -f basic.csv
|
||
2019-11-12 Foo
|
||
expenses:unknown 10.23
|
||
income:unknown -10.23
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
There\[aq]s an introductory Importing CSV data tutorial on hledger.org,
|
||
and more CSV rules examples below, and a larger collection at
|
||
https://github.com/simonmichael/hledger/tree/master/examples/csv.
|
||
.SS CSV rules cheatsheet
|
||
.PP
|
||
The following kinds of rule can appear in the rules file, in any order.
|
||
(Blank lines and lines beginning with \f[V]#\f[R] or \f[V];\f[R] or
|
||
\f[V]*\f[R] are ignored.)
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(23.7n) lw(46.3n).
|
||
T{
|
||
\f[B]\f[VB]source\f[B]\f[R]
|
||
T}@T{
|
||
optionally declare which file to read data from
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]separator\f[B]\f[R]
|
||
T}@T{
|
||
declare the field separator, instead of relying on file extension
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]skip\f[B]\f[R]
|
||
T}@T{
|
||
skip one or more header lines at start of file
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]date-format\f[B]\f[R]
|
||
T}@T{
|
||
declare how to parse CSV dates/date-times
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]timezone\f[B]\f[R]
|
||
T}@T{
|
||
declare the time zone of ambiguous CSV date-times
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]newest-first\f[B]\f[R]
|
||
T}@T{
|
||
improve txn order when: there are multiple records, newest first, all
|
||
with the same date
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]intra-day-reversed\f[B]\f[R]
|
||
T}@T{
|
||
improve txn order when: same-day txns are in opposite order to the
|
||
overall file
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]decimal-mark\f[B]\f[R]
|
||
T}@T{
|
||
declare the decimal mark used in CSV amounts, when ambiguous
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]fields\f[B] list\f[R]
|
||
T}@T{
|
||
name CSV fields for easy reference, and optionally assign their values
|
||
to hledger fields
|
||
T}
|
||
T{
|
||
\f[B]Field assignment\f[R]
|
||
T}@T{
|
||
assign a CSV value or interpolated text value to a hledger field
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]if\f[B] block\f[R]
|
||
T}@T{
|
||
conditionally assign values to hledger fields, or \f[V]skip\f[R] a
|
||
record or \f[V]end\f[R] (skip rest of file)
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]if\f[B] table\f[R]
|
||
T}@T{
|
||
conditionally assign values to hledger fields, using compact syntax
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]balance-type\f[B]\f[R]
|
||
T}@T{
|
||
select which type of balance assertions/assignments to generate
|
||
T}
|
||
T{
|
||
\f[B]\f[VB]include\f[B]\f[R]
|
||
T}@T{
|
||
inline another CSV rules file
|
||
T}
|
||
.TE
|
||
.PP
|
||
Working with CSV tips can be found below, including How CSV rules are
|
||
evaluated.
|
||
.SS \f[V]source\f[R]
|
||
.PP
|
||
If you tell hledger to read a csv file with \f[V]-f foo.csv\f[R], it
|
||
will look for rules in \f[V]foo.csv.rules\f[R].
|
||
Or, you can tell it to read the rules file, with
|
||
\f[V]-f foo.csv.rules\f[R], and it will look for data in
|
||
\f[V]foo.csv\f[R] (since 1.30).
|
||
.PP
|
||
These are mostly equivalent, but the second method provides some extra
|
||
features.
|
||
For one, the data file can be missing, without causing an error; it is
|
||
just considered empty.
|
||
And, you can specify a different data file by adding a \[dq]source\[dq]
|
||
rule:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
source ./Checking1.csv
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If you specify just a file name with no path, hledger will look for it
|
||
in your system\[aq]s downloads directory (\f[V]\[ti]/Downloads\f[R],
|
||
currently):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
source Checking1.csv
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
And if you specify a glob pattern, hledger will read the most recent of
|
||
the matched files (useful with repeated downloads):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
source Checking1*.csv
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
See also \[dq]Working with CSV > Reading files specified by rule\[dq].
|
||
.SS \f[V]separator\f[R]
|
||
.PP
|
||
You can use the \f[V]separator\f[R] rule to read other kinds of
|
||
character-separated data.
|
||
The argument is any single separator character, or the words
|
||
\f[V]tab\f[R] or \f[V]space\f[R] (case insensitive).
|
||
Eg, for comma-separated values (CSV):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
separator ,
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or for semicolon-separated values (SSV):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
separator ;
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or for tab-separated values (TSV):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
separator TAB
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If the input file has a \f[V].csv\f[R], \f[V].ssv\f[R] or \f[V].tsv\f[R]
|
||
file extension (or a \f[V]csv:\f[R], \f[V]ssv:\f[R], \f[V]tsv:\f[R]
|
||
prefix), the appropriate separator will be inferred automatically, and
|
||
you won\[aq]t need this rule.
|
||
.SS \f[V]skip\f[R]
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
skip N
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The word \f[V]skip\f[R] followed by a number (or no number, meaning 1)
|
||
tells hledger to ignore this many non-empty lines at the start of the
|
||
input data.
|
||
You\[aq]ll need this whenever your CSV data contains header lines.
|
||
Note, empty and blank lines are skipped automatically, so you don\[aq]t
|
||
need to count those.
|
||
.PP
|
||
\f[V]skip\f[R] has a second meaning: it can be used inside if blocks
|
||
(described below), to skip one or more records whenever the condition is
|
||
true.
|
||
Records skipped in this way are ignored, except they are still required
|
||
to be valid CSV.
|
||
.SS \f[V]date-format\f[R]
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
date-format DATEFMT
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This is a helper for the \f[V]date\f[R] (and \f[V]date2\f[R]) fields.
|
||
If your CSV dates are not formatted like \f[V]YYYY-MM-DD\f[R],
|
||
\f[V]YYYY/MM/DD\f[R] or \f[V]YYYY.MM.DD\f[R], you\[aq]ll need to add a
|
||
date-format rule describing them with a strptime-style date parsing
|
||
pattern - see
|
||
https://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:formatTime.
|
||
The pattern must parse the CSV date value completely.
|
||
Some examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# MM/DD/YY
|
||
date-format %m/%d/%y
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# D/M/YYYY
|
||
# The - makes leading zeros optional.
|
||
date-format %-d/%-m/%Y
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# YYYY-Mmm-DD
|
||
date-format %Y-%h-%d
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# M/D/YYYY HH:MM AM some other junk
|
||
# Note the time and junk must be fully parsed, though only the date is used.
|
||
date-format %-m/%-d/%Y %l:%M %p some other junk
|
||
\f[R]
|
||
.fi
|
||
.SS \f[V]timezone\f[R]
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
timezone TIMEZONE
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
When CSV contains date-times that are implicitly in some time zone other
|
||
than yours, but containing no explicit time zone information, you can
|
||
use this rule to declare the CSV\[aq]s native time zone, which helps
|
||
prevent off-by-one dates.
|
||
.PP
|
||
When the CSV date-times do contain time zone information, you don\[aq]t
|
||
need this rule; instead, use \f[V]%Z\f[R] in \f[V]date-format\f[R] (or
|
||
\f[V]%z\f[R], \f[V]%EZ\f[R], \f[V]%Ez\f[R]; see the formatTime link
|
||
above).
|
||
.PP
|
||
In either of these cases, hledger will do a time-zone-aware conversion,
|
||
localising the CSV date-times to your current system time zone.
|
||
If you prefer to localise to some other time zone, eg for
|
||
reproducibility, you can (on unix at least) set the output timezone with
|
||
the TZ environment variable, eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[V]timezone\f[R] currently does not understand timezone names, except
|
||
\[dq]UTC\[dq], \[dq]GMT\[dq], \[dq]EST\[dq], \[dq]EDT\[dq],
|
||
\[dq]CST\[dq], \[dq]CDT\[dq], \[dq]MST\[dq], \[dq]MDT\[dq],
|
||
\[dq]PST\[dq], or \[dq]PDT\[dq].
|
||
For others, use numeric format: +HHMM or -HHMM.
|
||
.SS \f[V]newest-first\f[R]
|
||
.PP
|
||
hledger tries to ensure that the generated transactions will be ordered
|
||
chronologically, including intra-day transactions.
|
||
Usually it can auto-detect how the CSV records are ordered.
|
||
But if it encounters CSV where all records are on the same date, it
|
||
assumes that the records are oldest first.
|
||
If in fact the CSV\[aq]s records are normally newest first, like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-10-01, txn 3...
|
||
2022-10-01, txn 2...
|
||
2022-10-01, txn 1...
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
you can add the \f[V]newest-first\f[R] rule to help hledger generate the
|
||
transactions in correct order.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# same-day CSV records are newest first
|
||
newest-first
|
||
\f[R]
|
||
.fi
|
||
.SS \f[V]intra-day-reversed\f[R]
|
||
.PP
|
||
CSV records for each day are sometimes ordered in reverse compared to
|
||
the overall date order.
|
||
Eg, here dates are newest first, but the transactions on each date are
|
||
oldest first:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-10-02, txn 3...
|
||
2022-10-02, txn 4...
|
||
2022-10-01, txn 1...
|
||
2022-10-01, txn 2...
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
In this situation, add the \f[V]intra-day-reversed\f[R] rule, and
|
||
hledger will compensate, improving the order of transactions.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# transactions within each day are reversed with respect to the overall date order
|
||
intra-day-reversed
|
||
\f[R]
|
||
.fi
|
||
.SS \f[V]decimal-mark\f[R]
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
decimal-mark .
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
decimal-mark ,
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
hledger automatically accepts either period or comma as a decimal mark
|
||
when parsing numbers (cf Amounts).
|
||
However if any numbers in the CSV contain digit group marks, such as
|
||
thousand-separating commas, you should declare the decimal mark
|
||
explicitly with this rule, to avoid misparsed numbers.
|
||
.SS \f[V]fields\f[R] list
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields FIELDNAME1, FIELDNAME2, ...
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
A fields list (the word \f[V]fields\f[R] followed by comma-separated
|
||
field names) is optional, but convenient.
|
||
It does two things:
|
||
.IP "1." 3
|
||
It names the CSV field in each column.
|
||
This can be convenient if you are referencing them in other rules, so
|
||
you can say \f[V]%SomeField\f[R] instead of remembering \f[V]%13\f[R].
|
||
.IP "2." 3
|
||
Whenever you use one of the special hledger field names (described
|
||
below), it assigns the CSV value in this position to that hledger field.
|
||
This is the quickest way to populate hledger\[aq]s fields and build a
|
||
transaction.
|
||
.PP
|
||
Here\[aq]s an example that says \[dq]use the 1st, 2nd and 4th fields as
|
||
the transaction\[aq]s date, description and amount; name the last two
|
||
fields for later reference; and ignore the others\[dq]:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields date, description, , amount, , , somefield, anotherfield
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
In a fields list, the separator is always comma; it is unrelated to the
|
||
CSV file\[aq]s separator.
|
||
Also:
|
||
.IP \[bu] 2
|
||
There must be least two items in the list (at least one comma).
|
||
.IP \[bu] 2
|
||
Field names may not contain spaces.
|
||
Spaces before/after field names are optional.
|
||
.IP \[bu] 2
|
||
Field names may contain \f[V]_\f[R] (underscore) or \f[V]-\f[R]
|
||
(hyphen).
|
||
.IP \[bu] 2
|
||
Fields you don\[aq]t care about can be given a dummy name or an empty
|
||
name.
|
||
.PP
|
||
If the CSV contains column headings, it\[aq]s convenient to use these
|
||
for your field names, suitably modified (eg lower-cased with spaces
|
||
replaced by underscores).
|
||
.PP
|
||
Sometimes you may want to alter a CSV field name to avoid assigning to a
|
||
hledger field with the same name.
|
||
Eg you could call the CSV\[aq]s \[dq]balance\[dq] field
|
||
\f[V]balance_\f[R] to avoid directly setting hledger\[aq]s
|
||
\f[V]balance\f[R] field (and generating a balance assertion).
|
||
.SS Field assignment
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
HLEDGERFIELD FIELDVALUE
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Field assignments are the more flexible way to assign CSV values to
|
||
hledger fields.
|
||
They can be used instead of or in addition to a fields list (see above).
|
||
.PP
|
||
To assign a value to a hledger field, write the field name (any of the
|
||
standard hledger field/pseudo-field names, defined below), a space,
|
||
followed by a text value on the same line.
|
||
This text value may interpolate CSV fields, referenced by their 1-based
|
||
position in the CSV record (\f[V]%N\f[R]), or by the name they were
|
||
given in the fields list (\f[V]%CSVFIELD\f[R]).
|
||
.PP
|
||
Some examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# set the amount to the 4th CSV field, with \[dq] USD\[dq] appended
|
||
amount %4 USD
|
||
|
||
# combine three fields to make a comment, containing note: and date: tags
|
||
comment note: %somefield - %anotherfield, date: %1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Tips:
|
||
.IP \[bu] 2
|
||
Interpolation strips outer whitespace (so a CSV value like
|
||
\f[V]\[dq] 1 \[dq]\f[R] becomes \f[V]1\f[R] when interpolated) (#1051).
|
||
.IP \[bu] 2
|
||
Interpolations always refer to a CSV field - you can\[aq]t interpolate a
|
||
hledger field.
|
||
(See Referencing other fields below).
|
||
.SS Field names
|
||
.PP
|
||
Note the two kinds of field names mentioned here, and used only in
|
||
hledger CSV rules files:
|
||
.IP "1." 3
|
||
\f[B]CSV field names\f[R] (\f[V]CSVFIELD\f[R] in these docs): you can
|
||
optionally name the CSV columns for easy reference (since hledger
|
||
doesn\[aq]t yet automatically recognise column headings in a CSV file),
|
||
by writing arbitrary names in a \f[V]fields\f[R] list, eg:
|
||
.RS 4
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields When, What, Some_Id, Net, Total, Foo, Bar
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP "2." 3
|
||
Special \f[B]hledger field names\f[R] (\f[V]HLEDGERFIELD\f[R] in these
|
||
docs): you must set at least some of these to generate the hledger
|
||
transaction from a CSV record, by writing them as the left hand side of
|
||
a field assignment, eg:
|
||
.RS 4
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
date %When
|
||
code %Some_Id
|
||
description %What
|
||
comment %Foo %Bar
|
||
amount1 $ %Total
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or directly in a \f[V]fields\f[R] list:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields date, description, code, , amount1, Foo, Bar
|
||
currency $
|
||
comment %Foo %Bar
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.PP
|
||
Here are all the special hledger field names available, and what happens
|
||
when you assign values to them:
|
||
.SS date field
|
||
.PP
|
||
Assigning to \f[V]date\f[R] sets the transaction date.
|
||
.SS date2 field
|
||
.PP
|
||
\f[V]date2\f[R] sets the transaction\[aq]s secondary date, if any.
|
||
.SS status field
|
||
.PP
|
||
\f[V]status\f[R] sets the transaction\[aq]s status, if any.
|
||
.SS code field
|
||
.PP
|
||
\f[V]code\f[R] sets the transaction\[aq]s code, if any.
|
||
.SS description field
|
||
.PP
|
||
\f[V]description\f[R] sets the transaction\[aq]s description, if any.
|
||
.SS comment field
|
||
.PP
|
||
\f[V]comment\f[R] sets the transaction\[aq]s comment, if any.
|
||
.PP
|
||
\f[V]commentN\f[R], where N is a number, sets the Nth posting\[aq]s
|
||
comment.
|
||
.PP
|
||
You can assign multi-line comments by writing literal \f[V]\[rs]n\f[R]
|
||
in the code.
|
||
A comment starting with \f[V]\[rs]n\f[R] will begin on a new line.
|
||
.PP
|
||
Comments can contain tags, as usual.
|
||
.SS account field
|
||
.PP
|
||
Assigning to \f[V]accountN\f[R], where N is 1 to 99, sets the account
|
||
name of the Nth posting, and causes that posting to be generated.
|
||
.PP
|
||
Most often there are two postings, so you\[aq]ll want to set
|
||
\f[V]account1\f[R] and \f[V]account2\f[R].
|
||
Typically \f[V]account1\f[R] is associated with the CSV file, and is set
|
||
once with a top-level assignment, while \f[V]account2\f[R] is set based
|
||
on each transaction\[aq]s description, in conditional rules.
|
||
.PP
|
||
If a posting\[aq]s account name is left unset but its amount is set (see
|
||
below), a default account name will be chosen (like
|
||
\[dq]expenses:unknown\[dq] or \[dq]income:unknown\[dq]).
|
||
.SS amount field
|
||
.PP
|
||
Amount setting can get a bit complex.
|
||
Assigning to \f[V]amount\f[R] is sufficient for simple transactions, but
|
||
there are four field name variants you can use for different situations:
|
||
.IP \[bu] 2
|
||
\f[B]\f[VB]amountN\f[B] sets a specific posting\[aq]s amount from one
|
||
CSV field or arbitrary value.\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Assigning to \f[V]amountN\f[R] sets the amount of the Nth posting - and
|
||
also causes that posting to be generated.
|
||
N is most often 1 or 2 but can go up to 99, potentially generating a
|
||
99-posting transaction.
|
||
(Posting numbers don\[aq]t have to be consecutive; higher posting
|
||
numbers can sometimes be useful with conditional rules, to ensure a
|
||
certain ordering of postings.)
|
||
.IP \[bu] 2
|
||
\f[B]\f[VB]amountN-in/-out\f[B] sets a specific posting\[aq]s amount
|
||
from two CSV fields.\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
When the amount is provided as two CSV fields -
|
||
\[dq]Debit\[dq]/\[dq]Credit\[dq],
|
||
\[dq]Deposit\[dq]/\[dq]Withdrawal\[dq], \[dq]Money In\[dq]/\[dq]Money
|
||
Out\[dq] or similar - assign those fields to \f[V]amountN-in\f[R] and
|
||
\f[V]amountN-out\f[R] respectively (or possibly the other way round,
|
||
depending on signs).
|
||
This will set the Nth posting\[aq]s amount to whichever of the two CSV
|
||
field values is non-zero.
|
||
Some notes:
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
Don\[aq]t mix \f[V]amountN\f[R] and \f[V]amountN-in\f[R]/\f[V]-out\f[R].
|
||
When you have one CSV amount field, use \f[V]amountN\f[R].
|
||
When you have two CSV amount fields, use
|
||
\f[V]amountN-in\f[R]/\f[V]amountN-out\f[R].
|
||
.IP \[bu] 2
|
||
\f[V]amountN-in\f[R] and \f[V]amountN-out\f[R] are always used together,
|
||
as a pair.
|
||
Assign to both of them.
|
||
.IP \[bu] 2
|
||
They do not generate two separate postings; rather, they generate the
|
||
Nth posting\[aq]s single amount, from the value found in one or other of
|
||
the two CSV fields.
|
||
.IP \[bu] 2
|
||
In each record, at least one of the two CSV fields must contain a zero
|
||
amount or be empty.
|
||
.IP \[bu] 2
|
||
hledger assumes the two CSV fields contain unsigned numbers, and it will
|
||
automatically negate the -out amount.
|
||
.IP \[bu] 2
|
||
This variant can be convenient, but it doesn\[aq]t handle every
|
||
two-amount-field situation; if you need more flexibility, use an
|
||
\f[V]if\f[R] rule (see \[dq]Setting amounts\[dq] below).
|
||
.RE
|
||
.PP
|
||
The other two variants are older and considered legacy syntax, but can
|
||
still be convenient sometimes:
|
||
.IP \[bu] 2
|
||
\f[B]\f[VB]amount\f[B] sets posting 1 and 2\[aq]s amounts from one CSV
|
||
field or value.\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Assigning to \f[V]amount\f[R], with no posting number,
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
sets posting 1\[aq]s amount (like \f[V]amount1\f[R])
|
||
.IP \[bu] 2
|
||
sets posting 2\[aq]s amount to the same amount but with opposite sign;
|
||
and also converts it to cost if it has a cost price
|
||
.IP \[bu] 2
|
||
can be overridden by \f[V]amount1\f[R] and/or \f[V]amount2\f[R]
|
||
assignments.
|
||
(This helps with incremental migration of old rules files to the newer
|
||
syntax.)
|
||
.RE
|
||
.IP \[bu] 2
|
||
\f[B]\f[VB]amount-in/-out\f[B] sets posting 1 and 2\[aq]s amounts from
|
||
two CSV fields.\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Assigning \f[V]amount-in\f[R] and \f[V]amount-out\f[R], with no posting
|
||
numbers, to two CSV fields reads whichever of the two values is non-zero
|
||
as the amount, and then sets the first two posting amounts as above.
|
||
.PP
|
||
We recommend using only one of these variants within a rules file,
|
||
rather than mixing them.
|
||
And remember that a \f[V]fields\f[R] list can also do assignments, so eg
|
||
naming a CSV field \[dq]amount\[dq] counts as an assignment to
|
||
\f[V]amount\f[R]; if you don\[aq]t want that, call it something else,
|
||
like \[dq]amount_\[dq].
|
||
.PP
|
||
In addition to this section, please see also the tips beginning at
|
||
\[dq]Working with CSV > Setting amounts\[dq] below.
|
||
.SS currency field
|
||
.PP
|
||
\f[V]currency\f[R] sets a currency symbol, to be prepended to all
|
||
postings\[aq] amounts.
|
||
You can use this if the CSV amounts do not have a currency symbol, eg if
|
||
it is in a separate column.
|
||
.PP
|
||
\f[V]currencyN\f[R] prepends a currency symbol to just the Nth
|
||
posting\[aq]s amount.
|
||
.SS balance field
|
||
.PP
|
||
\f[V]balanceN\f[R] sets a balance assertion amount (or if the posting
|
||
amount is left empty, a balance assignment) on posting N.
|
||
.PP
|
||
\f[V]balance\f[R] is a compatibility spelling for hledger <1.17; it is
|
||
equivalent to \f[V]balance1\f[R].
|
||
.PP
|
||
You can adjust the type of assertion/assignment with the
|
||
\f[V]balance-type\f[R] rule (see below).
|
||
.PP
|
||
See Tips below for more about setting amounts and currency.
|
||
.SS \f[V]if\f[R] block
|
||
.PP
|
||
Rules can be applied conditionally, depending on patterns in the CSV
|
||
data.
|
||
This allows flexibility; in particular, it is how you can categorise
|
||
transactions, selecting an appropriate account name based on their
|
||
description (for example).
|
||
There are two ways to write conditional rules: \[dq]if blocks\[dq],
|
||
described here, and \[dq]if tables\[dq], described below.
|
||
.PP
|
||
An if block is the word \f[V]if\f[R] and one or more \[dq]matcher\[dq]
|
||
expressions (can be a word or phrase), one per line, starting either on
|
||
the same or next line; followed by one or more indented rules.
|
||
Eg,
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
if MATCHER
|
||
RULE
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
if
|
||
MATCHER
|
||
MATCHER
|
||
MATCHER
|
||
RULE
|
||
RULE
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If any of the matchers succeeds, all of the indented rules will be
|
||
applied.
|
||
They are usually field assignments, but the following special rules may
|
||
also be used within an if block:
|
||
.IP \[bu] 2
|
||
\f[V]skip\f[R] - skips the matched CSV record (generating no transaction
|
||
from it)
|
||
.IP \[bu] 2
|
||
\f[V]end\f[R] - skips the rest of the current CSV file.
|
||
.PP
|
||
Some examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# if the record contains \[dq]groceries\[dq], set account2 to \[dq]expenses:groceries\[dq]
|
||
if groceries
|
||
account2 expenses:groceries
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# if the record contains any of these phrases, set account2 and a transaction comment as shown
|
||
if
|
||
monthly service fee
|
||
atm transaction fee
|
||
banking thru software
|
||
account2 expenses:business:banking
|
||
comment XXX deductible ? check it
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# if an empty record is seen (assuming five fields), ignore the rest of the CSV file
|
||
if ,,,,
|
||
end
|
||
\f[R]
|
||
.fi
|
||
.SS Matchers
|
||
.PP
|
||
There are two kinds:
|
||
.IP "1." 3
|
||
A record matcher is a word or single-line text fragment or regular
|
||
expression (\f[V]REGEX\f[R]), which hledger will try to match
|
||
case-insensitively anywhere within the CSV record.
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Eg: \f[V]whole foods\f[R]
|
||
.IP "2." 3
|
||
A field matcher is preceded with a percent sign and CSV field name
|
||
(\f[V]%CSVFIELD REGEX\f[R]).
|
||
hledger will try to match these just within the named CSV field.
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Eg: \f[V]%date 2023\f[R]
|
||
.PP
|
||
The regular expression is (as usual in hledger) a POSIX extended regular
|
||
expression, that also supports GNU word boundaries (\f[V]\[rs]b\f[R],
|
||
\f[V]\[rs]B\f[R], \f[V]\[rs]<\f[R], \f[V]\[rs]>\f[R]), and nothing else.
|
||
If you have trouble, see \[dq]Regular expressions\[dq] in the hledger
|
||
manual (https://hledger.org/hledger.html#regular-expressions).
|
||
.PP
|
||
With record matchers, it\[aq]s important to know that the record matched
|
||
is not the original CSV record, but a modified one: separators will be
|
||
converted to commas, and enclosing double quotes (but not enclosing
|
||
whitespace) are removed.
|
||
So for example, when reading an SSV file, if the original record was:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-01; \[dq]Acme, Inc.\[dq]; 1,000
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
the regex would see, and try to match, this modified record text:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-01,Acme, Inc., 1,000
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
When an if block has multiple matchers, they are combined as follows:
|
||
.IP \[bu] 2
|
||
By default they are OR\[aq]d (any one of them can match)
|
||
.IP \[bu] 2
|
||
When a matcher is preceded by ampersand (\f[V]&\f[R]) it will be
|
||
AND\[aq]ed with the previous matcher (both of them must match).
|
||
.PP
|
||
There\[aq]s not yet an easy syntax to negate a matcher.
|
||
.SS \f[V]if\f[R] table
|
||
.PP
|
||
\[dq]if tables\[dq] are an alternative to if blocks; they can express
|
||
many matchers and field assignments in a more compact tabular format,
|
||
like this:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
if,HLEDGERFIELD1,HLEDGERFIELD2,...
|
||
MATCHERA,VALUE1,VALUE2,...
|
||
MATCHERB,VALUE1,VALUE2,...
|
||
MATCHERC,VALUE1,VALUE2,...
|
||
<empty line>
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The first character after \f[V]if\f[R] is taken to be the separator for
|
||
the rest of the table.
|
||
It should be a non-alphanumeric character like \f[V],\f[R] or
|
||
\f[V]|\f[R] that does not appear anywhere else in the table.
|
||
(Note: it is unrelated to the CSV file\[aq]s separator.)
|
||
Whitespace can be used in the matcher lines for readability, but not in
|
||
the if line currently.
|
||
The table must be terminated by an empty line (or end of file).
|
||
Each line must contain the same number of separators; empty values are
|
||
allowed.
|
||
.PP
|
||
The above means: try all of the matchers; whenever a matcher succeeds,
|
||
assign all of the values on that line to the corresponding hledger
|
||
fields; later lines can overrider earlier ones.
|
||
It is equivalent to this sequence of if blocks:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
if MATCHERA
|
||
HLEDGERFIELD1 VALUE1
|
||
HLEDGERFIELD2 VALUE2
|
||
...
|
||
|
||
if MATCHERB
|
||
HLEDGERFIELD1 VALUE1
|
||
HLEDGERFIELD2 VALUE2
|
||
...
|
||
|
||
if MATCHERC
|
||
HLEDGERFIELD1 VALUE1
|
||
HLEDGERFIELD2 VALUE2
|
||
...
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
if,account2,comment
|
||
atm transaction fee,expenses:business:banking,deductible? check it
|
||
%description groceries,expenses:groceries,
|
||
2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out
|
||
\f[R]
|
||
.fi
|
||
.SS \f[V]balance-type\f[R]
|
||
.PP
|
||
Balance assertions generated by assigning to balanceN are of the simple
|
||
\f[V]=\f[R] type by default, which is a single-commodity,
|
||
subaccount-excluding assertion.
|
||
You may find the subaccount-including variants more useful, eg if you
|
||
have created some virtual subaccounts of checking to help with
|
||
budgeting.
|
||
You can select a different type of assertion with the
|
||
\f[V]balance-type\f[R] rule:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# balance assertions will consider all commodities and all subaccounts
|
||
balance-type ==*
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Here are the balance assertion types for quick reference:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
= single commodity, exclude subaccounts
|
||
=* single commodity, include subaccounts
|
||
== multi commodity, exclude subaccounts
|
||
==* multi commodity, include subaccounts
|
||
\f[R]
|
||
.fi
|
||
.SS \f[V]include\f[R]
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
include RULESFILE
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This includes the contents of another CSV rules file at this point.
|
||
\f[V]RULESFILE\f[R] is an absolute file path or a path relative to the
|
||
current file\[aq]s directory.
|
||
This can be useful for sharing common rules between several rules files,
|
||
eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# someaccount.csv.rules
|
||
|
||
## someaccount-specific rules
|
||
fields date,description,amount
|
||
account1 assets:someaccount
|
||
account2 expenses:misc
|
||
|
||
## common rules
|
||
include categorisation.rules
|
||
\f[R]
|
||
.fi
|
||
.SS Working with CSV
|
||
.PP
|
||
Some tips:
|
||
.SS Rapid feedback
|
||
.PP
|
||
It\[aq]s a good idea to get rapid feedback while
|
||
creating/troubleshooting CSV rules.
|
||
Here\[aq]s a good way, using entr from eradman.com/entrproject:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ ls foo.csv* | entr bash -c \[aq]echo ----; hledger -f foo.csv print desc:SOMEDESC\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
A desc: query (eg) is used to select just one, or a few, transactions of
|
||
interest.
|
||
\[dq]bash -c\[dq] is used to run multiple commands, so we can echo a
|
||
separator each time the command re-runs, making it easier to read the
|
||
output.
|
||
.SS Valid CSV
|
||
.PP
|
||
Note that hledger will only accept valid CSV conforming to RFC 4180, and
|
||
equivalent SSV and TSV formats (like RFC 4180 but with semicolon or tab
|
||
as separators).
|
||
This means, eg:
|
||
.IP \[bu] 2
|
||
Values may be enclosed in double quotes, or not.
|
||
Enclosing in single quotes is not allowed.
|
||
(Eg \f[V]\[aq]A\[aq],\[aq]B\[aq]\f[R] is rejected.)
|
||
.IP \[bu] 2
|
||
When values are enclosed in double quotes, spaces outside the quotes are
|
||
not allowed.
|
||
(Eg \f[V]\[dq]A\[dq], \[dq]B\[dq]\f[R] is rejected.)
|
||
.IP \[bu] 2
|
||
When values are not enclosed in quotes, they may not contain double
|
||
quotes.
|
||
(Eg \f[V]A\[dq]A, B\f[R] is rejected.)
|
||
.PP
|
||
If your CSV/SSV/TSV is not valid in this sense, you\[aq]ll need to
|
||
transform it before reading with hledger.
|
||
Try using sed, or a more permissive CSV parser like python\[aq]s csv
|
||
lib.
|
||
.SS File Extension
|
||
.PP
|
||
To help hledger choose the CSV file reader and show the right error
|
||
messages (and choose the right field separator character by default),
|
||
it\[aq]s best if CSV/SSV/TSV files are named with a \f[V].csv\f[R],
|
||
\f[V].ssv\f[R] or \f[V].tsv\f[R] filename extension.
|
||
(More about this at Data formats.)
|
||
.PP
|
||
When reading files with the \[dq]wrong\[dq] extension, you can ensure
|
||
the CSV reader (and the default field separator) by prefixing the file
|
||
path with \f[V]csv:\f[R], \f[V]ssv:\f[R] or \f[V]tsv:\f[R]: Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f ssv:foo.dat print
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
You can also override the default field separator with a separator rule
|
||
if needed.
|
||
.SS Reading CSV from standard input
|
||
.PP
|
||
You\[aq]ll need the file format prefix when reading CSV from stdin also,
|
||
since hledger assumes journal format by default.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ cat foo.dat | hledger -f ssv:- print
|
||
\f[R]
|
||
.fi
|
||
.SS Reading multiple CSV files
|
||
.PP
|
||
If you use multiple \f[V]-f\f[R] options to read multiple CSV files at
|
||
once, hledger will look for a correspondingly-named rules file for each
|
||
CSV file.
|
||
But if you use the \f[V]--rules-file\f[R] option, that rules file will
|
||
be used for all the CSV files.
|
||
.SS Reading files specified by rule
|
||
.PP
|
||
Instead of specifying a CSV file in the command line, you can specify a
|
||
rules file, as in \f[V]hledger -f foo.csv.rules CMD\f[R].
|
||
By default this will read data from foo.csv in the same directory, but
|
||
you can add a source rule to specify a different data file, perhaps
|
||
located in your web browser\[aq]s download directory.
|
||
.PP
|
||
This feature was added in hledger 1.30, so you won\[aq]t see it in most
|
||
CSV rules examples.
|
||
But it helps remove some of the busywork of managing CSV downloads.
|
||
Most of your financial institutions\[aq]s default CSV filenames are
|
||
different and can be recognised by a glob pattern.
|
||
So you can put a rule like \f[V]source Checking1*.csv\f[R] in
|
||
foo-checking.csv.rules, and then periodically follow a workflow like:
|
||
.IP "1." 3
|
||
Download CSV from Foo\[aq]s website, using your browser\[aq]s defaults
|
||
.IP "2." 3
|
||
Run \f[V]hledger import foo-checking.csv.rules\f[R] to import any new
|
||
transactions
|
||
.PP
|
||
After import, you can: discard the CSV, or leave it where it is for a
|
||
while, or move it into your archives, as you prefer.
|
||
If you do nothing, next time your browser will save something like
|
||
Checking1-2.csv, and hledger will use that because of the \f[V]*\f[R]
|
||
wild card and because it is the most recent.
|
||
.SS Valid transactions
|
||
.PP
|
||
After reading a CSV file, hledger post-processes and validates the
|
||
generated journal entries as it would for a journal file - balancing
|
||
them, applying balance assignments, and canonicalising amount styles.
|
||
Any errors at this stage will be reported in the usual way, displaying
|
||
the problem entry.
|
||
.PP
|
||
There is one exception: balance assertions, if you have generated them,
|
||
will not be checked, since normally these will work only when the CSV
|
||
data is part of the main journal.
|
||
If you do need to check balance assertions generated from CSV right
|
||
away, pipe into another hledger:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f file.csv print | hledger -f- print
|
||
\f[R]
|
||
.fi
|
||
.SS Deduplicating, importing
|
||
.PP
|
||
When you download a CSV file periodically, eg to get your latest bank
|
||
transactions, the new file may overlap with the old one, containing some
|
||
of the same records.
|
||
.PP
|
||
The import command will (a) detect the new transactions, and (b) append
|
||
just those transactions to your main journal.
|
||
It is idempotent, so you don\[aq]t have to remember how many times you
|
||
ran it or with which version of the CSV.
|
||
(It keeps state in a hidden \f[V].latest.FILE.csv\f[R] file.)
|
||
This is the easiest way to import CSV data.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# download the latest CSV files, then run this command.
|
||
# Note, no -f flags needed here.
|
||
$ hledger import *.csv [--dry]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This method works for most CSV files.
|
||
(Where records have a stable chronological order, and new records appear
|
||
only at the new end.)
|
||
.PP
|
||
A number of other tools and workflows, hledger-specific and otherwise,
|
||
exist for converting, deduplicating, classifying and managing CSV data.
|
||
See:
|
||
.IP \[bu] 2
|
||
https://hledger.org/cookbook.html#setups-and-workflows
|
||
.IP \[bu] 2
|
||
https://plaintextaccounting.org -> data import/conversion
|
||
.SS Setting amounts
|
||
.PP
|
||
Continuing from amount field above, here are more tips on handling
|
||
various amount-setting situations:
|
||
.IP "1." 3
|
||
\f[B]If the amount is in a single CSV field:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
.RS 4
|
||
.IP "a." 3
|
||
\f[B]If its sign indicates direction of flow:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Assign it to \f[V]amountN\f[R], to set the Nth posting\[aq]s amount.
|
||
N is usually 1 or 2 but can go up to 99.
|
||
.IP "b." 3
|
||
\f[B]If another field indicates direction of flow:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Use one or more conditional rules to set the appropriate amount sign.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# assume a withdrawal unless Type contains \[dq]deposit\[dq]:
|
||
amount1 -%Amount
|
||
if %Type deposit
|
||
amount1 %Amount
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP "2." 3
|
||
\f[B]If the amount is in one of two CSV fields (eg Debit and
|
||
Credit):\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
.RS 4
|
||
.IP "a." 3
|
||
\f[B]If both fields are unsigned:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Assign the fields to \f[V]amountN-in\f[R] and \f[V]amountN-out\f[R].
|
||
This sets posting N\[aq]s amount to whichever of these has a non-zero
|
||
value.
|
||
If it\[aq]s the -out value, the amount will be negated.
|
||
.IP "b." 3
|
||
\f[B]If either field is signed:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Use a conditional rule to flip the sign when needed.
|
||
Eg below, the -out value already has a minus sign so we undo
|
||
hledger\[aq]s automatic negating by negating once more (but only if the
|
||
field is non-empty, so that we don\[aq]t leave a minus sign by itself):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields date, description, amount1-in, amount1-out
|
||
if %amount1-out [1-9]
|
||
amount1-out -%amount1-out
|
||
\f[R]
|
||
.fi
|
||
.IP "c." 3
|
||
\f[B]If both fields can contain a non-zero value (or both can be
|
||
empty):\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
The -in/-out rules normally choose the value which is
|
||
non-zero/non-empty.
|
||
Some value pairs can be ambiguous, such as \f[V]1\f[R] and
|
||
\f[V]none\f[R].
|
||
For such cases, use conditional rules to help select the amount.
|
||
Eg, to handle the above you could select the value containing non-zero
|
||
digits:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields date, description, in, out
|
||
if %in [1-9]
|
||
amount1 %in
|
||
if %out [1-9]
|
||
amount1 %out
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP "3." 3
|
||
\f[B]If you want posting 2\[aq]s amount converted to cost:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Use the unnumbered \f[V]amount\f[R] (or \f[V]amount-in\f[R] and
|
||
\f[V]amount-out\f[R]) syntax.
|
||
.IP "4." 3
|
||
\f[B]If the CSV has only balance amounts, not transaction amounts:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Assign to \f[V]balanceN\f[R], to set a balance assignment on the Nth
|
||
posting, causing the posting\[aq]s amount to be calculated
|
||
automatically.
|
||
\f[V]balance\f[R] with no number is equivalent to \f[V]balance1\f[R].
|
||
In this situation hledger is more likely to guess the wrong default
|
||
account name, so you may need to set that explicitly.
|
||
.SS Amount signs
|
||
.PP
|
||
There is some special handling making it easier to parse and to reverse
|
||
amount signs.
|
||
(This only works for whole amounts, not for cost amounts such as COST in
|
||
\f[V]amount1 AMT \[at] COST\f[R]):
|
||
.IP \[bu] 2
|
||
\f[B]If an amount value begins with a plus sign:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
that will be removed: \f[V]+AMT\f[R] becomes \f[V]AMT\f[R]
|
||
.IP \[bu] 2
|
||
\f[B]If an amount value is parenthesised:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
it will be de-parenthesised and sign-flipped: \f[V](AMT)\f[R] becomes
|
||
\f[V]-AMT\f[R]
|
||
.IP \[bu] 2
|
||
\f[B]If an amount value has two minus signs (or two sets of parentheses,
|
||
or a minus sign and parentheses):\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
they cancel out and will be removed: \f[V]--AMT\f[R] or \f[V]-(AMT)\f[R]
|
||
becomes \f[V]AMT\f[R]
|
||
.IP \[bu] 2
|
||
\f[B]If an amount value contains just a sign (or just a set of
|
||
parentheses):\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
that is removed, making it an empty value.
|
||
\f[V]\[dq]+\[dq]\f[R] or \f[V]\[dq]-\[dq]\f[R] or \f[V]\[dq]()\[dq]\f[R]
|
||
becomes \f[V]\[dq]\[dq]\f[R].
|
||
.PP
|
||
It\[aq]s not possible (without preprocessing the CSV) to set an amount
|
||
to its absolute value, ie discard its sign.
|
||
.SS Setting currency/commodity
|
||
.PP
|
||
If the currency/commodity symbol is included in the CSV\[aq]s amount
|
||
field(s):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-01,foo,$123.00
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
you don\[aq]t have to do anything special for the commodity symbol, it
|
||
will be assigned as part of the amount.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields date,description,amount
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-01 foo
|
||
expenses:unknown $123.00
|
||
income:unknown $-123.00
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If the currency is provided as a separate CSV field:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-01,foo,USD,123.00
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
You can assign that to the \f[V]currency\f[R] pseudo-field, which has
|
||
the special effect of prepending itself to every amount in the
|
||
transaction (on the left, with no separating space):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields date,description,currency,amount
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-01 foo
|
||
expenses:unknown USD123.00
|
||
income:unknown USD-123.00
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Or, you can use a field assignment to construct the amount yourself,
|
||
with more control.
|
||
Eg to put the symbol on the right, and separated by a space:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields date,description,cur,amt
|
||
amount %amt %cur
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-01 foo
|
||
expenses:unknown 123.00 USD
|
||
income:unknown -123.00 USD
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note we used a temporary field name (\f[V]cur\f[R]) that is not
|
||
\f[V]currency\f[R] - that would trigger the prepending effect, which we
|
||
don\[aq]t want here.
|
||
.SS Amount decimal places
|
||
.PP
|
||
Like amounts in a journal file, the amounts generated by CSV rules like
|
||
\f[V]amount1\f[R] influence commodity display styles, such as the number
|
||
of decimal places displayed in reports.
|
||
.PP
|
||
The original amounts as written in the CSV file do not affect display
|
||
style (because we don\[aq]t yet reliably know their commodity).
|
||
.SS Referencing other fields
|
||
.PP
|
||
In field assignments, you can interpolate only CSV fields, not hledger
|
||
fields.
|
||
In the example below, there\[aq]s both a CSV field and a hledger field
|
||
named amount1, but %amount1 always means the CSV field, not the hledger
|
||
field:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# Name the third CSV field \[dq]amount1\[dq]
|
||
fields date,description,amount1
|
||
|
||
# Set hledger\[aq]s amount1 to the CSV amount1 field followed by USD
|
||
amount1 %amount1 USD
|
||
|
||
# Set comment to the CSV amount1 (not the amount1 assigned above)
|
||
comment %amount1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Here, since there\[aq]s no CSV amount1 field, %amount1 will produce a
|
||
literal \[dq]amount1\[dq]:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fields date,description,csvamount
|
||
amount1 %csvamount USD
|
||
# Can\[aq]t interpolate amount1 here
|
||
comment %amount1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
When there are multiple field assignments to the same hledger field,
|
||
only the last one takes effect.
|
||
Here, comment\[aq]s value will be be B, or C if \[dq]something\[dq] is
|
||
matched, but never A:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
comment A
|
||
comment B
|
||
if something
|
||
comment C
|
||
\f[R]
|
||
.fi
|
||
.SS How CSV rules are evaluated
|
||
.PP
|
||
Here\[aq]s how to think of CSV rules being evaluated (if you really need
|
||
to).
|
||
First,
|
||
.IP \[bu] 2
|
||
\f[V]include\f[R] - all includes are inlined, from top to bottom, depth
|
||
first.
|
||
(At each include point the file is inlined and scanned for further
|
||
includes, recursively, before proceeding.)
|
||
.PP
|
||
Then \[dq]global\[dq] rules are evaluated, top to bottom.
|
||
If a rule is repeated, the last one wins:
|
||
.IP \[bu] 2
|
||
\f[V]skip\f[R] (at top level)
|
||
.IP \[bu] 2
|
||
\f[V]date-format\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]newest-first\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]fields\f[R] - names the CSV fields, optionally sets up initial
|
||
assignments to hledger fields
|
||
.PP
|
||
Then for each CSV record in turn:
|
||
.IP \[bu] 2
|
||
test all \f[V]if\f[R] blocks.
|
||
If any of them contain a \f[V]end\f[R] rule, skip all remaining CSV
|
||
records.
|
||
Otherwise if any of them contain a \f[V]skip\f[R] rule, skip that many
|
||
CSV records.
|
||
If there are multiple matched \f[V]skip\f[R] rules, the first one wins.
|
||
.IP \[bu] 2
|
||
collect all field assignments at top level and in matched \f[V]if\f[R]
|
||
blocks.
|
||
When there are multiple assignments for a field, keep only the last one.
|
||
.IP \[bu] 2
|
||
compute a value for each hledger field - either the one that was
|
||
assigned to it (and interpolate the %CSVFIELD references), or a default
|
||
.IP \[bu] 2
|
||
generate a hledger transaction (journal entry) from these values.
|
||
.PP
|
||
This is all part of the CSV reader, one of several readers hledger can
|
||
use to parse input files.
|
||
When all files have been read successfully, the transactions are passed
|
||
as input to whichever hledger command the user specified.
|
||
.PP
|
||
.SS Well factored rules
|
||
.PP
|
||
Some things than can help reduce duplication and complexity in rules
|
||
files:
|
||
.IP \[bu] 2
|
||
Extracting common rules usable with multiple CSV files into a
|
||
\f[V]common.rules\f[R], and adding \f[V]include common.rules\f[R] to
|
||
each CSV\[aq]s rules file.
|
||
.IP \[bu] 2
|
||
Splitting if blocks into smaller if blocks, extracting the frequently
|
||
used parts.
|
||
.SS CSV rules examples
|
||
.SS Bank of Ireland
|
||
.PP
|
||
Here\[aq]s a CSV with two amount fields (Debit and Credit), and a
|
||
balance field, which we can use to add balance assertions, which is not
|
||
necessary but provides extra error checking:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Date,Details,Debit,Credit,Balance
|
||
07/12/2012,LODGMENT 529898,,10.0,131.21
|
||
07/12/2012,PAYMENT,5,,126
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# bankofireland-checking.csv.rules
|
||
|
||
# skip the header line
|
||
skip
|
||
|
||
# name the csv fields, and assign some of them as journal entry fields
|
||
fields date, description, amount-out, amount-in, balance
|
||
|
||
# We generate balance assertions by assigning to \[dq]balance\[dq]
|
||
# above, but you may sometimes need to remove these because:
|
||
#
|
||
# - the CSV balance differs from the true balance,
|
||
# by up to 0.0000000000005 in my experience
|
||
#
|
||
# - it is sometimes calculated based on non-chronological ordering,
|
||
# eg when multiple transactions clear on the same day
|
||
|
||
# date is in UK/Ireland format
|
||
date-format %d/%m/%Y
|
||
|
||
# set the currency
|
||
currency EUR
|
||
|
||
# set the base account for all txns
|
||
account1 assets:bank:boi:checking
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f bankofireland-checking.csv print
|
||
2012-12-07 LODGMENT 529898
|
||
assets:bank:boi:checking EUR10.0 = EUR131.2
|
||
income:unknown EUR-10.0
|
||
|
||
2012-12-07 PAYMENT
|
||
assets:bank:boi:checking EUR-5.0 = EUR126.0
|
||
expenses:unknown EUR5.0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The balance assertions don\[aq]t raise an error above, because we\[aq]re
|
||
reading directly from CSV, but they will be checked if these entries are
|
||
imported into a journal file.
|
||
.SS Coinbase
|
||
.PP
|
||
A simple example with some CSV from Coinbase.
|
||
The spot price is recorded using cost notation.
|
||
The legacy \f[V]amount\f[R] field name conveniently sets amount 2
|
||
(posting 2\[aq]s amount) to the total cost.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes
|
||
# 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,\[dq]\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]Received 100.00 USDC from an external account\[dq]
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# coinbase.csv.rules
|
||
skip 1
|
||
fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes
|
||
date %Timestamp
|
||
date-format %Y-%m-%dT%T%Z
|
||
description %Notes
|
||
account1 assets:coinbase:cc
|
||
amount %Quantity_Transacted %Asset \[at] %Spot_Price_at_Transaction %Spot_Price_Currency
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -f coinbase.csv
|
||
2021-12-30 Received 100.00 USDC from an external account
|
||
assets:coinbase:cc 100 USDC \[at] 0.740000 GBP
|
||
income:unknown -74.000000 GBP
|
||
\f[R]
|
||
.fi
|
||
.SS Amazon
|
||
.PP
|
||
Here we convert amazon.com order history, and use an if block to
|
||
generate a third posting if there\[aq]s a fee.
|
||
(In practice you\[aq]d probably get this data from your bank instead,
|
||
but it\[aq]s an example.)
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
\[dq]Date\[dq],\[dq]Type\[dq],\[dq]To/From\[dq],\[dq]Name\[dq],\[dq]Status\[dq],\[dq]Amount\[dq],\[dq]Fees\[dq],\[dq]Transaction ID\[dq]
|
||
\[dq]Jul 29, 2012\[dq],\[dq]Payment\[dq],\[dq]To\[dq],\[dq]Foo.\[dq],\[dq]Completed\[dq],\[dq]$20.00\[dq],\[dq]$0.00\[dq],\[dq]16000000000000DGLNJPI1P9B8DKPVHL\[dq]
|
||
\[dq]Jul 30, 2012\[dq],\[dq]Payment\[dq],\[dq]To\[dq],\[dq]Adapteva, Inc.\[dq],\[dq]Completed\[dq],\[dq]$25.00\[dq],\[dq]$1.00\[dq],\[dq]17LA58JSKRD4HDGLNJPI1P9B8DKPVHL\[dq]
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# amazon-orders.csv.rules
|
||
|
||
# skip one header line
|
||
skip 1
|
||
|
||
# name the csv fields, and assign the transaction\[aq]s date, amount and code.
|
||
# Avoided the \[dq]status\[dq] and \[dq]amount\[dq] hledger field names to prevent confusion.
|
||
fields date, _, toorfrom, name, amzstatus, amzamount, fees, code
|
||
|
||
# how to parse the date
|
||
date-format %b %-d, %Y
|
||
|
||
# combine two fields to make the description
|
||
description %toorfrom %name
|
||
|
||
# save the status as a tag
|
||
comment status:%amzstatus
|
||
|
||
# set the base account for all transactions
|
||
account1 assets:amazon
|
||
# leave amount1 blank so it can balance the other(s).
|
||
# I\[aq]m assuming amzamount excludes the fees, don\[aq]t remember
|
||
|
||
# set a generic account2
|
||
account2 expenses:misc
|
||
amount2 %amzamount
|
||
# and maybe refine it further:
|
||
#include categorisation.rules
|
||
|
||
# add a third posting for fees, but only if they are non-zero.
|
||
if %fees [1-9]
|
||
account3 expenses:fees
|
||
amount3 %fees
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f amazon-orders.csv print
|
||
2012-07-29 (16000000000000DGLNJPI1P9B8DKPVHL) To Foo. ; status:Completed
|
||
assets:amazon
|
||
expenses:misc $20.00
|
||
|
||
2012-07-30 (17LA58JSKRD4HDGLNJPI1P9B8DKPVHL) To Adapteva, Inc. ; status:Completed
|
||
assets:amazon
|
||
expenses:misc $25.00
|
||
expenses:fees $1.00
|
||
\f[R]
|
||
.fi
|
||
.SS Paypal
|
||
.PP
|
||
Here\[aq]s a real-world rules file for (customised) Paypal CSV, with
|
||
some Paypal-specific rules, and a second rules file included:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
\[dq]Date\[dq],\[dq]Time\[dq],\[dq]TimeZone\[dq],\[dq]Name\[dq],\[dq]Type\[dq],\[dq]Status\[dq],\[dq]Currency\[dq],\[dq]Gross\[dq],\[dq]Fee\[dq],\[dq]Net\[dq],\[dq]From Email Address\[dq],\[dq]To Email Address\[dq],\[dq]Transaction ID\[dq],\[dq]Item Title\[dq],\[dq]Item ID\[dq],\[dq]Reference Txn ID\[dq],\[dq]Receipt ID\[dq],\[dq]Balance\[dq],\[dq]Note\[dq]
|
||
\[dq]10/01/2019\[dq],\[dq]03:46:20\[dq],\[dq]PDT\[dq],\[dq]Calm Radio\[dq],\[dq]Subscription Payment\[dq],\[dq]Completed\[dq],\[dq]USD\[dq],\[dq]-6.99\[dq],\[dq]0.00\[dq],\[dq]-6.99\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]memberships\[at]calmradio.com\[dq],\[dq]60P57143A8206782E\[dq],\[dq]MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month\[dq],\[dq]\[dq],\[dq]I-R8YLY094FJYR\[dq],\[dq]\[dq],\[dq]-6.99\[dq],\[dq]\[dq]
|
||
\[dq]10/01/2019\[dq],\[dq]03:46:20\[dq],\[dq]PDT\[dq],\[dq]\[dq],\[dq]Bank Deposit to PP Account \[dq],\[dq]Pending\[dq],\[dq]USD\[dq],\[dq]6.99\[dq],\[dq]0.00\[dq],\[dq]6.99\[dq],\[dq]\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]0TU1544T080463733\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]60P57143A8206782E\[dq],\[dq]\[dq],\[dq]0.00\[dq],\[dq]\[dq]
|
||
\[dq]10/01/2019\[dq],\[dq]08:57:01\[dq],\[dq]PDT\[dq],\[dq]Patreon\[dq],\[dq]PreApproved Payment Bill User Payment\[dq],\[dq]Completed\[dq],\[dq]USD\[dq],\[dq]-7.00\[dq],\[dq]0.00\[dq],\[dq]-7.00\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]support\[at]patreon.com\[dq],\[dq]2722394R5F586712G\[dq],\[dq]Patreon* Membership\[dq],\[dq]\[dq],\[dq]B-0PG93074E7M86381M\[dq],\[dq]\[dq],\[dq]-7.00\[dq],\[dq]\[dq]
|
||
\[dq]10/01/2019\[dq],\[dq]08:57:01\[dq],\[dq]PDT\[dq],\[dq]\[dq],\[dq]Bank Deposit to PP Account \[dq],\[dq]Pending\[dq],\[dq]USD\[dq],\[dq]7.00\[dq],\[dq]0.00\[dq],\[dq]7.00\[dq],\[dq]\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]71854087RG994194F\[dq],\[dq]Patreon* Membership\[dq],\[dq]\[dq],\[dq]2722394R5F586712G\[dq],\[dq]\[dq],\[dq]0.00\[dq],\[dq]\[dq]
|
||
\[dq]10/19/2019\[dq],\[dq]03:02:12\[dq],\[dq]PDT\[dq],\[dq]Wikimedia Foundation, Inc.\[dq],\[dq]Subscription Payment\[dq],\[dq]Completed\[dq],\[dq]USD\[dq],\[dq]-2.00\[dq],\[dq]0.00\[dq],\[dq]-2.00\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]tle\[at]wikimedia.org\[dq],\[dq]K9U43044RY432050M\[dq],\[dq]Monthly donation to the Wikimedia Foundation\[dq],\[dq]\[dq],\[dq]I-R5C3YUS3285L\[dq],\[dq]\[dq],\[dq]-2.00\[dq],\[dq]\[dq]
|
||
\[dq]10/19/2019\[dq],\[dq]03:02:12\[dq],\[dq]PDT\[dq],\[dq]\[dq],\[dq]Bank Deposit to PP Account \[dq],\[dq]Pending\[dq],\[dq]USD\[dq],\[dq]2.00\[dq],\[dq]0.00\[dq],\[dq]2.00\[dq],\[dq]\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]3XJ107139A851061F\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]K9U43044RY432050M\[dq],\[dq]\[dq],\[dq]0.00\[dq],\[dq]\[dq]
|
||
\[dq]10/22/2019\[dq],\[dq]05:07:06\[dq],\[dq]PDT\[dq],\[dq]Noble Benefactor\[dq],\[dq]Subscription Payment\[dq],\[dq]Completed\[dq],\[dq]USD\[dq],\[dq]10.00\[dq],\[dq]-0.59\[dq],\[dq]9.41\[dq],\[dq]noble\[at]bene.fac.tor\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]6L8L1662YP1334033\[dq],\[dq]Joyful Systems\[dq],\[dq]\[dq],\[dq]I-KC9VBGY2GWDB\[dq],\[dq]\[dq],\[dq]9.41\[dq],\[dq]\[dq]
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# paypal-custom.csv.rules
|
||
|
||
# Tips:
|
||
# Export from Activity -> Statements -> Custom -> Activity download
|
||
# Suggested transaction type: \[dq]Balance affecting\[dq]
|
||
# Paypal\[aq]s default fields in 2018 were:
|
||
# \[dq]Date\[dq],\[dq]Time\[dq],\[dq]TimeZone\[dq],\[dq]Name\[dq],\[dq]Type\[dq],\[dq]Status\[dq],\[dq]Currency\[dq],\[dq]Gross\[dq],\[dq]Fee\[dq],\[dq]Net\[dq],\[dq]From Email Address\[dq],\[dq]To Email Address\[dq],\[dq]Transaction ID\[dq],\[dq]Shipping Address\[dq],\[dq]Address Status\[dq],\[dq]Item Title\[dq],\[dq]Item ID\[dq],\[dq]Shipping and Handling Amount\[dq],\[dq]Insurance Amount\[dq],\[dq]Sales Tax\[dq],\[dq]Option 1 Name\[dq],\[dq]Option 1 Value\[dq],\[dq]Option 2 Name\[dq],\[dq]Option 2 Value\[dq],\[dq]Reference Txn ID\[dq],\[dq]Invoice Number\[dq],\[dq]Custom Number\[dq],\[dq]Quantity\[dq],\[dq]Receipt ID\[dq],\[dq]Balance\[dq],\[dq]Address Line 1\[dq],\[dq]Address Line 2/District/Neighborhood\[dq],\[dq]Town/City\[dq],\[dq]State/Province/Region/County/Territory/Prefecture/Republic\[dq],\[dq]Zip/Postal Code\[dq],\[dq]Country\[dq],\[dq]Contact Phone Number\[dq],\[dq]Subject\[dq],\[dq]Note\[dq],\[dq]Country Code\[dq],\[dq]Balance Impact\[dq]
|
||
# This rules file assumes the following more detailed fields, configured in \[dq]Customize report fields\[dq]:
|
||
# \[dq]Date\[dq],\[dq]Time\[dq],\[dq]TimeZone\[dq],\[dq]Name\[dq],\[dq]Type\[dq],\[dq]Status\[dq],\[dq]Currency\[dq],\[dq]Gross\[dq],\[dq]Fee\[dq],\[dq]Net\[dq],\[dq]From Email Address\[dq],\[dq]To Email Address\[dq],\[dq]Transaction ID\[dq],\[dq]Item Title\[dq],\[dq]Item ID\[dq],\[dq]Reference Txn ID\[dq],\[dq]Receipt ID\[dq],\[dq]Balance\[dq],\[dq]Note\[dq]
|
||
|
||
fields date, time, timezone, description_, type, status_, currency, grossamount, feeamount, netamount, fromemail, toemail, code, itemtitle, itemid, referencetxnid, receiptid, balance, note
|
||
|
||
skip 1
|
||
|
||
date-format %-m/%-d/%Y
|
||
|
||
# ignore some paypal events
|
||
if
|
||
In Progress
|
||
Temporary Hold
|
||
Update to
|
||
skip
|
||
|
||
# add more fields to the description
|
||
description %description_ %itemtitle
|
||
|
||
# save some other fields as tags
|
||
comment itemid:%itemid, fromemail:%fromemail, toemail:%toemail, time:%time, type:%type, status:%status_
|
||
|
||
# convert to short currency symbols
|
||
if %currency USD
|
||
currency $
|
||
if %currency EUR
|
||
currency E
|
||
if %currency GBP
|
||
currency P
|
||
|
||
# generate postings
|
||
|
||
# the first posting will be the money leaving/entering my paypal account
|
||
# (negative means leaving my account, in all amount fields)
|
||
account1 assets:online:paypal
|
||
amount1 %netamount
|
||
|
||
# the second posting will be money sent to/received from other party
|
||
# (account2 is set below)
|
||
amount2 -%grossamount
|
||
|
||
# if there\[aq]s a fee, add a third posting for the money taken by paypal.
|
||
if %feeamount [1-9]
|
||
account3 expenses:banking:paypal
|
||
amount3 -%feeamount
|
||
comment3 business:
|
||
|
||
# choose an account for the second posting
|
||
|
||
# override the default account names:
|
||
# if the amount is positive, it\[aq]s income (a debit)
|
||
if %grossamount \[ha][\[ha]-]
|
||
account2 income:unknown
|
||
# if negative, it\[aq]s an expense (a credit)
|
||
if %grossamount \[ha]-
|
||
account2 expenses:unknown
|
||
|
||
# apply common rules for setting account2 & other tweaks
|
||
include common.rules
|
||
|
||
# apply some overrides specific to this csv
|
||
|
||
# Transfers from/to bank. These are usually marked Pending,
|
||
# which can be disregarded in this case.
|
||
if
|
||
Bank Account
|
||
Bank Deposit to PP Account
|
||
description %type for %referencetxnid %itemtitle
|
||
account2 assets:bank:wf:pchecking
|
||
account1 assets:online:paypal
|
||
|
||
# Currency conversions
|
||
if Currency Conversion
|
||
account2 equity:currency conversion
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# common.rules
|
||
|
||
if
|
||
darcs
|
||
noble benefactor
|
||
account2 revenues:foss donations:darcshub
|
||
comment2 business:
|
||
|
||
if
|
||
Calm Radio
|
||
account2 expenses:online:apps
|
||
|
||
if
|
||
electronic frontier foundation
|
||
Patreon
|
||
wikimedia
|
||
Advent of Code
|
||
account2 expenses:dues
|
||
|
||
if Google
|
||
account2 expenses:online:apps
|
||
description google | music
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f paypal-custom.csv print
|
||
2019-10-01 (60P57143A8206782E) Calm Radio MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month ; itemid:, fromemail:simon\[at]joyful.com, toemail:memberships\[at]calmradio.com, time:03:46:20, type:Subscription Payment, status:Completed
|
||
assets:online:paypal $-6.99 = $-6.99
|
||
expenses:online:apps $6.99
|
||
|
||
2019-10-01 (0TU1544T080463733) Bank Deposit to PP Account for 60P57143A8206782E ; itemid:, fromemail:, toemail:simon\[at]joyful.com, time:03:46:20, type:Bank Deposit to PP Account, status:Pending
|
||
assets:online:paypal $6.99 = $0.00
|
||
assets:bank:wf:pchecking $-6.99
|
||
|
||
2019-10-01 (2722394R5F586712G) Patreon Patreon* Membership ; itemid:, fromemail:simon\[at]joyful.com, toemail:support\[at]patreon.com, time:08:57:01, type:PreApproved Payment Bill User Payment, status:Completed
|
||
assets:online:paypal $-7.00 = $-7.00
|
||
expenses:dues $7.00
|
||
|
||
2019-10-01 (71854087RG994194F) Bank Deposit to PP Account for 2722394R5F586712G Patreon* Membership ; itemid:, fromemail:, toemail:simon\[at]joyful.com, time:08:57:01, type:Bank Deposit to PP Account, status:Pending
|
||
assets:online:paypal $7.00 = $0.00
|
||
assets:bank:wf:pchecking $-7.00
|
||
|
||
2019-10-19 (K9U43044RY432050M) Wikimedia Foundation, Inc. Monthly donation to the Wikimedia Foundation ; itemid:, fromemail:simon\[at]joyful.com, toemail:tle\[at]wikimedia.org, time:03:02:12, type:Subscription Payment, status:Completed
|
||
assets:online:paypal $-2.00 = $-2.00
|
||
expenses:dues $2.00
|
||
expenses:banking:paypal ; business:
|
||
|
||
2019-10-19 (3XJ107139A851061F) Bank Deposit to PP Account for K9U43044RY432050M ; itemid:, fromemail:, toemail:simon\[at]joyful.com, time:03:02:12, type:Bank Deposit to PP Account, status:Pending
|
||
assets:online:paypal $2.00 = $0.00
|
||
assets:bank:wf:pchecking $-2.00
|
||
|
||
2019-10-22 (6L8L1662YP1334033) Noble Benefactor Joyful Systems ; itemid:, fromemail:noble\[at]bene.fac.tor, toemail:simon\[at]joyful.com, time:05:07:06, type:Subscription Payment, status:Completed
|
||
assets:online:paypal $9.41 = $9.41
|
||
revenues:foss donations:darcshub $-10.00 ; business:
|
||
expenses:banking:paypal $0.59 ; business:
|
||
\f[R]
|
||
.fi
|
||
.SH Timeclock
|
||
.PP
|
||
The time logging format of timeclock.el, as read by hledger.
|
||
.PP
|
||
hledger can read time logs in timeclock format.
|
||
As with Ledger, these are (a subset of) timeclock.el\[aq]s format,
|
||
containing clock-in and clock-out entries as in the example below.
|
||
The date is a simple date.
|
||
The time format is HH:MM[:SS][+-ZZZZ].
|
||
Seconds and timezone are optional.
|
||
The timezone, if present, must be four digits and is ignored (currently
|
||
the time is always interpreted as a local time).
|
||
Lines beginning with \f[V]#\f[R] or \f[V];\f[R] or \f[V]*\f[R], and
|
||
blank lines, are ignored.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:
|
||
o 2015/03/30 09:20:00
|
||
i 2015/03/31 22:21:45 another:account
|
||
o 2015/04/01 02:00:34
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
hledger treats each clock-in/clock-out pair as a transaction posting
|
||
some number of hours to an account.
|
||
Or if the session spans more than one day, it is split into several
|
||
transactions, one for each day.
|
||
For the above time log, \f[V]hledger print\f[R] generates these journal
|
||
entries:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f t.timeclock print
|
||
2015-03-30 * optional description after 2 spaces ; optional comment, tags:
|
||
(some account) 0.33h
|
||
|
||
2015-03-31 * 22:21-23:59
|
||
(another:account) 1.64h
|
||
|
||
2015-04-01 * 00:00-02:00
|
||
(another:account) 2.01h
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Here is a sample.timeclock to download and some queries to try:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f sample.timeclock balance # current time balances
|
||
$ hledger -f sample.timeclock register -p 2009/3 # sessions in march 2009
|
||
$ hledger -f sample.timeclock register -p weekly --depth 1 --empty # time summary by week
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
To generate time logs, ie to clock in and clock out, you could:
|
||
.IP \[bu] 2
|
||
use emacs and the built-in timeclock.el, or the extended timeclock-x.el
|
||
and perhaps the extras in ledgerutils.el
|
||
.IP \[bu] 2
|
||
at the command line, use these bash aliases:
|
||
\f[V]shell alias ti=\[dq]echo i \[ga]date \[aq]+%Y-%m-%d %H:%M:%S\[aq]\[ga] \[rs]$* >>$TIMELOG\[dq] alias to=\[dq]echo o \[ga]date \[aq]+%Y-%m-%d %H:%M:%S\[aq]\[ga] >>$TIMELOG\[dq]\f[R]
|
||
.IP \[bu] 2
|
||
or use the old \f[V]ti\f[R] and \f[V]to\f[R] scripts in the ledger 2.x
|
||
repository.
|
||
These rely on a \[dq]timeclock\[dq] executable which I think is just the
|
||
ledger 2 executable renamed.
|
||
.PP
|
||
.SH Timedot
|
||
.PP
|
||
\f[V]timedot\f[R] format is hledger\[aq]s human-friendly time logging
|
||
format.
|
||
Compared to \f[V]timeclock\f[R] format, it is
|
||
.IP \[bu] 2
|
||
convenient for quick, approximate, and retroactive time logging
|
||
.IP \[bu] 2
|
||
readable: you can see at a glance where time was spent.
|
||
.PP
|
||
A timedot file contains a series of day entries, which might look like
|
||
this:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-05-01
|
||
hom:errands .... .... ; two hours
|
||
fos:hledger:timedot .. ; half an hour
|
||
per:admin:finance
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
hledger reads this as a transaction on this day with three (unbalanced)
|
||
postings, where each dot represents \[dq]0.25\[dq].
|
||
No commodity is assumed, but normally we interpret it as hours, with
|
||
each dot representing a quarter-hour.
|
||
It\[aq]s convenient, though not required, to group the dots in fours for
|
||
easy reading.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required
|
||
2023-05-01 *
|
||
(hom:errands) 2.00 ; two hours
|
||
(fos:hledger:timedot) 0.50 ; half an hour
|
||
(per:admin:finance) 0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
A transaction begins with a non-indented \f[B]simple date\f[R] (Y-M-D,
|
||
Y/M/D, or Y.M.D).
|
||
It can optionally be preceded by one or more stars and a space, for
|
||
Emacs org mode compatibility.
|
||
It can optionally be followed on the same line by a transaction
|
||
description, and/or a transaction comment following a semicolon.
|
||
.PP
|
||
After the date line are zero or more time postings, consisting of:
|
||
.IP \[bu] 2
|
||
an \f[B]account name\f[R] - any hledger-style account name, optionally
|
||
hierarchical, optionally indented.
|
||
.IP \[bu] 2
|
||
\f[B]two or more spaces\f[R] - a field separator, required if there is
|
||
an amount (as in journal format).
|
||
.IP \[bu] 2
|
||
an optional \f[B]timedot amount\f[R] - dots representing quarter hours,
|
||
or a number representing hours, optionally with a unit suffix.
|
||
.IP \[bu] 2
|
||
an optional \f[B]posting comment\f[R] following a semicolon.
|
||
.PP
|
||
Timedot amounts can be:
|
||
.IP \[bu] 2
|
||
\f[B]dots\f[R]: zero or more period characters (\f[V].\f[R]), each
|
||
representing 0.25.
|
||
Spaces are ignored and can be used for grouping.
|
||
Eg: \f[V].... ..\f[R]
|
||
.IP \[bu] 2
|
||
or a \f[B]number\f[R].
|
||
Eg: \f[V]1.5\f[R]
|
||
.IP \[bu] 2
|
||
or a \f[B]number immediately followed by a unit symbol\f[R] \f[V]s\f[R],
|
||
\f[V]m\f[R], \f[V]h\f[R], \f[V]d\f[R], \f[V]w\f[R], \f[V]mo\f[R], or
|
||
\f[V]y\f[R].
|
||
These are interpreted as seconds, minutes, hours, days weeks, months or
|
||
years, and converted to hours, assuming:
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]60s\f[R] = \f[V]1m\f[R], \f[V]60m\f[R] = \f[V]1h\f[R],
|
||
\f[V]24h\f[R] = \f[V]1d\f[R], \f[V]7d\f[R] = \f[V]1w\f[R], \f[V]30d\f[R]
|
||
= \f[V]1mo\f[R], \f[V]365d\f[R] = \f[V]1y\f[R].
|
||
Eg \f[V]90m\f[R] is parsed as \f[V]1.5\f[R].
|
||
.PP
|
||
There is some added flexibility to help with keeping time log data in
|
||
the same file as your notes, todo lists, etc.:
|
||
.IP \[bu] 2
|
||
Blank lines and lines beginning with \f[V]#\f[R] or \f[V];\f[R] are
|
||
ignored.
|
||
.IP \[bu] 2
|
||
Before the first date line, lines beginning with \f[V]*\f[R] are
|
||
ignored.
|
||
.IP \[bu] 2
|
||
From the first date line onward, one or more \f[V]*\f[R]\[aq]s followed
|
||
by a space at beginning of lines (ie, the headline prefix used by Emacs
|
||
Org mode) is ignored.
|
||
This means the time log can be kept under an Org headline, and date
|
||
lines or time transaction lines can be Org headlines.
|
||
.IP \[bu] 2
|
||
Lines not ending with a double-space and amount are parsed as postings
|
||
with zero amount.
|
||
Note hledger\[aq]s register reports hide these by default (add -E to see
|
||
them).
|
||
.PP
|
||
More examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.
|
||
2016/2/1
|
||
inc:client1 .... .... .... .... .... ....
|
||
fos:haskell .... ..
|
||
biz:research .
|
||
|
||
2016/2/2
|
||
inc:client1 .... ....
|
||
biz:research .
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2016/2/3
|
||
inc:client1 4
|
||
fos:hledger 3
|
||
biz:research 1
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
* Time log
|
||
** 2023-01-01
|
||
*** adm:time .
|
||
*** adm:finance .
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
* 2023 Work Diary
|
||
** Q1
|
||
*** 2023-02-29
|
||
**** DONE
|
||
0700 yoga
|
||
**** UNPLANNED
|
||
**** BEGUN
|
||
hom:chores
|
||
cleaning ...
|
||
water plants
|
||
outdoor - one full watering can
|
||
indoor - light watering
|
||
**** TODO
|
||
adm:planning: trip
|
||
*** LATER
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Reporting:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f a.timedot print date:2016/2/2
|
||
2016-02-02 *
|
||
(inc:client1) 2.00
|
||
|
||
2016-02-02 *
|
||
(biz:research) 0.25
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f a.timedot bal --daily --tree
|
||
Balance changes in 2016-02-01-2016-02-03:
|
||
|
||
|| 2016-02-01d 2016-02-02d 2016-02-03d
|
||
============++========================================
|
||
biz || 0.25 0.25 1.00
|
||
research || 0.25 0.25 1.00
|
||
fos || 1.50 0 3.00
|
||
haskell || 1.50 0 0
|
||
hledger || 0 0 3.00
|
||
inc || 6.00 2.00 4.00
|
||
client1 || 6.00 2.00 4.00
|
||
------------++----------------------------------------
|
||
|| 7.75 2.25 8.00
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Using period instead of colon as account name separator:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2016/2/4
|
||
fos.hledger.timedot 4
|
||
fos.ledger ..
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f a.timedot --alias /\[rs]\[rs]./=: bal --tree
|
||
4.50 fos
|
||
4.00 hledger:timedot
|
||
0.50 ledger
|
||
--------------------
|
||
4.50
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
A sample.timedot file.
|
||
.SH PART 3: REPORTING CONCEPTS
|
||
.SH Time periods
|
||
.PP
|
||
.SS Report start & end date
|
||
.PP
|
||
By default, most hledger reports will show the full span of time
|
||
represented by the journal.
|
||
The report start date will be the earliest transaction or posting date,
|
||
and the report end date will be the latest transaction, posting, or
|
||
market price date.
|
||
.PP
|
||
Often you will want to see a shorter time span, such as the current
|
||
month.
|
||
You can specify a start and/or end date using \f[V]-b/--begin\f[R],
|
||
\f[V]-e/--end\f[R], \f[V]-p/--period\f[R] or a \f[V]date:\f[R] query
|
||
(described below).
|
||
All of these accept the smart date syntax (below).
|
||
.PP
|
||
Some notes:
|
||
.IP \[bu] 2
|
||
End dates are exclusive, as in Ledger, so you should write the date
|
||
\f[I]after\f[R] the last day you want to see in the report.
|
||
.IP \[bu] 2
|
||
As noted in reporting options: among start/end dates specified with
|
||
\f[I]options\f[R], the last (i.e.
|
||
right-most) option takes precedence.
|
||
.IP \[bu] 2
|
||
The effective report start and end dates are the intersection of the
|
||
start/end dates from options and that from \f[V]date:\f[R] queries.
|
||
That is, \f[V]date:2019-01 date:2019 -p\[aq]2000 to 2030\[aq]\f[R]
|
||
yields January 2019, the smallest common time span.
|
||
.IP \[bu] 2
|
||
In some cases a report interval will adjust start/end dates to fall on
|
||
interval boundaries (see below).
|
||
.PP
|
||
Examples:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(12.4n) lw(57.6n).
|
||
T{
|
||
\f[V]-b 2016/3/17\f[R]
|
||
T}@T{
|
||
begin on St.\ Patrick\[cq]s day 2016
|
||
T}
|
||
T{
|
||
\f[V]-e 12/1\f[R]
|
||
T}@T{
|
||
end at the start of december 1st of the current year (11/30 will be the
|
||
last date included)
|
||
T}
|
||
T{
|
||
\f[V]-b thismonth\f[R]
|
||
T}@T{
|
||
all transactions on or after the 1st of the current month
|
||
T}
|
||
T{
|
||
\f[V]-p thismonth\f[R]
|
||
T}@T{
|
||
all transactions in the current month
|
||
T}
|
||
T{
|
||
\f[V]date:2016/3/17..\f[R]
|
||
T}@T{
|
||
the above written as queries instead (\f[V]..\f[R] can also be replaced
|
||
with \f[V]-\f[R])
|
||
T}
|
||
T{
|
||
\f[V]date:..12/1\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[V]date:thismonth..\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[V]date:thismonth\f[R]
|
||
T}@T{
|
||
T}
|
||
.TE
|
||
.SS Smart dates
|
||
.PP
|
||
hledger\[aq]s user interfaces accept a \[dq]smart date\[dq] syntax for
|
||
added convenience.
|
||
Smart dates optionally can be relative to today\[aq]s date, be written
|
||
with english words, and have less-significant parts omitted (missing
|
||
parts are inferred as 1).
|
||
Some examples:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(24.2n) lw(45.8n).
|
||
T{
|
||
\f[V]2004/10/1\f[R], \f[V]2004-01-01\f[R], \f[V]2004.9.1\f[R]
|
||
T}@T{
|
||
exact date, several separators allowed.
|
||
Year is 4+ digits, month is 1-12, day is 1-31
|
||
T}
|
||
T{
|
||
\f[V]2004\f[R]
|
||
T}@T{
|
||
start of year
|
||
T}
|
||
T{
|
||
\f[V]2004/10\f[R]
|
||
T}@T{
|
||
start of month
|
||
T}
|
||
T{
|
||
\f[V]10/1\f[R]
|
||
T}@T{
|
||
month and day in current year
|
||
T}
|
||
T{
|
||
\f[V]21\f[R]
|
||
T}@T{
|
||
day in current month
|
||
T}
|
||
T{
|
||
\f[V]october, oct\f[R]
|
||
T}@T{
|
||
start of month in current year
|
||
T}
|
||
T{
|
||
\f[V]yesterday, today, tomorrow\f[R]
|
||
T}@T{
|
||
-1, 0, 1 days from today
|
||
T}
|
||
T{
|
||
\f[V]last/this/next day/week/month/quarter/year\f[R]
|
||
T}@T{
|
||
-1, 0, 1 periods from the current period
|
||
T}
|
||
T{
|
||
\f[V]in n days/weeks/months/quarters/years\f[R]
|
||
T}@T{
|
||
n periods from the current period
|
||
T}
|
||
T{
|
||
\f[V]n days/weeks/months/quarters/years ahead\f[R]
|
||
T}@T{
|
||
n periods from the current period
|
||
T}
|
||
T{
|
||
\f[V]n days/weeks/months/quarters/years ago\f[R]
|
||
T}@T{
|
||
-n periods from the current period
|
||
T}
|
||
T{
|
||
\f[V]20181201\f[R]
|
||
T}@T{
|
||
8 digit YYYYMMDD with valid year month and day
|
||
T}
|
||
T{
|
||
\f[V]201812\f[R]
|
||
T}@T{
|
||
6 digit YYYYMM with valid year and month
|
||
T}
|
||
.TE
|
||
.PP
|
||
Some counterexamples - malformed digit sequences might give surprising
|
||
results:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(11.4n) lw(58.6n).
|
||
T{
|
||
\f[V]201813\f[R]
|
||
T}@T{
|
||
6 digits with an invalid month is parsed as start of 6-digit year
|
||
T}
|
||
T{
|
||
\f[V]20181301\f[R]
|
||
T}@T{
|
||
8 digits with an invalid month is parsed as start of 8-digit year
|
||
T}
|
||
T{
|
||
\f[V]20181232\f[R]
|
||
T}@T{
|
||
8 digits with an invalid day gives an error
|
||
T}
|
||
T{
|
||
\f[V]201801012\f[R]
|
||
T}@T{
|
||
9+ digits beginning with a valid YYYYMMDD gives an error
|
||
T}
|
||
.TE
|
||
.PP
|
||
\[dq]Today\[aq]s date\[dq] can be overridden with the \f[V]--today\f[R]
|
||
option, in case it\[aq]s needed for testing or for recreating old
|
||
reports.
|
||
(Except for periodic transaction rules, which are not affected by
|
||
\f[V]--today\f[R].)
|
||
.SS Report intervals
|
||
.PP
|
||
A report interval can be specified so that reports like register,
|
||
balance or activity become multi-period, showing each subperiod as a
|
||
separate row or column.
|
||
.PP
|
||
The following standard intervals can be enabled with command-line flags:
|
||
.IP \[bu] 2
|
||
\f[V]-D/--daily\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]-W/--weekly\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]-M/--monthly\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]-Q/--quarterly\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]-Y/--yearly\f[R]
|
||
.PP
|
||
More complex intervals can be specified using \f[V]-p/--period\f[R],
|
||
described below.
|
||
.SS Date adjustment
|
||
.PP
|
||
When there is a report interval (other than daily), report start/end
|
||
dates which have been inferred, eg from the journal, are automatically
|
||
adjusted to natural period boundaries.
|
||
This is convenient for producing simple periodic reports.
|
||
More precisely:
|
||
.IP \[bu] 2
|
||
an inferred start date will be adjusted earlier if needed to fall on a
|
||
natural period boundary
|
||
.IP \[bu] 2
|
||
an inferred end date will be adjusted later if needed to make the last
|
||
period the same length as the others.
|
||
.PP
|
||
By contrast, start/end dates which have been specified explicitly, with
|
||
\f[V]-b\f[R], \f[V]-e\f[R], \f[V]-p\f[R] or \f[V]date:\f[R], will not be
|
||
adjusted (since hledger 1.29).
|
||
This makes it possible to specify non-standard report periods, but it
|
||
also means that if you are specifying a start date, you should pick one
|
||
that\[aq]s on a period boundary if you want to see simple report period
|
||
headings.
|
||
.SS Period expressions
|
||
.PP
|
||
The \f[V]-p/--period\f[R] option specifies a period expression, which is
|
||
a compact way of expressing a start date, end date, and/or report
|
||
interval.
|
||
.PP
|
||
Here\[aq]s a period expression with a start and end date (specifying the
|
||
first quarter of 2009):
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
l.
|
||
T{
|
||
\f[V]-p \[dq]from 2009/1/1 to 2009/4/1\[dq]\f[R]
|
||
T}
|
||
.TE
|
||
.PP
|
||
Several keywords like \[dq]from\[dq] and \[dq]to\[dq] are supported for
|
||
readability; these are optional.
|
||
\[dq]to\[dq] can also be written as \[dq]..\[dq] or \[dq]-\[dq].
|
||
The spaces are also optional, as long as you don\[aq]t run two dates
|
||
together.
|
||
So the following are equivalent to the above:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
l.
|
||
T{
|
||
\f[V]-p \[dq]2009/1/1 2009/4/1\[dq]\f[R]
|
||
T}
|
||
T{
|
||
\f[V]-p2009/1/1to2009/4/1\f[R]
|
||
T}
|
||
T{
|
||
\f[V]-p2009/1/1..2009/4/1\f[R]
|
||
T}
|
||
.TE
|
||
.PP
|
||
Dates are smart dates, so if the current year is 2009, these are also
|
||
equivalent to the above:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
l.
|
||
T{
|
||
\f[V]-p \[dq]1/1 4/1\[dq]\f[R]
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]jan-apr\[dq]\f[R]
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]this year to 4/1\[dq]\f[R]
|
||
T}
|
||
.TE
|
||
.PP
|
||
If you specify only one date, the missing start or end date will be the
|
||
earliest or latest transaction date in the journal:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
l l.
|
||
T{
|
||
\f[V]-p \[dq]from 2009/1/1\[dq]\f[R]
|
||
T}@T{
|
||
everything after january 1, 2009
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]since 2009/1\[dq]\f[R]
|
||
T}@T{
|
||
the same, since is a synonym
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]from 2009\[dq]\f[R]
|
||
T}@T{
|
||
the same
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]to 2009\[dq]\f[R]
|
||
T}@T{
|
||
everything before january 1, 2009
|
||
T}
|
||
.TE
|
||
.PP
|
||
You can also specify a period by writing a single partial or full date:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(14.5n) lw(55.5n).
|
||
T{
|
||
\f[V]-p \[dq]2009\[dq]\f[R]
|
||
T}@T{
|
||
the year 2009; equivalent to \[lq]2009/1/1 to 2010/1/1\[rq]
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]2009/1\[dq]\f[R]
|
||
T}@T{
|
||
the month of january 2009; equivalent to \[lq]2009/1/1 to 2009/2/1\[rq]
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]2009/1/1\[dq]\f[R]
|
||
T}@T{
|
||
the first day of 2009; equivalent to \[lq]2009/1/1 to 2009/1/2\[rq]
|
||
T}
|
||
.TE
|
||
.PP
|
||
or by using the \[dq]Q\[dq] quarter-year syntax (case insensitive):
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(15.3n) lw(54.7n).
|
||
T{
|
||
\f[V]-p \[dq]2009Q1\[dq]\f[R]
|
||
T}@T{
|
||
first quarter of 2009, equivalent to \[lq]2009/1/1 to 2009/4/1\[rq]
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]q4\[dq]\f[R]
|
||
T}@T{
|
||
fourth quarter of the current year
|
||
T}
|
||
.TE
|
||
.SS Period expressions with a report interval
|
||
.PP
|
||
A period expression can also begin with a report interval, separated
|
||
from the start/end dates (if any) by a space or the word \f[V]in\f[R]:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
l.
|
||
T{
|
||
\f[V]-p \[dq]weekly from 2009/1/1 to 2009/4/1\[dq]\f[R]
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]monthly in 2008\[dq]\f[R]
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]quarterly\[dq]\f[R]
|
||
T}
|
||
.TE
|
||
.SS More complex report intervals
|
||
.PP
|
||
Some more complex intervals can be specified within period expressions,
|
||
such as:
|
||
.IP \[bu] 2
|
||
\f[V]biweekly\f[R] (every two weeks)
|
||
.IP \[bu] 2
|
||
\f[V]fortnightly\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]bimonthly\f[R] (every two months)
|
||
.IP \[bu] 2
|
||
\f[V]every day|week|month|quarter|year\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]every N days|weeks|months|quarters|years\f[R]
|
||
.PP
|
||
Weekly on a custom day:
|
||
.IP \[bu] 2
|
||
\f[V]every Nth day of week\f[R] (\f[V]th\f[R], \f[V]nd\f[R],
|
||
\f[V]rd\f[R], or \f[V]st\f[R] are all accepted after the number)
|
||
.IP \[bu] 2
|
||
\f[V]every WEEKDAYNAME\f[R] (full or three-letter english weekday name,
|
||
case insensitive)
|
||
.PP
|
||
Monthly on a custom day:
|
||
.IP \[bu] 2
|
||
\f[V]every Nth day [of month]\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]every Nth WEEKDAYNAME [of month]\f[R]
|
||
.PP
|
||
Yearly on a custom day:
|
||
.IP \[bu] 2
|
||
\f[V]every MM/DD [of year]\f[R] (month number and day of month number)
|
||
.IP \[bu] 2
|
||
\f[V]every MONTHNAME DDth [of year]\f[R] (full or three-letter english
|
||
month name, case insensitive, and day of month number)
|
||
.IP \[bu] 2
|
||
\f[V]every DDth MONTHNAME [of year]\f[R] (equivalent to the above)
|
||
.PP
|
||
Examples:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(26.8n) lw(43.2n).
|
||
T{
|
||
\f[V]-p \[dq]bimonthly from 2008\[dq]\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every 2 weeks\[dq]\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every 5 months from 2009/03\[dq]\f[R]
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every 2nd day of week\[dq]\f[R]
|
||
T}@T{
|
||
periods will go from Tue to Tue
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every Tue\[dq]\f[R]
|
||
T}@T{
|
||
same
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every 15th day\[dq]\f[R]
|
||
T}@T{
|
||
period boundaries will be on 15th of each month
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every 2nd Monday\[dq]\f[R]
|
||
T}@T{
|
||
period boundaries will be on second Monday of each month
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every 11/05\[dq]\f[R]
|
||
T}@T{
|
||
yearly periods with boundaries on 5th of November
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every 5th November\[dq]\f[R]
|
||
T}@T{
|
||
same
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every Nov 5th\[dq]\f[R]
|
||
T}@T{
|
||
same
|
||
T}
|
||
.TE
|
||
.PP
|
||
Show historical balances at end of the 15th day of each month (N is an
|
||
end date, exclusive as always):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance -H -p \[dq]every 16th day\[dq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Group postings from the start of wednesday to end of the following
|
||
tuesday (N is both (inclusive) start date and (exclusive) end date):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register checking -p \[dq]every 3rd day of week\[dq]
|
||
\f[R]
|
||
.fi
|
||
.SS Multiple weekday intervals
|
||
.PP
|
||
This special form is also supported:
|
||
.IP \[bu] 2
|
||
\f[V]every WEEKDAYNAME,WEEKDAYNAME,...\f[R] (full or three-letter
|
||
english weekday names, case insensitive)
|
||
.PP
|
||
Also, \f[V]weekday\f[R] and \f[V]weekendday\f[R] are shorthand for
|
||
\f[V]mon,tue,wed,thu,fri\f[R] and \f[V]sat,sun\f[R].
|
||
.PP
|
||
This is mainly intended for use with \f[V]--forecast\f[R], to generate
|
||
periodic transactions on arbitrary days of the week.
|
||
It may be less useful with \f[V]-p\f[R], since it divides each week into
|
||
subperiods of unequal length, which is unusual.
|
||
(Related: #1632)
|
||
.PP
|
||
Examples:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(17.8n) lw(52.2n).
|
||
T{
|
||
\f[V]-p \[dq]every mon,wed,fri\[dq]\f[R]
|
||
T}@T{
|
||
dates will be Mon, Wed, Fri; periods will be Mon-Tue, Wed-Thu, Fri-Sun
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every weekday\[dq]\f[R]
|
||
T}@T{
|
||
dates will be Mon, Tue, Wed, Thu, Fri; periods will be Mon, Tue, Wed,
|
||
Thu, Fri-Sun
|
||
T}
|
||
T{
|
||
\f[V]-p \[dq]every weekendday\[dq]\f[R]
|
||
T}@T{
|
||
dates will be Sat, Sun; periods will be Sat, Sun-Fri
|
||
T}
|
||
.TE
|
||
.SH Depth
|
||
.PP
|
||
With the \f[V]--depth NUM\f[R] option (short form: \f[V]-NUM\f[R]),
|
||
reports will show accounts only to the specified depth, hiding deeper
|
||
subaccounts.
|
||
Use this when you want a summary with less detail.
|
||
This flag has the same effect as a \f[V]depth:\f[R] query argument:
|
||
\f[V]depth:2\f[R], \f[V]--depth=2\f[R] or \f[V]-2\f[R] are equivalent.
|
||
.SH Queries
|
||
.PP
|
||
One of hledger\[aq]s strengths is being able to quickly report on a
|
||
precise subset of your data.
|
||
Most hledger commands accept optional query arguments to restrict their
|
||
scope.
|
||
The syntax is as follows:
|
||
.IP \[bu] 2
|
||
Zero or more space-separated query terms.
|
||
These are most often account name substrings:
|
||
.RS 2
|
||
.PP
|
||
\f[V]utilities food:groceries\f[R]
|
||
.RE
|
||
.IP \[bu] 2
|
||
Terms with spaces or other special characters should be enclosed in
|
||
quotes:
|
||
.RS 2
|
||
.PP
|
||
\f[V]\[dq]personal care\[dq]\f[R]
|
||
.RE
|
||
.IP \[bu] 2
|
||
Regular expressions are also supported:
|
||
.RS 2
|
||
.PP
|
||
\f[V]\[dq]\[ha]expenses\[rs]b\[dq]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]\[dq]accounts (payable|receivable)\[dq]\f[R]
|
||
.RE
|
||
.IP \[bu] 2
|
||
Add a query type prefix to match other parts of the data:
|
||
.RS 2
|
||
.PP
|
||
\f[V]date:202312-\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]status:\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]desc:amazon\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]cur:USD\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]\[dq]amt:>0\[dq]\f[R]
|
||
.RE
|
||
.IP \[bu] 2
|
||
Add a \f[V]not:\f[R] prefix to negate:
|
||
.RS 2
|
||
.PP
|
||
\f[V]not:cur:USD\f[R]
|
||
.RE
|
||
.IP \[bu] 2
|
||
Multiple unlike terms are AND-ed, multiple like terms are OR-ed
|
||
.RS 2
|
||
.PP
|
||
\f[V]date:2022 desc:amazon desc:amzn\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
(all transactions with \[dq]amazon\[dq] or \[dq]amzn\[dq] in description
|
||
during 2022)
|
||
.RE
|
||
.SS Query types
|
||
.PP
|
||
Here are the types of query term available.
|
||
Remember these can also be prefixed with \f[B]\f[VB]not:\f[B]\f[R] to
|
||
convert them into a negative match.
|
||
.PP
|
||
\f[B]\f[VB]acct:REGEX\f[B], \f[VB]REGEX\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match account names containing this (case insensitive) regular
|
||
expression.
|
||
This is the default query type when there is no prefix, and regular
|
||
expression syntax is typically not needed, so usually we just write an
|
||
account name substring, like \f[V]expenses\f[R] or \f[V]food\f[R].
|
||
.PP
|
||
\f[B]\f[VB]amt:N, amt:<N, amt:<=N, amt:>N, amt:>=N\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match postings with a single-commodity amount equal to, less than, or
|
||
greater than N.
|
||
(Postings with multi-commodity amounts are not tested and will always
|
||
match.)
|
||
The comparison has two modes: if N is preceded by a + or - sign (or is
|
||
0), the two signed numbers are compared.
|
||
Otherwise, the absolute magnitudes are compared, ignoring sign.
|
||
.PP
|
||
\f[B]\f[VB]code:REGEX\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match by transaction code (eg check number).
|
||
.PP
|
||
\f[B]\f[VB]cur:REGEX\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match postings or transactions including any amounts whose
|
||
currency/commodity symbol is fully matched by REGEX.
|
||
(For a partial match, use \f[V].*REGEX.*\f[R]).
|
||
Note, to match special characters which are regex-significant, you need
|
||
to escape them with \f[V]\[rs]\f[R].
|
||
And for characters which are significant to your shell you may need one
|
||
more level of escaping.
|
||
So eg to match the dollar sign:
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]hledger print cur:\[rs]\[rs]$\f[R].
|
||
.PP
|
||
\f[B]\f[VB]desc:REGEX\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match transaction descriptions.
|
||
.PP
|
||
\f[B]\f[VB]date:PERIODEXPR\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match dates (or with the \f[V]--date2\f[R] flag, secondary dates) within
|
||
the specified period.
|
||
PERIODEXPR is a period expression with no report interval.
|
||
Examples:
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
\f[V]date:2016\f[R], \f[V]date:thismonth\f[R], \f[V]date:2/1-2/15\f[R],
|
||
\f[V]date:2021-07-27..nextquarter\f[R].
|
||
.PP
|
||
\f[B]\f[VB]date2:PERIODEXPR\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match secondary dates within the specified period (independent of the
|
||
\f[V]--date2\f[R] flag).
|
||
.PP
|
||
\f[B]\f[VB]depth:N\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match (or display, depending on command) accounts at or above this
|
||
depth.
|
||
.PP
|
||
\f[B]\f[VB]expr:\[dq]TERM AND NOT (TERM OR TERM)\[dq]\f[B]\f[R] (eg)
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match with a boolean combination of queries (which must be enclosed in
|
||
quotes).
|
||
See Combining query terms below.
|
||
.PP
|
||
\f[B]\f[VB]note:REGEX\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match transaction notes (the part of the description right of
|
||
\f[V]|\f[R], or the whole description if there\[aq]s no \f[V]|\f[R]).
|
||
.PP
|
||
\f[B]\f[VB]payee:REGEX\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match transaction payee/payer names (the part of the description left of
|
||
\f[V]|\f[R], or the whole description if there\[aq]s no \f[V]|\f[R]).
|
||
.PP
|
||
\f[B]\f[VB]real:, real:0\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match real or virtual postings respectively.
|
||
.PP
|
||
\f[B]\f[VB]status:, status:!, status:*\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match unmarked, pending, or cleared transactions respectively.
|
||
.PP
|
||
\f[B]\f[VB]type:TYPECODES\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match by account type (see Declaring accounts > Account types).
|
||
\f[V]TYPECODES\f[R] is one or more of the single-letter account type
|
||
codes \f[V]ALERXCV\f[R], case insensitive.
|
||
Note \f[V]type:A\f[R] and \f[V]type:E\f[R] will also match their
|
||
respective subtypes \f[V]C\f[R] (Cash) and \f[V]V\f[R] (Conversion).
|
||
Certain kinds of account alias can disrupt account types, see Rewriting
|
||
accounts > Aliases and account types.
|
||
.PP
|
||
\f[B]\f[VB]tag:REGEX[=REGEX]\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Match by tag name, and optionally also by tag value.
|
||
(To match only by value, use \f[V]tag:.=REGEX\f[R].)
|
||
.PP
|
||
When querying by tag, note that:
|
||
.IP \[bu] 2
|
||
Accounts also inherit the tags of their parent accounts
|
||
.IP \[bu] 2
|
||
Postings also inherit the tags of their account and their transaction
|
||
.IP \[bu] 2
|
||
Transactions also acquire the tags of their postings.
|
||
.PP
|
||
(\f[B]\f[VB]inacct:ACCTNAME\f[B]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
A special query term used automatically in hledger-web only: tells
|
||
hledger-web to show the transaction register for an account.)
|
||
.SS Combining query terms
|
||
.PP
|
||
When given multiple space-separated query terms, most commands select
|
||
things which match:
|
||
.IP \[bu] 2
|
||
any of the description terms AND
|
||
.IP \[bu] 2
|
||
any of the account terms AND
|
||
.IP \[bu] 2
|
||
any of the status terms AND
|
||
.IP \[bu] 2
|
||
all the other terms.
|
||
.PP
|
||
The print command is a little different, showing transactions which:
|
||
.IP \[bu] 2
|
||
match any of the description terms AND
|
||
.IP \[bu] 2
|
||
have any postings matching any of the positive account terms AND
|
||
.IP \[bu] 2
|
||
have no postings matching any of the negative account terms AND
|
||
.IP \[bu] 2
|
||
match all the other terms.
|
||
.PP
|
||
We also support more complex boolean queries with the \[aq]expr:\[aq]
|
||
prefix.
|
||
This allows one to combine queries using one of three operators: AND,
|
||
OR, and NOT, where NOT is different syntax for \[aq]not:\[aq].
|
||
.PP
|
||
Examples of such queries are:
|
||
.IP \[bu] 2
|
||
Match transactions with \[aq]cool\[aq] in the description AND with the
|
||
\[aq]A\[aq] tag
|
||
.RS 2
|
||
.PP
|
||
\f[V]expr:\[dq]desc:cool AND tag:A\[dq]\f[R]
|
||
.RE
|
||
.IP \[bu] 2
|
||
Match transactions NOT to the \[aq]expenses:food\[aq] account OR with
|
||
the \[aq]A\[aq] tag
|
||
.RS 2
|
||
.PP
|
||
\f[V]expr:\[dq]NOT expenses:food OR tag:A\[dq]\f[R]
|
||
.RE
|
||
.IP \[bu] 2
|
||
Match transactions NOT involving the \[aq]expenses:food\[aq] account OR
|
||
with the \[aq]A\[aq] tag AND involving the \[aq]expenses:drink\[aq]
|
||
account.
|
||
(the AND is implicitly added by space-separation, following the rules
|
||
above)
|
||
.RS 2
|
||
.PP
|
||
\f[V]expr:\[dq]expenses:food OR (tag:A expenses:drink)\[dq]\f[R]
|
||
.RE
|
||
.SS Queries and command options
|
||
.PP
|
||
Some queries can also be expressed as command-line options:
|
||
\f[V]depth:2\f[R] is equivalent to \f[V]--depth 2\f[R],
|
||
\f[V]date:2023\f[R] is equivalent to \f[V]-p 2023\f[R], etc.
|
||
When you mix command options and query arguments, generally the
|
||
resulting query is their intersection.
|
||
.SS Queries and valuation
|
||
.PP
|
||
When amounts are converted to other commodities in cost or value
|
||
reports, \f[V]cur:\f[R] and \f[V]amt:\f[R] match the old commodity
|
||
symbol and the old amount quantity, not the new ones (except in hledger
|
||
1.22.0 where it\[aq]s reversed, see #1625).
|
||
.SS Querying with account aliases
|
||
.PP
|
||
When account names are rewritten with \f[V]--alias\f[R] or
|
||
\f[V]alias\f[R], note that \f[V]acct:\f[R] will match either the old or
|
||
the new account name.
|
||
.SS Querying with cost or value
|
||
.PP
|
||
When amounts are converted to other commodities in cost or value
|
||
reports, note that \f[V]cur:\f[R] matches the new commodity symbol, and
|
||
not the old one, and \f[V]amt:\f[R] matches the new quantity, and not
|
||
the old one.
|
||
Note: this changed in hledger 1.22, previously it was the reverse, see
|
||
the discussion at #1625.
|
||
.SH Pivoting
|
||
.PP
|
||
Normally, hledger groups and sums amounts within each account.
|
||
The \f[V]--pivot FIELD\f[R] option substitutes some other transaction
|
||
field for account names, causing amounts to be grouped and summed by
|
||
that field\[aq]s value instead.
|
||
FIELD can be any of the transaction fields \f[V]acct\f[R],
|
||
\f[V]status\f[R], \f[V]code\f[R], \f[V]desc\f[R], \f[V]payee\f[R],
|
||
\f[V]note\f[R], or a tag name.
|
||
When pivoting on a tag and a posting has multiple values of that tag,
|
||
only the first value is displayed.
|
||
Values containing \f[V]colon:separated:parts\f[R] will be displayed
|
||
hierarchically, like account names.
|
||
Multiple, colon-delimited fields can be pivoted simultaneously,
|
||
generating a hierarchical account name.
|
||
.PP
|
||
Some examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2016/02/16 Yearly Dues Payment
|
||
assets:bank account 2 EUR
|
||
income:dues -2 EUR ; member: John Doe, kind: Lifetime
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Normal balance report showing account names:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance
|
||
2 EUR assets:bank account
|
||
-2 EUR income:dues
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Pivoted balance report, using member: tag values instead:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance --pivot member
|
||
2 EUR
|
||
-2 EUR John Doe
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
One way to show only amounts with a member: value (using a query):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance --pivot member tag:member=.
|
||
-2 EUR John Doe
|
||
--------------------
|
||
-2 EUR
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Another way (the acct: query matches against the pivoted \[dq]account
|
||
name\[dq]):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance --pivot member acct:.
|
||
-2 EUR John Doe
|
||
--------------------
|
||
-2 EUR
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Hierarchical reports can be generated with multiple pivots:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance Income:Dues --pivot kind:member
|
||
-2 EUR Lifetime:John Doe
|
||
--------------------
|
||
-2 EUR
|
||
\f[R]
|
||
.fi
|
||
.SH Generating data
|
||
.PP
|
||
hledger has several features for generating data, such as:
|
||
.IP \[bu] 2
|
||
Periodic transaction rules can generate single or repeating transactions
|
||
following a template.
|
||
These are usually dated in the future, eg to help with forecasting.
|
||
They are activated by the \f[V]--forecast\f[R] option.
|
||
.IP \[bu] 2
|
||
The balance command\[aq]s \f[V]--budget\f[R] option uses these same
|
||
periodic rules to generate goals for the budget report.
|
||
.IP \[bu] 2
|
||
Auto posting rules can generate extra postings on certain matched
|
||
transactions.
|
||
They are always applied to forecast transactions; with the
|
||
\f[V]--auto\f[R] flag they are applied to transactions recorded in the
|
||
journal as well.
|
||
.IP \[bu] 2
|
||
The \f[V]--infer-equity\f[R] flag infers missing conversion equity
|
||
postings from \[at]/\[at]\[at] costs.
|
||
And the inverse \f[V]--infer-costs\f[R] flag infers missing
|
||
\[at]/\[at]\[at] costs from conversion equity postings.
|
||
.PP
|
||
Generated data of this kind is temporary, existing only at report time.
|
||
But you can see it in the output of \f[V]hledger print\f[R], and you can
|
||
save that to your journal, in effect converting it from temporary
|
||
generated data to permanent recorded data.
|
||
This could be useful as a data entry aid.
|
||
.PP
|
||
If you are wondering what data is being generated and why, add the
|
||
\f[V]--verbose-tags\f[R] flag.
|
||
In \f[V]hledger print\f[R] output you will see extra tags like
|
||
\f[V]generated-transaction\f[R], \f[V]generated-posting\f[R], and
|
||
\f[V]modified\f[R] on generated/modified data.
|
||
Also, even without \f[V]--verbose-tags\f[R], generated data always has
|
||
equivalen hidden tags (with an underscore prefix), so eg you could match
|
||
generated transactions with \f[V]tag:_generated-transaction\f[R].
|
||
.SH Forecasting
|
||
.PP
|
||
Forecasting, or speculative future reporting, can be useful for
|
||
estimating future balances, or for exploring different future scenarios.
|
||
.PP
|
||
The simplest and most flexible way to do it with hledger is to manually
|
||
record a bunch of future-dated transactions.
|
||
You could keep these in a separate \f[V]future.journal\f[R] and include
|
||
that with \f[V]-f\f[R] only when you want to see them.
|
||
.SS --forecast
|
||
.PP
|
||
There is another way: with the \f[V]--forecast\f[R] option, hledger can
|
||
generate temporary \[dq]forecast transactions\[dq] for reporting
|
||
purposes, according to periodic transaction rules defined in the
|
||
journal.
|
||
Each rule can generate multiple recurring transactions, so by changing
|
||
one rule you can change many forecasted transactions.
|
||
(These same rules can also generate budget goals, described in
|
||
Budgeting.)
|
||
.PP
|
||
Forecast transactions usually start after ordinary transactions end.
|
||
By default, they begin after your latest-dated ordinary transaction, or
|
||
today, whichever is later, and they end six months from today.
|
||
(The exact rules are a little more complicated, and are given below.)
|
||
.PP
|
||
This is the \[dq]forecast period\[dq], which need not be the same as the
|
||
report period.
|
||
You can override it - eg to forecast farther into the future, or to
|
||
force forecast transactions to overlap your ordinary transactions - by
|
||
giving the --forecast option a period expression argument, like
|
||
\f[V]--forecast=..2099\f[R] or \f[V]--forecast=2023-02-15..\f[R].
|
||
Note that the \f[V]=\f[R] is required.
|
||
.SS Inspecting forecast transactions
|
||
.PP
|
||
\f[V]print\f[R] is the best command for inspecting and troubleshooting
|
||
forecast transactions.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
\[ti] monthly from 2022-12-20 rent
|
||
assets:bank:checking
|
||
expenses:rent $1000
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --forecast --today=2023/4/21
|
||
2023-05-20 rent
|
||
; generated-transaction: \[ti] monthly from 2022-12-20
|
||
assets:bank:checking
|
||
expenses:rent $1000
|
||
|
||
2023-06-20 rent
|
||
; generated-transaction: \[ti] monthly from 2022-12-20
|
||
assets:bank:checking
|
||
expenses:rent $1000
|
||
|
||
2023-07-20 rent
|
||
; generated-transaction: \[ti] monthly from 2022-12-20
|
||
assets:bank:checking
|
||
expenses:rent $1000
|
||
|
||
2023-08-20 rent
|
||
; generated-transaction: \[ti] monthly from 2022-12-20
|
||
assets:bank:checking
|
||
expenses:rent $1000
|
||
|
||
2023-09-20 rent
|
||
; generated-transaction: \[ti] monthly from 2022-12-20
|
||
assets:bank:checking
|
||
expenses:rent $1000
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Here there are no ordinary transactions, so the forecasted transactions
|
||
begin on the first occurence after today\[aq]s date.
|
||
(You won\[aq]t normally use \f[V]--today\f[R]; it\[aq]s just to make
|
||
these examples reproducible.)
|
||
.SS Forecast reports
|
||
.PP
|
||
Forecast transactions affect all reports, as you would expect.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger areg rent --forecast --today=2023/4/21
|
||
Transactions in expenses:rent and subaccounts:
|
||
2023-05-20 rent as:ba:checking $1000 $1000
|
||
2023-06-20 rent as:ba:checking $1000 $2000
|
||
2023-07-20 rent as:ba:checking $1000 $3000
|
||
2023-08-20 rent as:ba:checking $1000 $4000
|
||
2023-09-20 rent as:ba:checking $1000 $5000
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger bal -M expenses --forecast --today=2023/4/21
|
||
Balance changes in 2023-05-01..2023-09-30:
|
||
|
||
|| May Jun Jul Aug Sep
|
||
===============++===================================
|
||
expenses:rent || $1000 $1000 $1000 $1000 $1000
|
||
---------------++-----------------------------------
|
||
|| $1000 $1000 $1000 $1000 $1000
|
||
\f[R]
|
||
.fi
|
||
.SS Forecast tags
|
||
.PP
|
||
Forecast transactions generated by --forecast have a hidden tag,
|
||
\f[V]_generated-transaction\f[R].
|
||
So if you ever need to match forecast transactions, you could use
|
||
\f[V]tag:_generated-transaction\f[R] (or just \f[V]tag:generated\f[R])
|
||
in a query.
|
||
.PP
|
||
For troubleshooting, you can add the \f[V]--verbose-tags\f[R] flag.
|
||
Then, visible \f[V]generated-transaction\f[R] tags will be added also,
|
||
so you can view them with the \f[V]print\f[R] command.
|
||
Their value indicates which periodic rule was responsible.
|
||
.SS Forecast period, in detail
|
||
.PP
|
||
Forecast start/end dates are chosen so as to do something useful by
|
||
default in almost all situations, while also being flexible.
|
||
Here are (with luck) the exact rules, to help with troubleshooting:
|
||
.PP
|
||
The forecast period starts on:
|
||
.IP \[bu] 2
|
||
the later of
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
the start date in the periodic transaction rule
|
||
.IP \[bu] 2
|
||
the start date in \f[V]--forecast\f[R]\[aq]s argument
|
||
.RE
|
||
.IP \[bu] 2
|
||
otherwise (if those are not available): the later of
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
the report start date specified with
|
||
\f[V]-b\f[R]/\f[V]-p\f[R]/\f[V]date:\f[R]
|
||
.IP \[bu] 2
|
||
the day after the latest ordinary transaction in the journal
|
||
.RE
|
||
.IP \[bu] 2
|
||
otherwise (if none of these are available): today.
|
||
.PP
|
||
The forecast period ends on:
|
||
.IP \[bu] 2
|
||
the earlier of
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
the end date in the periodic transaction rule
|
||
.IP \[bu] 2
|
||
the end date in \f[V]--forecast\f[R]\[aq]s argument
|
||
.RE
|
||
.IP \[bu] 2
|
||
otherwise: the report end date specified with
|
||
\f[V]-e\f[R]/\f[V]-p\f[R]/\f[V]date:\f[R]
|
||
.IP \[bu] 2
|
||
otherwise: 180 days (\[ti]6 months) from today.
|
||
.SS Forecast troubleshooting
|
||
.PP
|
||
When --forecast is not doing what you expect, one of these tips should
|
||
help:
|
||
.IP \[bu] 2
|
||
Remember to use the \f[V]--forecast\f[R] option.
|
||
.IP \[bu] 2
|
||
Remember to have at least one periodic transaction rule in your journal.
|
||
.IP \[bu] 2
|
||
Test with \f[V]print --forecast\f[R].
|
||
.IP \[bu] 2
|
||
Check for typos or too-restrictive start/end dates in your periodic
|
||
transaction rule.
|
||
.IP \[bu] 2
|
||
Leave at least 2 spaces between the rule\[aq]s period expression and
|
||
description fields.
|
||
.IP \[bu] 2
|
||
Check for future-dated ordinary transactions suppressing forecasted
|
||
transactions.
|
||
.IP \[bu] 2
|
||
Try setting explicit report start and/or end dates with \f[V]-b\f[R],
|
||
\f[V]-e\f[R], \f[V]-p\f[R] or \f[V]date:\f[R]
|
||
.IP \[bu] 2
|
||
Try adding the \f[V]-E\f[R] flag to encourage display of empty
|
||
periods/zero transactions.
|
||
.IP \[bu] 2
|
||
Try setting explicit forecast start and/or end dates with
|
||
\f[V]--forecast=START..END\f[R]
|
||
.IP \[bu] 2
|
||
Consult Forecast period, in detail, above.
|
||
.IP \[bu] 2
|
||
Check inside the engine: add \f[V]--debug=2\f[R] (eg).
|
||
.SH Budgeting
|
||
.PP
|
||
With the balance command\[aq]s \f[V]--budget\f[R] report, each periodic
|
||
transaction rule generates recurring budget goals in specified accounts,
|
||
and goals and actual performance can be compared.
|
||
See the balance command\[aq]s doc below.
|
||
.PP
|
||
You can generate budget goals and forecast transactions at the same
|
||
time, from the same or different periodic transaction rules:
|
||
\f[V]hledger bal -M --budget --forecast ...\f[R]
|
||
.PP
|
||
See also: Budgeting and Forecasting.
|
||
.SH Cost reporting
|
||
.PP
|
||
This section is about recording the cost of things, in transactions
|
||
where one commodity is exchanged for another.
|
||
Eg an exchange of currency, or a stock purchase or sale.
|
||
First, a quick glossary:
|
||
.IP \[bu] 2
|
||
Conversion - an exchange of one currency or commodity for another.
|
||
Eg a foreign currency exchange, or a purchase or sale of stock or
|
||
cryptocurrency.
|
||
.IP \[bu] 2
|
||
Conversion transaction - a transaction involving one or more
|
||
conversions.
|
||
.IP \[bu] 2
|
||
Conversion rate - the cost per unit of one commodity in the other, ie
|
||
the exchange rate.
|
||
.IP \[bu] 2
|
||
Cost - how much of one commodity was paid to acquire the other.
|
||
And more generally, in hledger docs: the amount exchanged in the
|
||
\[dq]secondary\[dq] commodity (usually your base currency), whether in a
|
||
purchase or a sale, and whether expressed per unit or in total.
|
||
Also, the \[dq]\[at]/\[at]\[at] PRICE\[dq] notation used to represent
|
||
this.
|
||
.SS -B: Convert to cost
|
||
.PP
|
||
As discussed in JOURNAL > Costs, when recording a transaction you can
|
||
also record the amount\[aq]s cost in another commodity, by adding
|
||
\f[V]\[at] UNITPRICE\f[R] or \f[V]\[at]\[at] TOTALPRICE\f[R].
|
||
.PP
|
||
Then you can see a report with amounts converted to cost, by adding the
|
||
\f[V]-B/--cost\f[R] flag.
|
||
(Mnemonic: \[dq]B\[dq] from \[dq]cost Basis\[dq], as in Ledger).
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-01-01
|
||
assets:dollars $-135 ; 135 dollars is exchanged for..
|
||
assets:euros €100 \[at] $1.35 ; one hundred euros purchased at $1.35 each
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger bal -N
|
||
$-135 assets:dollars
|
||
€100 assets:euros
|
||
$ hledger bal -N -B
|
||
$-135 assets:dollars
|
||
$135 assets:euros # <- the euros\[aq] cost
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Notes:
|
||
.PP
|
||
-B is sensitive to the order of postings when a cost is inferred: the
|
||
inferred price will be in the commodity of the last amount.
|
||
So if example 3\[aq]s postings are reversed, while the transaction is
|
||
equivalent, -B shows something different:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-01-01
|
||
assets:dollars $-135 ; 135 dollars sold
|
||
assets:euros €100 ; for 100 euros
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger bal -N -B
|
||
€-100 assets:dollars # <- the dollars\[aq] selling price
|
||
€100 assets:euros
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The \[at]/\[at]\[at] cost notation is convenient, but has some
|
||
drawbacks: it does not truly balance the transaction, so it disrupts the
|
||
accounting equation and tends to causes a non-zero total in balance
|
||
reports.
|
||
.SS Equity conversion postings
|
||
.PP
|
||
By contrast, conventional double entry bookkeeping (DEB) uses a
|
||
different notation: an extra pair of equity postings to balance
|
||
conversion transactions.
|
||
In this style, the above entry might be written:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-01-01 one hundred euros purchased at $1.35 each
|
||
assets:dollars $-135
|
||
equity:conversion $135
|
||
equity:conversion €-100
|
||
assets:euros €100
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This style is more correct, but it\[aq]s also more verbose and makes
|
||
cost reporting more difficult for PTA tools.
|
||
.PP
|
||
Happily, current hledger can read either notation, or convert one to the
|
||
other when needed, so you can use the one you prefer.
|
||
.PP
|
||
You can even use cost notation and equivalent conversion postings at the
|
||
same time, for clarity.
|
||
hledger will ignore the redundancy.
|
||
But be sure the cost and conversion posting amounts match, or you\[aq]ll
|
||
see a not-so-clear transaction balancing error message.
|
||
.SS Inferring equity postings from cost
|
||
.PP
|
||
With \f[V]--infer-equity\f[R], hledger detects transactions written with
|
||
PTA cost notation and adds equity conversion postings to them:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-01-01
|
||
assets:dollars -$135
|
||
assets:euros €100 \[at] $1.35
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --infer-equity
|
||
2022-01-01
|
||
assets:dollars $-135
|
||
assets:euros €100 \[at] $1.35
|
||
equity:conversion:$-€:€ €-100 ; generated-posting:
|
||
equity:conversion:$-€:$ $135.00 ; generated-posting:
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The conversion account names can be changed with the conversion account
|
||
type declaration.
|
||
.PP
|
||
--infer-equity is useful when when transactions have been recorded using
|
||
cost notation, to help preserve the accounting equation and balance
|
||
reports\[aq] zero total, or to produce more conventional journal entries
|
||
for sharing with non-PTA-users.
|
||
.SS Inferring cost from equity postings
|
||
.PP
|
||
The reverse operation is possible using \f[V]--infer-costs\f[R], which
|
||
detects transactions written with equity conversion postings and adds
|
||
cost notation to them:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-01-01
|
||
assets:dollars $-135
|
||
equity:conversion $135
|
||
equity:conversion €-100
|
||
assets:euros €100
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --infer-costs
|
||
2022-01-01
|
||
assets:dollars $-135 \[at]\[at] €100
|
||
equity:conversion $135
|
||
equity:conversion €-100
|
||
assets:euros €100
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
--infer-costs is useful when combined with -B/--cost, allowing cost
|
||
reporting even when transactions have been recorded using equity
|
||
postings:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --infer-costs -B
|
||
2009-01-01
|
||
assets:dollars €-100
|
||
assets:euros €100
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Notes:
|
||
.PP
|
||
For \f[V]--infer-costs\f[R] to work, an exchange must consist of four
|
||
postings:
|
||
.IP "1." 3
|
||
two non-equity postings
|
||
.IP "2." 3
|
||
two equity postings, next to one another
|
||
.IP "3." 3
|
||
the equity accounts must be declared, with account type
|
||
\f[V]V\f[R]/\f[V]Conversion\f[R] (or if they are not declared, they must
|
||
be named \f[V]equity:conversion\f[R], \f[V]equity:trade\f[R],
|
||
\f[V]equity:trading\f[R] or subaccounts of these)
|
||
.IP "4." 3
|
||
the equity postings\[aq] amounts must exactly match the non-equity
|
||
postings\[aq] amounts.
|
||
.PP
|
||
Multiple such exchanges can coexist within a single transaction.
|
||
.PP
|
||
When inferring cost, the order of postings matters: the cost is added to
|
||
the first of the non-equity postings involved in the exchange, in the
|
||
commodity of the last non-equity posting involved in the exchange.
|
||
If you don\[aq]t want to write your postings in the required order, you
|
||
can use explicit cost notation instead.
|
||
.PP
|
||
--infer-equity and --infer-costs can be used together, if you have a
|
||
mixture of both notations in your journal.
|
||
.SS When to infer cost/equity
|
||
.PP
|
||
Inferring equity postings or costs is still fairly new, so not enabled
|
||
by default.
|
||
We\[aq]re not sure yet if that should change.
|
||
Here are two suggestions to try, experience reports welcome:
|
||
.IP "1." 3
|
||
When you use -B, always use --infer-costs as well.
|
||
Eg: \f[V]hledger bal -B --infer-costs\f[R]
|
||
.IP "2." 3
|
||
Always run hledger with both flags enabled.
|
||
Eg: \f[V]alias hl=\[dq]hledger --infer-equity --infer-costs\[dq]\f[R]
|
||
.SS How to record conversions
|
||
.PP
|
||
Essentially there are four ways to record a conversion transaction in
|
||
hledger.
|
||
Here are all of them, with pros and cons.
|
||
.SS Conversion with implicit cost
|
||
.PP
|
||
Let\[aq]s assume 100 EUR is converted to 120 USD.
|
||
You can just record the outflow (100 EUR) and inflow (120 USD) in the
|
||
appropriate asset account:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2021-01-01
|
||
assets:cash -100 EUR
|
||
assets:cash 120 USD
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
hledger will assume this transaction is balanced, inferring that the
|
||
conversion rate must be 1 EUR = 1.20 USD.
|
||
You can see the inferred rate by using \f[V]hledger print -x\f[R].
|
||
.PP
|
||
Pro:
|
||
.IP \[bu] 2
|
||
Concise, easy
|
||
.PP
|
||
Con:
|
||
.IP \[bu] 2
|
||
Less error checking - typos in amounts or commodity symbols may not be
|
||
detected
|
||
.IP \[bu] 2
|
||
Conversion rate is not clear
|
||
.IP \[bu] 2
|
||
Disturbs the accounting equation, unless you add the --infer-equity flag
|
||
.PP
|
||
You can prevent accidental implicit conversions due to a mistyped
|
||
commodity symbol, by using \f[V]hledger check commodities\f[R].
|
||
.PP
|
||
You can prevent implicit conversions entirely, by using
|
||
\f[V]hledger check balancednoautoconversion\f[R], or
|
||
\f[V]-s/--strict\f[R].
|
||
.SS Conversion with explicit cost
|
||
.PP
|
||
You can add the conversion rate using \[at] notation:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2021-01-01
|
||
assets:cash -100 EUR \[at] 1.20 USD
|
||
assets:cash 120 USD
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Now hledger will check that 100 * 1.20 = 120, and would report an error
|
||
otherwise.
|
||
.PP
|
||
Pro:
|
||
.IP \[bu] 2
|
||
Still concise
|
||
.IP \[bu] 2
|
||
Makes the conversion rate clear
|
||
.IP \[bu] 2
|
||
Provides more error checking
|
||
.PP
|
||
Con:
|
||
.IP \[bu] 2
|
||
Disturbs the accounting equation, unless you add the --infer-equity flag
|
||
.SS Conversion with equity postings
|
||
.PP
|
||
In strict double entry bookkeeping, the above transaction is not
|
||
balanced in EUR or in USD, since some EUR disappears, and some USD
|
||
appears.
|
||
This violates the accounting equation (A+L+E=0), and prevents reports
|
||
like \f[V]balancesheetequity\f[R] from showing a zero total.
|
||
.PP
|
||
The proper way to make it balance is to add a balancing posting for each
|
||
commodity, using an equity account:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2021-01-01
|
||
assets:cash -100 EUR
|
||
equity:conversion 100 EUR
|
||
equity:conversion -120 USD
|
||
assets:cash 120 USD
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Pro:
|
||
.IP \[bu] 2
|
||
Preserves the accounting equation
|
||
.IP \[bu] 2
|
||
Keeps track of conversions and related gains/losses in one place
|
||
.IP \[bu] 2
|
||
Standard, works in any double entry accounting system
|
||
.PP
|
||
Con:
|
||
.IP \[bu] 2
|
||
More verbose
|
||
.IP \[bu] 2
|
||
Conversion rate is not obvious
|
||
.IP \[bu] 2
|
||
Cost reporting requires adding the --infer-costs flag
|
||
.SS Conversion with equity postings and explicit cost
|
||
.PP
|
||
Here both equity postings and \[at] notation are used together.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2021-01-01
|
||
assets:cash -100 EUR \[at] 1.20 USD
|
||
equity:conversion 100 EUR
|
||
equity:conversion -120 USD
|
||
assets:cash 120 USD
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Pro:
|
||
.IP \[bu] 2
|
||
Preserves the accounting equation
|
||
.IP \[bu] 2
|
||
Keeps track of conversions and related gains/losses in one place
|
||
.IP \[bu] 2
|
||
Makes the conversion rate clear
|
||
.IP \[bu] 2
|
||
Provides more error checking
|
||
.PP
|
||
Con:
|
||
.IP \[bu] 2
|
||
Most verbose
|
||
.IP \[bu] 2
|
||
Not compatible with ledger
|
||
.SS Cost tips
|
||
.IP \[bu] 2
|
||
Recording the cost/conversion rate explicitly is good because it makes
|
||
that clear and helps detect errors.
|
||
.IP \[bu] 2
|
||
Recording equity postings is good because it is correct bookkeeping and
|
||
preserves the accounting equation.
|
||
.IP \[bu] 2
|
||
Combining these is possible.
|
||
.IP \[bu] 2
|
||
When you want to see the cost (or sale proceeds) of things, use
|
||
\f[V]-B\f[R] (short form of \f[V]--cost\f[R]).
|
||
.IP \[bu] 2
|
||
If you use conversion postings without cost notation, add
|
||
\f[V]--infer-costs\f[R] also.
|
||
.IP \[bu] 2
|
||
If you use cost notation without conversion postings, and you want to
|
||
see a balanced balance sheet or print correct journal entries, use
|
||
\f[V]--infer-equity\f[R].
|
||
.IP \[bu] 2
|
||
Conversion to cost is performed before valuation (described next).
|
||
.SH Valuation
|
||
.PP
|
||
Instead of reporting amounts in their original commodity, hledger can
|
||
convert them to cost/sale amount (using the conversion rate recorded in
|
||
the transaction), and/or to market value (using some market price on a
|
||
certain date).
|
||
This is controlled by the \f[V]--value=TYPE[,COMMODITY]\f[R] option,
|
||
which will be described below.
|
||
We also provide the simpler \f[V]-V\f[R] and \f[V]-X COMMODITY\f[R]
|
||
options, and often one of these is all you need:
|
||
.SS -V: Value
|
||
.PP
|
||
The \f[V]-V/--market\f[R] flag converts amounts to market value in their
|
||
default \f[I]valuation commodity\f[R], using the market prices in effect
|
||
on the \f[I]valuation date(s)\f[R], if any.
|
||
More on these in a minute.
|
||
.SS -X: Value in specified commodity
|
||
.PP
|
||
The \f[V]-X/--exchange=COMM\f[R] option is like \f[V]-V\f[R], except you
|
||
tell it which currency you want to convert to, and it tries to convert
|
||
everything to that.
|
||
.SS Valuation date
|
||
.PP
|
||
Since market prices can change from day to day, market value reports
|
||
have a valuation date (or more than one), which determines which market
|
||
prices will be used.
|
||
.PP
|
||
For single period reports, if an explicit report end date is specified,
|
||
that will be used as the valuation date; otherwise the valuation date is
|
||
the journal\[aq]s end date.
|
||
.PP
|
||
For multiperiod reports, each column/period is valued on the last day of
|
||
the period, by default.
|
||
.SS Finding market price
|
||
.PP
|
||
To convert a commodity A to its market value in another commodity B,
|
||
hledger looks for a suitable market price (exchange rate) as follows, in
|
||
this order of preference :
|
||
.IP "1." 3
|
||
A \f[I]declared market price\f[R] or \f[I]inferred market price\f[R]:
|
||
A\[aq]s latest market price in B on or before the valuation date as
|
||
declared by a P directive, or (with the \f[V]--infer-market-prices\f[R]
|
||
flag) inferred from costs.
|
||
.IP "2." 3
|
||
A \f[I]reverse market price\f[R]: the inverse of a declared or inferred
|
||
market price from B to A.
|
||
.IP "3." 3
|
||
A \f[I]forward chain of market prices\f[R]: a synthetic price formed by
|
||
combining the shortest chain of \[dq]forward\[dq] (only 1 above) market
|
||
prices, leading from A to B.
|
||
.IP "4." 3
|
||
\f[I]Any chain of market prices\f[R]: a chain of any market prices,
|
||
including both forward and reverse prices (1 and 2 above), leading from
|
||
A to B.
|
||
.PP
|
||
There is a limit to the length of these price chains; if hledger reaches
|
||
that length without finding a complete chain or exhausting all
|
||
possibilities, it will give up (with a \[dq]gave up\[dq] message visible
|
||
in \f[V]--debug=2\f[R] output).
|
||
That limit is currently 1000.
|
||
.PP
|
||
Amounts for which no suitable market price can be found, are not
|
||
converted.
|
||
.SS --infer-market-prices: market prices from transactions
|
||
.PP
|
||
Normally, market value in hledger is fully controlled by, and requires,
|
||
P directives in your journal.
|
||
Since adding and updating those can be a chore, and since transactions
|
||
usually take place at close to market value, why not use the recorded
|
||
costs as additional market prices (as Ledger does) ?
|
||
Adding the \f[V]--infer-market-prices\f[R] flag to \f[V]-V\f[R],
|
||
\f[V]-X\f[R] or \f[V]--value\f[R] enables this.
|
||
.PP
|
||
So for example, \f[V]hledger bs -V --infer-market-prices\f[R] will get
|
||
market prices both from P directives and from transactions.
|
||
If both occur on the same day, the P directive takes precedence.
|
||
.PP
|
||
There is a downside: value reports can sometimes be affected in
|
||
confusing/undesired ways by your journal entries.
|
||
If this happens to you, read all of this Valuation section carefully,
|
||
and try adding \f[V]--debug\f[R] or \f[V]--debug=2\f[R] to troubleshoot.
|
||
.PP
|
||
\f[V]--infer-market-prices\f[R] can infer market prices from:
|
||
.IP \[bu] 2
|
||
multicommodity transactions with explicit prices
|
||
(\f[V]\[at]\f[R]/\f[V]\[at]\[at]\f[R])
|
||
.IP \[bu] 2
|
||
multicommodity transactions with implicit prices (no \f[V]\[at]\f[R],
|
||
two commodities, unbalanced).
|
||
(With these, the order of postings matters.
|
||
\f[V]hledger print -x\f[R] can be useful for troubleshooting.)
|
||
.IP \[bu] 2
|
||
multicommodity transactions with equity postings, if cost is inferred
|
||
with \f[V]--infer-costs\f[R].
|
||
.PP
|
||
There is a limitation (bug) currently: when a valuation commodity is not
|
||
specified, prices inferred with \f[V]--infer-market-prices\f[R] do not
|
||
help select a default valuation commodity, as \f[V]P\f[R] prices would.
|
||
So conversion might not happen because no valuation commodity was
|
||
detected (\f[V]--debug=2\f[R] will show this).
|
||
To be safe, specify the valuation commmodity, eg:
|
||
.IP \[bu] 2
|
||
\f[V]-X EUR --infer-market-prices\f[R], not
|
||
\f[V]-V --infer-market-prices\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]--value=then,EUR --infer-market-prices\f[R], not
|
||
\f[V]--value=then --infer-market-prices\f[R]
|
||
.PP
|
||
Signed costs and market prices can be confusing.
|
||
For reference, here is the current behaviour, since hledger 1.25.
|
||
(If you think it should work differently, see #1870.)
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022-01-01 Positive Unit prices
|
||
a A 1
|
||
b B -1 \[at] A 1
|
||
|
||
2022-01-01 Positive Total prices
|
||
a A 1
|
||
b B -1 \[at]\[at] A 1
|
||
|
||
|
||
2022-01-02 Negative unit prices
|
||
a A 1
|
||
b B 1 \[at] A -1
|
||
|
||
2022-01-02 Negative total prices
|
||
a A 1
|
||
b B 1 \[at]\[at] A -1
|
||
|
||
|
||
2022-01-03 Double Negative unit prices
|
||
a A -1
|
||
b B -1 \[at] A -1
|
||
|
||
2022-01-03 Double Negative total prices
|
||
a A -1
|
||
b B -1 \[at]\[at] A -1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
All of the transactions above are considered balanced (and on each day,
|
||
the two transactions are considered equivalent).
|
||
Here are the market prices inferred for B:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f- --infer-market-prices prices
|
||
P 2022-01-01 B A 1
|
||
P 2022-01-01 B A 1.0
|
||
P 2022-01-02 B A -1
|
||
P 2022-01-02 B A -1.0
|
||
P 2022-01-03 B A -1
|
||
P 2022-01-03 B A -1.0
|
||
\f[R]
|
||
.fi
|
||
.SS Valuation commodity
|
||
.PP
|
||
\f[B]When you specify a valuation commodity (\f[VB]-X COMM\f[B] or
|
||
\f[VB]--value TYPE,COMM\f[B]):\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
hledger will convert all amounts to COMM, wherever it can find a
|
||
suitable market price (including by reversing or chaining prices).
|
||
.PP
|
||
\f[B]When you leave the valuation commodity unspecified (\f[VB]-V\f[B]
|
||
or \f[VB]--value TYPE\f[B]):\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
For each commodity A, hledger picks a default valuation commodity as
|
||
follows, in this order of preference:
|
||
.IP "1." 3
|
||
The price commodity from the latest P-declared market price for A on or
|
||
before valuation date.
|
||
.IP "2." 3
|
||
The price commodity from the latest P-declared market price for A on any
|
||
date.
|
||
(Allows conversion to proceed when there are inferred prices before the
|
||
valuation date.)
|
||
.IP "3." 3
|
||
If there are no P directives at all (any commodity or date) and the
|
||
\f[V]--infer-market-prices\f[R] flag is used: the price commodity from
|
||
the latest transaction-inferred price for A on or before valuation date.
|
||
.PP
|
||
This means:
|
||
.IP \[bu] 2
|
||
If you have P directives, they determine which commodities \f[V]-V\f[R]
|
||
will convert, and to what.
|
||
.IP \[bu] 2
|
||
If you have no P directives, and use the \f[V]--infer-market-prices\f[R]
|
||
flag, costs determine it.
|
||
.PP
|
||
Amounts for which no valuation commodity can be found are not converted.
|
||
.SS Simple valuation examples
|
||
.PP
|
||
Here are some quick examples of \f[V]-V\f[R]:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; one euro is worth this many dollars from nov 1
|
||
P 2016/11/01 € $1.10
|
||
|
||
; purchase some euros on nov 3
|
||
2016/11/3
|
||
assets:euros €100
|
||
assets:checking
|
||
|
||
; the euro is worth fewer dollars by dec 21
|
||
P 2016/12/21 € $1.03
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
How many euros do I have ?
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f t.j bal -N euros
|
||
€100 assets:euros
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
What are they worth at end of nov 3 ?
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f t.j bal -N euros -V -e 2016/11/4
|
||
$110.00 assets:euros
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
What are they worth after 2016/12/21 ?
|
||
(no report end date specified, defaults to today)
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f t.j bal -N euros -V
|
||
$103.00 assets:euros
|
||
\f[R]
|
||
.fi
|
||
.SS --value: Flexible valuation
|
||
.PP
|
||
\f[V]-V\f[R] and \f[V]-X\f[R] are special cases of the more general
|
||
\f[V]--value\f[R] option:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
--value=TYPE[,COMM] TYPE is then, end, now or YYYY-MM-DD.
|
||
COMM is an optional commodity symbol.
|
||
Shows amounts converted to:
|
||
- default valuation commodity (or COMM) using market prices at posting dates
|
||
- default valuation commodity (or COMM) using market prices at period end(s)
|
||
- default valuation commodity (or COMM) using current market prices
|
||
- default valuation commodity (or COMM) using market prices at some date
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The TYPE part selects cost or value and valuation date:
|
||
.TP
|
||
\f[V]--value=then\f[R]
|
||
Convert amounts to their value in the default valuation commodity, using
|
||
market prices on each posting\[aq]s date.
|
||
.TP
|
||
\f[V]--value=end\f[R]
|
||
Convert amounts to their value in the default valuation commodity, using
|
||
market prices on the last day of the report period (or if unspecified,
|
||
the journal\[aq]s end date); or in multiperiod reports, market prices on
|
||
the last day of each subperiod.
|
||
.TP
|
||
\f[V]--value=now\f[R]
|
||
Convert amounts to their value in the default valuation commodity using
|
||
current market prices (as of when report is generated).
|
||
.TP
|
||
\f[V]--value=YYYY-MM-DD\f[R]
|
||
Convert amounts to their value in the default valuation commodity using
|
||
market prices on this date.
|
||
.PP
|
||
To select a different valuation commodity, add the optional
|
||
\f[V],COMM\f[R] part: a comma, then the target commodity\[aq]s symbol.
|
||
Eg: \f[B]\f[VB]--value=now,EUR\f[B]\f[R].
|
||
hledger will do its best to convert amounts to this commodity, deducing
|
||
market prices as described above.
|
||
.SS More valuation examples
|
||
.PP
|
||
Here are some examples showing the effect of \f[V]--value\f[R], as seen
|
||
with \f[V]print\f[R]:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
P 2000-01-01 A 1 B
|
||
P 2000-02-01 A 2 B
|
||
P 2000-03-01 A 3 B
|
||
P 2000-04-01 A 4 B
|
||
|
||
2000-01-01
|
||
(a) 1 A \[at] 5 B
|
||
|
||
2000-02-01
|
||
(a) 1 A \[at] 6 B
|
||
|
||
2000-03-01
|
||
(a) 1 A \[at] 7 B
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show the cost of each posting:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f- print --cost
|
||
2000-01-01
|
||
(a) 5 B
|
||
|
||
2000-02-01
|
||
(a) 6 B
|
||
|
||
2000-03-01
|
||
(a) 7 B
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show the value as of the last day of the report period (2000-02-29):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f- print --value=end date:2000/01-2000/03
|
||
2000-01-01
|
||
(a) 2 B
|
||
|
||
2000-02-01
|
||
(a) 2 B
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
With no report period specified, that shows the value as of the last day
|
||
of the journal (2000-03-01):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f- print --value=end
|
||
2000-01-01
|
||
(a) 3 B
|
||
|
||
2000-02-01
|
||
(a) 3 B
|
||
|
||
2000-03-01
|
||
(a) 3 B
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show the current value (the 2000-04-01 price is still in effect today):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f- print --value=now
|
||
2000-01-01
|
||
(a) 4 B
|
||
|
||
2000-02-01
|
||
(a) 4 B
|
||
|
||
2000-03-01
|
||
(a) 4 B
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show the value on 2000/01/15:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f- print --value=2000-01-15
|
||
2000-01-01
|
||
(a) 1 B
|
||
|
||
2000-02-01
|
||
(a) 1 B
|
||
|
||
2000-03-01
|
||
(a) 1 B
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
You may need to explicitly set a commodity\[aq]s display style, when
|
||
reverse prices are used.
|
||
Eg this output might be surprising:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
P 2000-01-01 A 2B
|
||
|
||
2000-01-01
|
||
a 1B
|
||
b
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -x -X A
|
||
2000-01-01
|
||
a 0
|
||
b 0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Explanation: because there\[aq]s no amount or commodity directive
|
||
specifying a display style for A, 0.5A gets the default style, which
|
||
shows no decimal digits.
|
||
Because the displayed amount looks like zero, the commodity symbol and
|
||
minus sign are not displayed either.
|
||
Adding a commodity directive sets a more useful display style for A:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
P 2000-01-01 A 2B
|
||
commodity 0.00A
|
||
|
||
2000-01-01
|
||
a 1B
|
||
b
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -X A
|
||
2000-01-01
|
||
a 0.50A
|
||
b -0.50A
|
||
\f[R]
|
||
.fi
|
||
.SS Interaction of valuation and queries
|
||
.PP
|
||
When matching postings based on queries in the presence of valuation,
|
||
the following happens.
|
||
.IP "1." 3
|
||
The query is separated into two parts:
|
||
.RS 4
|
||
.IP "1." 3
|
||
the currency (\f[V]cur:\f[R]) or amount (\f[V]amt:\f[R]).
|
||
.IP "2." 3
|
||
all other parts.
|
||
.RE
|
||
.IP "2." 3
|
||
The postings are matched to the currency and amount queries based on
|
||
pre-valued amounts.
|
||
.IP "3." 3
|
||
Valuation is applied to the postings.
|
||
.IP "4." 3
|
||
The postings are matched to the other parts of the query based on
|
||
post-valued amounts.
|
||
.PP
|
||
See: 1625
|
||
.SS Effect of valuation on reports
|
||
.PP
|
||
Here is a reference for how valuation is supposed to affect each part of
|
||
hledger\[aq]s reports (and a glossary).
|
||
(It\[aq]s wide, you\[aq]ll have to scroll sideways.)
|
||
It may be useful when troubleshooting.
|
||
If you find problems, please report them, ideally with a reproducible
|
||
example.
|
||
Related: #329, #1083.
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(9.5n) lw(11.8n) lw(12.0n) lw(17.2n) lw(12.0n) lw(7.4n).
|
||
T{
|
||
Report type
|
||
T}@T{
|
||
\f[V]-B\f[R], \f[V]--cost\f[R]
|
||
T}@T{
|
||
\f[V]-V\f[R], \f[V]-X\f[R]
|
||
T}@T{
|
||
\f[V]--value=then\f[R]
|
||
T}@T{
|
||
\f[V]--value=end\f[R]
|
||
T}@T{
|
||
\f[V]--value=DATE\f[R], \f[V]--value=now\f[R]
|
||
T}
|
||
_
|
||
T{
|
||
\f[B]print\f[R]
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
posting amounts
|
||
T}@T{
|
||
cost
|
||
T}@T{
|
||
value at report end or today
|
||
T}@T{
|
||
value at posting date
|
||
T}@T{
|
||
value at report or journal end
|
||
T}@T{
|
||
value at DATE/today
|
||
T}
|
||
T{
|
||
balance assertions/assignments
|
||
T}@T{
|
||
unchanged
|
||
T}@T{
|
||
unchanged
|
||
T}@T{
|
||
unchanged
|
||
T}@T{
|
||
unchanged
|
||
T}@T{
|
||
unchanged
|
||
T}
|
||
T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[B]register\f[R]
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
starting balance (-H)
|
||
T}@T{
|
||
cost
|
||
T}@T{
|
||
value at report or journal end
|
||
T}@T{
|
||
valued at day each historical posting was made
|
||
T}@T{
|
||
value at report or journal end
|
||
T}@T{
|
||
value at DATE/today
|
||
T}
|
||
T{
|
||
starting balance (-H) with report interval
|
||
T}@T{
|
||
cost
|
||
T}@T{
|
||
value at day before report or journal start
|
||
T}@T{
|
||
valued at day each historical posting was made
|
||
T}@T{
|
||
value at day before report or journal start
|
||
T}@T{
|
||
value at DATE/today
|
||
T}
|
||
T{
|
||
posting amounts
|
||
T}@T{
|
||
cost
|
||
T}@T{
|
||
value at report or journal end
|
||
T}@T{
|
||
value at posting date
|
||
T}@T{
|
||
value at report or journal end
|
||
T}@T{
|
||
value at DATE/today
|
||
T}
|
||
T{
|
||
summary posting amounts with report interval
|
||
T}@T{
|
||
summarised cost
|
||
T}@T{
|
||
value at period ends
|
||
T}@T{
|
||
sum of postings in interval, valued at interval start
|
||
T}@T{
|
||
value at period ends
|
||
T}@T{
|
||
value at DATE/today
|
||
T}
|
||
T{
|
||
running total/average
|
||
T}@T{
|
||
sum/average of displayed values
|
||
T}@T{
|
||
sum/average of displayed values
|
||
T}@T{
|
||
sum/average of displayed values
|
||
T}@T{
|
||
sum/average of displayed values
|
||
T}@T{
|
||
sum/average of displayed values
|
||
T}
|
||
T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[B]balance (bs, bse, cf, is)\f[R]
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
balance changes
|
||
T}@T{
|
||
sums of costs
|
||
T}@T{
|
||
value at report end or today of sums of postings
|
||
T}@T{
|
||
value at posting date
|
||
T}@T{
|
||
value at report or journal end of sums of postings
|
||
T}@T{
|
||
value at DATE/today of sums of postings
|
||
T}
|
||
T{
|
||
budget amounts (--budget)
|
||
T}@T{
|
||
like balance changes
|
||
T}@T{
|
||
like balance changes
|
||
T}@T{
|
||
like balance changes
|
||
T}@T{
|
||
like balances
|
||
T}@T{
|
||
like balance changes
|
||
T}
|
||
T{
|
||
grand total
|
||
T}@T{
|
||
sum of displayed values
|
||
T}@T{
|
||
sum of displayed values
|
||
T}@T{
|
||
sum of displayed valued
|
||
T}@T{
|
||
sum of displayed values
|
||
T}@T{
|
||
sum of displayed values
|
||
T}
|
||
T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
\f[B]balance (bs, bse, cf, is) with report interval\f[R]
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
starting balances (-H)
|
||
T}@T{
|
||
sums of costs of postings before report start
|
||
T}@T{
|
||
value at report start of sums of all postings before report start
|
||
T}@T{
|
||
sums of values of postings before report start at respective posting
|
||
dates
|
||
T}@T{
|
||
value at report start of sums of all postings before report start
|
||
T}@T{
|
||
sums of postings before report start
|
||
T}
|
||
T{
|
||
balance changes (bal, is, bs --change, cf --change)
|
||
T}@T{
|
||
sums of costs of postings in period
|
||
T}@T{
|
||
same as --value=end
|
||
T}@T{
|
||
sums of values of postings in period at respective posting dates
|
||
T}@T{
|
||
balance change in each period, valued at period ends
|
||
T}@T{
|
||
value at DATE/today of sums of postings
|
||
T}
|
||
T{
|
||
end balances (bal -H, is --H, bs, cf)
|
||
T}@T{
|
||
sums of costs of postings from before report start to period end
|
||
T}@T{
|
||
same as --value=end
|
||
T}@T{
|
||
sums of values of postings from before period start to period end at
|
||
respective posting dates
|
||
T}@T{
|
||
period end balances, valued at period ends
|
||
T}@T{
|
||
value at DATE/today of sums of postings
|
||
T}
|
||
T{
|
||
budget amounts (--budget)
|
||
T}@T{
|
||
like balance changes/end balances
|
||
T}@T{
|
||
like balance changes/end balances
|
||
T}@T{
|
||
like balance changes/end balances
|
||
T}@T{
|
||
like balances
|
||
T}@T{
|
||
like balance changes/end balances
|
||
T}
|
||
T{
|
||
row totals, row averages (-T, -A)
|
||
T}@T{
|
||
sums, averages of displayed values
|
||
T}@T{
|
||
sums, averages of displayed values
|
||
T}@T{
|
||
sums, averages of displayed values
|
||
T}@T{
|
||
sums, averages of displayed values
|
||
T}@T{
|
||
sums, averages of displayed values
|
||
T}
|
||
T{
|
||
column totals
|
||
T}@T{
|
||
sums of displayed values
|
||
T}@T{
|
||
sums of displayed values
|
||
T}@T{
|
||
sums of displayed values
|
||
T}@T{
|
||
sums of displayed values
|
||
T}@T{
|
||
sums of displayed values
|
||
T}
|
||
T{
|
||
grand total, grand average
|
||
T}@T{
|
||
sum, average of column totals
|
||
T}@T{
|
||
sum, average of column totals
|
||
T}@T{
|
||
sum, average of column totals
|
||
T}@T{
|
||
sum, average of column totals
|
||
T}@T{
|
||
sum, average of column totals
|
||
T}
|
||
T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
.TE
|
||
.PP
|
||
\f[V]--cumulative\f[R] is omitted to save space, it works like
|
||
\f[V]-H\f[R] but with a zero starting balance.
|
||
.PP
|
||
\f[B]Glossary:\f[R]
|
||
.TP
|
||
\f[I]cost\f[R]
|
||
calculated using price(s) recorded in the transaction(s).
|
||
.TP
|
||
\f[I]value\f[R]
|
||
market value using available market price declarations, or the unchanged
|
||
amount if no conversion rate can be found.
|
||
.TP
|
||
\f[I]report start\f[R]
|
||
the first day of the report period specified with -b or -p or date:,
|
||
otherwise today.
|
||
.TP
|
||
\f[I]report or journal start\f[R]
|
||
the first day of the report period specified with -b or -p or date:,
|
||
otherwise the earliest transaction date in the journal, otherwise today.
|
||
.TP
|
||
\f[I]report end\f[R]
|
||
the last day of the report period specified with -e or -p or date:,
|
||
otherwise today.
|
||
.TP
|
||
\f[I]report or journal end\f[R]
|
||
the last day of the report period specified with -e or -p or date:,
|
||
otherwise the latest transaction date in the journal, otherwise today.
|
||
.TP
|
||
\f[I]report interval\f[R]
|
||
a flag (-D/-W/-M/-Q/-Y) or period expression that activates the
|
||
report\[aq]s multi-period mode (whether showing one or many subperiods).
|
||
.SH PART 4: COMMANDS
|
||
.SS Commands overview
|
||
.PP
|
||
Here are the built-in commands:
|
||
.SS DATA ENTRY
|
||
.PP
|
||
These data entry commands are the only ones which can modify your
|
||
journal file.
|
||
.IP \[bu] 2
|
||
add - add transactions using terminal prompts
|
||
.IP \[bu] 2
|
||
import - add new transactions from other files, eg CSV files
|
||
.SS DATA CREATION
|
||
.IP \[bu] 2
|
||
close - generate balance-zeroing/restoring transactions
|
||
.IP \[bu] 2
|
||
rewrite - generate auto postings, like print --auto
|
||
.SS DATA MANAGEMENT
|
||
.IP \[bu] 2
|
||
check - check for various kinds of error in the data
|
||
.IP \[bu] 2
|
||
diff - compare account transactions in two journal files
|
||
.SS REPORTS, FINANCIAL
|
||
.IP \[bu] 2
|
||
aregister (areg) - show transactions in a particular account
|
||
.IP \[bu] 2
|
||
balancesheet (bs) - show assets, liabilities and net worth
|
||
.IP \[bu] 2
|
||
balancesheetequity (bse) - show assets, liabilities and equity
|
||
.IP \[bu] 2
|
||
cashflow (cf) - show changes in liquid assets
|
||
.IP \[bu] 2
|
||
incomestatement (is) - show revenues and expenses
|
||
.SS REPORTS, VERSATILE
|
||
.IP \[bu] 2
|
||
balance (bal) - show balance changes, end balances, budgets, gains..
|
||
.IP \[bu] 2
|
||
print - show transactions or export journal data
|
||
.IP \[bu] 2
|
||
register (reg) - show postings in one or more accounts & running total
|
||
.IP \[bu] 2
|
||
roi - show return on investments
|
||
.SS REPORTS, BASIC
|
||
.IP \[bu] 2
|
||
accounts - show account names
|
||
.IP \[bu] 2
|
||
activity - show bar charts of posting counts per period
|
||
.IP \[bu] 2
|
||
codes - show transaction codes
|
||
.IP \[bu] 2
|
||
commodities - show commodity/currency symbols
|
||
.IP \[bu] 2
|
||
descriptions - show transaction descriptions
|
||
.IP \[bu] 2
|
||
files - show input file paths
|
||
.IP \[bu] 2
|
||
notes - show note parts of transaction descriptions
|
||
.IP \[bu] 2
|
||
payees - show payee parts of transaction descriptions
|
||
.IP \[bu] 2
|
||
prices - show market prices
|
||
.IP \[bu] 2
|
||
stats - show journal statistics
|
||
.IP \[bu] 2
|
||
tags - show tag names
|
||
.IP \[bu] 2
|
||
test - run self tests
|
||
.SS HELP
|
||
.IP \[bu] 2
|
||
help - show the hledger manual with info/man/pager
|
||
.IP \[bu] 2
|
||
demo - show small hledger demos in the terminal
|
||
.PP
|
||
.SS ADD-ONS
|
||
.PP
|
||
And here are some typical add-on commands.
|
||
Some of these are installed by the hledger-install script.
|
||
If installed, they will appear in hledger\[aq]s commands list:
|
||
.IP \[bu] 2
|
||
ui - run hledger\[aq]s terminal UI
|
||
.IP \[bu] 2
|
||
web - run hledger\[aq]s web UI
|
||
.IP \[bu] 2
|
||
iadd - add transactions using a TUI (currently hard to build)
|
||
.IP \[bu] 2
|
||
interest - generate interest transactions
|
||
.IP \[bu] 2
|
||
stockquotes - download market prices from AlphaVantage
|
||
.IP \[bu] 2
|
||
Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,
|
||
pijul, plot, and more..
|
||
.PP
|
||
Next, each command is described in detail, in alphabetical order.
|
||
.SS accounts
|
||
.PP
|
||
Show account names.
|
||
.PP
|
||
This command lists account names.
|
||
By default it shows all known accounts, either used in transactions or
|
||
declared with account directives.
|
||
.PP
|
||
With query arguments, only matched account names and account names
|
||
referenced by matched postings are shown.
|
||
.PP
|
||
Or it can show just the used accounts (\f[V]--used\f[R]/\f[V]-u\f[R]),
|
||
the declared accounts (\f[V]--declared\f[R]/\f[V]-d\f[R]), the accounts
|
||
declared but not used (\f[V]--unused\f[R]), the accounts used but not
|
||
declared (\f[V]--undeclared\f[R]), or the first account matched by an
|
||
account name pattern, if any (\f[V]--find\f[R]).
|
||
.PP
|
||
It shows a flat list by default.
|
||
With \f[V]--tree\f[R], it uses indentation to show the account
|
||
hierarchy.
|
||
In flat mode you can add \f[V]--drop N\f[R] to omit the first few
|
||
account name components.
|
||
Account names can be depth-clipped with \f[V]depth:N\f[R] or
|
||
\f[V]--depth N\f[R] or \f[V]-N\f[R].
|
||
.PP
|
||
With \f[V]--types\f[R], it also shows each account\[aq]s type, if
|
||
it\[aq]s known.
|
||
(See Declaring accounts > Account types.)
|
||
.PP
|
||
With \f[V]--positions\f[R], it also shows the file and line number of
|
||
each account\[aq]s declaration, if any, and the account\[aq]s overall
|
||
declaration order; these may be useful when troubleshooting account
|
||
display order.
|
||
.PP
|
||
With \f[V]--directives\f[R], it adds the \f[V]account\f[R] keyword,
|
||
showing valid account directives which can be pasted into a journal
|
||
file.
|
||
This is useful together with \f[V]--undeclared\f[R] when updating your
|
||
account declarations to satisfy \f[V]hledger check accounts\f[R].
|
||
.PP
|
||
The \f[V]--find\f[R] flag can be used to look up a single account name,
|
||
in the same way that the \f[V]aregister\f[R] command does.
|
||
It returns the alphanumerically-first matched account name, or if none
|
||
can be found, it fails with a non-zero exit code.
|
||
.PP
|
||
Examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger accounts
|
||
assets:bank:checking
|
||
assets:bank:saving
|
||
assets:cash
|
||
expenses:food
|
||
expenses:supplies
|
||
income:gifts
|
||
income:salary
|
||
liabilities:debts
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger accounts --undeclared --directives >> $LEDGER_FILE
|
||
$ hledger check accounts
|
||
\f[R]
|
||
.fi
|
||
.SS activity
|
||
.PP
|
||
Show an ascii barchart of posting counts per interval.
|
||
.PP
|
||
The activity command displays an ascii histogram showing transaction
|
||
counts by day, week, month or other reporting interval (by day is the
|
||
default).
|
||
With query arguments, it counts only matched transactions.
|
||
.PP
|
||
Examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger activity --quarterly
|
||
2008-01-01 **
|
||
2008-04-01 *******
|
||
2008-07-01
|
||
2008-10-01 **
|
||
\f[R]
|
||
.fi
|
||
.SS add
|
||
.PP
|
||
Prompt for transactions and add them to the journal.
|
||
Any arguments will be used as default inputs for the first N prompts.
|
||
.PP
|
||
Many hledger users edit their journals directly with a text editor, or
|
||
generate them from CSV.
|
||
For more interactive data entry, there is the \f[V]add\f[R] command,
|
||
which prompts interactively on the console for new transactions, and
|
||
appends them to the main journal file (which should be in journal
|
||
format).
|
||
Existing transactions are not changed.
|
||
This is one of the few hledger commands that writes to the journal file
|
||
(see also \f[V]import\f[R]).
|
||
.PP
|
||
To use it, just run \f[V]hledger add\f[R] and follow the prompts.
|
||
You can add as many transactions as you like; when you are finished,
|
||
enter \f[V].\f[R] or press control-d or control-c to exit.
|
||
.PP
|
||
Features:
|
||
.IP \[bu] 2
|
||
add tries to provide useful defaults, using the most similar (by
|
||
description) recent transaction (filtered by the query, if any) as a
|
||
template.
|
||
.IP \[bu] 2
|
||
You can also set the initial defaults with command line arguments.
|
||
.IP \[bu] 2
|
||
Readline-style edit keys can be used during data entry.
|
||
.IP \[bu] 2
|
||
The tab key will auto-complete whenever possible - accounts,
|
||
payees/descriptions, dates (\f[V]yesterday\f[R], \f[V]today\f[R],
|
||
\f[V]tomorrow\f[R]).
|
||
If the input area is empty, it will insert the default value.
|
||
.IP \[bu] 2
|
||
If the journal defines a default commodity, it will be added to any bare
|
||
numbers entered.
|
||
.IP \[bu] 2
|
||
A parenthesised transaction code may be entered following a date.
|
||
.IP \[bu] 2
|
||
Comments and tags may be entered following a description or amount.
|
||
.IP \[bu] 2
|
||
If you make a mistake, enter \f[V]<\f[R] at any prompt to go one step
|
||
backward.
|
||
.IP \[bu] 2
|
||
Input prompts are displayed in a different colour when the terminal
|
||
supports it.
|
||
.PP
|
||
Example (see https://hledger.org/add.html for a detailed tutorial):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger add
|
||
Adding transactions to journal file /src/hledger/examples/sample.journal
|
||
Any command line arguments will be used as defaults.
|
||
Use tab key to complete, readline keys to edit, enter to accept defaults.
|
||
An optional (CODE) may follow transaction dates.
|
||
An optional ; COMMENT may follow descriptions or amounts.
|
||
If you make a mistake, enter < at any prompt to go one step backward.
|
||
To end a transaction, enter . when prompted.
|
||
To quit, enter . at a date prompt or press control-d or control-c.
|
||
Date [2015/05/22]:
|
||
Description: supermarket
|
||
Account 1: expenses:food
|
||
Amount 1: $10
|
||
Account 2: assets:checking
|
||
Amount 2 [$-10.0]:
|
||
Account 3 (or . or enter to finish this transaction): .
|
||
2015/05/22 supermarket
|
||
expenses:food $10
|
||
assets:checking $-10.0
|
||
|
||
Save this transaction to the journal ? [y]:
|
||
Saved.
|
||
Starting the next transaction (. or ctrl-D/ctrl-C to quit)
|
||
Date [2015/05/22]: <CTRL-D> $
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
On Microsoft Windows, the add command makes sure that no part of the
|
||
file path ends with a period, as that would cause problems (#1056).
|
||
.SS aregister
|
||
.PP
|
||
(areg)
|
||
.PP
|
||
Show the transactions and running historical balance of a single
|
||
account, with each transaction displayed as one line.
|
||
.PP
|
||
\f[V]aregister\f[R] shows the overall transactions affecting a
|
||
particular account (and any subaccounts).
|
||
Each report line represents one transaction in this account.
|
||
Transactions before the report start date are always included in the
|
||
running balance (\f[V]--historical\f[R] mode is always on).
|
||
.PP
|
||
This is a more \[dq]real world\[dq], bank-like view than the
|
||
\f[V]register\f[R] command (which shows individual postings, possibly
|
||
from multiple accounts, not necessarily in historical mode).
|
||
As a quick rule of thumb: - use \f[V]aregister\f[R] for reviewing and
|
||
reconciling real-world asset/liability accounts - use \f[V]register\f[R]
|
||
for reviewing detailed revenues/expenses.
|
||
.PP
|
||
\f[V]aregister\f[R] requires one argument: the account to report on.
|
||
You can write either the full account name, or a case-insensitive
|
||
regular expression which will select the alphabetically first matched
|
||
account.
|
||
.PP
|
||
When there are multiple matches, the alphabetically-first choice can be
|
||
surprising; eg if you have \f[V]assets:per:checking 1\f[R] and
|
||
\f[V]assets:biz:checking 2\f[R] accounts,
|
||
\f[V]hledger areg checking\f[R] would select
|
||
\f[V]assets:biz:checking 2\f[R].
|
||
It\[aq]s just a convenience to save typing, so if in doubt, write the
|
||
full account name, or a distinctive substring that matches uniquely.
|
||
.PP
|
||
Transactions involving subaccounts of this account will also be shown.
|
||
\f[V]aregister\f[R] ignores depth limits, so its final total will always
|
||
match a balance report with similar arguments.
|
||
.PP
|
||
Any additional arguments form a query which will filter the transactions
|
||
shown.
|
||
Note some queries will disturb the running balance, causing it to be
|
||
different from the account\[aq]s real-world running balance.
|
||
.PP
|
||
An example: this shows the transactions and historical running balance
|
||
during july, in the first account whose name contains
|
||
\[dq]checking\[dq]:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger areg checking date:jul
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Each \f[V]aregister\f[R] line item shows:
|
||
.IP \[bu] 2
|
||
the transaction\[aq]s date (or the relevant posting\[aq]s date if
|
||
different, see below)
|
||
.IP \[bu] 2
|
||
the names of all the other account(s) involved in this transaction
|
||
(probably abbreviated)
|
||
.IP \[bu] 2
|
||
the total change to this account\[aq]s balance from this transaction
|
||
.IP \[bu] 2
|
||
the account\[aq]s historical running balance after this transaction.
|
||
.PP
|
||
Transactions making a net change of zero are not shown by default; add
|
||
the \f[V]-E/--empty\f[R] flag to show them.
|
||
.PP
|
||
For performance reasons, column widths are chosen based on the first
|
||
1000 lines; this means unusually wide values in later lines can cause
|
||
visual discontinuities as column widths are adjusted.
|
||
If you want to ensure perfect alignment, at the cost of more time and
|
||
memory, use the \f[V]--align-all\f[R] flag.
|
||
.PP
|
||
This command also supports the output destination and output format
|
||
options.
|
||
The output formats supported are \f[V]txt\f[R], \f[V]csv\f[R], and
|
||
\f[V]json\f[R].
|
||
.SS aregister and custom posting dates
|
||
.PP
|
||
Transactions whose date is outside the report period can still be shown,
|
||
if they have a posting to this account dated inside the report period.
|
||
(And in this case it\[aq]s the posting date that is shown.)
|
||
This ensures that \f[V]aregister\f[R] can show an accurate historical
|
||
running balance, matching the one shown by \f[V]register -H\f[R] with
|
||
the same arguments.
|
||
.PP
|
||
To filter strictly by transaction date instead, add the
|
||
\f[V]--txn-dates\f[R] flag.
|
||
If you use this flag and some of your postings have custom dates,
|
||
it\[aq]s probably best to assume the running balance is wrong.
|
||
.SS balance
|
||
.PP
|
||
(bal)
|
||
.PP
|
||
Show accounts and their balances.
|
||
.PP
|
||
\f[V]balance\f[R] is one of hledger\[aq]s oldest and most versatile
|
||
commands, for listing account balances, balance changes, values, value
|
||
changes and more, during one time period or many.
|
||
Generally it shows a table, with rows representing accounts, and columns
|
||
representing periods.
|
||
.PP
|
||
Note there are some higher-level variants of the \f[V]balance\f[R]
|
||
command with convenient defaults, which can be simpler to use:
|
||
\f[V]balancesheet\f[R], \f[V]balancesheetequity\f[R], \f[V]cashflow\f[R]
|
||
and \f[V]incomestatement\f[R].
|
||
When you need more control, then use \f[V]balance\f[R].
|
||
.SS balance features
|
||
.PP
|
||
Here\[aq]s a quick overview of the \f[V]balance\f[R] command\[aq]s
|
||
features, followed by more detailed descriptions and examples.
|
||
Many of these work with the higher-level commands as well.
|
||
.PP
|
||
\f[V]balance\f[R] can show..
|
||
.IP \[bu] 2
|
||
accounts as a list (\f[V]-l\f[R]) or a tree (\f[V]-t\f[R])
|
||
.IP \[bu] 2
|
||
optionally depth-limited (\f[V]-[1-9]\f[R])
|
||
.IP \[bu] 2
|
||
sorted by declaration order and name, or by amount
|
||
.PP
|
||
\&..and their..
|
||
.IP \[bu] 2
|
||
balance changes (the default)
|
||
.IP \[bu] 2
|
||
or actual and planned balance changes (\f[V]--budget\f[R])
|
||
.IP \[bu] 2
|
||
or value of balance changes (\f[V]-V\f[R])
|
||
.IP \[bu] 2
|
||
or change of balance values (\f[V]--valuechange\f[R])
|
||
.IP \[bu] 2
|
||
or unrealised capital gain/loss (\f[V]--gain\f[R])
|
||
.IP \[bu] 2
|
||
or postings count (\f[V]--count\f[R])
|
||
.PP
|
||
\&..in..
|
||
.IP \[bu] 2
|
||
one time period (the whole journal period by default)
|
||
.IP \[bu] 2
|
||
or multiple periods (\f[V]-D\f[R], \f[V]-W\f[R], \f[V]-M\f[R],
|
||
\f[V]-Q\f[R], \f[V]-Y\f[R], \f[V]-p INTERVAL\f[R])
|
||
.PP
|
||
\&..either..
|
||
.IP \[bu] 2
|
||
per period (the default)
|
||
.IP \[bu] 2
|
||
or accumulated since report start date (\f[V]--cumulative\f[R])
|
||
.IP \[bu] 2
|
||
or accumulated since account creation (\f[V]--historical/-H\f[R])
|
||
.PP
|
||
\&..possibly converted to..
|
||
.IP \[bu] 2
|
||
cost (\f[V]--value=cost[,COMM]\f[R]/\f[V]--cost\f[R]/\f[V]-B\f[R])
|
||
.IP \[bu] 2
|
||
or market value, as of transaction dates (\f[V]--value=then[,COMM]\f[R])
|
||
.IP \[bu] 2
|
||
or at period ends (\f[V]--value=end[,COMM]\f[R])
|
||
.IP \[bu] 2
|
||
or now (\f[V]--value=now\f[R])
|
||
.IP \[bu] 2
|
||
or at some other date (\f[V]--value=YYYY-MM-DD\f[R])
|
||
.PP
|
||
\&..with..
|
||
.IP \[bu] 2
|
||
totals (\f[V]-T\f[R]), averages (\f[V]-A\f[R]), percentages
|
||
(\f[V]-%\f[R]), inverted sign (\f[V]--invert\f[R])
|
||
.IP \[bu] 2
|
||
rows and columns swapped (\f[V]--transpose\f[R])
|
||
.IP \[bu] 2
|
||
another field used as account name (\f[V]--pivot\f[R])
|
||
.IP \[bu] 2
|
||
custom-formatted line items (single-period reports only)
|
||
(\f[V]--format\f[R])
|
||
.IP \[bu] 2
|
||
commodities displayed on the same line or multiple lines
|
||
(\f[V]--layout\f[R])
|
||
.PP
|
||
This command supports the output destination and output format options,
|
||
with output formats \f[V]txt\f[R], \f[V]csv\f[R], \f[V]json\f[R], and
|
||
(multi-period reports only:) \f[V]html\f[R].
|
||
In \f[V]txt\f[R] output in a colour-supporting terminal, negative
|
||
amounts are shown in red.
|
||
.PP
|
||
The \f[V]--related\f[R]/\f[V]-r\f[R] flag shows the balance of the
|
||
\f[I]other\f[R] postings in the transactions of the postings which would
|
||
normally be shown.
|
||
.SS Simple balance report
|
||
.PP
|
||
With no arguments, \f[V]balance\f[R] shows a list of all accounts and
|
||
their change of balance - ie, the sum of posting amounts, both inflows
|
||
and outflows - during the entire period of the journal.
|
||
(\[dq]Simple\[dq] here means just one column of numbers, covering a
|
||
single period.
|
||
You can also have multi-period reports, described later.)
|
||
.PP
|
||
For real-world accounts, these numbers will normally be their end
|
||
balance at the end of the journal period; more on this below.
|
||
.PP
|
||
Accounts are sorted by declaration order if any, and then alphabetically
|
||
by account name.
|
||
For instance (using examples/sample.journal):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/sample.journal bal
|
||
$1 assets:bank:saving
|
||
$-2 assets:cash
|
||
$1 expenses:food
|
||
$1 expenses:supplies
|
||
$-1 income:gifts
|
||
$-1 income:salary
|
||
$1 liabilities:debts
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Accounts with a zero balance (and no non-zero subaccounts, in tree mode
|
||
- see below) are hidden by default.
|
||
Use \f[V]-E/--empty\f[R] to show them (revealing
|
||
\f[V]assets:bank:checking\f[R] here):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/sample.journal bal -E
|
||
0 assets:bank:checking
|
||
$1 assets:bank:saving
|
||
$-2 assets:cash
|
||
$1 expenses:food
|
||
$1 expenses:supplies
|
||
$-1 income:gifts
|
||
$-1 income:salary
|
||
$1 liabilities:debts
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The total of the amounts displayed is shown as the last line, unless
|
||
\f[V]-N\f[R]/\f[V]--no-total\f[R] is used.
|
||
.SS Balance report line format
|
||
.PP
|
||
For single-period balance reports displayed in the terminal (only), you
|
||
can use \f[V]--format FMT\f[R] to customise the format and content of
|
||
each line.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/sample.journal balance --format \[dq]%20(account) %12(total)\[dq]
|
||
assets $-1
|
||
bank:saving $1
|
||
cash $-2
|
||
expenses $2
|
||
food $1
|
||
supplies $1
|
||
income $-2
|
||
gifts $-1
|
||
salary $-1
|
||
liabilities:debts $1
|
||
---------------------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The FMT format string specifies the formatting applied to each
|
||
account/balance pair.
|
||
It may contain any suitable text, with data fields interpolated like so:
|
||
.PP
|
||
\f[V]%[MIN][.MAX](FIELDNAME)\f[R]
|
||
.IP \[bu] 2
|
||
MIN pads with spaces to at least this width (optional)
|
||
.IP \[bu] 2
|
||
MAX truncates at this width (optional)
|
||
.IP \[bu] 2
|
||
FIELDNAME must be enclosed in parentheses, and can be one of:
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
\f[V]depth_spacer\f[R] - a number of spaces equal to the account\[aq]s
|
||
depth, or if MIN is specified, MIN * depth spaces.
|
||
.IP \[bu] 2
|
||
\f[V]account\f[R] - the account\[aq]s name
|
||
.IP \[bu] 2
|
||
\f[V]total\f[R] - the account\[aq]s balance/posted total, right
|
||
justified
|
||
.RE
|
||
.PP
|
||
Also, FMT can begin with an optional prefix to control how
|
||
multi-commodity amounts are rendered:
|
||
.IP \[bu] 2
|
||
\f[V]%_\f[R] - render on multiple lines, bottom-aligned (the default)
|
||
.IP \[bu] 2
|
||
\f[V]%\[ha]\f[R] - render on multiple lines, top-aligned
|
||
.IP \[bu] 2
|
||
\f[V]%,\f[R] - render on one line, comma-separated
|
||
.PP
|
||
There are some quirks.
|
||
Eg in one-line mode, \f[V]%(depth_spacer)\f[R] has no effect, instead
|
||
\f[V]%(account)\f[R] has indentation built in.
|
||
Experimentation may be needed to get pleasing results.
|
||
.PP
|
||
Some example formats:
|
||
.IP \[bu] 2
|
||
\f[V]%(total)\f[R] - the account\[aq]s total
|
||
.IP \[bu] 2
|
||
\f[V]%-20.20(account)\f[R] - the account\[aq]s name, left justified,
|
||
padded to 20 characters and clipped at 20 characters
|
||
.IP \[bu] 2
|
||
\f[V]%,%-50(account) %25(total)\f[R] - account name padded to 50
|
||
characters, total padded to 20 characters, with multiple commodities
|
||
rendered on one line
|
||
.IP \[bu] 2
|
||
\f[V]%20(total) %2(depth_spacer)%-(account)\f[R] - the default format
|
||
for the single-column balance report
|
||
.SS Filtered balance report
|
||
.PP
|
||
You can show fewer accounts, a different time period, totals from
|
||
cleared transactions only, etc.
|
||
by using query arguments or options to limit the postings being matched.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/sample.journal bal --cleared assets date:200806
|
||
$-2 assets:cash
|
||
--------------------
|
||
$-2
|
||
\f[R]
|
||
.fi
|
||
.SS List or tree mode
|
||
.PP
|
||
By default, or with \f[V]-l/--flat\f[R], accounts are shown as a flat
|
||
list with their full names visible, as in the examples above.
|
||
.PP
|
||
With \f[V]-t/--tree\f[R], the account hierarchy is shown, with
|
||
subaccounts\[aq] \[dq]leaf\[dq] names indented below their parent:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/sample.journal balance
|
||
$-1 assets
|
||
$1 bank:saving
|
||
$-2 cash
|
||
$2 expenses
|
||
$1 food
|
||
$1 supplies
|
||
$-2 income
|
||
$-1 gifts
|
||
$-1 salary
|
||
$1 liabilities:debts
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Notes:
|
||
.IP \[bu] 2
|
||
\[dq]Boring\[dq] accounts are combined with their subaccount for more
|
||
compact output, unless \f[V]--no-elide\f[R] is used.
|
||
Boring accounts have no balance of their own and just one subaccount (eg
|
||
\f[V]assets:bank\f[R] and \f[V]liabilities\f[R] above).
|
||
.IP \[bu] 2
|
||
All balances shown are \[dq]inclusive\[dq], ie including the balances
|
||
from all subaccounts.
|
||
Note this means some repetition in the output, which requires
|
||
explanation when sharing reports with non-plaintextaccounting-users.
|
||
A tree mode report\[aq]s final total is the sum of the top-level
|
||
balances shown, not of all the balances shown.
|
||
.IP \[bu] 2
|
||
Each group of sibling accounts (ie, under a common parent) is sorted
|
||
separately.
|
||
.SS Depth limiting
|
||
.PP
|
||
With a \f[V]depth:NUM\f[R] query, or \f[V]--depth NUM\f[R] option, or
|
||
just \f[V]-NUM\f[R] (eg: \f[V]-3\f[R]) balance reports will show
|
||
accounts only to the specified depth, hiding the deeper subaccounts.
|
||
This can be useful for getting an overview without too much detail.
|
||
.PP
|
||
Account balances at the depth limit always include the balances from any
|
||
deeper subaccounts (even in list mode).
|
||
Eg, limiting to depth 1:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/sample.journal balance -1
|
||
$-1 assets
|
||
$2 expenses
|
||
$-2 income
|
||
$1 liabilities
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.SS Dropping top-level accounts
|
||
.PP
|
||
You can also hide one or more top-level account name parts, using
|
||
\f[V]--drop NUM\f[R].
|
||
This can be useful for hiding repetitive top-level account names:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/sample.journal bal expenses --drop 1
|
||
$1 food
|
||
$1 supplies
|
||
--------------------
|
||
$2
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
.SS Showing declared accounts
|
||
.PP
|
||
With \f[V]--declared\f[R], accounts which have been declared with an
|
||
account directive will be included in the balance report, even if they
|
||
have no transactions.
|
||
(Since they will have a zero balance, you will also need
|
||
\f[V]-E/--empty\f[R] to see them.)
|
||
.PP
|
||
More precisely, \f[I]leaf\f[R] declared accounts (with no subaccounts)
|
||
will be included, since those are usually the more useful in reports.
|
||
.PP
|
||
The idea of this is to be able to see a useful \[dq]complete\[dq]
|
||
balance report, even when you don\[aq]t have transactions in all of your
|
||
declared accounts yet.
|
||
.SS Sorting by amount
|
||
.PP
|
||
With \f[V]-S/--sort-amount\f[R], accounts with the largest (most
|
||
positive) balances are shown first.
|
||
Eg: \f[V]hledger bal expenses -MAS\f[R] shows your biggest averaged
|
||
monthly expenses first.
|
||
When more than one commodity is present, they will be sorted by the
|
||
alphabetically earliest commodity first, and then by subsequent
|
||
commodities (if an amount is missing a commodity, it is treated as 0).
|
||
.PP
|
||
Revenues and liability balances are typically negative, however, so
|
||
\f[V]-S\f[R] shows these in reverse order.
|
||
To work around this, you can add \f[V]--invert\f[R] to flip the signs.
|
||
(Or, use one of the higher-level reports, which flip the sign
|
||
automatically.
|
||
Eg: \f[V]hledger incomestatement -MAS\f[R]).
|
||
.PP
|
||
.SS Percentages
|
||
.PP
|
||
With \f[V]-%/--percent\f[R], balance reports show each account\[aq]s
|
||
value expressed as a percentage of the (column) total.
|
||
.PP
|
||
Note it is not useful to calculate percentages if the amounts in a
|
||
column have mixed signs.
|
||
In this case, make a separate report for each sign, eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger bal -% amt:\[ga]>0\[ga]
|
||
$ hledger bal -% amt:\[ga]<0\[ga]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Similarly, if the amounts in a column have mixed commodities, convert
|
||
them to one commodity with \f[V]-B\f[R], \f[V]-V\f[R], \f[V]-X\f[R] or
|
||
\f[V]--value\f[R], or make a separate report for each commodity:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger bal -% cur:\[rs]\[rs]$
|
||
$ hledger bal -% cur:€
|
||
\f[R]
|
||
.fi
|
||
.SS Multi-period balance report
|
||
.PP
|
||
With a report interval (set by the \f[V]-D/--daily\f[R],
|
||
\f[V]-W/--weekly\f[R], \f[V]-M/--monthly\f[R], \f[V]-Q/--quarterly\f[R],
|
||
\f[V]-Y/--yearly\f[R], or \f[V]-p/--period\f[R] flag), \f[V]balance\f[R]
|
||
shows a tabular report, with columns representing successive time
|
||
periods (and a title):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/sample.journal bal --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
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Notes:
|
||
.IP \[bu] 2
|
||
The report\[aq]s start/end dates will be expanded, if necessary, to
|
||
fully encompass the displayed subperiods (so that the first and last
|
||
subperiods have the same duration as the others).
|
||
.IP \[bu] 2
|
||
Leading and trailing periods (columns) containing all zeroes are not
|
||
shown, unless \f[V]-E/--empty\f[R] is used.
|
||
.IP \[bu] 2
|
||
Accounts (rows) containing all zeroes are not shown, unless
|
||
\f[V]-E/--empty\f[R] is used.
|
||
.IP \[bu] 2
|
||
Amounts with many commodities are shown in abbreviated form, unless
|
||
\f[V]--no-elide\f[R] is used.
|
||
\f[I](experimental)\f[R]
|
||
.IP \[bu] 2
|
||
Average and/or total columns can be added with the
|
||
\f[V]-A/--average\f[R] and \f[V]-T/--row-total\f[R] flags.
|
||
.IP \[bu] 2
|
||
The \f[V]--transpose\f[R] flag can be used to exchange rows and columns.
|
||
.IP \[bu] 2
|
||
The \f[V]--pivot FIELD\f[R] option causes a different transaction field
|
||
to be used as \[dq]account name\[dq].
|
||
See PIVOTING.
|
||
.PP
|
||
Multi-period reports with many periods can be too wide for easy viewing
|
||
in the terminal.
|
||
Here are some ways to handle that:
|
||
.IP \[bu] 2
|
||
Hide the totals row with \f[V]-N/--no-total\f[R]
|
||
.IP \[bu] 2
|
||
Convert to a single currency with \f[V]-V\f[R]
|
||
.IP \[bu] 2
|
||
Maximize the terminal window
|
||
.IP \[bu] 2
|
||
Reduce the terminal\[aq]s font size
|
||
.IP \[bu] 2
|
||
View with a pager like less, eg:
|
||
\f[V]hledger bal -D --color=yes | less -RS\f[R]
|
||
.IP \[bu] 2
|
||
Output as CSV and use a CSV viewer like visidata
|
||
(\f[V]hledger bal -D -O csv | vd -f csv\f[R]), Emacs\[aq] csv-mode
|
||
(\f[V]M-x csv-mode, C-c C-a\f[R]), or a spreadsheet
|
||
(\f[V]hledger bal -D -o a.csv && open a.csv\f[R])
|
||
.IP \[bu] 2
|
||
Output as HTML and view with a browser:
|
||
\f[V]hledger bal -D -o a.html && open a.html\f[R]
|
||
.SS Balance change, end balance
|
||
.PP
|
||
It\[aq]s important to be clear on the meaning of the numbers shown in
|
||
balance reports.
|
||
Here is some terminology we use:
|
||
.PP
|
||
A \f[B]\f[BI]balance change\f[B]\f[R] is the net amount added to, or
|
||
removed from, an account during some period.
|
||
.PP
|
||
An \f[B]\f[BI]end balance\f[B]\f[R] is the amount accumulated in an
|
||
account as of some date (and some time, but hledger doesn\[aq]t store
|
||
that; assume end of day in your timezone).
|
||
It is the sum of previous balance changes.
|
||
.PP
|
||
We call it a \f[B]\f[BI]historical end balance\f[B]\f[R] if it includes
|
||
all balance changes since the account was created.
|
||
For a real world account, this means it will match the \[dq]historical
|
||
record\[dq], eg the balances reported in your bank statements or bank
|
||
web UI.
|
||
(If they are correct!)
|
||
.PP
|
||
In general, balance changes are what you want to see when reviewing
|
||
revenues and expenses, and historical end balances are what you want to
|
||
see when reviewing or reconciling asset, liability and equity accounts.
|
||
.PP
|
||
\f[V]balance\f[R] shows balance changes by default.
|
||
To see accurate historical end balances:
|
||
.IP "1." 3
|
||
Initialise account starting balances with an \[dq]opening balances\[dq]
|
||
transaction (a transfer from equity to the account), unless the journal
|
||
covers the account\[aq]s full lifetime.
|
||
.IP "2." 3
|
||
Include all of of the account\[aq]s prior postings in the report, by not
|
||
specifying a report start date, or by using the
|
||
\f[V]-H/--historical\f[R] flag.
|
||
(\f[V]-H\f[R] causes report start date to be ignored when summing
|
||
postings.)
|
||
.SS Balance report types
|
||
.PP
|
||
The balance command is quite flexible; here is the full detail on how to
|
||
control what it reports.
|
||
If the following seems complicated, don\[aq]t worry - this is for
|
||
advanced reporting, and it does take time and experimentation to get
|
||
familiar with all the report modes.
|
||
.PP
|
||
There are three important option groups:
|
||
.PP
|
||
\f[V]hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE] ...\f[R]
|
||
.SS Calculation type
|
||
.PP
|
||
The basic calculation to perform for each table cell.
|
||
It is one of:
|
||
.IP \[bu] 2
|
||
\f[V]--sum\f[R] : sum the posting amounts (\f[B]default\f[R])
|
||
.IP \[bu] 2
|
||
\f[V]--budget\f[R] : sum the amounts, but also show the budget goal
|
||
amount (for each account/period)
|
||
.IP \[bu] 2
|
||
\f[V]--valuechange\f[R] : show the change in period-end historical
|
||
balance values (caused by deposits, withdrawals, and/or market price
|
||
fluctuations)
|
||
.IP \[bu] 2
|
||
\f[V]--gain\f[R] : show the unrealised capital gain/loss, (the current
|
||
valued balance minus each amount\[aq]s original cost)
|
||
.IP \[bu] 2
|
||
\f[V]--count\f[R] : show the count of postings
|
||
.SS Accumulation type
|
||
.PP
|
||
How amounts should accumulate across report periods.
|
||
Another way to say it: which time period\[aq]s postings should
|
||
contribute to each cell\[aq]s calculation.
|
||
It is one of:
|
||
.IP \[bu] 2
|
||
\f[V]--change\f[R] : calculate with postings from column start to column
|
||
end, ie \[dq]just this column\[dq].
|
||
Typically used to see revenues/expenses.
|
||
(\f[B]default for balance, incomestatement\f[R])
|
||
.IP \[bu] 2
|
||
\f[V]--cumulative\f[R] : calculate with postings from report start to
|
||
column end, ie \[dq]previous columns plus this column\[dq].
|
||
Typically used to show changes accumulated since the report\[aq]s start
|
||
date.
|
||
Not often used.
|
||
.IP \[bu] 2
|
||
\f[V]--historical/-H\f[R] : calculate with postings from journal start
|
||
to column end, ie \[dq]all postings from before report start date until
|
||
this column\[aq]s end\[dq].
|
||
Typically used to see historical end balances of
|
||
assets/liabilities/equity.
|
||
(\f[B]default for balancesheet, balancesheetequity, cashflow\f[R])
|
||
.SS Valuation type
|
||
.PP
|
||
Which kind of value or cost conversion should be applied, if any, before
|
||
displaying the report.
|
||
It is one of:
|
||
.IP \[bu] 2
|
||
no valuation type : don\[aq]t convert to cost or value
|
||
(\f[B]default\f[R])
|
||
.IP \[bu] 2
|
||
\f[V]--value=cost[,COMM]\f[R] : convert amounts to cost (then optionally
|
||
to some other commodity)
|
||
.IP \[bu] 2
|
||
\f[V]--value=then[,COMM]\f[R] : convert amounts to market value on
|
||
transaction dates
|
||
.IP \[bu] 2
|
||
\f[V]--value=end[,COMM]\f[R] : convert amounts to market value on period
|
||
end date(s)
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
(\f[B]default with \f[VB]--valuechange\f[B], \f[VB]--gain\f[B]\f[R])
|
||
.IP \[bu] 2
|
||
\f[V]--value=now[,COMM]\f[R] : convert amounts to market value on
|
||
today\[aq]s date
|
||
.IP \[bu] 2
|
||
\f[V]--value=YYYY-MM-DD[,COMM]\f[R] : convert amounts to market value on
|
||
another date
|
||
.PP
|
||
or one of the equivalent simpler flags:
|
||
.IP \[bu] 2
|
||
\f[V]-B/--cost\f[R] : like --value=cost (though, note --cost and --value
|
||
are independent options which can both be used at once)
|
||
.IP \[bu] 2
|
||
\f[V]-V/--market\f[R] : like --value=end
|
||
.IP \[bu] 2
|
||
\f[V]-X COMM/--exchange COMM\f[R] : like --value=end,COMM
|
||
.PP
|
||
See Cost reporting and Valuation for more about these.
|
||
.SS Combining balance report types
|
||
.PP
|
||
Most combinations of these options should produce reasonable reports,
|
||
but if you find any that seem wrong or misleading, let us know.
|
||
The following restrictions are applied:
|
||
.IP \[bu] 2
|
||
\f[V]--valuechange\f[R] implies \f[V]--value=end\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]--valuechange\f[R] makes \f[V]--change\f[R] the default when used
|
||
with the \f[V]balancesheet\f[R]/\f[V]balancesheetequity\f[R] commands
|
||
.IP \[bu] 2
|
||
\f[V]--cumulative\f[R] or \f[V]--historical\f[R] disables
|
||
\f[V]--row-total/-T\f[R]
|
||
.PP
|
||
For reference, here is what the combinations of accumulation and
|
||
valuation show:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(7.9n) lw(16.4n) lw(16.9n) lw(15.1n) lw(13.7n).
|
||
T{
|
||
Valuation:> Accumulation:v
|
||
T}@T{
|
||
no valuation
|
||
T}@T{
|
||
\f[V]--value= then\f[R]
|
||
T}@T{
|
||
\f[V]--value= end\f[R]
|
||
T}@T{
|
||
\f[V]--value= YYYY-MM-DD /now\f[R]
|
||
T}
|
||
_
|
||
T{
|
||
\f[V]--change\f[R]
|
||
T}@T{
|
||
change in period
|
||
T}@T{
|
||
sum of posting-date market values in period
|
||
T}@T{
|
||
period-end value of change in period
|
||
T}@T{
|
||
DATE-value of change in period
|
||
T}
|
||
T{
|
||
\f[V]--cumulative\f[R]
|
||
T}@T{
|
||
change from report start to period end
|
||
T}@T{
|
||
sum of posting-date market values from report start to period end
|
||
T}@T{
|
||
period-end value of change from report start to period end
|
||
T}@T{
|
||
DATE-value of change from report start to period end
|
||
T}
|
||
T{
|
||
\f[V]--historical /-H\f[R]
|
||
T}@T{
|
||
change from journal start to period end (historical end balance)
|
||
T}@T{
|
||
sum of posting-date market values from journal start to period end
|
||
T}@T{
|
||
period-end value of change from journal start to period end
|
||
T}@T{
|
||
DATE-value of change from journal start to period end
|
||
T}
|
||
.TE
|
||
.SS Budget report
|
||
.PP
|
||
The \f[V]--budget\f[R] report type activates extra columns showing any
|
||
budget goals for each account and period.
|
||
The budget goals are defined by periodic transactions.
|
||
This is useful for comparing planned and actual income, expenses, time
|
||
usage, etc.
|
||
.PP
|
||
For example, you can take average monthly expenses in the common expense
|
||
categories to construct a minimal monthly budget:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
;; Budget
|
||
\[ti] 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
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
You can now see a monthly budget report:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ 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]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This is different from a normal balance report in several ways.
|
||
Currently:
|
||
.IP \[bu] 2
|
||
Accounts with budget goals during the report period, and their parents,
|
||
are shown.
|
||
.IP \[bu] 2
|
||
Their subaccounts are not shown (regardless of the depth setting).
|
||
.IP \[bu] 2
|
||
Accounts without budget goals, if any, are aggregated and shown as
|
||
\[dq]<unbudgeted>\[dq].
|
||
.IP \[bu] 2
|
||
Amounts are always inclusive (subaccount-including), even in list mode.
|
||
.IP \[bu] 2
|
||
After each actual amount, the corresponding goal amount and percentage
|
||
of goal reached are also shown, in square brackets.
|
||
.PP
|
||
This means that the numbers displayed will not always add up!
|
||
Eg above, the \f[V]expenses\f[R] actual amount includes the gifts and
|
||
supplies transactions, but the \f[V]expenses:gifts\f[R] and
|
||
\f[V]expenses:supplies\f[R] accounts are not shown, as they have no
|
||
budget amounts declared.
|
||
.PP
|
||
This can be confusing.
|
||
When you need to make things clearer, use the \f[V]-E/--empty\f[R] flag,
|
||
which will reveal all accounts including unbudgeted ones, giving the
|
||
full picture.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ 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]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
You can roll over unspent budgets to next period with
|
||
\f[V]--cumulative\f[R]:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ 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]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
It\[aq]s common to limit budgets/budget reports to just expenses
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
hledger bal -M --budget expenses
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or just revenues and expenses (eg, using account types):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
hledger bal -M --budget type:rx
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
It\[aq]s also common to limit or convert them to a single currency
|
||
(\f[V]cur:COMM\f[R] or \f[V]-X COMM [--infer-market-prices]\f[R]).
|
||
If showing multiple currencies, \f[V]--layout bare\f[R] or
|
||
\f[V]--layout tall\f[R] can help.
|
||
.PP
|
||
For more examples and notes, see Budgeting.
|
||
.SS Budget report start date
|
||
.PP
|
||
This might be a bug, but for now: when making budget reports, it\[aq]s a
|
||
good idea to explicitly set the report\[aq]s start date to the first day
|
||
of a reporting period, because a periodic rule like
|
||
\f[V]\[ti] monthly\f[R] 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:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
\[ti] monthly in 2020
|
||
(expenses:food) $500
|
||
|
||
2020-01-15
|
||
expenses:food $400
|
||
assets:checking
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger bal expenses --budget
|
||
Budget performance in 2020-01-15:
|
||
|
||
|| 2020-01-15
|
||
==============++============
|
||
<unbudgeted> || $400
|
||
--------------++------------
|
||
|| $400
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
To avoid this, specify the budget report\[aq]s period, or at least the
|
||
start date, with \f[V]-b\f[R]/\f[V]-e\f[R]/\f[V]-p\f[R]/\f[V]date:\f[R],
|
||
to ensure it includes the budget goal transactions (periodic
|
||
transactions) that you want.
|
||
Eg, adding \f[V]-b 2020/1/1\f[R] to the above:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ 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]
|
||
\f[R]
|
||
.fi
|
||
.SS Budgets and subaccounts
|
||
.PP
|
||
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.
|
||
.PP
|
||
In the most simple case this means that once you add a budget to any
|
||
account, all its parents would have budget as well.
|
||
.PP
|
||
To illustrate this, consider the following budget:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
\[ti] monthly from 2019/01
|
||
expenses:personal $1,000.00
|
||
expenses:personal:electronics $100.00
|
||
liabilities
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
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 \f[V]expenses:personal\f[R] and
|
||
\f[V]expenses\f[R] is $1100.
|
||
.PP
|
||
Transactions in \f[V]expenses:personal:electronics\f[R] will be counted
|
||
both towards its $100 budget and $1100 of \f[V]expenses:personal\f[R] ,
|
||
and transactions in any other subaccount of \f[V]expenses:personal\f[R]
|
||
would be counted towards only towards the budget of
|
||
\f[V]expenses:personal\f[R].
|
||
.PP
|
||
For example, let\[aq]s consider these transactions:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
\[ti] 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
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
As you can see, we have transactions in
|
||
\f[V]expenses:personal:electronics:upgrades\f[R] and
|
||
\f[V]expenses:personal:train tickets\f[R], and since both of these
|
||
accounts are without explicitly defined budget, these transactions would
|
||
be counted towards budgets of \f[V]expenses:personal:electronics\f[R]
|
||
and \f[V]expenses:personal\f[R] accordingly:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ 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]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
And with \f[V]--empty\f[R], we can get a better picture of budget
|
||
allocation and consumption:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ 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]
|
||
\f[R]
|
||
.fi
|
||
.SS Selecting budget goals
|
||
.PP
|
||
The budget report evaluates periodic transaction rules to generate
|
||
special \[dq]goal transactions\[dq], which generate the goal amounts for
|
||
each account in each report subperiod.
|
||
When troubleshooting, you can use \f[V]print --forecast\f[R] to show
|
||
these as forecasted transactions:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print --forecast=BUDGETREPORTPERIOD tag:generated
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
By default, the budget report uses all available periodic transaction
|
||
rules to generate goals.
|
||
This includes rules with a different report interval from your report.
|
||
Eg if you have daily, weekly and monthly periodic rules, all of these
|
||
will contribute to the goals in a monthly budget report.
|
||
.PP
|
||
You can select a subset of periodic rules by providing an argument to
|
||
the \f[V]--budget\f[R] flag.
|
||
\f[V]--budget=DESCPAT\f[R] will match all periodic rules whose
|
||
description contains DESCPAT, a case-insensitive substring (not a
|
||
regular expression or query).
|
||
This means you can give your periodic rules descriptions (remember that
|
||
two spaces are needed), and then select from multiple budgets defined in
|
||
your journal.
|
||
.SS Budget vs forecast
|
||
.PP
|
||
\f[V]hledger --forecast ...\f[R] and
|
||
\f[V]hledger balance --budget ...\f[R] are separate features, though
|
||
both of them use the periodic transaction rules defined in the journal,
|
||
and both of them generate temporary transactions for reporting purposes
|
||
(\[dq]forecast transactions\[dq] and \[dq]budget goal transactions\[dq],
|
||
respectively).
|
||
You can use both features at the same time if you want.
|
||
Here are some differences between them, as of hledger 1.29:
|
||
.PP
|
||
CLI:
|
||
.IP \[bu] 2
|
||
--forecast is a general hledger option, usable with any command
|
||
.IP \[bu] 2
|
||
--budget is a \f[V]balance\f[R] command option, usable only with that
|
||
command.
|
||
.PP
|
||
Visibility of generated transactions:
|
||
.IP \[bu] 2
|
||
forecast transactions are visible in any report, like ordinary
|
||
transactions
|
||
.IP \[bu] 2
|
||
budget goal transactions are invisible except for the goal amounts they
|
||
produce in --budget reports.
|
||
.PP
|
||
Periodic transaction rules:
|
||
.IP \[bu] 2
|
||
--forecast uses all available periodic transaction rules
|
||
.IP \[bu] 2
|
||
--budget uses all periodic rules (\f[V]--budget\f[R]) or a selected
|
||
subset (\f[V]--budget=DESCPAT\f[R])
|
||
.PP
|
||
Period of generated transactions:
|
||
.IP \[bu] 2
|
||
--forecast generates forecast transactions
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
from after the last regular transaction to the end of the report period
|
||
(\f[V]--forecast\f[R])
|
||
.IP \[bu] 2
|
||
or, during a specified period (\f[V]--forecast=PERIODEXPR\f[R])
|
||
.IP \[bu] 2
|
||
possibly further restricted by a period specified in the periodic
|
||
transaction rule
|
||
.IP \[bu] 2
|
||
and always restricted within the bounds of the report period
|
||
.RE
|
||
.IP \[bu] 2
|
||
--budget generates budget goal transactions
|
||
.RS 2
|
||
.IP \[bu] 2
|
||
throughout the report period
|
||
.IP \[bu] 2
|
||
possibly restricted by a period specified in the periodic transaction
|
||
rule.
|
||
.RE
|
||
.SS Data layout
|
||
.PP
|
||
The \f[V]--layout\f[R] option affects how balance reports show
|
||
multi-commodity amounts and commodity symbols, which can improve
|
||
readability.
|
||
It can also normalise the data for easy consumption by other programs.
|
||
It has four possible values:
|
||
.IP \[bu] 2
|
||
\f[V]--layout=wide[,WIDTH]\f[R]: commodities are shown on a single line,
|
||
optionally elided to WIDTH
|
||
.IP \[bu] 2
|
||
\f[V]--layout=tall\f[R]: each commodity is shown on a separate line
|
||
.IP \[bu] 2
|
||
\f[V]--layout=bare\f[R]: commodity symbols are in their own column,
|
||
amounts are bare numbers
|
||
.IP \[bu] 2
|
||
\f[V]--layout=tidy\f[R]: data is normalised to easily-consumed
|
||
\[dq]tidy\[dq] form, with one row per data value
|
||
.PP
|
||
Here are the \f[V]--layout\f[R] modes supported by each output format;
|
||
note only CSV output supports all of them:
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
l l l l l l.
|
||
T{
|
||
-
|
||
T}@T{
|
||
txt
|
||
T}@T{
|
||
csv
|
||
T}@T{
|
||
html
|
||
T}@T{
|
||
json
|
||
T}@T{
|
||
sql
|
||
T}
|
||
_
|
||
T{
|
||
wide
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
tall
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
bare
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
T{
|
||
tidy
|
||
T}@T{
|
||
T}@T{
|
||
Y
|
||
T}@T{
|
||
T}@T{
|
||
T}@T{
|
||
T}
|
||
.TE
|
||
.PP
|
||
Examples:
|
||
.IP \[bu] 2
|
||
Wide layout.
|
||
With many commodities, reports can be very wide:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide
|
||
Balance changes in 2012-01-01..2014-12-31:
|
||
|
||
|| 2012 2013 2014 Total
|
||
==================++====================================================================================================================================================================================================================
|
||
Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT
|
||
------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||
|| 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP \[bu] 2
|
||
Limited wide layout.
|
||
A width limit reduces the width, but some commodities will be hidden:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32
|
||
Balance changes in 2012-01-01..2014-12-31:
|
||
|
||
|| 2012 2013 2014 Total
|
||
==================++===========================================================================================================================
|
||
Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..
|
||
------------------++---------------------------------------------------------------------------------------------------------------------------
|
||
|| 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP \[bu] 2
|
||
Tall layout.
|
||
Each commodity gets a new line (may be different in each column), and
|
||
account names are repeated:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall
|
||
Balance changes in 2012-01-01..2014-12-31:
|
||
|
||
|| 2012 2013 2014 Total
|
||
==================++==================================================
|
||
Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD
|
||
Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT
|
||
Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD
|
||
Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA
|
||
Assets:US:ETrade || 18.00 VHT 294.00 VHT
|
||
------------------++--------------------------------------------------
|
||
|| 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD
|
||
|| 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT
|
||
|| 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD
|
||
|| 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA
|
||
|| 18.00 VHT 294.00 VHT
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP \[bu] 2
|
||
Bare layout.
|
||
Commodity symbols are kept in one column, each commodity gets its own
|
||
report row, account names are repeated:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare
|
||
Balance changes in 2012-01-01..2014-12-31:
|
||
|
||
|| Commodity 2012 2013 2014 Total
|
||
==================++=============================================
|
||
Assets:US:ETrade || GLD 0 70.00 0 70.00
|
||
Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00
|
||
Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50
|
||
Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00
|
||
Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00
|
||
------------------++---------------------------------------------
|
||
|| GLD 0 70.00 0 70.00
|
||
|| ITOT 10.00 18.00 -11.00 17.00
|
||
|| USD 337.18 -98.12 4881.44 5120.50
|
||
|| VEA 12.00 10.00 14.00 36.00
|
||
|| VHT 106.00 18.00 170.00 294.00
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP \[bu] 2
|
||
Bare layout also affects CSV output, which is useful for producing data
|
||
that is easier to consume, eg for making charts:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare
|
||
\[dq]account\[dq],\[dq]commodity\[dq],\[dq]balance\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]GLD\[dq],\[dq]70.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]ITOT\[dq],\[dq]17.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]USD\[dq],\[dq]5120.50\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]VEA\[dq],\[dq]36.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]VHT\[dq],\[dq]294.00\[dq]
|
||
\[dq]total\[dq],\[dq]GLD\[dq],\[dq]70.00\[dq]
|
||
\[dq]total\[dq],\[dq]ITOT\[dq],\[dq]17.00\[dq]
|
||
\[dq]total\[dq],\[dq]USD\[dq],\[dq]5120.50\[dq]
|
||
\[dq]total\[dq],\[dq]VEA\[dq],\[dq]36.00\[dq]
|
||
\[dq]total\[dq],\[dq]VHT\[dq],\[dq]294.00\[dq]
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP \[bu] 2
|
||
Tidy layout produces normalised \[dq]tidy data\[dq], where every
|
||
variable has its own column and each row represents a single data point.
|
||
See
|
||
https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html
|
||
for more.
|
||
This is the easiest kind of data for other software to consume.
|
||
Here\[aq]s how it looks:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy
|
||
\[dq]account\[dq],\[dq]period\[dq],\[dq]start_date\[dq],\[dq]end_date\[dq],\[dq]commodity\[dq],\[dq]value\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2012\[dq],\[dq]2012-01-01\[dq],\[dq]2012-12-31\[dq],\[dq]GLD\[dq],\[dq]0\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2012\[dq],\[dq]2012-01-01\[dq],\[dq]2012-12-31\[dq],\[dq]ITOT\[dq],\[dq]10.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2012\[dq],\[dq]2012-01-01\[dq],\[dq]2012-12-31\[dq],\[dq]USD\[dq],\[dq]337.18\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2012\[dq],\[dq]2012-01-01\[dq],\[dq]2012-12-31\[dq],\[dq]VEA\[dq],\[dq]12.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2012\[dq],\[dq]2012-01-01\[dq],\[dq]2012-12-31\[dq],\[dq]VHT\[dq],\[dq]106.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2013\[dq],\[dq]2013-01-01\[dq],\[dq]2013-12-31\[dq],\[dq]GLD\[dq],\[dq]70.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2013\[dq],\[dq]2013-01-01\[dq],\[dq]2013-12-31\[dq],\[dq]ITOT\[dq],\[dq]18.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2013\[dq],\[dq]2013-01-01\[dq],\[dq]2013-12-31\[dq],\[dq]USD\[dq],\[dq]-98.12\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2013\[dq],\[dq]2013-01-01\[dq],\[dq]2013-12-31\[dq],\[dq]VEA\[dq],\[dq]10.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2013\[dq],\[dq]2013-01-01\[dq],\[dq]2013-12-31\[dq],\[dq]VHT\[dq],\[dq]18.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2014\[dq],\[dq]2014-01-01\[dq],\[dq]2014-12-31\[dq],\[dq]GLD\[dq],\[dq]0\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2014\[dq],\[dq]2014-01-01\[dq],\[dq]2014-12-31\[dq],\[dq]ITOT\[dq],\[dq]-11.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2014\[dq],\[dq]2014-01-01\[dq],\[dq]2014-12-31\[dq],\[dq]USD\[dq],\[dq]4881.44\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2014\[dq],\[dq]2014-01-01\[dq],\[dq]2014-12-31\[dq],\[dq]VEA\[dq],\[dq]14.00\[dq]
|
||
\[dq]Assets:US:ETrade\[dq],\[dq]2014\[dq],\[dq]2014-01-01\[dq],\[dq]2014-12-31\[dq],\[dq]VHT\[dq],\[dq]170.00\[dq]
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.SS Useful balance reports
|
||
.PP
|
||
Some frequently used \f[V]balance\f[R] options/reports are:
|
||
.IP \[bu] 2
|
||
\f[V]bal -M revenues expenses\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Show revenues/expenses in each month.
|
||
Also available as the \f[V]incomestatement\f[R] command.
|
||
.IP \[bu] 2
|
||
\f[V]bal -M -H assets liabilities\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Show historical asset/liability balances at each month end.
|
||
Also available as the \f[V]balancesheet\f[R] command.
|
||
.IP \[bu] 2
|
||
\f[V]bal -M -H assets liabilities equity\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Show historical asset/liability/equity balances at each month end.
|
||
Also available as the \f[V]balancesheetequity\f[R] command.
|
||
.IP \[bu] 2
|
||
\f[V]bal -M assets not:receivable\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Show changes to liquid assets in each month.
|
||
Also available as the \f[V]cashflow\f[R] command.
|
||
.PP
|
||
Also:
|
||
.IP \[bu] 2
|
||
\f[V]bal -M expenses -2 -SA\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Show monthly expenses summarised to depth 2 and sorted by average
|
||
amount.
|
||
.IP \[bu] 2
|
||
\f[V]bal -M --budget expenses\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Show monthly expenses and budget goals.
|
||
.IP \[bu] 2
|
||
\f[V]bal -M --valuechange investments\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Show monthly change in market value of investment assets.
|
||
.IP \[bu] 2
|
||
\f[V]bal investments --valuechange -D date:lastweek amt:\[aq]>1000\[aq] -STA [--invert]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Show top gainers [or losers] last week
|
||
.SS balancesheet
|
||
.PP
|
||
(bs)
|
||
.PP
|
||
This command displays a balance sheet, showing historical ending
|
||
balances of asset and liability accounts.
|
||
(To see equity as well, use the balancesheetequity command.)
|
||
Amounts are shown with normal positive sign, as in conventional
|
||
financial statements.
|
||
.PP
|
||
This report shows accounts declared with the \f[V]Asset\f[R],
|
||
\f[V]Cash\f[R] or \f[V]Liability\f[R] type (see account types).
|
||
Or if no such accounts are declared, it shows top-level accounts named
|
||
\f[V]asset\f[R] or \f[V]liability\f[R] (case insensitive, plurals
|
||
allowed) and their subaccounts.
|
||
.PP
|
||
Example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balancesheet
|
||
Balance Sheet
|
||
|
||
Assets:
|
||
$-1 assets
|
||
$1 bank:saving
|
||
$-2 cash
|
||
--------------------
|
||
$-1
|
||
|
||
Liabilities:
|
||
$1 liabilities:debts
|
||
--------------------
|
||
$1
|
||
|
||
Total:
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This command is a higher-level variant of the \f[V]balance\f[R] command,
|
||
and supports many of that command\[aq]s features, such as multi-period
|
||
reports.
|
||
It is similar to \f[V]hledger balance -H assets liabilities\f[R], but
|
||
with smarter account detection, and liabilities displayed with their
|
||
sign flipped.
|
||
.PP
|
||
This command also supports the output destination and output format
|
||
options The output formats supported are \f[V]txt\f[R], \f[V]csv\f[R],
|
||
\f[V]html\f[R], and (experimental) \f[V]json\f[R].
|
||
.SS balancesheetequity
|
||
.PP
|
||
(bse)
|
||
.PP
|
||
This command displays a balance sheet, showing historical ending
|
||
balances of asset, liability and equity accounts.
|
||
Amounts are shown with normal positive sign, as in conventional
|
||
financial statements.
|
||
.PP
|
||
This report shows accounts declared with the \f[V]Asset\f[R],
|
||
\f[V]Cash\f[R], \f[V]Liability\f[R] or \f[V]Equity\f[R] type (see
|
||
account types).
|
||
Or if no such accounts are declared, it shows top-level accounts named
|
||
\f[V]asset\f[R], \f[V]liability\f[R] or \f[V]equity\f[R] (case
|
||
insensitive, plurals allowed) and their subaccounts.
|
||
.PP
|
||
Example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balancesheetequity
|
||
Balance Sheet With Equity
|
||
|
||
Assets:
|
||
$-2 assets
|
||
$1 bank:saving
|
||
$-3 cash
|
||
--------------------
|
||
$-2
|
||
|
||
Liabilities:
|
||
$1 liabilities:debts
|
||
--------------------
|
||
$1
|
||
|
||
Equity:
|
||
$1 equity:owner
|
||
--------------------
|
||
$1
|
||
|
||
Total:
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This command is a higher-level variant of the \f[V]balance\f[R] command,
|
||
and supports many of that command\[aq]s features, such as multi-period
|
||
reports.
|
||
It is similar to \f[V]hledger balance -H assets liabilities equity\f[R],
|
||
but with smarter account detection, and liabilities/equity displayed
|
||
with their sign flipped.
|
||
.PP
|
||
This command also supports the output destination and output format
|
||
options The output formats supported are \f[V]txt\f[R], \f[V]csv\f[R],
|
||
\f[V]html\f[R], and (experimental) \f[V]json\f[R].
|
||
.SS cashflow
|
||
.PP
|
||
(cf)
|
||
.PP
|
||
This command displays a cashflow statement, showing the inflows and
|
||
outflows affecting \[dq]cash\[dq] (ie, liquid, easily convertible)
|
||
assets.
|
||
Amounts are shown with normal positive sign, as in conventional
|
||
financial statements.
|
||
.PP
|
||
This report shows accounts declared with the \f[V]Cash\f[R] type (see
|
||
account types).
|
||
Or if no such accounts are declared, it shows accounts
|
||
.IP \[bu] 2
|
||
under a top-level account named \f[V]asset\f[R] (case insensitive,
|
||
plural allowed)
|
||
.IP \[bu] 2
|
||
whose name contains some variation of \f[V]cash\f[R], \f[V]bank\f[R],
|
||
\f[V]checking\f[R] or \f[V]saving\f[R].
|
||
.PP
|
||
More precisely: all accounts matching this case insensitive regular
|
||
expression:
|
||
.PP
|
||
\f[V]\[ha]assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)\f[R]
|
||
.PP
|
||
and their subaccounts.
|
||
.PP
|
||
An example cashflow report:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger cashflow
|
||
Cashflow Statement
|
||
|
||
Cash flows:
|
||
$-1 assets
|
||
$1 bank:saving
|
||
$-2 cash
|
||
--------------------
|
||
$-1
|
||
|
||
Total:
|
||
--------------------
|
||
$-1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This command is a higher-level variant of the \f[V]balance\f[R] command,
|
||
and supports many of that command\[aq]s features, such as multi-period
|
||
reports.
|
||
It is similar to
|
||
\f[V]hledger balance assets not:fixed not:investment not:receivable\f[R],
|
||
but with smarter account detection.
|
||
.PP
|
||
This command also supports the output destination and output format
|
||
options The output formats supported are \f[V]txt\f[R], \f[V]csv\f[R],
|
||
\f[V]html\f[R], and (experimental) \f[V]json\f[R].
|
||
.SS check
|
||
.PP
|
||
Check for various kinds of errors in your data.
|
||
.PP
|
||
hledger provides a number of built-in error checks to help prevent
|
||
problems in your data.
|
||
Some of these are run automatically; or, you can use this
|
||
\f[V]check\f[R] command to run them on demand, with no output and a zero
|
||
exit code if all is well.
|
||
Specify their names (or a prefix) as argument(s).
|
||
.PP
|
||
Some examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
hledger check # basic checks
|
||
hledger check -s # basic + strict checks
|
||
hledger check ordereddates payees # basic + two other checks
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If you are an Emacs user, you can also configure flycheck-hledger to run
|
||
these checks, providing instant feedback as you edit the journal.
|
||
.PP
|
||
Here are the checks currently available:
|
||
.SS Basic checks
|
||
.PP
|
||
These checks are always run automatically, by (almost) all hledger
|
||
commands, including \f[V]check\f[R]:
|
||
.IP \[bu] 2
|
||
\f[B]parseable\f[R] - data files are well-formed and can be successfully
|
||
parsed
|
||
.IP \[bu] 2
|
||
\f[B]balancedwithautoconversion\f[R] - all transactions are balanced,
|
||
inferring missing amounts where necessary, and possibly converting
|
||
commodities using costs or automatically-inferred costs
|
||
.IP \[bu] 2
|
||
\f[B]assertions\f[R] - all balance assertions in the journal are
|
||
passing.
|
||
(This check can be disabled with
|
||
\f[V]-I\f[R]/\f[V]--ignore-assertions\f[R].)
|
||
.SS Strict checks
|
||
.PP
|
||
These additional checks are run when the \f[V]-s\f[R]/\f[V]--strict\f[R]
|
||
(strict mode) flag is used.
|
||
Or, they can be run by giving their names as arguments to
|
||
\f[V]check\f[R]:
|
||
.IP \[bu] 2
|
||
\f[B]accounts\f[R] - all account names used by transactions have been
|
||
declared
|
||
.IP \[bu] 2
|
||
\f[B]commodities\f[R] - all commodity symbols used have been declared
|
||
.IP \[bu] 2
|
||
\f[B]balancednoautoconversion\f[R] - transactions are balanced, possibly
|
||
using explicit costs but not inferred ones
|
||
.SS Other checks
|
||
.PP
|
||
These checks can be run only by giving their names as arguments to
|
||
\f[V]check\f[R].
|
||
They are more specialised and not desirable for everyone, therefore
|
||
optional:
|
||
.IP \[bu] 2
|
||
\f[B]ordereddates\f[R] - transactions are ordered by date within each
|
||
file
|
||
.IP \[bu] 2
|
||
\f[B]payees\f[R] - all payees used by transactions have been declared
|
||
.IP \[bu] 2
|
||
\f[B]recentassertions\f[R] - all accounts with balance assertions have a
|
||
balance assertion no more than 7 days before their latest posting
|
||
.IP \[bu] 2
|
||
\f[B]tags\f[R] - all tags used by transactions have been declared
|
||
.IP \[bu] 2
|
||
\f[B]uniqueleafnames\f[R] - all account leaf names are unique
|
||
.SS Custom checks
|
||
.PP
|
||
A few more checks are are available as separate add-on commands, in
|
||
https://github.com/simonmichael/hledger/tree/master/bin:
|
||
.IP \[bu] 2
|
||
\f[B]hledger-check-tagfiles\f[R] - all tag values containing / (a
|
||
forward slash) exist as file paths
|
||
.IP \[bu] 2
|
||
\f[B]hledger-check-fancyassertions\f[R] - more complex balance
|
||
assertions are passing
|
||
.PP
|
||
You could make similar scripts to perform your own custom checks.
|
||
See: Cookbook -> Scripting.
|
||
.SS More about specific checks
|
||
.PP
|
||
\f[V]hledger check recentassertions\f[R] will complain if any
|
||
balance-asserted account does not have a balance assertion within 7 days
|
||
before its latest posting.
|
||
This aims to prevent the situation where you are regularly updating your
|
||
journal, but forgetting to check your balances against the real world,
|
||
then one day must dig back through months of data to find an error.
|
||
It assumes that adding a balance assertion requires/reminds you to check
|
||
the real-world balance.
|
||
That may not be true if you auto-generate balance assertions from bank
|
||
data; in that case, I recommend to import transactions uncleared, then
|
||
use the manual-review-and-mark-cleared phase as a reminder to check the
|
||
latest assertions against real-world balances.
|
||
.SS close
|
||
.PP
|
||
(equity)
|
||
.PP
|
||
Generate transactions which transfer account balances to and/or from
|
||
another account (typically equity).
|
||
This can be useful for migrating balances to a new journal file, or for
|
||
merging earnings into equity at end of accounting period.
|
||
.PP
|
||
By default, it prints a transaction that zeroes out ALE accounts (asset,
|
||
liability, equity accounts; this requires account types to be
|
||
configured); or if ACCTQUERY is provided, the accounts matched by that.
|
||
.PP
|
||
\f[I](experimental)\f[R]
|
||
.PP
|
||
This command has four main modes, corresponding to the most common use
|
||
cases:
|
||
.IP "1." 3
|
||
With \f[V]--close\f[R] (default), it prints a \[dq]closing balances\[dq]
|
||
transaction that zeroes out ALE (asset, liability, equity) accounts by
|
||
default (this requires account types to be inferred or declared); or,
|
||
the accounts matched by the provided ACCTQUERY arguments.
|
||
.IP "2." 3
|
||
With \f[V]--open\f[R], it prints an opposite \[dq]opening balances\[dq]
|
||
transaction that restores those balances from zero.
|
||
This is similar to Ledger\[aq]s equity command.
|
||
.IP "3." 3
|
||
With \f[V]--migrate\f[R], it prints both the closing and opening
|
||
transactions.
|
||
This is the preferred way to migrate balances to a new file: run
|
||
\f[V]hledger close --migrate\f[R], add the closing transaction at the
|
||
end of the old file, and add the opening transaction at the start of the
|
||
new file.
|
||
The matching closing/opening transactions cancel each other out,
|
||
preserving correct balances during multi-file reporting.
|
||
.IP "4." 3
|
||
With \f[V]--retain\f[R], it prints a \[dq]retain earnings\[dq]
|
||
transaction that transfers RX (revenue and expense) balances to
|
||
\f[V]equity:retained earnings\f[R].
|
||
Businesses traditionally do this at the end of each accounting period;
|
||
it is less necessary with computer-based accounting, but it could still
|
||
be useful if you want to see the accounting equation (A=L+E) satisfied.
|
||
.PP
|
||
In all modes, the defaults can be overridden:
|
||
.IP \[bu] 2
|
||
the transaction descriptions can be changed with
|
||
\f[V]--close-desc=DESC\f[R] and \f[V]--open-desc=DESC\f[R]
|
||
.IP \[bu] 2
|
||
the account to transfer to/from can be changed with
|
||
\f[V]--close-acct=ACCT\f[R] and \f[V]--open-acct=ACCT\f[R]
|
||
.IP \[bu] 2
|
||
the accounts to be closed/opened can be changed with \f[V]ACCTQUERY\f[R]
|
||
(account query arguments).
|
||
.IP \[bu] 2
|
||
the closing/opening dates can be changed with \f[V]-e DATE\f[R] (a
|
||
report end date)
|
||
.PP
|
||
By default just one destination/source posting will be used, with its
|
||
amount left implicit.
|
||
With \f[V]--x/--explicit\f[R], the amount will be shown explicitly, and
|
||
if it involves multiple commodities, a separate posting will be
|
||
generated for each of them (similar to \f[V]print -x\f[R]).
|
||
.PP
|
||
With \f[V]--show-costs\f[R], any amount costs are shown, with separate
|
||
postings for each cost.
|
||
This is currently the best way to view investment lots.
|
||
If you have many currency conversion or investment transactions, it can
|
||
generate very large journal entries.
|
||
.PP
|
||
With \f[V]--interleaved\f[R], each individual transfer is shown with
|
||
source and destination postings next to each other.
|
||
This could be useful for troubleshooting.
|
||
.PP
|
||
The default closing date is yesterday, or the journal\[aq]s end date,
|
||
whichever is later.
|
||
You can change this by specifying a report end date with \f[V]-e\f[R].
|
||
The last day of the report period will be the closing date, eg
|
||
\f[V]-e 2024\f[R] means \[dq]close on 2023-12-31\[dq].
|
||
The opening date is always the day after the closing date.
|
||
.SS close and balance assertions
|
||
.PP
|
||
Balance assertions will be generated, verifying that the accounts have
|
||
been reset to zero (and then restored to their previous balances, if
|
||
there is an opening transaction).
|
||
.PP
|
||
These provide useful error checking, but you can ignore them temporarily
|
||
with \f[V]-I\f[R], or remove them if you prefer.
|
||
.PP
|
||
You probably should avoid filtering transactions by status or realness
|
||
(\f[V]-C\f[R], \f[V]-R\f[R], \f[V]status:\f[R]), or generating postings
|
||
(\f[V]--auto\f[R]), with this command, since the balance assertions
|
||
would depend on these.
|
||
.PP
|
||
Note custom posting dates spanning the file boundary will disrupt the
|
||
balance assertions:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-12-30 a purchase made in december, cleared in january
|
||
expenses:food 5
|
||
assets:bank:checking -5 ; date: 2023-01-02
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
To solve that you can transfer the money to and from a temporary
|
||
account, in effect splitting the multi-day transaction into two
|
||
single-day transactions:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; in 2022.journal:
|
||
2022-12-30 a purchase made in december, cleared in january
|
||
expenses:food 5
|
||
equity:pending -5
|
||
|
||
; in 2023.journal:
|
||
2023-01-02 last year\[aq]s transaction cleared
|
||
equity:pending 5 = 0
|
||
assets:bank:checking -5
|
||
\f[R]
|
||
.fi
|
||
.SS Example: retain earnings
|
||
.PP
|
||
Record 2022\[aq]s revenues/expenses as retained earnings on 2022-12-31,
|
||
appending the generated transaction to the journal:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note 2022\[aq]s income statement will now show only zeroes, because
|
||
revenues and expenses have been moved entirely to equity.
|
||
To see them again, you could exclude the retain transaction:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f 2022.journal is not:desc:\[aq]retain earnings\[aq]
|
||
\f[R]
|
||
.fi
|
||
.SS Example: migrate balances to a new file
|
||
.PP
|
||
Close assets/liabilities/equity on 2022-12-31 and re-open them on
|
||
2023-01-01:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger close --migrate -f 2022.journal -p 2022
|
||
# copy/paste the closing transaction to the end of 2022.journal
|
||
# copy/paste the opening transaction to the start of 2023.journal
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Now 2022\[aq]s balance sheet will show only zeroes, indicating a
|
||
balanced accounting equation.
|
||
(Unless you are using \[at]/\[at]\[at] notation - in that case, try
|
||
adding --infer-equity.)
|
||
To see the end-of-year balances again, you could exclude the closing
|
||
transaction:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f 2022.journal bs not:desc:\[aq]closing balances\[aq]
|
||
\f[R]
|
||
.fi
|
||
.SS Example: excluding closing/opening transactions
|
||
.PP
|
||
When combining many files for multi-year reports, the closing/opening
|
||
transactions cause some noise in transaction-oriented reports like
|
||
\f[V]print\f[R] and \f[V]register\f[R].
|
||
You can exclude them as shown above, but \f[V]not:desc:...\f[R] is not
|
||
ideal as it depends on consistent descriptions; also you will want to
|
||
avoid excluding the very first opening transaction, which could be
|
||
awkward.
|
||
Here is one alternative, using tags:
|
||
.PP
|
||
Add \f[V]clopen:\f[R] tags to all opening/closing balances transactions
|
||
except the first, like this:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; 2021.journal
|
||
2021-06-01 first opening balances
|
||
\&...
|
||
2021-12-31 closing balances ; clopen:2022
|
||
\&...
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; 2022.journal
|
||
2022-01-01 opening balances ; clopen:2022
|
||
\&...
|
||
2022-12-31 closing balances ; clopen:2023
|
||
\&...
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; 2023.journal
|
||
2023-01-01 opening balances ; clopen:2023
|
||
\&...
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Now, assuming a combined journal like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
; all.journal
|
||
include 2021.journal
|
||
include 2022.journal
|
||
include 2023.journal
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The \f[V]clopen:\f[R] tag can exclude all but the first opening
|
||
transaction.
|
||
To show a clean multi-year checking register:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f all.journal areg checking not:tag:clopen
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
And the year values allow more precision.
|
||
To show 2022\[aq]s year-end balance sheet:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger -f all.journal bs -e2023 not:tag:clopen=2023
|
||
\f[R]
|
||
.fi
|
||
.SS codes
|
||
.PP
|
||
List the codes seen in transactions, in the order parsed.
|
||
.PP
|
||
This command prints the value of each transaction\[aq]s code field, in
|
||
the order transactions were parsed.
|
||
The transaction code is an optional value written in parentheses between
|
||
the date and description, often used to store a cheque number, order
|
||
number or similar.
|
||
.PP
|
||
Transactions aren\[aq]t required to have a code, and missing or empty
|
||
codes will not be shown by default.
|
||
With the \f[V]-E\f[R]/\f[V]--empty\f[R] flag, they will be printed as
|
||
blank lines.
|
||
.PP
|
||
You can add a query to select a subset of transactions.
|
||
.PP
|
||
Examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2022/1/1 (123) Supermarket
|
||
Food $5.00
|
||
Checking
|
||
|
||
2022/1/2 (124) Post Office
|
||
Postage $8.32
|
||
Checking
|
||
|
||
2022/1/3 Supermarket
|
||
Food $11.23
|
||
Checking
|
||
|
||
2022/1/4 (126) Post Office
|
||
Postage $3.21
|
||
Checking
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger codes
|
||
123
|
||
124
|
||
126
|
||
\f[R]
|
||
.fi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger codes -E
|
||
123
|
||
124
|
||
|
||
126
|
||
\f[R]
|
||
.fi
|
||
.SS commodities
|
||
.PP
|
||
List all commodity/currency symbols used or declared in the journal.
|
||
.SS demo
|
||
.PP
|
||
Play demos of hledger usage in the terminal, if asciinema is installed.
|
||
.PP
|
||
Run this command with no argument to list the demos.
|
||
To play a demo, write its number or a prefix or substring of its title.
|
||
Tips:
|
||
.PP
|
||
Make your terminal window large enough to see the demo clearly.
|
||
.PP
|
||
Use the -s/--speed SPEED option to set your preferred playback speed, eg
|
||
\f[V]-s4\f[R] to play at 4x original speed or \f[V]-s.5\f[R] to play at
|
||
half speed.
|
||
The default speed is 2x.
|
||
.PP
|
||
Other asciinema options can be added following a double dash, eg
|
||
\f[V]-- -i.1\f[R] to limit pauses or \f[V]-- -h\f[R] to list
|
||
asciinema\[aq]s other options.
|
||
.PP
|
||
During playback, several keys are available: SPACE to pause/unpause, .
|
||
to step forward (while paused), CTRL-c quit.
|
||
.PP
|
||
Examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger demo # list available demos
|
||
$ hledger demo 1 # play the first demo at default speed (2x)
|
||
$ hledger demo install -s4 # play the \[dq]install\[dq] demo at 4x speed
|
||
\f[R]
|
||
.fi
|
||
.SS descriptions
|
||
.PP
|
||
List the unique descriptions that appear in transactions.
|
||
.PP
|
||
This command lists the unique descriptions that appear in transactions,
|
||
in alphabetic order.
|
||
You can add a query to select a subset of transactions.
|
||
.PP
|
||
Example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger descriptions
|
||
Store Name
|
||
Gas Station | Petrol
|
||
Person A
|
||
\f[R]
|
||
.fi
|
||
.SS diff
|
||
.PP
|
||
Compares a particular account\[aq]s transactions in two input files.
|
||
It shows any transactions to this account which are in one file but not
|
||
in the other.
|
||
.PP
|
||
More precisely, for each posting affecting this account in either file,
|
||
it looks for a corresponding posting in the other file which posts the
|
||
same amount to the same account (ignoring date, description, etc.)
|
||
Since postings not transactions are compared, this also works when
|
||
multiple bank transactions have been combined into a single journal
|
||
entry.
|
||
.PP
|
||
This is useful eg if you have downloaded an account\[aq]s transactions
|
||
from your bank (eg as CSV data).
|
||
When hledger and your bank disagree about the account balance, you can
|
||
compare the bank data with your journal to find out the cause.
|
||
.PP
|
||
Examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger diff -f $LEDGER_FILE -f bank.csv assets:bank:giro
|
||
These transactions are in the first file only:
|
||
|
||
2014/01/01 Opening Balances
|
||
assets:bank:giro EUR ...
|
||
...
|
||
equity:opening balances EUR -...
|
||
|
||
These transactions are in the second file only:
|
||
\f[R]
|
||
.fi
|
||
.SS files
|
||
.PP
|
||
List all files included in the journal.
|
||
With a REGEX argument, only file names matching the regular expression
|
||
(case sensitive) are shown.
|
||
.SS help
|
||
.PP
|
||
Show the hledger user manual in the terminal, with \f[V]info\f[R],
|
||
\f[V]man\f[R], or a pager.
|
||
With a TOPIC argument, open it at that topic if possible.
|
||
TOPIC can be any heading in the manual, or a heading prefix, case
|
||
insensitive.
|
||
Eg: \f[V]commands\f[R], \f[V]print\f[R], \f[V]forecast\f[R],
|
||
\f[V]journal\f[R], \f[V]amount\f[R], \f[V]\[dq]auto postings\[dq]\f[R].
|
||
.PP
|
||
This command shows the hledger manual built in to your hledger version.
|
||
It can be useful when offline, or when you prefer the terminal to a web
|
||
browser, or when the appropriate hledger manual or viewing tools are not
|
||
installed on your system.
|
||
.PP
|
||
By default it chooses the best viewer found in $PATH, trying (in this
|
||
order): \f[V]info\f[R], \f[V]man\f[R], \f[V]$PAGER\f[R], \f[V]less\f[R],
|
||
\f[V]more\f[R].
|
||
You can force the use of info, man, or a pager with the \f[V]-i\f[R],
|
||
\f[V]-m\f[R], or \f[V]-p\f[R] flags, If no viewer can be found, or the
|
||
command is run non-interactively, it just prints the manual to stdout.
|
||
.PP
|
||
If using \f[V]info\f[R], note that version 6 or greater is needed for
|
||
TOPIC lookup.
|
||
If you are on mac you will likely have info 4.8, and should consider
|
||
installing a newer version, eg with \f[V]brew install texinfo\f[R]
|
||
(#1770).
|
||
.PP
|
||
Examples
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger help --help # show how the help command works
|
||
$ hledger help # show the hledger manual with info, man or $PAGER
|
||
$ hledger help journal # show the journal topic in the hledger manual
|
||
$ hledger help -m journal # show it with man, even if info is installed
|
||
\f[R]
|
||
.fi
|
||
.SS import
|
||
.PP
|
||
Read new transactions added to each FILE since last run, and add them to
|
||
the journal.
|
||
Or with --dry-run, just print the transactions that would be added.
|
||
Or with --catchup, just mark all of the FILEs\[aq] transactions as
|
||
imported, without actually importing any.
|
||
.PP
|
||
This command may append new transactions to the main journal file (which
|
||
should be in journal format).
|
||
Existing transactions are not changed.
|
||
This is one of the few hledger commands that writes to the journal file
|
||
(see also \f[V]add\f[R]).
|
||
.PP
|
||
Unlike other hledger commands, with \f[V]import\f[R] the journal file is
|
||
an output file, and will be modified, though only by appending (existing
|
||
data will not be changed).
|
||
The input files are specified as arguments, so to import one or more CSV
|
||
files to your main journal, you will run
|
||
\f[V]hledger import bank.csv\f[R] or perhaps
|
||
\f[V]hledger import *.csv\f[R].
|
||
.PP
|
||
Note you can import from any file format, though CSV files are the most
|
||
common import source, and these docs focus on that case.
|
||
.SS Deduplication
|
||
.PP
|
||
As a convenience \f[V]import\f[R] does \f[I]deduplication\f[R] while
|
||
reading transactions.
|
||
This does not mean \[dq]ignore transactions that look the same\[dq], but
|
||
rather \[dq]ignore transactions that have been seen before\[dq].
|
||
This is intended for when you are periodically importing foreign data
|
||
which may contain already-imported transactions.
|
||
So eg, if every day you download bank CSV files containing redundant
|
||
data, you can safely run \f[V]hledger import bank.csv\f[R] and only new
|
||
transactions will be imported.
|
||
(\f[V]import\f[R] is idempotent.)
|
||
.PP
|
||
Since the items being read (CSV records, eg) often do not come with
|
||
unique identifiers, hledger detects new transactions by date, assuming
|
||
that:
|
||
.IP "1." 3
|
||
new items always have the newest dates
|
||
.IP "2." 3
|
||
item dates do not change across reads
|
||
.IP "3." 3
|
||
and items with the same date remain in the same relative order across
|
||
reads.
|
||
.PP
|
||
These are often true of CSV files representing transactions, or true
|
||
enough so that it works pretty well in practice.
|
||
1 is important, but violations of 2 and 3 amongst the old transactions
|
||
won\[aq]t matter (and if you import often, the new transactions will be
|
||
few, so less likely to be the ones affected).
|
||
.PP
|
||
hledger remembers the latest date processed in each input file by saving
|
||
a hidden \[dq].latest\[dq] state file in the same directory.
|
||
Eg when reading \f[V]finance/bank.csv\f[R], it will look for and update
|
||
the \f[V]finance/.latest.bank.csv\f[R] state file.
|
||
The format is simple: one or more lines containing the same ISO-format
|
||
date (YYYY-MM-DD), meaning \[dq]I have processed transactions up to this
|
||
date, and this many of them on that date.\[dq] Normally you won\[aq]t
|
||
see or manipulate these state files yourself.
|
||
But if needed, you can delete them to reset the state (making all
|
||
transactions \[dq]new\[dq]), or you can construct them to \[dq]catch
|
||
up\[dq] to a certain date.
|
||
.PP
|
||
Note deduplication (and updating of state files) can also be done by
|
||
\f[V]print --new\f[R], but this is less often used.
|
||
.SS Import testing
|
||
.PP
|
||
With \f[V]--dry-run\f[R], the transactions that will be imported are
|
||
printed to the terminal, without updating your journal or state files.
|
||
The output is valid journal format, like the print command, so you can
|
||
re-parse it.
|
||
Eg, to see any importable transactions which CSV rules have not
|
||
categorised:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger import --dry bank.csv | hledger -f- -I print unknown
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
or (live updating):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ ls bank.csv* | entr bash -c \[aq]echo ====; hledger import --dry bank.csv | hledger -f- -I print unknown\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note: when importing from multiple files at once, it\[aq]s currently
|
||
possible for some .latest files to be updated successfully, while the
|
||
actual import fails because of a problem in one of the files, leaving
|
||
them out of sync (and causing some transactions to be missed).
|
||
To prevent this, do a --dry-run first and fix any problems before the
|
||
real import.
|
||
.SS Importing balance assignments
|
||
.PP
|
||
Entries added by import will have their posting amounts made explicit
|
||
(like \f[V]hledger print -x\f[R]).
|
||
This means that any balance assignments in imported files must be
|
||
evaluated; but, imported files don\[aq]t get to see the main file\[aq]s
|
||
account balances.
|
||
As a result, importing entries with balance assignments (eg from an
|
||
institution that provides only balances and not posting amounts) will
|
||
probably generate incorrect posting amounts.
|
||
To avoid this problem, use print instead of import:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print IMPORTFILE [--new] >> $LEDGER_FILE
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
(If you think import should leave amounts implicit like print does,
|
||
please test it and send a pull request.)
|
||
.SS Commodity display styles
|
||
.PP
|
||
Imported amounts will be formatted according to the canonical commodity
|
||
styles (declared or inferred) in the main journal file.
|
||
.SS incomestatement
|
||
.PP
|
||
(is)
|
||
.PP
|
||
This command displays an income statement, showing revenues and expenses
|
||
during one or more periods.
|
||
Amounts are shown with normal positive sign, as in conventional
|
||
financial statements.
|
||
.PP
|
||
This report shows accounts declared with the \f[V]Revenue\f[R] or
|
||
\f[V]Expense\f[R] type (see account types).
|
||
Or if no such accounts are declared, it shows top-level accounts named
|
||
\f[V]revenue\f[R] or \f[V]income\f[R] or \f[V]expense\f[R] (case
|
||
insensitive, plurals allowed) and their subaccounts.
|
||
.PP
|
||
Example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger incomestatement
|
||
Income Statement
|
||
|
||
Revenues:
|
||
$-2 income
|
||
$-1 gifts
|
||
$-1 salary
|
||
--------------------
|
||
$-2
|
||
|
||
Expenses:
|
||
$2 expenses
|
||
$1 food
|
||
$1 supplies
|
||
--------------------
|
||
$2
|
||
|
||
Total:
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This command is a higher-level variant of the \f[V]balance\f[R] command,
|
||
and supports many of that command\[aq]s features, such as multi-period
|
||
reports.
|
||
It is similar to
|
||
\f[V]hledger balance \[aq](revenues|income)\[aq] expenses\f[R], but with
|
||
smarter account detection, and revenues/income displayed with their sign
|
||
flipped.
|
||
.PP
|
||
This command also supports the output destination and output format
|
||
options The output formats supported are \f[V]txt\f[R], \f[V]csv\f[R],
|
||
\f[V]html\f[R], and (experimental) \f[V]json\f[R].
|
||
.SS notes
|
||
.PP
|
||
List the unique notes that appear in transactions.
|
||
.PP
|
||
This command lists the unique notes that appear in transactions, in
|
||
alphabetic order.
|
||
You can add a query to select a subset of transactions.
|
||
The note is the part of the transaction description after a | character
|
||
(or if there is no |, the whole description).
|
||
.PP
|
||
Example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger notes
|
||
Petrol
|
||
Snacks
|
||
\f[R]
|
||
.fi
|
||
.SS payees
|
||
.PP
|
||
List the unique payee/payer names that appear in transactions.
|
||
.PP
|
||
This command lists unique payee/payer names which have been declared
|
||
with payee directives (--declared), used in transaction descriptions
|
||
(--used), or both (the default).
|
||
.PP
|
||
The payee/payer is the part of the transaction description before a |
|
||
character (or if there is no |, the whole description).
|
||
.PP
|
||
You can add query arguments to select a subset of transactions.
|
||
This implies --used.
|
||
.PP
|
||
Example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger payees
|
||
Store Name
|
||
Gas Station
|
||
Person A
|
||
\f[R]
|
||
.fi
|
||
.SS prices
|
||
.PP
|
||
Print market price directives from the journal.
|
||
With --infer-market-prices, generate additional market prices from
|
||
costs.
|
||
With --infer-reverse-prices, also generate market prices by inverting
|
||
known prices.
|
||
Prices can be filtered by a query.
|
||
Price amounts are displayed with their full precision.
|
||
.SS print
|
||
.PP
|
||
Show transaction journal entries, sorted by date.
|
||
.PP
|
||
The print command displays full journal entries (transactions) from the
|
||
journal file, sorted by date (or with \f[V]--date2\f[R], by secondary
|
||
date).
|
||
.PP
|
||
Amounts are shown mostly normalised to commodity display style, eg the
|
||
placement of commodity symbols will be consistent.
|
||
All of their decimal places are shown, as in the original journal entry
|
||
(with one alteration: in some cases trailing zeroes are added.)
|
||
.PP
|
||
Amounts are shown right-aligned within each transaction (but not across
|
||
all transactions).
|
||
.PP
|
||
Directives and inter-transaction comments are not shown, currently.
|
||
This means the print command is somewhat lossy, and if you are using it
|
||
to reformat your journal you should take care to also copy over the
|
||
directives and file-level comments.
|
||
.PP
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print
|
||
2008/01/01 income
|
||
assets:bank:checking $1
|
||
income:salary $-1
|
||
|
||
2008/06/01 gift
|
||
assets:bank:checking $1
|
||
income:gifts $-1
|
||
|
||
2008/06/02 save
|
||
assets:bank:saving $1
|
||
assets:bank:checking $-1
|
||
|
||
2008/06/03 * eat & shop
|
||
expenses:food $1
|
||
expenses:supplies $1
|
||
assets:cash $-2
|
||
|
||
2008/12/31 * pay off
|
||
liabilities:debts $1
|
||
assets:bank:checking $-1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
print\[aq]s output is usually a valid hledger journal, and you can
|
||
process it again with a second hledger command.
|
||
This can be useful for certain kinds of search, eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
# Show running total of food expenses paid from cash.
|
||
# -f- reads from stdin. -I/--ignore-assertions is sometimes needed.
|
||
$ hledger print assets:cash | hledger -f- -I reg expenses:food
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
There are some situations where print\[aq]s output can become
|
||
unparseable:
|
||
.IP \[bu] 2
|
||
Valuation affects posting amounts but not balance assertion or balance
|
||
assignment amounts, potentially causing those to fail.
|
||
.IP \[bu] 2
|
||
Auto postings can generate postings with too many missing amounts.
|
||
.IP \[bu] 2
|
||
Account aliases can generate bad account names.
|
||
.PP
|
||
Normally, the journal entry\[aq]s explicit or implicit amount style is
|
||
preserved.
|
||
For example, when an amount is omitted in the journal, it will not
|
||
appear in the output.
|
||
Similarly, when a cost is implied but not written, it will not appear in
|
||
the output.
|
||
You can use the \f[V]-x\f[R]/\f[V]--explicit\f[R] flag to make all
|
||
amounts and costs explicit, which can be useful for troubleshooting or
|
||
for making your journal more readable and robust against data entry
|
||
errors.
|
||
\f[V]-x\f[R] is also implied by using any of
|
||
\f[V]-B\f[R],\f[V]-V\f[R],\f[V]-X\f[R],\f[V]--value\f[R].
|
||
.PP
|
||
Note, \f[V]-x\f[R]/\f[V]--explicit\f[R] will cause postings with a
|
||
multi-commodity amount (these can arise when a multi-commodity
|
||
transaction has an implicit amount) to be split into multiple
|
||
single-commodity postings, keeping the output parseable.
|
||
.PP
|
||
With \f[V]-B\f[R]/\f[V]--cost\f[R], amounts with costs are converted to
|
||
cost using that price.
|
||
This can be used for troubleshooting.
|
||
.PP
|
||
With \f[V]-m DESC\f[R]/\f[V]--match=DESC\f[R], print does a fuzzy search
|
||
for one recent transaction whose description is most similar to DESC.
|
||
DESC should contain at least two characters.
|
||
If there is no similar-enough match, no transaction will be shown and
|
||
the program exit code will be non-zero.
|
||
.PP
|
||
With \f[V]--new\f[R], hledger prints only transactions it has not seen
|
||
on a previous run.
|
||
This uses the same deduplication system as the \f[V]import\f[R] command.
|
||
(See import\[aq]s docs for details.)
|
||
.PP
|
||
This command also supports the output destination and output format
|
||
options The output formats supported are \f[V]txt\f[R], \f[V]csv\f[R],
|
||
and (experimental) \f[V]json\f[R] and \f[V]sql\f[R].
|
||
.PP
|
||
Here\[aq]s an example of print\[aq]s CSV output:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print -Ocsv
|
||
\[dq]txnidx\[dq],\[dq]date\[dq],\[dq]date2\[dq],\[dq]status\[dq],\[dq]code\[dq],\[dq]description\[dq],\[dq]comment\[dq],\[dq]account\[dq],\[dq]amount\[dq],\[dq]commodity\[dq],\[dq]credit\[dq],\[dq]debit\[dq],\[dq]posting-status\[dq],\[dq]posting-comment\[dq]
|
||
\[dq]1\[dq],\[dq]2008/01/01\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]income\[dq],\[dq]\[dq],\[dq]assets:bank:checking\[dq],\[dq]1\[dq],\[dq]$\[dq],\[dq]\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]1\[dq],\[dq]2008/01/01\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]income\[dq],\[dq]\[dq],\[dq]income:salary\[dq],\[dq]-1\[dq],\[dq]$\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]2\[dq],\[dq]2008/06/01\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]gift\[dq],\[dq]\[dq],\[dq]assets:bank:checking\[dq],\[dq]1\[dq],\[dq]$\[dq],\[dq]\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]2\[dq],\[dq]2008/06/01\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]gift\[dq],\[dq]\[dq],\[dq]income:gifts\[dq],\[dq]-1\[dq],\[dq]$\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]3\[dq],\[dq]2008/06/02\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]save\[dq],\[dq]\[dq],\[dq]assets:bank:saving\[dq],\[dq]1\[dq],\[dq]$\[dq],\[dq]\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]3\[dq],\[dq]2008/06/02\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]save\[dq],\[dq]\[dq],\[dq]assets:bank:checking\[dq],\[dq]-1\[dq],\[dq]$\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]4\[dq],\[dq]2008/06/03\[dq],\[dq]\[dq],\[dq]*\[dq],\[dq]\[dq],\[dq]eat & shop\[dq],\[dq]\[dq],\[dq]expenses:food\[dq],\[dq]1\[dq],\[dq]$\[dq],\[dq]\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]4\[dq],\[dq]2008/06/03\[dq],\[dq]\[dq],\[dq]*\[dq],\[dq]\[dq],\[dq]eat & shop\[dq],\[dq]\[dq],\[dq]expenses:supplies\[dq],\[dq]1\[dq],\[dq]$\[dq],\[dq]\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]4\[dq],\[dq]2008/06/03\[dq],\[dq]\[dq],\[dq]*\[dq],\[dq]\[dq],\[dq]eat & shop\[dq],\[dq]\[dq],\[dq]assets:cash\[dq],\[dq]-2\[dq],\[dq]$\[dq],\[dq]2\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]5\[dq],\[dq]2008/12/31\[dq],\[dq]\[dq],\[dq]*\[dq],\[dq]\[dq],\[dq]pay off\[dq],\[dq]\[dq],\[dq]liabilities:debts\[dq],\[dq]1\[dq],\[dq]$\[dq],\[dq]\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\[dq]5\[dq],\[dq]2008/12/31\[dq],\[dq]\[dq],\[dq]*\[dq],\[dq]\[dq],\[dq]pay off\[dq],\[dq]\[dq],\[dq]assets:bank:checking\[dq],\[dq]-1\[dq],\[dq]$\[dq],\[dq]1\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]\[dq]
|
||
\f[R]
|
||
.fi
|
||
.IP \[bu] 2
|
||
There is one CSV record per posting, with the parent transaction\[aq]s
|
||
fields repeated.
|
||
.IP \[bu] 2
|
||
The \[dq]txnidx\[dq] (transaction index) field shows which postings
|
||
belong to the same transaction.
|
||
(This number might change if transactions are reordered within the file,
|
||
files are parsed/included in a different order, etc.)
|
||
.IP \[bu] 2
|
||
The amount is separated into \[dq]commodity\[dq] (the symbol) and
|
||
\[dq]amount\[dq] (numeric quantity) fields.
|
||
.IP \[bu] 2
|
||
The numeric amount is repeated in either the \[dq]credit\[dq] or
|
||
\[dq]debit\[dq] column, for convenience.
|
||
(Those names are not accurate in the accounting sense; it just puts
|
||
negative amounts under credit and zero or greater amounts under debit.)
|
||
.SS register
|
||
.PP
|
||
(reg)
|
||
.PP
|
||
Show postings and their running total.
|
||
.PP
|
||
The register command displays matched postings, across all accounts, in
|
||
date order, with their running total or running historical balance.
|
||
(See also the \f[V]aregister\f[R] command, which shows matched
|
||
transactions in a specific account.)
|
||
.PP
|
||
register normally shows line per posting, but note that multi-commodity
|
||
amounts will occupy multiple lines (one line per commodity).
|
||
.PP
|
||
It is typically used with a query selecting a particular account, to see
|
||
that account\[aq]s activity:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register checking
|
||
2008/01/01 income assets:bank:checking $1 $1
|
||
2008/06/01 gift assets:bank:checking $1 $2
|
||
2008/06/02 save assets:bank:checking $-1 $1
|
||
2008/12/31 pay off assets:bank:checking $-1 0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
With \f[V]--date2\f[R], it shows and sorts by secondary date instead.
|
||
.PP
|
||
For performance reasons, column widths are chosen based on the first
|
||
1000 lines; this means unusually wide values in later lines can cause
|
||
visual discontinuities as column widths are adjusted.
|
||
If you want to ensure perfect alignment, at the cost of more time and
|
||
memory, use the \f[V]--align-all\f[R] flag.
|
||
.PP
|
||
The \f[V]--historical\f[R]/\f[V]-H\f[R] flag adds the balance from any
|
||
undisplayed prior postings to the running total.
|
||
This is useful when you want to see only recent activity, with a
|
||
historically accurate running balance:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register checking -b 2008/6 --historical
|
||
2008/06/01 gift assets:bank:checking $1 $2
|
||
2008/06/02 save assets:bank:checking $-1 $1
|
||
2008/12/31 pay off assets:bank:checking $-1 0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The \f[V]--depth\f[R] option limits the amount of sub-account detail
|
||
displayed.
|
||
.PP
|
||
The \f[V]--average\f[R]/\f[V]-A\f[R] flag shows the running average
|
||
posting amount instead of the running total (so, the final number
|
||
displayed is the average for the whole report period).
|
||
This flag implies \f[V]--empty\f[R] (see below).
|
||
It is affected by \f[V]--historical\f[R].
|
||
It works best when showing just one account and one commodity.
|
||
.PP
|
||
The \f[V]--related\f[R]/\f[V]-r\f[R] flag shows the \f[I]other\f[R]
|
||
postings in the transactions of the postings which would normally be
|
||
shown.
|
||
.PP
|
||
The \f[V]--invert\f[R] flag negates all amounts.
|
||
For example, it can be used on an income account where amounts are
|
||
normally displayed as negative numbers.
|
||
It\[aq]s also useful to show postings on the checking account together
|
||
with the related account:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register --related --invert assets:checking
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
With a reporting interval, register shows summary postings, one per
|
||
interval, aggregating the postings to each account:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register --monthly income
|
||
2008/01 income:salary $-1 $-1
|
||
2008/06 income:gifts $-1 $-2
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Periods with no activity, and summary postings with a zero amount, are
|
||
not shown by default; use the \f[V]--empty\f[R]/\f[V]-E\f[R] flag to see
|
||
them:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register --monthly income -E
|
||
2008/01 income:salary $-1 $-1
|
||
2008/02 0 $-1
|
||
2008/03 0 $-1
|
||
2008/04 0 $-1
|
||
2008/05 0 $-1
|
||
2008/06 income:gifts $-1 $-2
|
||
2008/07 0 $-2
|
||
2008/08 0 $-2
|
||
2008/09 0 $-2
|
||
2008/10 0 $-2
|
||
2008/11 0 $-2
|
||
2008/12 0 $-2
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Often, you\[aq]ll want to see just one line per interval.
|
||
The \f[V]--depth\f[R] option helps with this, causing subaccounts to be
|
||
aggregated:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register --monthly assets --depth 1h
|
||
2008/01 assets $1 $1
|
||
2008/06 assets $-1 0
|
||
2008/12 assets $-1 $-1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note when using report intervals, if you specify start/end dates these
|
||
will be adjusted outward if necessary to contain a whole number of
|
||
intervals.
|
||
This ensures that the first and last intervals are full length and
|
||
comparable to the others in the report.
|
||
.PP
|
||
With \f[V]-m DESC\f[R]/\f[V]--match=DESC\f[R], register does a fuzzy
|
||
search for one recent posting whose description is most similar to DESC.
|
||
DESC should contain at least two characters.
|
||
If there is no similar-enough match, no posting will be shown and the
|
||
program exit code will be non-zero.
|
||
.SS Custom register output
|
||
.PP
|
||
register uses the full terminal width by default, except on windows.
|
||
You can override this by setting the \f[V]COLUMNS\f[R] environment
|
||
variable (not a bash shell variable) or by using the
|
||
\f[V]--width\f[R]/\f[V]-w\f[R] option.
|
||
.PP
|
||
The description and account columns normally share the space equally
|
||
(about half of (width - 40) each).
|
||
You can adjust this by adding a description width as part of
|
||
--width\[aq]s argument, comma-separated: \f[V]--width W,D\f[R] .
|
||
Here\[aq]s a diagram (won\[aq]t display correctly in --help):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
<--------------------------------- width (W) ---------------------------------->
|
||
date (10) description (D) account (W-41-D) amount (12) balance (12)
|
||
DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
and some examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger reg # use terminal width (or 80 on windows)
|
||
$ hledger reg -w 100 # use width 100
|
||
$ COLUMNS=100 hledger reg # set with one-time environment variable
|
||
$ export COLUMNS=100; hledger reg # set till session end (or window resize)
|
||
$ hledger reg -w 100,40 # set overall width 100, description width 40
|
||
$ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This command also supports the output destination and output format
|
||
options The output formats supported are \f[V]txt\f[R], \f[V]csv\f[R],
|
||
and (experimental) \f[V]json\f[R].
|
||
.SS rewrite
|
||
.PP
|
||
Print all transactions, rewriting the postings of matched transactions.
|
||
For now the only rewrite available is adding new postings, like print
|
||
--auto.
|
||
.PP
|
||
This is a start at a generic rewriter of transaction entries.
|
||
It reads the default journal and prints the transactions, like print,
|
||
but adds one or more specified postings to any transactions matching
|
||
QUERY.
|
||
The posting amounts can be fixed, or a multiplier of the existing
|
||
transaction\[aq]s first posting amount.
|
||
.PP
|
||
Examples:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger-rewrite.hs \[ha]income --add-posting \[aq](liabilities:tax) *.33 ; income tax\[aq] --add-posting \[aq](reserve:gifts) $100\[aq]
|
||
$ hledger-rewrite.hs expenses:gifts --add-posting \[aq](reserve:gifts) *-1\[dq]\[aq]
|
||
$ hledger-rewrite.hs -f rewrites.hledger
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
rewrites.hledger may consist of entries like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
= \[ha]income amt:<0 date:2017
|
||
(liabilities:tax) *0.33 ; tax on income
|
||
(reserve:grocery) *0.25 ; reserve 25% for grocery
|
||
(reserve:) *0.25 ; reserve 25% for grocery
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note the single quotes to protect the dollar sign from bash, and the two
|
||
spaces between account and amount.
|
||
.PP
|
||
More:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger rewrite -- [QUERY] --add-posting \[dq]ACCT AMTEXPR\[dq] ...
|
||
$ hledger rewrite -- \[ha]income --add-posting \[aq](liabilities:tax) *.33\[aq]
|
||
$ hledger rewrite -- expenses:gifts --add-posting \[aq](budget:gifts) *-1\[dq]\[aq]
|
||
$ hledger rewrite -- \[ha]income --add-posting \[aq](budget:foreign currency) *0.25 JPY; diversify\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Argument for \f[V]--add-posting\f[R] option is a usual posting of
|
||
transaction with an exception for amount specification.
|
||
More precisely, you can use \f[V]\[aq]*\[aq]\f[R] (star symbol) before
|
||
the amount to indicate that that this is a factor for an amount of
|
||
original matched posting.
|
||
If the amount includes a commodity name, the new posting amount will be
|
||
in the new commodity; otherwise, it will be in the matched posting
|
||
amount\[aq]s commodity.
|
||
.SS Re-write rules in a file
|
||
.PP
|
||
During the run this tool will execute so called \[dq]Automated
|
||
Transactions\[dq] found in any journal it process.
|
||
I.e instead of specifying this operations in command line you can put
|
||
them in a journal file.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ rewrite-rules.journal
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Make contents look like this:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
= \[ha]income
|
||
(liabilities:tax) *.33
|
||
|
||
= expenses:gifts
|
||
budget:gifts *-1
|
||
assets:budget *1
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Note that \f[V]\[aq]=\[aq]\f[R] (equality symbol) that is used instead
|
||
of date in transactions you usually write.
|
||
It indicates the query by which you want to match the posting to add new
|
||
ones.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This is something similar to the commands pipeline:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger rewrite -- -f input.journal \[aq]\[ha]income\[aq] --add-posting \[aq](liabilities:tax) *.33\[aq] \[rs]
|
||
| hledger rewrite -- -f - expenses:gifts --add-posting \[aq]budget:gifts *-1\[aq] \[rs]
|
||
--add-posting \[aq]assets:budget *1\[aq] \[rs]
|
||
> rewritten-tidy-output.journal
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
It is important to understand that relative order of such entries in
|
||
journal is important.
|
||
You can re-use result of previously added postings.
|
||
.SS Diff output format
|
||
.PP
|
||
To use this tool for batch modification of your journal files you may
|
||
find useful output in form of unified diff.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger rewrite -- --diff -f examples/sample.journal \[aq]\[ha]income\[aq] --add-posting \[aq](liabilities:tax) *.33\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Output might look like:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
--- /tmp/examples/sample.journal
|
||
+++ /tmp/examples/sample.journal
|
||
\[at]\[at] -18,3 +18,4 \[at]\[at]
|
||
2008/01/01 income
|
||
- assets:bank:checking $1
|
||
+ assets:bank:checking $1
|
||
income:salary
|
||
+ (liabilities:tax) 0
|
||
\[at]\[at] -22,3 +23,4 \[at]\[at]
|
||
2008/06/01 gift
|
||
- assets:bank:checking $1
|
||
+ assets:bank:checking $1
|
||
income:gifts
|
||
+ (liabilities:tax) 0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If you\[aq]ll pass this through \f[V]patch\f[R] tool you\[aq]ll get
|
||
transactions containing the posting that matches your query be updated.
|
||
Note that multiple files might be update according to list of input
|
||
files specified via \f[V]--file\f[R] options and \f[V]include\f[R]
|
||
directives inside of these files.
|
||
.PP
|
||
Be careful.
|
||
Whole transaction being re-formatted in a style of output from
|
||
\f[V]hledger print\f[R].
|
||
.PP
|
||
See also:
|
||
.PP
|
||
https://github.com/simonmichael/hledger/issues/99
|
||
.SS rewrite vs. print --auto
|
||
.PP
|
||
This command predates print --auto, and currently does much the same
|
||
thing, but with these differences:
|
||
.IP \[bu] 2
|
||
with multiple files, rewrite lets rules in any file affect all other
|
||
files.
|
||
print --auto uses standard directive scoping; rules affect only child
|
||
files.
|
||
.IP \[bu] 2
|
||
rewrite\[aq]s query limits which transactions can be rewritten; all are
|
||
printed.
|
||
print --auto\[aq]s query limits which transactions are printed.
|
||
.IP \[bu] 2
|
||
rewrite applies rules specified on command line or in the journal.
|
||
print --auto applies rules specified in the journal.
|
||
.SS roi
|
||
.PP
|
||
Shows the time-weighted (TWR) and money-weighted (IRR) rate of return on
|
||
your investments.
|
||
.PP
|
||
At a minimum, you need to supply a query (which could be just an account
|
||
name) to select your investment(s) with \f[V]--inv\f[R], and another
|
||
query to identify your profit and loss transactions with
|
||
\f[V]--pnl\f[R].
|
||
.PP
|
||
If you do not record changes in the value of your investment manually,
|
||
or do not require computation of time-weighted return (TWR),
|
||
\f[V]--pnl\f[R] could be an empty query (\f[V]--pnl \[dq]\[dq]\f[R] or
|
||
\f[V]--pnl STR\f[R] where \f[V]STR\f[R] does not match any of your
|
||
accounts).
|
||
.PP
|
||
This command will compute and display the internalized rate of return
|
||
(IRR) and time-weighted rate of return (TWR) for your investments for
|
||
the time period requested.
|
||
Both rates of return are annualized before display, regardless of the
|
||
length of reporting interval.
|
||
.PP
|
||
Price directives will be taken into account if you supply appropriate
|
||
\f[V]--cost\f[R] or \f[V]--value\f[R] flags (see VALUATION).
|
||
.PP
|
||
Note, in some cases this report can fail, for these reasons:
|
||
.IP \[bu] 2
|
||
Error (NotBracketed): No solution for Internal Rate of Return (IRR).
|
||
Possible causes: IRR is huge (>1000000%), balance of investment becomes
|
||
negative at some point in time.
|
||
.IP \[bu] 2
|
||
Error (SearchFailed): Failed to find solution for Internal Rate of
|
||
Return (IRR).
|
||
Either search does not converge to a solution, or converges too slowly.
|
||
.PP
|
||
Examples:
|
||
.IP \[bu] 2
|
||
Using roi to compute total return of investment in stocks:
|
||
https://github.com/simonmichael/hledger/blob/master/examples/investing/roi-unrealised.ledger
|
||
.IP \[bu] 2
|
||
Cookbook > Return on Investment: https://hledger.org/roi.html
|
||
.SS Spaces and special characters in \f[V]--inv\f[R] and \f[V]--pnl\f[R]
|
||
.PP
|
||
Note that \f[V]--inv\f[R] and \f[V]--pnl\f[R]\[aq]s argument is a query,
|
||
and queries could have several space-separated terms (see QUERIES).
|
||
.PP
|
||
To indicate that all search terms form single command-line argument, you
|
||
will need to put them in quotes (see Special characters):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger roi --inv \[aq]term1 term2 term3 ...\[aq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
If any query terms contain spaces themselves, you will need an extra
|
||
level of nested quoting, eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger roi --inv=\[dq]\[aq]Assets:Test 1\[aq]\[dq] --pnl=\[dq]\[aq]Equity:Unrealized Profit and Loss\[aq]\[dq]
|
||
\f[R]
|
||
.fi
|
||
.SS Semantics of \f[V]--inv\f[R] and \f[V]--pnl\f[R]
|
||
.PP
|
||
Query supplied to \f[V]--inv\f[R] has to match all transactions that are
|
||
related to your investment.
|
||
Transactions not matching \f[V]--inv\f[R] will be ignored.
|
||
.PP
|
||
In these transactions, ROI will conside postings that match
|
||
\f[V]--inv\f[R] to be \[dq]investment postings\[dq] and other postings
|
||
(not matching \f[V]--inv\f[R]) will be sorted into two categories:
|
||
\[dq]cash flow\[dq] and \[dq]profit and loss\[dq], as ROI needs to know
|
||
which part of the investment value is your contributions and which is
|
||
due to the return on investment.
|
||
.IP \[bu] 2
|
||
\[dq]Cash flow\[dq] is depositing or withdrawing money, buying or
|
||
selling assets, or otherwise converting between your investment
|
||
commodity and any other commodity.
|
||
Example:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2019-01-01 Investing in Snake Oil
|
||
assets:cash -$100
|
||
investment:snake oil
|
||
|
||
2020-01-01 Selling my Snake Oil
|
||
assets:cash $10
|
||
investment:snake oil = 0
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP \[bu] 2
|
||
\[dq]Profit and loss\[dq] is change in the value of your investment:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2019-06-01 Snake Oil falls in value
|
||
investment:snake oil = $57
|
||
equity:unrealized profit or loss
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.PP
|
||
All non-investment postings are assumed to be \[dq]cash flow\[dq],
|
||
unless they match \f[V]--pnl\f[R] query.
|
||
Changes in value of your investment due to \[dq]profit and loss\[dq]
|
||
postings will be considered as part of your investment return.
|
||
.PP
|
||
Example: if you use \f[V]--inv snake --pnl equity:unrealized\f[R], then
|
||
postings in the example below would be classifed as:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2019-01-01 Snake Oil #1
|
||
assets:cash -$100 ; cash flow posting
|
||
investment:snake oil ; investment posting
|
||
|
||
2019-03-01 Snake Oil #2
|
||
equity:unrealized pnl -$100 ; profit and loss posting
|
||
snake oil ; investment posting
|
||
|
||
2019-07-01 Snake Oil #3
|
||
equity:unrealized pnl ; profit and loss posting
|
||
cash -$100 ; cash flow posting
|
||
snake oil $50 ; investment posting
|
||
\f[R]
|
||
.fi
|
||
.SS IRR and TWR explained
|
||
.PP
|
||
\[dq]ROI\[dq] stands for \[dq]return on investment\[dq].
|
||
Traditionally this was computed as a difference between current value of
|
||
investment and its initial value, expressed in percentage of the initial
|
||
value.
|
||
.PP
|
||
However, this approach is only practical in simple cases, where
|
||
investments receives no in-flows or out-flows of money, and where rate
|
||
of growth is fixed over time.
|
||
For more complex scenarios you need different ways to compute rate of
|
||
return, and this command implements two of them: IRR and TWR.
|
||
.PP
|
||
Internal rate of return, or \[dq]IRR\[dq] (also called
|
||
\[dq]money-weighted rate of return\[dq]) takes into account effects of
|
||
in-flows and out-flows.
|
||
Naively, if you are withdrawing from your investment, your future gains
|
||
would be smaller (in absolute numbers), and will be a smaller percentage
|
||
of your initial investment, and if you are adding to your investment,
|
||
you will receive bigger absolute gains (but probably at the same rate of
|
||
return).
|
||
IRR is a way to compute rate of return for each period between in-flow
|
||
or out-flow of money, and then combine them in a way that gives you a
|
||
compound annual rate of return that investment is expected to generate.
|
||
.PP
|
||
As mentioned before, in-flows and out-flows would be any cash that you
|
||
personally put in or withdraw, and for the \[dq]roi\[dq] command, these
|
||
are the postings that match the query in the\f[V]--inv\f[R] argument and
|
||
NOT match the query in the\f[V]--pnl\f[R] argument.
|
||
.PP
|
||
If you manually record changes in the value of your investment as
|
||
transactions that balance them against \[dq]profit and loss\[dq] (or
|
||
\[dq]unrealized gains\[dq]) account or use price directives, then in
|
||
order for IRR to compute the precise effect of your in-flows and
|
||
out-flows on the rate of return, you will need to record the value of
|
||
your investement on or close to the days when in- or out-flows occur.
|
||
.PP
|
||
In technical terms, IRR uses the same approach as computation of net
|
||
present value, and tries to find a discount rate that makes net present
|
||
value of all the cash flows of your investment to add up to zero.
|
||
This could be hard to wrap your head around, especially if you
|
||
haven\[aq]t done discounted cash flow analysis before.
|
||
Implementation of IRR in hledger should produce results that match the
|
||
\f[V]XIRR\f[R] formula in Excel.
|
||
.PP
|
||
Second way to compute rate of return that \f[V]roi\f[R] command
|
||
implements is called \[dq]time-weighted rate of return\[dq] or
|
||
\[dq]TWR\[dq].
|
||
Like IRR, it will also break the history of your investment into periods
|
||
between in-flows, out-flows and value changes, to compute rate of return
|
||
per each period and then a compound rate of return.
|
||
However, internal workings of TWR are quite different.
|
||
.PP
|
||
TWR represents your investment as an imaginary \[dq]unit fund\[dq] where
|
||
in-flows/ out-flows lead to buying or selling \[dq]units\[dq] of your
|
||
investment and changes in its value change the value of \[dq]investment
|
||
unit\[dq].
|
||
Change in \[dq]unit price\[dq] over the reporting period gives you rate
|
||
of return of your investment.
|
||
.PP
|
||
References:
|
||
.IP \[bu] 2
|
||
Explanation of rate of return
|
||
.IP \[bu] 2
|
||
Explanation of IRR
|
||
.IP \[bu] 2
|
||
Explanation of TWR
|
||
.IP \[bu] 2
|
||
Examples of computing IRR and TWR and discussion of the limitations of
|
||
both metrics
|
||
.SS stats
|
||
.PP
|
||
Show journal and performance statistics.
|
||
.PP
|
||
The stats command displays summary information for the whole journal, or
|
||
a matched part of it.
|
||
With a reporting interval, it shows a report for each report period.
|
||
.PP
|
||
At the end, it shows (in the terminal) the overall run time and number
|
||
of transactions processed per second.
|
||
Note these are approximate and will vary based on machine, current load,
|
||
data size, hledger version, haskell lib versions, GHC version..
|
||
but they may be of interest.
|
||
The \f[V]stats\f[R] command\[aq]s run time is similar to that of a
|
||
single-column balance report.
|
||
.PP
|
||
Example:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger stats -f examples/1000x1000x10.journal
|
||
Main file : /Users/simon/src/hledger/examples/1000x1000x10.journal
|
||
Included files :
|
||
Transactions span : 2000-01-01 to 2002-09-27 (1000 days)
|
||
Last transaction : 2002-09-26 (6995 days ago)
|
||
Transactions : 1000 (1.0 per day)
|
||
Transactions last 30 days: 0 (0.0 per day)
|
||
Transactions last 7 days : 0 (0.0 per day)
|
||
Payees/descriptions : 1000
|
||
Accounts : 1000 (depth 10)
|
||
Commodities : 26 (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)
|
||
Market prices : 1000 (A)
|
||
|
||
Run time : 0.12 s
|
||
Throughput : 8342 txns/s
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
This command supports the -o/--output-file option (but not
|
||
-O/--output-format selection).
|
||
.SS tags
|
||
.PP
|
||
List the tags used in the journal, or their values.
|
||
.PP
|
||
This command lists the tag names used in the journal, whether on
|
||
transactions, postings, or account declarations.
|
||
.PP
|
||
With a TAGREGEX argument, only tag names matching this regular
|
||
expression (case insensitive, infix matched) are shown.
|
||
.PP
|
||
With QUERY arguments, only transactions and accounts matching this query
|
||
are considered.
|
||
If the query involves transaction fields (date:, desc:, amt:, ...), the
|
||
search is restricted to the matched transactions and their accounts.
|
||
.PP
|
||
With the --values flag, the tags\[aq] unique non-empty values are listed
|
||
instead.
|
||
With -E/--empty, blank/empty values are also shown.
|
||
.PP
|
||
With --parsed, tags or values are shown in the order they were parsed,
|
||
with duplicates included.
|
||
(Except, tags from account declarations are always shown first.)
|
||
.PP
|
||
Tip: remember, accounts also acquire tags from their parents, postings
|
||
also acquire tags from their account and transaction, transactions also
|
||
acquire tags from their postings.
|
||
.SS test
|
||
.PP
|
||
Run built-in unit tests.
|
||
.PP
|
||
This command runs the unit tests built in to hledger and hledger-lib,
|
||
printing the results on stdout.
|
||
If any test fails, the exit code will be non-zero.
|
||
.PP
|
||
This is mainly used by hledger developers, but you can also use it to
|
||
sanity-check the installed hledger executable on your platform.
|
||
All tests are expected to pass - if you ever see a failure, please
|
||
report as a bug!
|
||
.PP
|
||
This command also accepts tasty test runner options, written after a --
|
||
(double hyphen).
|
||
Eg to run only the tests in Hledger.Data.Amount, with ANSI colour codes
|
||
disabled:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger test -- -pData.Amount --color=never
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
For help on these, see https://github.com/feuerbach/tasty#options
|
||
(\f[V]-- --help\f[R] currently doesn\[aq]t show them).
|
||
.PP
|
||
.SH PART 5: COMMON TASKS
|
||
.PP
|
||
Here are some quick examples of how to do some basic tasks with hledger.
|
||
.SS Getting help
|
||
.PP
|
||
Here\[aq]s how to list commands and view options and command docs:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger # show available commands
|
||
$ hledger --help # show common options
|
||
$ hledger CMD --help # show CMD\[aq]s options, common options and CMD\[aq]s documentation
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
You can also view your hledger version\[aq]s manual in several formats
|
||
by using the help command.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger help # show the hledger manual with info, man or $PAGER (best available)
|
||
$ hledger help journal # show the journal topic in the hledger manual
|
||
$ hledger help --help # find out more about the help command
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
To view manuals and introductory docs on the web, visit
|
||
https://hledger.org.
|
||
Chat and mail list support and discussion archives can be found at
|
||
https://hledger.org/support.
|
||
.SS Constructing command lines
|
||
.PP
|
||
hledger has a flexible command line interface.
|
||
We strive to keep it simple and ergonomic, but if you run into one of
|
||
the sharp edges described in OPTIONS, here are some tips that might
|
||
help:
|
||
.IP \[bu] 2
|
||
command-specific options must go after the command (it\[aq]s fine to put
|
||
common options there too: \f[V]hledger CMD OPTS ARGS\f[R])
|
||
.IP \[bu] 2
|
||
running add-on executables directly simplifies command line parsing
|
||
(\f[V]hledger-ui OPTS ARGS\f[R])
|
||
.IP \[bu] 2
|
||
enclose \[dq]problematic\[dq] args in single quotes
|
||
.IP \[bu] 2
|
||
if needed, also add a backslash to hide regular expression
|
||
metacharacters from the shell
|
||
.IP \[bu] 2
|
||
to see how a misbehaving command line is being parsed, add
|
||
\f[V]--debug=2\f[R].
|
||
.SS Starting a journal file
|
||
.PP
|
||
hledger looks for your accounting data in a journal file,
|
||
\f[V]$HOME/.hledger.journal\f[R] by default:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger stats
|
||
The hledger journal file \[dq]/Users/simon/.hledger.journal\[dq] was not found.
|
||
Please create it first, eg with \[dq]hledger add\[dq] or a text editor.
|
||
Or, specify an existing journal file with -f or LEDGER_FILE.
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
You can override this by setting the \f[V]LEDGER_FILE\f[R] environment
|
||
variable (see below).
|
||
It\[aq]s a good practice to keep this important file under version
|
||
control, and to start a new file each year.
|
||
So you could do something like this:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ mkdir \[ti]/finance
|
||
$ cd \[ti]/finance
|
||
$ git init
|
||
Initialized empty Git repository in /Users/simon/finance/.git/
|
||
$ touch 2023.journal
|
||
$ echo \[dq]export LEDGER_FILE=$HOME/finance/2023.journal\[dq] >> \[ti]/.profile
|
||
$ source \[ti]/.profile
|
||
$ hledger stats
|
||
Main file : /Users/simon/finance/2023.journal
|
||
Included files :
|
||
Transactions span : to (0 days)
|
||
Last transaction : none
|
||
Transactions : 0 (0.0 per day)
|
||
Transactions last 30 days: 0 (0.0 per day)
|
||
Transactions last 7 days : 0 (0.0 per day)
|
||
Payees/descriptions : 0
|
||
Accounts : 0 (depth 0)
|
||
Commodities : 0 ()
|
||
Market prices : 0 ()
|
||
\f[R]
|
||
.fi
|
||
.SS Setting LEDGER_FILE
|
||
.PP
|
||
How to set \f[V]LEDGER_FILE\f[R] permanently depends on your setup:
|
||
.PP
|
||
On unix and mac, running these commands in the terminal will work for
|
||
many people; adapt as needed:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ echo \[aq]export LEDGER_FILE=\[ti]/finance/2023.journal\[ga] >> \[ti]/.profile
|
||
$ source \[ti]/.profile
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
When correctly configured, in a new terminal window
|
||
\f[V]env | grep LEDGER_FILE\f[R] will show your file, and so will
|
||
\f[V]hledger files\f[R].
|
||
.PP
|
||
On mac, this additional step might be helpful for GUI applications (like
|
||
Emacs started from the dock): add an entry to
|
||
\f[V]\[ti]/.MacOSX/environment.plist\f[R] like
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
{
|
||
\[dq]LEDGER_FILE\[dq] : \[dq]\[ti]/finance/2023.journal\[dq]
|
||
}
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
and then run \f[V]killall Dock\f[R] in a terminal window (or restart the
|
||
machine).
|
||
.PP
|
||
On Windows, see https://www.java.com/en/download/help/path.html, or try
|
||
running these commands in a powershell window (let us know if it
|
||
persists across a reboot, and if you need to be an Administrator):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
> CD
|
||
> MKDIR finance
|
||
> SETX LEDGER_FILE \[dq]C:\[rs]Users\[rs]USERNAME\[rs]finance\[rs]2023.journal\[dq]
|
||
\f[R]
|
||
.fi
|
||
.SS Setting opening balances
|
||
.PP
|
||
Pick a starting date for which you can look up the balances of some
|
||
real-world assets (bank accounts, wallet..)
|
||
and liabilities (credit cards..).
|
||
.PP
|
||
To avoid a lot of data entry, you may want to start with just one or two
|
||
accounts, like your checking account or cash wallet; and pick a recent
|
||
starting date, like today or the start of the week.
|
||
You can always come back later and add more accounts and older
|
||
transactions, eg going back to january 1st.
|
||
.PP
|
||
Add an opening balances transaction to the journal, declaring the
|
||
balances on this date.
|
||
Here are two ways to do it:
|
||
.IP \[bu] 2
|
||
The first way: open the journal in any text editor and save an entry
|
||
like this:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-01 * opening balances
|
||
assets:bank:checking $1000 = $1000
|
||
assets:bank:savings $2000 = $2000
|
||
assets:cash $100 = $100
|
||
liabilities:creditcard $-50 = $-50
|
||
equity:opening/closing balances
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
These are start-of-day balances, ie whatever was in the account at the
|
||
end of the previous day.
|
||
.PP
|
||
The * after the date is an optional status flag.
|
||
Here it means \[dq]cleared & confirmed\[dq].
|
||
.PP
|
||
The currency symbols are optional, but usually a good idea as you\[aq]ll
|
||
be dealing with multiple currencies sooner or later.
|
||
.PP
|
||
The = amounts are optional balance assertions, providing extra error
|
||
checking.
|
||
.RE
|
||
.IP \[bu] 2
|
||
The second way: run \f[V]hledger add\f[R] and follow the prompts to
|
||
record a similar transaction:
|
||
.RS 2
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger add
|
||
Adding transactions to journal file /Users/simon/finance/2023.journal
|
||
Any command line arguments will be used as defaults.
|
||
Use tab key to complete, readline keys to edit, enter to accept defaults.
|
||
An optional (CODE) may follow transaction dates.
|
||
An optional ; COMMENT may follow descriptions or amounts.
|
||
If you make a mistake, enter < at any prompt to go one step backward.
|
||
To end a transaction, enter . when prompted.
|
||
To quit, enter . at a date prompt or press control-d or control-c.
|
||
Date [2023-02-07]: 2023-01-01
|
||
Description: * opening balances
|
||
Account 1: assets:bank:checking
|
||
Amount 1: $1000
|
||
Account 2: assets:bank:savings
|
||
Amount 2 [$-1000]: $2000
|
||
Account 3: assets:cash
|
||
Amount 3 [$-3000]: $100
|
||
Account 4: liabilities:creditcard
|
||
Amount 4 [$-3100]: $-50
|
||
Account 5: equity:opening/closing balances
|
||
Amount 5 [$-3050]:
|
||
Account 6 (or . or enter to finish this transaction): .
|
||
2023-01-01 * opening balances
|
||
assets:bank:checking $1000
|
||
assets:bank:savings $2000
|
||
assets:cash $100
|
||
liabilities:creditcard $-50
|
||
equity:opening/closing balances $-3050
|
||
|
||
Save this transaction to the journal ? [y]:
|
||
Saved.
|
||
Starting the next transaction (. or ctrl-D/ctrl-C to quit)
|
||
Date [2023-01-01]: .
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.PP
|
||
If you\[aq]re using version control, this could be a good time to commit
|
||
the journal.
|
||
Eg:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ git commit -m \[aq]initial balances\[aq] 2023.journal
|
||
\f[R]
|
||
.fi
|
||
.SS Recording transactions
|
||
.PP
|
||
As you spend or receive money, you can record these transactions using
|
||
one of the methods above (text editor, hledger add) or by using the
|
||
hledger-iadd or hledger-web add-ons, or by using the import command to
|
||
convert CSV data downloaded from your bank.
|
||
.PP
|
||
Here are some simple transactions, see the hledger_journal(5) manual and
|
||
hledger.org for more ideas:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023/1/10 * gift received
|
||
assets:cash $20
|
||
income:gifts
|
||
|
||
2023.1.12 * farmers market
|
||
expenses:food $13
|
||
assets:cash
|
||
|
||
2023-01-15 paycheck
|
||
income:salary
|
||
assets:bank:checking $1000
|
||
\f[R]
|
||
.fi
|
||
.SS Reconciling
|
||
.PP
|
||
Periodically you should reconcile - compare your hledger-reported
|
||
balances against external sources of truth, like bank statements or your
|
||
bank\[aq]s website - to be sure that your ledger accurately represents
|
||
the real-world balances (and, that the real-world institutions have not
|
||
made a mistake!).
|
||
This gets easy and fast with (1) practice and (2) frequency.
|
||
If you do it daily, it can take 2-10 minutes.
|
||
If you let it pile up, expect it to take longer as you hunt down errors
|
||
and discrepancies.
|
||
.PP
|
||
A typical workflow:
|
||
.IP "1." 3
|
||
Reconcile cash.
|
||
Count what\[aq]s in your wallet.
|
||
Compare with what hledger reports (\f[V]hledger bal cash\f[R]).
|
||
If they are different, try to remember the missing transaction, or look
|
||
for the error in the already-recorded transactions.
|
||
A register report can be helpful (\f[V]hledger reg cash\f[R]).
|
||
If you can\[aq]t find the error, add an adjustment transaction.
|
||
Eg if you have $105 after the above, and can\[aq]t explain the missing
|
||
$2, it could be:
|
||
.RS 4
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
2023-01-16 * adjust cash
|
||
assets:cash $-2 = $105
|
||
expenses:misc
|
||
\f[R]
|
||
.fi
|
||
.RE
|
||
.IP "2." 3
|
||
Reconcile checking.
|
||
Log in to your bank\[aq]s website.
|
||
Compare today\[aq]s (cleared) balance with hledger\[aq]s cleared balance
|
||
(\f[V]hledger bal checking -C\f[R]).
|
||
If they are different, track down the error or record the missing
|
||
transaction(s) or add an adjustment transaction, similar to the above.
|
||
Unlike the cash case, you can usually compare the transaction history
|
||
and running balance from your bank with the one reported by
|
||
\f[V]hledger reg checking -C\f[R].
|
||
This will be easier if you generally record transaction dates quite
|
||
similar to your bank\[aq]s clearing dates.
|
||
.IP "3." 3
|
||
Repeat for other asset/liability accounts.
|
||
.PP
|
||
Tip: instead of the register command, use hledger-ui to see a
|
||
live-updating register while you edit the journal:
|
||
\f[V]hledger-ui --watch --register checking -C\f[R]
|
||
.PP
|
||
After reconciling, it could be a good time to mark the reconciled
|
||
transactions\[aq] status as \[dq]cleared and confirmed\[dq], if you want
|
||
to track that, by adding the \f[V]*\f[R] marker.
|
||
Eg in the paycheck transaction above, insert \f[V]*\f[R] between
|
||
\f[V]2023-01-15\f[R] and \f[V]paycheck\f[R]
|
||
.PP
|
||
If you\[aq]re using version control, this can be another good time to
|
||
commit:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ git commit -m \[aq]txns\[aq] 2023.journal
|
||
\f[R]
|
||
.fi
|
||
.SS Reporting
|
||
.PP
|
||
Here are some basic reports.
|
||
.PP
|
||
Show all transactions:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger print
|
||
2023-01-01 * opening balances
|
||
assets:bank:checking $1000
|
||
assets:bank:savings $2000
|
||
assets:cash $100
|
||
liabilities:creditcard $-50
|
||
equity:opening/closing balances $-3050
|
||
|
||
2023-01-10 * gift received
|
||
assets:cash $20
|
||
income:gifts
|
||
|
||
2023-01-12 * farmers market
|
||
expenses:food $13
|
||
assets:cash
|
||
|
||
2023-01-15 * paycheck
|
||
income:salary
|
||
assets:bank:checking $1000
|
||
|
||
2023-01-16 * adjust cash
|
||
assets:cash $-2 = $105
|
||
expenses:misc
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show account names, and their hierarchy:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger accounts --tree
|
||
assets
|
||
bank
|
||
checking
|
||
savings
|
||
cash
|
||
equity
|
||
opening/closing balances
|
||
expenses
|
||
food
|
||
misc
|
||
income
|
||
gifts
|
||
salary
|
||
liabilities
|
||
creditcard
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show all account totals:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger balance
|
||
$4105 assets
|
||
$4000 bank
|
||
$2000 checking
|
||
$2000 savings
|
||
$105 cash
|
||
$-3050 equity:opening/closing balances
|
||
$15 expenses
|
||
$13 food
|
||
$2 misc
|
||
$-1020 income
|
||
$-20 gifts
|
||
$-1000 salary
|
||
$-50 liabilities:creditcard
|
||
--------------------
|
||
0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show only asset and liability balances, as a flat list, limited to depth
|
||
2:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger bal assets liabilities -2
|
||
$4000 assets:bank
|
||
$105 assets:cash
|
||
$-50 liabilities:creditcard
|
||
--------------------
|
||
$4055
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show the same thing without negative numbers, formatted as a simple
|
||
balance sheet:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger bs -2
|
||
Balance Sheet 2023-01-16
|
||
|
||
|| 2023-01-16
|
||
========================++============
|
||
Assets ||
|
||
------------------------++------------
|
||
assets:bank || $4000
|
||
assets:cash || $105
|
||
------------------------++------------
|
||
|| $4105
|
||
========================++============
|
||
Liabilities ||
|
||
------------------------++------------
|
||
liabilities:creditcard || $50
|
||
------------------------++------------
|
||
|| $50
|
||
========================++============
|
||
Net: || $4055
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The final total is your \[dq]net worth\[dq] on the end date.
|
||
(Or use \f[V]bse\f[R] for a full balance sheet with equity.)
|
||
.PP
|
||
Show income and expense totals, formatted as an income statement:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
hledger is
|
||
Income Statement 2023-01-01-2023-01-16
|
||
|
||
|| 2023-01-01-2023-01-16
|
||
===============++=======================
|
||
Revenues ||
|
||
---------------++-----------------------
|
||
income:gifts || $20
|
||
income:salary || $1000
|
||
---------------++-----------------------
|
||
|| $1020
|
||
===============++=======================
|
||
Expenses ||
|
||
---------------++-----------------------
|
||
expenses:food || $13
|
||
expenses:misc || $2
|
||
---------------++-----------------------
|
||
|| $15
|
||
===============++=======================
|
||
Net: || $1005
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The final total is your net income during this period.
|
||
.PP
|
||
Show transactions affecting your wallet, with running total:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger register cash
|
||
2023-01-01 opening balances assets:cash $100 $100
|
||
2023-01-10 gift received assets:cash $20 $120
|
||
2023-01-12 farmers market assets:cash $-13 $107
|
||
2023-01-16 adjust cash assets:cash $-2 $105
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Show weekly posting counts as a bar chart:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ hledger activity -W
|
||
2019-12-30 *****
|
||
2023-01-06 ****
|
||
2023-01-13 ****
|
||
\f[R]
|
||
.fi
|
||
.SS Migrating to a new file
|
||
.PP
|
||
At the end of the year, you may want to continue your journal in a new
|
||
file, so that old transactions don\[aq]t slow down or clutter your
|
||
reports, and to help ensure the integrity of your accounting history.
|
||
See the close command.
|
||
.PP
|
||
If using version control, don\[aq]t forget to \f[V]git add\f[R] the new
|
||
file.
|
||
.SH BUGS
|
||
.PP
|
||
We welcome bug reports in the hledger issue tracker (shortcut:
|
||
http://bugs.hledger.org), or on the #hledger chat or hledger mail list
|
||
(https://hledger.org/support).
|
||
.PP
|
||
Some known issues and limitations:
|
||
.PP
|
||
The need to precede add-on command options with \f[V]--\f[R] when
|
||
invoked from hledger is awkward.
|
||
(See Command options, Constructing command lines.)
|
||
.PP
|
||
A UTF-8-aware system locale must be configured to work with non-ascii
|
||
data.
|
||
(See Unicode characters, Troubleshooting.)
|
||
.PP
|
||
On Microsoft Windows, depending whether you are running in a CMD window
|
||
or a Cygwin/MSYS/Mintty window and how you installed hledger, non-ascii
|
||
characters and colours may not be supported, and the tab key may not be
|
||
supported by \f[V]hledger add\f[R].
|
||
(Running in a WSL window should resolve these.)
|
||
.PP
|
||
When processing large data files, hledger uses more memory than Ledger.
|
||
.SS Troubleshooting
|
||
.PP
|
||
Here are some common issues you might encounter when you run hledger,
|
||
and how to resolve them (and remember also you can usually get quick
|
||
Support):
|
||
.PP
|
||
\f[B]PATH issues: I get an error like \[dq]No command \[aq]hledger\[aq]
|
||
found\[dq]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Depending how you installed hledger, the executables may not be in your
|
||
shell\[aq]s PATH.
|
||
Eg on unix systems, stack installs hledger in \f[V]\[ti]/.local/bin\f[R]
|
||
and cabal installs it in \f[V]\[ti]/.cabal/bin\f[R].
|
||
You may need to add one of these directories to your shell\[aq]s PATH,
|
||
and/or open a new terminal window.
|
||
.PP
|
||
\f[B]LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not
|
||
using it\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
.IP \[bu] 2
|
||
\f[V]LEDGER_FILE\f[R] should be a real environment variable, not just a
|
||
shell variable.
|
||
Eg on unix, the command \f[V]env | grep LEDGER_FILE\f[R] should show it.
|
||
You may need to use \f[V]export\f[R] (see
|
||
https://stackoverflow.com/a/7411509).
|
||
.IP \[bu] 2
|
||
You may need to force your shell to see the new configuration.
|
||
A simple way is to close your terminal window and open a new one.
|
||
.PP
|
||
\f[B]LANG issues: I get errors like \[dq]Illegal byte sequence\[dq] or
|
||
\[dq]Invalid or incomplete multibyte or wide character\[dq] or
|
||
\[dq]commitAndReleaseBuffer: invalid argument (invalid
|
||
character)\[dq]\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Programs compiled with GHC (hledger, haskell build tools, etc.)
|
||
need the system locale to be UTF-8-aware, or they will fail when they
|
||
encounter non-ascii characters.
|
||
To fix it, set the LANG environment variable to a locale which supports
|
||
UTF-8 and which is installed on your system.
|
||
.PP
|
||
On unix, \f[V]locale -a\f[R] lists the installed locales.
|
||
Look for one which mentions \f[V]utf8\f[R], \f[V]UTF-8\f[R] or similar.
|
||
Some examples: \f[V]C.UTF-8\f[R], \f[V]en_US.utf-8\f[R],
|
||
\f[V]fr_FR.utf8\f[R].
|
||
If necessary, use your system package manager to install one.
|
||
Then select it by setting the \f[V]LANG\f[R] environment variable.
|
||
Note, exact spelling and capitalisation of the locale name may be
|
||
important: Here\[aq]s one common way to configure this permanently for
|
||
your shell:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
$ echo \[dq]export LANG=en_US.utf8\[dq] >>\[ti]/.profile
|
||
# close and re-open terminal window
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]COMPATIBILITY ISSUES: hledger gives an error with my Ledger
|
||
file\f[R]
|
||
.PD 0
|
||
.P
|
||
.PD
|
||
Not all of Ledger\[aq]s journal file syntax or feature set is supported.
|
||
See hledger and Ledger for full details.
|
||
|
||
|
||
.SH AUTHORS
|
||
Simon Michael <simon@joyful.com> and contributors.
|
||
.br
|
||
See http://hledger.org/CREDITS.html
|
||
|
||
.SH COPYRIGHT
|
||
Copyright 2007-2023 Simon Michael and contributors.
|
||
|
||
.SH LICENSE
|
||
Released under GNU GPL v3 or later.
|
||
|
||
.SH SEE ALSO
|
||
hledger(1), hledger\-ui(1), hledger\-web(1), ledger(1)
|