6598 lines
286 KiB
Plaintext
6598 lines
286 KiB
Plaintext
|
|
HLEDGER(1) hledger User Manuals HLEDGER(1)
|
|
|
|
|
|
|
|
NAME
|
|
This is the command-line interface (CLI) for the hledger accounting
|
|
tool. Here we also describe hledger's concepts and file formats. This
|
|
manual is for hledger 1.20.99.
|
|
|
|
SYNOPSIS
|
|
hledger
|
|
|
|
hledger [-f FILE] COMMAND [OPTIONS] [ARGS]
|
|
|
|
hledger [-f FILE] ADDONCMD -- [OPTIONS] [ARGS]
|
|
|
|
DESCRIPTION
|
|
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).
|
|
|
|
The basic function of the hledger CLI is to read a plain text file de-
|
|
scribing financial transactions (in accounting terms, a general jour-
|
|
nal) 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's $PATH and can invoke them as
|
|
subcommands.
|
|
|
|
hledger reads data from one or more files in hledger journal, time-
|
|
clock, timedot, or CSV format specified with -f, or $LEDGER_FILE, or
|
|
$HOME/.hledger.journal (on windows, perhaps
|
|
C:/Users/USER/.hledger.journal). If using $LEDGER_FILE, note this must
|
|
be a real environment variable, not a shell variable. You can specify
|
|
standard input with -f-.
|
|
|
|
Transactions are dated movements of money between two (or more) named
|
|
accounts, and are recorded with journal entries like this:
|
|
|
|
2015/10/16 bought food
|
|
expenses:food $10
|
|
assets:cash
|
|
|
|
For more about this format, see hledger_journal(5).
|
|
|
|
Most users use a text editor to edit the journal, usually with an edi-
|
|
tor mode such as ledger-mode for added convenience. hledger's interac-
|
|
tive add command is another way to record new transactions. hledger
|
|
never changes existing transactions.
|
|
|
|
To get started, you can either save some entries like the above in
|
|
~/.hledger.journal, or run hledger add and follow the prompts. Then
|
|
try some commands like hledger print or hledger balance. Run hledger
|
|
with no arguments for a list of commands.
|
|
|
|
OPTIONS
|
|
General options
|
|
To see general usage help, including general options which are sup-
|
|
ported by most hledger commands, run hledger -h.
|
|
|
|
General help options:
|
|
|
|
-h --help
|
|
show general or COMMAND help
|
|
|
|
--man show general or COMMAND user manual with man
|
|
|
|
--info show general or COMMAND user manual with info
|
|
|
|
--version
|
|
show general or ADDONCMD version
|
|
|
|
--debug[=N]
|
|
show debug output (levels 1-9, default: 1)
|
|
|
|
General input options:
|
|
|
|
-f FILE --file=FILE
|
|
use a different input file. For stdin, use - (default:
|
|
$LEDGER_FILE or $HOME/.hledger.journal)
|
|
|
|
--rules-file=RULESFILE
|
|
Conversion rules file to use when reading CSV (default:
|
|
FILE.rules)
|
|
|
|
--separator=CHAR
|
|
Field separator to expect when reading CSV (default: ',')
|
|
|
|
--alias=OLD=NEW
|
|
rename accounts named OLD to NEW
|
|
|
|
--anon anonymize accounts and payees
|
|
|
|
--pivot FIELDNAME
|
|
use some other field or tag for the account name
|
|
|
|
-I --ignore-assertions
|
|
disable balance assertion checks (note: does not disable balance
|
|
assignments)
|
|
|
|
-s --strict
|
|
do extra error checking (check that all posted accounts are de-
|
|
clared)
|
|
|
|
General reporting options:
|
|
|
|
-b --begin=DATE
|
|
include postings/txns on or after this date
|
|
|
|
-e --end=DATE
|
|
include postings/txns before this date
|
|
|
|
-D --daily
|
|
multiperiod/multicolumn report by day
|
|
|
|
-W --weekly
|
|
multiperiod/multicolumn report by week
|
|
|
|
-M --monthly
|
|
multiperiod/multicolumn report by month
|
|
|
|
-Q --quarterly
|
|
multiperiod/multicolumn report by quarter
|
|
|
|
-Y --yearly
|
|
multiperiod/multicolumn report by year
|
|
|
|
-p --period=PERIODEXP
|
|
set start date, end date, and/or reporting interval all at once
|
|
using period expressions syntax
|
|
|
|
--date2
|
|
match the secondary date instead (see command help for other ef-
|
|
fects)
|
|
|
|
-U --unmarked
|
|
include only unmarked postings/txns (can combine with -P or -C)
|
|
|
|
-P --pending
|
|
include only pending postings/txns
|
|
|
|
-C --cleared
|
|
include only cleared postings/txns
|
|
|
|
-R --real
|
|
include only non-virtual postings
|
|
|
|
-NUM --depth=NUM
|
|
hide/aggregate accounts or postings more than NUM levels deep
|
|
|
|
-E --empty
|
|
show items with zero amount, normally hidden (and vice-versa in
|
|
hledger-ui/hledger-web)
|
|
|
|
-B --cost
|
|
convert amounts to their cost/selling amount at transaction time
|
|
|
|
-V --market
|
|
convert amounts to their market value in default valuation com-
|
|
modities
|
|
|
|
-X --exchange=COMM
|
|
convert amounts to their market value in commodity COMM
|
|
|
|
--value
|
|
convert amounts to cost or market value, more flexibly than
|
|
-B/-V/-X
|
|
|
|
--infer-value
|
|
with -V/-X/--value, also infer market prices from transactions
|
|
|
|
--auto apply automated posting rules to modify transactions.
|
|
|
|
--forecast
|
|
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.
|
|
|
|
--color=WHEN (or --colour=WHEN)
|
|
Should color-supporting commands use ANSI color codes in text
|
|
output. 'auto' (default): whenever stdout seems to be a color-
|
|
supporting terminal. 'always' or 'yes': always, useful eg when
|
|
piping output into 'less -R'. 'never' or 'no': never. A
|
|
NO_COLOR environment variable overrides this.
|
|
|
|
When a reporting option appears more than once in the command line, the
|
|
last one takes precedence.
|
|
|
|
Some reporting options can also be written as query arguments.
|
|
|
|
Command options
|
|
To see options for a particular command, including command-specific op-
|
|
tions, run: hledger COMMAND -h.
|
|
|
|
Command-specific options must be written after the command name, eg:
|
|
hledger print -x.
|
|
|
|
Additionally, if the command is an add-on, you may need to put its op-
|
|
tions after a double-hyphen, eg: hledger ui -- --watch. Or, you can
|
|
run the add-on executable directly: hledger-ui --watch.
|
|
|
|
Command arguments
|
|
Most hledger commands accept arguments after the command name, which
|
|
are often a query, filtering the data in some way.
|
|
|
|
You can save a set of command line options/arguments in a file, and
|
|
then reuse them by writing @FILENAME as a command line argument. Eg:
|
|
hledger bal @foo.args. (To prevent this, eg if you have an argument
|
|
that begins with a literal @, precede it with --, eg: hledger bal --
|
|
@ARG).
|
|
|
|
Inside the argument file, each line should contain just one option or
|
|
argument. Avoid the use of spaces, except inside quotes (or you'll see
|
|
a confusing error). Between a flag and its argument, use = (or noth-
|
|
ing). Bad:
|
|
|
|
assets depth:2
|
|
-X USD
|
|
|
|
Good:
|
|
|
|
assets
|
|
depth:2
|
|
-X=USD
|
|
|
|
For special characters (see below), use one less level of quoting than
|
|
you would at the command prompt. Bad:
|
|
|
|
-X"$"
|
|
|
|
Good:
|
|
|
|
-X$
|
|
|
|
See also: Save frequently used options.
|
|
|
|
Special characters
|
|
Single escaping (shell metacharacters)
|
|
In shell command lines, characters significant to your shell - such as
|
|
spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want
|
|
hledger to see them. This is done by enclosing them in single or dou-
|
|
ble quotes, or by writing a backslash before them. Eg to match an ac-
|
|
count name containing a space:
|
|
|
|
$ hledger register 'credit card'
|
|
|
|
or:
|
|
|
|
$ hledger register credit\ card
|
|
|
|
Double escaping (regular expression metacharacters)
|
|
Characters significant in regular expressions (described below) - such
|
|
as ., ^, $, [, ], (, ), |, and \ - may need to be "regex-escaped" if
|
|
you don't want them to be interpreted by hledger'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 $ sign while
|
|
using the bash shell:
|
|
|
|
$ hledger balance cur:'\$'
|
|
|
|
or:
|
|
|
|
$ hledger balance cur:\\$
|
|
|
|
Triple escaping (for add-on commands)
|
|
When you use hledger to run an external add-on command (described be-
|
|
low), 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 $ sign while using the bash
|
|
shell and running an add-on command (ui):
|
|
|
|
$ hledger ui cur:'\\$'
|
|
|
|
or:
|
|
|
|
$ hledger ui cur:\\\\$
|
|
|
|
If you wondered why four backslashes, perhaps this helps:
|
|
|
|
unescaped: $
|
|
escaped: \$
|
|
double-escaped: \\$
|
|
triple-escaped: \\\\$
|
|
|
|
Or, you can avoid the extra escaping by running the add-on executable
|
|
directly:
|
|
|
|
$ hledger-ui cur:\\$
|
|
|
|
Less escaping
|
|
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:
|
|
|
|
o an @argumentfile
|
|
|
|
o hledger-ui's filter field
|
|
|
|
o hledger-web's search form
|
|
|
|
o GHCI's prompt (used by developers).
|
|
|
|
Unicode characters
|
|
hledger is expected to handle non-ascii characters correctly:
|
|
|
|
o they should be parsed correctly in input files and on the command
|
|
line, by all hledger tools (add, iadd, hledger-web's search/add/edit
|
|
forms, etc.)
|
|
|
|
o they should be displayed correctly by all hledger tools, and on-
|
|
screen alignment should be preserved.
|
|
|
|
This requires a well-configured environment. Here are some tips:
|
|
|
|
o A system locale must be configured, and it must be one that can de-
|
|
code the characters being used. In bash, you can set a locale like
|
|
this: export LANG=en_US.UTF-8. There are some more details in Trou-
|
|
bleshooting. This step is essential - without it, hledger will quit
|
|
on encountering a non-ascii character (as with all GHC-compiled pro-
|
|
grams).
|
|
|
|
o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)
|
|
must support unicode
|
|
|
|
o the terminal must be using a font which includes the required unicode
|
|
glyphs
|
|
|
|
o the terminal should be configured to display wide characters as dou-
|
|
ble width (for report alignment)
|
|
|
|
o 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 stan-
|
|
dard 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).
|
|
|
|
Regular expressions
|
|
hledger uses regular expressions in a number of places:
|
|
|
|
o query terms, on the command line and in the hledger-web search form:
|
|
REGEX, desc:REGEX, cur:REGEX, tag:...=REGEX
|
|
|
|
o CSV rules conditional blocks: if REGEX ...
|
|
|
|
o account alias directives and options: alias /REGEX/ = REPLACEMENT,
|
|
--alias /REGEX/=REPLACEMENT
|
|
|
|
hledger's regular expressions come from the regex-tdfa library. If
|
|
they're not doing what you expect, it's important to know exactly what
|
|
they support:
|
|
|
|
1. they are case insensitive
|
|
|
|
2. they are infix matching (they do not need to match the entire thing
|
|
being matched)
|
|
|
|
3. they are POSIX ERE (extended regular expressions)
|
|
|
|
4. they also support GNU word boundaries (\b, \B, \<, \>)
|
|
|
|
5. they do not support backreferences; if you write \1, it will match
|
|
the digit 1. 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.
|
|
|
|
6. they do not support mode modifiers ((?s)), character classes (\w,
|
|
\d), or anything else not mentioned above.
|
|
|
|
Some things to note:
|
|
|
|
o In the alias directive and --alias option, regular expressions must
|
|
be enclosed in forward slashes (/REGEX/). Elsewhere in hledger,
|
|
these are not required.
|
|
|
|
o In queries, to match a regular expression metacharacter like $ as a
|
|
literal character, prepend a backslash. Eg to search for amounts
|
|
with the dollar sign in hledger-web, write cur:\$.
|
|
|
|
o On the command line, some metacharacters like $ have a special mean-
|
|
ing to the shell and so must be escaped at least once more. See Spe-
|
|
cial characters.
|
|
|
|
ENVIRONMENT
|
|
LEDGER_FILE The journal file path when not specified with -f. Default:
|
|
~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour-
|
|
nal).
|
|
|
|
A typical value is ~/DIR/YYYY.journal, where DIR is a version-con-
|
|
trolled finance directory and YYYY is the current year. Or ~/DIR/cur-
|
|
rent.journal, where current.journal is a symbolic link to YYYY.journal.
|
|
|
|
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 ~/.MacOSX/en-
|
|
vironment.plist file containing
|
|
|
|
{
|
|
"LEDGER_FILE" : "~/finance/current.journal"
|
|
}
|
|
|
|
To see the effect you may need to killall Dock, or reboot.
|
|
|
|
COLUMNS The screen width used by the register command. Default: the
|
|
full terminal width.
|
|
|
|
NO_COLOR If this variable exists with any value, hledger will not use
|
|
ANSI color codes in terminal output. This overrides the
|
|
--color/--colour option.
|
|
|
|
DATA FILES
|
|
hledger reads transactions from one or more data files. The default
|
|
data file is $HOME/.hledger.journal (or on Windows, something like
|
|
C:/Users/USER/.hledger.journal).
|
|
|
|
You can override this with the $LEDGER_FILE environment variable:
|
|
|
|
$ setenv LEDGER_FILE ~/finance/2016.journal
|
|
$ hledger stats
|
|
|
|
or with one or more -f/--file options:
|
|
|
|
$ hledger -f /some/file -f another_file stats
|
|
|
|
The file name - means standard input:
|
|
|
|
$ cat some.journal | hledger -f-
|
|
|
|
Data formats
|
|
Usually the data file is in hledger's journal format, but it can be in
|
|
any of the supported file formats, which currently are:
|
|
|
|
Reader: Reads: Used for file exten-
|
|
sions:
|
|
-----------------------------------------------------------------------------
|
|
journal hledger journal files and some Ledger .journal .j .hledger
|
|
journals, for transactions .ledger
|
|
time- timeclock files, for precise time log- .timeclock
|
|
clock ging
|
|
timedot timedot files, for approximate time .timedot
|
|
logging
|
|
csv comma/semicolon/tab/other-separated .csv .ssv .tsv
|
|
values, for data import
|
|
|
|
These formats are described in their own sections, below.
|
|
|
|
hledger detects the format automatically based on the file extensions
|
|
shown above. If it can't recognise the file extension, it assumes
|
|
journal format. So for non-journal files, it's important to use a
|
|
recognised file extension, so as to either read successfully or to show
|
|
relevant error messages.
|
|
|
|
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:
|
|
|
|
$ hledger -f csv:/some/csv-file.dat stats
|
|
$ echo 'i 2009/13/1 08:00:00' | hledger print -ftimeclock:-
|
|
|
|
Multiple files
|
|
You can specify multiple -f options, to read multiple files as one big
|
|
journal. There are some limitations with this:
|
|
|
|
o most directives do not affect sibling files
|
|
|
|
o balance assertions will not see any account balances from previous
|
|
files
|
|
|
|
If you need either of those things, you can
|
|
|
|
o use a single parent file which includes the others
|
|
|
|
o or concatenate the files into one before reading, eg: cat a.journal
|
|
b.journal | hledger -f- CMD.
|
|
|
|
Strict mode
|
|
hledger checks input files for valid data. By default, the most impor-
|
|
tant errors are detected, while still accepting easy journal files
|
|
without a lot of declarations:
|
|
|
|
o Are the input files parseable, with valid syntax ?
|
|
|
|
o Are all transactions balanced ?
|
|
|
|
o Do all balance assertions pass ?
|
|
|
|
With the -s/--strict flag, additional checks are performed:
|
|
|
|
o Are all accounts posted to, declared with an account directive ?
|
|
(Account error checking)
|
|
|
|
o Are all commodities declared with a commodity directive ? (Commodity
|
|
error checking)
|
|
|
|
See also: https://hledger.org/checking-for-errors.html
|
|
|
|
experimental.
|
|
|
|
TIME PERIODS
|
|
Smart dates
|
|
hledger's user interfaces accept a flexible "smart date" syntax. Smart
|
|
dates allow some english words, can be relative to today's date, and
|
|
can have less-significant date parts omitted (defaulting to 1).
|
|
|
|
Examples:
|
|
|
|
2004/10/1, 2004-01-01, exact date, several separators allowed. Year
|
|
2004.9.1 is 4+ digits, month is 1-12, day is 1-31
|
|
2004 start of year
|
|
2004/10 start of month
|
|
10/1 month and day in current year
|
|
21 day in current month
|
|
october, oct start of month in current year
|
|
yesterday, today, tomor- -1, 0, 1 days from today
|
|
row
|
|
last/this/next -1, 0, 1 periods from the current period
|
|
day/week/month/quar-
|
|
ter/year
|
|
20181201 8 digit YYYYMMDD with valid year month and day
|
|
201812 6 digit YYYYMM with valid year and month
|
|
|
|
Counterexamples - malformed digit sequences might give surprising re-
|
|
sults:
|
|
|
|
201813 6 digits with an invalid month is parsed as start of
|
|
6-digit year
|
|
20181301 8 digits with an invalid month is parsed as start of
|
|
8-digit year
|
|
20181232 8 digits with an invalid day gives an error
|
|
201801012 9+ digits beginning with a valid YYYYMMDD gives an error
|
|
|
|
Report start & end date
|
|
By default, most hledger reports will show the full span of time repre-
|
|
sented 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.
|
|
|
|
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 -b/--begin,
|
|
-e/--end, -p/--period or a date: query (described below). All of these
|
|
accept the smart date syntax.
|
|
|
|
Some notes:
|
|
|
|
o As in Ledger, end dates are exclusive, so you need to write the date
|
|
after the last day you want to include.
|
|
|
|
o As noted in reporting options: among start/end dates specified with
|
|
options, the last (i.e. right-most) option takes precedence.
|
|
|
|
o The effective report start and end dates are the intersection of the
|
|
start/end dates from options and that from date: queries. That is,
|
|
date:2019-01 date:2019 -p'2000 to 2030' yields January 2019, the
|
|
smallest common time span.
|
|
|
|
Examples:
|
|
|
|
-b 2016/3/17 begin on St. Patrick's day 2016
|
|
|
|
-e 12/1 end at the start of december 1st of the current year
|
|
(11/30 will be the last date included)
|
|
-b thismonth all transactions on or after the 1st of the current month
|
|
-p thismonth all transactions in the current month
|
|
date:2016/3/17.. the above written as queries instead (.. can also be re-
|
|
placed with -)
|
|
date:..12/1
|
|
date:thismonth..
|
|
date:thismonth
|
|
|
|
Report intervals
|
|
A report interval can be specified so that commands like register, bal-
|
|
ance and activity will divide their reports into multiple subperiods.
|
|
The basic intervals can be selected with one of -D/--daily,
|
|
-W/--weekly, -M/--monthly, -Q/--quarterly, or -Y/--yearly. More com-
|
|
plex intervals may be specified with a period expression. Report in-
|
|
tervals can not be specified with a query.
|
|
|
|
Period expressions
|
|
The -p/--period option accepts period expressions, a shorthand way of
|
|
expressing a start date, end date, and/or report interval all at once.
|
|
|
|
Here's a basic period expression specifying the first quarter of 2009.
|
|
Note, hledger always treats start dates as inclusive and end dates as
|
|
exclusive:
|
|
|
|
-p "from 2009/1/1 to 2009/4/1"
|
|
|
|
Keywords like "from" and "to" are optional, and so are the spaces, as
|
|
long as you don't run two dates together. "to" can also be written as
|
|
".." or "-". These are equivalent to the above:
|
|
|
|
-p "2009/1/1 2009/4/1"
|
|
-p2009/1/1to2009/4/1
|
|
-p2009/1/1..2009/4/1
|
|
|
|
Dates are smart dates, so if the current year is 2009, the above can
|
|
also be written as:
|
|
|
|
-p "1/1 4/1"
|
|
-p "january-apr"
|
|
-p "this year to 4/1"
|
|
|
|
If you specify only one date, the missing start or end date will be the
|
|
earliest or latest transaction in your journal:
|
|
|
|
-p "from 2009/1/1" everything after january
|
|
1, 2009
|
|
-p "from 2009/1" the same
|
|
-p "from 2009" the same
|
|
-p "to 2009" everything before january
|
|
1, 2009
|
|
|
|
A single date with no "from" or "to" defines both the start and end
|
|
date like so:
|
|
|
|
-p "2009" the year 2009; equivalent
|
|
to "2009/1/1 to 2010/1/1"
|
|
-p "2009/1" the month of jan; equiva-
|
|
lent to "2009/1/1 to
|
|
2009/2/1"
|
|
-p "2009/1/1" just that day; equivalent
|
|
to "2009/1/1 to 2009/1/2"
|
|
|
|
Or you can specify a single quarter like so:
|
|
|
|
-p "2009Q1" first quarter of 2009,
|
|
equivalent to "2009/1/1 to
|
|
2009/4/1"
|
|
|
|
|
|
-p "q4" fourth quarter of the cur-
|
|
rent year
|
|
|
|
The argument of -p can also begin with, or be, a report interval ex-
|
|
pression. The basic report intervals are daily, weekly, monthly, quar-
|
|
terly, or yearly, which have the same effect as the -D,-W,-M,-Q, or -Y
|
|
flags. Between report interval and start/end dates (if any), the word
|
|
in is optional. Examples:
|
|
|
|
-p "weekly from 2009/1/1 to 2009/4/1"
|
|
-p "monthly in 2008"
|
|
-p "quarterly"
|
|
|
|
Note that weekly, monthly, quarterly and yearly 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 ex-
|
|
pression specifies different explicit start and end date.
|
|
|
|
For example:
|
|
|
|
-p "weekly from 2009/1/1 starts on 2008/12/29, closest preceding Mon-
|
|
to 2009/4/1" day
|
|
-p "monthly in starts on 2018/11/01
|
|
2008/11/25"
|
|
-p "quarterly from starts on 2009/04/01, ends on 2009/06/30,
|
|
2009-05-05 to 2009-06-01" which are first and last days of Q2 2009
|
|
-p "yearly from starts on 2009/01/01, first day of 2009
|
|
2009-12-29"
|
|
|
|
The following more complex report intervals are also supported: bi-
|
|
weekly, fortnightly, bimonthly, every day|week|month|quarter|year, ev-
|
|
ery N days|weeks|months|quarters|years.
|
|
|
|
All of these will start on the first day of the requested period and
|
|
end on the last one, as described above.
|
|
|
|
Examples:
|
|
|
|
-p "bimonthly from 2008" periods will have boundaries on 2008/01/01,
|
|
2008/03/01, ...
|
|
-p "every 2 weeks" starts on closest preceding Monday
|
|
-p "every 5 month from periods will have boundaries on 2009/03/01,
|
|
2009/03" 2009/08/01, ...
|
|
|
|
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:
|
|
|
|
every Nth day of week, every WEEKDAYNAME (eg
|
|
mon|tue|wed|thu|fri|sat|sun), every Nth day [of month], every Nth WEEK-
|
|
DAYNAME [of month], every MM/DD [of year], every Nth MMM [of year], ev-
|
|
ery MMM Nth [of year].
|
|
|
|
Examples:
|
|
|
|
-p "every 2nd day of periods will go from Tue to Tue
|
|
week"
|
|
-p "every Tue" same
|
|
-p "every 15th day" period boundaries will be on 15th of each
|
|
month
|
|
-p "every 2nd Monday" period boundaries will be on second Monday of
|
|
each month
|
|
-p "every 11/05" yearly periods with boundaries on 5th of Nov
|
|
-p "every 5th Nov" same
|
|
-p "every Nov 5th" same
|
|
|
|
Show historical balances at end of 15th each month (N is exclusive end
|
|
date):
|
|
|
|
hledger balance -H -p "every 16th day"
|
|
|
|
Group postings from start of wednesday to end of next tuesday (N is
|
|
start date and exclusive end date):
|
|
|
|
hledger register checking -p "every 3rd day of week"
|
|
|
|
DEPTH
|
|
With the --depth N option (short form: -N), commands like account, bal-
|
|
ance 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 de-
|
|
tail. This flag has the same effect as a depth: query argument (so -2,
|
|
--depth=2 or depth:2 are equivalent).
|
|
|
|
QUERIES
|
|
One of hledger's strengths is being able to quickly report on precise
|
|
subsets of your data. Most commands accept an optional query expres-
|
|
sion, 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.
|
|
|
|
We do not yet support arbitrary boolean combinations of search terms;
|
|
instead most commands show transactions/postings/accounts which match
|
|
(or negatively match):
|
|
|
|
o any of the description terms AND
|
|
|
|
o any of the account terms AND
|
|
|
|
o any of the status terms AND
|
|
|
|
o all the other terms.
|
|
|
|
The print command instead shows transactions which:
|
|
|
|
o match any of the description terms AND
|
|
|
|
o have any postings matching any of the positive account terms AND
|
|
|
|
o have no postings matching any of the negative account terms AND
|
|
|
|
o match all the other terms.
|
|
|
|
The following kinds of search terms can be used. Remember these can
|
|
also be prefixed with not:, eg to exclude a particular subaccount.
|
|
|
|
REGEX, acct:REGEX
|
|
match account names by this regular expression. (With no pre-
|
|
fix, acct: is assumed.) same as above
|
|
|
|
amt:N, amt:<N, amt:<=N, amt:>N, amt:>=N
|
|
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.
|
|
|
|
code:REGEX
|
|
match by transaction code (eg check number)
|
|
|
|
cur:REGEX
|
|
match postings or transactions including any amounts whose cur-
|
|
rency/commodity symbol is fully matched by REGEX. (For a par-
|
|
tial match, use .*REGEX.*). Note, to match characters which are
|
|
regex-significant, like the dollar sign ($), you need to prepend
|
|
\. And when using the command line you need to add one more
|
|
level of quoting to hide it from the shell, so eg do: hledger
|
|
print cur:'\$' or hledger print cur:\\$.
|
|
|
|
desc:REGEX
|
|
match transaction descriptions.
|
|
|
|
date:PERIODEXPR
|
|
match dates within the specified period. PERIODEXPR is a period
|
|
expression (with no report interval). Examples: date:2016,
|
|
date:thismonth, date:2000/2/1-2/15, date:lastweek-. If the
|
|
--date2 command line flag is present, this matches secondary
|
|
dates instead.
|
|
|
|
date2:PERIODEXPR
|
|
match secondary dates within the specified period.
|
|
|
|
depth:N
|
|
match (or display, depending on command) accounts at or above
|
|
this depth
|
|
|
|
note:REGEX
|
|
match transaction notes (part of description right of |, or
|
|
whole description when there's no |)
|
|
|
|
payee:REGEX
|
|
match transaction payee/payer names (part of description left of
|
|
|, or whole description when there's no |)
|
|
|
|
real:, real:0
|
|
match real or virtual postings respectively
|
|
|
|
status:, status:!, status:*
|
|
match unmarked, pending, or cleared transactions respectively
|
|
|
|
tag:REGEX[=REGEX]
|
|
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.
|
|
|
|
The following special search term is used automatically in hledger-web,
|
|
only:
|
|
|
|
inacct:ACCTNAME
|
|
tells hledger-web to show the transaction register for this ac-
|
|
count. Can be filtered further with acct etc.
|
|
|
|
Some of these can also be expressed as command-line options (eg depth:2
|
|
is equivalent to --depth 2). Generally you can mix options and query
|
|
arguments, and the resulting query will be their intersection (perhaps
|
|
excluding the -p/--period option).
|
|
|
|
VALUATION
|
|
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 cer-
|
|
tain date). This is controlled by the --value=TYPE[,COMMODITY] option,
|
|
but we also provide the simpler -B/-V/-X flags, and usually one of
|
|
those is all you need.
|
|
|
|
-B: Cost
|
|
The -B/--cost flag converts amounts to their cost or sale amount at
|
|
transaction time, if they have a transaction price specified.
|
|
|
|
-V: Value
|
|
The -V/--market flag converts amounts to market value in their default
|
|
valuation commodity, using the market prices in effect on the valuation
|
|
date(s), if any. More on these in a minute.
|
|
|
|
-X: Value in specified commodity
|
|
The -X/--exchange=COMM option is like -V, except you tell it which cur-
|
|
rency you want to convert to, and it tries to convert everything to
|
|
that.
|
|
|
|
Valuation date
|
|
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.
|
|
|
|
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's end date.
|
|
|
|
For multiperiod reports, each column/period is valued on the last day
|
|
of the period, by default.
|
|
|
|
Market prices
|
|
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 :
|
|
|
|
1. A declared market price or inferred market price: A's latest market
|
|
price in B on or before the valuation date as declared by a P direc-
|
|
tive, or (with the --infer-value flag) inferred from transaction
|
|
prices.
|
|
|
|
2. A reverse market price: the inverse of a declared or inferred market
|
|
price from B to A.
|
|
|
|
3. A a forward chain of market prices: a synthetic price formed by com-
|
|
bining the shortest chain of "forward" (only 1 above) market prices,
|
|
leading from A to B.
|
|
|
|
4. A any chain of market prices: a chain of any market prices, includ-
|
|
ing both forward and reverse prices (1 and 2 above), leading from A
|
|
to B.
|
|
|
|
Amounts for which no applicable market price can be found, are not con-
|
|
verted.
|
|
|
|
--infer-value: market prices from transactions
|
|
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 need-
|
|
ing P directives at all.
|
|
|
|
Adding the --infer-value flag to -V, -X or --value enables this. So
|
|
for example, hledger bs -V --infer-value will get market prices both
|
|
from P directives and from transactions.
|
|
|
|
There is a downside: value reports can sometimes be affected in confus-
|
|
ing/undesired ways by your journal entries. If this happens to you,
|
|
read all of this Valuation section carefully, and try adding --debug or
|
|
--debug=2 to troubleshoot.
|
|
|
|
--infer-value can infer market prices from:
|
|
|
|
o multicommodity transactions with explicit prices (@/@@)
|
|
|
|
o multicommodity transactions with implicit prices (no @, two commodi-
|
|
ties, unbalanced). (With these, the order of postings matters.
|
|
hledger print -x can be useful for troubleshooting.)
|
|
|
|
o but not, currently, from "more correct" multicommodity transactions
|
|
(no @, multiple commodities, balanced).
|
|
|
|
Valuation commodity
|
|
When you specify a valuation commodity (-X COMM or --value TYPE,COMM):
|
|
hledger will convert all amounts to COMM, wherever it can find a suit-
|
|
able market price (including by reversing or chaining prices).
|
|
|
|
When you leave the valuation commodity unspecified (-V or --value
|
|
TYPE):
|
|
For each commodity A, hledger picks a default valuation commodity as
|
|
follows, in this order of preference:
|
|
|
|
1. The price commodity from the latest P-declared market price for A on
|
|
or before valuation date.
|
|
|
|
2. 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.)
|
|
|
|
3. If there are no P directives at all (any commodity or date) and the
|
|
--infer-value flag is used: the price commodity from the latest
|
|
transaction-inferred price for A on or before valuation date.
|
|
|
|
This means:
|
|
|
|
o If you have P directives, they determine which commodities -V will
|
|
convert, and to what.
|
|
|
|
o If you have no P directives, and use the --infer-value flag, transac-
|
|
tion prices determine it.
|
|
|
|
Amounts for which no valuation commodity can be found are not con-
|
|
verted.
|
|
|
|
Simple valuation examples
|
|
Here are some quick examples of -V:
|
|
|
|
; one euro is worth this many dollars from nov 1
|
|
P 2016/11/01 EUR $1.10
|
|
|
|
; purchase some euros on nov 3
|
|
2016/11/3
|
|
assets:euros EUR100
|
|
assets:checking
|
|
|
|
; the euro is worth fewer dollars by dec 21
|
|
P 2016/12/21 EUR $1.03
|
|
|
|
How many euros do I have ?
|
|
|
|
$ hledger -f t.j bal -N euros
|
|
EUR100 assets:euros
|
|
|
|
What are they worth at end of nov 3 ?
|
|
|
|
$ hledger -f t.j bal -N euros -V -e 2016/11/4
|
|
$110.00 assets:euros
|
|
|
|
What are they worth after 2016/12/21 ? (no report end date specified,
|
|
defaults to today)
|
|
|
|
$ hledger -f t.j bal -N euros -V
|
|
$103.00 assets:euros
|
|
|
|
--value: Flexible valuation
|
|
-B, -V and -X are special cases of the more general --value option:
|
|
|
|
--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
|
|
|
|
The TYPE part selects cost or value and valuation date:
|
|
|
|
--value=cost
|
|
Convert amounts to cost, using the prices recorded in transac-
|
|
tions.
|
|
|
|
--value=then
|
|
Convert amounts to their value in the default valuation commod-
|
|
ity, using market prices on each posting's date. This is cur-
|
|
rently supported only by the print and register commands.
|
|
|
|
--value=end
|
|
Convert amounts to their value in the default valuation commod-
|
|
ity, using market prices on the last day of the report period
|
|
(or if unspecified, the journal's end date); or in multiperiod
|
|
reports, market prices on the last day of each subperiod.
|
|
|
|
--value=now
|
|
Convert amounts to their value in the default valuation commod-
|
|
ity using current market prices (as of when report is gener-
|
|
ated).
|
|
|
|
--value=YYYY-MM-DD
|
|
Convert amounts to their value in the default valuation commod-
|
|
ity using market prices on this date.
|
|
|
|
To select a different valuation commodity, add the optional ,COMM part:
|
|
a comma, then the target commodity's symbol. Eg: --value=now,EUR.
|
|
hledger will do its best to convert amounts to this commodity, deducing
|
|
market prices as described above.
|
|
|
|
More valuation examples
|
|
Here are some examples showing the effect of --value, as seen with
|
|
print:
|
|
|
|
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 @ 5 B
|
|
|
|
2000-02-01
|
|
(a) 1 A @ 6 B
|
|
|
|
2000-03-01
|
|
(a) 1 A @ 7 B
|
|
|
|
Show the cost of each posting:
|
|
|
|
$ hledger -f- print --value=cost
|
|
2000-01-01
|
|
(a) 5 B
|
|
|
|
2000-02-01
|
|
(a) 6 B
|
|
|
|
2000-03-01
|
|
(a) 7 B
|
|
|
|
Show the value as of the last day of the report period (2000-02-29):
|
|
|
|
$ hledger -f- print --value=end date:2000/01-2000/03
|
|
2000-01-01
|
|
(a) 2 B
|
|
|
|
2000-02-01
|
|
(a) 2 B
|
|
|
|
With no report period specified, that shows the value as of the last
|
|
day of the journal (2000-03-01):
|
|
|
|
$ hledger -f- print --value=end
|
|
2000-01-01
|
|
(a) 3 B
|
|
|
|
2000-02-01
|
|
(a) 3 B
|
|
|
|
2000-03-01
|
|
(a) 3 B
|
|
|
|
Show the current value (the 2000-04-01 price is still in effect today):
|
|
|
|
$ hledger -f- print --value=now
|
|
2000-01-01
|
|
(a) 4 B
|
|
|
|
2000-02-01
|
|
(a) 4 B
|
|
|
|
2000-03-01
|
|
(a) 4 B
|
|
|
|
Show the value on 2000/01/15:
|
|
|
|
$ 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
|
|
|
|
You may need to explicitly set a commodity's display style, when re-
|
|
verse prices are used. Eg this output might be surprising:
|
|
|
|
P 2000-01-01 A 2B
|
|
|
|
2000-01-01
|
|
a 1B
|
|
b
|
|
|
|
$ hledger print -x -X A
|
|
2000-01-01
|
|
a 0
|
|
b 0
|
|
|
|
Explanation: because there's no amount or commodity directive specify-
|
|
ing a display style for A, 0.5A gets the default style, which shows no
|
|
decimal digits. Because the displayed amount looks like zero, the com-
|
|
modity symbol and minus sign are not displayed either. Adding a com-
|
|
modity directive sets a more useful display style for A:
|
|
|
|
P 2000-01-01 A 2B
|
|
commodity 0.00A
|
|
|
|
2000-01-01
|
|
a 1B
|
|
b
|
|
|
|
$ hledger print -X A
|
|
2000-01-01
|
|
a 0.50A
|
|
b -0.50A
|
|
|
|
Effect of valuation on reports
|
|
Here is a reference for how valuation is supposed to affect each part
|
|
of hledger's reports (and a glossary). (It's wide, you'll have to
|
|
scroll sideways.) It may be useful when troubleshooting. If you find
|
|
problems, please report them, ideally with a reproducible example. Re-
|
|
lated: #329, #1083.
|
|
|
|
Report type -B, -V, -X --value=then --value=end --value=DATE,
|
|
--value=cost --value=now
|
|
--------------------------------------------------------------------------------------------
|
|
print
|
|
posting cost value at re- value at value at re- value at
|
|
amounts port end or posting date port or jour- DATE/today
|
|
today nal end
|
|
|
|
balance as- unchanged unchanged unchanged unchanged unchanged
|
|
ser-
|
|
tions/as-
|
|
signments
|
|
|
|
register
|
|
starting cost value at day not sup- value at day value at
|
|
balance before report ported before report DATE/today
|
|
(-H) or journal or journal
|
|
start start
|
|
posting cost value at re- value at value at re- value at
|
|
amounts port end or posting date port or jour- DATE/today
|
|
today nal end
|
|
summary summarised value at pe- sum of post- value at pe- value at
|
|
posting cost riod ends ings in in- riod ends DATE/today
|
|
amounts terval, val-
|
|
with report ued at in-
|
|
interval terval start
|
|
running to- sum/average sum/average sum/average sum/average sum/average
|
|
tal/average of displayed of displayed of displayed of displayed of displayed
|
|
values values values values values
|
|
|
|
balance
|
|
(bs, bse,
|
|
cf, is)
|
|
balance sums of costs value at re- not sup- value at re- value at
|
|
changes port end or ported port or jour- DATE/today of
|
|
today of sums nal end of sums of post-
|
|
of postings sums of post- ings
|
|
ings
|
|
budget like balance like balance not sup- like balances like balance
|
|
amounts changes changes ported changes
|
|
(--budget)
|
|
grand total sum of dis- sum of dis- not sup- sum of dis- sum of dis-
|
|
played values played values ported played values played values
|
|
|
|
balance
|
|
(bs, bse,
|
|
cf, is)
|
|
with report
|
|
interval
|
|
starting sums of costs value at re- not sup- value at re- sums of post-
|
|
balances of postings port start of ported port start of ings before
|
|
(-H) before report sums of all sums of all report start
|
|
start postings be- postings be-
|
|
fore report fore report
|
|
start start
|
|
balance sums of costs same as not sup- balance value at
|
|
changes of postings --value=end ported change in DATE/today of
|
|
(bal, is, in period each period, sums of post-
|
|
bs valued at pe- ings
|
|
--change, riod ends
|
|
cf
|
|
--change)
|
|
end bal- sums of costs same as not sup- period end value at
|
|
ances (bal of postings --value=end ported balances, DATE/today of
|
|
-H, is --H, from before valued at pe- sums of post-
|
|
bs, cf) report start riod ends ings
|
|
to period end
|
|
budget like balance like balance not sup- like balances like balance
|
|
amounts changes/end changes/end ported changes/end
|
|
(--budget) balances balances balances
|
|
row totals, sums, aver- sums, aver- not sup- sums, aver- sums, aver-
|
|
row aver- ages of dis- ages of dis- ported ages of dis- ages of dis-
|
|
ages (-T, played values played values played values played values
|
|
-A)
|
|
column to- sums of dis- sums of dis- not sup- sums of dis- sums of dis-
|
|
tals played values played values ported played values played values
|
|
grand to- sum, average sum, average not sup- sum, average sum, average
|
|
tal, grand of column to- of column to- ported of column to- of column to-
|
|
average tals tals tals tals
|
|
|
|
|
|
|
|
--cumulative is omitted to save space, it works like -H but with a zero
|
|
starting balance.
|
|
|
|
Glossary:
|
|
|
|
cost calculated using price(s) recorded in the transaction(s).
|
|
|
|
value market value using available market price declarations, or the
|
|
unchanged amount if no conversion rate can be found.
|
|
|
|
report start
|
|
the first day of the report period specified with -b or -p or
|
|
date:, otherwise today.
|
|
|
|
report or journal start
|
|
the first day of the report period specified with -b or -p or
|
|
date:, otherwise the earliest transaction date in the journal,
|
|
otherwise today.
|
|
|
|
report end
|
|
the last day of the report period specified with -e or -p or
|
|
date:, otherwise today.
|
|
|
|
report or journal end
|
|
the last day of the report period specified with -e or -p or
|
|
date:, otherwise the latest transaction date in the journal,
|
|
otherwise today.
|
|
|
|
report interval
|
|
a flag (-D/-W/-M/-Q/-Y) or period expression that activates the
|
|
report's multi-period mode (whether showing one or many subperi-
|
|
ods).
|
|
|
|
PIVOTING
|
|
Normally hledger sums amounts, and organizes them in a hierarchy, based
|
|
on account name. The --pivot FIELD option causes it to sum and orga-
|
|
nize hierarchy based on the value of some other field instead. FIELD
|
|
can be: code, description, payee, note, or the full name (case insensi-
|
|
tive) of any tag. As with account names, values containing colon:sepa-
|
|
rated:parts will be displayed hierarchically in reports.
|
|
|
|
--pivot is a general option affecting all reports; you can think of
|
|
hledger transforming the journal before any other processing, replacing
|
|
every posting'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's not present.
|
|
|
|
An example:
|
|
|
|
2016/02/16 Member Fee Payment
|
|
assets:bank account 2 EUR
|
|
income:member fees -2 EUR ; member: John Doe
|
|
|
|
Normal balance report showing account names:
|
|
|
|
$ hledger balance
|
|
2 EUR assets:bank account
|
|
-2 EUR income:member fees
|
|
--------------------
|
|
0
|
|
|
|
Pivoted balance report, using member: tag values instead:
|
|
|
|
$ hledger balance --pivot member
|
|
2 EUR
|
|
-2 EUR John Doe
|
|
--------------------
|
|
0
|
|
|
|
One way to show only amounts with a member: value (using a query, de-
|
|
scribed below):
|
|
|
|
$ hledger balance --pivot member tag:member=.
|
|
-2 EUR John Doe
|
|
--------------------
|
|
-2 EUR
|
|
|
|
Another way (the acct: query matches against the pivoted "account
|
|
name"):
|
|
|
|
$ hledger balance --pivot member acct:.
|
|
-2 EUR John Doe
|
|
--------------------
|
|
-2 EUR
|
|
|
|
OUTPUT
|
|
Output destination
|
|
hledger commands send their output to the terminal by default. You can
|
|
of course redirect this, eg into a file, using standard shell syntax:
|
|
|
|
$ hledger print > foo.txt
|
|
|
|
Some commands (print, register, stats, the balance commands) also pro-
|
|
vide the -o/--output-file option, which does the same thing without
|
|
needing the shell. Eg:
|
|
|
|
$ hledger print -o foo.txt
|
|
$ hledger print -o - # write to stdout (the default)
|
|
|
|
Output format
|
|
Some commands (print, register, the balance commands) offer a choice of
|
|
output format. In addition to the usual plain text format (txt), there
|
|
are CSV (csv), HTML (html), JSON (json) and SQL (sql). This is con-
|
|
trolled by the -O/--output-format option:
|
|
|
|
$ hledger print -O csv
|
|
|
|
or, by a file extension specified with -o/--output-file:
|
|
|
|
$ hledger balancesheet -o foo.html # write HTML to foo.html
|
|
|
|
The -O option can be used to override the file extension if needed:
|
|
|
|
$ hledger balancesheet -o foo.txt -O html # write HTML to foo.txt
|
|
|
|
Some notes about JSON output:
|
|
|
|
o This feature is marked experimental, and not yet much used; you
|
|
should expect our JSON to evolve. Real-world feedback is welcome.
|
|
|
|
o Our JSON is rather large and verbose, as it is quite a faithful rep-
|
|
resentation of hledger'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.
|
|
|
|
o 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'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)
|
|
|
|
Notes about SQL output:
|
|
|
|
o SQL output is also marked experimental, and much like JSON could use
|
|
real-world feedback.
|
|
|
|
o SQL output is expected to work with sqlite, MySQL and PostgreSQL
|
|
|
|
o SQL output is structured with the expectations that statements will
|
|
be executed in the empty database. If you already have tables cre-
|
|
ated via SQL output of hledger, you would probably want to either
|
|
clear tables of existing data (via delete or truncate SQL statements)
|
|
or drop tables completely as otherwise your postings will be duped.
|
|
|
|
COMMANDS
|
|
hledger provides a number of commands for producing reports and manag-
|
|
ing your data. Run hledger with no arguments to list the commands
|
|
available, and hledger CMD to run a command. CMD can be the full com-
|
|
mand name, or its standard abbreviation shown in the commands list, or
|
|
any unambiguous prefix of the name. Eg: hledger bal.
|
|
|
|
Here are the built-in commands, with the most often-used in bold:
|
|
|
|
Data entry:
|
|
|
|
These data entry commands are the only ones which can modify your jour-
|
|
nal file.
|
|
|
|
o add - add transactions using guided prompts
|
|
|
|
o import - add any new transactions from other files (eg csv)
|
|
|
|
Data management:
|
|
|
|
o check - check for various kinds of issue in the data
|
|
|
|
o close (equity) - generate balance-resetting transactions
|
|
|
|
o diff - compare account transactions in two journal files
|
|
|
|
o rewrite - generate extra postings, similar to print --auto
|
|
|
|
Financial statements:
|
|
|
|
o aregister (areg) - show transactions in a particular account
|
|
|
|
o balancesheet (bs) - show assets, liabilities and net worth
|
|
|
|
o balancesheetequity (bse) - show assets, liabilities and equity
|
|
|
|
o cashflow (cf) - show changes in liquid assets
|
|
|
|
o incomestatement (is) - show revenues and expenses
|
|
|
|
o roi - show return on investments
|
|
|
|
Miscellaneous reports:
|
|
|
|
o accounts - show account names
|
|
|
|
o activity - show postings-per-interval bar charts
|
|
|
|
o balance (bal) - show balance changes/end balances/budgets in any ac-
|
|
counts
|
|
|
|
o codes - show transaction codes
|
|
|
|
o commodities - show commodity/currency symbols
|
|
|
|
o descriptions - show unique transaction descriptions
|
|
|
|
o files - show input file paths
|
|
|
|
o help - show hledger user manuals in several formats
|
|
|
|
o notes - show unique note segments of transaction descriptions
|
|
|
|
o payees - show unique payee segments of transaction descriptions
|
|
|
|
o prices - show market price records
|
|
|
|
o print - show transactions (journal entries)
|
|
|
|
o print-unique - show only transactions with unique descriptions
|
|
|
|
o register (reg) - show postings in one or more accounts & running to-
|
|
tal
|
|
|
|
o register-match - show a recent posting that best matches a descrip-
|
|
tion
|
|
|
|
o stats - show journal statistics
|
|
|
|
o tags - show tag names
|
|
|
|
o test - run self tests
|
|
|
|
Add-on commands:
|
|
|
|
Programs or scripts named hledger-SOMETHING in your PATH are add-on
|
|
commands; these appear in the commands list with a + mark. Two of
|
|
these are maintained and released with hledger:
|
|
|
|
o ui - an efficient terminal interface (TUI) for hledger
|
|
|
|
o web - a simple web interface (WUI) for hledger
|
|
|
|
And these add-ons are maintained separately:
|
|
|
|
o iadd - a more interactive alternative for the add command
|
|
|
|
o interest - generates interest transactions according to various
|
|
schemes
|
|
|
|
o stockquotes - downloads market prices for your commodities from Al-
|
|
phaVantage (experimental)
|
|
|
|
Next, the detailed command docs, in alphabetical order.
|
|
|
|
accounts
|
|
accounts
|
|
Show account names.
|
|
|
|
This command lists account names, either declared with account direc-
|
|
tives (--declared), posted to (--used), or both (the default). With
|
|
query arguments, only matched account names and account names refer-
|
|
enced by matched postings are shown. It shows a flat list by default.
|
|
With --tree, it uses indentation to show the account hierarchy. In
|
|
flat mode you can add --drop N to omit the first few account name com-
|
|
ponents. Account names can be depth-clipped with depth:N or --depth N
|
|
or -N.
|
|
|
|
Examples:
|
|
|
|
$ hledger accounts
|
|
assets:bank:checking
|
|
assets:bank:saving
|
|
assets:cash
|
|
expenses:food
|
|
expenses:supplies
|
|
income:gifts
|
|
income:salary
|
|
liabilities:debts
|
|
|
|
activity
|
|
activity
|
|
Show an ascii barchart of posting counts per interval.
|
|
|
|
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.
|
|
|
|
Examples:
|
|
|
|
$ hledger activity --quarterly
|
|
2008-01-01 **
|
|
2008-04-01 *******
|
|
2008-07-01
|
|
2008-10-01 **
|
|
|
|
add
|
|
add
|
|
Prompt for transactions and add them to the journal. Any arguments
|
|
will be used as default inputs for the first N prompts.
|
|
|
|
Many hledger users edit their journals directly with a text editor, or
|
|
generate them from CSV. For more interactive data entry, there is the
|
|
add command, which prompts interactively on the console for new trans-
|
|
actions, and appends them to the journal file (if there are multiple -f
|
|
FILE options, the first file is used.) Existing transactions are not
|
|
changed. This is the only hledger command that writes to the journal
|
|
file.
|
|
|
|
To use it, just run hledger add and follow the prompts. You can add as
|
|
many transactions as you like; when you are finished, enter . or press
|
|
control-d or control-c to exit.
|
|
|
|
Features:
|
|
|
|
o add tries to provide useful defaults, using the most similar (by de-
|
|
scription) recent transaction (filtered by the query, if any) as a
|
|
template.
|
|
|
|
o You can also set the initial defaults with command line arguments.
|
|
|
|
o Readline-style edit keys can be used during data entry.
|
|
|
|
o The tab key will auto-complete whenever possible - accounts, descrip-
|
|
tions, dates (yesterday, today, tomorrow). If the input area is
|
|
empty, it will insert the default value.
|
|
|
|
o If the journal defines a default commodity, it will be added to any
|
|
bare numbers entered.
|
|
|
|
o A parenthesised transaction code may be entered following a date.
|
|
|
|
o Comments and tags may be entered following a description or amount.
|
|
|
|
o If you make a mistake, enter < at any prompt to go one step backward.
|
|
|
|
o Input prompts are displayed in a different colour when the terminal
|
|
supports it.
|
|
|
|
Example (see the tutorial for a detailed explanation):
|
|
|
|
$ 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> $
|
|
|
|
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).
|
|
|
|
aregister
|
|
aregister, areg
|
|
Show transactions affecting a particular account, and the account's
|
|
running balance.
|
|
|
|
aregister shows the transactions affecting a particular account (and
|
|
its subaccounts), from the point of view of that account. Each line
|
|
shows:
|
|
|
|
o the transaction's (or posting's, see below) date
|
|
|
|
o the names of the other account(s) involved
|
|
|
|
o the net change to this account's balance
|
|
|
|
o the account's historical running balance (including balance from
|
|
transactions before the report start date).
|
|
|
|
With aregister, each line represents a whole transaction - as in
|
|
hledger-ui, hledger-web, and your bank statement. By contrast, the
|
|
register command shows individual postings, across all accounts. You
|
|
might prefer aregister for reconciling with real-world asset/liability
|
|
accounts, and register for reviewing detailed revenues/expenses.
|
|
|
|
An account must be specified as the first argument, which should be the
|
|
full account name or an account pattern (regular expression). aregis-
|
|
ter will show transactions in this account (the first one matched) and
|
|
any of its subaccounts.
|
|
|
|
Any additional arguments form a query which will filter the transac-
|
|
tions shown.
|
|
|
|
Transactions making a net change of zero are not shown by default; add
|
|
the -E/--empty flag to show them.
|
|
|
|
This command also supports the output destination and output format op-
|
|
tions The output formats supported are txt, csv, and json.
|
|
|
|
aregister and custom posting dates
|
|
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's the posting date that is shown.) This
|
|
ensures that aregister can show an accurate historical running balance,
|
|
matching the one shown by register -H with the same arguments.
|
|
|
|
To filter strictly by transaction date instead, add the --txn-dates
|
|
flag. If you use this flag and some of your postings have custom
|
|
dates, it's probably best to assume the running balance is wrong.
|
|
|
|
Examples:
|
|
|
|
Show all transactions and historical running balance in the first ac-
|
|
count whose name contains "checking":
|
|
|
|
$ hledger areg checking
|
|
|
|
Show transactions and historical running balance in all asset accounts
|
|
during july:
|
|
|
|
$ hledger areg assets date:jul
|
|
|
|
balance
|
|
balance, bal
|
|
Show accounts and their balances.
|
|
|
|
The balance command is hledger's most versatile command. Note, despite
|
|
the name, it is not always used for showing real-world account bal-
|
|
ances; the more accounting-aware balancesheet and incomestatement may
|
|
be more convenient for that.
|
|
|
|
By default, it displays all accounts, and each account's change in bal-
|
|
ance during the entire period of the journal. Balance changes are cal-
|
|
culated by adding up the postings in each account. You can limit the
|
|
postings matched, by a query, to see fewer accounts, changes over a
|
|
different time period, changes from only cleared transactions, etc.
|
|
|
|
If you include an account's complete history of postings in the report,
|
|
the balance change is equivalent to the account's current ending bal-
|
|
ance. For a real-world account, typically you won't have all transac-
|
|
tions in the journal; instead you'll have all transactions after a cer-
|
|
tain date, and an "opening balances" transaction setting the correct
|
|
starting balance on that date. Then the balance command will show
|
|
real-world account balances. In some cases the -H/--historical flag is
|
|
used to ensure this (more below).
|
|
|
|
This command also supports the output destination and output format op-
|
|
tions The output formats supported are (in most modes): txt, csv, html,
|
|
and json.
|
|
|
|
The balance command can produce several styles of report:
|
|
|
|
Classic balance report
|
|
This is the original balance report, as found in Ledger. It usually
|
|
looks like this:
|
|
|
|
$ 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
|
|
|
|
By default, accounts are displayed hierarchically, with subaccounts in-
|
|
dented below their parent, with accounts at each level of the tree
|
|
sorted by declaration order if declared, then by account name.
|
|
|
|
"Boring" accounts, which contain a single interesting subaccount and no
|
|
balance of their own, are elided into the following line for more com-
|
|
pact output. (Eg above, the "liabilities" account.) Use --no-elide to
|
|
prevent this.
|
|
|
|
Account balances are "inclusive" - they include the balances of any
|
|
subaccounts.
|
|
|
|
Accounts which have zero balance (and no non-zero subaccounts) are
|
|
omitted. Use -E/--empty to show them.
|
|
|
|
A final total is displayed by default; use -N/--no-total to suppress
|
|
it, eg:
|
|
|
|
$ hledger balance -p 2008/6 expenses --no-total
|
|
$2 expenses
|
|
$1 food
|
|
$1 supplies
|
|
|
|
Customising the classic balance report
|
|
You can customise the layout of classic balance reports with --format
|
|
FMT:
|
|
|
|
$ hledger balance --format "%20(account) %12(total)"
|
|
assets $-1
|
|
bank:saving $1
|
|
cash $-2
|
|
expenses $2
|
|
food $1
|
|
supplies $1
|
|
income $-2
|
|
gifts $-1
|
|
salary $-1
|
|
liabilities:debts $1
|
|
---------------------------------
|
|
0
|
|
|
|
The FMT format string (plus a newline) specifies the formatting applied
|
|
to each account/balance pair. It may contain any suitable text, with
|
|
data fields interpolated like so:
|
|
|
|
%[MIN][.MAX](FIELDNAME)
|
|
|
|
o MIN pads with spaces to at least this width (optional)
|
|
|
|
o MAX truncates at this width (optional)
|
|
|
|
o FIELDNAME must be enclosed in parentheses, and can be one of:
|
|
|
|
o depth_spacer - a number of spaces equal to the account's depth, or
|
|
if MIN is specified, MIN * depth spaces.
|
|
|
|
o account - the account's name
|
|
|
|
o total - the account's balance/posted total, right justified
|
|
|
|
Also, FMT can begin with an optional prefix to control how multi-com-
|
|
modity amounts are rendered:
|
|
|
|
o %_ - render on multiple lines, bottom-aligned (the default)
|
|
|
|
o %^ - render on multiple lines, top-aligned
|
|
|
|
o %, - render on one line, comma-separated
|
|
|
|
There are some quirks. Eg in one-line mode, %(depth_spacer) has no ef-
|
|
fect, instead %(account) has indentation built in. Experimentation may
|
|
be needed to get pleasing results.
|
|
|
|
Some example formats:
|
|
|
|
o %(total) - the account's total
|
|
|
|
o %-20.20(account) - the account's name, left justified, padded to 20
|
|
characters and clipped at 20 characters
|
|
|
|
o %,%-50(account) %25(total) - account name padded to 50 characters,
|
|
total padded to 20 characters, with multiple commodities rendered on
|
|
one line
|
|
|
|
o %20(total) %2(depth_spacer)%-(account) - the default format for the
|
|
single-column balance report
|
|
|
|
Colour support
|
|
In terminal output, when colour is enabled, the balance command shows
|
|
negative amounts in red.
|
|
|
|
Flat mode
|
|
To see a flat list instead of the default hierarchical display, use
|
|
--flat. In this mode, accounts (unless depth-clipped) show their full
|
|
names and "exclusive" balance, excluding any subaccount balances. In
|
|
this mode, you can also use --drop N to omit the first few account name
|
|
components.
|
|
|
|
$ hledger balance -p 2008/6 expenses -N --flat --drop 1
|
|
$1 food
|
|
$1 supplies
|
|
|
|
Depth limited balance reports
|
|
With --depth N or depth:N or just -N, 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.
|
|
|
|
$ hledger balance -N -1
|
|
$-1 assets
|
|
$2 expenses
|
|
$-2 income
|
|
$1 liabilities
|
|
|
|
Flat-mode balance reports, which normally show exclusive balances, show
|
|
inclusive balances at the depth limit.
|
|
|
|
Percentages
|
|
With -% or --percent, balance reports show each account's value ex-
|
|
pressed as a percentage of the column's total. This is useful to get
|
|
an overview of the relative sizes of account balances. For example to
|
|
obtain an overview of expenses:
|
|
|
|
$ hledger balance expenses -%
|
|
100.0 % expenses
|
|
50.0 % food
|
|
50.0 % supplies
|
|
--------------------
|
|
100.0 %
|
|
|
|
Note that --tree does not have an effect on -%. The percentages are
|
|
always relative to the total sum of each column, they are never rela-
|
|
tive to the parent account.
|
|
|
|
Since the percentages are relative to the columns sum, it is usually
|
|
not useful to calculate percentages if the signs of the amounts are
|
|
mixed. Although the results are technically correct, they are most
|
|
likely useless. Especially in a balance report that sums up to zero
|
|
(eg hledger balance -B) all percentage values will be zero.
|
|
|
|
This flag does not work if the report contains any mixed commodity ac-
|
|
counts. If there are mixed commodity accounts in the report be sure to
|
|
use -V or -B to coerce the report into using a single commodity.
|
|
|
|
Sorting by amount
|
|
With -S/--sort-amount, accounts with the largest (most positive) bal-
|
|
ances are shown first. For example, hledger bal expenses -MAS shows
|
|
your biggest averaged monthly expenses first.
|
|
|
|
Revenues and liability balances are typically negative, however, so -S
|
|
shows these in reverse order. To work around this, you can add --in-
|
|
vert to flip the signs. Or, use one of the sign-flipping reports like
|
|
balancesheet or incomestatement, which also support -S. Eg: hledger is
|
|
-MAS.
|
|
|
|
Multicolumn balance report
|
|
Multicolumn or tabular balance reports are a very useful hledger fea-
|
|
ture, and usually the preferred style. They share many of the above
|
|
features, but they show the report as a table, with columns represent-
|
|
ing time periods. This mode is activated by providing a reporting in-
|
|
terval.
|
|
|
|
There are three types of multicolumn balance report, showing different
|
|
information:
|
|
|
|
1. By default: each column shows the sum of postings in that period, ie
|
|
the account's change of balance in that period. This is useful eg
|
|
for a monthly income statement:
|
|
|
|
$ hledger balance --quarterly income expenses -E
|
|
Balance changes in 2008:
|
|
|
|
|| 2008q1 2008q2 2008q3 2008q4
|
|
===================++=================================
|
|
expenses:food || 0 $1 0 0
|
|
expenses:supplies || 0 $1 0 0
|
|
income:gifts || 0 $-1 0 0
|
|
income:salary || $-1 0 0 0
|
|
-------------------++---------------------------------
|
|
|| $-1 $1 0 0
|
|
|
|
2. With --cumulative: each column shows the ending balance for that pe-
|
|
riod, accumulating the changes across periods, starting from 0 at
|
|
the report start date:
|
|
|
|
$ hledger balance --quarterly income expenses -E --cumulative
|
|
Ending balances (cumulative) in 2008:
|
|
|
|
|| 2008/03/31 2008/06/30 2008/09/30 2008/12/31
|
|
===================++=================================================
|
|
expenses:food || 0 $1 $1 $1
|
|
expenses:supplies || 0 $1 $1 $1
|
|
income:gifts || 0 $-1 $-1 $-1
|
|
income:salary || $-1 $-1 $-1 $-1
|
|
-------------------++-------------------------------------------------
|
|
|| $-1 0 0 0
|
|
|
|
3. With --historical/-H: 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:
|
|
|
|
$ hledger balance ^assets ^liabilities --quarterly --historical --begin 2008/4/1
|
|
Ending balances (historical) in 2008/04/01-2008/12/31:
|
|
|
|
|| 2008/06/30 2008/09/30 2008/12/31
|
|
======================++=====================================
|
|
assets:bank:checking || $1 $1 0
|
|
assets:bank:saving || $1 $1 $1
|
|
assets:cash || $-2 $-2 $-2
|
|
liabilities:debts || 0 0 $1
|
|
----------------------++-------------------------------------
|
|
|| 0 0 0
|
|
|
|
Note that --cumulative or --historical/-H disable --row-total/-T, since
|
|
summing end balances generally does not make sense.
|
|
|
|
Multicolumn balance reports display accounts in flat mode by default;
|
|
to see the hierarchy, use --tree.
|
|
|
|
With a reporting interval (like --quarterly above), the report
|
|
start/end dates will be adjusted if necessary so that they encompass
|
|
the displayed report periods. This is so that the first and last peri-
|
|
ods will be "full" and comparable to the others.
|
|
|
|
The -E/--empty flag does two things in multicolumn balance reports:
|
|
first, the report will show all columns within the specified report pe-
|
|
riod (without -E, leading and trailing columns with all zeroes are not
|
|
shown). Second, all accounts which existed at the report start date
|
|
will be considered, not just the ones with activity during the report
|
|
period (use -E to include low-activity accounts which would otherwise
|
|
would be omitted).
|
|
|
|
The -T/--row-total flag adds an additional column showing the total for
|
|
each row.
|
|
|
|
The -A/--average flag adds a column showing the average value in each
|
|
row.
|
|
|
|
Here's an example of all three:
|
|
|
|
$ hledger balance -Q income expenses --tree -ETA
|
|
Balance changes in 2008:
|
|
|
|
|| 2008q1 2008q2 2008q3 2008q4 Total Average
|
|
============++===================================================
|
|
expenses || 0 $2 0 0 $2 $1
|
|
food || 0 $1 0 0 $1 0
|
|
supplies || 0 $1 0 0 $1 0
|
|
income || $-1 $-1 0 0 $-2 $-1
|
|
gifts || 0 $-1 0 0 $-1 0
|
|
salary || $-1 0 0 0 $-1 0
|
|
------------++---------------------------------------------------
|
|
|| $-1 $1 0 0 0 0
|
|
|
|
(Average is rounded to the dollar here since all journal amounts are)
|
|
|
|
The --transpose flag can be used to exchange the rows and columns of a
|
|
multicolumn report.
|
|
|
|
When showing multicommodity amounts, multicolumn balance reports will
|
|
elide any amounts which have more than two commodities, since otherwise
|
|
columns could get very wide. The --no-elide flag disables this. Hid-
|
|
ing totals with the -N/--no-total flag can also help reduce the width
|
|
of multicommodity reports.
|
|
|
|
When the report is still too wide, a good workaround is to pipe it into
|
|
less -RS (-R for colour, -S to chop long lines). Eg: hledger bal -D
|
|
--color=yes | less -RS.
|
|
|
|
Budget report
|
|
With --budget, 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 in-
|
|
come, expenses, time usage, etc. --budget is most often combined with
|
|
a report interval.
|
|
|
|
For example, you can take average monthly expenses in the common ex-
|
|
pense categories to construct a minimal monthly budget:
|
|
|
|
;; Budget
|
|
~ monthly
|
|
income $2000
|
|
expenses:food $400
|
|
expenses:bus $50
|
|
expenses:movies $30
|
|
assets:bank:checking
|
|
|
|
;; Two months worth of expenses
|
|
2017-11-01
|
|
income $1950
|
|
expenses:food $396
|
|
expenses:bus $49
|
|
expenses:movies $30
|
|
expenses:supplies $20
|
|
assets:bank:checking
|
|
|
|
2017-12-01
|
|
income $2100
|
|
expenses:food $412
|
|
expenses:bus $53
|
|
expenses:gifts $100
|
|
assets:bank:checking
|
|
|
|
You can now see a monthly budget report:
|
|
|
|
$ hledger balance -M --budget
|
|
Budget performance in 2017/11/01-2017/12/31:
|
|
|
|
|| Nov Dec
|
|
======================++====================================================
|
|
assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
|
|
assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
|
|
assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
|
|
expenses || $495 [ 103% of $480] $565 [ 118% of $480]
|
|
expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]
|
|
expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]
|
|
expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]
|
|
income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]
|
|
----------------------++----------------------------------------------------
|
|
|| 0 [ 0] 0 [ 0]
|
|
|
|
This is different from a normal balance report in several ways:
|
|
|
|
o Only accounts with budget goals during the report period are shown,
|
|
by default.
|
|
|
|
o In each column, in square brackets after the actual amount, budget
|
|
goal amounts are shown, and the actual/goal percentage. (Note: bud-
|
|
get goals should be in the same commodity as the actual amount.)
|
|
|
|
o All parent accounts are always shown, even in flat mode. Eg assets,
|
|
assets:bank, and expenses above.
|
|
|
|
o Amounts always include all subaccounts, budgeted or unbudgeted, even
|
|
in flat mode.
|
|
|
|
This means that the numbers displayed will not always add up! Eg above,
|
|
the expenses actual amount includes the gifts and supplies transac-
|
|
tions, but the expenses:gifts and expenses:supplies accounts are not
|
|
shown, as they have no budget amounts declared.
|
|
|
|
This can be confusing. When you need to make things clearer, use the
|
|
-E/--empty flag, which will reveal all accounts including unbudgeted
|
|
ones, giving the full picture. Eg:
|
|
|
|
$ hledger balance -M --budget --empty
|
|
Budget performance in 2017/11/01-2017/12/31:
|
|
|
|
|| Nov Dec
|
|
======================++====================================================
|
|
assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
|
|
assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
|
|
assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]
|
|
expenses || $495 [ 103% of $480] $565 [ 118% of $480]
|
|
expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]
|
|
expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]
|
|
expenses:gifts || 0 $100
|
|
expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]
|
|
expenses:supplies || $20 0
|
|
income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]
|
|
----------------------++----------------------------------------------------
|
|
|| 0 [ 0] 0 [ 0]
|
|
|
|
You can roll over unspent budgets to next period with --cumulative:
|
|
|
|
$ hledger balance -M --budget --cumulative
|
|
Budget performance in 2017/11/01-2017/12/31:
|
|
|
|
|| Nov Dec
|
|
======================++====================================================
|
|
assets || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]
|
|
assets:bank || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]
|
|
assets:bank:checking || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]
|
|
expenses || $495 [ 103% of $480] $1060 [ 110% of $960]
|
|
expenses:bus || $49 [ 98% of $50] $102 [ 102% of $100]
|
|
expenses:food || $396 [ 99% of $400] $808 [ 101% of $800]
|
|
expenses:movies || $30 [ 100% of $30] $30 [ 50% of $60]
|
|
income || $1950 [ 98% of $2000] $4050 [ 101% of $4000]
|
|
----------------------++----------------------------------------------------
|
|
|| 0 [ 0] 0 [ 0]
|
|
|
|
For more examples and notes, see Budgeting.
|
|
|
|
Budget report start date
|
|
This might be a bug, but for now: when making budget reports, it's a
|
|
good idea to explicitly set the report's start date to the first day of
|
|
a reporting period, because a periodic rule like ~ monthly generates
|
|
its transactions on the 1st of each month, and if your journal has no
|
|
regular transactions on the 1st, the default report start date could
|
|
exclude that budget goal, which can be a little surprising. Eg here
|
|
the default report period is just the day of 2020-01-15:
|
|
|
|
~ monthly in 2020
|
|
(expenses:food) $500
|
|
|
|
2020-01-15
|
|
expenses:food $400
|
|
assets:checking
|
|
|
|
$ hledger bal expenses --budget
|
|
Budget performance in 2020-01-15:
|
|
|
|
|| 2020-01-15
|
|
==============++============
|
|
<unbudgeted> || $400
|
|
--------------++------------
|
|
|| $400
|
|
|
|
To avoid this, specify the budget report's period, or at least the
|
|
start date, with -b/-e/-p/date:, to ensure it includes the budget goal
|
|
transactions (periodic transactions) that you want. Eg, adding -b
|
|
2020/1/1 to the above:
|
|
|
|
$ hledger bal expenses --budget -b 2020/1/1
|
|
Budget performance in 2020-01-01..2020-01-15:
|
|
|
|
|| 2020-01-01..2020-01-15
|
|
===============++========================
|
|
expenses:food || $400 [80% of $500]
|
|
---------------++------------------------
|
|
|| $400 [80% of $500]
|
|
|
|
Nested budgets
|
|
You can add budgets to any account in your account hierarchy. If you
|
|
have budgets on both parent account and some of its children, then bud-
|
|
get(s) of the child account(s) would be added to the budget of their
|
|
parent, much like account balances behave.
|
|
|
|
In the most simple case this means that once you add a budget to any
|
|
account, all its parents would have budget as well.
|
|
|
|
To illustrate this, consider the following budget:
|
|
|
|
~ monthly from 2019/01
|
|
expenses:personal $1,000.00
|
|
expenses:personal:electronics $100.00
|
|
liabilities
|
|
|
|
With this, monthly budget for electronics is defined to be $100 and
|
|
budget for personal expenses is an additional $1000, which implicitly
|
|
means that budget for both expenses:personal and expenses is $1100.
|
|
|
|
Transactions in expenses:personal:electronics will be counted both to-
|
|
wards its $100 budget and $1100 of expenses:personal , and transactions
|
|
in any other subaccount of expenses:personal would be counted towards
|
|
only towards the budget of expenses:personal.
|
|
|
|
For example, let's consider these transactions:
|
|
|
|
~ monthly from 2019/01
|
|
expenses:personal $1,000.00
|
|
expenses:personal:electronics $100.00
|
|
liabilities
|
|
|
|
2019/01/01 Google home hub
|
|
expenses:personal:electronics $90.00
|
|
liabilities $-90.00
|
|
|
|
2019/01/02 Phone screen protector
|
|
expenses:personal:electronics:upgrades $10.00
|
|
liabilities
|
|
|
|
2019/01/02 Weekly train ticket
|
|
expenses:personal:train tickets $153.00
|
|
liabilities
|
|
|
|
2019/01/03 Flowers
|
|
expenses:personal $30.00
|
|
liabilities
|
|
|
|
As you can see, we have transactions in expenses:personal:electron-
|
|
ics:upgrades and expenses:personal:train tickets, and since both of
|
|
these accounts are without explicitly defined budget, these transac-
|
|
tions would be counted towards budgets of expenses:personal:electronics
|
|
and expenses:personal accordingly:
|
|
|
|
$ hledger balance --budget -M
|
|
Budget performance in 2019/01:
|
|
|
|
|| Jan
|
|
===============================++===============================
|
|
expenses || $283.00 [ 26% of $1100.00]
|
|
expenses:personal || $283.00 [ 26% of $1100.00]
|
|
expenses:personal:electronics || $100.00 [ 100% of $100.00]
|
|
liabilities || $-283.00 [ 26% of $-1100.00]
|
|
-------------------------------++-------------------------------
|
|
|| 0 [ 0]
|
|
|
|
And with --empty, we can get a better picture of budget allocation and
|
|
consumption:
|
|
|
|
$ hledger balance --budget -M --empty
|
|
Budget performance in 2019/01:
|
|
|
|
|| Jan
|
|
========================================++===============================
|
|
expenses || $283.00 [ 26% of $1100.00]
|
|
expenses:personal || $283.00 [ 26% of $1100.00]
|
|
expenses:personal:electronics || $100.00 [ 100% of $100.00]
|
|
expenses:personal:electronics:upgrades || $10.00
|
|
expenses:personal:train tickets || $153.00
|
|
liabilities || $-283.00 [ 26% of $-1100.00]
|
|
----------------------------------------++-------------------------------
|
|
|| 0 [ 0]
|
|
|
|
balancesheet
|
|
balancesheet, bs
|
|
This command displays a balance sheet, showing historical ending bal-
|
|
ances 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.
|
|
|
|
The asset and liability accounts shown are those accounts declared with
|
|
the Asset or Cash or Liability type, or otherwise all accounts under a
|
|
top-level asset or liability account (case insensitive, plurals al-
|
|
lowed).
|
|
|
|
(This report is essentially similar to "hledger balance --historical
|
|
assets liabilities", with liabilities sign-flipped.)
|
|
|
|
Example:
|
|
|
|
$ hledger balancesheet
|
|
Balance Sheet
|
|
|
|
Assets:
|
|
$-1 assets
|
|
$1 bank:saving
|
|
$-2 cash
|
|
--------------------
|
|
$-1
|
|
|
|
Liabilities:
|
|
$1 liabilities:debts
|
|
--------------------
|
|
$1
|
|
|
|
Total:
|
|
--------------------
|
|
0
|
|
|
|
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 --change/--cumulative/--historical. Normally bal-
|
|
ancesheet shows historical ending balances, which is what you need for
|
|
a balance sheet; note this means it ignores report begin dates (and
|
|
-T/--row-total, since summing end balances generally does not make
|
|
sense). Instead of absolute values percentages can be displayed with
|
|
-%.
|
|
|
|
This command also supports the output destination and output format op-
|
|
tions The output formats supported are txt, csv, html, and (experimen-
|
|
tal) json.
|
|
|
|
balancesheetequity
|
|
balancesheetequity, bse
|
|
This command displays a balance sheet, showing historical ending bal-
|
|
ances of asset, liability and equity accounts. Amounts are shown with
|
|
normal positive sign, as in conventional financial statements.
|
|
|
|
The asset, liability and equity accounts shown are those accounts de-
|
|
clared with the Asset, Cash, Liability or Equity type, or otherwise all
|
|
accounts under a top-level asset, liability or equity account (case in-
|
|
sensitive, plurals allowed).
|
|
|
|
(This report is essentially similar to "hledger balance --historical
|
|
assets liabilities equity", with liabilities and equity sign-flipped.)
|
|
|
|
Example:
|
|
|
|
$ 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
|
|
|
|
This command also supports the output destination and output format op-
|
|
tions The output formats supported are txt, csv, html, and (experimen-
|
|
tal) json.
|
|
|
|
cashflow
|
|
cashflow, cf
|
|
This command displays a cashflow statement, showing the inflows and
|
|
outflows affecting "cash" (ie, liquid) assets. Amounts are shown with
|
|
normal positive sign, as in conventional financial statements.
|
|
|
|
The "cash" accounts shown are those accounts declared with the Cash
|
|
type, or otherwise all accounts under a top-level asset account (case
|
|
insensitive, plural allowed) which do not have fixed, investment, re-
|
|
ceivable or A/R in their name.
|
|
|
|
(This report is essentially similar to "hledger balance --change assets
|
|
not:fixed not:investment not:receivable".)
|
|
|
|
Example:
|
|
|
|
$ hledger cashflow
|
|
Cashflow Statement
|
|
|
|
Cash flows:
|
|
$-1 assets
|
|
$1 bank:saving
|
|
$-2 cash
|
|
--------------------
|
|
$-1
|
|
|
|
Total:
|
|
--------------------
|
|
$-1
|
|
|
|
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 --change/--cumulative/--historical. Instead of absolute val-
|
|
ues percentages can be displayed with -%.
|
|
|
|
This command also supports the output destination and output format op-
|
|
tions The output formats supported are txt, csv, html, and (experimen-
|
|
tal) json.
|
|
|
|
check
|
|
check
|
|
Check for various kinds of errors in your data. experimental
|
|
|
|
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 check command to run them on demand, with no output and a
|
|
zero exit code if all is well. Some examples:
|
|
|
|
hledger check # basic checks
|
|
hledger check -s # basic + strict checks
|
|
hledger check ordereddates uniqueleafnames # basic + specified checks
|
|
|
|
Here are the checks currently available:
|
|
|
|
Basic checks
|
|
These are always run by this command and other commands:
|
|
|
|
o parseable - data files are well-formed and can be successfully parsed
|
|
|
|
o autobalanced - all transactions are balanced, inferring missing
|
|
amounts where necessary, and possibly converting commodities using
|
|
transaction prices or automatically-inferred transaction prices
|
|
|
|
o assertions - all balance assertions in the journal are passing.
|
|
(This check can be disabled with -I/--ignore-assertions.)
|
|
|
|
Strict checks
|
|
These are always run by this and other commands when -s/--strict is
|
|
used (strict mode):
|
|
|
|
o accounts - all account names used by transactions have been declared
|
|
|
|
o commodities - all commodity symbols used have been declared
|
|
|
|
Other checks
|
|
These checks can be run by specifying their names as arguments to the
|
|
check command:
|
|
|
|
o ordereddates - transactions are ordered by date (similar to the old
|
|
check-dates command)
|
|
|
|
o uniqueleafnames - all account leaf names are unique (similar to the
|
|
old check-dupes command)
|
|
|
|
Add-on checks
|
|
Some checks are not yet integrated with this command, but are available
|
|
as add-on commands in https://github.com/simonmichael/hledger/tree/mas-
|
|
ter/bin:
|
|
|
|
o hledger-check-tagfiles - all tag values containing / (a forward
|
|
slash) exist as file paths
|
|
|
|
o hledger-check-fancyassertions - more complex balance assertions are
|
|
passing
|
|
|
|
You could make your own similar scripts to perform custom checks; Cook-
|
|
book -> Scripting may be helpful.
|
|
|
|
close
|
|
close, equity
|
|
Prints a "closing balances" transaction and an "opening balances"
|
|
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/ex-
|
|
penses to retained earnings at the end of a period.
|
|
|
|
You can print just one of these transactions by using the --close or
|
|
--open flag. You can customise their descriptions with the --close-
|
|
desc and --open-desc options.
|
|
|
|
One amountless posting to "equity:opening/closing balances" is added to
|
|
balance the transactions, by default. You can customise this account
|
|
name with --close-acct and --open-acct; if you specify only one of
|
|
these, it will be used for both.
|
|
|
|
With --x/--explicit, the equity posting's amount will be shown. And if
|
|
it involves multiple commodities, a posting for each commodity will be
|
|
shown, as with the print command.
|
|
|
|
With --interleaved, the equity postings are shown next to the postings
|
|
they balance, which makes troubleshooting easier.
|
|
|
|
By default, transaction prices in the journal are ignored when generat-
|
|
ing the closing/opening transactions. With --show-costs, this cost in-
|
|
formation is preserved (balance -B 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.
|
|
|
|
close usage
|
|
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 transac-
|
|
tion 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 transac-
|
|
tions cancel each other out. (They will show up in print or register
|
|
reports; you can exclude them with a query like not:desc:'(open-
|
|
ing|closing) balances'.)
|
|
|
|
If you're running a business, you might also use this command to "close
|
|
the books" 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 "equity:retained earn-
|
|
ings".)
|
|
|
|
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: hledger close -e OPEN-
|
|
INGDATE. Eg, to close/open on the 2018/2019 boundary, use -e 2019.
|
|
You can also use -p or date:PERIOD (any starting date is ignored).
|
|
|
|
Both transactions will include balance assertions for the closed/re-
|
|
opened accounts. You probably shouldn't use status or realness filters
|
|
(like -C or -R or status:) with this command, or the generated balance
|
|
assertions will depend on these flags. Likewise, if you run this com-
|
|
mand with --auto, the balance assertions will probably always require
|
|
--auto.
|
|
|
|
Examples:
|
|
|
|
Carrying asset/liability balances into a new file for 2019:
|
|
|
|
$ 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)
|
|
|
|
Now:
|
|
|
|
$ 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
|
|
|
|
Transactions spanning the closing date can complicate matters, breaking
|
|
balance assertions:
|
|
|
|
2018/12/30 a purchase made in 2018, clearing the following year
|
|
expenses:food 5
|
|
assets:bank:checking -5 ; [2019/1/2]
|
|
|
|
Here's one way to resolve that:
|
|
|
|
; 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's pending transactions
|
|
liabilities:pending 5 = 0
|
|
assets:checking
|
|
|
|
codes
|
|
codes
|
|
List the codes seen in transactions, in the order parsed.
|
|
|
|
This command prints the value of each transaction'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.
|
|
|
|
Transactions aren't required to have a code, and missing or empty codes
|
|
will not be shown by default. With the -E/--empty flag, they will be
|
|
printed as blank lines.
|
|
|
|
You can add a query to select a subset of transactions.
|
|
|
|
Examples:
|
|
|
|
1/1 (123)
|
|
(a) 1
|
|
|
|
1/1 ()
|
|
(a) 1
|
|
|
|
1/1
|
|
(a) 1
|
|
|
|
1/1 (126)
|
|
(a) 1
|
|
|
|
$ hledger codes
|
|
123
|
|
124
|
|
126
|
|
|
|
$ hledger codes -E
|
|
123
|
|
124
|
|
|
|
|
|
126
|
|
|
|
commodities
|
|
commodities
|
|
List all commodity/currency symbols used or declared in the journal.
|
|
|
|
descriptions
|
|
descriptions
|
|
List the unique descriptions that appear in transactions.
|
|
|
|
This command lists the unique descriptions that appear in transactions,
|
|
in alphabetic order. You can add a query to select a subset of trans-
|
|
actions.
|
|
|
|
Example:
|
|
|
|
$ hledger descriptions
|
|
Store Name
|
|
Gas Station | Petrol
|
|
Person A
|
|
|
|
diff
|
|
diff
|
|
Compares a particular account's transactions in two input files. It
|
|
shows any transactions to this account which are in one file but not in
|
|
the other.
|
|
|
|
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 mul-
|
|
tiple bank transactions have been combined into a single journal entry.
|
|
|
|
This is useful eg if you have downloaded an account'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.
|
|
|
|
Examples:
|
|
|
|
$ 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:
|
|
|
|
files
|
|
files
|
|
List all files included in the journal. With a REGEX argument, only
|
|
file names matching the regular expression (case sensitive) are shown.
|
|
|
|
help
|
|
help
|
|
Show the hledger user manual in one of several formats, optionally po-
|
|
sitioned at a given TOPIC (if possible). TOPIC is any heading, or
|
|
heading prefix, in the manual. Some examples: commands, print, 'auto
|
|
postings', periodic.
|
|
|
|
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.
|
|
|
|
By default it uses the best viewer it can find in $PATH, in this order:
|
|
info, man, $PAGER (unless a topic is specified), less, or stdout. When
|
|
run non-interactively, it always uses stdout. Or you can select a par-
|
|
ticular viewer with the -i (info), -m (man), or -p (pager) flags.
|
|
|
|
import
|
|
import
|
|
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 transac-
|
|
tions that would be added. Or with --catchup, just mark all of the
|
|
FILEs' transactions as imported, without actually importing any.
|
|
|
|
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's just: hledger import *.csv
|
|
|
|
New transactions are detected in the same way as print --new: by assum-
|
|
ing transactions are always added to the input files in increasing date
|
|
order, and by saving .latest.FILE state files.
|
|
|
|
The --dry-run output is in journal format, so you can filter it, eg to
|
|
see only uncategorised transactions:
|
|
|
|
$ hledger import --dry ... | hledger -f- print unknown --ignore-assertions
|
|
|
|
Importing balance assignments
|
|
Entries added by import will have their posting amounts made explicit
|
|
(like hledger print -x). This means that any balance assignments in
|
|
imported files must be evaluated; but, imported files don't get to see
|
|
the main file'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:
|
|
|
|
$ hledger print IMPORTFILE [--new] >> $LEDGER_FILE
|
|
|
|
(If you think import should leave amounts implicit like print does,
|
|
please test it and send a pull request.)
|
|
|
|
Commodity display styles
|
|
Imported amounts will be formatted according to the canonical commodity
|
|
styles (declared or inferred) in the main journal file.
|
|
|
|
incomestatement
|
|
incomestatement, is
|
|
This command displays an income statement, showing revenues and ex-
|
|
penses during one or more periods. Amounts are shown with normal posi-
|
|
tive sign, as in conventional financial statements.
|
|
|
|
The revenue and expense accounts shown are those accounts declared with
|
|
the Revenue or Expense type, or otherwise all accounts under a top-
|
|
level revenue or income or expense account (case insensitive, plurals
|
|
allowed).
|
|
|
|
(This report is essentially similar to "hledger balance --change rev-
|
|
enues expenses", with revenues sign-flipped.)
|
|
|
|
Example:
|
|
|
|
$ hledger incomestatement
|
|
Income Statement
|
|
|
|
Revenues:
|
|
$-2 income
|
|
$-1 gifts
|
|
$-1 salary
|
|
--------------------
|
|
$-2
|
|
|
|
Expenses:
|
|
$2 expenses
|
|
$1 food
|
|
$1 supplies
|
|
--------------------
|
|
$2
|
|
|
|
Total:
|
|
--------------------
|
|
0
|
|
|
|
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 --change/--cumulative/--historical. Instead of abso-
|
|
lute values percentages can be displayed with -%.
|
|
|
|
This command also supports the output destination and output format op-
|
|
tions The output formats supported are txt, csv, html, and (experimen-
|
|
tal) json.
|
|
|
|
notes
|
|
notes
|
|
List the unique notes that appear in transactions.
|
|
|
|
This command lists the unique notes that appear in transactions, in al-
|
|
phabetic order. You can add a query to select a subset of transac-
|
|
tions. The note is the part of the transaction description after a |
|
|
character (or if there is no |, the whole description).
|
|
|
|
Example:
|
|
|
|
$ hledger notes
|
|
Petrol
|
|
Snacks
|
|
|
|
payees
|
|
payees
|
|
List the unique payee/payer names that appear in transactions.
|
|
|
|
This command lists the unique payee/payer names that appear in transac-
|
|
tions, in alphabetic order. You can add a query to select a subset of
|
|
transactions. The payee/payer is the part of the transaction descrip-
|
|
tion before a | character (or if there is no |, the whole description).
|
|
|
|
Example:
|
|
|
|
$ hledger payees
|
|
Store Name
|
|
Gas Station
|
|
Person A
|
|
|
|
prices
|
|
prices
|
|
Print market price directives from the journal. With --costs, also
|
|
print synthetic market prices based on transaction prices. With --in-
|
|
verted-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.
|
|
|
|
print
|
|
print
|
|
Show transaction journal entries, sorted by date.
|
|
|
|
The print command displays full journal entries (transactions) from the
|
|
journal file, sorted by date (or with --date2, 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:
|
|
|
|
$ 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
|
|
|
|
print'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:
|
|
|
|
# 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
|
|
|
|
There are some situations where print's output can become unparseable:
|
|
|
|
o Rounding amounts according to commodity display styles can cause
|
|
transactions to appear unbalanced.
|
|
|
|
o Valuation affects posting amounts but not balance assertion or bal-
|
|
ance assignment amounts, potentially causing those to fail.
|
|
|
|
o Auto postings can generate postings with too many missing amounts.
|
|
|
|
Normally, the journal entry's explicit or implicit amount style is pre-
|
|
served. For example, when an amount is omitted in the journal, it will
|
|
not appear in the output. Similarly, when a transaction price is im-
|
|
plied but not written, it will not appear in the output. You can use
|
|
the -x/--explicit flag to make all amounts and transaction prices ex-
|
|
plicit, which can be useful for troubleshooting or for making your
|
|
journal more readable and robust against data entry errors. -x is also
|
|
implied by using any of -B,-V,-X,--value.
|
|
|
|
Note, -x/--explicit 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.
|
|
|
|
With -B/--cost, amounts with transaction prices are converted to cost
|
|
using that price. This can be used for troubleshooting.
|
|
|
|
With -m/--match and a STR argument, print will show at most one trans-
|
|
action: 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.
|
|
|
|
With --new, for each FILE being read, hledger reads (and writes) a spe-
|
|
cial state file (.latest.FILE 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 ig-
|
|
noring already-seen entries in import data, such as downloaded CSV
|
|
files. Eg:
|
|
|
|
$ hledger -f bank1.csv print --new
|
|
(shows transactions added since last print --new on this file)
|
|
|
|
This assumes that transactions added to FILE always have same or in-
|
|
creasing dates, and that transactions on the same day do not get re-
|
|
ordered. See also the import command.
|
|
|
|
This command also supports the output destination and output format op-
|
|
tions The output formats supported are txt, csv, and (experimental)
|
|
json and sql.
|
|
|
|
Here's an example of print's CSV output:
|
|
|
|
$ hledger print -Ocsv
|
|
"txnidx","date","date2","status","code","description","comment","account","amount","commodity","credit","debit","posting-status","posting-comment"
|
|
"1","2008/01/01","","","","income","","assets:bank:checking","1","$","","1","",""
|
|
"1","2008/01/01","","","","income","","income:salary","-1","$","1","","",""
|
|
"2","2008/06/01","","","","gift","","assets:bank:checking","1","$","","1","",""
|
|
"2","2008/06/01","","","","gift","","income:gifts","-1","$","1","","",""
|
|
"3","2008/06/02","","","","save","","assets:bank:saving","1","$","","1","",""
|
|
"3","2008/06/02","","","","save","","assets:bank:checking","-1","$","1","","",""
|
|
"4","2008/06/03","","*","","eat & shop","","expenses:food","1","$","","1","",""
|
|
"4","2008/06/03","","*","","eat & shop","","expenses:supplies","1","$","","1","",""
|
|
"4","2008/06/03","","*","","eat & shop","","assets:cash","-2","$","2","","",""
|
|
"5","2008/12/31","","*","","pay off","","liabilities:debts","1","$","","1","",""
|
|
"5","2008/12/31","","*","","pay off","","assets:bank:checking","-1","$","1","","",""
|
|
|
|
o There is one CSV record per posting, with the parent transaction's
|
|
fields repeated.
|
|
|
|
o The "txnidx" (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.)
|
|
|
|
o The amount is separated into "commodity" (the symbol) and "amount"
|
|
(numeric quantity) fields.
|
|
|
|
o The numeric amount is repeated in either the "credit" or "debit" col-
|
|
umn, for convenience. (Those names are not accurate in the account-
|
|
ing sense; it just puts negative amounts under credit and zero or
|
|
greater amounts under debit.)
|
|
|
|
print-unique
|
|
print-unique
|
|
Print transactions which do not reuse an already-seen description.
|
|
|
|
Example:
|
|
|
|
$ 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
|
|
|
|
register
|
|
register, reg
|
|
Show postings and their running total.
|
|
|
|
The register command displays matched postings, across all accounts, in
|
|
date order, with their running total or running historical balance.
|
|
(See also the aregister command, which shows matched transactions in a
|
|
specific account.)
|
|
|
|
register normally shows line per posting, but note that multi-commodity
|
|
amounts will occupy multiple lines (one line per commodity).
|
|
|
|
It is typically used with a query selecting a particular account, to
|
|
see that account's activity:
|
|
|
|
$ 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
|
|
|
|
With --date2, it shows and sorts by secondary date instead.
|
|
|
|
The --historical/-H 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:
|
|
|
|
$ 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
|
|
|
|
The --depth option limits the amount of sub-account detail displayed.
|
|
|
|
The --average/-A 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 --empty (see below). It
|
|
is affected by --historical. It works best when showing just one ac-
|
|
count and one commodity.
|
|
|
|
The --related/-r flag shows the other postings in the transactions of
|
|
the postings which would normally be shown.
|
|
|
|
The --invert flag negates all amounts. For example, it can be used on
|
|
an income account where amounts are normally displayed as negative num-
|
|
bers. It's also useful to show postings on the checking account to-
|
|
gether with the related account:
|
|
|
|
$ hledger register --related --invert assets:checking
|
|
|
|
With a reporting interval, register shows summary postings, one per in-
|
|
terval, aggregating the postings to each account:
|
|
|
|
$ hledger register --monthly income
|
|
2008/01 income:salary $-1 $-1
|
|
2008/06 income:gifts $-1 $-2
|
|
|
|
Periods with no activity, and summary postings with a zero amount, are
|
|
not shown by default; use the --empty/-E flag to see them:
|
|
|
|
$ 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
|
|
|
|
Often, you'll want to see just one line per interval. The --depth op-
|
|
tion helps with this, causing subaccounts to be aggregated:
|
|
|
|
$ hledger register --monthly assets --depth 1h
|
|
2008/01 assets $1 $1
|
|
2008/06 assets $-1 0
|
|
2008/12 assets $-1 $-1
|
|
|
|
Note when using report intervals, if you specify start/end dates these
|
|
will be adjusted outward if necessary to contain a whole number of in-
|
|
tervals. This ensures that the first and last intervals are full
|
|
length and comparable to the others in the report.
|
|
|
|
Custom register output
|
|
register uses the full terminal width by default, except on windows.
|
|
You can override this by setting the COLUMNS environment variable (not
|
|
a bash shell variable) or by using the --width/-w option.
|
|
|
|
The description and account columns normally share the space equally
|
|
(about half of (width - 40) each). You can adjust this by adding a de-
|
|
scription width as part of --width's argument, comma-separated: --width
|
|
W,D . Here's a diagram (won't display correctly in --help):
|
|
|
|
<--------------------------------- width (W) ---------------------------------->
|
|
date (10) description (D) account (W-41-D) amount (12) balance (12)
|
|
DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA
|
|
|
|
and some examples:
|
|
|
|
$ 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
|
|
|
|
This command also supports the output destination and output format op-
|
|
tions The output formats supported are txt, csv, and (experimental)
|
|
json.
|
|
|
|
register-match
|
|
register-match
|
|
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-au-
|
|
tosync detect already-seen transactions when importing.
|
|
|
|
rewrite
|
|
rewrite
|
|
Print all transactions, rewriting the postings of matched transactions.
|
|
For now the only rewrite available is adding new postings, like print
|
|
--auto.
|
|
|
|
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 transac-
|
|
tion's first posting amount.
|
|
|
|
Examples:
|
|
|
|
$ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'
|
|
$ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'
|
|
$ hledger-rewrite.hs -f rewrites.hledger
|
|
|
|
rewrites.hledger may consist of entries like:
|
|
|
|
= ^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
|
|
|
|
Note the single quotes to protect the dollar sign from bash, and the
|
|
two spaces between account and amount.
|
|
|
|
More:
|
|
|
|
$ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...
|
|
$ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'
|
|
$ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'
|
|
$ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'
|
|
|
|
Argument for --add-posting option is a usual posting of transaction
|
|
with an exception for amount specification. More precisely, you can
|
|
use '*' (star symbol) before the amount to indicate that that this is a
|
|
factor for an amount of original matched posting. If the amount in-
|
|
cludes a commodity name, the new posting amount will be in the new com-
|
|
modity; otherwise, it will be in the matched posting amount's commod-
|
|
ity.
|
|
|
|
Re-write rules in a file
|
|
During the run this tool will execute so called "Automated Transac-
|
|
tions" found in any journal it process. I.e instead of specifying this
|
|
operations in command line you can put them in a journal file.
|
|
|
|
$ rewrite-rules.journal
|
|
|
|
Make contents look like this:
|
|
|
|
= ^income
|
|
(liabilities:tax) *.33
|
|
|
|
= expenses:gifts
|
|
budget:gifts *-1
|
|
assets:budget *1
|
|
|
|
Note that '=' (equality symbol) that is used instead of date in trans-
|
|
actions you usually write. It indicates the query by which you want to
|
|
match the posting to add new ones.
|
|
|
|
$ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal
|
|
|
|
This is something similar to the commands pipeline:
|
|
|
|
$ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \
|
|
| hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \
|
|
--add-posting 'assets:budget *1' \
|
|
> rewritten-tidy-output.journal
|
|
|
|
It is important to understand that relative order of such entries in
|
|
journal is important. You can re-use result of previously added post-
|
|
ings.
|
|
|
|
Diff output format
|
|
To use this tool for batch modification of your journal files you may
|
|
find useful output in form of unified diff.
|
|
|
|
$ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'
|
|
|
|
Output might look like:
|
|
|
|
--- /tmp/examples/sample.journal
|
|
+++ /tmp/examples/sample.journal
|
|
@@ -18,3 +18,4 @@
|
|
2008/01/01 income
|
|
- assets:bank:checking $1
|
|
+ assets:bank:checking $1
|
|
income:salary
|
|
+ (liabilities:tax) 0
|
|
@@ -22,3 +23,4 @@
|
|
2008/06/01 gift
|
|
- assets:bank:checking $1
|
|
+ assets:bank:checking $1
|
|
income:gifts
|
|
+ (liabilities:tax) 0
|
|
|
|
If you'll pass this through patch tool you'll get transactions contain-
|
|
ing the posting that matches your query be updated. Note that multiple
|
|
files might be update according to list of input files specified via
|
|
--file options and include directives inside of these files.
|
|
|
|
Be careful. Whole transaction being re-formatted in a style of output
|
|
from hledger print.
|
|
|
|
See also:
|
|
|
|
https://github.com/simonmichael/hledger/issues/99
|
|
|
|
rewrite vs. print --auto
|
|
This command predates print --auto, and currently does much the same
|
|
thing, but with these differences:
|
|
|
|
o with multiple files, rewrite lets rules in any file affect all other
|
|
files. print --auto uses standard directive scoping; rules affect
|
|
only child files.
|
|
|
|
o rewrite's query limits which transactions can be rewritten; all are
|
|
printed. print --auto's query limits which transactions are printed.
|
|
|
|
o rewrite applies rules specified on command line or in the journal.
|
|
print --auto applies rules specified in the journal.
|
|
|
|
roi
|
|
roi
|
|
Shows the time-weighted (TWR) and money-weighted (IRR) rate of return
|
|
on your investments.
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
At a minimum, you need to supply a query (which could be just an ac-
|
|
count name) to select your investments with --inv, and another query to
|
|
identify your profit and loss transactions with --pnl.
|
|
|
|
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.
|
|
|
|
Note, in some cases this report can fail, for these reasons:
|
|
|
|
o Error (NotBracketed): No solution for Internal Rate of Return (IRR).
|
|
Possible causes: IRR is huge (>1000000%), balance of investment be-
|
|
comes negative at some point in time.
|
|
|
|
o Error (SearchFailed): Failed to find solution for Internal Rate of
|
|
Return (IRR). Either search does not converge to a solution, or con-
|
|
verges too slowly.
|
|
|
|
Examples:
|
|
|
|
o Using roi to report unrealised gains: https://github.com/simon-
|
|
michael/hledger/blob/master/examples/roi-unrealised.ledger
|
|
|
|
More background:
|
|
|
|
"ROI" stands for "return on investment". Traditionally this was com-
|
|
puted as a difference between current value of investment and its ini-
|
|
tial value, expressed in percentage of the initial value.
|
|
|
|
However, this approach is only practical in simple cases, where invest-
|
|
ments receives no in-flows or out-flows of money, and where rate of
|
|
growth is fixed over time. For more complex scenarios you need differ-
|
|
ent ways to compute rate of return, and this command implements two of
|
|
them: IRR and TWR.
|
|
|
|
Internal rate of return, or "IRR" (also called "money-weighted rate of
|
|
return") 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 percent-
|
|
age of your initial investment, and if you are adding to your invest-
|
|
ment, 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 pe-
|
|
riod 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.
|
|
|
|
As mentioned before, in-flows and out-flows would be any cash that you
|
|
personally put in or withdraw, and for the "roi" command, these are
|
|
transactions that involve account(s) matching --inv argument and NOT
|
|
involve account(s) matching --pnl argument.
|
|
|
|
Presumably, you will also record changes in the value of your invest-
|
|
ment, and balance them against "profit and loss" (or "unrealized
|
|
gains") account. Note that in order for IRR to compute the precise ef-
|
|
fect 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.
|
|
|
|
Implementation of IRR in hledger should match the XIRR formula in Ex-
|
|
cel.
|
|
|
|
Second way to compute rate of return that roi command implements is
|
|
called "time-weighted rate of return" or "TWR". 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.
|
|
|
|
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't done
|
|
discounted cash flow analysis before.
|
|
|
|
TWR represents your investment as an imaginary "unit fund" where in-
|
|
flows/ out-flows lead to buying or selling "units" of your investment
|
|
and changes in its value change the value of "investment unit". Change
|
|
in "unit price" over the reporting period gives you rate of return of
|
|
your investment.
|
|
|
|
References: * Explanation of rate of return * Explanation of IRR * Ex-
|
|
planation of TWR * Examples of computing IRR and TWR and discussion of
|
|
the limitations of both metrics
|
|
|
|
More examples:
|
|
|
|
Lets say that we found an investment in Snake Oil that is proising to
|
|
give us 10% annually:
|
|
|
|
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
|
|
|
|
For now, basic computation of the rate of return, as well as IRR and
|
|
TWR, gives us the expected 10%:
|
|
|
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
|
| || 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% |
|
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
|
|
|
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 "fear of
|
|
mission out", 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:
|
|
|
|
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
|
|
|
|
Now IRR and TWR are drastically different:
|
|
|
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
|
| || 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% |
|
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
|
|
|
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?
|
|
|
|
Based on the transactions in our journal, TWR "think" that we are buy-
|
|
ing 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's take a closer look at what is
|
|
happening here by asking for quarterly reports instead of annual:
|
|
|
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
|
| || 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% |
|
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
|
|
|
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 compu-
|
|
tation 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!
|
|
|
|
Let's try to keep a better record of how Snake Oil grew in value:
|
|
|
|
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
|
|
|
|
Would our quartery report look better now? Almost:
|
|
|
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
|
| || 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% |
|
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
|
|
|
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:
|
|
|
|
2019-12-30 Fear of missing out and growth of Snake Oil
|
|
assets:cash -$90
|
|
investment:snake oil
|
|
equity:unrealized gains -$0.25
|
|
|
|
Now growth of investment properly affects its price at the time of buy-
|
|
back:
|
|
|
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
|
| || 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% |
|
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
|
|
|
And for annual report, TWR now reports the exact profitability of our
|
|
investment:
|
|
|
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
|
| || 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% |
|
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
|
|
|
stats
|
|
stats
|
|
Show some journal statistics.
|
|
|
|
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.
|
|
|
|
Example:
|
|
|
|
$ 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 ($)
|
|
|
|
This command also supports output destination and output format selec-
|
|
tion.
|
|
|
|
tags
|
|
tags
|
|
List the unique tag names used in the journal. With a TAGREGEX argu-
|
|
ment, only tag names matching the regular expression (case insensitive)
|
|
are shown. With QUERY arguments, only transactions matching the query
|
|
are considered.
|
|
|
|
With the --values flag, the tags' unique values are listed instead.
|
|
|
|
With --parsed flag, all tags or values are shown in the order they are
|
|
parsed from the input data, including duplicates.
|
|
|
|
With -E/--empty, any blank/empty values will also be shown, otherwise
|
|
they are omitted.
|
|
|
|
test
|
|
test
|
|
Run built-in unit tests.
|
|
|
|
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.
|
|
|
|
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!
|
|
|
|
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:
|
|
|
|
$ hledger test -- -pData.Amount --color=never
|
|
|
|
For help on these, see https://github.com/feuerbach/tasty#options (--
|
|
--help currently doesn't show them).
|
|
|
|
About add-on commands
|
|
Add-on commands are programs or scripts in your PATH
|
|
|
|
o whose name starts with hledger-
|
|
|
|
o whose name ends with a recognised file extension: .bat,.com,.exe,
|
|
.hs,.lhs,.pl,.py,.rb,.rkt,.sh or none
|
|
|
|
o and (on unix, mac) which are executable by the current user.
|
|
|
|
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's bin/ directory.
|
|
|
|
Note in a hledger command line, add-on command flags must have a double
|
|
dash (--) preceding them. Eg you must write:
|
|
|
|
$ hledger web -- --serve
|
|
|
|
and not:
|
|
|
|
$ hledger web --serve
|
|
|
|
(because the --serve flag belongs to hledger-web, not hledger).
|
|
|
|
The -h/--help and --version flags don't require --.
|
|
|
|
If you have any trouble with this, remember you can always run the add-
|
|
on program directly, eg:
|
|
|
|
$ hledger-web --serve
|
|
|
|
JOURNAL FORMAT
|
|
hledger's default file format, representing a General Journal.
|
|
|
|
hledger's usual data source is a plain text file containing journal en-
|
|
tries in hledger journal format. This file represents a standard ac-
|
|
counting general journal. I use file names ending in .journal, but
|
|
that'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.
|
|
|
|
hledger's journal format is a compatible subset, mostly, of ledger's
|
|
journal format, so hledger can work with compatible ledger journal
|
|
files as well. It's safe, and encouraged, to run both hledger and
|
|
ledger on the same journal file, eg to validate the results you're get-
|
|
ting.
|
|
|
|
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.
|
|
|
|
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 configura-
|
|
tion at hledger.org for the full list.
|
|
|
|
Here's a description of each part of the file format (and hledger's
|
|
data model). These are mostly in the order you'll use them, but in
|
|
some cases related concepts have been grouped together for easy refer-
|
|
ence, or linked before they are introduced, so feel free to skip over
|
|
anything that looks unnecessary right now.
|
|
|
|
Transactions
|
|
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.
|
|
|
|
Each transaction is recorded as a journal entry, beginning with a sim-
|
|
ple date in column 0. This can be followed by any of the following op-
|
|
tional fields, separated by spaces:
|
|
|
|
o a status character (empty, !, or *)
|
|
|
|
o a code (any short number or text, enclosed in parentheses)
|
|
|
|
o a description (any remaining text until end of line or a semicolon)
|
|
|
|
o a comment (any remaining text following a semicolon until end of
|
|
line, and any following indented lines beginning with a semicolon)
|
|
|
|
o 0 or more indented posting lines, describing what was transferred and
|
|
the accounts involved (indented comment lines are also allowed, but
|
|
not blank lines or non-indented lines).
|
|
|
|
Here's a simple journal file containing one transaction:
|
|
|
|
2008/01/01 income
|
|
assets:bank:checking $1
|
|
income:salary $-1
|
|
|
|
Dates
|
|
Simple dates
|
|
Dates in the journal file use simple dates format: YYYY-MM-DD or
|
|
YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be
|
|
omitted, in which case it will be inferred from the context: the cur-
|
|
rent transaction, the default year set with a default year directive,
|
|
or the current date when the command is run. Some examples:
|
|
2010-01-31, 2010/01/31, 2010.1.31, 1/31.
|
|
|
|
(The UI also accepts simple dates, as well as the more flexible smart
|
|
dates documented in the hledger manual.)
|
|
|
|
Secondary dates
|
|
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.
|
|
|
|
Or, you can use the older secondary date feature (Ledger calls it aux-
|
|
iliary date or effective date). Note: we support this for compatibil-
|
|
ity, but I usually recommend avoiding this feature; posting dates are
|
|
almost always clearer and simpler.
|
|
|
|
A secondary date is written after the primary date, following an equals
|
|
sign. If the year is omitted, the primary date's year is assumed.
|
|
When running reports, the primary (left) date is used by default, but
|
|
with the --date2 flag (or --aux-date or --effective), the secondary
|
|
(right) date will be used instead.
|
|
|
|
The meaning of secondary dates is up to you, but it's best to follow a
|
|
consistent rule. Eg "primary = the bank's clearing date, secondary =
|
|
date the transaction was initiated, if different", as shown here:
|
|
|
|
2010/2/23=2/19 movie ticket
|
|
expenses:cinema $10
|
|
assets:checking
|
|
|
|
$ hledger register checking
|
|
2010-02-23 movie ticket assets:checking $-10 $-10
|
|
|
|
$ hledger register checking --date2
|
|
2010-02-19 movie ticket assets:checking $-10 $-10
|
|
|
|
Posting dates
|
|
You can give individual postings a different date from their parent
|
|
transaction, by adding a posting comment containing a tag (see below)
|
|
like date:DATE. This is probably the best way to control posting dates
|
|
precisely. Eg in this example the expense should appear in May re-
|
|
ports, and the deduction from checking should be reported on 6/1 for
|
|
easy bank reconciliation:
|
|
|
|
2015/5/30
|
|
expenses:food $10 ; food purchased on saturday 5/30
|
|
assets:checking ; bank cleared it on monday, date:6/1
|
|
|
|
$ hledger -f t.j register food
|
|
2015-05-30 expenses:food $10 $10
|
|
|
|
$ hledger -f t.j register checking
|
|
2015-06-01 assets:checking $-10 $-10
|
|
|
|
DATE should be a simple date; if the year is not specified it will use
|
|
the year of the transaction's date. You can set the secondary date
|
|
similarly, with date2:DATE2. The date: or date2: tags must have a
|
|
valid simple date value if they are present, eg a date: tag with no
|
|
value is not allowed.
|
|
|
|
Ledger's earlier, more compact bracketed date syntax is also supported:
|
|
[DATE], [DATE=DATE2] or [=DATE2]. hledger will attempt to parse any
|
|
square-bracketed sequence of the 0123456789/-.= characters in this way.
|
|
With this syntax, DATE infers its year from the transaction and DATE2
|
|
infers its year from DATE.
|
|
|
|
Status
|
|
Transactions, or individual postings within a transaction, can have a
|
|
status mark, which is a single character before the transaction de-
|
|
scription or posting account name, separated from it by a space, indi-
|
|
cating one of three statuses:
|
|
|
|
mark status
|
|
------------------
|
|
unmarked
|
|
! pending
|
|
* cleared
|
|
|
|
When reporting, you can filter by status with the -U/--unmarked,
|
|
-P/--pending, and -C/--cleared flags; or the status:, status:!, and
|
|
status:* queries; or the U, P, C keys in hledger-ui.
|
|
|
|
Note, in Ledger and in older versions of hledger, the "unmarked" state
|
|
is called "uncleared". As of hledger 1.3 we have renamed it to un-
|
|
marked for clarity.
|
|
|
|
To replicate Ledger and old hledger's behaviour of also matching pend-
|
|
ing, combine -U and -P.
|
|
|
|
Status marks are optional, but can be helpful eg for reconciling with
|
|
real-world accounts. Some editor modes provide highlighting and short-
|
|
cuts 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.
|
|
|
|
What "uncleared", "pending", and "cleared" actually mean is up to you.
|
|
Here's one suggestion:
|
|
|
|
status meaning
|
|
--------------------------------------------------------------------------
|
|
uncleared recorded but not yet reconciled; needs review
|
|
pending tentatively reconciled (if needed, eg during a big reconcil-
|
|
iation)
|
|
cleared complete, reconciled as far as possible, and considered cor-
|
|
rect
|
|
|
|
With this scheme, you would use -PC to see the current balance at your
|
|
bank, -U to see things which will probably hit your bank soon (like un-
|
|
cashed checks), and no flags to see the most up-to-date state of your
|
|
finances.
|
|
|
|
Description
|
|
A transaction's description is the rest of the line following the date
|
|
and status mark (or until a comment begins). Sometimes called the
|
|
"narration" in traditional bookkeeping, it can be used for whatever you
|
|
wish, or left blank. Transaction descriptions can be queried, unlike
|
|
comments.
|
|
|
|
Payee and note
|
|
You can optionally include a | (pipe) character in descriptions to sub-
|
|
divide the description into separate fields for payee/payer name on the
|
|
left (up to the first |) and an additional note field on the right (af-
|
|
ter the first |). This may be worthwhile if you need to do more pre-
|
|
cise querying and pivoting by payee or by note.
|
|
|
|
Comments
|
|
Lines in the journal beginning with a semicolon (;) or hash (#) or star
|
|
(*) 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.)
|
|
|
|
You can attach comments to a transaction by writing them after the de-
|
|
scription 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. Transac-
|
|
tion and posting comments must begin with a semicolon (;).
|
|
|
|
Some examples:
|
|
|
|
# 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 "end comment"
|
|
(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)
|
|
|
|
You can also comment larger regions of a file using comment and end
|
|
comment directives.
|
|
|
|
Tags
|
|
Tags are a way to add extra labels or labelled data to postings and
|
|
transactions, which you can then search or pivot on.
|
|
|
|
A simple tag is a word (which may contain hyphens) followed by a full
|
|
colon, written inside a transaction or posting comment line:
|
|
|
|
2017/1/16 bought groceries ; sometag:
|
|
|
|
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:
|
|
|
|
expenses:food $10 ; a-posting-tag: the tag value
|
|
|
|
Note this means hledger's tag values can not contain commas or new-
|
|
lines. Ending at commas means you can write multiple short tags on one
|
|
line, comma separated:
|
|
|
|
assets:checking ; a comment containing tag1:, tag2: some value ...
|
|
|
|
Here,
|
|
|
|
o "a comment containing" is just comment text, not a tag
|
|
|
|
o "tag1" is a tag with no value
|
|
|
|
o "tag2" is another tag, whose value is "some value ..."
|
|
|
|
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 (A, TAG2, third-
|
|
tag) and the posting has four (those plus posting-tag):
|
|
|
|
1/1 a transaction ; A:, TAG2:
|
|
; third-tag: a third transaction tag, <- with a value
|
|
(a) $1 ; posting-tag:
|
|
|
|
Tags are like Ledger's metadata feature, except hledger's tag values
|
|
are simple strings.
|
|
|
|
Postings
|
|
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:
|
|
|
|
o (optional) a status character (empty, !, or *), followed by a space
|
|
|
|
o (required) an account name (any text, optionally containing single
|
|
spaces, until end of line or a double space)
|
|
|
|
o (optional) two or more spaces or tabs followed by an amount.
|
|
|
|
Positive amounts are being added to the account, negative amounts are
|
|
being removed.
|
|
|
|
The amounts within a transaction must always sum up to zero. As a con-
|
|
venience, one amount may be left blank; it will be inferred so as to
|
|
balance the transaction.
|
|
|
|
Be sure to note the unusual two-space delimiter between account name
|
|
and amount. This makes it easy to write account names containing spa-
|
|
ces. But if you accidentally leave only one space (or tab) before the
|
|
amount, the amount will be considered part of the account name.
|
|
|
|
Virtual postings
|
|
A posting with a parenthesised account name is called a virtual posting
|
|
or unbalanced posting, which means it is exempt from the usual rule
|
|
that a transaction's postings must balance add up to zero.
|
|
|
|
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:
|
|
|
|
1/1 opening balances
|
|
(assets:checking) $1000
|
|
(assets:savings) $2000
|
|
|
|
A posting with a bracketed account name is called a balanced virtual
|
|
posting. The balanced virtual postings in a transaction must add up to
|
|
zero (separately from other postings). Eg:
|
|
|
|
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
|
|
|
|
Ordinary non-parenthesised, non-bracketed postings are called real
|
|
postings. You can exclude virtual postings from reports with the
|
|
-R/--real flag or real:1 query.
|
|
|
|
Account names
|
|
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: assets, liabilities, income, expenses, and equity.
|
|
|
|
Account names may contain single spaces, eg: assets:accounts receiv-
|
|
able. Because of this, they must always be followed by two or more
|
|
spaces (or newline).
|
|
|
|
Account names can be aliased.
|
|
|
|
Amounts
|
|
After the account name, there is usually an amount. (Important: be-
|
|
tween account name and amount, there must be two or more spaces.)
|
|
|
|
hledger's amount format is flexible, supporting several international
|
|
formats. Here are some examples. Amounts have a number (the "quan-
|
|
tity"):
|
|
|
|
1
|
|
|
|
..and usually a currency or commodity name (the "commodity"). This is
|
|
a symbol, word, or phrase, to the left or right of the quantity, with
|
|
or without a separating space:
|
|
|
|
$1
|
|
4000 AAPL
|
|
|
|
If the commodity name contains spaces, numbers, or punctuation, it must
|
|
be enclosed in double quotes:
|
|
|
|
3 "no. 42 green apples"
|
|
|
|
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 com-
|
|
modity symbol:
|
|
|
|
-$1
|
|
$-1
|
|
|
|
One or more spaces between the sign and the number are acceptable when
|
|
parsing (but they won't be displayed in output):
|
|
|
|
+ $1
|
|
$- 1
|
|
|
|
Scientific E notation is allowed:
|
|
|
|
1E-6
|
|
EUR 1E3
|
|
|
|
A decimal mark can be written as a period or a comma:
|
|
|
|
1.23
|
|
1,23456780000009
|
|
|
|
Digit group marks
|
|
In the integer part of the quantity (left of the decimal mark), groups
|
|
of digits can optionally be separated by a "digit group mark" - a
|
|
space, comma, or period (different from the decimal mark):
|
|
|
|
$1,000,000.00
|
|
EUR 2.000.000,00
|
|
INR 9,99,99,999.00
|
|
1 000 000.9455
|
|
|
|
Note, a number containing a single group mark and no decimal mark is
|
|
ambiguous. Are these group marks or decimal marks ?
|
|
|
|
1,000
|
|
1.000
|
|
|
|
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 ex-
|
|
plicitly declare the decimal mark (and optionally a digit group mark).
|
|
Note, these formats ("amount styles") are specific to each commodity,
|
|
so if your data uses multiple formats, hledger can handle it:
|
|
|
|
commodity $1,000.00
|
|
commodity EUR 1.000,00
|
|
commodity INR 9,99,99,999.00
|
|
commodity 1 000 000.9455
|
|
|
|
Commodity display style
|
|
For the amounts in each commodity, hledger chooses a consistent display
|
|
style. (Excluding price amounts, which are always displayed as writ-
|
|
ten). The display style is chosen as follows:
|
|
|
|
o If there is a commodity directive (or default commodity directive)
|
|
for the commodity, its style is used (see examples above).
|
|
|
|
o Otherwise the style is inferred from the amounts in that commodity
|
|
seen in the journal.
|
|
|
|
o Or if there are no such amounts in the journal, a default style is
|
|
used (like $1000.00).
|
|
|
|
A style is inferred from the journal amounts in a commodity as follows:
|
|
|
|
o Use the general style (decimal mark, symbol placement) of the first
|
|
amount
|
|
|
|
o Use the first-seen digit group style (digit group mark, digit group
|
|
sizes), if any
|
|
|
|
o Use the maximum number of decimal places of all.
|
|
|
|
Transaction price amounts don't affect the commodity display style di-
|
|
rectly, but occasionally they can do so indirectly (eg when a posting's
|
|
amount is inferred using a transaction price). If you find this caus-
|
|
ing problems, use a commodity directive to fix the display style.
|
|
|
|
In summary, each commodity's amounts will be normalised to
|
|
|
|
o the style declared by a commodity directive
|
|
|
|
o 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.
|
|
|
|
So if your reports are showing amounts in a way you don't like, eg with
|
|
too many decimal places, use a commodity directive to set the commod-
|
|
ity's display style. For example:
|
|
|
|
# declare euro, dollar and bitcoin commodities and set their display styles:
|
|
commodity EUR 1.000,
|
|
commodity $1000.00
|
|
commodity 1000.00000000 BTC
|
|
|
|
Rounding
|
|
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's rounding: it
|
|
rounds to the nearest even number, eg 0.5 displayed with zero decimal
|
|
places is "0"). (Guaranteed since hledger 1.17.1; in older versions
|
|
this could vary if hledger was built with Decimal < 0.5.1.)
|
|
|
|
Transaction prices
|
|
Within a transaction, you can note an amount's price in another commod-
|
|
ity. 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 cer-
|
|
tain date.
|
|
|
|
There are several ways to record a transaction price:
|
|
|
|
1. Write the price per unit, as @ UNITPRICE after the amount:
|
|
|
|
2009/1/1
|
|
assets:euros EUR100 @ $1.35 ; one hundred euros purchased at $1.35 each
|
|
assets:dollars ; balancing amount is -$135.00
|
|
|
|
2. Write the total price, as @@ TOTALPRICE after the amount:
|
|
|
|
2009/1/1
|
|
assets:euros EUR100 @@ $135 ; one hundred euros purchased at $135 for the lot
|
|
assets:dollars
|
|
|
|
3. Specify amounts for all postings, using exactly two commodities, and
|
|
let hledger infer the price that balances the transaction:
|
|
|
|
2009/1/1
|
|
assets:euros EUR100 ; one hundred euros purchased
|
|
assets:dollars $-135 ; for $135
|
|
|
|
4. Like 1, but the @ is parenthesised, i.e. (@); this is for compati-
|
|
bility with Ledger journals (Virtual posting costs), and is equiva-
|
|
lent to 1 in hledger.
|
|
|
|
5. Like 2, but as in 4 the @@ is parenthesised, i.e. (@@); in hledger,
|
|
this is equivalent to 2.
|
|
|
|
Use the -B/--cost flag to convert amounts to their transaction price's
|
|
commodity, if any. (mnemonic: "B" is from "cost Basis", as in Ledger).
|
|
Eg here is how -B affects the balance report for the example above:
|
|
|
|
$ hledger bal -N --flat
|
|
$-135 assets:dollars
|
|
EUR100 assets:euros
|
|
$ hledger bal -N --flat -B
|
|
$-135 assets:dollars
|
|
$135 assets:euros # <- the euros' cost
|
|
|
|
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's postings are reversed, while the transaction
|
|
is equivalent, -B shows something different:
|
|
|
|
2009/1/1
|
|
assets:dollars $-135 ; 135 dollars sold
|
|
assets:euros EUR100 ; for 100 euros
|
|
|
|
$ hledger bal -N --flat -B
|
|
EUR-100 assets:dollars # <- the dollars' selling price
|
|
EUR100 assets:euros
|
|
|
|
Lot prices, lot dates
|
|
Ledger allows another kind of price, lot price (four variants: {UNIT-
|
|
PRICE}, {{TOTALPRICE}}, {=FIXEDUNITPRICE}, {{=FIXEDTOTALPRICE}}),
|
|
and/or a lot date ([DATE]) 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.
|
|
|
|
Balance assertions
|
|
hledger supports Ledger-style balance assertions in journal files.
|
|
These look like, for example, = EXPECTEDBALANCE following a posting's
|
|
amount. Eg here we assert the expected dollar balance in accounts a
|
|
and b after each posting:
|
|
|
|
2013/1/1
|
|
a $1 =$1
|
|
b =$-1
|
|
|
|
2013/1/2
|
|
a $1 =$2
|
|
b $-1 =$-2
|
|
|
|
After reading a journal file, hledger will check all balance assertions
|
|
and report an error if any of them fail. Balance assertions can pro-
|
|
tect you from, eg, inadvertently disrupting reconciled balances while
|
|
cleaning up old entries. You can disable them temporarily with the
|
|
-I/--ignore-assertions flag, which can be useful for troubleshooting or
|
|
for reading Ledger files. (Note: this flag currently does not disable
|
|
balance assignments, below).
|
|
|
|
Assertions and ordering
|
|
hledger sorts an account's postings and assertions first by date and
|
|
then (for postings on the same day) by parse order. Note this is dif-
|
|
ferent from Ledger, which sorts assertions only by parse order. (Also,
|
|
Ledger assertions do not see the accumulated effect of repeated post-
|
|
ings to the same account within a transaction.)
|
|
|
|
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.
|
|
|
|
Assertions and included files
|
|
With included files, things are a little more complicated. Including
|
|
preserves the ordering of postings and assertions. If you have multi-
|
|
ple postings to an account on the same day, split across different
|
|
files, and you also want to assert the account's balance on the same
|
|
day, you'll have to put the assertion in the right file.
|
|
|
|
Assertions and multiple -f options
|
|
Balance assertions don't work well across files specified with multiple
|
|
-f options. Use include or concatenate the files instead.
|
|
|
|
Assertions and commodities
|
|
The asserted balance must be a simple single-commodity amount, and in
|
|
fact the assertion checks only this commodity's balance within the
|
|
(possibly multi-commodity) account balance. This is how assertions
|
|
work in Ledger also. We could call this a "partial" balance assertion.
|
|
|
|
To assert the balance of more than one commodity in an account, you can
|
|
write multiple postings, each asserting one commodity's balance.
|
|
|
|
You can make a stronger "total" balance assertion by writing a double
|
|
equals sign (== EXPECTEDBALANCE). This asserts that there are no other
|
|
unasserted commodities in the account (or, that their balance is 0).
|
|
|
|
2013/1/1
|
|
a $1
|
|
a 1EUR
|
|
b $-1
|
|
c -1EUR
|
|
|
|
2013/1/2 ; These assertions succeed
|
|
a 0 = $1
|
|
a 0 = 1EUR
|
|
b 0 == $-1
|
|
c 0 == -1EUR
|
|
|
|
2013/1/3 ; This assertion fails as 'a' also contains 1EUR
|
|
a 0 == $1
|
|
|
|
It'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:
|
|
|
|
2013/1/1
|
|
a:usd $1
|
|
a:euro 1EUR
|
|
b
|
|
|
|
2013/1/2
|
|
a 0 == 0
|
|
a:usd 0 == $1
|
|
a:euro 0 == 1EUR
|
|
|
|
Assertions and prices
|
|
Balance assertions ignore transaction prices, and should normally be
|
|
written without one:
|
|
|
|
2019/1/1
|
|
(a) $1 @ EUR1 = $1
|
|
|
|
We do allow prices to be written there, however, and print shows them,
|
|
even though they don't affect whether the assertion passes or fails.
|
|
This is for backward compatibility (hledger's close command used to
|
|
generate balance assertions with prices), and because balance assign-
|
|
ments do use them (see below).
|
|
|
|
Assertions and subaccounts
|
|
The balance assertions above (= and ==) do not count the balance from
|
|
subaccounts; they check the account's exclusive balance only. You can
|
|
assert the balance including subaccounts by writing =* or ==*, eg:
|
|
|
|
2019/1/1
|
|
equity:opening balances
|
|
checking:a 5
|
|
checking:b 5
|
|
checking 1 ==* 11
|
|
|
|
Assertions and virtual postings
|
|
Balance assertions are checked against all postings, both real and vir-
|
|
tual. They are not affected by the --real/-R flag or real: query.
|
|
|
|
Assertions and precision
|
|
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 asser-
|
|
tions. Balance assertion failure messages show exact amounts.
|
|
|
|
Balance assignments
|
|
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:
|
|
|
|
; 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
|
|
|
|
or when adjusting a balance to reality:
|
|
|
|
; no cash left; update balance, record any untracked spending as a generic expense
|
|
2016/1/15
|
|
assets:cash = $0
|
|
expenses:misc
|
|
|
|
The calculated amount depends on the account'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 assign-
|
|
ment). 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.
|
|
|
|
Balance assignments and prices
|
|
A transaction price in a balance assignment will cause the calculated
|
|
amount to have that price attached:
|
|
|
|
2019/1/1
|
|
(a) = $1 @ EUR2
|
|
|
|
$ hledger print --explicit
|
|
2019-01-01
|
|
(a) $1 @ EUR2 = $1 @ EUR2
|
|
|
|
Directives
|
|
A directive is a line in the journal beginning with a special keyword,
|
|
that influences how the journal is processed. hledger's directives are
|
|
based on a subset of Ledger's, but there are many differences (and also
|
|
some differences between hledger versions).
|
|
|
|
Directives' 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.
|
|
|
|
direc- end di- subdi- purpose can affect (as of
|
|
tive rective rec- 2018/06)
|
|
tives
|
|
------------------------------------------------------------------------------------
|
|
account any document account names, de- all entries in all
|
|
text clare account types & dis- files, before or
|
|
play order after
|
|
alias end rewrite account names following entries
|
|
aliases until end of cur-
|
|
rent file or end
|
|
directive
|
|
apply end apply prepend a common parent to following entries
|
|
account account account names until end of cur-
|
|
rent file or end
|
|
directive
|
|
comment end com- ignore part of journal following entries
|
|
ment until end of cur-
|
|
rent file or end
|
|
directive
|
|
commod- format declare a commodity and its number notation:
|
|
ity number notation & display following entries
|
|
style in that commodity
|
|
in all files ; dis-
|
|
play style: amounts
|
|
of that commodity
|
|
in reports
|
|
D declare a commodity to be default commodity:
|
|
used for commodityless following commod-
|
|
amounts, and its number no- ityless entries un-
|
|
tation & display style til end of current
|
|
file; number nota-
|
|
tion: following en-
|
|
tries in that com-
|
|
modity until end of
|
|
current file; dis-
|
|
play style: amounts
|
|
of that commodity
|
|
in reports
|
|
include include entries/directives what the included
|
|
from another file directives affect
|
|
P declare a market price for a amounts of that
|
|
commodity commodity in re-
|
|
ports, when -V is
|
|
used
|
|
Y declare a year for yearless following entries
|
|
dates until end of cur-
|
|
rent file
|
|
= declare an auto posting all entries in par-
|
|
rule, adding postings to ent/current/child
|
|
other transactions files (but not sib-
|
|
ling files, see
|
|
#1212)
|
|
|
|
And some definitions:
|
|
|
|
subdi- optional indented directive line immediately following a parent
|
|
rec- directive
|
|
tive
|
|
number how to interpret numbers when parsing journal entries (the iden-
|
|
nota- tity of the decimal separator character). (Currently each com-
|
|
tion modity can have its own notation, even in the same file.)
|
|
dis- how to display amounts of a commodity in reports (symbol side
|
|
play and spacing, digit groups, decimal separator, decimal places)
|
|
style
|
|
|
|
|
|
direc- which entries and (when there are multiple files) which files
|
|
tive are affected by a directive
|
|
scope
|
|
|
|
As you can see, directives vary in which journal entries and files they
|
|
affect, and whether they are focussed on input (parsing) or output (re-
|
|
ports). Some directives have multiple effects.
|
|
|
|
Directives and multiple files
|
|
If you use multiple -f/--file options, or the include 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.
|
|
|
|
This may seem inconvenient, but it's intentional; it makes reports sta-
|
|
ble 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.
|
|
|
|
It can be surprising though; for example, it means that alias direc-
|
|
tives do not affect parent or sibling files (see below).
|
|
|
|
Comment blocks
|
|
A line containing just comment starts a commented region of the file,
|
|
and a line containing just end comment (or the end of the current file)
|
|
ends it. See also comments.
|
|
|
|
Including other files
|
|
You can pull in the content of additional files by writing an include
|
|
directive, like this:
|
|
|
|
include FILEPATH
|
|
|
|
Only journal files can include, and only journal, timeclock or timedot
|
|
files can be included (not CSV files, currently).
|
|
|
|
If the file path does not begin with a slash, it is relative to the
|
|
current file's folder.
|
|
|
|
A tilde means home directory, eg: include ~/main.journal.
|
|
|
|
The path may contain glob patterns to match multiple files, eg: include
|
|
*.journal.
|
|
|
|
There is limited support for recursive wildcards: **/ (the slash is re-
|
|
quired) matches 0 or more subdirectories. It's not super convenient
|
|
since you have to avoid include cycles and including directories, but
|
|
this can be done, eg: include */**/*.journal.
|
|
|
|
The path may also be prefixed to force a specific file format, overrid-
|
|
ing the file extension (as described in hledger.1 -> Input files): in-
|
|
clude timedot:~/notes/2020*.md.
|
|
|
|
Default year
|
|
You can set a default year to be used for subsequent dates which don't
|
|
specify a year. This is a line beginning with Y followed by the year.
|
|
Eg:
|
|
|
|
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
|
|
|
|
Declaring commodities
|
|
The commodity directive has several functions:
|
|
|
|
1. It declares commodities which may be used in the journal. This is
|
|
currently not enforced, but can serve as documentation.
|
|
|
|
2. 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 1,000
|
|
and 1.000 as 1).
|
|
|
|
3. It declares a commodity's display style in output - decimal and
|
|
digit group marks, number of decimal places, symbol placement etc.
|
|
|
|
You are likely to run into one of the problems solved by commodity di-
|
|
rectives, sooner or later, so it's a good idea to just always use them
|
|
to declare your commodities.
|
|
|
|
A commodity directive is just the word commodity followed by an amount.
|
|
It may be written on a single line, like this:
|
|
|
|
; 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
|
|
|
|
or on multiple lines, using the "format" subdirective. (In this case
|
|
the commodity symbol appears twice and should be the same in both
|
|
places.):
|
|
|
|
; 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
|
|
|
|
The quantity of the amount does not matter; only the format is signifi-
|
|
cant. The number must include a decimal mark: either a period or a
|
|
comma, followed by 0 or more decimal digits.
|
|
|
|
Note hledger normally uses banker's rounding, so 0.5 displayed with
|
|
zero decimal digits is "0". (More at Commodity display style.)
|
|
|
|
Commodity error checking
|
|
In strict mode, enabled with the -s/--strict flag, hledger will report
|
|
an error if a commodity symbol is used that has not been declared by a
|
|
commodity directive. This works similarly to account error checking,
|
|
see the notes there for more details.
|
|
|
|
Default commodity
|
|
The D directive sets a default commodity, to be used for amounts with-
|
|
out a commodity symbol (ie, plain numbers). This commodity will be ap-
|
|
plied to all subsequent commodity-less amounts, or until the next D di-
|
|
rective. (Note, this is different from Ledger's D.)
|
|
|
|
For compatibility/historical reasons, D also acts like a commodity di-
|
|
rective, setting the commodity's display style (for output) and decimal
|
|
mark (for parsing input). As with commodity, the amount must always be
|
|
written with a decimal mark (period or comma). If both directives are
|
|
used, commodity's style takes precedence.
|
|
|
|
The syntax is D AMOUNT. Eg:
|
|
|
|
; 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
|
|
|
|
Declaring market prices
|
|
The P directive declares a market price, which is an exchange rate be-
|
|
tween two commodities on a certain date. (In Ledger, they are called
|
|
"historical prices".) These are often obtained from a stock exchange,
|
|
cryptocurrency exchange, or the foreign exchange market.
|
|
|
|
Here is the format:
|
|
|
|
P DATE COMMODITYA COMMODITYBAMOUNT
|
|
|
|
o DATE is a simple date
|
|
|
|
o COMMODITYA is the symbol of the commodity being priced
|
|
|
|
o COMMODITYBAMOUNT is an amount (symbol and quantity) in a second com-
|
|
modity, giving the price in commodity B of one unit of commodity A.
|
|
|
|
These two market price directives say that one euro was worth 1.35 US
|
|
dollars during 2009, and $1.40 from 2010 onward:
|
|
|
|
P 2009/1/1 EUR $1.35
|
|
P 2010/1/1 EUR $1.40
|
|
|
|
The -V, -X and --value flags use these market prices to show amount
|
|
values in another commodity. See Valuation.
|
|
|
|
Declaring accounts
|
|
account directives can be used to declare accounts (ie, the places that
|
|
amounts are transferred from and to). Though not required, these dec-
|
|
larations can provide several benefits:
|
|
|
|
o They can document your intended chart of accounts, providing a refer-
|
|
ence.
|
|
|
|
o They can help hledger know your accounts' types (asset, liability,
|
|
equity, revenue, expense), useful for reports like balancesheet and
|
|
incomestatement.
|
|
|
|
o They control account display order in reports, allowing non-alpha-
|
|
betic sorting (eg Revenues to appear above Expenses).
|
|
|
|
o They can store extra information about accounts (account numbers,
|
|
notes, etc.)
|
|
|
|
o They help with account name completion in the add command, hledger-
|
|
iadd, hledger-web, ledger-mode etc.
|
|
|
|
o In strict mode, they restrict which accounts may be posted to by
|
|
transactions, which helps detect typos.
|
|
|
|
The simplest form is just the word account followed by a hledger-style
|
|
account name, eg this account directive declares the assets:bank:check-
|
|
ing account:
|
|
|
|
account assets:bank:checking
|
|
|
|
Account error checking
|
|
By default, accounts come into existence when a transaction references
|
|
them by name. This is convenient, but it means hledger can't warn you
|
|
when you mis-spell an account name in the journal. Usually you'll find
|
|
the error later, as an extra account in balance reports, or an incor-
|
|
rect balance when reconciling.
|
|
|
|
In strict mode, enabled with the -s/--strict flag, hledger will report
|
|
an error if any transaction uses an account name that has not been de-
|
|
clared by an account directive. Some notes:
|
|
|
|
o The declaration is case-sensitive; transactions must use the correct
|
|
account name capitalisation.
|
|
|
|
o The account directive's scope is "whole file and below" (see direc-
|
|
tives). This means it affects all of the current file, and any files
|
|
it includes, but not parent or sibling files. The position of ac-
|
|
count directives within the file does not matter, though it's usual
|
|
to put them at the top.
|
|
|
|
o Accounts can only be declared in journal files (but will affect in-
|
|
cluded files in other formats).
|
|
|
|
o It's currently not possible to declare "all possible subaccounts"
|
|
with a wildcard; every account posted to must be declared.
|
|
|
|
Account comments
|
|
Comments, beginning with a semicolon, can be added:
|
|
|
|
o on the same line, after two or more spaces (because ; is allowed in
|
|
account names)
|
|
|
|
o on the next lines, indented
|
|
|
|
An example of both:
|
|
|
|
account assets:bank:checking ; same-line comment, note 2+ spaces before ;
|
|
; next-line comment
|
|
; another with tag, acctno:12345 (not used yet)
|
|
|
|
Same-line comments are not supported by Ledger, or hledger <1.13.
|
|
|
|
Account subdirectives
|
|
We also allow (and ignore) Ledger-style indented subdirectives, just
|
|
for compatibility.:
|
|
|
|
account assets:bank:checking
|
|
format blah blah ; <- subdirective, ignored
|
|
|
|
Here is the full syntax of account directives:
|
|
|
|
account ACCTNAME [ACCTTYPE] [;COMMENT]
|
|
[;COMMENTS]
|
|
[LEDGER-STYLE SUBDIRECTIVES, IGNORED]
|
|
|
|
Account types
|
|
hledger recognises five main types of account, corresponding to the ac-
|
|
count classes in the accounting equation:
|
|
|
|
Asset, Liability, Equity, Revenue, Expense.
|
|
|
|
These account types are important for controlling which accounts appear
|
|
in the balancesheet, balancesheetequity, incomestatement reports (and
|
|
probably for other things in future).
|
|
|
|
Additionally, we recognise the Cash type, which is also an Asset, and
|
|
which causes accounts to appear in the cashflow report. ("Cash" here
|
|
means liquid assets, eg bank balances but typically not investments or
|
|
receivables.)
|
|
|
|
Declaring account types
|
|
Generally, to make these reports work you should declare your top-level
|
|
accounts and their types, using account directives with type: tags.
|
|
|
|
The tag's value should be one of: Asset, Liability, Equity, Revenue,
|
|
Expense, Cash, A, L, E, R, X, C (all case insensitive). The type is
|
|
inherited by all subaccounts except where they override it. Here's a
|
|
complete example:
|
|
|
|
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
|
|
|
|
Auto-detected account types
|
|
If you happen to use common english top-level account names, you may
|
|
not need to declare account types, as they will be detected automati-
|
|
cally using the following rules:
|
|
|
|
If name matches regular account type is:
|
|
expression:
|
|
----------------------------------------------
|
|
^assets?(:|$) Asset
|
|
^(debts?|lia- Liability
|
|
bilit(y|ies))(:|$)
|
|
^equity(:|$) Equity
|
|
^(income|revenue)s?(:|$) Revenue
|
|
^expenses?(:|$) Expense
|
|
|
|
If account type is Asset and name does not contain regu- account type
|
|
lar expression: is:
|
|
--------------------------------------------------------------------------
|
|
(investment|receivable|:A/R|:fixed) Cash
|
|
|
|
Even so, explicit declarations may be a good idea, for clarity and pre-
|
|
dictability.
|
|
|
|
Interference from auto-detected account types
|
|
If you assign any account type, it's a good idea to assign all of them,
|
|
to prevent any confusion from mixing declared and auto-detected types.
|
|
Although it's unlikely to happen in real life, here's an example: with
|
|
the following journal, balancesheetequity shows "liabilities" in both
|
|
Liabilities and Equity sections. Declaring another account as type:Li-
|
|
ability would fix it:
|
|
|
|
account liabilities ; type:Equity
|
|
|
|
2020-01-01
|
|
assets 1
|
|
liabilities 1
|
|
equity -2
|
|
|
|
Old account type syntax
|
|
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:
|
|
|
|
account assets A
|
|
account liabilities L
|
|
account equity E
|
|
account revenues R
|
|
account expenses X
|
|
|
|
Account display order
|
|
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:
|
|
|
|
account assets
|
|
account liabilities
|
|
account equity
|
|
account revenues
|
|
account expenses
|
|
|
|
you'll see those accounts displayed in declaration order, not alphabet-
|
|
ically:
|
|
|
|
$ hledger accounts -1
|
|
assets
|
|
liabilities
|
|
equity
|
|
revenues
|
|
expenses
|
|
|
|
Undeclared accounts, if any, are displayed last, in alphabetical order.
|
|
|
|
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:
|
|
|
|
account other:zoo
|
|
|
|
would influence the position of zoo among other's subaccounts, but not
|
|
the position of other among the top-level accounts. This means:
|
|
|
|
o you will sometimes declare parent accounts (eg account other above)
|
|
that you don't intend to post to, just to customize their display or-
|
|
der
|
|
|
|
o sibling accounts stay together (you couldn't display x:y in between
|
|
a:b and a:c).
|
|
|
|
Rewriting accounts
|
|
You can define account alias rules which rewrite your account names, or
|
|
parts of them, before generating reports. This can be useful for:
|
|
|
|
o expanding shorthand account names to their full form, allowing easier
|
|
data entry and a less verbose journal
|
|
|
|
o adapting old journals to your current chart of accounts
|
|
|
|
o experimenting with new account organisations, like a new hierarchy or
|
|
combining two accounts into one
|
|
|
|
o customising reports
|
|
|
|
Account aliases also rewrite account names in account directives. They
|
|
do not affect account names being entered via hledger add or hledger-
|
|
web.
|
|
|
|
See also Rewrite account names.
|
|
|
|
Basic aliases
|
|
To set an account alias, use the alias 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:
|
|
|
|
alias OLD = NEW
|
|
|
|
Or, you can use the --alias 'OLD=NEW' option on the command line. This
|
|
affects all entries. It's useful for trying out aliases interactively.
|
|
|
|
OLD and NEW are case sensitive full account names. hledger will re-
|
|
place any occurrence of the old account name with the new one. Subac-
|
|
counts are also affected. Eg:
|
|
|
|
alias checking = assets:bank:wells fargo:checking
|
|
; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"
|
|
|
|
Regex aliases
|
|
There is also a more powerful variant that uses a regular expression,
|
|
indicated by the forward slashes:
|
|
|
|
alias /REGEX/ = REPLACEMENT
|
|
|
|
or --alias '/REGEX/=REPLACEMENT'.
|
|
|
|
REGEX is a case-insensitive regular expression. Anywhere it matches
|
|
inside an account name, the matched part will be replaced by REPLACE-
|
|
MENT. If REGEX contains parenthesised match groups, these can be ref-
|
|
erenced by the usual numeric backreferences in REPLACEMENT. Eg:
|
|
|
|
alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3
|
|
; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"
|
|
|
|
Also note that REPLACEMENT continues to the end of line (or on command
|
|
line, to end of option argument), so it can contain trailing white-
|
|
space.
|
|
|
|
Combining aliases
|
|
You can define as many aliases as you like, using journal directives
|
|
and/or command line options.
|
|
|
|
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.
|
|
|
|
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:
|
|
|
|
1. alias directives preceding the journal entry, most recently parsed
|
|
first (ie, reading upward from the journal entry, bottom to top)
|
|
|
|
2. --alias options, in the order they appeared on the command line
|
|
(left to right).
|
|
|
|
In other words, for (an account name in) a given journal entry:
|
|
|
|
o the nearest alias declaration before/above the entry is applied first
|
|
|
|
o the next alias before/above that will be be applied next, and so on
|
|
|
|
o aliases defined after/below the entry do not affect it.
|
|
|
|
This gives nearby aliases precedence over distant ones, and helps pro-
|
|
vide semantic stability - aliases will keep working the same way inde-
|
|
pendent of which files are being read and in which order.
|
|
|
|
In case of trouble, adding --debug=6 to the command line will show
|
|
which aliases are being applied when.
|
|
|
|
Aliases and multiple files
|
|
As explained at Directives and multiple files, alias directives do not
|
|
affect parent or sibling files. Eg in this command,
|
|
|
|
hledger -f a.aliases -f b.journal
|
|
|
|
account aliases defined in a.aliases will not affect b.journal. In-
|
|
cluding the aliases doesn't work either:
|
|
|
|
include a.aliases
|
|
|
|
2020-01-01 ; not affected by a.aliases
|
|
foo 1
|
|
bar
|
|
|
|
This means that account aliases should usually be declared at the start
|
|
of your top-most file, like this:
|
|
|
|
alias foo=Foo
|
|
alias bar=Bar
|
|
|
|
2020-01-01 ; affected by aliases above
|
|
foo 1
|
|
bar
|
|
|
|
include c.journal ; also affected
|
|
|
|
end aliases
|
|
You can clear (forget) all currently defined aliases with the end
|
|
aliases directive:
|
|
|
|
end aliases
|
|
|
|
Default parent account
|
|
You can specify a parent account which will be prepended to all ac-
|
|
counts within a section of the journal. Use the apply account and end
|
|
apply account directives like so:
|
|
|
|
apply account home
|
|
|
|
2010/1/1
|
|
food $10
|
|
cash
|
|
|
|
end apply account
|
|
|
|
which is equivalent to:
|
|
|
|
2010/01/01
|
|
home:food $10
|
|
home:cash $-10
|
|
|
|
If end apply account is omitted, the effect lasts to the end of the
|
|
file. Included files are also affected, eg:
|
|
|
|
apply account business
|
|
include biz.journal
|
|
end apply account
|
|
apply account personal
|
|
include personal.journal
|
|
|
|
Prior to hledger 1.0, legacy account and end spellings were also sup-
|
|
ported.
|
|
|
|
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.
|
|
|
|
Periodic transactions
|
|
Periodic transaction rules describe transactions that recur. They al-
|
|
low hledger to generate temporary future transactions to help with
|
|
forecasting, so you don't have to write out each one in the journal,
|
|
and it's easy to try out different forecasts.
|
|
|
|
Periodic transactions can be a little tricky, so before you use them,
|
|
read this whole section - or at least these tips:
|
|
|
|
1. Two spaces accidentally added or omitted will cause you trouble -
|
|
read about this below.
|
|
|
|
2. For troubleshooting, show the generated transactions with hledger
|
|
print --forecast tag:generated or hledger register --forecast
|
|
tag:generated.
|
|
|
|
3. Forecasted transactions will begin only after the last non-fore-
|
|
casted transaction's date.
|
|
|
|
4. Forecasted transactions will end 6 months from today, by default.
|
|
See below for the exact start/end rules.
|
|
|
|
5. period expressions can be tricky. Their documentation needs im-
|
|
provement, but is worth studying.
|
|
|
|
6. Some period expressions with a repeating interval must begin on a
|
|
natural boundary of that interval. Eg in weekly from DATE, DATE
|
|
must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an
|
|
error.
|
|
|
|
7. 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's a bit
|
|
inconsistent with the above.) Eg: ~ every 10th day of month from
|
|
2020/01, which is equivalent to ~ every 10th day of month from
|
|
2020/01/01, will be adjusted to start on 2019/12/10.
|
|
|
|
Periodic transaction rules also have a second meaning: they are used to
|
|
define budget goals, shown in budget reports.
|
|
|
|
Periodic rule syntax
|
|
A periodic transaction rule looks like a normal journal entry, with the
|
|
date replaced by a tilde (~) followed by a period expression (mnemonic:
|
|
~ looks like a recurring sine wave.):
|
|
|
|
~ monthly
|
|
expenses:rent $2000
|
|
assets:bank:checking
|
|
|
|
There is an additional constraint on the period expression: the start
|
|
date must fall on a natural boundary of the interval. Eg monthly from
|
|
2018/1/1 is valid, but monthly from 2018/1/15 is not.
|
|
|
|
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's
|
|
date, unless a Y default year directive is in effect, in which case
|
|
they will be relative to Y/1/1.
|
|
|
|
Two spaces between period expression and description!
|
|
If the period expression is followed by a transaction description,
|
|
these must be separated by two or more spaces. This helps hledger know
|
|
where the period expression ends, so that descriptions can not acciden-
|
|
tally alter their meaning, as in this example:
|
|
|
|
; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020"
|
|
; ||
|
|
; vv
|
|
~ every 2 months in 2020, we will review
|
|
assets:bank:checking $1500
|
|
income:acme inc
|
|
|
|
So,
|
|
|
|
o Do write two spaces between your period expression and your transac-
|
|
tion description, if any.
|
|
|
|
o Don't accidentally write two spaces in the middle of your period ex-
|
|
pression.
|
|
|
|
Forecasting with periodic transactions
|
|
The --forecast 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 print --forecast into the journal.
|
|
|
|
These transactions will have an extra tag indicating which periodic
|
|
rule generated them: generated-transaction:~ PERIODICEXPR. And a simi-
|
|
lar, hidden tag (beginning with an underscore) which, because it's
|
|
never displayed by print, can be used to match transactions generated
|
|
"just now": _generated-transaction:~ PERIODICEXPR.
|
|
|
|
Periodic transactions are generated within some forecast period. By
|
|
default, this
|
|
|
|
o begins on the later of
|
|
|
|
o the report start date if specified with -b/-p/date:
|
|
|
|
o the day after the latest normal (non-periodic) transaction in the
|
|
journal, or today if there are no normal transactions.
|
|
|
|
o ends on the report end date if specified with -e/-p/date:, or 6
|
|
months (180 days) from today.
|
|
|
|
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 ~ YYYY-MM-DD ...).
|
|
|
|
Or, you can set your own arbitrary "forecast period", which can overlap
|
|
recorded transactions, and need not be in the future, by providing an
|
|
option argument, like --forecast=PERIODEXPR. Note the equals sign is
|
|
required, a space won't work. PERIODEXPR is a period expression, which
|
|
can specify the start date, end date, or both, like in a date: query.
|
|
(See also hledger.1 -> Report start & end date). Some examples:
|
|
--forecast=202001-202004, --forecast=jan-, --forecast=2020.
|
|
|
|
Budgeting with periodic transactions
|
|
With the --budget 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 com-
|
|
pared in budget reports.
|
|
|
|
See also: Budgeting and Forecasting.
|
|
|
|
Auto postings
|
|
"Automated postings" or "auto postings" are extra postings which get
|
|
added automatically to transactions which match certain queries, de-
|
|
fined by "auto posting rules", when you use the --auto flag.
|
|
|
|
An auto posting rule looks a bit like a transaction:
|
|
|
|
= QUERY
|
|
ACCOUNT AMOUNT
|
|
...
|
|
ACCOUNT [AMOUNT]
|
|
|
|
except the first line is an equals sign (mnemonic: = suggests match-
|
|
ing), followed by a query (which matches existing postings), and each
|
|
"posting" line describes a posting to be generated, and the posting
|
|
amounts can be:
|
|
|
|
o a normal amount with a commodity symbol, eg $2. This will be used
|
|
as-is.
|
|
|
|
o a number, eg 2. The commodity symbol (if any) from the matched post-
|
|
ing will be added to this.
|
|
|
|
o a numeric multiplier, eg *2 (a star followed by a number N). The
|
|
matched posting's amount (and total price, if any) will be multiplied
|
|
by N.
|
|
|
|
o a multiplier with a commodity symbol, eg *$2 (a star, number N, and
|
|
symbol S). The matched posting's amount will be multiplied by N, and
|
|
its commodity symbol will be replaced with S.
|
|
|
|
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:
|
|
|
|
= expenses:groceries 'expenses:dining out'
|
|
(budget:funds:dining out) *-1
|
|
|
|
Some examples:
|
|
|
|
; 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
|
|
|
|
$ 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
|
|
|
|
Auto postings and multiple files
|
|
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/--file are used - see #1212).
|
|
|
|
Auto postings and dates
|
|
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.
|
|
|
|
Auto postings and transaction balancing / inferred amounts / balance asser-
|
|
tions
|
|
Currently, auto postings are added:
|
|
|
|
o after missing amounts are inferred, and transactions are checked for
|
|
balancedness,
|
|
|
|
o but before balance assertions are checked.
|
|
|
|
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.
|
|
|
|
Auto posting tags
|
|
Automated postings will have some extra tags:
|
|
|
|
o generated-posting:= QUERY - shows this was generated by an auto post-
|
|
ing rule, and the query
|
|
|
|
o _generated-posting:= QUERY - a hidden tag, which does not appear in
|
|
hledger's output. This can be used to match postings generated "just
|
|
now", rather than generated in the past and saved to the journal.
|
|
|
|
Also, any transaction that has been changed by auto posting rules will
|
|
have these tags added:
|
|
|
|
o modified: - this transaction was modified
|
|
|
|
o _modified: - a hidden tag not appearing in the comment; this transac-
|
|
tion was modified "just now".
|
|
|
|
CSV FORMAT
|
|
How hledger reads CSV data, and the CSV rules file format.
|
|
|
|
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.
|
|
|
|
(To learn about writing CSV, see CSV output.)
|
|
|
|
We describe each CSV file's format with a corresponding rules file. By
|
|
default this is named like the CSV file with a .rules extension added.
|
|
Eg when reading FILE.csv, hledger also looks for FILE.csv.rules in the
|
|
same directory as FILE.csv. You can specify a different rules file
|
|
with the --rules-file option. If a rules file is not found, hledger
|
|
will create a sample rules file, which you'll need to adjust.
|
|
|
|
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's an overview of the CSV rules; these are described more fully be-
|
|
low, after the examples:
|
|
|
|
skip skip one or more header lines or matched
|
|
CSV records
|
|
fields name CSV fields, assign them to hledger
|
|
fields
|
|
field assignment assign a value to one hledger field,
|
|
with interpolation
|
|
separator a custom field separator
|
|
if block apply some rules to CSV records matched
|
|
by patterns
|
|
if table apply some rules to CSV records matched
|
|
by patterns, alternate syntax
|
|
end skip the remaining CSV records
|
|
date-format how to parse dates in CSV records
|
|
|
|
|
|
decimal-mark the decimal mark used in CSV amounts, if
|
|
ambiguous
|
|
newest-first disambiguate record order when there's
|
|
only one date
|
|
include inline another CSV rules file
|
|
balance-type choose which type of balance assignments
|
|
to use
|
|
|
|
Note, for best error messages when reading CSV files, use a .csv, .tsv
|
|
or .ssv file extension or file prefix - see File Extension below.
|
|
|
|
There's an introductory Convert CSV files tutorial on hledger.org.
|
|
|
|
Examples
|
|
Here are some sample hledger CSV rules files. See also the full col-
|
|
lection at:
|
|
https://github.com/simonmichael/hledger/tree/master/examples/csv
|
|
|
|
Basic
|
|
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's a simple CSV file and a rules file for it:
|
|
|
|
Date, Description, Id, Amount
|
|
12/11/2019, Foo, 123, 10.23
|
|
|
|
# basic.csv.rules
|
|
skip 1
|
|
fields date, description, _, amount
|
|
date-format %d/%m/%Y
|
|
|
|
$ hledger print -f basic.csv
|
|
2019-11-12 Foo
|
|
expenses:unknown 10.23
|
|
income:unknown -10.23
|
|
|
|
Default account names are chosen, since we didn't set them.
|
|
|
|
Bank of Ireland
|
|
Here'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 neces-
|
|
sary but provides extra error checking:
|
|
|
|
Date,Details,Debit,Credit,Balance
|
|
07/12/2012,LODGMENT 529898,,10.0,131.21
|
|
07/12/2012,PAYMENT,5,,126
|
|
|
|
# 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 "balance"
|
|
# 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
|
|
|
|
$ 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
|
|
|
|
The balance assertions don't raise an error above, because we're read-
|
|
ing directly from CSV, but they will be checked if these entries are
|
|
imported into a journal file.
|
|
|
|
Amazon
|
|
Here we convert amazon.com order history, and use an if block to gener-
|
|
ate a third posting if there's a fee. (In practice you'd probably get
|
|
this data from your bank instead, but it's an example.)
|
|
|
|
"Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"
|
|
"Jul 29, 2012","Payment","To","Foo.","Completed","$20.00","$0.00","16000000000000DGLNJPI1P9B8DKPVHL"
|
|
"Jul 30, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$1.00","17LA58JSKRD4HDGLNJPI1P9B8DKPVHL"
|
|
|
|
# amazon-orders.csv.rules
|
|
|
|
# skip one header line
|
|
skip 1
|
|
|
|
# name the csv fields, and assign the transaction's date, amount and code.
|
|
# Avoided the "status" and "amount" 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'm assuming amzamount excludes the fees, don'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
|
|
|
|
$ 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
|
|
|
|
Paypal
|
|
Here's a real-world rules file for (customised) Paypal CSV, with some
|
|
Paypal-specific rules, and a second rules file included:
|
|
|
|
"Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"
|
|
"10/01/2019","03:46:20","PDT","Calm Radio","Subscription Payment","Completed","USD","-6.99","0.00","-6.99","simon@joyful.com","memberships@calmradio.com","60P57143A8206782E","MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month","","I-R8YLY094FJYR","","-6.99",""
|
|
"10/01/2019","03:46:20","PDT","","Bank Deposit to PP Account ","Pending","USD","6.99","0.00","6.99","","simon@joyful.com","0TU1544T080463733","","","60P57143A8206782E","","0.00",""
|
|
"10/01/2019","08:57:01","PDT","Patreon","PreApproved Payment Bill User Payment","Completed","USD","-7.00","0.00","-7.00","simon@joyful.com","support@patreon.com","2722394R5F586712G","Patreon* Membership","","B-0PG93074E7M86381M","","-7.00",""
|
|
"10/01/2019","08:57:01","PDT","","Bank Deposit to PP Account ","Pending","USD","7.00","0.00","7.00","","simon@joyful.com","71854087RG994194F","Patreon* Membership","","2722394R5F586712G","","0.00",""
|
|
"10/19/2019","03:02:12","PDT","Wikimedia Foundation, Inc.","Subscription Payment","Completed","USD","-2.00","0.00","-2.00","simon@joyful.com","tle@wikimedia.org","K9U43044RY432050M","Monthly donation to the Wikimedia Foundation","","I-R5C3YUS3285L","","-2.00",""
|
|
"10/19/2019","03:02:12","PDT","","Bank Deposit to PP Account ","Pending","USD","2.00","0.00","2.00","","simon@joyful.com","3XJ107139A851061F","","","K9U43044RY432050M","","0.00",""
|
|
"10/22/2019","05:07:06","PDT","Noble Benefactor","Subscription Payment","Completed","USD","10.00","-0.59","9.41","noble@bene.fac.tor","simon@joyful.com","6L8L1662YP1334033","Joyful Systems","","I-KC9VBGY2GWDB","","9.41",""
|
|
|
|
# paypal-custom.csv.rules
|
|
|
|
# Tips:
|
|
# Export from Activity -> Statements -> Custom -> Activity download
|
|
# Suggested transaction type: "Balance affecting"
|
|
# Paypal's default fields in 2018 were:
|
|
# "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Shipping Address","Address Status","Item Title","Item ID","Shipping and Handling Amount","Insurance Amount","Sales Tax","Option 1 Name","Option 1 Value","Option 2 Name","Option 2 Value","Reference Txn ID","Invoice Number","Custom Number","Quantity","Receipt ID","Balance","Address Line 1","Address Line 2/District/Neighborhood","Town/City","State/Province/Region/County/Territory/Prefecture/Republic","Zip/Postal Code","Country","Contact Phone Number","Subject","Note","Country Code","Balance Impact"
|
|
# This rules file assumes the following more detailed fields, configured in "Customize report fields":
|
|
# "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"
|
|
|
|
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'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's income (a debit)
|
|
if %grossamount ^[^-]
|
|
account2 income:unknown
|
|
# if negative, it's an expense (a credit)
|
|
if %grossamount ^-
|
|
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
|
|
|
|
# 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
|
|
|
|
$ 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@joyful.com, toemail:memberships@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@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@joyful.com, toemail:support@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@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@joyful.com, toemail:tle@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@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@bene.fac.tor, toemail:simon@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:
|
|
|
|
CSV rules
|
|
The following kinds of rule can appear in the rules file, in any order.
|
|
Blank lines and lines beginning with # or ; are ignored.
|
|
|
|
skip
|
|
skip N
|
|
|
|
The word "skip" 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'll need this when-
|
|
ever your CSV data contains header lines.
|
|
|
|
It also has a second purpose: it can be used inside if blocks to ignore
|
|
certain CSV records (described below).
|
|
|
|
fields
|
|
fields FIELDNAME1, FIELDNAME2, ...
|
|
|
|
A fields list (the word "fields" followed by comma-separated field
|
|
names) is the quick way to assign CSV field values to hledger fields.
|
|
It does two things:
|
|
|
|
1. it names the CSV fields. This is optional, but can be convenient
|
|
later for interpolating them.
|
|
|
|
2. when you use a standard hledger field name, it assigns the CSV value
|
|
to that part of the hledger transaction.
|
|
|
|
Here's an example that says "use the 1st, 2nd and 4th fields as the
|
|
transaction's date, description and amount; name the last two fields
|
|
for later reference; and ignore the others":
|
|
|
|
fields date, description, , amount, , , somefield, anotherfield
|
|
|
|
Field names may not contain whitespace. Fields you don't care about
|
|
can be left unnamed. Currently there must be least two items (there
|
|
must be at least one comma).
|
|
|
|
Note, always use comma in the fields list, even if your CSV uses an-
|
|
other separator character.
|
|
|
|
Here are the standard hledger field/pseudo-field names. For more about
|
|
the transaction parts they refer to, see the manual for hledger's jour-
|
|
nal format.
|
|
|
|
Transaction field names
|
|
date, date2, status, code, description, comment can be used to form the
|
|
transaction's first line.
|
|
|
|
Posting field names
|
|
account
|
|
accountN, where N is 1 to 99, causes a posting to be generated, with
|
|
that account name.
|
|
|
|
Most often there are two postings, so you'll want to set account1 and
|
|
account2. Typically account1 is associated with the CSV file, and is
|
|
set once with a top-level assignment, while account2 is set based on
|
|
each transaction's description, and in conditional blocks.
|
|
|
|
If a posting's account name is left unset but its amount is set (see
|
|
below), a default account name will be chosen (like "expenses:unknown"
|
|
or "income:unknown").
|
|
|
|
amount
|
|
amountN sets posting N's amount. If the CSV uses separate fields for
|
|
inflows and outflows, you can use amountN-in and amountN-out instead.
|
|
By assigning to amount1, amount2, ... etc. you can generate anywhere
|
|
from 0 to 99 postings.
|
|
|
|
There is also an older, unnumbered form of these names, suitable for
|
|
2-posting transactions, which sets both posting 1's and (negated) post-
|
|
ing 2's amount: amount, or amount-in and amount-out. 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's amount to cost if there's a transaction price, which can be useful.
|
|
|
|
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 amount/amount-in/amount-out if any of
|
|
amount1/amount1-in/amount1-out are assigned, and posting 2 ignores them
|
|
if any of amount2/amount2-in/amount2-out are assigned, avoiding con-
|
|
flicts.
|
|
|
|
currency
|
|
If the CSV has the currency symbol in a separate field (ie, not part of
|
|
the amount field), you can use currencyN to prepend it to posting N's
|
|
amount. Or, currency with no number affects all postings.
|
|
|
|
balance
|
|
balanceN sets a balance assertion amount (or if the posting amount is
|
|
left empty, a balance assignment) on posting N.
|
|
|
|
Also, for compatibility with hledger <1.17: balance with no number is
|
|
equivalent to balance1.
|
|
|
|
You can adjust the type of assertion/assignment with the balance-type
|
|
rule (see below).
|
|
|
|
comment
|
|
Finally, commentN sets a comment on the Nth posting. Comments can also
|
|
contain tags, as usual.
|
|
|
|
See TIPS below for more about setting amounts and currency.
|
|
|
|
field assignment
|
|
HLEDGERFIELDNAME FIELDVALUE
|
|
|
|
Instead of or in addition to a fields list, you can use a "field as-
|
|
signment" 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 (%N), or by the name they
|
|
were given in the fields list (%CSVFIELDNAME). Some examples:
|
|
|
|
# set the amount to the 4th CSV field, with " USD" appended
|
|
amount %4 USD
|
|
|
|
# combine three fields to make a comment, containing note: and date: tags
|
|
comment note: %somefield - %anotherfield, date: %1
|
|
|
|
Interpolation strips outer whitespace (so a CSV value like " 1 " be-
|
|
comes 1 when interpolated) (#1051). See TIPS below for more about ref-
|
|
erencing other fields.
|
|
|
|
separator
|
|
You can use the separator rule to read other kinds of character-sepa-
|
|
rated data. The argument is any single separator character, or the
|
|
words tab or space (case insensitive). Eg, for comma-separated values
|
|
(CSV):
|
|
|
|
separator ,
|
|
|
|
or for semicolon-separated values (SSV):
|
|
|
|
separator ;
|
|
|
|
or for tab-separated values (TSV):
|
|
|
|
separator TAB
|
|
|
|
If the input file has a .csv, .ssv or .tsv file extension (or a csv:,
|
|
ssv:, tsv: prefix), the appropriate separator will be inferred automat-
|
|
ically, and you won't need this rule.
|
|
|
|
if block
|
|
if MATCHER
|
|
RULE
|
|
|
|
if
|
|
MATCHER
|
|
MATCHER
|
|
MATCHER
|
|
RULE
|
|
RULE
|
|
|
|
Conditional blocks ("if blocks") 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.
|
|
|
|
Matching the whole record
|
|
Each MATCHER can be a record matcher, which looks like this:
|
|
|
|
REGEX
|
|
|
|
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 (\b, \B, \<, \>),
|
|
and nothing else. If you have trouble, be sure to check our
|
|
https://hledger.org/hledger.html#regular-expressions doc.
|
|
|
|
Important note: the record that is matched is not the original record,
|
|
but a synthetic one, with any enclosing double quotes (but not enclos-
|
|
ing 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 2020-01-01; "Acme, Inc."; 1,000, the REGEX will ac-
|
|
tually see 2020-01-01,Acme, Inc., 1,000).
|
|
|
|
Matching individual fields
|
|
Or, MATCHER can be a field matcher, like this:
|
|
|
|
%CSVFIELD REGEX
|
|
|
|
which matches just the content of a particular CSV field. CSVFIELD is
|
|
a percent sign followed by the field's name or column number, like
|
|
%date or %1.
|
|
|
|
Combining matchers
|
|
A single matcher can be written on the same line as the "if"; or multi-
|
|
ple matchers can be written on the following lines, non-indented. Mul-
|
|
tiple matchers are OR'd (any one of them can match), unless one begins
|
|
with an & symbol, in which case it is AND'ed with the previous matcher.
|
|
|
|
if
|
|
MATCHER
|
|
& MATCHER
|
|
RULE
|
|
|
|
Rules applied on successful match
|
|
After the patterns there should be one or more rules to apply, all in-
|
|
dented by at least one space. Three kinds of rule are allowed in con-
|
|
ditional blocks:
|
|
|
|
o field assignments (to set a hledger field)
|
|
|
|
o skip (to skip the matched CSV record)
|
|
|
|
o end (to skip all remaining CSV records).
|
|
|
|
Examples:
|
|
|
|
# if the CSV record contains "groceries", set account2 to "expenses:groceries"
|
|
if groceries
|
|
account2 expenses:groceries
|
|
|
|
# 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
|
|
|
|
if table
|
|
if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn
|
|
MATCHER1,VALUE11,VALUE12,...,VALUE1n
|
|
MATCHER2,VALUE21,VALUE22,...,VALUE2n
|
|
MATCHER3,VALUE31,VALUE32,...,VALUE3n
|
|
<empty line>
|
|
|
|
Conditional tables ("if tables") are a different syntax to specify
|
|
field assignments that will be applied only to CSV records which match
|
|
certain patterns.
|
|
|
|
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 if line, in the same order.
|
|
|
|
Therefore if table is exactly equivalent to a sequence of of if blocks:
|
|
|
|
if MATCHER1
|
|
CSVFIELDNAME1 VALUE11
|
|
CSVFIELDNAME2 VALUE12
|
|
...
|
|
CSVFIELDNAMEn VALUE1n
|
|
|
|
if MATCHER2
|
|
CSVFIELDNAME1 VALUE21
|
|
CSVFIELDNAME2 VALUE22
|
|
...
|
|
CSVFIELDNAMEn VALUE2n
|
|
|
|
if MATCHER3
|
|
CSVFIELDNAME1 VALUE31
|
|
CSVFIELDNAME2 VALUE32
|
|
...
|
|
CSVFIELDNAMEn VALUE3n
|
|
|
|
Each line starting with MATCHER should contain enough (possibly empty)
|
|
values for all the listed fields.
|
|
|
|
Rules would be checked and applied in the order they are listed in the
|
|
table and, like with if blocks, later rules (in the same or another ta-
|
|
ble) or if blocks could override the effect of any rule.
|
|
|
|
Instead of ',' you can use a variety of other non-alphanumeric charac-
|
|
ters as a separator. First character after if is taken to be the sepa-
|
|
rator 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.
|
|
|
|
Example:
|
|
|
|
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
|
|
|
|
end
|
|
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:
|
|
|
|
# ignore everything following the first empty record
|
|
if ,,,,
|
|
end
|
|
|
|
date-format
|
|
date-format DATEFMT
|
|
|
|
This is a helper for the date (and date2) fields. If your CSV dates
|
|
are not formatted like YYYY-MM-DD, YYYY/MM/DD or YYYY.MM.DD, you'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:
|
|
|
|
# MM/DD/YY
|
|
date-format %m/%d/%y
|
|
|
|
# D/M/YYYY
|
|
# The - makes leading zeros optional.
|
|
date-format %-d/%-m/%Y
|
|
|
|
# YYYY-Mmm-DD
|
|
date-format %Y-%h-%d
|
|
|
|
# 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
|
|
|
|
For the supported strptime syntax, see:
|
|
https://hackage.haskell.org/package/time/docs/Data-Time-For-
|
|
mat.html#v:formatTime
|
|
|
|
decimal-mark
|
|
decimal-mark .
|
|
|
|
or:
|
|
|
|
decimal-mark ,
|
|
|
|
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.
|
|
|
|
newest-first
|
|
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's normal order is
|
|
oldest first or newest first. But if all of the following are true:
|
|
|
|
o the CSV might sometimes contain just one day of data (all records
|
|
having the same date)
|
|
|
|
o the CSV records are normally in reverse chronological order (newest
|
|
at the top)
|
|
|
|
o and you care about preserving the order of same-day transactions
|
|
|
|
then, you should add the newest-first rule as a hint. Eg:
|
|
|
|
# tell hledger explicitly that the CSV is normally newest first
|
|
newest-first
|
|
|
|
include
|
|
include RULESFILE
|
|
|
|
This includes the contents of another CSV rules file at this point.
|
|
RULESFILE is an absolute file path or a path relative to the current
|
|
file's directory. This can be useful for sharing common rules between
|
|
several rules files, eg:
|
|
|
|
# someaccount.csv.rules
|
|
|
|
## someaccount-specific rules
|
|
fields date,description,amount
|
|
account1 assets:someaccount
|
|
account2 expenses:misc
|
|
|
|
## common rules
|
|
include categorisation.rules
|
|
|
|
balance-type
|
|
Balance assertions generated by assigning to balanceN are of the simple
|
|
= 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
|
|
balance-type rule:
|
|
|
|
# balance assertions will consider all commodities and all subaccounts
|
|
balance-type ==*
|
|
|
|
Here are the balance assertion types for quick reference:
|
|
|
|
= single commodity, exclude subaccounts
|
|
=* single commodity, include subaccounts
|
|
== multi commodity, exclude subaccounts
|
|
==* multi commodity, include subaccounts
|
|
|
|
Tips
|
|
Rapid feedback
|
|
It's a good idea to get rapid feedback while creating/troubleshooting
|
|
CSV rules. Here's a good way, using entr from http://eradman.com/entr-
|
|
project :
|
|
|
|
$ ls foo.csv* | entr bash -c 'echo ----; hledger -f foo.csv print desc:SOMEDESC'
|
|
|
|
A desc: query (eg) is used to select just one, or a few, transactions
|
|
of interest. "bash -c" 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.
|
|
|
|
Valid CSV
|
|
hledger accepts CSV conforming to RFC 4180. When CSV values are en-
|
|
closed in quotes, note:
|
|
|
|
o they must be double quotes (not single quotes)
|
|
|
|
o spaces outside the quotes are not allowed
|
|
|
|
File Extension
|
|
To help hledger identify the format and show the right error messages,
|
|
CSV/SSV/TSV files should normally be named with a .csv, .ssv or .tsv
|
|
filename extension. Or, the file path should be prefixed with csv:,
|
|
ssv: or tsv:. Eg:
|
|
|
|
$ hledger -f foo.ssv print
|
|
|
|
or:
|
|
|
|
$ cat foo | hledger -f ssv:- foo
|
|
|
|
You can override the file extension with a separator rule if needed.
|
|
See also: Input files in the hledger manual.
|
|
|
|
Reading multiple CSV files
|
|
If you use multiple -f 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 --rules-file option, that rules file will be
|
|
used for all the CSV files.
|
|
|
|
Valid transactions
|
|
After reading a CSV file, hledger post-processes and validates the gen-
|
|
erated 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.
|
|
|
|
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 as-
|
|
sertions generated from CSV right away, pipe into another hledger:
|
|
|
|
$ hledger -f file.csv print | hledger -f- print
|
|
|
|
Deduplicating, importing
|
|
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.
|
|
|
|
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't have to remember how many times you ran it or with which version
|
|
of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This
|
|
is the easiest way to import CSV data. Eg:
|
|
|
|
# download the latest CSV files, then run this command.
|
|
# Note, no -f flags needed here.
|
|
$ hledger import *.csv [--dry]
|
|
|
|
This method works for most CSV files. (Where records have a stable
|
|
chronological order, and new records appear only at the new end.)
|
|
|
|
A number of other tools and workflows, hledger-specific and otherwise,
|
|
exist for converting, deduplicating, classifying and managing CSV data.
|
|
See:
|
|
|
|
o https://hledger.org -> sidebar -> real world setups
|
|
|
|
o https://plaintextaccounting.org -> data import/conversion
|
|
|
|
Setting amounts
|
|
A posting amount can be set in one of these ways:
|
|
|
|
o by assigning (with a fields list or field assignment) to amountN
|
|
(posting N's amount) or amount (posting 1's amount)
|
|
|
|
o by assigning to amountN-in and amountN-out (or amount-in and amount-
|
|
out). 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.
|
|
|
|
o by assigning to balanceN (or balance) 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.
|
|
|
|
There is some special handling for an amount's sign:
|
|
|
|
o If an amount value is parenthesised, it will be de-parenthesised and
|
|
sign-flipped.
|
|
|
|
o If an amount value begins with a double minus sign, those cancel out
|
|
and are removed.
|
|
|
|
o If an amount value begins with a plus sign, that will be removed
|
|
|
|
Setting currency/commodity
|
|
If the currency/commodity symbol is included in the CSV's amount
|
|
field(s):
|
|
|
|
2020-01-01,foo,$123.00
|
|
|
|
you don't have to do anything special for the commodity symbol, it will
|
|
be assigned as part of the amount. Eg:
|
|
|
|
fields date,description,amount
|
|
|
|
2020-01-01 foo
|
|
expenses:unknown $123.00
|
|
income:unknown $-123.00
|
|
|
|
If the currency is provided as a separate CSV field:
|
|
|
|
2020-01-01,foo,USD,123.00
|
|
|
|
You can assign that to the currency pseudo-field, which has the special
|
|
effect of prepending itself to every amount in the transaction (on the
|
|
left, with no separating space):
|
|
|
|
fields date,description,currency,amount
|
|
|
|
2020-01-01 foo
|
|
expenses:unknown USD123.00
|
|
income:unknown USD-123.00
|
|
|
|
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:
|
|
|
|
fields date,description,cur,amt
|
|
amount %amt %cur
|
|
|
|
2020-01-01 foo
|
|
expenses:unknown 123.00 USD
|
|
income:unknown -123.00 USD
|
|
|
|
Note we used a temporary field name (cur) that is not currency - that
|
|
would trigger the prepending effect, which we don't want here.
|
|
|
|
Referencing other fields
|
|
In field assignments, you can interpolate only CSV fields, not hledger
|
|
fields. In the example below, there's both a CSV field and a hledger
|
|
field named amount1, but %amount1 always means the CSV field, not the
|
|
hledger field:
|
|
|
|
# Name the third CSV field "amount1"
|
|
fields date,description,amount1
|
|
|
|
# Set hledger'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
|
|
|
|
Here, since there's no CSV amount1 field, %amount1 will produce a lit-
|
|
eral "amount1":
|
|
|
|
fields date,description,csvamount
|
|
amount1 %csvamount USD
|
|
# Can't interpolate amount1 here
|
|
comment %amount1
|
|
|
|
When there are multiple field assignments to the same hledger field,
|
|
only the last one takes effect. Here, comment's value will be be B, or
|
|
C if "something" is matched, but never A:
|
|
|
|
comment A
|
|
comment B
|
|
if something
|
|
comment C
|
|
|
|
How CSV rules are evaluated
|
|
Here's how to think of CSV rules being evaluated (if you really need
|
|
to). First,
|
|
|
|
o include - 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.)
|
|
|
|
Then "global" rules are evaluated, top to bottom. If a rule is re-
|
|
peated, the last one wins:
|
|
|
|
o skip (at top level)
|
|
|
|
o date-format
|
|
|
|
o newest-first
|
|
|
|
o fields - names the CSV fields, optionally sets up initial assignments
|
|
to hledger fields
|
|
|
|
Then for each CSV record in turn:
|
|
|
|
o test all if blocks. If any of them contain a end rule, skip all re-
|
|
maining CSV records. Otherwise if any of them contain a skip rule,
|
|
skip that many CSV records. If there are multiple matched skip
|
|
rules, the first one wins.
|
|
|
|
o collect all field assignments at top level and in matched if blocks.
|
|
When there are multiple assignments for a field, keep only the last
|
|
one.
|
|
|
|
o compute a value for each hledger field - either the one that was as-
|
|
signed to it (and interpolate the %CSVFIELDNAME references), or a de-
|
|
fault
|
|
|
|
o generate a synthetic hledger transaction from these values.
|
|
|
|
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.
|
|
|
|
TIMECLOCK FORMAT
|
|
The time logging format of timeclock.el, as read by hledger.
|
|
|
|
hledger can read time logs in timeclock format. As with Ledger, these
|
|
are (a subset of) timeclock.el'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).
|
|
|
|
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
|
|
|
|
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, hledger print generates these journal entries:
|
|
|
|
$ 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
|
|
|
|
Here is a sample.timeclock to download and some queries to try:
|
|
|
|
$ 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
|
|
|
|
To generate time logs, ie to clock in and clock out, you could:
|
|
|
|
o use emacs and the built-in timeclock.el, or the extended timeclock-
|
|
x.el and perhaps the extras in ledgerutils.el
|
|
|
|
o at the command line, use these bash aliases: shell alias ti="echo
|
|
i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o
|
|
`date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"
|
|
|
|
o or use the old ti and to scripts in the ledger 2.x repository. These
|
|
rely on a "timeclock" executable which I think is just the ledger 2
|
|
executable renamed.
|
|
|
|
TIMEDOT FORMAT
|
|
hledger's human-friendly time logging format.
|
|
|
|
Timedot is a plain text format for logging dated, categorised quanti-
|
|
ties (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 interrup-
|
|
tive. It can be formatted like a bar chart, making clear at a glance
|
|
where time was spent.
|
|
|
|
Though called "timedot", this format is read by hledger as commodity-
|
|
less quantities, so it could be used to represent dated quantities
|
|
other than time. In the docs below we'll assume it's time.
|
|
|
|
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 descrip-
|
|
tion for this day.
|
|
|
|
This is followed by optionally-indented timelog items for that day, one
|
|
per line. Each timelog item is a note, usually a hledger:style:ac-
|
|
count:name representing a time category, followed by two or more spa-
|
|
ces, and a quantity. Each timelog item generates a hledger transac-
|
|
tion.
|
|
|
|
Quantities can be written as:
|
|
|
|
o dots: a sequence of dots (.) representing quarter hours. Spaces may
|
|
optionally be used for grouping. Eg: .... ..
|
|
|
|
o an integral or decimal number, representing hours. Eg: 1.5
|
|
|
|
o an integral or decimal number immediately followed by a unit symbol
|
|
s, m, h, d, w, mo, or y, representing seconds, minutes, hours, days
|
|
weeks, months or years respectively. Eg: 90m. The following equiva-
|
|
lencies are assumed, currently: 1m = 60s, 1h = 60m, 1d = 24h, 1w =
|
|
7d, 1mo = 30d, 1y=365d.
|
|
|
|
There is some flexibility allowing notes and todo lists to be kept
|
|
right in the time log, if needed:
|
|
|
|
o Blank lines and lines beginning with # or ; are ignored.
|
|
|
|
o 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.)
|
|
|
|
o Org mode headlines (lines beginning with one or more * followed by a
|
|
space) can be used as date lines or timelog items (the stars are ig-
|
|
nored). Also all org headlines before the first date line are ig-
|
|
nored. This means org users can manage their timelog as an org out-
|
|
line (eg using org-mode/orgstruct-mode in Emacs), for organisation,
|
|
faster navigation, controlling visibility etc.
|
|
|
|
Examples:
|
|
|
|
# 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 .
|
|
|
|
2016/2/3
|
|
inc:client1 4
|
|
fos:hledger 3
|
|
biz:research 1
|
|
|
|
* Time log
|
|
** 2020-01-01
|
|
*** adm:time .
|
|
*** adm:finance .
|
|
|
|
* 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
|
|
|
|
Reporting:
|
|
|
|
$ hledger -f t.timedot print date:2016/2/2
|
|
2016-02-02 *
|
|
(inc:client1) 2.00
|
|
|
|
2016-02-02 *
|
|
(biz:research) 0.25
|
|
|
|
$ 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
|
|
|
|
I prefer to use period for separating account components. We can make
|
|
this work with an account alias:
|
|
|
|
2016/2/4
|
|
fos.hledger.timedot 4
|
|
fos.ledger ..
|
|
|
|
$ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4 --tree
|
|
4.50 fos
|
|
4.00 hledger:timedot
|
|
0.50 ledger
|
|
--------------------
|
|
4.50
|
|
|
|
Here is a sample.timedot.
|
|
|
|
COMMON TASKS
|
|
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.
|
|
|
|
Getting help
|
|
$ 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
|
|
|
|
Find more docs, chat, mail list, reddit, issue tracker:
|
|
https://hledger.org#help-feedback
|
|
|
|
Constructing command lines
|
|
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 hap-
|
|
pens, here are some tips that may help:
|
|
|
|
o command-specific options must go after the command (it's fine to put
|
|
all options there) (hledger CMD OPTS ARGS)
|
|
|
|
o running add-on executables directly simplifies command line parsing
|
|
(hledger-ui OPTS ARGS)
|
|
|
|
o enclose "problematic" args in single quotes
|
|
|
|
o if needed, also add a backslash to hide regular expression metachar-
|
|
acters from the shell
|
|
|
|
o to see how a misbehaving command is being parsed, add --debug=2.
|
|
|
|
Starting a journal file
|
|
hledger looks for your accounting data in a journal file,
|
|
$HOME/.hledger.journal by default:
|
|
|
|
$ hledger stats
|
|
The hledger journal file "/Users/simon/.hledger.journal" was not found.
|
|
Please create it first, eg with "hledger add" or a text editor.
|
|
Or, specify an existing journal file with -f or LEDGER_FILE.
|
|
|
|
You can override this by setting the LEDGER_FILE environment variable.
|
|
It'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:
|
|
|
|
$ mkdir ~/finance
|
|
$ cd ~/finance
|
|
$ git init
|
|
Initialized empty Git repository in /Users/simon/finance/.git/
|
|
$ touch 2020.journal
|
|
$ echo "export LEDGER_FILE=$HOME/finance/2020.journal" >> ~/.bashrc
|
|
$ source ~/.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 ()
|
|
|
|
Setting opening balances
|
|
Pick a starting date for which you can look up the balances of some
|
|
real-world assets (bank accounts, wallet..) and liabilities (credit
|
|
cards..).
|
|
|
|
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 re-
|
|
cent starting date, like today or the start of the week. You can al-
|
|
ways come back later and add more accounts and older transactions, eg
|
|
going back to january 1st.
|
|
|
|
Add an opening balances transaction to the journal, declaring the bal-
|
|
ances on this date. Here are two ways to do it:
|
|
|
|
o The first way: open the journal in any text editor and save an entry
|
|
like this:
|
|
|
|
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
|
|
|
|
These are start-of-day balances, ie whatever was in the account at
|
|
the end of the previous day.
|
|
|
|
The * after the date is an optional status flag. Here it means
|
|
"cleared & confirmed".
|
|
|
|
The currency symbols are optional, but usually a good idea as you'll
|
|
be dealing with multiple currencies sooner or later.
|
|
|
|
The = amounts are optional balance assertions, providing extra error
|
|
checking.
|
|
|
|
o The second way: run hledger add and follow the prompts to record a
|
|
similar transaction:
|
|
|
|
$ 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]: .
|
|
|
|
If you're using version control, this could be a good time to commit
|
|
the journal. Eg:
|
|
|
|
$ git commit -m 'initial balances' 2020.journal
|
|
|
|
Recording transactions
|
|
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.
|
|
|
|
Here are some simple transactions, see the hledger_journal(5) manual
|
|
and hledger.org for more ideas:
|
|
|
|
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
|
|
|
|
Reconciling
|
|
Periodically you should reconcile - compare your hledger-reported bal-
|
|
ances against external sources of truth, like bank statements or your
|
|
bank'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 dis-
|
|
crepancies.
|
|
|
|
A typical workflow:
|
|
|
|
1. Reconcile cash. Count what's in your wallet. Compare with what
|
|
hledger reports (hledger bal cash). If they are different, try to
|
|
remember the missing transaction, or look for the error in the al-
|
|
ready-recorded transactions. A register report can be helpful
|
|
(hledger reg cash). If you can't find the error, add an adjustment
|
|
transaction. Eg if you have $105 after the above, and can't explain
|
|
the missing $2, it could be:
|
|
|
|
2020-01-16 * adjust cash
|
|
assets:cash $-2 = $105
|
|
expenses:misc
|
|
|
|
2. Reconcile checking. Log in to your bank's website. Compare today's
|
|
(cleared) balance with hledger's cleared balance (hledger bal check-
|
|
ing -C). 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 trans-
|
|
action history and running balance from your bank with the one re-
|
|
ported by hledger reg checking -C. This will be easier if you gen-
|
|
erally record transaction dates quite similar to your bank's clear-
|
|
ing dates.
|
|
|
|
3. Repeat for other asset/liability accounts.
|
|
|
|
Tip: instead of the register command, use hledger-ui to see a live-up-
|
|
dating register while you edit the journal: hledger-ui --watch --regis-
|
|
ter checking -C
|
|
|
|
After reconciling, it could be a good time to mark the reconciled
|
|
transactions' status as "cleared and confirmed", if you want to track
|
|
that, by adding the * marker. Eg in the paycheck transaction above,
|
|
insert * between 2020-01-15 and paycheck
|
|
|
|
If you're using version control, this can be another good time to com-
|
|
mit:
|
|
|
|
$ git commit -m 'txns' 2020.journal
|
|
|
|
Reporting
|
|
Here are some basic reports.
|
|
|
|
Show all transactions:
|
|
|
|
$ 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
|
|
|
|
Show account names, and their hierarchy:
|
|
|
|
$ hledger accounts --tree
|
|
assets
|
|
bank
|
|
checking
|
|
savings
|
|
cash
|
|
equity
|
|
opening/closing balances
|
|
expenses
|
|
food
|
|
misc
|
|
income
|
|
gifts
|
|
salary
|
|
liabilities
|
|
creditcard
|
|
|
|
Show all account totals:
|
|
|
|
$ 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
|
|
|
|
Show only asset and liability balances, as a flat list, limited to
|
|
depth 2:
|
|
|
|
$ hledger bal assets liabilities --flat -2
|
|
$4000 assets:bank
|
|
$105 assets:cash
|
|
$-50 liabilities:creditcard
|
|
--------------------
|
|
$4055
|
|
|
|
Show the same thing without negative numbers, formatted as a simple
|
|
balance sheet:
|
|
|
|
$ 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
|
|
|
|
The final total is your "net worth" on the end date. (Or use bse for a
|
|
full balance sheet with equity.)
|
|
|
|
Show income and expense totals, formatted as an income statement:
|
|
|
|
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
|
|
|
|
The final total is your net income during this period.
|
|
|
|
Show transactions affecting your wallet, with running total:
|
|
|
|
$ 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
|
|
|
|
Show weekly posting counts as a bar chart:
|
|
|
|
$ hledger activity -W
|
|
2019-12-30 *****
|
|
2020-01-06 ****
|
|
2020-01-13 ****
|
|
|
|
Migrating to a new file
|
|
At the end of the year, you may want to continue your journal in a new
|
|
file, so that old transactions don't slow down or clutter your reports,
|
|
and to help ensure the integrity of your accounting history. See the
|
|
close command.
|
|
|
|
If using version control, don't forget to git add the new file.
|
|
|
|
LIMITATIONS
|
|
The need to precede add-on command options with -- when invoked from
|
|
hledger is awkward.
|
|
|
|
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.
|
|
|
|
In a Microsoft Windows CMD window, non-ascii characters and colours are
|
|
not supported.
|
|
|
|
On Windows, non-ascii characters may not display correctly when running
|
|
a hledger built in CMD in MSYS/CYGWIN, or vice-versa.
|
|
|
|
In a Cygwin/MSYS/Mintty window, the tab key is not supported in hledger
|
|
add.
|
|
|
|
Not all of Ledger's journal file syntax is supported. See file format
|
|
differences.
|
|
|
|
On large data files, hledger is slower and uses more memory than
|
|
Ledger.
|
|
|
|
TROUBLESHOOTING
|
|
Here are some issues you might encounter when you run hledger (and re-
|
|
member you can also seek help from the IRC channel, mail list or bug
|
|
tracker):
|
|
|
|
Successfully installed, but "No command 'hledger' found"
|
|
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 ~/.local/bin and ~/.cabal/bin respectively.
|
|
|
|
I set a custom LEDGER_FILE, but hledger is still using the default file
|
|
LEDGER_FILE should be a real environment variable, not just a shell
|
|
variable. The command env | grep LEDGER_FILE should show it. You may
|
|
need to use export. Here's an explanation.
|
|
|
|
Getting errors like "Illegal byte sequence" or "Invalid or incomplete
|
|
multibyte or wide character" or "commitAndReleaseBuffer: invalid argu-
|
|
ment (invalid character)"
|
|
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.
|
|
|
|
To fix it, set the LANG environment variable to some locale which sup-
|
|
ports UTF-8. The locale you choose must be installed on your system.
|
|
|
|
Here's an example of setting LANG temporarily, on Ubuntu GNU/Linux:
|
|
|
|
$ 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'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
|
|
|
|
If available, C.UTF-8 will also work. If your preferred locale isn't
|
|
listed by locale -a, you might need to install it. Eg on Ubuntu/De-
|
|
bian:
|
|
|
|
$ 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
|
|
|
|
Here's how you could set it permanently, if you use a bash shell:
|
|
|
|
$ echo "export LANG=en_US.utf8" >>~/.bash_profile
|
|
$ bash --login
|
|
|
|
Exact spelling and capitalisation may be important. Note the differ-
|
|
ence on MacOS (UTF-8, not utf8). Some platforms (eg ubuntu) allow
|
|
variant spellings, but others (eg macos) require it to be exact:
|
|
|
|
$ locale -a | grep -iE en_us.*utf
|
|
en_US.UTF-8
|
|
$ LANG=en_US.UTF-8 hledger -f my.journal print
|
|
|
|
|
|
|
|
REPORTING BUGS
|
|
Report bugs at http://bugs.hledger.org (or on the #hledger IRC channel
|
|
or hledger mail list)
|
|
|
|
|
|
AUTHORS
|
|
Simon Michael <simon@joyful.com> and contributors
|
|
|
|
|
|
COPYRIGHT
|
|
Copyright (C) 2007-2020 Simon Michael.
|
|
Released under GNU GPL v3 or later.
|
|
|
|
|
|
SEE ALSO
|
|
hledger(1), hledger-ui(1), hledger-web(1), ledger(1)
|
|
|
|
|
|
|
|
hledger-1.20.99 December 2020 HLEDGER(1)
|