8994 lines
263 KiB
Groff
8994 lines
263 KiB
Groff
.\"t
|
|
|
|
.TH "HLEDGER" "1" "December 2020" "hledger-1.20.99 " "hledger User Manuals"
|
|
|
|
|
|
|
|
.SH NAME
|
|
.PP
|
|
This is the command-line interface (CLI) for the hledger accounting
|
|
tool.
|
|
Here we also describe hledger\[aq]s concepts and file formats.
|
|
This manual is for hledger 1.20.99.
|
|
.SH SYNOPSIS
|
|
.PP
|
|
\f[C]hledger\f[R]
|
|
.PP
|
|
\f[C]hledger [-f FILE] COMMAND [OPTIONS] [ARGS]\f[R]
|
|
.PP
|
|
\f[C]hledger [-f FILE] ADDONCMD -- [OPTIONS] [ARGS]\f[R]
|
|
.SH DESCRIPTION
|
|
.PP
|
|
hledger is a reliable, 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).
|
|
.PP
|
|
The basic function of the hledger CLI is to read a plain text file
|
|
describing financial transactions (in accounting terms, a general
|
|
journal) and print useful reports on standard output, or export them as
|
|
CSV.
|
|
hledger can also read some other file formats such as CSV files,
|
|
translating them to journal format.
|
|
Additionally, hledger lists other hledger-* executables found in the
|
|
user\[cq]s $PATH and can invoke them as subcommands.
|
|
.PP
|
|
hledger reads data from one or more files in hledger journal, timeclock,
|
|
timedot, or CSV format specified with \f[C]-f\f[R], or
|
|
\f[C]$LEDGER_FILE\f[R], or \f[C]$HOME/.hledger.journal\f[R] (on windows,
|
|
perhaps \f[C]C:/Users/USER/.hledger.journal\f[R]).
|
|
If using \f[C]$LEDGER_FILE\f[R], note this must be a real environment
|
|
variable, not a shell variable.
|
|
You can specify standard input with \f[C]-f-\f[R].
|
|
.PP
|
|
Transactions are dated movements of money between two (or more) named
|
|
accounts, and are recorded with journal entries like this:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2015/10/16 bought food
|
|
expenses:food $10
|
|
assets:cash
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
For more about this format, see hledger_journal(5).
|
|
.PP
|
|
Most users use a text editor to edit the journal, usually with an editor
|
|
mode such as ledger-mode for added convenience.
|
|
hledger\[cq]s interactive add command is another way to record new
|
|
transactions.
|
|
hledger never changes existing transactions.
|
|
.PP
|
|
To get started, you can either save some entries like the above in
|
|
\f[C]\[ti]/.hledger.journal\f[R], or run \f[C]hledger add\f[R] and
|
|
follow the prompts.
|
|
Then try some commands like \f[C]hledger print\f[R] or
|
|
\f[C]hledger balance\f[R].
|
|
Run \f[C]hledger\f[R] with no arguments for a list of commands.
|
|
.SH OPTIONS
|
|
.SS General options
|
|
.PP
|
|
To see general usage help, including general options which are supported
|
|
by most hledger commands, run \f[C]hledger -h\f[R].
|
|
.PP
|
|
General help options:
|
|
.TP
|
|
\f[B]\f[CB]-h --help\f[B]\f[R]
|
|
show general or COMMAND help
|
|
.TP
|
|
\f[B]\f[CB]--man\f[B]\f[R]
|
|
show general or COMMAND user manual with man
|
|
.TP
|
|
\f[B]\f[CB]--info\f[B]\f[R]
|
|
show general or COMMAND user manual with info
|
|
.TP
|
|
\f[B]\f[CB]--version\f[B]\f[R]
|
|
show general or ADDONCMD version
|
|
.TP
|
|
\f[B]\f[CB]--debug[=N]\f[B]\f[R]
|
|
show debug output (levels 1-9, default: 1)
|
|
.PP
|
|
General input options:
|
|
.TP
|
|
\f[B]\f[CB]-f FILE --file=FILE\f[B]\f[R]
|
|
use a different input file.
|
|
For stdin, use - (default: \f[C]$LEDGER_FILE\f[R] or
|
|
\f[C]$HOME/.hledger.journal\f[R])
|
|
.TP
|
|
\f[B]\f[CB]--rules-file=RULESFILE\f[B]\f[R]
|
|
Conversion rules file to use when reading CSV (default: FILE.rules)
|
|
.TP
|
|
\f[B]\f[CB]--separator=CHAR\f[B]\f[R]
|
|
Field separator to expect when reading CSV (default: \[aq],\[aq])
|
|
.TP
|
|
\f[B]\f[CB]--alias=OLD=NEW\f[B]\f[R]
|
|
rename accounts named OLD to NEW
|
|
.TP
|
|
\f[B]\f[CB]--anon\f[B]\f[R]
|
|
anonymize accounts and payees
|
|
.TP
|
|
\f[B]\f[CB]--pivot FIELDNAME\f[B]\f[R]
|
|
use some other field or tag for the account name
|
|
.TP
|
|
\f[B]\f[CB]-I --ignore-assertions\f[B]\f[R]
|
|
disable balance assertion checks (note: does not disable balance
|
|
assignments)
|
|
.TP
|
|
\f[B]\f[CB]-s --strict\f[B]\f[R]
|
|
do extra error checking (check that all posted accounts are declared)
|
|
.PP
|
|
General reporting options:
|
|
.TP
|
|
\f[B]\f[CB]-b --begin=DATE\f[B]\f[R]
|
|
include postings/txns on or after this date
|
|
.TP
|
|
\f[B]\f[CB]-e --end=DATE\f[B]\f[R]
|
|
include postings/txns before this date
|
|
.TP
|
|
\f[B]\f[CB]-D --daily\f[B]\f[R]
|
|
multiperiod/multicolumn report by day
|
|
.TP
|
|
\f[B]\f[CB]-W --weekly\f[B]\f[R]
|
|
multiperiod/multicolumn report by week
|
|
.TP
|
|
\f[B]\f[CB]-M --monthly\f[B]\f[R]
|
|
multiperiod/multicolumn report by month
|
|
.TP
|
|
\f[B]\f[CB]-Q --quarterly\f[B]\f[R]
|
|
multiperiod/multicolumn report by quarter
|
|
.TP
|
|
\f[B]\f[CB]-Y --yearly\f[B]\f[R]
|
|
multiperiod/multicolumn report by year
|
|
.TP
|
|
\f[B]\f[CB]-p --period=PERIODEXP\f[B]\f[R]
|
|
set start date, end date, and/or reporting interval all at once using
|
|
period expressions syntax
|
|
.TP
|
|
\f[B]\f[CB]--date2\f[B]\f[R]
|
|
match the secondary date instead (see command help for other effects)
|
|
.TP
|
|
\f[B]\f[CB]-U --unmarked\f[B]\f[R]
|
|
include only unmarked postings/txns (can combine with -P or -C)
|
|
.TP
|
|
\f[B]\f[CB]-P --pending\f[B]\f[R]
|
|
include only pending postings/txns
|
|
.TP
|
|
\f[B]\f[CB]-C --cleared\f[B]\f[R]
|
|
include only cleared postings/txns
|
|
.TP
|
|
\f[B]\f[CB]-R --real\f[B]\f[R]
|
|
include only non-virtual postings
|
|
.TP
|
|
\f[B]\f[CB]-NUM --depth=NUM\f[B]\f[R]
|
|
hide/aggregate accounts or postings more than NUM levels deep
|
|
.TP
|
|
\f[B]\f[CB]-E --empty\f[B]\f[R]
|
|
show items with zero amount, normally hidden (and vice-versa in
|
|
hledger-ui/hledger-web)
|
|
.TP
|
|
\f[B]\f[CB]-B --cost\f[B]\f[R]
|
|
convert amounts to their cost/selling amount at transaction time
|
|
.TP
|
|
\f[B]\f[CB]-V --market\f[B]\f[R]
|
|
convert amounts to their market value in default valuation commodities
|
|
.TP
|
|
\f[B]\f[CB]-X --exchange=COMM\f[B]\f[R]
|
|
convert amounts to their market value in commodity COMM
|
|
.TP
|
|
\f[B]\f[CB]--value\f[B]\f[R]
|
|
convert amounts to cost or market value, more flexibly than -B/-V/-X
|
|
.TP
|
|
\f[B]\f[CB]--infer-value\f[B]\f[R]
|
|
with -V/-X/--value, also infer market prices from transactions
|
|
.TP
|
|
\f[B]\f[CB]--auto\f[B]\f[R]
|
|
apply automated posting rules to modify transactions.
|
|
.TP
|
|
\f[B]\f[CB]--forecast\f[B]\f[R]
|
|
generate future transactions from periodic transaction rules, for the
|
|
next 6 months or till report end date.
|
|
In hledger-ui, also make ordinary future transactions visible.
|
|
.TP
|
|
\f[B]\f[CB]--color=WHEN (or --colour=WHEN)\f[B]\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.
|
|
.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.
|
|
.SS Command options
|
|
.PP
|
|
To see options for a particular command, including command-specific
|
|
options, run: \f[C]hledger COMMAND -h\f[R].
|
|
.PP
|
|
Command-specific options must be written after the command name, eg:
|
|
\f[C]hledger print -x\f[R].
|
|
.PP
|
|
Additionally, if the command is an add-on, you may need to put its
|
|
options after a double-hyphen, eg: \f[C]hledger ui -- --watch\f[R].
|
|
Or, you can run the add-on executable directly:
|
|
\f[C]hledger-ui --watch\f[R].
|
|
.SS Command arguments
|
|
.PP
|
|
Most hledger commands accept arguments after the command name, which are
|
|
often a query, filtering the data in some way.
|
|
.PP
|
|
You can save a set of command line options/arguments in a file, and then
|
|
reuse them by writing \f[C]\[at]FILENAME\f[R] as a command line
|
|
argument.
|
|
Eg: \f[C]hledger bal \[at]foo.args\f[R].
|
|
(To prevent this, eg if you have an argument that begins with a literal
|
|
\f[C]\[at]\f[R], precede it with \f[C]--\f[R], eg:
|
|
\f[C]hledger bal -- \[at]ARG\f[R]).
|
|
.PP
|
|
Inside the argument file, each line should contain just one option or
|
|
argument.
|
|
Avoid the use of spaces, except inside quotes (or you\[aq]ll see a
|
|
confusing error).
|
|
Between a flag and its argument, use = (or nothing).
|
|
Bad:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
assets depth:2
|
|
-X USD
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Good:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
assets
|
|
depth:2
|
|
-X=USD
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
For special characters (see below), use one less level of quoting than
|
|
you would at the command prompt.
|
|
Bad:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
-X\[dq]$\[dq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Good:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
-X$
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
See also: Save frequently used options.
|
|
.SS Special characters
|
|
.SS Single escaping (shell metacharacters)
|
|
.PP
|
|
In shell command lines, characters significant to your shell - such as
|
|
spaces, \f[C]<\f[R], \f[C]>\f[R], \f[C](\f[R], \f[C])\f[R], \f[C]|\f[R],
|
|
\f[C]$\f[R] and \f[C]\[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
|
|
.SS Double escaping (regular expression metacharacters)
|
|
.PP
|
|
Characters significant in regular expressions (described below) - such
|
|
as \f[C].\f[R], \f[C]\[ha]\f[R], \f[C]$\f[R], \f[C][\f[R], \f[C]]\f[R],
|
|
\f[C](\f[R], \f[C])\f[R], \f[C]|\f[R], and \f[C]\[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[C]$\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[C]$\f[R] sign while using the bash shell and
|
|
running an add-on command (\f[C]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[C]$\f[R]
|
|
T}
|
|
T{
|
|
escaped:
|
|
T}@T{
|
|
\f[C]\[rs]$\f[R]
|
|
T}
|
|
T{
|
|
double-escaped:
|
|
T}@T{
|
|
\f[C]\[rs]\[rs]$\f[R]
|
|
T}
|
|
T{
|
|
triple-escaped:
|
|
T}@T{
|
|
\f[C]\[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[C]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[C]REGEX\f[R], \f[C]desc:REGEX\f[R], \f[C]cur:REGEX\f[R],
|
|
\f[C]tag:...=REGEX\f[R]
|
|
.IP \[bu] 2
|
|
CSV rules conditional blocks: \f[C]if REGEX ...\f[R]
|
|
.IP \[bu] 2
|
|
account alias directives and options:
|
|
\f[C]alias /REGEX/ = REPLACEMENT\f[R],
|
|
\f[C]--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[C]\[rs]b\f[R],
|
|
\f[C]\[rs]B\f[R], \f[C]\[rs]<\f[R], \f[C]\[rs]>\f[R])
|
|
.IP "5." 3
|
|
they do not support backreferences; if you write \f[C]\[rs]1\f[R], it
|
|
will match the digit \f[C]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[C](?s)\f[R]), character classes
|
|
(\f[C]\[rs]w\f[R], \f[C]\[rs]d\f[R]), or anything else not mentioned
|
|
above.
|
|
.PP
|
|
Some things to note:
|
|
.IP \[bu] 2
|
|
In the \f[C]alias\f[R] directive and \f[C]--alias\f[R] option, regular
|
|
expressions must be enclosed in forward slashes (\f[C]/REGEX/\f[R]).
|
|
Elsewhere in hledger, these are not required.
|
|
.IP \[bu] 2
|
|
In queries, to match a regular expression metacharacter like \f[C]$\f[R]
|
|
as a literal character, prepend a backslash.
|
|
Eg to search for amounts with the dollar sign in hledger-web, write
|
|
\f[C]cur:\[rs]$\f[R].
|
|
.IP \[bu] 2
|
|
On the command line, some metacharacters like \f[C]$\f[R] have a special
|
|
meaning to the shell and so must be escaped at least once more.
|
|
See Special characters.
|
|
.SH ENVIRONMENT
|
|
.PP
|
|
\f[B]LEDGER_FILE\f[R] The journal file path when not specified with
|
|
\f[C]-f\f[R].
|
|
Default: \f[C]\[ti]/.hledger.journal\f[R] (on windows, perhaps
|
|
\f[C]C:/Users/USER/.hledger.journal\f[R]).
|
|
.PP
|
|
A typical value is \f[C]\[ti]/DIR/YYYY.journal\f[R], where DIR is a
|
|
version-controlled finance directory and YYYY is the current year.
|
|
Or \f[C]\[ti]/DIR/current.journal\f[R], where current.journal is a
|
|
symbolic link to YYYY.journal.
|
|
.PP
|
|
On Mac computers, you can set this and other environment variables in a
|
|
more thorough way that also affects applications started from the GUI
|
|
(say, an Emacs dock icon).
|
|
Eg on MacOS Catalina I have a \f[C]\[ti]/.MacOSX/environment.plist\f[R]
|
|
file containing
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{
|
|
\[dq]LEDGER_FILE\[dq] : \[dq]\[ti]/finance/current.journal\[dq]
|
|
}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
To see the effect you may need to \f[C]killall Dock\f[R], or reboot.
|
|
.PP
|
|
\f[B]COLUMNS\f[R] The screen width used by the register command.
|
|
Default: the full terminal width.
|
|
.PP
|
|
\f[B]NO_COLOR\f[R] If this variable exists with any value, hledger will
|
|
not use ANSI color codes in terminal output.
|
|
This overrides the --color/--colour option.
|
|
.SH DATA FILES
|
|
.PP
|
|
hledger reads transactions from one or more data files.
|
|
The default data file is \f[C]$HOME/.hledger.journal\f[R] (or on
|
|
Windows, something like \f[C]C:/Users/USER/.hledger.journal\f[R]).
|
|
.PP
|
|
You can override this with the \f[C]$LEDGER_FILE\f[R] environment
|
|
variable:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ setenv LEDGER_FILE \[ti]/finance/2016.journal
|
|
$ hledger stats
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
or with one or more \f[C]-f/--file\f[R] options:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger -f /some/file -f another_file stats
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
The file name \f[C]-\f[R] means standard input:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ cat some.journal | hledger -f-
|
|
\f[R]
|
|
.fi
|
|
.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[C]journal\f[R]
|
|
T}@T{
|
|
hledger journal files and some Ledger journals, for transactions
|
|
T}@T{
|
|
\f[C].journal\f[R] \f[C].j\f[R] \f[C].hledger\f[R] \f[C].ledger\f[R]
|
|
T}
|
|
T{
|
|
\f[C]timeclock\f[R]
|
|
T}@T{
|
|
timeclock files, for precise time logging
|
|
T}@T{
|
|
\f[C].timeclock\f[R]
|
|
T}
|
|
T{
|
|
\f[C]timedot\f[R]
|
|
T}@T{
|
|
timedot files, for approximate time logging
|
|
T}@T{
|
|
\f[C].timedot\f[R]
|
|
T}
|
|
T{
|
|
\f[C]csv\f[R]
|
|
T}@T{
|
|
comma/semicolon/tab/other-separated values, for data import
|
|
T}@T{
|
|
\f[C].csv\f[R] \f[C].ssv\f[R] \f[C].tsv\f[R]
|
|
T}
|
|
.TE
|
|
.PP
|
|
These formats are described in their own sections, 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[C]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:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger -f csv:/some/csv-file.dat stats
|
|
$ echo \[aq]i 2009/13/1 08:00:00\[aq] | hledger print -ftimeclock:-
|
|
\f[R]
|
|
.fi
|
|
.SS Multiple files
|
|
.PP
|
|
You can specify multiple \f[C]-f\f[R] options, to read multiple files as
|
|
one big journal.
|
|
There are some limitations with this:
|
|
.IP \[bu] 2
|
|
most directives do not affect sibling files
|
|
.IP \[bu] 2
|
|
balance assertions will not see any account balances from previous files
|
|
.PP
|
|
If you need either of those things, you can
|
|
.IP \[bu] 2
|
|
use a single parent file which includes the others
|
|
.IP \[bu] 2
|
|
or concatenate the files into one before reading, eg:
|
|
\f[C]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[C]-s\f[R]/\f[C]--strict\f[R] flag, additional checks are
|
|
performed:
|
|
.IP \[bu] 2
|
|
Are all accounts posted to, declared with an \f[C]account\f[R] directive
|
|
?
|
|
(Account error checking)
|
|
.IP \[bu] 2
|
|
Are all commodities declared with a \f[C]commodity\f[R] directive ?
|
|
(Commodity error checking)
|
|
.PP
|
|
See also: https://hledger.org/checking-for-errors.html
|
|
.PP
|
|
\f[I]experimental.\f[R]
|
|
.SH TIME PERIODS
|
|
.SS Smart dates
|
|
.PP
|
|
hledger\[aq]s user interfaces accept a flexible \[dq]smart date\[dq]
|
|
syntax.
|
|
Smart dates allow some english words, can be relative to today\[aq]s
|
|
date, and can have less-significant date parts omitted (defaulting to
|
|
1).
|
|
.PP
|
|
Examples:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(24.2n) lw(45.8n).
|
|
T{
|
|
\f[C]2004/10/1\f[R], \f[C]2004-01-01\f[R], \f[C]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[C]2004\f[R]
|
|
T}@T{
|
|
start of year
|
|
T}
|
|
T{
|
|
\f[C]2004/10\f[R]
|
|
T}@T{
|
|
start of month
|
|
T}
|
|
T{
|
|
\f[C]10/1\f[R]
|
|
T}@T{
|
|
month and day in current year
|
|
T}
|
|
T{
|
|
\f[C]21\f[R]
|
|
T}@T{
|
|
day in current month
|
|
T}
|
|
T{
|
|
\f[C]october, oct\f[R]
|
|
T}@T{
|
|
start of month in current year
|
|
T}
|
|
T{
|
|
\f[C]yesterday, today, tomorrow\f[R]
|
|
T}@T{
|
|
-1, 0, 1 days from today
|
|
T}
|
|
T{
|
|
\f[C]last/this/next day/week/month/quarter/year\f[R]
|
|
T}@T{
|
|
-1, 0, 1 periods from the current period
|
|
T}
|
|
T{
|
|
\f[C]20181201\f[R]
|
|
T}@T{
|
|
8 digit YYYYMMDD with valid year month and day
|
|
T}
|
|
T{
|
|
\f[C]201812\f[R]
|
|
T}@T{
|
|
6 digit YYYYMM with valid year and month
|
|
T}
|
|
.TE
|
|
.PP
|
|
Counterexamples - malformed digit sequences might give surprising
|
|
results:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(11.4n) lw(58.6n).
|
|
T{
|
|
\f[C]201813\f[R]
|
|
T}@T{
|
|
6 digits with an invalid month is parsed as start of 6-digit year
|
|
T}
|
|
T{
|
|
\f[C]20181301\f[R]
|
|
T}@T{
|
|
8 digits with an invalid month is parsed as start of 8-digit year
|
|
T}
|
|
T{
|
|
\f[C]20181232\f[R]
|
|
T}@T{
|
|
8 digits with an invalid day gives an error
|
|
T}
|
|
T{
|
|
\f[C]201801012\f[R]
|
|
T}@T{
|
|
9+ digits beginning with a valid YYYYMMDD gives an error
|
|
T}
|
|
.TE
|
|
.SS Report start & end date
|
|
.PP
|
|
By default, most hledger reports will show the full span of time
|
|
represented by the journal data.
|
|
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[C]-b/--begin\f[R],
|
|
\f[C]-e/--end\f[R], \f[C]-p/--period\f[R] or a \f[C]date:\f[R] query
|
|
(described below).
|
|
All of these accept the smart date syntax.
|
|
.PP
|
|
Some notes:
|
|
.IP \[bu] 2
|
|
As in Ledger, end dates are exclusive, so you need to write the date
|
|
\f[I]after\f[R] the last day you want to include.
|
|
.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[C]date:\f[R] queries.
|
|
That is, \f[C]date:2019-01 date:2019 -p\[aq]2000 to 2030\[aq]\f[R]
|
|
yields January 2019, the smallest common time span.
|
|
.PP
|
|
Examples:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(12.4n) lw(57.6n).
|
|
T{
|
|
\f[C]-b 2016/3/17\f[R]
|
|
T}@T{
|
|
begin on St.\ Patrick\[cq]s day 2016
|
|
T}
|
|
T{
|
|
\f[C]-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[C]-b thismonth\f[R]
|
|
T}@T{
|
|
all transactions on or after the 1st of the current month
|
|
T}
|
|
T{
|
|
\f[C]-p thismonth\f[R]
|
|
T}@T{
|
|
all transactions in the current month
|
|
T}
|
|
T{
|
|
\f[C]date:2016/3/17..\f[R]
|
|
T}@T{
|
|
the above written as queries instead (\f[C]..\f[R] can also be replaced
|
|
with \f[C]-\f[R])
|
|
T}
|
|
T{
|
|
\f[C]date:..12/1\f[R]
|
|
T}@T{
|
|
T}
|
|
T{
|
|
\f[C]date:thismonth..\f[R]
|
|
T}@T{
|
|
T}
|
|
T{
|
|
\f[C]date:thismonth\f[R]
|
|
T}@T{
|
|
T}
|
|
.TE
|
|
.SS Report intervals
|
|
.PP
|
|
A report interval can be specified so that commands like register,
|
|
balance and activity will divide their reports into multiple subperiods.
|
|
The basic intervals can be selected with one of \f[C]-D/--daily\f[R],
|
|
\f[C]-W/--weekly\f[R], \f[C]-M/--monthly\f[R], \f[C]-Q/--quarterly\f[R],
|
|
or \f[C]-Y/--yearly\f[R].
|
|
More complex intervals may be specified with a period expression.
|
|
Report intervals can not be specified with a query.
|
|
.SS Period expressions
|
|
.PP
|
|
The \f[C]-p/--period\f[R] option accepts period expressions, a shorthand
|
|
way of expressing a start date, end date, and/or report interval all at
|
|
once.
|
|
.PP
|
|
Here\[aq]s a basic period expression specifying the first quarter of
|
|
2009.
|
|
Note, hledger always treats start dates as inclusive and end dates as
|
|
exclusive:
|
|
.PP
|
|
\f[C]-p \[dq]from 2009/1/1 to 2009/4/1\[dq]\f[R]
|
|
.PP
|
|
Keywords like \[dq]from\[dq] and \[dq]to\[dq] are optional, and so are
|
|
the spaces, as long as you don\[aq]t run two dates together.
|
|
\[dq]to\[dq] can also be written as \[dq]..\[dq] or \[dq]-\[dq].
|
|
These are equivalent to the above:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l.
|
|
T{
|
|
\f[C]-p \[dq]2009/1/1 2009/4/1\[dq]\f[R]
|
|
T}
|
|
T{
|
|
\f[C]-p2009/1/1to2009/4/1\f[R]
|
|
T}
|
|
T{
|
|
\f[C]-p2009/1/1..2009/4/1\f[R]
|
|
T}
|
|
.TE
|
|
.PP
|
|
Dates are smart dates, so if the current year is 2009, the above can
|
|
also be written as:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l.
|
|
T{
|
|
\f[C]-p \[dq]1/1 4/1\[dq]\f[R]
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]january-apr\[dq]\f[R]
|
|
T}
|
|
T{
|
|
\f[C]-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 in your journal:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l l.
|
|
T{
|
|
\f[C]-p \[dq]from 2009/1/1\[dq]\f[R]
|
|
T}@T{
|
|
everything after january 1, 2009
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]from 2009/1\[dq]\f[R]
|
|
T}@T{
|
|
the same
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]from 2009\[dq]\f[R]
|
|
T}@T{
|
|
the same
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]to 2009\[dq]\f[R]
|
|
T}@T{
|
|
everything before january 1, 2009
|
|
T}
|
|
.TE
|
|
.PP
|
|
A single date with no \[dq]from\[dq] or \[dq]to\[dq] defines both the
|
|
start and end date like so:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l l.
|
|
T{
|
|
\f[C]-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[C]-p \[dq]2009/1\[dq]\f[R]
|
|
T}@T{
|
|
the month of jan; equivalent to \[lq]2009/1/1 to 2009/2/1\[rq]
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]2009/1/1\[dq]\f[R]
|
|
T}@T{
|
|
just that day; equivalent to \[lq]2009/1/1 to 2009/1/2\[rq]
|
|
T}
|
|
.TE
|
|
.PP
|
|
Or you can specify a single quarter like so:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l l.
|
|
T{
|
|
\f[C]-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[C]-p \[dq]q4\[dq]\f[R]
|
|
T}@T{
|
|
fourth quarter of the current year
|
|
T}
|
|
.TE
|
|
.PP
|
|
The argument of \f[C]-p\f[R] can also begin with, or be, a report
|
|
interval expression.
|
|
The basic report intervals are \f[C]daily\f[R], \f[C]weekly\f[R],
|
|
\f[C]monthly\f[R], \f[C]quarterly\f[R], or \f[C]yearly\f[R], which have
|
|
the same effect as the
|
|
\f[C]-D\f[R],\f[C]-W\f[R],\f[C]-M\f[R],\f[C]-Q\f[R], or \f[C]-Y\f[R]
|
|
flags.
|
|
Between report interval and start/end dates (if any), the word
|
|
\f[C]in\f[R] is optional.
|
|
Examples:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l.
|
|
T{
|
|
\f[C]-p \[dq]weekly from 2009/1/1 to 2009/4/1\[dq]\f[R]
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]monthly in 2008\[dq]\f[R]
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]quarterly\[dq]\f[R]
|
|
T}
|
|
.TE
|
|
.PP
|
|
Note that \f[C]weekly\f[R], \f[C]monthly\f[R], \f[C]quarterly\f[R] and
|
|
\f[C]yearly\f[R] intervals will always start on the first day on week,
|
|
month, quarter or year accordingly, and will end on the last day of same
|
|
period, even if associated period expression specifies different
|
|
explicit start and end date.
|
|
.PP
|
|
For example:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(25.5n) lw(44.5n).
|
|
T{
|
|
\f[C]-p \[dq]weekly from 2009/1/1 to 2009/4/1\[dq]\f[R]
|
|
T}@T{
|
|
starts on 2008/12/29, closest preceding Monday
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]monthly in 2008/11/25\[dq]\f[R]
|
|
T}@T{
|
|
starts on 2018/11/01
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]quarterly from 2009-05-05 to 2009-06-01\[dq]\f[R]
|
|
T}@T{
|
|
starts on 2009/04/01, ends on 2009/06/30, which are first and last days
|
|
of Q2 2009
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]yearly from 2009-12-29\[dq]\f[R]
|
|
T}@T{
|
|
starts on 2009/01/01, first day of 2009
|
|
T}
|
|
.TE
|
|
.PP
|
|
The following more complex report intervals are also supported:
|
|
\f[C]biweekly\f[R], \f[C]fortnightly\f[R], \f[C]bimonthly\f[R],
|
|
\f[C]every day|week|month|quarter|year\f[R],
|
|
\f[C]every N days|weeks|months|quarters|years\f[R].
|
|
.PP
|
|
All of these will start on the first day of the requested period and end
|
|
on the last one, as described above.
|
|
.PP
|
|
Examples:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(25.5n) lw(44.5n).
|
|
T{
|
|
\f[C]-p \[dq]bimonthly from 2008\[dq]\f[R]
|
|
T}@T{
|
|
periods will have boundaries on 2008/01/01, 2008/03/01, ...
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]every 2 weeks\[dq]\f[R]
|
|
T}@T{
|
|
starts on closest preceding Monday
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]every 5 month from 2009/03\[dq]\f[R]
|
|
T}@T{
|
|
periods will have boundaries on 2009/03/01, 2009/08/01, ...
|
|
T}
|
|
.TE
|
|
.PP
|
|
If you want intervals that start on arbitrary day of your choosing and
|
|
span a week, month or year, you need to use any of the following:
|
|
.PP
|
|
\f[C]every Nth day of week\f[R], \f[C]every WEEKDAYNAME\f[R] (eg
|
|
\f[C]mon|tue|wed|thu|fri|sat|sun\f[R]),
|
|
\f[C]every Nth day [of month]\f[R],
|
|
\f[C]every Nth WEEKDAYNAME [of month]\f[R],
|
|
\f[C]every MM/DD [of year]\f[R], \f[C]every Nth MMM [of year]\f[R],
|
|
\f[C]every MMM Nth [of year]\f[R].
|
|
.PP
|
|
Examples:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(23.9n) lw(46.1n).
|
|
T{
|
|
\f[C]-p \[dq]every 2nd day of week\[dq]\f[R]
|
|
T}@T{
|
|
periods will go from Tue to Tue
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]every Tue\[dq]\f[R]
|
|
T}@T{
|
|
same
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]every 15th day\[dq]\f[R]
|
|
T}@T{
|
|
period boundaries will be on 15th of each month
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]every 2nd Monday\[dq]\f[R]
|
|
T}@T{
|
|
period boundaries will be on second Monday of each month
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]every 11/05\[dq]\f[R]
|
|
T}@T{
|
|
yearly periods with boundaries on 5th of Nov
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]every 5th Nov\[dq]\f[R]
|
|
T}@T{
|
|
same
|
|
T}
|
|
T{
|
|
\f[C]-p \[dq]every Nov 5th\[dq]\f[R]
|
|
T}@T{
|
|
same
|
|
T}
|
|
.TE
|
|
.PP
|
|
Show historical balances at end of 15th each month (N is exclusive end
|
|
date):
|
|
.PP
|
|
\f[C]hledger balance -H -p \[dq]every 16th day\[dq]\f[R]
|
|
.PP
|
|
Group postings from start of wednesday to end of next tuesday (N is
|
|
start date and exclusive end date):
|
|
.PP
|
|
\f[C]hledger register checking -p \[dq]every 3rd day of week\[dq]\f[R]
|
|
.SH DEPTH
|
|
.PP
|
|
With the \f[C]--depth N\f[R] option (short form: \f[C]-N\f[R]), commands
|
|
like account, balance and register will show only the uppermost accounts
|
|
in the account tree, down to level N.
|
|
Use this when you want a summary with less detail.
|
|
This flag has the same effect as a \f[C]depth:\f[R] query argument (so
|
|
\f[C]-2\f[R], \f[C]--depth=2\f[R] or \f[C]depth:2\f[R] are equivalent).
|
|
.SH QUERIES
|
|
.PP
|
|
One of hledger\[aq]s strengths is being able to quickly report on
|
|
precise subsets of your data.
|
|
Most commands accept an optional query expression, written as arguments
|
|
after the command name, to filter the data by date, account name or
|
|
other criteria.
|
|
The syntax is similar to a web search: one or more space-separated
|
|
search terms, quotes to enclose whitespace, prefixes to match specific
|
|
fields, a not: prefix to negate the match.
|
|
.PP
|
|
We do not yet support arbitrary boolean combinations of search terms;
|
|
instead most commands show transactions/postings/accounts which match
|
|
(or negatively 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 instead shows 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
|
|
The following kinds of search terms can be used.
|
|
Remember these can also be prefixed with \f[B]\f[CB]not:\f[B]\f[R], eg
|
|
to exclude a particular subaccount.
|
|
.TP
|
|
\f[B]\f[R]\f[C]REGEX\f[R]\f[B], \f[R]\f[C]acct:REGEX\f[R]\f[B]\f[R]
|
|
match account names by this regular expression.
|
|
(With no prefix, \f[C]acct:\f[R] is assumed.)
|
|
same as above
|
|
.TP
|
|
\f[B]\f[R]\f[C]amt:N, amt:<N, amt:<=N, amt:>N, amt:>=N\f[R]\f[B]\f[R]
|
|
match postings with a single-commodity amount that is equal to, less
|
|
than, or greater than N.
|
|
(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.
|
|
.TP
|
|
\f[B]\f[R]\f[C]code:REGEX\f[R]\f[B]\f[R]
|
|
match by transaction code (eg check number)
|
|
.TP
|
|
\f[B]\f[R]\f[C]cur:REGEX\f[R]\f[B]\f[R]
|
|
match postings or transactions including any amounts whose
|
|
currency/commodity symbol is fully matched by REGEX.
|
|
(For a partial match, use \f[C].*REGEX.*\f[R]).
|
|
Note, to match characters which are regex-significant, like the dollar
|
|
sign (\f[C]$\f[R]), you need to prepend \f[C]\[rs]\f[R].
|
|
And when using the command line you need to add one more level of
|
|
quoting to hide it from the shell, so eg do:
|
|
\f[C]hledger print cur:\[aq]\[rs]$\[aq]\f[R] or
|
|
\f[C]hledger print cur:\[rs]\[rs]$\f[R].
|
|
.TP
|
|
\f[B]\f[R]\f[C]desc:REGEX\f[R]\f[B]\f[R]
|
|
match transaction descriptions.
|
|
.TP
|
|
\f[B]\f[R]\f[C]date:PERIODEXPR\f[R]\f[B]\f[R]
|
|
match dates within the specified period.
|
|
PERIODEXPR is a period expression (with no report interval).
|
|
Examples: \f[C]date:2016\f[R], \f[C]date:thismonth\f[R],
|
|
\f[C]date:2000/2/1-2/15\f[R], \f[C]date:lastweek-\f[R].
|
|
If the \f[C]--date2\f[R] command line flag is present, this matches
|
|
secondary dates instead.
|
|
.TP
|
|
\f[B]\f[R]\f[C]date2:PERIODEXPR\f[R]\f[B]\f[R]
|
|
match secondary dates within the specified period.
|
|
.TP
|
|
\f[B]\f[R]\f[C]depth:N\f[R]\f[B]\f[R]
|
|
match (or display, depending on command) accounts at or above this depth
|
|
.TP
|
|
\f[B]\f[R]\f[C]note:REGEX\f[R]\f[B]\f[R]
|
|
match transaction notes (part of description right of \f[C]|\f[R], or
|
|
whole description when there\[aq]s no \f[C]|\f[R])
|
|
.TP
|
|
\f[B]\f[R]\f[C]payee:REGEX\f[R]\f[B]\f[R]
|
|
match transaction payee/payer names (part of description left of
|
|
\f[C]|\f[R], or whole description when there\[aq]s no \f[C]|\f[R])
|
|
.TP
|
|
\f[B]\f[R]\f[C]real:, real:0\f[R]\f[B]\f[R]
|
|
match real or virtual postings respectively
|
|
.TP
|
|
\f[B]\f[R]\f[C]status:, status:!, status:*\f[R]\f[B]\f[R]
|
|
match unmarked, pending, or cleared transactions respectively
|
|
.TP
|
|
\f[B]\f[R]\f[C]tag:REGEX[=REGEX]\f[R]\f[B]\f[R]
|
|
match by tag name, and optionally also by tag value.
|
|
Note a tag: query is considered to match a transaction if it matches any
|
|
of the postings.
|
|
Also remember that postings inherit the tags of their parent
|
|
transaction.
|
|
.PP
|
|
The following special search term is used automatically in hledger-web,
|
|
only:
|
|
.TP
|
|
\f[B]\f[R]\f[C]inacct:ACCTNAME\f[R]\f[B]\f[R]
|
|
tells hledger-web to show the transaction register for this account.
|
|
Can be filtered further with \f[C]acct\f[R] etc.
|
|
.PP
|
|
Some of these can also be expressed as command-line options (eg
|
|
\f[C]depth:2\f[R] is equivalent to \f[C]--depth 2\f[R]).
|
|
Generally you can mix options and query arguments, and the resulting
|
|
query will be their intersection (perhaps excluding the
|
|
\f[C]-p/--period\f[R] option).
|
|
.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), or to market value (using some market price on a
|
|
certain date).
|
|
This is controlled by the \f[C]--value=TYPE[,COMMODITY]\f[R] option, but
|
|
we also provide the simpler \f[C]-B\f[R]/\f[C]-V\f[R]/\f[C]-X\f[R]
|
|
flags, and usually one of those is all you need.
|
|
.SS -B: Cost
|
|
.PP
|
|
The \f[C]-B/--cost\f[R] flag converts amounts to their cost or sale
|
|
amount at transaction time, if they have a transaction price specified.
|
|
.SS -V: Value
|
|
.PP
|
|
The \f[C]-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[C]-X/--exchange=COMM\f[R] option is like \f[C]-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 Market prices
|
|
.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[C]--infer-value\f[R] flag)
|
|
inferred from transaction prices.
|
|
.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]a 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
|
|
A \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
|
|
Amounts for which no applicable market price can be found, are not
|
|
converted.
|
|
.SS --infer-value: 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
|
|
transaction prices as additional market prices (as Ledger does) ?
|
|
We could produce value reports without needing P directives at all.
|
|
.PP
|
|
Adding the \f[C]--infer-value\f[R] flag to \f[C]-V\f[R], \f[C]-X\f[R] or
|
|
\f[C]--value\f[R] enables this.
|
|
So for example, \f[C]hledger bs -V --infer-value\f[R] will get market
|
|
prices both from P directives and from transactions.
|
|
.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[C]--debug\f[R] or \f[C]--debug=2\f[R] to troubleshoot.
|
|
.PP
|
|
\f[C]--infer-value\f[R] can infer market prices from:
|
|
.IP \[bu] 2
|
|
multicommodity transactions with explicit prices
|
|
(\f[C]\[at]\f[R]/\f[C]\[at]\[at]\f[R])
|
|
.IP \[bu] 2
|
|
multicommodity transactions with implicit prices (no \f[C]\[at]\f[R],
|
|
two commodities, unbalanced).
|
|
(With these, the order of postings matters.
|
|
\f[C]hledger print -x\f[R] can be useful for troubleshooting.)
|
|
.IP \[bu] 2
|
|
but not, currently, from \[dq]more correct\[dq] multicommodity
|
|
transactions (no \f[C]\[at]\f[R], multiple commodities, balanced).
|
|
.SS Valuation commodity
|
|
.PP
|
|
\f[B]When you specify a valuation commodity (\f[CB]-X COMM\f[B] or
|
|
\f[CB]--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[CB]-V\f[B]
|
|
or \f[CB]--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[C]--infer-value\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[C]-V\f[R]
|
|
will convert, and to what.
|
|
.IP \[bu] 2
|
|
If you have no P directives, and use the \f[C]--infer-value\f[R] flag,
|
|
transaction prices 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[C]-V\f[R]:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
; one euro is worth this many dollars from nov 1
|
|
P 2016/11/01 \[Eu] $1.10
|
|
|
|
; purchase some euros on nov 3
|
|
2016/11/3
|
|
assets:euros \[Eu]100
|
|
assets:checking
|
|
|
|
; the euro is worth fewer dollars by dec 21
|
|
P 2016/12/21 \[Eu] $1.03
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
How many euros do I have ?
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger -f t.j bal -N euros
|
|
\[Eu]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[C]-B\f[R], \f[C]-V\f[R] and \f[C]-X\f[R] are special cases of the
|
|
more general \f[C]--value\f[R] option:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
--value=TYPE[,COMM] TYPE is cost, then, end, now or YYYY-MM-DD.
|
|
COMM is an optional commodity symbol.
|
|
Shows amounts converted to:
|
|
- cost commodity using transaction prices (then optionally to COMM using market prices at period end(s))
|
|
- 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[B]\f[CB]--value=cost\f[B]\f[R]
|
|
Convert amounts to cost, using the prices recorded in transactions.
|
|
.TP
|
|
\f[B]\f[CB]--value=then\f[B]\f[R]
|
|
Convert amounts to their value in the default valuation commodity, using
|
|
market prices on each posting\[aq]s date.
|
|
This is currently supported only by the print and register commands.
|
|
.TP
|
|
\f[B]\f[CB]--value=end\f[B]\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[B]\f[CB]--value=now\f[B]\f[R]
|
|
Convert amounts to their value in the default valuation commodity using
|
|
current market prices (as of when report is generated).
|
|
.TP
|
|
\f[B]\f[CB]--value=YYYY-MM-DD\f[B]\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[C],COMM\f[R] part: a comma, then the target commodity\[aq]s symbol.
|
|
Eg: \f[B]\f[CB]--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[C]--value\f[R], as seen
|
|
with \f[C]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 --value=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 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(10.6n) lw(13.2n) lw(13.4n) lw(11.0n) lw(13.4n) lw(8.2n).
|
|
T{
|
|
Report type
|
|
T}@T{
|
|
\f[C]-B\f[R], \f[C]--value=cost\f[R]
|
|
T}@T{
|
|
\f[C]-V\f[R], \f[C]-X\f[R]
|
|
T}@T{
|
|
\f[C]--value=then\f[R]
|
|
T}@T{
|
|
\f[C]--value=end\f[R]
|
|
T}@T{
|
|
\f[C]--value=DATE\f[R], \f[C]--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 day before report or journal start
|
|
T}@T{
|
|
not supported
|
|
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 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{
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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{
|
|
not supported
|
|
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[C]--cumulative\f[R] is omitted to save space, it works like
|
|
\f[C]-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 PIVOTING
|
|
.PP
|
|
Normally hledger sums amounts, and organizes them in a hierarchy, based
|
|
on account name.
|
|
The \f[C]--pivot FIELD\f[R] option causes it to sum and organize
|
|
hierarchy based on the value of some other field instead.
|
|
FIELD can be: \f[C]code\f[R], \f[C]description\f[R], \f[C]payee\f[R],
|
|
\f[C]note\f[R], or the full name (case insensitive) of any tag.
|
|
As with account names, values containing \f[C]colon:separated:parts\f[R]
|
|
will be displayed hierarchically in reports.
|
|
.PP
|
|
\f[C]--pivot\f[R] is a general option affecting all reports; you can
|
|
think of hledger transforming the journal before any other processing,
|
|
replacing every posting\[aq]s account name with the value of the
|
|
specified field on that posting, inheriting it from the transaction or
|
|
using a blank value if it\[aq]s not present.
|
|
.PP
|
|
An example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2016/02/16 Member Fee Payment
|
|
assets:bank account 2 EUR
|
|
income:member fees -2 EUR ; member: John Doe
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Normal balance report showing account names:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance
|
|
2 EUR assets:bank account
|
|
-2 EUR income:member fees
|
|
--------------------
|
|
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,
|
|
described below):
|
|
.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
|
|
.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[C]-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 (print, register, the balance commands) offer a choice of
|
|
output format.
|
|
In addition to the usual plain text format (\f[C]txt\f[R]), there are
|
|
CSV (\f[C]csv\f[R]), HTML (\f[C]html\f[R]), JSON (\f[C]json\f[R]) and
|
|
SQL (\f[C]sql\f[R]).
|
|
This is controlled by the \f[C]-O/--output-format\f[R] option:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger print -O csv
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
or, by a file extension specified with \f[C]-o/--output-file\f[R]:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balancesheet -o foo.html # write HTML to foo.html
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
The \f[C]-O\f[R] option can be used to override the file extension if
|
|
needed:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balancesheet -o foo.txt -O html # write HTML to foo.txt
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Some notes about JSON output:
|
|
.IP \[bu] 2
|
|
This feature is marked experimental, and not yet much used; you should
|
|
expect our JSON to evolve.
|
|
Real-world feedback is welcome.
|
|
.IP \[bu] 2
|
|
Our JSON is rather large and verbose, as it is quite 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)
|
|
.PP
|
|
Notes about SQL output:
|
|
.IP \[bu] 2
|
|
SQL output is also marked experimental, and much like JSON could use
|
|
real-world feedback.
|
|
.IP \[bu] 2
|
|
SQL output is expected to work with sqlite, MySQL and PostgreSQL
|
|
.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[C]delete\f[R] or \f[C]truncate\f[R] SQL statements) or drop tables
|
|
completely as otherwise your postings will be duped.
|
|
.SH COMMANDS
|
|
.PP
|
|
hledger provides a number of commands for producing reports and managing
|
|
your data.
|
|
Run \f[C]hledger\f[R] with no arguments to list the commands available,
|
|
and \f[C]hledger CMD\f[R] to run a command.
|
|
CMD can be the full command name, or its standard abbreviation shown in
|
|
the commands list, or any unambiguous prefix of the name.
|
|
Eg: \f[C]hledger bal\f[R].
|
|
.PP
|
|
Here are the built-in commands, with the most often-used in bold:
|
|
.PP
|
|
\f[B]Data entry:\f[R]
|
|
.PP
|
|
These data entry commands are the only ones which can modify your
|
|
journal file.
|
|
.IP \[bu] 2
|
|
\f[B]add\f[R] - add transactions using guided prompts
|
|
.IP \[bu] 2
|
|
\f[B]import\f[R] - add any new transactions from other files (eg csv)
|
|
.PP
|
|
\f[B]Data management:\f[R]
|
|
.IP \[bu] 2
|
|
check - check for various kinds of issue in the data
|
|
.IP \[bu] 2
|
|
close (equity) - generate balance-resetting transactions
|
|
.IP \[bu] 2
|
|
diff - compare account transactions in two journal files
|
|
.IP \[bu] 2
|
|
rewrite - generate extra postings, similar to print --auto
|
|
.PP
|
|
\f[B]Financial statements:\f[R]
|
|
.IP \[bu] 2
|
|
\f[B]aregister (areg)\f[R] - show transactions in a particular account
|
|
.IP \[bu] 2
|
|
\f[B]balancesheet (bs)\f[R] - 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
|
|
\f[B]incomestatement (is)\f[R] - show revenues and expenses
|
|
.IP \[bu] 2
|
|
roi - show return on investments
|
|
.PP
|
|
\f[B]Miscellaneous reports:\f[R]
|
|
.IP \[bu] 2
|
|
accounts - show account names
|
|
.IP \[bu] 2
|
|
activity - show postings-per-interval bar charts
|
|
.IP \[bu] 2
|
|
\f[B]balance (bal)\f[R] - show balance changes/end balances/budgets in
|
|
any accounts
|
|
.IP \[bu] 2
|
|
codes - show transaction codes
|
|
.IP \[bu] 2
|
|
commodities - show commodity/currency symbols
|
|
.IP \[bu] 2
|
|
descriptions - show unique transaction descriptions
|
|
.IP \[bu] 2
|
|
files - show input file paths
|
|
.IP \[bu] 2
|
|
help - show hledger user manuals in several formats
|
|
.IP \[bu] 2
|
|
notes - show unique note segments of transaction descriptions
|
|
.IP \[bu] 2
|
|
payees - show unique payee segments of transaction descriptions
|
|
.IP \[bu] 2
|
|
prices - show market price records
|
|
.IP \[bu] 2
|
|
\f[B]print\f[R] - show transactions (journal entries)
|
|
.IP \[bu] 2
|
|
print-unique - show only transactions with unique descriptions
|
|
.IP \[bu] 2
|
|
\f[B]register (reg)\f[R] - show postings in one or more accounts &
|
|
running total
|
|
.IP \[bu] 2
|
|
register-match - show a recent posting that best matches a description
|
|
.IP \[bu] 2
|
|
stats - show journal statistics
|
|
.IP \[bu] 2
|
|
tags - show tag names
|
|
.IP \[bu] 2
|
|
test - run self tests
|
|
.PP
|
|
\f[B]Add-on commands:\f[R]
|
|
.PP
|
|
Programs or scripts named \f[C]hledger-SOMETHING\f[R] in your PATH are
|
|
add-on commands; these appear in the commands list with a \f[C]+\f[R]
|
|
mark.
|
|
Two of these are maintained and released with hledger:
|
|
.IP \[bu] 2
|
|
\f[B]ui\f[R] - an efficient terminal interface (TUI) for hledger
|
|
.IP \[bu] 2
|
|
\f[B]web\f[R] - a simple web interface (WUI) for hledger
|
|
.PP
|
|
And these add-ons are maintained separately:
|
|
.IP \[bu] 2
|
|
iadd - a more interactive alternative for the add command
|
|
.IP \[bu] 2
|
|
interest - generates interest transactions according to various schemes
|
|
.IP \[bu] 2
|
|
stockquotes - downloads market prices for your commodities from
|
|
AlphaVantage \f[I](experimental)\f[R]
|
|
.PP
|
|
Next, the detailed command docs, in alphabetical order.
|
|
.SS accounts
|
|
.PP
|
|
accounts
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Show account names.
|
|
.PP
|
|
This command lists account names, either declared with account
|
|
directives (--declared), posted to (--used), or both (the default).
|
|
With query arguments, only matched account names and account names
|
|
referenced by matched postings are shown.
|
|
It shows a flat list by default.
|
|
With \f[C]--tree\f[R], it uses indentation to show the account
|
|
hierarchy.
|
|
In flat mode you can add \f[C]--drop N\f[R] to omit the first few
|
|
account name components.
|
|
Account names can be depth-clipped with \f[C]depth:N\f[R] or
|
|
\f[C]--depth N\f[R] or \f[C]-N\f[R].
|
|
.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
|
|
.SS activity
|
|
.PP
|
|
activity
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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
|
|
add
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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[C]add\f[R] command,
|
|
which prompts interactively on the console for new transactions, and
|
|
appends them to the journal file (if there are multiple
|
|
\f[C]-f FILE\f[R] options, the first file is used.) Existing
|
|
transactions are not changed.
|
|
This is the only hledger command that writes to the journal file.
|
|
.PP
|
|
To use it, just run \f[C]hledger add\f[R] and follow the prompts.
|
|
You can add as many transactions as you like; when you are finished,
|
|
enter \f[C].\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,
|
|
descriptions, dates (\f[C]yesterday\f[R], \f[C]today\f[R],
|
|
\f[C]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[C]<\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 the tutorial for a detailed explanation):
|
|
.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
|
|
aregister, areg
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Show transactions affecting a particular account, and the account\[aq]s
|
|
running balance.
|
|
.PP
|
|
\f[C]aregister\f[R] shows the transactions affecting a particular
|
|
account (and its subaccounts), from the point of view of that account.
|
|
Each line shows:
|
|
.IP \[bu] 2
|
|
the transaction\[aq]s (or posting\[aq]s, see below) date
|
|
.IP \[bu] 2
|
|
the names of the other account(s) involved
|
|
.IP \[bu] 2
|
|
the net change to this account\[aq]s balance
|
|
.IP \[bu] 2
|
|
the account\[aq]s historical running balance (including balance from
|
|
transactions before the report start date).
|
|
.PP
|
|
With \f[C]aregister\f[R], each line represents a whole transaction - as
|
|
in hledger-ui, hledger-web, and your bank statement.
|
|
By contrast, the \f[C]register\f[R] command shows individual postings,
|
|
across all accounts.
|
|
You might prefer \f[C]aregister\f[R] for reconciling with real-world
|
|
asset/liability accounts, and \f[C]register\f[R] for reviewing detailed
|
|
revenues/expenses.
|
|
.PP
|
|
An account must be specified as the first argument, which should be the
|
|
full account name or an account pattern (regular expression).
|
|
aregister will show transactions in this account (the first one matched)
|
|
and any of its subaccounts.
|
|
.PP
|
|
Any additional arguments form a query which will filter the transactions
|
|
shown.
|
|
.PP
|
|
Transactions making a net change of zero are not shown by default; add
|
|
the \f[C]-E/--empty\f[R] flag to show them.
|
|
.PP
|
|
This command also supports the output destination and output format
|
|
options The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R],
|
|
and \f[C]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[C]aregister\f[R] can show an accurate historical running
|
|
balance, matching the one shown by \f[C]register -H\f[R] with the same
|
|
arguments.
|
|
.PP
|
|
To filter strictly by transaction date instead, add the
|
|
\f[C]--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.
|
|
.PP
|
|
Examples:
|
|
.PP
|
|
Show all transactions and historical running balance in the first
|
|
account whose name contains \[dq]checking\[dq]:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger areg checking
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Show transactions and historical running balance in all asset accounts
|
|
during july:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger areg assets date:jul
|
|
\f[R]
|
|
.fi
|
|
.SS balance
|
|
.PP
|
|
balance, bal
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Show accounts and their balances.
|
|
.PP
|
|
The balance command is hledger\[aq]s most versatile command.
|
|
Note, despite the name, it is not always used for showing real-world
|
|
account balances; the more accounting-aware balancesheet and
|
|
incomestatement may be more convenient for that.
|
|
.PP
|
|
By default, it displays all accounts, and each account\[aq]s change in
|
|
balance during the entire period of the journal.
|
|
Balance changes are calculated by adding up the postings in each
|
|
account.
|
|
You can limit the postings matched, by a query, to see fewer accounts,
|
|
changes over a different time period, changes from only cleared
|
|
transactions, etc.
|
|
.PP
|
|
If you include an account\[aq]s complete history of postings in the
|
|
report, the balance change is equivalent to the account\[aq]s current
|
|
ending balance.
|
|
For a real-world account, typically you won\[aq]t have all transactions
|
|
in the journal; instead you\[aq]ll have all transactions after a certain
|
|
date, and an \[dq]opening balances\[dq] transaction setting the correct
|
|
starting balance on that date.
|
|
Then the balance command will show real-world account balances.
|
|
In some cases the -H/--historical flag is used to ensure this (more
|
|
below).
|
|
.PP
|
|
This command also supports the output destination and output format
|
|
options The output formats supported are (in most modes): \f[C]txt\f[R],
|
|
\f[C]csv\f[R], \f[C]html\f[R], and \f[C]json\f[R].
|
|
.PP
|
|
The balance command can produce several styles of report:
|
|
.SS Classic balance report
|
|
.PP
|
|
This is the original balance report, as found in Ledger.
|
|
It usually looks like this:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance
|
|
$-1 assets
|
|
$1 bank:saving
|
|
$-2 cash
|
|
$2 expenses
|
|
$1 food
|
|
$1 supplies
|
|
$-2 income
|
|
$-1 gifts
|
|
$-1 salary
|
|
$1 liabilities:debts
|
|
--------------------
|
|
0
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
By default, accounts are displayed hierarchically, with subaccounts
|
|
indented below their parent, with accounts at each level of the tree
|
|
sorted by declaration order if declared, then by account name.
|
|
.PP
|
|
\[dq]Boring\[dq] accounts, which contain a single interesting subaccount
|
|
and no balance of their own, are elided into the following line for more
|
|
compact output.
|
|
(Eg above, the \[dq]liabilities\[dq] account.) Use \f[C]--no-elide\f[R]
|
|
to prevent this.
|
|
.PP
|
|
Account balances are \[dq]inclusive\[dq] - they include the balances of
|
|
any subaccounts.
|
|
.PP
|
|
Accounts which have zero balance (and no non-zero subaccounts) are
|
|
omitted.
|
|
Use \f[C]-E/--empty\f[R] to show them.
|
|
.PP
|
|
A final total is displayed by default; use \f[C]-N/--no-total\f[R] to
|
|
suppress it, eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance -p 2008/6 expenses --no-total
|
|
$2 expenses
|
|
$1 food
|
|
$1 supplies
|
|
\f[R]
|
|
.fi
|
|
.SS Customising the classic balance report
|
|
.PP
|
|
You can customise the layout of classic balance reports with
|
|
\f[C]--format FMT\f[R]:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger 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 (plus a newline) specifies the formatting applied
|
|
to each account/balance pair.
|
|
It may contain any suitable text, with data fields interpolated like so:
|
|
.PP
|
|
\f[C]%[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[C]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[C]account\f[R] - the account\[aq]s name
|
|
.IP \[bu] 2
|
|
\f[C]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[C]%_\f[R] - render on multiple lines, bottom-aligned (the default)
|
|
.IP \[bu] 2
|
|
\f[C]%\[ha]\f[R] - render on multiple lines, top-aligned
|
|
.IP \[bu] 2
|
|
\f[C]%,\f[R] - render on one line, comma-separated
|
|
.PP
|
|
There are some quirks.
|
|
Eg in one-line mode, \f[C]%(depth_spacer)\f[R] has no effect, instead
|
|
\f[C]%(account)\f[R] has indentation built in.
|
|
Experimentation may be needed to get pleasing results.
|
|
.PP
|
|
Some example formats:
|
|
.IP \[bu] 2
|
|
\f[C]%(total)\f[R] - the account\[aq]s total
|
|
.IP \[bu] 2
|
|
\f[C]%-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[C]%,%-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[C]%20(total) %2(depth_spacer)%-(account)\f[R] - the default format
|
|
for the single-column balance report
|
|
.SS Colour support
|
|
.PP
|
|
In terminal output, when colour is enabled, the balance command shows
|
|
negative amounts in red.
|
|
.SS Flat mode
|
|
.PP
|
|
To see a flat list instead of the default hierarchical display, use
|
|
\f[C]--flat\f[R].
|
|
In this mode, accounts (unless depth-clipped) show their full names and
|
|
\[dq]exclusive\[dq] balance, excluding any subaccount balances.
|
|
In this mode, you can also use \f[C]--drop N\f[R] to omit the first few
|
|
account name components.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance -p 2008/6 expenses -N --flat --drop 1
|
|
$1 food
|
|
$1 supplies
|
|
\f[R]
|
|
.fi
|
|
.SS Depth limited balance reports
|
|
.PP
|
|
With \f[C]--depth N\f[R] or \f[C]depth:N\f[R] or just \f[C]-N\f[R],
|
|
balance reports show accounts only to the specified numeric depth.
|
|
This is very useful to summarise a complex set of accounts and get an
|
|
overview.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance -N -1
|
|
$-1 assets
|
|
$2 expenses
|
|
$-2 income
|
|
$1 liabilities
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Flat-mode balance reports, which normally show exclusive balances, show
|
|
inclusive balances at the depth limit.
|
|
.SS Percentages
|
|
.PP
|
|
With \f[C]-%\f[R] or \f[C]--percent\f[R], balance reports show each
|
|
account\[aq]s value expressed as a percentage of the column\[aq]s total.
|
|
This is useful to get an overview of the relative sizes of account
|
|
balances.
|
|
For example to obtain an overview of expenses:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance expenses -%
|
|
100.0 % expenses
|
|
50.0 % food
|
|
50.0 % supplies
|
|
--------------------
|
|
100.0 %
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Note that \f[C]--tree\f[R] does not have an effect on \f[C]-%\f[R].
|
|
The percentages are always relative to the total sum of each column,
|
|
they are never relative to the parent account.
|
|
.PP
|
|
Since the percentages are relative to the columns sum, it is usually not
|
|
useful to calculate percentages if the signs of the amounts are mixed.
|
|
Although the results are technically correct, they are most likely
|
|
useless.
|
|
Especially in a balance report that sums up to zero (eg
|
|
\f[C]hledger balance -B\f[R]) all percentage values will be zero.
|
|
.PP
|
|
This flag does not work if the report contains any mixed commodity
|
|
accounts.
|
|
If there are mixed commodity accounts in the report be sure to use
|
|
\f[C]-V\f[R] or \f[C]-B\f[R] to coerce the report into using a single
|
|
commodity.
|
|
.SS Sorting by amount
|
|
.PP
|
|
With \f[C]-S\f[R]/\f[C]--sort-amount\f[R], accounts with the largest
|
|
(most positive) balances are shown first.
|
|
For example, \f[C]hledger bal expenses -MAS\f[R] shows your biggest
|
|
averaged monthly expenses first.
|
|
.PP
|
|
Revenues and liability balances are typically negative, however, so
|
|
\f[C]-S\f[R] shows these in reverse order.
|
|
To work around this, you can add \f[C]--invert\f[R] to flip the signs.
|
|
Or, use one of the sign-flipping reports like \f[C]balancesheet\f[R] or
|
|
\f[C]incomestatement\f[R], which also support \f[C]-S\f[R].
|
|
Eg: \f[C]hledger is -MAS\f[R].
|
|
.SS Multicolumn balance report
|
|
.PP
|
|
Multicolumn or tabular balance reports are a very useful hledger
|
|
feature, and usually the preferred style.
|
|
They share many of the above features, but they show the report as a
|
|
table, with columns representing time periods.
|
|
This mode is activated by providing a reporting interval.
|
|
.PP
|
|
There are three types of multicolumn balance report, showing different
|
|
information:
|
|
.IP "1." 3
|
|
By default: each column shows the sum of postings in that period, ie the
|
|
account\[aq]s change of balance in that period.
|
|
This is useful eg for a monthly income statement:
|
|
.RS 4
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance --quarterly income expenses -E
|
|
Balance changes in 2008:
|
|
|
|
|| 2008q1 2008q2 2008q3 2008q4
|
|
===================++=================================
|
|
expenses:food || 0 $1 0 0
|
|
expenses:supplies || 0 $1 0 0
|
|
income:gifts || 0 $-1 0 0
|
|
income:salary || $-1 0 0 0
|
|
-------------------++---------------------------------
|
|
|| $-1 $1 0 0
|
|
\f[R]
|
|
.fi
|
|
.RE
|
|
.IP "2." 3
|
|
With \f[C]--cumulative\f[R]: each column shows the ending balance for
|
|
that period, accumulating the changes across periods, starting from 0 at
|
|
the report start date:
|
|
.RS 4
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance --quarterly income expenses -E --cumulative
|
|
Ending balances (cumulative) in 2008:
|
|
|
|
|| 2008/03/31 2008/06/30 2008/09/30 2008/12/31
|
|
===================++=================================================
|
|
expenses:food || 0 $1 $1 $1
|
|
expenses:supplies || 0 $1 $1 $1
|
|
income:gifts || 0 $-1 $-1 $-1
|
|
income:salary || $-1 $-1 $-1 $-1
|
|
-------------------++-------------------------------------------------
|
|
|| $-1 0 0 0
|
|
\f[R]
|
|
.fi
|
|
.RE
|
|
.IP "3." 3
|
|
With \f[C]--historical/-H\f[R]: each column shows the actual historical
|
|
ending balance for that period, accumulating the changes across periods,
|
|
starting from the actual balance at the report start date.
|
|
This is useful eg for a multi-period balance sheet, and when you are
|
|
showing only the data after a certain start date:
|
|
.RS 4
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance \[ha]assets \[ha]liabilities --quarterly --historical --begin 2008/4/1
|
|
Ending balances (historical) in 2008/04/01-2008/12/31:
|
|
|
|
|| 2008/06/30 2008/09/30 2008/12/31
|
|
======================++=====================================
|
|
assets:bank:checking || $1 $1 0
|
|
assets:bank:saving || $1 $1 $1
|
|
assets:cash || $-2 $-2 $-2
|
|
liabilities:debts || 0 0 $1
|
|
----------------------++-------------------------------------
|
|
|| 0 0 0
|
|
\f[R]
|
|
.fi
|
|
.RE
|
|
.PP
|
|
Note that \f[C]--cumulative\f[R] or \f[C]--historical/-H\f[R] disable
|
|
\f[C]--row-total/-T\f[R], since summing end balances generally does not
|
|
make sense.
|
|
.PP
|
|
Multicolumn balance reports display accounts in flat mode by default; to
|
|
see the hierarchy, use \f[C]--tree\f[R].
|
|
.PP
|
|
With a reporting interval (like \f[C]--quarterly\f[R] above), the report
|
|
start/end dates will be adjusted if necessary so that they encompass the
|
|
displayed report periods.
|
|
This is so that the first and last periods will be \[dq]full\[dq] and
|
|
comparable to the others.
|
|
.PP
|
|
The \f[C]-E/--empty\f[R] flag does two things in multicolumn balance
|
|
reports: first, the report will show all columns within the specified
|
|
report period (without -E, leading and trailing columns with all zeroes
|
|
are not shown).
|
|
Second, all accounts which existed at the report start date will be
|
|
considered, not just the ones with activity during the report period
|
|
(use -E to include low-activity accounts which would otherwise would be
|
|
omitted).
|
|
.PP
|
|
The \f[C]-T/--row-total\f[R] flag adds an additional column showing the
|
|
total for each row.
|
|
.PP
|
|
The \f[C]-A/--average\f[R] flag adds a column showing the average value
|
|
in each row.
|
|
.PP
|
|
Here\[aq]s an example of all three:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger balance -Q income expenses --tree -ETA
|
|
Balance changes in 2008:
|
|
|
|
|| 2008q1 2008q2 2008q3 2008q4 Total Average
|
|
============++===================================================
|
|
expenses || 0 $2 0 0 $2 $1
|
|
food || 0 $1 0 0 $1 0
|
|
supplies || 0 $1 0 0 $1 0
|
|
income || $-1 $-1 0 0 $-2 $-1
|
|
gifts || 0 $-1 0 0 $-1 0
|
|
salary || $-1 0 0 0 $-1 0
|
|
------------++---------------------------------------------------
|
|
|| $-1 $1 0 0 0 0
|
|
|
|
(Average is rounded to the dollar here since all journal amounts are)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
The \f[C]--transpose\f[R] flag can be used to exchange the rows and
|
|
columns of a multicolumn report.
|
|
.PP
|
|
When showing multicommodity amounts, multicolumn balance reports will
|
|
elide any amounts which have more than two commodities, since otherwise
|
|
columns could get very wide.
|
|
The \f[C]--no-elide\f[R] flag disables this.
|
|
Hiding totals with the \f[C]-N/--no-total\f[R] flag can also help reduce
|
|
the width of multicommodity reports.
|
|
.PP
|
|
When the report is still too wide, a good workaround is to pipe it into
|
|
\f[C]less -RS\f[R] (-R for colour, -S to chop long lines).
|
|
Eg: \f[C]hledger bal -D --color=yes | less -RS\f[R].
|
|
.SS Budget report
|
|
.PP
|
|
With \f[C]--budget\f[R], extra columns are displayed showing budget
|
|
goals for each account and period, if any.
|
|
Budget goals are defined by periodic transactions.
|
|
This is very useful for comparing planned and actual income, expenses,
|
|
time usage, etc.
|
|
--budget is most often combined with a report interval.
|
|
.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:
|
|
.IP \[bu] 2
|
|
Only accounts with budget goals during the report period are shown, by
|
|
default.
|
|
.IP \[bu] 2
|
|
In each column, in square brackets after the actual amount, budget goal
|
|
amounts are shown, and the actual/goal percentage.
|
|
(Note: budget goals should be in the same commodity as the actual
|
|
amount.)
|
|
.IP \[bu] 2
|
|
All parent accounts are always shown, even in flat mode.
|
|
Eg assets, assets:bank, and expenses above.
|
|
.IP \[bu] 2
|
|
Amounts always include all subaccounts, budgeted or unbudgeted, even in
|
|
flat mode.
|
|
.PP
|
|
This means that the numbers displayed will not always add up! Eg above,
|
|
the \f[C]expenses\f[R] actual amount includes the gifts and supplies
|
|
transactions, but the \f[C]expenses:gifts\f[R] and
|
|
\f[C]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[C]-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[C]--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
|
|
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[C]\[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[C]-b\f[R]/\f[C]-e\f[R]/\f[C]-p\f[R]/\f[C]date:\f[R],
|
|
to ensure it includes the budget goal transactions (periodic
|
|
transactions) that you want.
|
|
Eg, adding \f[C]-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 Nested budgets
|
|
.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[C]expenses:personal\f[R] and
|
|
\f[C]expenses\f[R] is $1100.
|
|
.PP
|
|
Transactions in \f[C]expenses:personal:electronics\f[R] will be counted
|
|
both towards its $100 budget and $1100 of \f[C]expenses:personal\f[R] ,
|
|
and transactions in any other subaccount of \f[C]expenses:personal\f[R]
|
|
would be counted towards only towards the budget of
|
|
\f[C]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[C]expenses:personal:electronics:upgrades\f[R] and
|
|
\f[C]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[C]expenses:personal:electronics\f[R]
|
|
and \f[C]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[C]--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 balancesheet
|
|
.PP
|
|
balancesheet, bs
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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
|
|
The asset and liability accounts shown are those accounts declared with
|
|
the \f[C]Asset\f[R] or \f[C]Cash\f[R] or \f[C]Liability\f[R] type, or
|
|
otherwise all accounts under a top-level \f[C]asset\f[R] or
|
|
\f[C]liability\f[R] account (case insensitive, plurals allowed).
|
|
.PP
|
|
(This report is essentially similar to \[dq]hledger balance --historical
|
|
assets liabilities\[dq], with liabilities sign-flipped.)
|
|
.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
|
|
With a reporting interval, multiple columns will be shown, one for each
|
|
report period.
|
|
As with multicolumn balance reports, you can alter the report mode with
|
|
\f[C]--change\f[R]/\f[C]--cumulative\f[R]/\f[C]--historical\f[R].
|
|
Normally balancesheet shows historical ending balances, which is what
|
|
you need for a balance sheet; note this means it ignores report begin
|
|
dates (and \f[C]-T/--row-total\f[R], since summing end balances
|
|
generally does not make sense).
|
|
Instead of absolute values percentages can be displayed with
|
|
\f[C]-%\f[R].
|
|
.PP
|
|
This command also supports the output destination and output format
|
|
options The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R],
|
|
\f[C]html\f[R], and (experimental) \f[C]json\f[R].
|
|
.SS balancesheetequity
|
|
.PP
|
|
balancesheetequity, bse
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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
|
|
The asset, liability and equity accounts shown are those accounts
|
|
declared with the \f[C]Asset\f[R], \f[C]Cash\f[R], \f[C]Liability\f[R]
|
|
or \f[C]Equity\f[R] type, or otherwise all accounts under a top-level
|
|
\f[C]asset\f[R], \f[C]liability\f[R] or \f[C]equity\f[R] account (case
|
|
insensitive, plurals allowed).
|
|
.PP
|
|
(This report is essentially similar to \[dq]hledger balance --historical
|
|
assets liabilities equity\[dq], with liabilities and equity
|
|
sign-flipped.)
|
|
.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 also supports the output destination and output format
|
|
options The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R],
|
|
\f[C]html\f[R], and (experimental) \f[C]json\f[R].
|
|
.SS cashflow
|
|
.PP
|
|
cashflow, cf
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
This command displays a cashflow statement, showing the inflows and
|
|
outflows affecting \[dq]cash\[dq] (ie, liquid) assets.
|
|
Amounts are shown with normal positive sign, as in conventional
|
|
financial statements.
|
|
.PP
|
|
The \[dq]cash\[dq] accounts shown are those accounts declared with the
|
|
\f[C]Cash\f[R] type, or otherwise all accounts under a top-level
|
|
\f[C]asset\f[R] account (case insensitive, plural allowed) which do not
|
|
have \f[C]fixed\f[R], \f[C]investment\f[R], \f[C]receivable\f[R] or
|
|
\f[C]A/R\f[R] in their name.
|
|
.PP
|
|
(This report is essentially similar to \[dq]hledger balance --change
|
|
assets not:fixed not:investment not:receivable\[dq].)
|
|
.PP
|
|
Example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger cashflow
|
|
Cashflow Statement
|
|
|
|
Cash flows:
|
|
$-1 assets
|
|
$1 bank:saving
|
|
$-2 cash
|
|
--------------------
|
|
$-1
|
|
|
|
Total:
|
|
--------------------
|
|
$-1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
With a reporting interval, multiple columns will be shown, one for each
|
|
report period.
|
|
Normally cashflow shows changes in assets per period, though as with
|
|
multicolumn balance reports you can alter the report mode with
|
|
\f[C]--change\f[R]/\f[C]--cumulative\f[R]/\f[C]--historical\f[R].
|
|
Instead of absolute values percentages can be displayed with
|
|
\f[C]-%\f[R].
|
|
.PP
|
|
This command also supports the output destination and output format
|
|
options The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R],
|
|
\f[C]html\f[R], and (experimental) \f[C]json\f[R].
|
|
.SS check
|
|
.PP
|
|
check
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Check for various kinds of errors in your data.
|
|
\f[I]experimental\f[R]
|
|
.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[C]check\f[R] command to run them on demand, with no output and a zero
|
|
exit code if all is well.
|
|
Some examples:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
hledger check # basic checks
|
|
hledger check -s # basic + strict checks
|
|
hledger check ordereddates uniqueleafnames # basic + specified checks
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Here are the checks currently available:
|
|
.SS Basic checks
|
|
.PP
|
|
These are always run by this command and other commands:
|
|
.IP \[bu] 2
|
|
\f[B]parseable\f[R] - data files are well-formed and can be successfully
|
|
parsed
|
|
.IP \[bu] 2
|
|
\f[B]autobalanced\f[R] - all transactions are balanced, inferring
|
|
missing amounts where necessary, and possibly converting commodities
|
|
using transaction prices or automatically-inferred transaction prices
|
|
.IP \[bu] 2
|
|
\f[B]assertions\f[R] - all balance assertions in the journal are
|
|
passing.
|
|
(This check can be disabled with
|
|
\f[C]-I\f[R]/\f[C]--ignore-assertions\f[R].)
|
|
.SS Strict checks
|
|
.PP
|
|
These are always run by this and other commands when
|
|
\f[C]-s\f[R]/\f[C]--strict\f[R] is used (strict mode):
|
|
.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
|
|
.SS Other checks
|
|
.PP
|
|
These checks can be run by specifying their names as arguments to the
|
|
check command:
|
|
.IP \[bu] 2
|
|
\f[B]ordereddates\f[R] - transactions are ordered by date (similar to
|
|
the old \f[C]check-dates\f[R] command)
|
|
.IP \[bu] 2
|
|
\f[B]uniqueleafnames\f[R] - all account leaf names are unique (similar
|
|
to the old \f[C]check-dupes\f[R] command)
|
|
.SS Add-on checks
|
|
.PP
|
|
Some checks are not yet integrated with this command, but are available
|
|
as 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 your own similar scripts to perform custom checks;
|
|
Cookbook -> Scripting may be helpful.
|
|
.SS close
|
|
.PP
|
|
close, equity
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Prints a \[dq]closing balances\[dq] transaction and an \[dq]opening
|
|
balances\[dq] transaction that bring account balances to and from zero,
|
|
respectively.
|
|
These can be added to your journal file(s), eg to bring asset/liability
|
|
balances forward into a new journal file, or to close out
|
|
revenues/expenses to retained earnings at the end of a period.
|
|
.PP
|
|
You can print just one of these transactions by using the
|
|
\f[C]--close\f[R] or \f[C]--open\f[R] flag.
|
|
You can customise their descriptions with the \f[C]--close-desc\f[R] and
|
|
\f[C]--open-desc\f[R] options.
|
|
.PP
|
|
One amountless posting to \[dq]equity:opening/closing balances\[dq] is
|
|
added to balance the transactions, by default.
|
|
You can customise this account name with \f[C]--close-acct\f[R] and
|
|
\f[C]--open-acct\f[R]; if you specify only one of these, it will be used
|
|
for both.
|
|
.PP
|
|
With \f[C]--x/--explicit\f[R], the equity posting\[aq]s amount will be
|
|
shown.
|
|
And if it involves multiple commodities, a posting for each commodity
|
|
will be shown, as with the print command.
|
|
.PP
|
|
With \f[C]--interleaved\f[R], the equity postings are shown next to the
|
|
postings they balance, which makes troubleshooting easier.
|
|
.PP
|
|
By default, transaction prices in the journal are ignored when
|
|
generating the closing/opening transactions.
|
|
With \f[C]--show-costs\f[R], this cost information is preserved
|
|
(\f[C]balance -B\f[R] reports will be unchanged after the transition).
|
|
Separate postings are generated for each cost in each commodity.
|
|
Note this can generate very large journal entries, if you have many
|
|
foreign currency or investment transactions.
|
|
.SS close usage
|
|
.PP
|
|
If you split your journal files by time (eg yearly), you will typically
|
|
run this command at the end of the year, and save the closing
|
|
transaction as last entry of the old file, and the opening transaction
|
|
as the first entry of the new file.
|
|
This makes the files self contained, so that correct balances are
|
|
reported no matter which of them are loaded.
|
|
Ie, if you load just one file, the balances are initialised correctly;
|
|
or if you load several files, the redundant closing/opening transactions
|
|
cancel each other out.
|
|
(They will show up in print or register reports; you can exclude them
|
|
with a query like
|
|
\f[C]not:desc:\[aq](opening|closing) balances\[aq]\f[R].)
|
|
.PP
|
|
If you\[aq]re running a business, you might also use this command to
|
|
\[dq]close the books\[dq] at the end of an accounting period,
|
|
transferring income statement account balances to retained earnings.
|
|
(You may want to change the equity account name to something like
|
|
\[dq]equity:retained earnings\[dq].)
|
|
.PP
|
|
By default, the closing transaction is dated yesterday, the balances are
|
|
calculated as of end of yesterday, and the opening transaction is dated
|
|
today.
|
|
To close on some other date, use:
|
|
\f[C]hledger close -e OPENINGDATE\f[R].
|
|
Eg, to close/open on the 2018/2019 boundary, use \f[C]-e 2019\f[R].
|
|
You can also use -p or \f[C]date:PERIOD\f[R] (any starting date is
|
|
ignored).
|
|
.PP
|
|
Both transactions will include balance assertions for the
|
|
closed/reopened accounts.
|
|
You probably shouldn\[aq]t use status or realness filters (like -C or -R
|
|
or \f[C]status:\f[R]) with this command, or the generated balance
|
|
assertions will depend on these flags.
|
|
Likewise, if you run this command with --auto, the balance assertions
|
|
will probably always require --auto.
|
|
.PP
|
|
Examples:
|
|
.PP
|
|
Carrying asset/liability balances into a new file for 2019:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger close -f 2018.journal -e 2019 assets liabilities --open
|
|
# (copy/paste the output to the start of your 2019 journal file)
|
|
$ hledger close -f 2018.journal -e 2019 assets liabilities --close
|
|
# (copy/paste the output to the end of your 2018 journal file)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Now:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger bs -f 2019.journal # one file - balances are correct
|
|
$ hledger bs -f 2018.journal -f 2019.journal # two files - balances still correct
|
|
$ hledger bs -f 2018.journal not:desc:closing # to see year-end balances, must exclude closing txn
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Transactions spanning the closing date can complicate matters, breaking
|
|
balance assertions:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2018/12/30 a purchase made in 2018, clearing the following year
|
|
expenses:food 5
|
|
assets:bank:checking -5 ; [2019/1/2]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Here\[aq]s one way to resolve that:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
; in 2018.journal:
|
|
2018/12/30 a purchase made in 2018, clearing the following year
|
|
expenses:food 5
|
|
liabilities:pending
|
|
|
|
; in 2019.journal:
|
|
2019/1/2 clearance of last year\[aq]s pending transactions
|
|
liabilities:pending 5 = 0
|
|
assets:checking
|
|
\f[R]
|
|
.fi
|
|
.SS codes
|
|
.PP
|
|
codes
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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[C]-E\f[R]/\f[C]--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]
|
|
1/1 (123)
|
|
(a) 1
|
|
|
|
1/1 ()
|
|
(a) 1
|
|
|
|
1/1
|
|
(a) 1
|
|
|
|
1/1 (126)
|
|
(a) 1
|
|
\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
|
|
commodities
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
List all commodity/currency symbols used or declared in the journal.
|
|
.SS descriptions
|
|
.PP
|
|
descriptions
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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
|
|
diff
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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
|
|
files
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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
|
|
help
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Show the hledger user manual in one of several formats, optionally
|
|
positioned at a given TOPIC (if possible).
|
|
TOPIC is any heading, or heading prefix, in the manual.
|
|
Some examples: commands, print, \[aq]auto postings\[aq], periodic.
|
|
.PP
|
|
This command shows the user manual built in to this hledger version.
|
|
It can be useful if the correct version of the hledger manual, or the
|
|
usual viewing tools, are not installed on your system.
|
|
.PP
|
|
By default it uses the best viewer it can find in $PATH, in this order:
|
|
\f[C]info\f[R], \f[C]man\f[R], $PAGER (unless a topic is specified),
|
|
\f[C]less\f[R], or stdout.
|
|
When run non-interactively, it always uses stdout.
|
|
Or you can select a particular viewer with the \f[C]-i\f[R] (info),
|
|
\f[C]-m\f[R] (man), or \f[C]-p\f[R] (pager) flags.
|
|
.SS import
|
|
.PP
|
|
import
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Read new transactions added to each FILE since last run, and add them to
|
|
the main journal file.
|
|
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
|
|
The input files are specified as arguments - no need to write -f before
|
|
each one.
|
|
So eg to add new transactions from all CSV files to the main journal,
|
|
it\[aq]s just: \f[C]hledger import *.csv\f[R]
|
|
.PP
|
|
New transactions are detected in the same way as print --new: by
|
|
assuming transactions are always added to the input files in increasing
|
|
date order, and by saving \f[C].latest.FILE\f[R] state files.
|
|
.PP
|
|
The --dry-run output is in journal format, so you can filter it, eg to
|
|
see only uncategorised transactions:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger import --dry ... | hledger -f- print unknown --ignore-assertions
|
|
\f[R]
|
|
.fi
|
|
.SS Importing balance assignments
|
|
.PP
|
|
Entries added by import will have their posting amounts made explicit
|
|
(like \f[C]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
|
|
incomestatement, is
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
.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
|
|
The revenue and expense accounts shown are those accounts declared with
|
|
the \f[C]Revenue\f[R] or \f[C]Expense\f[R] type, or otherwise all
|
|
accounts under a top-level \f[C]revenue\f[R] or \f[C]income\f[R] or
|
|
\f[C]expense\f[R] account (case insensitive, plurals allowed).
|
|
.PP
|
|
(This report is essentially similar to \[dq]hledger balance --change
|
|
revenues expenses\[dq], with revenues sign-flipped.)
|
|
.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
|
|
With a reporting interval, multiple columns will be shown, one for each
|
|
report period.
|
|
Normally incomestatement shows revenues/expenses per period, though as
|
|
with multicolumn balance reports you can alter the report mode with
|
|
\f[C]--change\f[R]/\f[C]--cumulative\f[R]/\f[C]--historical\f[R].
|
|
Instead of absolute values percentages can be displayed with
|
|
\f[C]-%\f[R].
|
|
.PP
|
|
This command also supports the output destination and output format
|
|
options The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R],
|
|
\f[C]html\f[R], and (experimental) \f[C]json\f[R].
|
|
.SS notes
|
|
.PP
|
|
notes
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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
|
|
payees
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
List the unique payee/payer names that appear in transactions.
|
|
.PP
|
|
This command lists the unique payee/payer names that appear in
|
|
transactions, in alphabetic order.
|
|
You can add a query to select a subset of transactions.
|
|
The payee/payer is the part of the transaction description before a |
|
|
character (or if there is no |, the whole description).
|
|
.PP
|
|
Example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger payees
|
|
Store Name
|
|
Gas Station
|
|
Person A
|
|
\f[R]
|
|
.fi
|
|
.SS prices
|
|
.PP
|
|
prices
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Print market price directives from the journal.
|
|
With --costs, also print synthetic market prices based on transaction
|
|
prices.
|
|
With --inverted-costs, also print inverse prices based on transaction
|
|
prices.
|
|
Prices (and postings providing prices) can be filtered by a query.
|
|
Price amounts are always displayed with their full precision.
|
|
.SS print
|
|
.PP
|
|
print
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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[C]--date2\f[R], by secondary
|
|
date).
|
|
Amounts are shown right-aligned within each transaction (but not across
|
|
all transactions).
|
|
Directives and inter-transaction comments are not shown.
|
|
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
|
|
Rounding amounts according to commodity display styles can cause
|
|
transactions to appear unbalanced.
|
|
.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.
|
|
.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 transaction price is implied but not written, it will
|
|
not appear in the output.
|
|
You can use the \f[C]-x\f[R]/\f[C]--explicit\f[R] flag to make all
|
|
amounts and transaction prices explicit, which can be useful for
|
|
troubleshooting or for making your journal more readable and robust
|
|
against data entry errors.
|
|
\f[C]-x\f[R] is also implied by using any of
|
|
\f[C]-B\f[R],\f[C]-V\f[R],\f[C]-X\f[R],\f[C]--value\f[R].
|
|
.PP
|
|
Note, \f[C]-x\f[R]/\f[C]--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[C]-B\f[R]/\f[C]--cost\f[R], amounts with transaction prices are
|
|
converted to cost using that price.
|
|
This can be used for troubleshooting.
|
|
.PP
|
|
With \f[C]-m\f[R]/\f[C]--match\f[R] and a STR argument, print will show
|
|
at most one transaction: the one one whose description is most similar
|
|
to STR, and is most recent.
|
|
STR should contain at least two characters.
|
|
If there is no similar-enough match, no transaction will be shown.
|
|
.PP
|
|
With \f[C]--new\f[R], for each FILE being read, hledger reads (and
|
|
writes) a special state file (\f[C].latest.FILE\f[R] in the same
|
|
directory), containing the latest transaction date(s) that were seen
|
|
last time FILE was read.
|
|
When this file is found, only transactions with newer dates (and new
|
|
transactions on the latest date) are printed.
|
|
This is useful for ignoring already-seen entries in import data, such as
|
|
downloaded CSV files.
|
|
Eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger -f bank1.csv print --new
|
|
(shows transactions added since last print --new on this file)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
This assumes that transactions added to FILE always have same or
|
|
increasing dates, and that transactions on the same day do not get
|
|
reordered.
|
|
See also the import command.
|
|
.PP
|
|
This command also supports the output destination and output format
|
|
options The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R],
|
|
and (experimental) \f[C]json\f[R] and \f[C]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 print-unique
|
|
.PP
|
|
print-unique
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Print transactions which do not reuse an already-seen description.
|
|
.PP
|
|
Example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ cat unique.journal
|
|
1/1 test
|
|
(acct:one) 1
|
|
2/2 test
|
|
(acct:two) 2
|
|
$ LEDGER_FILE=unique.journal hledger print-unique
|
|
(-f option not supported)
|
|
2015/01/01 test
|
|
(acct:one) 1
|
|
\f[R]
|
|
.fi
|
|
.SS register
|
|
.PP
|
|
register, reg
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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[C]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 --date2, it shows and sorts by secondary date instead.
|
|
.PP
|
|
The \f[C]--historical\f[R]/\f[C]-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[C]--depth\f[R] option limits the amount of sub-account detail
|
|
displayed.
|
|
.PP
|
|
The \f[C]--average\f[R]/\f[C]-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[C]--empty\f[R] (see below).
|
|
It is affected by \f[C]--historical\f[R].
|
|
It works best when showing just one account and one commodity.
|
|
.PP
|
|
The \f[C]--related\f[R]/\f[C]-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[C]--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[C]--empty\f[R]/\f[C]-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[C]--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.
|
|
.SS Custom register output
|
|
.PP
|
|
register uses the full terminal width by default, except on windows.
|
|
You can override this by setting the \f[C]COLUMNS\f[R] environment
|
|
variable (not a bash shell variable) or by using the
|
|
\f[C]--width\f[R]/\f[C]-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[C]--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[C]txt\f[R], \f[C]csv\f[R],
|
|
and (experimental) \f[C]json\f[R].
|
|
.SS register-match
|
|
.PP
|
|
register-match
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Print the one posting whose transaction description is closest to DESC,
|
|
in the style of the register command.
|
|
If there are multiple equally good matches, it shows the most recent.
|
|
Query options (options, not arguments) can be used to restrict the
|
|
search space.
|
|
Helps ledger-autosync detect already-seen transactions when importing.
|
|
.SS rewrite
|
|
.PP
|
|
rewrite
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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[C]--add-posting\f[R] option is a usual posting of
|
|
transaction with an exception for amount specification.
|
|
More precisely, you can use \f[C]\[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[C]\[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[C]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[C]--file\f[R] options and \f[C]include\f[R]
|
|
directives inside of these files.
|
|
.PP
|
|
Be careful.
|
|
Whole transaction being re-formatted in a style of output from
|
|
\f[C]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
|
|
roi
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Shows the time-weighted (TWR) and money-weighted (IRR) rate of return on
|
|
your investments.
|
|
.PP
|
|
This command assumes that you have account(s) that hold nothing but your
|
|
investments and whenever you record current appraisal/valuation of these
|
|
investments you offset unrealized profit and loss into account(s) that,
|
|
again, hold nothing but unrealized profit and loss.
|
|
.PP
|
|
Any transactions affecting balance of investment account(s) and not
|
|
originating from unrealized profit and loss account(s) are assumed to be
|
|
your investments or withdrawals.
|
|
.PP
|
|
At a minimum, you need to supply a query (which could be just an account
|
|
name) to select your investments with \f[C]--inv\f[R], and another query
|
|
to identify your profit and loss transactions with \f[C]--pnl\f[R].
|
|
.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
|
|
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 report unrealised gains:
|
|
https://github.com/simonmichael/hledger/blob/master/examples/roi-unrealised.ledger
|
|
.PP
|
|
More background:
|
|
.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 an
|
|
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 transactions that involve account(s) matching \f[C]--inv\f[R]
|
|
argument and NOT involve account(s) matching \f[C]--pnl\f[R] argument.
|
|
.PP
|
|
Presumably, you will also record changes in the value of your
|
|
investment, and balance them against \[dq]profit and loss\[dq] (or
|
|
\[dq]unrealized gains\[dq]) account.
|
|
Note that 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
|
|
Implementation of IRR in hledger should match the \f[C]XIRR\f[R] formula
|
|
in Excel.
|
|
.PP
|
|
Second way to compute rate of return that \f[C]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 and out-flows to compute rate of return per each period
|
|
and then a compound rate of return.
|
|
However, internal workings of TWR are quite different.
|
|
.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.
|
|
.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: * Explanation of rate of return * Explanation of IRR *
|
|
Explanation of TWR * Examples of computing IRR and TWR and discussion of
|
|
the limitations of both metrics
|
|
.PP
|
|
More examples:
|
|
.PP
|
|
Lets say that we found an investment in Snake Oil that is proising to
|
|
give us 10% annually:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2019-01-01 Investing in Snake Oil
|
|
assets:cash -$100
|
|
investment:snake oil
|
|
|
|
2019-12-24 Recording the growth of Snake Oil
|
|
investment:snake oil = $110
|
|
equity:unrealized gains
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
For now, basic computation of the rate of return, as well as IRR and
|
|
TWR, gives us the expected 10%:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger roi -Y --inv investment --pnl \[dq]unrealized\[dq]
|
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
|
+===++============+============++===============+==========+=============+=====++========+========+
|
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 110 | 10 || 10.00% | 10.00% |
|
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
However, lets say that shorty after investing in the Snake Oil we
|
|
started to have second thoughs, so we prompty withdrew $90, leaving only
|
|
$10 in.
|
|
Before Christmas, though, we started to get the \[dq]fear of mission
|
|
out\[dq], so we put the $90 back in.
|
|
So for most of the year, our investment was just $10 dollars, and it
|
|
gave us just $1 in growth:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2019-01-01 Investing in Snake Oil
|
|
assets:cash -$100
|
|
investment:snake oil
|
|
|
|
2019-01-02 Buyers remorse
|
|
assets:cash $90
|
|
investment:snake oil
|
|
|
|
2019-12-30 Fear of missing out
|
|
assets:cash -$90
|
|
investment:snake oil
|
|
|
|
2019-12-31 Recording the growth of Snake Oil
|
|
investment:snake oil = $101
|
|
equity:unrealized gains
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Now IRR and TWR are drastically different:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger roi -Y --inv investment --pnl \[dq]unrealized\[dq]
|
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
|
+===++============+============++===============+==========+=============+=====++=======+=======+
|
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 101 | 1 || 9.32% | 1.00% |
|
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Here, IRR tells us that we made close to 10% on the $10 dollars that we
|
|
had in the account most of the time.
|
|
And TWR is ...
|
|
just 1%?
|
|
Why?
|
|
.PP
|
|
Based on the transactions in our journal, TWR \[dq]think\[dq] that we
|
|
are buying back $90 worst of Snake Oil at the same price that it had at
|
|
the beginning of they year, and then after that our $100 investment gets
|
|
$1 increase in value, or 1% of $100.
|
|
Let\[aq]s take a closer look at what is happening here by asking for
|
|
quarterly reports instead of annual:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger roi -Q --inv investment --pnl \[dq]unrealized\[dq]
|
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
|
+===++============+============++===============+==========+=============+=====++========+=======+
|
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10 | 0 || 0.00% | 0.00% |
|
|
| 2 || 2019-04-01 | 2019-06-30 || 10 | 0 | 10 | 0 || 0.00% | 0.00% |
|
|
| 3 || 2019-07-01 | 2019-09-30 || 10 | 0 | 10 | 0 || 0.00% | 0.00% |
|
|
| 4 || 2019-10-01 | 2019-12-31 || 10 | 90 | 101 | 1 || 37.80% | 4.03% |
|
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Now both IRR and TWR are thrown off by the fact that all of the growth
|
|
for our investment happens in Q4 2019.
|
|
This happes because IRR computation is still yielding 9.32% and TWR is
|
|
still 1%, but this time these are rates for three month period instead
|
|
of twelve, so in order to get an annual rate they should be multiplied
|
|
by four!
|
|
.PP
|
|
Let\[aq]s try to keep a better record of how Snake Oil grew in value:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2019-01-01 Investing in Snake Oil
|
|
assets:cash -$100
|
|
investment:snake oil
|
|
|
|
2019-01-02 Buyers remorse
|
|
assets:cash $90
|
|
investment:snake oil
|
|
|
|
2019-02-28 Recording the growth of Snake Oil
|
|
investment:snake oil
|
|
equity:unrealized gains -$0.25
|
|
|
|
2019-06-30 Recording the growth of Snake Oil
|
|
investment:snake oil
|
|
equity:unrealized gains -$0.25
|
|
|
|
2019-09-30 Recording the growth of Snake Oil
|
|
investment:snake oil
|
|
equity:unrealized gains -$0.25
|
|
|
|
2019-12-30 Fear of missing out
|
|
assets:cash -$90
|
|
investment:snake oil
|
|
|
|
2019-12-31 Recording the growth of Snake Oil
|
|
investment:snake oil
|
|
equity:unrealized gains -$0.25
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Would our quartery report look better now?
|
|
Almost:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger roi -Q --inv investment --pnl \[dq]unrealized\[dq]
|
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
|
+===++============+============++===============+==========+=============+======++========+========+
|
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10.25 | 0.25 || 9.53% | 10.53% |
|
|
| 2 || 2019-04-01 | 2019-06-30 || 10.25 | 0 | 10.50 | 0.25 || 10.15% | 10.15% |
|
|
| 3 || 2019-07-01 | 2019-09-30 || 10.50 | 0 | 10.75 | 0.25 || 9.79% | 9.78% |
|
|
| 4 || 2019-10-01 | 2019-12-31 || 10.75 | 90 | 101.00 | 0.25 || 8.05% | 1.00% |
|
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Something is still wrong with TWR computation for Q4, and if you have
|
|
been paying attention you know what it is already: big $90 buy-back is
|
|
recorded prior to the only transaction that captures the change of value
|
|
of Snake Oil that happened in this time period.
|
|
Lets combine transactions from 30th and 31st of Dec into one:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2019-12-30 Fear of missing out and growth of Snake Oil
|
|
assets:cash -$90
|
|
investment:snake oil
|
|
equity:unrealized gains -$0.25
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Now growth of investment properly affects its price at the time of
|
|
buy-back:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger roi -Q --inv investment --pnl \[dq]unrealized\[dq]
|
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
|
+===++============+============++===============+==========+=============+======++========+========+
|
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10.25 | 0.25 || 9.53% | 10.53% |
|
|
| 2 || 2019-04-01 | 2019-06-30 || 10.25 | 0 | 10.50 | 0.25 || 10.15% | 10.15% |
|
|
| 3 || 2019-07-01 | 2019-09-30 || 10.50 | 0 | 10.75 | 0.25 || 9.79% | 9.78% |
|
|
| 4 || 2019-10-01 | 2019-12-31 || 10.75 | 90 | 101.00 | 0.25 || 8.05% | 9.57% |
|
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
And for annual report, TWR now reports the exact profitability of our
|
|
investment:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger roi -Y --inv investment --pnl \[dq]unrealized\[dq]
|
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
|
+===++============+============++===============+==========+=============+======++=======+========+
|
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 101.00 | 1.00 || 9.32% | 10.00% |
|
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
|
\f[R]
|
|
.fi
|
|
.SS stats
|
|
.PP
|
|
stats
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
Show some journal 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
|
|
Example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger stats
|
|
Main journal file : /src/hledger/examples/sample.journal
|
|
Included journal files :
|
|
Transactions span : 2008-01-01 to 2009-01-01 (366 days)
|
|
Last transaction : 2008-12-31 (2333 days ago)
|
|
Transactions : 5 (0.0 per day)
|
|
Transactions last 30 days: 0 (0.0 per day)
|
|
Transactions last 7 days : 0 (0.0 per day)
|
|
Payees/descriptions : 5
|
|
Accounts : 8 (depth 3)
|
|
Commodities : 1 ($)
|
|
Market prices : 12 ($)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
This command also supports output destination and output format
|
|
selection.
|
|
.SS tags
|
|
.PP
|
|
tags
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
List the unique tag names used in the journal.
|
|
With a TAGREGEX argument, only tag names matching the regular expression
|
|
(case insensitive) are shown.
|
|
With QUERY arguments, only transactions matching the query are
|
|
considered.
|
|
.PP
|
|
With the --values flag, the tags\[aq] unique values are listed instead.
|
|
.PP
|
|
With --parsed flag, all tags or values are shown in the order they are
|
|
parsed from the input data, including duplicates.
|
|
.PP
|
|
With -E/--empty, any blank/empty values will also be shown, otherwise
|
|
they are omitted.
|
|
.SS test
|
|
.PP
|
|
test
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
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[C]-- --help\f[R] currently doesn\[aq]t show them).
|
|
.SS About add-on commands
|
|
.PP
|
|
Add-on commands are programs or scripts in your PATH
|
|
.IP \[bu] 2
|
|
whose name starts with \f[C]hledger-\f[R]
|
|
.IP \[bu] 2
|
|
whose name ends with a recognised file extension:
|
|
\f[C].bat\f[R],\f[C].com\f[R],\f[C].exe\f[R],
|
|
\f[C].hs\f[R],\f[C].lhs\f[R],\f[C].pl\f[R],\f[C].py\f[R],\f[C].rb\f[R],\f[C].rkt\f[R],\f[C].sh\f[R]
|
|
or none
|
|
.IP \[bu] 2
|
|
and (on unix, mac) which are executable by the current user.
|
|
.PP
|
|
Add-ons are a relatively easy way to add local features or experiment
|
|
with new ideas.
|
|
They can be written in any language, but haskell scripts have a big
|
|
advantage: they can use the same hledger library functions that built-in
|
|
commands use for command-line options, parsing and reporting.
|
|
Some experimental/example add-on scripts can be found in the hledger
|
|
repo\[aq]s bin/ directory.
|
|
.PP
|
|
Note in a hledger command line, add-on command flags must have a double
|
|
dash (\f[C]--\f[R]) preceding them.
|
|
Eg you must write:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger web -- --serve
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
and not:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger web --serve
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
(because the \f[C]--serve\f[R] flag belongs to \f[C]hledger-web\f[R],
|
|
not \f[C]hledger\f[R]).
|
|
.PP
|
|
The \f[C]-h/--help\f[R] and \f[C]--version\f[R] flags don\[aq]t require
|
|
\f[C]--\f[R].
|
|
.PP
|
|
If you have any trouble with this, remember you can always run the
|
|
add-on program directly, eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger-web --serve
|
|
\f[R]
|
|
.fi
|
|
.SH JOURNAL FORMAT
|
|
.PP
|
|
hledger\[aq]s default file format, representing a General Journal.
|
|
.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[C].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 a compatible subset, mostly, of
|
|
ledger\[aq]s journal format, so hledger can work with compatible ledger
|
|
journal files as well.
|
|
It\[aq]s safe, and encouraged, to run both hledger and ledger on the
|
|
same journal file, eg to validate the results you\[aq]re getting.
|
|
.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).
|
|
These are mostly in the order you\[aq]ll use them, but in some cases
|
|
related concepts have been grouped together for easy reference, or
|
|
linked before they are introduced, so feel free to skip over anything
|
|
that looks unnecessary right now.
|
|
.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[C]!\f[R], or \f[C]*\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[C]YYYY-MM-DD\f[R] or \f[C]YYYY/MM/DD\f[R] or \f[C]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 default
|
|
year directive, or the current date when the command is run.
|
|
Some examples: \f[C]2010-01-31\f[R], \f[C]2010/01/31\f[R],
|
|
\f[C]2010.1.31\f[R], \f[C]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 Secondary dates
|
|
.PP
|
|
Real-life transactions sometimes involve more than one date - eg the
|
|
date you write a cheque, and the date it clears in your bank.
|
|
When you want to model this, for more accurate daily balances, you can
|
|
specify individual posting dates.
|
|
.PP
|
|
Or, you can use the older \f[I]secondary date\f[R] feature (Ledger calls
|
|
it auxiliary date or effective date).
|
|
Note: we support this for compatibility, but I usually recommend
|
|
avoiding this feature; posting dates are almost always clearer and
|
|
simpler.
|
|
.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[C]--date2\f[R] flag (or \f[C]--aux-date\f[R] or
|
|
\f[C]--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], as shown here:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2010/2/23=2/19 movie ticket
|
|
expenses:cinema $10
|
|
assets:checking
|
|
\f[R]
|
|
.fi
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger register checking
|
|
2010-02-23 movie ticket assets:checking $-10 $-10
|
|
\f[R]
|
|
.fi
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger register checking --date2
|
|
2010-02-19 movie ticket assets:checking $-10 $-10
|
|
\f[R]
|
|
.fi
|
|
.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[C]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.
|
|
You can set the secondary date similarly, with \f[C]date2:DATE2\f[R].
|
|
The \f[C]date:\f[R] or \f[C]date2:\f[R] tags must have a valid simple
|
|
date value if they are present, eg a \f[C]date:\f[R] tag with no value
|
|
is not allowed.
|
|
.PP
|
|
Ledger\[aq]s earlier, more compact bracketed date syntax is also
|
|
supported: \f[C][DATE]\f[R], \f[C][DATE=DATE2]\f[R] or
|
|
\f[C][=DATE2]\f[R].
|
|
hledger will attempt to parse any square-bracketed sequence of the
|
|
\f[C]0123456789/-.=\f[R] characters in this way.
|
|
With this syntax, DATE infers its year from the transaction and DATE2
|
|
infers its year from DATE.
|
|
.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[C]!\f[R]
|
|
T}@T{
|
|
pending
|
|
T}
|
|
T{
|
|
\f[C]*\f[R]
|
|
T}@T{
|
|
cleared
|
|
T}
|
|
.TE
|
|
.PP
|
|
When reporting, you can filter by status with the
|
|
\f[C]-U/--unmarked\f[R], \f[C]-P/--pending\f[R], and
|
|
\f[C]-C/--cleared\f[R] flags; or the \f[C]status:\f[R],
|
|
\f[C]status:!\f[R], and \f[C]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[C]-PC\f[R] to see the current balance
|
|
at your bank, \f[C]-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 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[C]|\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[C]|\f[R]) and an
|
|
additional note field on the right (after the first \f[C]|\f[R]).
|
|
This may be worthwhile if you need to do more precise querying and
|
|
pivoting by payee or by note.
|
|
.SS Comments
|
|
.PP
|
|
Lines in the journal beginning with a semicolon (\f[C];\f[R]) or hash
|
|
(\f[C]#\f[R]) or star (\f[C]*\f[R]) are comments, and will be ignored.
|
|
(Star comments cause org-mode nodes to be ignored, allowing emacs users
|
|
to fold and navigate their journals with org-mode or orgstruct-mode.)
|
|
.PP
|
|
You can attach comments to a transaction by writing them after the
|
|
description and/or indented on the following lines (before the
|
|
postings).
|
|
Similarly, you can attach comments to an individual posting by writing
|
|
them after the amount and/or indented on the following lines.
|
|
Transaction and posting comments must begin with a semicolon
|
|
(\f[C];\f[R]).
|
|
.PP
|
|
Some examples:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# a file comment
|
|
; another file comment
|
|
* also a file comment, useful in org/orgstruct mode
|
|
|
|
comment
|
|
A multiline file comment, which continues
|
|
until a line containing just \[dq]end comment\[dq]
|
|
(or end of file).
|
|
end comment
|
|
|
|
2012/5/14 something ; a transaction comment
|
|
; the transaction comment, continued
|
|
posting1 1 ; a comment for posting 1
|
|
posting2
|
|
; a comment for posting 2
|
|
; another comment line for posting 2
|
|
; a file comment (because not indented)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
You can also comment larger regions of a file using \f[C]comment\f[R]
|
|
and \f[C]end comment\f[R] directives.
|
|
.SS Tags
|
|
.PP
|
|
Tags are a way to add extra labels or labelled data to postings and
|
|
transactions, which you can then search or pivot on.
|
|
.PP
|
|
A simple tag is a word (which may contain hyphens) followed by a full
|
|
colon, written inside a transaction or posting comment line:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2017/1/16 bought groceries ; sometag:
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Tags can have a value, which is the text after the colon, up to the next
|
|
comma or end of line, with leading/trailing whitespace removed:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
expenses:food $10 ; a-posting-tag: the tag value
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Note this means hledger\[aq]s tag values can not contain commas or
|
|
newlines.
|
|
Ending at commas means you can write multiple short tags on one line,
|
|
comma separated:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
assets:checking ; a comment containing tag1:, tag2: some value ...
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Here,
|
|
.IP \[bu] 2
|
|
\[dq]\f[C]a comment containing\f[R]\[dq] is just comment text, not a tag
|
|
.IP \[bu] 2
|
|
\[dq]\f[C]tag1\f[R]\[dq] is a tag with no value
|
|
.IP \[bu] 2
|
|
\[dq]\f[C]tag2\f[R]\[dq] is another tag, whose value is
|
|
\[dq]\f[C]some value ...\f[R]\[dq]
|
|
.PP
|
|
Tags in a transaction comment affect the transaction and all of its
|
|
postings, while tags in a posting comment affect only that posting.
|
|
For example, the following transaction has three tags (\f[C]A\f[R],
|
|
\f[C]TAG2\f[R], \f[C]third-tag\f[R]) and the posting has four (those
|
|
plus \f[C]posting-tag\f[R]):
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1/1 a transaction ; A:, TAG2:
|
|
; third-tag: a third transaction tag, <- with a value
|
|
(a) $1 ; posting-tag:
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Tags are like Ledger\[aq]s metadata feature, except hledger\[aq]s tag
|
|
values are simple strings.
|
|
.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[C]!\f[R], or \f[C]*\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 Virtual postings
|
|
.PP
|
|
A posting with a parenthesised account name is called a \f[I]virtual
|
|
posting\f[R] or \f[I]unbalanced posting\f[R], which means it is exempt
|
|
from the usual rule that a transaction\[aq]s postings must balance add
|
|
up to zero.
|
|
.PP
|
|
This is not part of double entry accounting, so you might choose to
|
|
avoid this feature.
|
|
Or you can use it sparingly for certain special cases where it can be
|
|
convenient.
|
|
Eg, you could set opening balances without using a balancing equity
|
|
account:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1/1 opening balances
|
|
(assets:checking) $1000
|
|
(assets:savings) $2000
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
A posting with a bracketed account name is called a \f[I]balanced
|
|
virtual posting\f[R].
|
|
The balanced virtual postings in a transaction must add up to zero
|
|
(separately from other postings).
|
|
Eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1/1 buy food with cash, update budget envelope subaccounts, & something else
|
|
assets:cash $-10 ; <- these balance
|
|
expenses:food $7 ; <-
|
|
expenses:food $3 ; <-
|
|
[assets:checking:budget:food] $-10 ; <- and these balance
|
|
[assets:checking:available] $10 ; <-
|
|
(something:else) $5 ; <- not required to balance
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Ordinary non-parenthesised, non-bracketed postings are called \f[I]real
|
|
postings\f[R].
|
|
You can exclude virtual postings from reports with the
|
|
\f[C]-R/--real\f[R] flag or \f[C]real:1\f[R] query.
|
|
.SS Account names
|
|
.PP
|
|
Account names typically have several parts separated by a full colon,
|
|
from which hledger derives a hierarchical chart of accounts.
|
|
They can be anything you like, but in finance there are traditionally
|
|
five top-level accounts: \f[C]assets\f[R], \f[C]liabilities\f[R],
|
|
\f[C]income\f[R], \f[C]expenses\f[R], and \f[C]equity\f[R].
|
|
.PP
|
|
Account names may contain single spaces, eg:
|
|
\f[C]assets:accounts receivable\f[R].
|
|
Because of this, they must always be followed by \f[B]two or more
|
|
spaces\f[R] (or newline).
|
|
.PP
|
|
Account names can be aliased.
|
|
.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 or commodity name (the \[dq]commodity\[dq]).
|
|
This is a symbol, word, or phrase, to the left or right of the quantity,
|
|
with or without a separating space:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$1
|
|
4000 AAPL
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
If the commodity name contains spaces, numbers, or punctuation, it must
|
|
be enclosed in double quotes:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
3 \[dq]no. 42 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
|
|
.PP
|
|
A decimal mark can be written as a period or a comma:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1.23
|
|
1,23456780000009
|
|
\f[R]
|
|
.fi
|
|
.SS Digit group marks
|
|
.PP
|
|
In the integer part of the quantity (left of the decimal mark), groups
|
|
of digits can optionally be separated by a \[dq]digit group mark\[dq] -
|
|
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 group mark and no decimal mark is
|
|
ambiguous.
|
|
Are these group marks or decimal marks ?
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1,000
|
|
1.000
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
hledger will treat them both as decimal marks by default (cf #793).
|
|
If you use digit group marks, to prevent confusion and undetected typos
|
|
we recommend you write commodity directives at the top of the file to
|
|
explicitly declare the decimal mark (and optionally a digit group mark).
|
|
Note, these formats (\[dq]amount styles\[dq]) are specific to each
|
|
commodity, so if your data uses multiple formats, hledger can handle it:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
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.
|
|
(Excluding price amounts, which are always displayed as written).
|
|
The display style is chosen as follows:
|
|
.IP \[bu] 2
|
|
If there is a commodity directive (or default commodity directive) for
|
|
the commodity, its style is used (see examples above).
|
|
.IP \[bu] 2
|
|
Otherwise the style is inferred from the amounts in that commodity seen
|
|
in the journal.
|
|
.IP \[bu] 2
|
|
Or if there are no such amounts in the journal, a default style is used
|
|
(like \f[C]$1000.00\f[R]).
|
|
.PP
|
|
A style is inferred from the journal amounts in a commodity 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
|
|
Transaction price 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 transaction price).
|
|
If you find this causing problems, use a commodity directive to fix the
|
|
display style.
|
|
.PP
|
|
In summary, each commodity\[aq]s amounts will be normalised to
|
|
.IP \[bu] 2
|
|
the style declared by a \f[C]commodity\f[R] directive
|
|
.IP \[bu] 2
|
|
or, 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.
|
|
.PP
|
|
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 to set the
|
|
commodity\[aq]s display style.
|
|
For example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# declare euro, dollar and bitcoin commodities and set their display styles:
|
|
commodity EUR 1.000,
|
|
commodity $1000.00
|
|
commodity 1000.00000000 BTC
|
|
\f[R]
|
|
.fi
|
|
.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]).
|
|
(Guaranteed since hledger 1.17.1; in older versions this could vary if
|
|
hledger was built with Decimal < 0.5.1.)
|
|
.SS Transaction prices
|
|
.PP
|
|
Within a transaction, you can note an amount\[aq]s price in another
|
|
commodity.
|
|
This can be used to document the cost (in a purchase) or selling price
|
|
(in a sale).
|
|
For example, transaction prices are useful to record purchases of a
|
|
foreign currency.
|
|
Note transaction prices are fixed at the time of the transaction, and do
|
|
not change over time.
|
|
See also market prices, which represent prevailing exchange rates on a
|
|
certain date.
|
|
.PP
|
|
There are several ways to record a transaction price:
|
|
.IP "1." 3
|
|
Write the price per unit, as \f[C]\[at] UNITPRICE\f[R] after the amount:
|
|
.RS 4
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2009/1/1
|
|
assets:euros \[Eu]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[C]\[at]\[at] TOTALPRICE\f[R] after the
|
|
amount:
|
|
.RS 4
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2009/1/1
|
|
assets:euros \[Eu]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:
|
|
.RS 4
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2009/1/1
|
|
assets:euros \[Eu]100 ; one hundred euros purchased
|
|
assets:dollars $-135 ; for $135
|
|
\f[R]
|
|
.fi
|
|
.RE
|
|
.IP "4." 3
|
|
Like 1, but the \f[C]\[at]\f[R] is parenthesised, i.e.
|
|
\f[C](\[at])\f[R]; this is for compatibility with Ledger journals
|
|
(Virtual posting costs), and is equivalent to 1 in hledger.
|
|
.IP "5." 3
|
|
Like 2, but as in 4 the \f[C]\[at]\[at]\f[R] is parenthesised, i.e.
|
|
\f[C](\[at]\[at])\f[R]; in hledger, this is equivalent to 2.
|
|
.PP
|
|
Use the \f[C]-B/--cost\f[R] flag to convert amounts to their transaction
|
|
price\[aq]s commodity, if any.
|
|
(mnemonic: \[dq]B\[dq] is from \[dq]cost Basis\[dq], as in Ledger).
|
|
Eg here is how -B affects the balance report for the example above:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger bal -N --flat
|
|
$-135 assets:dollars
|
|
\[Eu]100 assets:euros
|
|
$ hledger bal -N --flat -B
|
|
$-135 assets:dollars
|
|
$135 assets:euros # <- the euros\[aq] cost
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Note -B is sensitive to the order of postings when a transaction price
|
|
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]
|
|
2009/1/1
|
|
assets:dollars $-135 ; 135 dollars sold
|
|
assets:euros \[Eu]100 ; for 100 euros
|
|
\f[R]
|
|
.fi
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger bal -N --flat -B
|
|
\[Eu]-100 assets:dollars # <- the dollars\[aq] selling price
|
|
\[Eu]100 assets:euros
|
|
\f[R]
|
|
.fi
|
|
.SS Lot prices, lot dates
|
|
.PP
|
|
Ledger allows another kind of price, lot price (four variants:
|
|
\f[C]{UNITPRICE}\f[R], \f[C]{{TOTALPRICE}}\f[R],
|
|
\f[C]{=FIXEDUNITPRICE}\f[R], \f[C]{{=FIXEDTOTALPRICE}}\f[R]), and/or a
|
|
lot date (\f[C][DATE]\f[R]) to be specified.
|
|
These are normally used to select a lot when selling investments.
|
|
hledger will parse these, for compatibility with Ledger journals, but
|
|
currently ignores them.
|
|
A transaction price, lot price and/or lot date may appear in any order,
|
|
after the posting amount and before the balance assertion if any.
|
|
.SS Balance assertions
|
|
.PP
|
|
hledger supports Ledger-style balance assertions in journal files.
|
|
These look like, for example, \f[C]= 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[C]-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, 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 included files
|
|
.PP
|
|
With included files, things are a little more complicated.
|
|
Including preserves the ordering of postings and assertions.
|
|
If you have multiple postings to an account on the same day, split
|
|
across different files, and you also want to assert the account\[aq]s
|
|
balance on the same day, you\[aq]ll have to put the assertion in the
|
|
right file.
|
|
.SS Assertions and multiple -f options
|
|
.PP
|
|
Balance assertions don\[aq]t work well across files specified with
|
|
multiple -f options.
|
|
Use include or concatenate the files instead.
|
|
.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[C]== EXPECTEDBALANCE\f[R]).
|
|
This asserts that there are no other unasserted commodities in the
|
|
account (or, that their balance is 0).
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2013/1/1
|
|
a $1
|
|
a 1\[Eu]
|
|
b $-1
|
|
c -1\[Eu]
|
|
|
|
2013/1/2 ; These assertions succeed
|
|
a 0 = $1
|
|
a 0 = 1\[Eu]
|
|
b 0 == $-1
|
|
c 0 == -1\[Eu]
|
|
|
|
2013/1/3 ; This assertion fails as \[aq]a\[aq] also contains 1\[Eu]
|
|
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\[Eu]
|
|
b
|
|
|
|
2013/1/2
|
|
a 0 == 0
|
|
a:usd 0 == $1
|
|
a:euro 0 == 1\[Eu]
|
|
\f[R]
|
|
.fi
|
|
.SS Assertions and prices
|
|
.PP
|
|
Balance assertions ignore transaction prices, and should normally be
|
|
written without one:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2019/1/1
|
|
(a) $1 \[at] \[Eu]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[C]=\f[R] and \f[C]==\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[C]=*\f[R]
|
|
or \f[C]==*\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 are checked against all postings, both real and
|
|
virtual.
|
|
They are not affected by the \f[C]--real/-R\f[R] flag or \f[C]real:\f[R]
|
|
query.
|
|
.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 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).
|
|
Note that using balance assignments makes your journal a little less
|
|
explicit; to know the exact amount posted, you have to run hledger or do
|
|
the calculations yourself, instead of just reading it.
|
|
.SS Balance assignments and prices
|
|
.PP
|
|
A transaction price in a balance assignment will cause the calculated
|
|
amount to have that price attached:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2019/1/1
|
|
(a) = $1 \[at] \[Eu]2
|
|
\f[R]
|
|
.fi
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger print --explicit
|
|
2019-01-01
|
|
(a) $1 \[at] \[Eu]2 = $1 \[at] \[Eu]2
|
|
\f[R]
|
|
.fi
|
|
.SS Directives
|
|
.PP
|
|
A directive is a line in the journal beginning with a special keyword,
|
|
that influences how the journal is processed.
|
|
hledger\[aq]s directives are based on a subset of Ledger\[aq]s, but
|
|
there are many differences (and also some differences between hledger
|
|
versions).
|
|
.PP
|
|
Directives\[aq] behaviour and interactions can get a little bit complex,
|
|
so here is a table summarising the directives and their effects, with
|
|
links to more detailed docs.
|
|
Note part of this table is hidden when viewed in a web browser - scroll
|
|
it sideways to see more.
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(7.8n) lw(8.6n) lw(7.0n) lw(27.8n) lw(18.8n).
|
|
T{
|
|
directive
|
|
T}@T{
|
|
end directive
|
|
T}@T{
|
|
subdirectives
|
|
T}@T{
|
|
purpose
|
|
T}@T{
|
|
can affect (as of 2018/06)
|
|
T}
|
|
_
|
|
T{
|
|
\f[C]account\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
any text
|
|
T}@T{
|
|
document account names, declare account types & display order
|
|
T}@T{
|
|
all entries in all files, before or after
|
|
T}
|
|
T{
|
|
\f[C]alias\f[R]
|
|
T}@T{
|
|
\f[C]end aliases\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
rewrite account names
|
|
T}@T{
|
|
following entries until end of current file or end directive
|
|
T}
|
|
T{
|
|
\f[C]apply account\f[R]
|
|
T}@T{
|
|
\f[C]end apply account\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
prepend a common parent to account names
|
|
T}@T{
|
|
following entries until end of current file or end directive
|
|
T}
|
|
T{
|
|
\f[C]comment\f[R]
|
|
T}@T{
|
|
\f[C]end comment\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
ignore part of journal
|
|
T}@T{
|
|
following entries until end of current file or end directive
|
|
T}
|
|
T{
|
|
\f[C]commodity\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
\f[C]format\f[R]
|
|
T}@T{
|
|
declare a commodity and its number notation & display style
|
|
T}@T{
|
|
number notation: following entries in that commodity in all files ;
|
|
display style: amounts of that commodity in reports
|
|
T}
|
|
T{
|
|
\f[C]D\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
T}@T{
|
|
declare a commodity to be used for commodityless amounts, and its number
|
|
notation & display style
|
|
T}@T{
|
|
default commodity: following commodityless entries until end of current
|
|
file; number notation: following entries in that commodity until end of
|
|
current file; display style: amounts of that commodity in reports
|
|
T}
|
|
T{
|
|
\f[C]include\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
T}@T{
|
|
include entries/directives from another file
|
|
T}@T{
|
|
what the included directives affect
|
|
T}
|
|
T{
|
|
\f[C]P\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
T}@T{
|
|
declare a market price for a commodity
|
|
T}@T{
|
|
amounts of that commodity in reports, when -V is used
|
|
T}
|
|
T{
|
|
\f[C]Y\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
T}@T{
|
|
declare a year for yearless dates
|
|
T}@T{
|
|
following entries until end of current file
|
|
T}
|
|
T{
|
|
\f[C]=\f[R]
|
|
T}@T{
|
|
T}@T{
|
|
T}@T{
|
|
declare an auto posting rule, adding postings to other transactions
|
|
T}@T{
|
|
all entries in parent/current/child files (but not sibling files, see
|
|
#1212)
|
|
T}
|
|
.TE
|
|
.PP
|
|
And some definitions:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(6.0n) lw(64.0n).
|
|
T{
|
|
subdirective
|
|
T}@T{
|
|
optional indented directive line immediately following a parent
|
|
directive
|
|
T}
|
|
T{
|
|
number notation
|
|
T}@T{
|
|
how to interpret numbers when parsing journal entries (the identity of
|
|
the decimal separator character).
|
|
(Currently each commodity can have its own notation, even in the same
|
|
file.)
|
|
T}
|
|
T{
|
|
display style
|
|
T}@T{
|
|
how to display amounts of a commodity in reports (symbol side and
|
|
spacing, digit groups, decimal separator, decimal places)
|
|
T}
|
|
T{
|
|
directive scope
|
|
T}@T{
|
|
which entries and (when there are multiple files) which files are
|
|
affected by a directive
|
|
T}
|
|
.TE
|
|
.PP
|
|
As you can see, directives vary in which journal entries and files they
|
|
affect, and whether they are focussed on input (parsing) or output
|
|
(reports).
|
|
Some directives have multiple effects.
|
|
.SS Directives and multiple files
|
|
.PP
|
|
If you use multiple \f[C]-f\f[R]/\f[C]--file\f[R] options, or the
|
|
\f[C]include\f[R] directive, hledger will process multiple input files.
|
|
But note that directives which affect input (see above) typically last
|
|
only until the end of the file in which they occur.
|
|
.PP
|
|
This may seem inconvenient, but it\[aq]s intentional; it makes reports
|
|
stable and deterministic, independent of the order of input.
|
|
Otherwise you could see different numbers if you happened to write -f
|
|
options in a different order, or if you moved includes around while
|
|
cleaning up your files.
|
|
.PP
|
|
It can be surprising though; for example, it means that \f[C]alias\f[R]
|
|
directives do not affect parent or sibling files (see below).
|
|
.SS Comment blocks
|
|
.PP
|
|
A line containing just \f[C]comment\f[R] starts a commented region of
|
|
the file, and a line containing just \f[C]end comment\f[R] (or the end
|
|
of the current file) ends it.
|
|
See also comments.
|
|
.SS Including other files
|
|
.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[C]include \[ti]/main.journal\f[R].
|
|
.PP
|
|
The path may contain glob patterns to match multiple files, eg:
|
|
\f[C]include *.journal\f[R].
|
|
.PP
|
|
There is limited support for recursive wildcards: \f[C]**/\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[C]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[C]include timedot:\[ti]/notes/2020*.md\f[R].
|
|
.SS Default year
|
|
.PP
|
|
You can set a default year to be used for subsequent dates which
|
|
don\[aq]t specify a year.
|
|
This is a line beginning with \f[C]Y\f[R] followed by the year.
|
|
Eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Y2009 ; set default year to 2009
|
|
|
|
12/15 ; equivalent to 2009/12/15
|
|
expenses 1
|
|
assets
|
|
|
|
Y2010 ; 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
|
|
.SS Declaring commodities
|
|
.PP
|
|
The \f[C]commodity\f[R] directive has several functions:
|
|
.IP "1." 3
|
|
It declares commodities which may be used in the journal.
|
|
This is currently not enforced, but can serve as documentation.
|
|
.IP "2." 3
|
|
It declares what 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[C]1,000\f[R] and
|
|
\f[C]1.000\f[R] as 1).
|
|
.IP "3." 3
|
|
It declares a commodity\[aq]s display style in output - decimal and
|
|
digit group marks, number of decimal places, symbol placement etc.
|
|
.PP
|
|
You are likely to run into one of the problems solved by commodity
|
|
directives, sooner or later, so it\[aq]s a good idea to just always use
|
|
them to declare your commodities.
|
|
.PP
|
|
A commodity directive is just the word \f[C]commodity\f[R] followed by
|
|
an amount.
|
|
It may be written on a single line, like this:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
; commodity EXAMPLEAMOUNT
|
|
|
|
; display AAAA amounts with the symbol on the right, space-separated,
|
|
; using period as decimal point, with four decimal places, and
|
|
; separating thousands with comma.
|
|
commodity 1,000.0000 AAAA
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
or on multiple lines, using the \[dq]format\[dq] subdirective.
|
|
(In this case the commodity symbol appears twice and should be the same
|
|
in both places.):
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
; commodity SYMBOL
|
|
; format EXAMPLEAMOUNT
|
|
|
|
; 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
|
|
The quantity of the amount does not matter; only the format is
|
|
significant.
|
|
The number must include a decimal mark: either a period or a comma,
|
|
followed by 0 or more decimal digits.
|
|
.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.)
|
|
.SS Commodity error checking
|
|
.PP
|
|
In strict mode, enabled with the \f[C]-s\f[R]/\f[C]--strict\f[R] flag,
|
|
hledger will report an error if a commodity symbol is used that has not
|
|
been declared by a \f[C]commodity\f[R] directive.
|
|
This works similarly to account error checking, see the notes there for
|
|
more details.
|
|
.SS Default commodity
|
|
.PP
|
|
The \f[C]D\f[R] directive sets a default commodity, to be used for
|
|
amounts without a commodity symbol (ie, plain numbers).
|
|
This commodity will be applied to all subsequent commodity-less amounts,
|
|
or until the next \f[C]D\f[R] directive.
|
|
(Note, this is different from Ledger\[aq]s \f[C]D\f[R].)
|
|
.PP
|
|
For compatibility/historical reasons, \f[C]D\f[R] also acts like a
|
|
\f[C]commodity\f[R] directive, setting the commodity\[aq]s display style
|
|
(for output) and decimal mark (for parsing input).
|
|
As with \f[C]commodity\f[R], the amount must always be written with a
|
|
decimal mark (period or comma).
|
|
If both directives are used, \f[C]commodity\f[R]\[aq]s style takes
|
|
precedence.
|
|
.PP
|
|
The syntax is \f[C]D AMOUNT\f[R].
|
|
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
|
|
.SS Declaring market prices
|
|
.PP
|
|
The \f[C]P\f[R] directive declares a market price, which is an exchange
|
|
rate between two commodities on a certain date.
|
|
(In Ledger, they are called \[dq]historical prices\[dq].) These are
|
|
often obtained from a stock exchange, cryptocurrency exchange, or the
|
|
foreign exchange market.
|
|
.PP
|
|
Here is the format:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
P DATE COMMODITYA COMMODITYBAMOUNT
|
|
\f[R]
|
|
.fi
|
|
.IP \[bu] 2
|
|
DATE is a simple date
|
|
.IP \[bu] 2
|
|
COMMODITYA is the symbol of the commodity being priced
|
|
.IP \[bu] 2
|
|
COMMODITYBAMOUNT is an amount (symbol and quantity) in a second
|
|
commodity, giving the price in commodity B of one unit of commodity A.
|
|
.PP
|
|
These two market price directives say that one euro was worth 1.35 US
|
|
dollars during 2009, and $1.40 from 2010 onward:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
P 2009/1/1 \[Eu] $1.35
|
|
P 2010/1/1 \[Eu] $1.40
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
The \f[C]-V\f[R], \f[C]-X\f[R] and \f[C]--value\f[R] flags use these
|
|
market prices to show amount values in another commodity.
|
|
See Valuation.
|
|
.SS Declaring accounts
|
|
.PP
|
|
\f[C]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
|
|
They can help hledger know your accounts\[aq] types (asset, liability,
|
|
equity, revenue, expense), useful for reports like balancesheet and
|
|
incomestatement.
|
|
.IP \[bu] 2
|
|
They control account display order in reports, allowing non-alphabetic
|
|
sorting (eg Revenues to appear above Expenses).
|
|
.IP \[bu] 2
|
|
They can store extra information about accounts (account numbers, notes,
|
|
etc.)
|
|
.IP \[bu] 2
|
|
They help with account name completion in the add command, hledger-iadd,
|
|
hledger-web, ledger-mode etc.
|
|
.IP \[bu] 2
|
|
In strict mode, they restrict which accounts may be posted to by
|
|
transactions, which helps detect typos.
|
|
.PP
|
|
The simplest form is just the word \f[C]account\f[R] followed by a
|
|
hledger-style account name, eg this account directive declares the
|
|
\f[C]assets:bank:checking\f[R] account:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
account assets:bank:checking
|
|
\f[R]
|
|
.fi
|
|
.SS Account error checking
|
|
.PP
|
|
By default, accounts come into existence when a transaction references
|
|
them by name.
|
|
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 the error later, as an extra account in balance
|
|
reports, or an incorrect balance when reconciling.
|
|
.PP
|
|
In strict mode, enabled with the \f[C]-s\f[R]/\f[C]--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[C]journal\f[R] files (but will
|
|
affect included files in other formats).
|
|
.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 comments
|
|
.PP
|
|
Comments, beginning with a semicolon, can be added:
|
|
.IP \[bu] 2
|
|
on the same line, \f[B]after two or more spaces\f[R] (because ; is
|
|
allowed in account names)
|
|
.IP \[bu] 2
|
|
on the next lines, indented
|
|
.PP
|
|
An example of both:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
account assets:bank:checking ; same-line comment, note 2+ spaces before ;
|
|
; next-line comment
|
|
; another with tag, acctno:12345 (not used yet)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Same-line comments are not supported by Ledger, or hledger <1.13.
|
|
.SS Account subdirectives
|
|
.PP
|
|
We also allow (and ignore) Ledger-style indented subdirectives, just for
|
|
compatibility.:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
account assets:bank:checking
|
|
format blah blah ; <- subdirective, ignored
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Here is the full syntax of account directives:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
account ACCTNAME [ACCTTYPE] [;COMMENT]
|
|
[;COMMENTS]
|
|
[LEDGER-STYLE SUBDIRECTIVES, IGNORED]
|
|
\f[R]
|
|
.fi
|
|
.SS Account types
|
|
.PP
|
|
hledger recognises five main types of account, corresponding to the
|
|
account classes in the accounting equation:
|
|
.PP
|
|
\f[C]Asset\f[R], \f[C]Liability\f[R], \f[C]Equity\f[R],
|
|
\f[C]Revenue\f[R], \f[C]Expense\f[R].
|
|
.PP
|
|
These account types are important for controlling which accounts appear
|
|
in the balancesheet, balancesheetequity, incomestatement reports (and
|
|
probably for other things in future).
|
|
.PP
|
|
Additionally, we recognise the \f[C]Cash\f[R] type, which is also an
|
|
\f[C]Asset\f[R], and which causes accounts to appear in the cashflow
|
|
report.
|
|
(\[dq]Cash\[dq] here means liquid assets, eg bank balances but typically
|
|
not investments or receivables.)
|
|
.SS Declaring account types
|
|
.PP
|
|
Generally, to make these reports work you should declare your top-level
|
|
accounts and their types, using account directives with \f[C]type:\f[R]
|
|
tags.
|
|
.PP
|
|
The tag\[aq]s value should be one of: \f[C]Asset\f[R],
|
|
\f[C]Liability\f[R], \f[C]Equity\f[R], \f[C]Revenue\f[R],
|
|
\f[C]Expense\f[R], \f[C]Cash\f[R], \f[C]A\f[R], \f[C]L\f[R],
|
|
\f[C]E\f[R], \f[C]R\f[R], \f[C]X\f[R], \f[C]C\f[R] (all case
|
|
insensitive).
|
|
The type is inherited by all subaccounts except where they override it.
|
|
Here\[aq]s a complete example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
account assets ; type: Asset
|
|
account assets:bank ; type: Cash
|
|
account assets:cash ; type: Cash
|
|
account liabilities ; type: Liability
|
|
account equity ; type: Equity
|
|
account revenues ; type: Revenue
|
|
account expenses ; type: Expense
|
|
\f[R]
|
|
.fi
|
|
.SS Auto-detected account types
|
|
.PP
|
|
If you happen to use common english top-level account names, you may not
|
|
need to declare account types, as they will be detected automatically
|
|
using the following rules:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l l.
|
|
T{
|
|
If name matches regular expression:
|
|
T}@T{
|
|
account type is:
|
|
T}
|
|
_
|
|
T{
|
|
\f[C]\[ha]assets?(:|$)\f[R]
|
|
T}@T{
|
|
\f[C]Asset\f[R]
|
|
T}
|
|
T{
|
|
\f[C]\[ha](debts?|liabilit(y|ies))(:|$)\f[R]
|
|
T}@T{
|
|
\f[C]Liability\f[R]
|
|
T}
|
|
T{
|
|
\f[C]\[ha]equity(:|$)\f[R]
|
|
T}@T{
|
|
\f[C]Equity\f[R]
|
|
T}
|
|
T{
|
|
\f[C]\[ha](income|revenue)s?(:|$)\f[R]
|
|
T}@T{
|
|
\f[C]Revenue\f[R]
|
|
T}
|
|
T{
|
|
\f[C]\[ha]expenses?(:|$)\f[R]
|
|
T}@T{
|
|
\f[C]Expense\f[R]
|
|
T}
|
|
.TE
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(56.9n) lw(13.1n).
|
|
T{
|
|
If account type is \f[C]Asset\f[R] and name does not contain regular
|
|
expression:
|
|
T}@T{
|
|
account type is:
|
|
T}
|
|
_
|
|
T{
|
|
\f[C](investment|receivable|:A/R|:fixed)\f[R]
|
|
T}@T{
|
|
\f[C]Cash\f[R]
|
|
T}
|
|
.TE
|
|
.PP
|
|
Even so, explicit declarations may be a good idea, for clarity and
|
|
predictability.
|
|
.SS Interference from auto-detected account types
|
|
.PP
|
|
If you assign any account type, it\[aq]s a good idea to assign all of
|
|
them, to prevent any confusion from mixing declared and auto-detected
|
|
types.
|
|
Although it\[aq]s unlikely to happen in real life, here\[aq]s an
|
|
example: with the following journal, \f[C]balancesheetequity\f[R] shows
|
|
\[dq]liabilities\[dq] in both Liabilities and Equity sections.
|
|
Declaring another account as \f[C]type:Liability\f[R] would fix it:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
account liabilities ; type:Equity
|
|
|
|
2020-01-01
|
|
assets 1
|
|
liabilities 1
|
|
equity -2
|
|
\f[R]
|
|
.fi
|
|
.SS Old account type syntax
|
|
.PP
|
|
In some hledger journals you might instead see this old syntax (the
|
|
letters ALERX, separated from the account name by two or more spaces);
|
|
this is deprecated and may be removed soon:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
account assets A
|
|
account liabilities L
|
|
account equity E
|
|
account revenues R
|
|
account expenses X
|
|
\f[R]
|
|
.fi
|
|
.SS Account display order
|
|
.PP
|
|
Account directives also set the order in which accounts are displayed,
|
|
eg in reports, the hledger-ui accounts screen, and the hledger-web
|
|
sidebar.
|
|
By default accounts are listed in alphabetical order.
|
|
But if you have these account directives in the journal:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
account assets
|
|
account liabilities
|
|
account equity
|
|
account revenues
|
|
account expenses
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
you\[aq]ll see those accounts displayed in declaration order, not
|
|
alphabetically:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger accounts -1
|
|
assets
|
|
liabilities
|
|
equity
|
|
revenues
|
|
expenses
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Undeclared accounts, if any, are displayed last, in alphabetical order.
|
|
.PP
|
|
Note that 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[C]zoo\f[R] among
|
|
\f[C]other\f[R]\[aq]s subaccounts, but not the position of
|
|
\f[C]other\f[R] among the top-level accounts.
|
|
This means:
|
|
.IP \[bu] 2
|
|
you will sometimes declare parent accounts (eg \f[C]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[C]x:y\f[R]
|
|
in between \f[C]a:b\f[R] and \f[C]a:c\f[R]).
|
|
.SS Rewriting accounts
|
|
.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 or
|
|
combining two accounts into one
|
|
.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
|
|
See also Rewrite account names.
|
|
.SS Basic aliases
|
|
.PP
|
|
To set an account alias, use the \f[C]alias\f[R] directive in your
|
|
journal file.
|
|
This affects all subsequent journal entries in the current file or its
|
|
included files.
|
|
The spaces around the = are optional:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
alias OLD = NEW
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Or, you can use the \f[C]--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 the forward slashes:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
alias /REGEX/ = REPLACEMENT
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
or \f[C]--alias \[aq]/REGEX/=REPLACEMENT\[aq]\f[R].
|
|
.PP
|
|
REGEX is a case-insensitive regular expression.
|
|
Anywhere it matches inside an account name, the matched part will be
|
|
replaced by REPLACEMENT.
|
|
If REGEX contains parenthesised match groups, these can be referenced by
|
|
the usual numeric backreferences in REPLACEMENT.
|
|
Eg:
|
|
.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
|
|
Also note that 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[C]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[C]--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[C]--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[C]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
|
|
|
|
2020-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
|
|
|
|
2020-01-01 ; affected by aliases above
|
|
foo 1
|
|
bar
|
|
|
|
include c.journal ; also affected
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]end aliases\f[R]
|
|
.PP
|
|
You can clear (forget) all currently defined aliases with the
|
|
\f[C]end aliases\f[R] directive:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
end aliases
|
|
\f[R]
|
|
.fi
|
|
.SS Default parent account
|
|
.PP
|
|
You can specify a parent account which will be prepended to all accounts
|
|
within a section of the journal.
|
|
Use the \f[C]apply account\f[R] and \f[C]end apply account\f[R]
|
|
directives like so:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
apply account home
|
|
|
|
2010/1/1
|
|
food $10
|
|
cash
|
|
|
|
end apply account
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
which is equivalent to:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2010/01/01
|
|
home:food $10
|
|
home:cash $-10
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
If \f[C]end apply account\f[R] is omitted, the effect lasts to the end
|
|
of the file.
|
|
Included files are also affected, eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
apply account business
|
|
include biz.journal
|
|
end apply account
|
|
apply account personal
|
|
include personal.journal
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Prior to hledger 1.0, legacy \f[C]account\f[R] and \f[C]end\f[R]
|
|
spellings were also supported.
|
|
.PP
|
|
A default parent account also affects account directives.
|
|
It does not affect account names being entered via hledger add or
|
|
hledger-web.
|
|
If account aliases are present, they are applied after the default
|
|
parent account.
|
|
.SS Periodic transactions
|
|
.PP
|
|
Periodic transaction rules describe transactions that recur.
|
|
They allow hledger to generate temporary future transactions to help
|
|
with forecasting, so you don\[aq]t have to write out each one in the
|
|
journal, and it\[aq]s easy to try out different forecasts.
|
|
.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[C]hledger print --forecast tag:generated\f[R] or
|
|
\f[C]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[C]weekly from DATE\f[R], DATE must be a monday.
|
|
\f[C]\[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[C]\[ti] every 10th day of month from 2020/01\f[R], which is
|
|
equivalent to \f[C]\[ti] every 10th day of month from 2020/01/01\f[R],
|
|
will be adjusted to start on 2019/12/10.
|
|
.PP
|
|
Periodic transaction rules also have a second meaning: they are used to
|
|
define budget goals, shown in budget reports.
|
|
.SS Periodic rule syntax
|
|
.PP
|
|
A periodic transaction rule looks like a normal journal entry, with the
|
|
date replaced by a tilde (\f[C]\[ti]\f[R]) followed by a period
|
|
expression (mnemonic: \f[C]\[ti]\f[R] looks like a recurring sine
|
|
wave.):
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\[ti] monthly
|
|
expenses:rent $2000
|
|
assets:bank:checking
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
There is an additional constraint on the period expression: the start
|
|
date must fall on a natural boundary of the interval.
|
|
Eg \f[C]monthly from 2018/1/1\f[R] is valid, but
|
|
\f[C]monthly from 2018/1/15\f[R] is not.
|
|
.PP
|
|
Partial or relative dates (M/D, D, tomorrow, last week) in the period
|
|
expression can work (useful or not).
|
|
They will be relative to today\[aq]s date, unless a Y default year
|
|
directive is in effect, in which case they will be relative to Y/1/1.
|
|
.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 2020\[dq]
|
|
; ||
|
|
; vv
|
|
\[ti] every 2 months in 2020, 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 Forecasting with periodic transactions
|
|
.PP
|
|
The \f[C]--forecast\f[R] flag activates any periodic transaction rules
|
|
in the journal.
|
|
They will generate temporary recurring transactions, which are not saved
|
|
in the journal, but will appear in all reports (eg print).
|
|
This can be useful for estimating balances into the future, or
|
|
experimenting with different scenarios.
|
|
Or, it can be used as a data entry aid: describe recurring transactions,
|
|
and every so often copy the output of \f[C]print --forecast\f[R] into
|
|
the journal.
|
|
.PP
|
|
These transactions will have an extra tag indicating which periodic rule
|
|
generated them: \f[C]generated-transaction:\[ti] PERIODICEXPR\f[R].
|
|
And a similar, hidden tag (beginning with an underscore) which, because
|
|
it\[aq]s never displayed by print, can be used to match transactions
|
|
generated \[dq]just now\[dq]:
|
|
\f[C]_generated-transaction:\[ti] PERIODICEXPR\f[R].
|
|
.PP
|
|
Periodic transactions are generated within some forecast period.
|
|
By default, this
|
|
.IP \[bu] 2
|
|
begins on the later of
|
|
.RS 2
|
|
.IP \[bu] 2
|
|
the report start date if specified with -b/-p/date:
|
|
.IP \[bu] 2
|
|
the day after the latest normal (non-periodic) transaction in the
|
|
journal, or today if there are no normal transactions.
|
|
.RE
|
|
.IP \[bu] 2
|
|
ends on the report end date if specified with -e/-p/date:, or 6 months
|
|
(180 days) from today.
|
|
.PP
|
|
This means that periodic transactions will begin only after the latest
|
|
recorded transaction.
|
|
And a recorded transaction dated in the future can prevent generation of
|
|
periodic transactions.
|
|
(You can avoid that by writing the future transaction as a one-time
|
|
periodic rule instead - put tilde before the date, eg
|
|
\f[C]\[ti] YYYY-MM-DD ...\f[R]).
|
|
.PP
|
|
Or, you can set your own arbitrary \[dq]forecast period\[dq], which can
|
|
overlap recorded transactions, and need not be in the future, by
|
|
providing an option argument, like \f[C]--forecast=PERIODEXPR\f[R].
|
|
Note the equals sign is required, a space won\[aq]t work.
|
|
PERIODEXPR is a period expression, which can specify the start date, end
|
|
date, or both, like in a \f[C]date:\f[R] query.
|
|
(See also hledger.1 -> Report start & end date).
|
|
Some examples: \f[C]--forecast=202001-202004\f[R],
|
|
\f[C]--forecast=jan-\f[R], \f[C]--forecast=2020\f[R].
|
|
.SS Budgeting with periodic transactions
|
|
.PP
|
|
With the \f[C]--budget\f[R] flag, currently supported by the balance
|
|
command, each periodic transaction rule declares recurring budget goals
|
|
for the specified accounts.
|
|
Eg the first example above declares a goal of spending $2000 on rent
|
|
(and also, a goal of depositing $2000 into checking) every month.
|
|
Goals and actual performance can then be compared in budget reports.
|
|
.PP
|
|
See also: Budgeting and Forecasting.
|
|
.PP
|
|
.SS Auto postings
|
|
.PP
|
|
\[dq]Automated postings\[dq] or \[dq]auto postings\[dq] are extra
|
|
postings which get added automatically to transactions which match
|
|
certain queries, defined by \[dq]auto posting rules\[dq], when you use
|
|
the \f[C]--auto\f[R] flag.
|
|
.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[C]=\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[C]$2\f[R].
|
|
This will be used as-is.
|
|
.IP \[bu] 2
|
|
a number, eg \f[C]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[C]*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[C]*$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[C]-f\f[R]/\f[C]--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.
|
|
.SS Auto posting tags
|
|
.PP
|
|
Automated postings will have some extra tags:
|
|
.IP \[bu] 2
|
|
\f[C]generated-posting:= QUERY\f[R] - shows this was generated by an
|
|
auto posting rule, and the query
|
|
.IP \[bu] 2
|
|
\f[C]_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[C]modified:\f[R] - this transaction was modified
|
|
.IP \[bu] 2
|
|
\f[C]_modified:\f[R] - a hidden tag not appearing in the comment; this
|
|
transaction was modified \[dq]just now\[dq].
|
|
.SH CSV FORMAT
|
|
.PP
|
|
How hledger reads CSV data, and the CSV rules file format.
|
|
.PP
|
|
hledger can read CSV files (Character Separated Value - usually comma,
|
|
semicolon, or tab) containing dated records as if they were journal
|
|
files, automatically converting each CSV record into a transaction.
|
|
.PP
|
|
(To learn about \f[I]writing\f[R] CSV, see CSV output.)
|
|
.PP
|
|
We describe each CSV file\[aq]s format with a corresponding \f[I]rules
|
|
file\f[R].
|
|
By default this is named like the CSV file with a \f[C].rules\f[R]
|
|
extension added.
|
|
Eg when reading \f[C]FILE.csv\f[R], hledger also looks for
|
|
\f[C]FILE.csv.rules\f[R] in the same directory as \f[C]FILE.csv\f[R].
|
|
You can specify a different rules file with the \f[C]--rules-file\f[R]
|
|
option.
|
|
If a rules file is not found, hledger will create a sample rules file,
|
|
which you\[aq]ll need to adjust.
|
|
.PP
|
|
This file contains rules describing the CSV data (header line, fields
|
|
layout, date format etc.), and how to construct hledger journal entries
|
|
(transactions) from it.
|
|
Often there will also be a list of conditional rules for categorising
|
|
transactions based on their descriptions.
|
|
Here\[aq]s an overview of the CSV rules; these are described more fully
|
|
below, after the examples:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(30.1n) lw(39.9n).
|
|
T{
|
|
\f[B]\f[CB]skip\f[B]\f[R]
|
|
T}@T{
|
|
skip one or more header lines or matched CSV records
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]fields\f[B]\f[R]
|
|
T}@T{
|
|
name CSV fields, assign them to hledger fields
|
|
T}
|
|
T{
|
|
\f[B]field assignment\f[R]
|
|
T}@T{
|
|
assign a value to one hledger field, with interpolation
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]separator\f[B]\f[R]
|
|
T}@T{
|
|
a custom field separator
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]if\f[B] block\f[R]
|
|
T}@T{
|
|
apply some rules to CSV records matched by patterns
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]if\f[B] table\f[R]
|
|
T}@T{
|
|
apply some rules to CSV records matched by patterns, alternate syntax
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]end\f[B]\f[R]
|
|
T}@T{
|
|
skip the remaining CSV records
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]date-format\f[B]\f[R]
|
|
T}@T{
|
|
how to parse dates in CSV records
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]decimal-mark\f[B]\f[R]
|
|
T}@T{
|
|
the decimal mark used in CSV amounts, if ambiguous
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]newest-first\f[B]\f[R]
|
|
T}@T{
|
|
disambiguate record order when there\[aq]s only one date
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]include\f[B]\f[R]
|
|
T}@T{
|
|
inline another CSV rules file
|
|
T}
|
|
T{
|
|
\f[B]\f[CB]balance-type\f[B]\f[R]
|
|
T}@T{
|
|
choose which type of balance assignments to use
|
|
T}
|
|
.TE
|
|
.PP
|
|
Note, for best error messages when reading CSV files, use a
|
|
\f[C].csv\f[R], \f[C].tsv\f[R] or \f[C].ssv\f[R] file extension or file
|
|
prefix - see File Extension below.
|
|
.PP
|
|
There\[aq]s an introductory Convert CSV files tutorial on hledger.org.
|
|
.SS Examples
|
|
.PP
|
|
Here are some sample hledger CSV rules files.
|
|
See also the full collection at:
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
https://github.com/simonmichael/hledger/tree/master/examples/csv
|
|
.SS Basic
|
|
.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
|
|
Default account names are chosen, since we didn\[aq]t set them.
|
|
.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 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
|
|
.SS CSV rules
|
|
.PP
|
|
The following kinds of rule can appear in the rules file, in any order.
|
|
Blank lines and lines beginning with \f[C]#\f[R] or \f[C];\f[R] are
|
|
ignored.
|
|
.SS \f[C]skip\f[R]
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
skip N
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
The word \[dq]skip\[dq] followed by a number (or no number, meaning 1)
|
|
tells hledger to ignore this many non-empty lines preceding the CSV
|
|
data.
|
|
(Empty/blank lines are skipped automatically.) You\[aq]ll need this
|
|
whenever your CSV data contains header lines.
|
|
.PP
|
|
It also has a second purpose: it can be used inside if blocks to ignore
|
|
certain CSV records (described below).
|
|
.SS \f[C]fields\f[R]
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
fields FIELDNAME1, FIELDNAME2, ...
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
A fields list (the word \[dq]fields\[dq] followed by comma-separated
|
|
field names) is the quick way to assign CSV field values to hledger
|
|
fields.
|
|
It does two things:
|
|
.IP "1." 3
|
|
it names the CSV fields.
|
|
This is optional, but can be convenient later for interpolating them.
|
|
.IP "2." 3
|
|
when you use a standard hledger field name, it assigns the CSV value to
|
|
that part of the hledger 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
|
|
Field names may not contain whitespace.
|
|
Fields you don\[aq]t care about can be left unnamed.
|
|
Currently there must be least two items (there must be at least one
|
|
comma).
|
|
.PP
|
|
Note, always use comma in the fields list, even if your CSV uses another
|
|
separator character.
|
|
.PP
|
|
Here are the standard hledger field/pseudo-field names.
|
|
For more about the transaction parts they refer to, see the manual for
|
|
hledger\[aq]s journal format.
|
|
.SS Transaction field names
|
|
.PP
|
|
\f[C]date\f[R], \f[C]date2\f[R], \f[C]status\f[R], \f[C]code\f[R],
|
|
\f[C]description\f[R], \f[C]comment\f[R] can be used to form the
|
|
transaction\[aq]s first line.
|
|
.SS Posting field names
|
|
.SS account
|
|
.PP
|
|
\f[C]accountN\f[R], where N is 1 to 99, causes a posting to be
|
|
generated, with that account name.
|
|
.PP
|
|
Most often there are two postings, so you\[aq]ll want to set
|
|
\f[C]account1\f[R] and \f[C]account2\f[R].
|
|
Typically \f[C]account1\f[R] is associated with the CSV file, and is set
|
|
once with a top-level assignment, while \f[C]account2\f[R] is set based
|
|
on each transaction\[aq]s description, and in conditional blocks.
|
|
.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
|
|
.PP
|
|
\f[C]amountN\f[R] sets posting N\[aq]s amount.
|
|
If the CSV uses separate fields for inflows and outflows, you can use
|
|
\f[C]amountN-in\f[R] and \f[C]amountN-out\f[R] instead.
|
|
By assigning to \f[C]amount1\f[R], \f[C]amount2\f[R], ...
|
|
etc.
|
|
you can generate anywhere from 0 to 99 postings.
|
|
.PP
|
|
There is also an older, unnumbered form of these names, suitable for
|
|
2-posting transactions, which sets both posting 1\[aq]s and (negated)
|
|
posting 2\[aq]s amount: \f[C]amount\f[R], or \f[C]amount-in\f[R] and
|
|
\f[C]amount-out\f[R].
|
|
This is still supported because it keeps pre-hledger-1.17 csv rules
|
|
files working, and because it can be more succinct, and because it
|
|
converts posting 2\[aq]s amount to cost if there\[aq]s a transaction
|
|
price, which can be useful.
|
|
.PP
|
|
If you have an existing rules file using the unnumbered form, you might
|
|
want to use the numbered form in certain conditional blocks, without
|
|
having to update and retest all the old rules.
|
|
To facilitate this, posting 1 ignores
|
|
\f[C]amount\f[R]/\f[C]amount-in\f[R]/\f[C]amount-out\f[R] if any of
|
|
\f[C]amount1\f[R]/\f[C]amount1-in\f[R]/\f[C]amount1-out\f[R] are
|
|
assigned, and posting 2 ignores them if any of
|
|
\f[C]amount2\f[R]/\f[C]amount2-in\f[R]/\f[C]amount2-out\f[R] are
|
|
assigned, avoiding conflicts.
|
|
.SS currency
|
|
.PP
|
|
If the CSV has the currency symbol in a separate field (ie, not part of
|
|
the amount field), you can use \f[C]currencyN\f[R] to prepend it to
|
|
posting N\[aq]s amount.
|
|
Or, \f[C]currency\f[R] with no number affects all postings.
|
|
.SS balance
|
|
.PP
|
|
\f[C]balanceN\f[R] sets a balance assertion amount (or if the posting
|
|
amount is left empty, a balance assignment) on posting N.
|
|
.PP
|
|
Also, for compatibility with hledger <1.17: \f[C]balance\f[R] with no
|
|
number is equivalent to \f[C]balance1\f[R].
|
|
.PP
|
|
You can adjust the type of assertion/assignment with the
|
|
\f[C]balance-type\f[R] rule (see below).
|
|
.SS comment
|
|
.PP
|
|
Finally, \f[C]commentN\f[R] sets a comment on the Nth posting.
|
|
Comments can also contain tags, as usual.
|
|
.PP
|
|
See TIPS below for more about setting amounts and currency.
|
|
.SS field assignment
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
HLEDGERFIELDNAME FIELDVALUE
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Instead of or in addition to a fields list, you can use a \[dq]field
|
|
assignment\[dq] rule to set the value of a single hledger field, by
|
|
writing its name (any of the standard hledger field names above)
|
|
followed by a text value.
|
|
The value may contain interpolated CSV fields, referenced by their
|
|
1-based position in the CSV record (\f[C]%N\f[R]), or by the name they
|
|
were given in the fields list (\f[C]%CSVFIELDNAME\f[R]).
|
|
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
|
|
Interpolation strips outer whitespace (so a CSV value like
|
|
\f[C]\[dq] 1 \[dq]\f[R] becomes \f[C]1\f[R] when interpolated) (#1051).
|
|
See TIPS below for more about referencing other fields.
|
|
.SS \f[C]separator\f[R]
|
|
.PP
|
|
You can use the \f[C]separator\f[R] rule to read other kinds of
|
|
character-separated data.
|
|
The argument is any single separator character, or the words
|
|
\f[C]tab\f[R] or \f[C]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[C].csv\f[R], \f[C].ssv\f[R] or \f[C].tsv\f[R]
|
|
file extension (or a \f[C]csv:\f[R], \f[C]ssv:\f[R], \f[C]tsv:\f[R]
|
|
prefix), the appropriate separator will be inferred automatically, and
|
|
you won\[aq]t need this rule.
|
|
.SS \f[C]if\f[R] block
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
if MATCHER
|
|
RULE
|
|
|
|
if
|
|
MATCHER
|
|
MATCHER
|
|
MATCHER
|
|
RULE
|
|
RULE
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Conditional blocks (\[dq]if blocks\[dq]) are a block of rules that are
|
|
applied only to CSV records which match certain patterns.
|
|
They are often used for customising account names based on transaction
|
|
descriptions.
|
|
.SS Matching the whole record
|
|
.PP
|
|
Each MATCHER can be a record matcher, which looks like this:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
REGEX
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
REGEX is a case-insensitive regular expression which tries to match
|
|
anywhere within the CSV record.
|
|
It is a POSIX ERE (extended regular expression) that also supports GNU
|
|
word boundaries (\f[C]\[rs]b\f[R], \f[C]\[rs]B\f[R], \f[C]\[rs]<\f[R],
|
|
\f[C]\[rs]>\f[R]), and nothing else.
|
|
If you have trouble, be sure to check our
|
|
https://hledger.org/hledger.html#regular-expressions doc.
|
|
.PP
|
|
Important note: the record that is matched is not the original record,
|
|
but a synthetic one, with any enclosing double quotes (but not enclosing
|
|
whitespace) removed, and always comma-separated (which means that a
|
|
field containing a comma will appear like two fields).
|
|
Eg, if the original record is
|
|
\f[C]2020-01-01; \[dq]Acme, Inc.\[dq]; 1,000\f[R], the REGEX will
|
|
actually see \f[C]2020-01-01,Acme, Inc., 1,000\f[R]).
|
|
.SS Matching individual fields
|
|
.PP
|
|
Or, MATCHER can be a field matcher, like this:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
%CSVFIELD REGEX
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
which matches just the content of a particular CSV field.
|
|
CSVFIELD is a percent sign followed by the field\[aq]s name or column
|
|
number, like \f[C]%date\f[R] or \f[C]%1\f[R].
|
|
.SS Combining matchers
|
|
.PP
|
|
A single matcher can be written on the same line as the \[dq]if\[dq]; or
|
|
multiple matchers can be written on the following lines, non-indented.
|
|
Multiple matchers are OR\[aq]d (any one of them can match), unless one
|
|
begins with an \f[C]&\f[R] symbol, in which case it is AND\[aq]ed with
|
|
the previous matcher.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
if
|
|
MATCHER
|
|
& MATCHER
|
|
RULE
|
|
\f[R]
|
|
.fi
|
|
.SS Rules applied on successful match
|
|
.PP
|
|
After the patterns there should be one or more rules to apply, all
|
|
indented by at least one space.
|
|
Three kinds of rule are allowed in conditional blocks:
|
|
.IP \[bu] 2
|
|
field assignments (to set a hledger field)
|
|
.IP \[bu] 2
|
|
skip (to skip the matched CSV record)
|
|
.IP \[bu] 2
|
|
end (to skip all remaining CSV records).
|
|
.PP
|
|
Examples:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# if the CSV 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 CSV record contains any of these patterns, set account2 and 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
|
|
.SS \f[C]if\f[R] table
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn
|
|
MATCHER1,VALUE11,VALUE12,...,VALUE1n
|
|
MATCHER2,VALUE21,VALUE22,...,VALUE2n
|
|
MATCHER3,VALUE31,VALUE32,...,VALUE3n
|
|
<empty line>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Conditional tables (\[dq]if tables\[dq]) are a different syntax to
|
|
specify field assignments that will be applied only to CSV records which
|
|
match certain patterns.
|
|
.PP
|
|
MATCHER could be either field or record matcher, as described above.
|
|
When MATCHER matches, values from that row would be assigned to the CSV
|
|
fields named on the \f[C]if\f[R] line, in the same order.
|
|
.PP
|
|
Therefore \f[C]if\f[R] table is exactly equivalent to a sequence of of
|
|
\f[C]if\f[R] blocks:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
if MATCHER1
|
|
CSVFIELDNAME1 VALUE11
|
|
CSVFIELDNAME2 VALUE12
|
|
...
|
|
CSVFIELDNAMEn VALUE1n
|
|
|
|
if MATCHER2
|
|
CSVFIELDNAME1 VALUE21
|
|
CSVFIELDNAME2 VALUE22
|
|
...
|
|
CSVFIELDNAMEn VALUE2n
|
|
|
|
if MATCHER3
|
|
CSVFIELDNAME1 VALUE31
|
|
CSVFIELDNAME2 VALUE32
|
|
...
|
|
CSVFIELDNAMEn VALUE3n
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Each line starting with MATCHER should contain enough (possibly empty)
|
|
values for all the listed fields.
|
|
.PP
|
|
Rules would be checked and applied in the order they are listed in the
|
|
table and, like with \f[C]if\f[R] blocks, later rules (in the same or
|
|
another table) or \f[C]if\f[R] blocks could override the effect of any
|
|
rule.
|
|
.PP
|
|
Instead of \[aq],\[aq] you can use a variety of other non-alphanumeric
|
|
characters as a separator.
|
|
First character after \f[C]if\f[R] is taken to be the separator for the
|
|
rest of the table.
|
|
It is the responsibility of the user to ensure that separator does not
|
|
occur inside MATCHERs and values - there is no way to escape separator.
|
|
.PP
|
|
Example:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
if,account2,comment
|
|
atm transaction fee,expenses:business:banking,deductible? check it
|
|
%description groceries,expenses:groceries,
|
|
2020/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]end\f[R]
|
|
.PP
|
|
This rule can be used inside if blocks (only), to make hledger stop
|
|
reading this CSV file and move on to the next input file, or to command
|
|
execution.
|
|
Eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# ignore everything following the first empty record
|
|
if ,,,,
|
|
end
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]date-format\f[R]
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
date-format DATEFMT
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
This is a helper for the \f[C]date\f[R] (and \f[C]date2\f[R]) fields.
|
|
If your CSV dates are not formatted like \f[C]YYYY-MM-DD\f[R],
|
|
\f[C]YYYY/MM/DD\f[R] or \f[C]YYYY.MM.DD\f[R], you\[aq]ll need to add a
|
|
date-format rule describing them with a strptime date parsing pattern,
|
|
which 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
|
|
.PP
|
|
For the supported strptime syntax, see:
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
https://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:formatTime
|
|
.SS \f[C]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[C]newest-first\f[R]
|
|
.PP
|
|
hledger always sorts the generated transactions by date.
|
|
Transactions on the same date should appear in the same order as their
|
|
CSV records, as hledger can usually auto-detect whether the CSV\[aq]s
|
|
normal order is oldest first or newest first.
|
|
But if all of the following are true:
|
|
.IP \[bu] 2
|
|
the CSV might sometimes contain just one day of data (all records having
|
|
the same date)
|
|
.IP \[bu] 2
|
|
the CSV records are normally in reverse chronological order (newest at
|
|
the top)
|
|
.IP \[bu] 2
|
|
and you care about preserving the order of same-day transactions
|
|
.PP
|
|
then, you should add the \f[C]newest-first\f[R] rule as a hint.
|
|
Eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# tell hledger explicitly that the CSV is normally newest first
|
|
newest-first
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]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[C]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 \f[C]balance-type\f[R]
|
|
.PP
|
|
Balance assertions generated by assigning to balanceN are of the simple
|
|
\f[C]=\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[C]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 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 http://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
|
|
hledger accepts CSV conforming to RFC 4180.
|
|
When CSV values are enclosed in quotes, note:
|
|
.IP \[bu] 2
|
|
they must be double quotes (not single quotes)
|
|
.IP \[bu] 2
|
|
spaces outside the quotes are not allowed
|
|
.SS File Extension
|
|
.PP
|
|
To help hledger identify the format and show the right error messages,
|
|
CSV/SSV/TSV files should normally be named with a \f[C].csv\f[R],
|
|
\f[C].ssv\f[R] or \f[C].tsv\f[R] filename extension.
|
|
Or, the file path should be prefixed with \f[C]csv:\f[R], \f[C]ssv:\f[R]
|
|
or \f[C]tsv:\f[R].
|
|
Eg:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger -f foo.ssv print
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
or:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ cat foo | hledger -f ssv:- foo
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
You can override the file extension with a separator rule if needed.
|
|
See also: Input files in the hledger manual.
|
|
.SS Reading multiple CSV files
|
|
.PP
|
|
If you use multiple \f[C]-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[C]--rules-file\f[R] option, that rules file will
|
|
be used for all the CSV files.
|
|
.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[C].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 -> sidebar -> real world setups
|
|
.IP \[bu] 2
|
|
https://plaintextaccounting.org -> data import/conversion
|
|
.SS Setting amounts
|
|
.PP
|
|
A posting amount can be set in one of these ways:
|
|
.IP \[bu] 2
|
|
by assigning (with a fields list or field assignment) to
|
|
\f[C]amountN\f[R] (posting N\[aq]s amount) or \f[C]amount\f[R] (posting
|
|
1\[aq]s amount)
|
|
.IP \[bu] 2
|
|
by assigning to \f[C]amountN-in\f[R] and \f[C]amountN-out\f[R] (or
|
|
\f[C]amount-in\f[R] and \f[C]amount-out\f[R]).
|
|
For each CSV record, whichever of these has a non-zero value will be
|
|
used, with appropriate sign.
|
|
If both contain a non-zero value, this may not work.
|
|
.IP \[bu] 2
|
|
by assigning to \f[C]balanceN\f[R] (or \f[C]balance\f[R]) instead of the
|
|
above, setting the amount indirectly via a balance assignment.
|
|
If you do this the default account name may be wrong, so you should set
|
|
that explicitly.
|
|
.PP
|
|
There is some special handling for an amount\[aq]s sign:
|
|
.IP \[bu] 2
|
|
If an amount value is parenthesised, it will be de-parenthesised and
|
|
sign-flipped.
|
|
.IP \[bu] 2
|
|
If an amount value begins with a double minus sign, those cancel out and
|
|
are removed.
|
|
.IP \[bu] 2
|
|
If an amount value begins with a plus sign, that will be removed
|
|
.SS Setting currency/commodity
|
|
.PP
|
|
If the currency/commodity symbol is included in the CSV\[aq]s amount
|
|
field(s):
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2020-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]
|
|
2020-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]
|
|
2020-01-01,foo,USD,123.00
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
You can assign that to the \f[C]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]
|
|
2020-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]
|
|
2020-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[C]cur\f[R]) that is not
|
|
\f[C]currency\f[R] - that would trigger the prepending effect, which we
|
|
don\[aq]t want here.
|
|
.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[C]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[C]skip\f[R] (at top level)
|
|
.IP \[bu] 2
|
|
\f[C]date-format\f[R]
|
|
.IP \[bu] 2
|
|
\f[C]newest-first\f[R]
|
|
.IP \[bu] 2
|
|
\f[C]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[C]if\f[R] blocks.
|
|
If any of them contain a \f[C]end\f[R] rule, skip all remaining CSV
|
|
records.
|
|
Otherwise if any of them contain a \f[C]skip\f[R] rule, skip that many
|
|
CSV records.
|
|
If there are multiple matched \f[C]skip\f[R] rules, the first one wins.
|
|
.IP \[bu] 2
|
|
collect all field assignments at top level and in matched \f[C]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 %CSVFIELDNAME references), or a
|
|
default
|
|
.IP \[bu] 2
|
|
generate a synthetic hledger transaction 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.
|
|
.SH TIMECLOCK FORMAT
|
|
.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).
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
i 2015/03/30 09:00:00 some:account name optional description after two spaces
|
|
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[C]hledger print\f[R] generates these journal
|
|
entries:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger -f t.timeclock print
|
|
2015-03-30 * optional description after two spaces
|
|
(some:account name) 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[C]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[C]ti\f[R] and \f[C]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.
|
|
.SH TIMEDOT FORMAT
|
|
.PP
|
|
hledger\[aq]s human-friendly time logging format.
|
|
.PP
|
|
Timedot is a plain text format for logging dated, categorised quantities
|
|
(of time, usually), supported by hledger.
|
|
It is convenient for approximate and retroactive time logging, eg when
|
|
the real-time clock-in/out required with a timeclock file is too precise
|
|
or too interruptive.
|
|
It can be formatted like a bar chart, making clear at a glance where
|
|
time was spent.
|
|
.PP
|
|
Though called \[dq]timedot\[dq], this format is read by hledger as
|
|
commodityless quantities, so it could be used to represent dated
|
|
quantities other than time.
|
|
In the docs below we\[aq]ll assume it\[aq]s time.
|
|
.PP
|
|
A timedot file contains a series of day entries.
|
|
A day entry begins with a non-indented hledger-style simple date (Y-M-D,
|
|
Y/M/D, Y.M.D..) Any additional text on the same line is used as a
|
|
transaction description for this day.
|
|
.PP
|
|
This is followed by optionally-indented timelog items for that day, one
|
|
per line.
|
|
Each timelog item is a note, usually a hledger:style:account:name
|
|
representing a time category, followed by two or more spaces, and a
|
|
quantity.
|
|
Each timelog item generates a hledger transaction.
|
|
.PP
|
|
Quantities can be written as:
|
|
.IP \[bu] 2
|
|
dots: a sequence of dots (.) representing quarter hours.
|
|
Spaces may optionally be used for grouping.
|
|
Eg: ....
|
|
\&..
|
|
.IP \[bu] 2
|
|
an integral or decimal number, representing hours.
|
|
Eg: 1.5
|
|
.IP \[bu] 2
|
|
an integral or decimal number immediately followed by a unit symbol
|
|
\f[C]s\f[R], \f[C]m\f[R], \f[C]h\f[R], \f[C]d\f[R], \f[C]w\f[R],
|
|
\f[C]mo\f[R], or \f[C]y\f[R], representing seconds, minutes, hours, days
|
|
weeks, months or years respectively.
|
|
Eg: 90m.
|
|
The following equivalencies are assumed, currently: 1m = 60s, 1h = 60m,
|
|
1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.
|
|
.PP
|
|
There is some flexibility allowing notes and todo lists to be kept right
|
|
in the time log, if needed:
|
|
.IP \[bu] 2
|
|
Blank lines and lines beginning with \f[C]#\f[R] or \f[C];\f[R] are
|
|
ignored.
|
|
.IP \[bu] 2
|
|
Lines not ending with a double-space and quantity are parsed as items
|
|
taking no time, which will not appear in balance reports by default.
|
|
(Add -E to see them.)
|
|
.IP \[bu] 2
|
|
Org mode headlines (lines beginning with one or more \f[C]*\f[R]
|
|
followed by a space) can be used as date lines or timelog items (the
|
|
stars are ignored).
|
|
Also all org headlines before the first date line are ignored.
|
|
This means org users can manage their timelog as an org outline (eg
|
|
using org-mode/orgstruct-mode in Emacs), for organisation, faster
|
|
navigation, controlling visibility etc.
|
|
.PP
|
|
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
|
|
** 2020-01-01
|
|
*** adm:time .
|
|
*** adm:finance .
|
|
\f[R]
|
|
.fi
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
* 2020 Work Diary
|
|
** Q1
|
|
*** 2020-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 t.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 t.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
|
|
I prefer to use period for separating account components.
|
|
We can make this work with an account alias:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2016/2/4
|
|
fos.hledger.timedot 4
|
|
fos.ledger ..
|
|
\f[R]
|
|
.fi
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger -f t.timedot --alias /\[rs]\[rs]./=: bal date:2016/2/4 --tree
|
|
4.50 fos
|
|
4.00 hledger:timedot
|
|
0.50 ledger
|
|
--------------------
|
|
4.50
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Here is a sample.timedot.
|
|
.SH COMMON TASKS
|
|
.PP
|
|
Here are some quick examples of how to do some basic tasks with hledger.
|
|
For more details, see the reference section below, the
|
|
hledger_journal(5) manual, or the more extensive docs at
|
|
https://hledger.org.
|
|
.SS Getting help
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger # show available commands
|
|
$ hledger --help # show common options
|
|
$ hledger CMD --help # show common and command options, and command help
|
|
$ hledger help # show available manuals/topics
|
|
$ hledger help hledger # show hledger manual as info/man/text (auto-chosen)
|
|
$ hledger help journal --man # show the journal manual as a man page
|
|
$ hledger help --help # show more detailed help for the help command
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Find more docs, chat, mail list, reddit, issue tracker:
|
|
https://hledger.org#help-feedback
|
|
.SS Constructing command lines
|
|
.PP
|
|
hledger has an extensive and powerful command line interface.
|
|
We strive to keep it simple and ergonomic, but you may run into one of
|
|
the confusing real world details described in OPTIONS, below.
|
|
If that happens, here are some tips that may help:
|
|
.IP \[bu] 2
|
|
command-specific options must go after the command (it\[aq]s fine to put
|
|
all options there) (\f[C]hledger CMD OPTS ARGS\f[R])
|
|
.IP \[bu] 2
|
|
running add-on executables directly simplifies command line parsing
|
|
(\f[C]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 is being parsed, add
|
|
\f[C]--debug=2\f[R].
|
|
.SS Starting a journal file
|
|
.PP
|
|
hledger looks for your accounting data in a journal file,
|
|
\f[C]$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[C]LEDGER_FILE\f[R] environment
|
|
variable.
|
|
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 2020.journal
|
|
$ echo \[dq]export LEDGER_FILE=$HOME/finance/2020.journal\[dq] >> \[ti]/.bashrc
|
|
$ source \[ti]/.bashrc
|
|
$ hledger stats
|
|
Main file : /Users/simon/finance/2020.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 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]
|
|
2020-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[C]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/2020.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 [2020-02-07]: 2020-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): .
|
|
2020-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 [2020-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] 2020.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]
|
|
2020/1/10 * gift received
|
|
assets:cash $20
|
|
income:gifts
|
|
|
|
2020.1.12 * farmers market
|
|
expenses:food $13
|
|
assets:cash
|
|
|
|
2020-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[C]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[C]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]
|
|
2020-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[C]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[C]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[C]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[C]*\f[R] marker.
|
|
Eg in the paycheck transaction above, insert \f[C]*\f[R] between
|
|
\f[C]2020-01-15\f[R] and \f[C]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] 2020.journal
|
|
\f[R]
|
|
.fi
|
|
.SS Reporting
|
|
.PP
|
|
Here are some basic reports.
|
|
.PP
|
|
Show all transactions:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ hledger print
|
|
2020-01-01 * opening balances
|
|
assets:bank:checking $1000
|
|
assets:bank:savings $2000
|
|
assets:cash $100
|
|
liabilities:creditcard $-50
|
|
equity:opening/closing balances $-3050
|
|
|
|
2020-01-10 * gift received
|
|
assets:cash $20
|
|
income:gifts
|
|
|
|
2020-01-12 * farmers market
|
|
expenses:food $13
|
|
assets:cash
|
|
|
|
2020-01-15 * paycheck
|
|
income:salary
|
|
assets:bank:checking $1000
|
|
|
|
2020-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 --flat -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 --flat -2
|
|
Balance Sheet 2020-01-16
|
|
|
|
|| 2020-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[C]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 2020-01-01-2020-01-16
|
|
|
|
|| 2020-01-01-2020-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
|
|
2020-01-01 opening balances assets:cash $100 $100
|
|
2020-01-10 gift received assets:cash $20 $120
|
|
2020-01-12 farmers market assets:cash $-13 $107
|
|
2020-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 *****
|
|
2020-01-06 ****
|
|
2020-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[C]git add\f[R] the new
|
|
file.
|
|
.SH LIMITATIONS
|
|
.PP
|
|
The need to precede add-on command options with \f[C]--\f[R] when
|
|
invoked from hledger is awkward.
|
|
.PP
|
|
When input data contains non-ascii characters, a suitable system locale
|
|
must be configured (or there will be an unhelpful error).
|
|
Eg on POSIX, set LANG to something other than C.
|
|
.PP
|
|
In a Microsoft Windows CMD window, non-ascii characters and colours are
|
|
not supported.
|
|
.PP
|
|
On Windows, non-ascii characters may not display correctly when running
|
|
a hledger built in CMD in MSYS/CYGWIN, or vice-versa.
|
|
.PP
|
|
In a Cygwin/MSYS/Mintty window, the tab key is not supported in hledger
|
|
add.
|
|
.PP
|
|
Not all of Ledger\[aq]s journal file syntax is supported.
|
|
See file format differences.
|
|
.PP
|
|
On large data files, hledger is slower and uses more memory than Ledger.
|
|
.SH TROUBLESHOOTING
|
|
.PP
|
|
Here are some issues you might encounter when you run hledger (and
|
|
remember you can also seek help from the IRC channel, mail list or bug
|
|
tracker):
|
|
.PP
|
|
\f[B]Successfully installed, but \[dq]No command \[aq]hledger\[aq]
|
|
found\[dq]\f[R]
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
stack and cabal install binaries into a special directory, which should
|
|
be added to your PATH environment variable.
|
|
Eg on unix-like systems, that is \[ti]/.local/bin and \[ti]/.cabal/bin
|
|
respectively.
|
|
.PP
|
|
\f[B]I set a custom LEDGER_FILE, but hledger is still using the default
|
|
file\f[R]
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\f[C]LEDGER_FILE\f[R] should be a real environment variable, not just a
|
|
shell variable.
|
|
The command \f[C]env | grep LEDGER_FILE\f[R] should show it.
|
|
You may need to use \f[C]export\f[R].
|
|
Here\[aq]s an explanation.
|
|
.PP
|
|
\f[B]Getting 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 to
|
|
have a UTF-8-aware locale configured in the environment, otherwise they
|
|
will fail with these kinds of errors when they encounter non-ascii
|
|
characters.
|
|
.PP
|
|
To fix it, set the LANG environment variable to some locale which
|
|
supports UTF-8.
|
|
The locale you choose must be installed on your system.
|
|
.PP
|
|
Here\[aq]s an example of setting LANG temporarily, on Ubuntu GNU/Linux:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ file my.journal
|
|
my.journal: UTF-8 Unicode text # the file is UTF8-encoded
|
|
$ echo $LANG
|
|
C # LANG is set to the default locale, which does not support UTF8
|
|
$ locale -a # which locales are installed ?
|
|
C
|
|
en_US.utf8 # here\[aq]s a UTF8-aware one we can use
|
|
POSIX
|
|
$ LANG=en_US.utf8 hledger -f my.journal print # ensure it is used for this command
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
If available, \f[C]C.UTF-8\f[R] will also work.
|
|
If your preferred locale isn\[aq]t listed by \f[C]locale -a\f[R], you
|
|
might need to install it.
|
|
Eg on Ubuntu/Debian:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ apt-get install language-pack-fr
|
|
$ locale -a
|
|
C
|
|
en_US.utf8
|
|
fr_BE.utf8
|
|
fr_CA.utf8
|
|
fr_CH.utf8
|
|
fr_FR.utf8
|
|
fr_LU.utf8
|
|
POSIX
|
|
$ LANG=fr_FR.utf8 hledger -f my.journal print
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Here\[aq]s how you could set it permanently, if you use a bash shell:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ echo \[dq]export LANG=en_US.utf8\[dq] >>\[ti]/.bash_profile
|
|
$ bash --login
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Exact spelling and capitalisation may be important.
|
|
Note the difference on MacOS (\f[C]UTF-8\f[R], not \f[C]utf8\f[R]).
|
|
Some platforms (eg ubuntu) allow variant spellings, but others (eg
|
|
macos) require it to be exact:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
$ locale -a | grep -iE en_us.*utf
|
|
en_US.UTF-8
|
|
$ LANG=en_US.UTF-8 hledger -f my.journal print
|
|
\f[R]
|
|
.fi
|
|
|
|
|
|
.SH "REPORTING BUGS"
|
|
Report bugs at http://bugs.hledger.org
|
|
(or on the #hledger IRC channel or hledger mail list)
|
|
|
|
.SH AUTHORS
|
|
Simon Michael <simon@joyful.com> and contributors
|
|
|
|
.SH COPYRIGHT
|
|
|
|
Copyright (C) 2007-2020 Simon Michael.
|
|
.br
|
|
Released under GNU GPL v3 or later.
|
|
|
|
.SH SEE ALSO
|
|
hledger(1), hledger\-ui(1), hledger\-web(1), ledger(1)
|