diff --git a/hledger-lib/.date.m4 b/hledger-lib/.date.m4 index c44025480..0908cb747 100644 --- a/hledger-lib/.date.m4 +++ b/hledger-lib/.date.m4 @@ -1,2 +1,2 @@ m4_dnl Date to show in man pages. Updated by "Shake manuals" -m4_define({{_monthyear_}}, {{June 2023}})m4_dnl +m4_define({{_monthyear_}}, {{August 2023}})m4_dnl diff --git a/hledger-ui/.date.m4 b/hledger-ui/.date.m4 index c44025480..0908cb747 100644 --- a/hledger-ui/.date.m4 +++ b/hledger-ui/.date.m4 @@ -1,2 +1,2 @@ m4_dnl Date to show in man pages. Updated by "Shake manuals" -m4_define({{_monthyear_}}, {{June 2023}})m4_dnl +m4_define({{_monthyear_}}, {{August 2023}})m4_dnl diff --git a/hledger-ui/hledger-ui.1 b/hledger-ui/hledger-ui.1 index 548e29243..94a3d0d1e 100644 --- a/hledger-ui/hledger-ui.1 +++ b/hledger-ui/hledger-ui.1 @@ -1,5 +1,5 @@ -.TH "HLEDGER-UI" "1" "June 2023" "hledger-ui-1.30.99 " "hledger User Manuals" +.TH "HLEDGER-UI" "1" "August 2023" "hledger-ui-1.30.99 " "hledger User Manuals" diff --git a/hledger-ui/hledger-ui.txt b/hledger-ui/hledger-ui.txt index 4b20aac38..dd71dfd35 100644 --- a/hledger-ui/hledger-ui.txt +++ b/hledger-ui/hledger-ui.txt @@ -1,8 +1,6 @@ HLEDGER-UI(1) hledger User Manuals HLEDGER-UI(1) - - NAME hledger-ui - robust, friendly plain text accounting (TUI version) @@ -114,7 +112,7 @@ OPTIONS assignments) -s --strict - do extra error checking (check that all posted accounts are de- + do extra error checking (check that all posted accounts are de- clared) General reporting options @@ -142,7 +140,7 @@ OPTIONS multiperiod/multicolumn report by year -p --period=PERIODEXP - set start date, end date, and/or reporting interval all at once + set start date, end date, and/or reporting interval all at once using period expressions syntax --date2 @@ -233,7 +231,7 @@ OPTIONS Some reporting options can also be written as query arguments. MOUSE - In most modern terminals, you can navigate through the screens with a + In most modern terminals, you can navigate through the screens with a mouse or touchpad: o Use mouse wheel or trackpad to scroll up and down @@ -245,25 +243,25 @@ MOUSE KEYS Keyboard gives more control. - ? shows a help dialog listing all keys. (Some of these also appear in - the quick help at the bottom of each screen.) Press ? again (or ES- - CAPE, or LEFT, or q) to close it. The following keys work on most + ? shows a help dialog listing all keys. (Some of these also appear in + the quick help at the bottom of each screen.) Press ? again (or ES- + CAPE, or LEFT, or q) to close it. The following keys work on most screens: - The cursor keys navigate: RIGHT or ENTER goes deeper, LEFT returns to + The cursor keys navigate: RIGHT or ENTER goes deeper, LEFT returns to the previous screen, UP/DOWN/PGUP/PGDN/HOME/END move up and down - through lists. Emacs-style (CTRL-p/CTRL-n/CTRL-f/CTRL-b) and VI-style - (k,j,l,h) movement keys are also supported. A tip: movement speed is - limited by your keyboard repeat rate, to move faster you may want to - adjust it. (If you're on a mac, the karabiner app is one way to do + through lists. Emacs-style (CTRL-p/CTRL-n/CTRL-f/CTRL-b) and VI-style + (k,j,l,h) movement keys are also supported. A tip: movement speed is + limited by your keyboard repeat rate, to move faster you may want to + adjust it. (If you're on a mac, the karabiner app is one way to do that.) - With shift pressed, the cursor keys adjust the report period, limiting - the transactions to be shown (by default, all are shown). SHIFT- - DOWN/UP steps downward and upward through these standard report period - durations: year, quarter, month, week, day. Then, SHIFT-LEFT/RIGHT - moves to the previous/next period. T sets the report period to today. - With the -w/--watch option, when viewing a "current" period (the cur- + With shift pressed, the cursor keys adjust the report period, limiting + the transactions to be shown (by default, all are shown). SHIFT- + DOWN/UP steps downward and upward through these standard report period + durations: year, quarter, month, week, day. Then, SHIFT-LEFT/RIGHT + moves to the previous/next period. T sets the report period to today. + With the -w/--watch option, when viewing a "current" period (the cur- rent day, week, month, quarter, or year), the period will move automat- ically to track the current date. To set a non-standard period, you can use / and a date: query. @@ -280,10 +278,10 @@ KEYS the same query terms as in hledger and hledger-web. While editing the query, you can use CTRL-a/e/d/k, BS, cursor keys; press ENTER to set it, or ESCAPEto cancel. There are also keys for quickly adjusting some - common filters like account depth and transaction status (see below). + common filters like account depth and transaction status (see below). BACKSPACE or DELETE removes all filters, showing all transactions. - As mentioned above, by default hledger-ui hides future transactions - + As mentioned above, by default hledger-ui hides future transactions - both ordinary transactions recorded in the journal, and periodic trans- actions generated by rule. F toggles forecast mode, in which fu- ture/forecasted transactions are shown. @@ -339,15 +337,15 @@ KEYS SCREENS At startup, hledger-ui shows a menu screen by default. From here you can navigate to other screens using the cursor keys: UP/DOWN to select, - RIGHT to move to the selected screen, LEFT to return to the previous + RIGHT to move to the selected screen, LEFT to return to the previous screen. Or you can use ESC to return directly to the top menu screen. - You can also use a command line flag to specific a different startup + You can also use a command line flag to specific a different startup screen (--cs, --bs, --is, --all, or --register=ACCT). Menu - This is the top-most screen. From here you can navigate to several - screens listing accounts of various types. Note some of these may not + This is the top-most screen. From here you can navigate to several + screens listing accounts of various types. Note some of these may not show anything until you have configured account types. Cash accounts @@ -385,13 +383,13 @@ SCREENS o the period total, which is from just the transactions displayed - o or the historical total, which includes any undisplayed transac- - tions before the start of the report period (and matching the fil- - ter query if any). This will be the running historical balance - (what you would see on a bank's website, eg) if not disturbed by a + o or the historical total, which includes any undisplayed transac- + tions before the start of the report period (and matching the fil- + ter query if any). This will be the running historical balance + (what you would see on a bank's website, eg) if not disturbed by a query. - Transactions affecting this account's subaccounts will be included in + Transactions affecting this account's subaccounts will be included in the register if the accounts screen is in tree mode, or if it's in list mode but this account has subaccounts which are not shown due to a depth limit. In other words, the register always shows the transac- @@ -400,31 +398,31 @@ SCREENS U toggles filtering by unmarked status, showing or hiding unmarked transactions. Similarly, P toggles pending transactions, and C toggles - cleared transactions. (By default, transactions with all statuses are - shown; if you activate one or two status filters, only those transac- + cleared transactions. (By default, transactions with all statuses are + shown; if you activate one or two status filters, only those transac- tions are shown; and if you activate all three, the filter is removed.) R toggles real mode, in which virtual postings are ignored. - z toggles nonzero mode, in which only transactions posting a nonzero - change are shown (hledger-ui shows zero items by default, unlike com- + z toggles nonzero mode, in which only transactions posting a nonzero + change are shown (hledger-ui shows zero items by default, unlike com- mand-line hledger). Press RIGHT to view the selected transaction in detail. Transaction - This screen shows a single transaction, as a general journal entry, - similar to hledger's print command and journal format (hledger_jour- + This screen shows a single transaction, as a general journal entry, + similar to hledger's print command and journal format (hledger_jour- nal(5)). - The transaction's date(s) and any cleared flag, transaction code, de- - scription, comments, along with all of its account postings are shown. - Simple transactions have two postings, but there can be more (or in + The transaction's date(s) and any cleared flag, transaction code, de- + scription, comments, along with all of its account postings are shown. + Simple transactions have two postings, but there can be more (or in certain cases, fewer). - UP and DOWN will step through all transactions listed in the previous - account register screen. In the title bar, the numbers in parentheses - show your position within that account register. They will vary de- + UP and DOWN will step through all transactions listed in the previous + account register screen. In the title bar, the numbers in parentheses + show your position within that account register. They will vary de- pending on which account register you came from (remember most transac- tions appear in multiple account registers). The #N number preceding them is the transaction's position within the complete unfiltered jour- @@ -437,13 +435,13 @@ SCREENS This screen has a limitation with showing file updates: it will not show them until you exit and re-enter it. So eg to see the effect of using the E key, currently you must: - press E, edit and save the file, - then exit the editor, returning to hledger-ui - press g to reload the - file (or use -w/--watch mode) - press LEFT then RIGHT to exit and re- + then exit the editor, returning to hledger-ui - press g to reload the + file (or use -w/--watch mode) - press LEFT then RIGHT to exit and re- enter the transaction screen. Error - This screen will appear if there is a problem, such as a parse error, - when you press g to reload. Once you have fixed the problem, press g + This screen will appear if there is a problem, such as a parse error, + when you press g to reload. Once you have fixed the problem, press g again to reload and resume normal operation. (Or, you can press escape to cancel the reload attempt.) @@ -471,32 +469,32 @@ TIPS It may not work correctly for you, depending on platform or system con- figuration. (Eg #836.) - At least on mac, there can be a slow build-up of CPU usage over time, - until the program is restarted (or, suspending and restarting with + At least on mac, there can be a slow build-up of CPU usage over time, + until the program is restarted (or, suspending and restarting with CTRL-z fg may be enough). - It will not detect file changes made by certain editors, such as Jet- - brains IDEs or gedit, or on certain less common filesystems. (To work - around, press g to reload manually, or try #1617's fs.ino- + It will not detect file changes made by certain editors, such as Jet- + brains IDEs or gedit, or on certain less common filesystems. (To work + around, press g to reload manually, or try #1617's fs.ino- tify.max_user_watches workaround and let us know.) - If you are viewing files mounted from another machine, the system + If you are viewing files mounted from another machine, the system clocks on both machines should be roughly in agreement. Debug output - You can add --debug[=N] to the command line to log debug output. This - will be logged to the file hledger-ui.log in the current directory. N + You can add --debug[=N] to the command line to log debug output. This + will be logged to the file hledger-ui.log in the current directory. N ranges from 1 (least output, the default) to 9 (maximum output). ENVIRONMENT COLUMNS The screen width to use. Default: the full terminal width. - LEDGER_FILE The main journal file to use when not specified with + LEDGER_FILE The main journal file to use when not specified with -f/--file. Default: $HOME/.hledger.journal. BUGS We welcome bug reports in the hledger issue tracker (shortcut: - http://bugs.hledger.org), or on the #hledger chat or hledger mail list + http://bugs.hledger.org), or on the #hledger chat or hledger mail list (https://hledger.org/support). Some known issues: @@ -529,6 +527,4 @@ LICENSE SEE ALSO hledger(1), hledger-ui(1), hledger-web(1), ledger(1) - - -hledger-ui-1.30.99 June 2023 HLEDGER-UI(1) +hledger-ui-1.30.99 August 2023 HLEDGER-UI(1) diff --git a/hledger-web/.date.m4 b/hledger-web/.date.m4 index c44025480..0908cb747 100644 --- a/hledger-web/.date.m4 +++ b/hledger-web/.date.m4 @@ -1,2 +1,2 @@ m4_dnl Date to show in man pages. Updated by "Shake manuals" -m4_define({{_monthyear_}}, {{June 2023}})m4_dnl +m4_define({{_monthyear_}}, {{August 2023}})m4_dnl diff --git a/hledger-web/hledger-web.1 b/hledger-web/hledger-web.1 index b3d877dbc..ff32a9b60 100644 --- a/hledger-web/hledger-web.1 +++ b/hledger-web/hledger-web.1 @@ -1,5 +1,5 @@ -.TH "HLEDGER-WEB" "1" "June 2023" "hledger-web-1.30.99 " "hledger User Manuals" +.TH "HLEDGER-WEB" "1" "August 2023" "hledger-web-1.30.99 " "hledger User Manuals" diff --git a/hledger-web/hledger-web.txt b/hledger-web/hledger-web.txt index 979c6983b..88d3f3cb6 100644 --- a/hledger-web/hledger-web.txt +++ b/hledger-web/hledger-web.txt @@ -1,8 +1,6 @@ HLEDGER-WEB(1) hledger User Manuals HLEDGER-WEB(1) - - NAME hledger-web - robust, friendly plain text accounting (Web version) @@ -26,16 +24,16 @@ DESCRIPTION register, balance charts) and allowing history-aware data entry, inter- active searching, and bookmarking. - hledger-web also lets you share a journal with multiple users, or even - the public web. There is no access control, so if you need that you - should put it behind a suitable web proxy. As a small protection - against data loss when running an unprotected instance, it writes a + hledger-web also lets you share a journal with multiple users, or even + the public web. There is no access control, so if you need that you + should put it behind a suitable web proxy. As a small protection + against data loss when running an unprotected instance, it writes a numbered backup of the main journal file (only) on every edit. - Like hledger, it reads from (and appends to) a journal file specified - by the LEDGER_FILE environment variable (defaulting to - $HOME/.hledger.journal); or you can specify files with -f options. It - can also read timeclock files, timedot files, or any CSV/SSV/TSV file + Like hledger, it reads from (and appends to) a journal file specified + by the LEDGER_FILE environment variable (defaulting to + $HOME/.hledger.journal); or you can specify files with -f options. It + can also read timeclock files, timedot files, or any CSV/SSV/TSV file with a date field. (See hledger(1) -> Input for details.) hledger-web can be run in three modes: @@ -85,26 +83,26 @@ OPTIONS --file-url=URL set the static files url (default: BASEURL/static). hledger-web - normally serves static files itself, but if you wanted to serve - them from another server for efficiency, you would set the url + normally serves static files itself, but if you wanted to serve + them from another server for efficiency, you would set the url with this. --capabilities=CAP[,CAP..] - enable the view, add, and/or manage capabilities (default: + enable the view, add, and/or manage capabilities (default: view,add) --capabilities-header=HTTPHEADER - read capabilities to enable from a HTTP header, like X-Sand- + read capabilities to enable from a HTTP header, like X-Sand- storm-Permissions (default: disabled) - --test run hledger-web's tests and exit. hspec test runner args may + --test run hledger-web's tests and exit. hspec test runner args may follow a --, eg: hledger-web --test -- --help - By default the server listens on IP address 127.0.0.1, accessible only - to local requests. You can use --host to change this, eg --host + By default the server listens on IP address 127.0.0.1, accessible only + to local requests. You can use --host to change this, eg --host 0.0.0.0 to listen on all configured addresses. - Similarly, use --port to set a TCP port other than 5000, eg if you are + Similarly, use --port to set a TCP port other than 5000, eg if you are running multiple hledger-web instances. Both of these options are ignored when --socket is used. In this case, @@ -113,14 +111,14 @@ OPTIONS hledger-web instances behind a reverse proxy that handles authentica- tion for different users. The path can be derived in a predictable way, eg by using the username within the path. As an example, nginx as - reverse proxy can use the variable $remote_user to derive a path from - the username used in a HTTP basic authentication. The following - proxy_pass directive allows access to all hledger-web instances that + reverse proxy can use the variable $remote_user to derive a path from + the username used in a HTTP basic authentication. The following + proxy_pass directive allows access to all hledger-web instances that created a socket in /tmp/hledger/: proxy_pass http://unix:/tmp/hledger/${remote_user}.socket; - You can use --base-url to change the protocol, hostname, port and path + You can use --base-url to change the protocol, hostname, port and path that appear in hyperlinks, useful eg for integrating hledger-web within a larger website. The default is http://HOST:PORT/ using the server's configured host address and TCP port (or http://HOST if PORT is 80). @@ -170,7 +168,7 @@ OPTIONS assignments) -s --strict - do extra error checking (check that all posted accounts are de- + do extra error checking (check that all posted accounts are de- clared) General reporting options @@ -198,7 +196,7 @@ OPTIONS multiperiod/multicolumn report by year -p --period=PERIODEXP - set start date, end date, and/or reporting interval all at once + set start date, end date, and/or reporting interval all at once using period expressions syntax --date2 @@ -289,13 +287,13 @@ OPTIONS Some reporting options can also be written as query arguments. PERMISSIONS - By default, hledger-web allows anyone who can reach it to view the + By default, hledger-web allows anyone who can reach it to view the journal and to add new transactions, but not to change existing data. You can restrict who can reach it by - o setting the IP address it listens on (see --host above). By default - it listens on 127.0.0.1, accessible to all users on the local ma- + o setting the IP address it listens on (see --host above). By default + it listens on 127.0.0.1, accessible to all users on the local ma- chine. o putting it behind an authenticating proxy, using eg apache or nginx @@ -341,8 +339,8 @@ EDITING, UPLOADING, DOWNLOADING RELOADING hledger-web detects changes made to the files by other means (eg if you - edit it directly, outside of hledger-web), and it will show the new - data when you reload the page or navigate to a new page. If a change + edit it directly, outside of hledger-web), and it will show the new + data when you reload the page or navigate to a new page. If a change makes a file unparseable, hledger-web will display an error message un- til the file has been fixed. @@ -350,8 +348,8 @@ RELOADING that both machine clocks are roughly in step.) JSON API - In addition to the web UI, hledger-web also serves a JSON API that can - be used to get data or add new transactions. If you want the JSON API + In addition to the web UI, hledger-web also serves a JSON API that can + be used to get data or add new transactions. If you want the JSON API only, you can use the --serve-api flag. Eg: $ hledger-web -f examples/sample.journal --serve-api @@ -415,8 +413,8 @@ JSON API derstanding, see the journal docs. In some cases there is outer JSON corresponding to a "Report" type. To - understand that, go to the Hledger.Web.Handler.MiscR haddock and look - at the source for the appropriate handler to see what it returns. Eg + understand that, go to the Hledger.Web.Handler.MiscR haddock and look + at the source for the appropriate handler to see what it returns. Eg for /accounttransactions it's getAccounttransactionsR, returning a "ac- countTransactionsReport ...". Looking up the haddock for that we can see that /accounttransactions returns an AccountTransactionsReport, @@ -426,8 +424,8 @@ JSON API You can add a new transaction to the journal with a PUT request to /add, if hledger-web was started with the add capability (enabled by default). The payload must be the full, exact JSON representation of a - hledger transaction (partial data won't do). You can get sample JSON - from hledger-web's /transactions or /accounttransactions, or you can + hledger transaction (partial data won't do). You can get sample JSON + from hledger-web's /transactions or /accounttransactions, or you can export it with hledger-lib, eg like so: .../hledger$ stack ghci hledger-lib @@ -532,8 +530,8 @@ DEBUG OUTPUT Debug output You can add --debug[=N] to the command line to log debug output. N ranges from 1 (least output, the default) to 9 (maximum output). Typi- - cally you would start with 1 and increase until you are seeing enough. - Debug output goes to stderr, interleaved with the requests logged on + cally you would start with 1 and increase until you are seeing enough. + Debug output goes to stderr, interleaved with the requests logged on stdout. To capture debug output in a log file instead, you can usually redirect stderr, eg: hledger-web --debug=3 2>hledger-web.log. @@ -569,6 +567,4 @@ LICENSE SEE ALSO hledger(1), hledger-ui(1), hledger-web(1), ledger(1) - - -hledger-web-1.30.99 June 2023 HLEDGER-WEB(1) +hledger-web-1.30.99 August 2023 HLEDGER-WEB(1) diff --git a/hledger/.date.m4 b/hledger/.date.m4 index c44025480..0908cb747 100644 --- a/hledger/.date.m4 +++ b/hledger/.date.m4 @@ -1,2 +1,2 @@ m4_dnl Date to show in man pages. Updated by "Shake manuals" -m4_define({{_monthyear_}}, {{June 2023}})m4_dnl +m4_define({{_monthyear_}}, {{August 2023}})m4_dnl diff --git a/hledger/hledger.1 b/hledger/hledger.1 index 977d7a230..e64240919 100644 --- a/hledger/hledger.1 +++ b/hledger/hledger.1 @@ -1,6 +1,6 @@ .\"t -.TH "HLEDGER" "1" "June 2023" "hledger-1.30.99 " "hledger User Manuals" +.TH "HLEDGER" "1" "August 2023" "hledger-1.30.99 " "hledger User Manuals" @@ -759,7 +759,7 @@ Here are those commands and the formats currently supported: .PP .TS tab(@); -lw(25.9n) lw(9.1n) lw(9.1n) lw(11.7n) lw(7.8n) lw(6.5n). +lw(16.1n) lw(14.5n) lw(14.5n) lw(16.1n) lw(4.8n) lw(4.0n). T{ - T}@T{ @@ -1814,7 +1814,7 @@ making it \f[V]€100 \[at]\[at] $135\f[R], as in example 2: .RE .PP Amounts can be converted to cost at report time using the -\f[V]-B/--cost\f[R] flag; this is discussed more in the ˜COST REPORTING +\f[V]-B/--cost\f[R] flag; this is discussed more in the Cost reporting section. .PP Note that the cost normally should be a positive amount, though it\[aq]s @@ -2619,7 +2619,7 @@ or, it can be (these are used less often): assets for the cashflow report) .IP \[bu] 2 \f[V]V\f[R] or \f[V]Conversion\f[R] (a subtype of Equity, for -conversions (see COST REPORTING).) +conversions (see Cost reporting).) .PP Here is a typical set of account type declarations: .IP @@ -3133,7 +3133,7 @@ P 2010-01-01 € $1.40 .PP The \f[V]-V\f[R], \f[V]-X\f[R] and \f[V]--value\f[R] flags use these market prices to show amount values in another commodity. -See Valuation. +See Value reporting. .PP .SS \f[V]payee\f[R] directive .PP @@ -3499,6 +3499,11 @@ $ hledger print --explicit (a) $1 \[at] €2 = $1 \[at] €2 \f[R] .fi +.SS Balance assignments and multiple files +.PP +Balance assignments handle multiple files like balance assertions. +They see balance from other files previously included from the current +file, but not from previous sibling or parent files. .SS Bracketed posting dates .PP For setting posting dates and secondary posting dates, Ledger\[aq]s @@ -4073,7 +4078,7 @@ For others, use numeric format: +HHMM or -HHMM. .SS \f[V]newest-first\f[R] .PP hledger tries to ensure that the generated transactions will be ordered -chronologically, including intra-day transactions. +chronologically, including same-day transactions. Usually it can auto-detect how the CSV records are ordered. But if it encounters CSV where all records are on the same date, it assumes that the records are oldest first. @@ -4098,10 +4103,11 @@ newest-first .fi .SS \f[V]intra-day-reversed\f[R] .PP -CSV records for each day are sometimes ordered in reverse compared to -the overall date order. -Eg, here dates are newest first, but the transactions on each date are -oldest first: +If CSV records within a single day are ordered opposite to the overall +record order, you can add the \f[V]intra-day-reversed\f[R] rule to +improve the order of journal entries. +Eg, here the overall record order is newest first, but same-day records +are oldest first: .IP .nf \f[C] @@ -4111,9 +4117,6 @@ oldest first: 2022-10-01, txn 2... \f[R] .fi -.PP -In this situation, add the \f[V]intra-day-reversed\f[R] rule, and -hledger will compensate, improving the order of transactions. .IP .nf \f[C] @@ -4326,103 +4329,69 @@ below), a default account name will be chosen (like \[dq]expenses:unknown\[dq] or \[dq]income:unknown\[dq]). .SS amount field .PP -Amount setting can get a bit complex. -Assigning to \f[V]amount\f[R] is sufficient for simple transactions, but -there are four field name variants you can use for different situations: +There are several ways to set posting amounts from CSV, useful in +different situations. +.IP "1." 3 +\f[B]\f[VB]amount\f[B]\f[R] is the oldest and simplest. +Assigning to this sets the amount of the first and second postings. +In the second posting, the amount will be negated; also, if it has a +cost attached, it will be converted to cost. +.IP "2." 3 +\f[B]\f[VB]amount-in\f[B]\f[R] and \f[B]\f[VB]amount-out\f[B]\f[R] work +exactly like the above, but should be used when the CSV has two amount +fields (such as \[dq]Debit\[dq] and \[dq]Credit\[dq], or +\[dq]Inflow\[dq] and \[dq]Outflow\[dq]). +Whichever field has a non-zero value will be used as the amount of the +first and second postings. +Here are some tips to avoid confusion: +.RS 4 .IP \[bu] 2 -\f[B]\f[VB]amountN\f[B] sets a specific posting\[aq]s amount from one -CSV field or arbitrary value.\f[R] -.PD 0 -.P -.PD -Assigning to \f[V]amountN\f[R] sets the amount of the Nth posting - and -also causes that posting to be generated. -N is most often 1 or 2 but can go up to 99, potentially generating a -99-posting transaction. -(Posting numbers don\[aq]t have to be consecutive; higher posting -numbers can sometimes be useful with conditional rules, to ensure a -certain ordering of postings.) +It\[aq]s not \[dq]amount-in for posting 1 and amount-out for posting +2\[dq], it is \[dq]extract a single amount from the amount-in or +amount-out field, and use that for posting 1 and (negated) for posting +2\[dq]. .IP \[bu] 2 -\f[B]\f[VB]amountN-in/-out\f[B] sets a specific posting\[aq]s amount -from two CSV fields.\f[R] -.PD 0 -.P -.PD -When the amount is provided as two CSV fields - -\[dq]Debit\[dq]/\[dq]Credit\[dq], -\[dq]Deposit\[dq]/\[dq]Withdrawal\[dq], \[dq]Money In\[dq]/\[dq]Money -Out\[dq] or similar - assign those fields to \f[V]amountN-in\f[R] and -\f[V]amountN-out\f[R] respectively (or possibly the other way round, -depending on signs). -This will set the Nth posting\[aq]s amount to whichever of the two CSV -field values is non-zero. -Some notes: -.RS 2 +Don\[aq]t use both \f[V]amount\f[R] and +\f[V]amount-in\f[R]/\f[V]amount-out\f[R] in the same rules file; choose +based on whether the amount is in a single CSV field or spread across +two fields. .IP \[bu] 2 -Don\[aq]t mix \f[V]amountN\f[R] and \f[V]amountN-in\f[R]/\f[V]-out\f[R]. -When you have one CSV amount field, use \f[V]amountN\f[R]. -When you have two CSV amount fields, use -\f[V]amountN-in\f[R]/\f[V]amountN-out\f[R]. +In each record, at most one of the two CSV fields should contain a +non-zero amount; the other field must contain a zero or nothing. .IP \[bu] 2 -\f[V]amountN-in\f[R] and \f[V]amountN-out\f[R] are always used together, -as a pair. -Assign to both of them. +hledger assumes both CSV fields contain unsigned numbers, and it +automatically negates the amount-out values. .IP \[bu] 2 -They do not generate two separate postings; rather, they generate the -Nth posting\[aq]s single amount, from the value found in one or other of -the two CSV fields. -.IP \[bu] 2 -In each record, at least one of the two CSV fields must contain a zero -amount or be empty. -.IP \[bu] 2 -hledger assumes the two CSV fields contain unsigned numbers, and it will -automatically negate the -out amount. -.IP \[bu] 2 -This variant can be convenient, but it doesn\[aq]t handle every -two-amount-field situation; if you need more flexibility, use an -\f[V]if\f[R] rule (see \[dq]Setting amounts\[dq] below). +If the data doesn\[aq]t fit these requirements, you\[aq]ll probably need +an if rule (see below). .RE -.PP -The other two variants are older and considered legacy syntax, but can -still be convenient sometimes: -.IP \[bu] 2 -\f[B]\f[VB]amount\f[B] sets posting 1 and 2\[aq]s amounts from one CSV -field or value.\f[R] -.PD 0 -.P -.PD -Assigning to \f[V]amount\f[R], with no posting number, -.RS 2 -.IP \[bu] 2 -sets posting 1\[aq]s amount (like \f[V]amount1\f[R]) -.IP \[bu] 2 -sets posting 2\[aq]s amount to the same amount but with opposite sign; -and also converts it to cost if it has a cost price -.IP \[bu] 2 -can be overridden by \f[V]amount1\f[R] and/or \f[V]amount2\f[R] -assignments. -(This helps with incremental migration of old rules files to the newer -syntax.) -.RE -.IP \[bu] 2 -\f[B]\f[VB]amount-in/-out\f[B] sets posting 1 and 2\[aq]s amounts from -two CSV fields.\f[R] -.PD 0 -.P -.PD -Assigning \f[V]amount-in\f[R] and \f[V]amount-out\f[R], with no posting -numbers, to two CSV fields reads whichever of the two values is non-zero -as the amount, and then sets the first two posting amounts as above. -.PP -We recommend using only one of these variants within a rules file, -rather than mixing them. -And remember that a \f[V]fields\f[R] list can also do assignments, so eg -naming a CSV field \[dq]amount\[dq] counts as an assignment to -\f[V]amount\f[R]; if you don\[aq]t want that, call it something else, -like \[dq]amount_\[dq]. -.PP -In addition to this section, please see also the tips beginning at -\[dq]Working with CSV > Setting amounts\[dq] below. +.IP "3." 3 +\f[B]\f[VB]amountN\f[B]\f[R] (where N is a number from 1 to 99) sets the +amount of only a single posting: the Nth posting in the transaction. +You\[aq]ll usually need at least two such assignments to make a balanced +transaction. +You can also generate more than two postings, to represent more complex +transactions. +The posting numbers don\[aq]t have to be consecutive; with if rules, +higher posting numbers can be useful to ensure a certain order of +postings. +.IP "4." 3 +\f[B]\f[VB]amountN-in\f[B]\f[R] and \f[B]\f[VB]amountN-out\f[B]\f[R] +work exactly like the above, but should be used when the CSV has two +amount fields. +This is analogous to \f[V]amount-in\f[R] and \f[V]amount-out\f[R], and +those tips also apply here. +.IP "5." 3 +Remember that a \f[V]fields\f[R] list can also do assignments. +So in a fields list if you name a CSV field \[dq]amount\[dq], that +counts as assigning to \f[V]amount\f[R]. +(If you don\[aq]t want that, call it something else in the fields list, +like \[dq]amount_\[dq].) +.IP "6." 3 +The above don\[aq]t handle every situation; if you need more +flexibility, use an \f[V]if\f[R] rule to set amounts conditionally. +See \[dq]Working with CSV > Setting amounts\[dq] below for more on this +and on amount-setting generally. .SS currency field .PP \f[V]currency\f[R] sets a currency symbol, to be prepended to all @@ -4849,8 +4818,8 @@ https://hledger.org/cookbook.html#setups-and-workflows https://plaintextaccounting.org -> data import/conversion .SS Setting amounts .PP -Continuing from amount field above, here are more tips on handling -various amount-setting situations: +Continuing from amount field above, here are more tips for +amount-setting: .IP "1." 3 \f[B]If the amount is in a single CSV field:\f[R] .PD 0 @@ -4882,8 +4851,8 @@ if %Type deposit .fi .RE .IP "2." 3 -\f[B]If the amount is in one of two CSV fields (eg Debit and -Credit):\f[R] +\f[B]If the amount is in two CSV fields (such as Debit and Credit, or In +and Out):\f[R] .PD 0 .P .PD @@ -4893,22 +4862,21 @@ Credit):\f[R] .PD 0 .P .PD -Assign the fields to \f[V]amountN-in\f[R] and \f[V]amountN-out\f[R]. -This sets posting N\[aq]s amount to whichever of these has a non-zero -value. -If it\[aq]s the -out value, the amount will be negated. +Assign one field to \f[V]amountN-in\f[R] and the other to +\f[V]amountN-out\f[R]. +hledger will automatically negate the \[dq]out\[dq] field, and will use +whichever field value is non-zero as posting N\[aq]s amount. .IP "b." 3 \f[B]If either field is signed:\f[R] .PD 0 .P .PD -Use a conditional rule to flip the sign when needed. -Eg below, the -out value already has a minus sign so we undo -hledger\[aq]s automatic negating by negating once more (but only if the -field is non-empty, so that we don\[aq]t leave a minus sign by itself): +You will probably need to override hledger\[aq]s sign for one or the +other field, as in the following example: .IP .nf \f[C] +# Negate the -out value, but only if it is not empty: fields date, description, amount1-in, amount1-out if %amount1-out [1-9] amount1-out -%amount1-out @@ -6945,116 +6913,169 @@ time, from the same or different periodic transaction rules: See also: Budgeting and Forecasting. .SH Cost reporting .PP -This section is about recording the cost of things, in transactions -where one commodity is exchanged for another. -Eg an exchange of currency, or a stock purchase or sale. -First, a quick glossary: -.IP \[bu] 2 -Conversion - an exchange of one currency or commodity for another. -Eg a foreign currency exchange, or a purchase or sale of stock or -cryptocurrency. -.IP \[bu] 2 -Conversion transaction - a transaction involving one or more -conversions. -.IP \[bu] 2 -Conversion rate - the cost per unit of one commodity in the other, ie -the exchange rate. -.IP \[bu] 2 -Cost - how much of one commodity was paid to acquire the other. -And more generally, in hledger docs: the amount exchanged in the -\[dq]secondary\[dq] commodity (usually your base currency), whether in a -purchase or a sale, and whether expressed per unit or in total. -Also, the \[dq]\[at]/\[at]\[at] PRICE\[dq] notation used to represent -this. -.SS -B: Convert to cost +In some transactions - for example a currency conversion, or a purchase +or sale of stock - one commodity is exchanged for another. +In these transactions there is a conversion rate, also called the cost +(when buying) or selling price (when selling). +In hledger docs we just say \[dq]cost\[dq], for convenience; feel free +to mentally translate to \[dq]conversion rate\[dq] or \[dq]selling +price\[dq] if helpful. +.SS Recording costs .PP -As discussed in JOURNAL > Costs, when recording a transaction you can -also record the amount\[aq]s cost in another commodity, by adding -\f[V]\[at] UNITPRICE\f[R] or \f[V]\[at]\[at] TOTALPRICE\f[R]. +We\[aq]ll explore several ways of recording transactions involving +costs. +These are also summarised at hledger Cookbook > Cost notation. .PP -Then you can see a report with amounts converted to cost, by adding the -\f[V]-B/--cost\f[R] flag. -(Mnemonic: \[dq]B\[dq] from \[dq]cost Basis\[dq], as in Ledger). -Eg: +Costs can be recorded explicitly in the journal, using the +\f[V]\[at] UNITCOST\f[R] or \f[V]\[at]\[at] TOTALCOST\f[R] notation +described in Journal > Costs: +.PP +\f[B]Variant 1\f[R] .IP .nf \f[C] 2022-01-01 - assets:dollars $-135 ; 135 dollars is exchanged for.. - assets:euros €100 \[at] $1.35 ; one hundred euros purchased at $1.35 each -\f[R] -.fi -.IP -.nf -\f[C] -$ hledger bal -N - $-135 assets:dollars - €100 assets:euros -$ hledger bal -N -B - $-135 assets:dollars - $135 assets:euros # <- the euros\[aq] cost + assets:dollars $-135 + assets:euros €100 \[at] $1.35 ; $1.35 per euro (unit cost) \f[R] .fi .PP -Notes: -.PP --B is sensitive to the order of postings when a cost is inferred: the -inferred price will be in the commodity of the last amount. -So if example 3\[aq]s postings are reversed, while the transaction is -equivalent, -B shows something different: +\f[B]Variant 2\f[R] .IP .nf \f[C] 2022-01-01 - assets:dollars $-135 ; 135 dollars sold - assets:euros €100 ; for 100 euros -\f[R] -.fi -.IP -.nf -\f[C] -$ hledger bal -N -B - €-100 assets:dollars # <- the dollars\[aq] selling price - €100 assets:euros + assets:dollars $-135 + assets:euros €100 \[at]\[at] $135 ; $135 total cost \f[R] .fi .PP -The \[at]/\[at]\[at] cost notation is convenient, but has some -drawbacks: it does not truly balance the transaction, so it disrupts the -accounting equation and tends to causes a non-zero total in balance -reports. +Typically, writing the unit cost (variant 1) is preferable; it can be +more effort, requiring more attention to decimal digits; but it reveals +the per-unit cost basis, and makes stock sales easier. +.PP +Costs can also be left implicit, and hledger will infer the cost that is +consistent with a balanced transaction: +.PP +\f[B]Variant 3\f[R] +.IP +.nf +\f[C] +2022-01-01 + assets:dollars $-135 + assets:euros €100 +\f[R] +.fi +.PP +Here, hledger will attach a \f[V]\[at]\[at] €100\f[R] cost to the first +amount (you can see it with \f[V]hledger print -x\f[R]). +This form looks convenient, but there are downsides: +.IP \[bu] 2 +It sacrifices some error checking. +For example, if you accidentally wrote €10 instead of €100, hledger +would not be able to detect the mistake. +.IP \[bu] 2 +It is sensitive to the order of postings - if they were reversed, a +different entry would be inferred and reports would be different. +.IP \[bu] 2 +The per-unit cost basis is not easy to read. +.PP +So generally this kind of entry is not recommended. +You can make sure you have none of these by using \f[V]-s\f[R] (strict +mode), or by running \f[V]hledger check balanced\f[R]. +.SS Reporting at cost +.PP +Now when you add the \f[V]-B\f[R]/\f[V]--cost\f[R] flag to reports +(\[dq]B\[dq] is from Ledger\[aq]s -B/--basis/--cost flag), any amounts +which have been annotated with costs will be converted to their +cost\[aq]s commodity (in the report output). +Ie they will be displayed \[dq]at cost\[dq] or \[dq]at sale price\[dq]. +.PP +Some things to note: +.IP \[bu] 2 +Costs are attached to specific posting amounts in specific transactions, +and once recorded they do not change. +This contrasts with market prices, which are ambient and fluctuating. +.IP \[bu] 2 +Conversion to cost is performed before conversion to market value +(described below). .SS Equity conversion postings .PP -By contrast, conventional double entry bookkeeping (DEB) uses a -different notation: an extra pair of equity postings to balance -conversion transactions. -In this style, the above entry might be written: +There is a problem with the entries above - they are not conventional +Double Entry Bookkeeping (DEB) notation, and because of the +\[dq]magical\[dq] transformation of one commodity into another, they +cause an imbalance in the Accounting Equation. +This shows up as a non-zero grand total in balance reports like +\f[V]hledger bse\f[R]. +.PP +For most hledger users, this doesn\[aq]t matter in practice and can +safely be ignored ! +But if you\[aq]d like to learn more, keep reading. +.PP +Conventional DEB uses an extra pair of equity postings to balance the +transaction. +Of course you can do this in hledger as well: +.PP +\f[B]Variant 4\f[R] .IP .nf \f[C] -2022-01-01 one hundred euros purchased at $1.35 each +2022-01-01 assets:dollars $-135 + assets:euros €100 equity:conversion $135 equity:conversion €-100 - assets:euros €100 \f[R] .fi .PP -This style is more correct, but it\[aq]s also more verbose and makes -cost reporting more difficult for PTA tools. +Now the transaction is perfectly balanced according to standard DEB, and +\f[V]hledger bse\f[R]\[aq]s total will not be disrupted. .PP -Happily, current hledger can read either notation, or convert one to the -other when needed, so you can use the one you prefer. +And, hledger can still infer the cost for cost reporting, but it\[aq]s +not done by default - you must add the \f[V]--infer-costs\f[R] flag like +so: +.IP +.nf +\f[C] +$ hledger print --infer-costs +2022-01-01 one hundred euros purchased at $1.35 each + assets:dollars $-135 \[at]\[at] €100 + assets:euros €100 + equity:conversion $135 + equity:conversion €-100 +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger bal --infer-costs -B + €-100 assets:dollars + €100 assets:euros +-------------------- + 0 +\f[R] +.fi .PP -You can even use cost notation and equivalent conversion postings at the -same time, for clarity. -hledger will ignore the redundancy. -But be sure the cost and conversion posting amounts match, or you\[aq]ll -see a not-so-clear transaction balancing error message. -.SS Inferring equity postings from cost +Here are some downsides of this kind of entry: +.IP \[bu] 2 +The per-unit cost basis is not easy to read. +.IP \[bu] 2 +Instead of \f[V]-B\f[R] you must remember to type +\f[V]-B --infer-costs\f[R]. +.IP \[bu] 2 +\f[V]--infer-costs\f[R] works only where hledger can identify the two +equity:conversion postings and match them up with the two non-equity +postings. +So writing the journal entry in a particular format becomes more +important. +More on this below. +.SS Inferring equity conversion postings .PP -With \f[V]--infer-equity\f[R], hledger detects transactions written with -PTA cost notation and adds equity conversion postings to them: +Can we go in the other direction ? +Yes, if you have transactions written with the \[at]/\[at]\[at] cost +notation, hledger can infer the missing equity postings, if you add the +\f[V]--infer-equity\f[R] flag. +Eg: .IP .nf \f[C] @@ -7070,252 +7091,105 @@ $ hledger print --infer-equity 2022-01-01 assets:dollars $-135 assets:euros €100 \[at] $1.35 - equity:conversion:$-€:€ €-100 ; generated-posting: - equity:conversion:$-€:$ $135.00 ; generated-posting: + equity:conversion:$-€:€ €-100 + equity:conversion:$-€:$ $135.00 \f[R] .fi .PP -The conversion account names can be changed with the conversion account -type declaration. +The equity account names will be \[dq]equity:conversion:A-B:A\[dq] and +\[dq]equity:conversion:A-B:B\[dq] where A is the alphabetically first +commodity symbol. +You can customise the \[dq]equity:conversion\[dq] part by declaring an +account with the \f[V]V\f[R]/\f[V]Conversion\f[R] account type. +.SS Combining costs and equity conversion postings .PP ---infer-equity is useful when when transactions have been recorded using -cost notation, to help preserve the accounting equation and balance -reports\[aq] zero total, or to produce more conventional journal entries -for sharing with non-PTA-users. -.SS Inferring cost from equity postings +Finally, you can use both the \[at]/\[at]\[at] cost notation and equity +postings at the same time. +This in theory gives the best of all worlds - preserving the accounting +equation, revealing the per-unit cost basis, and providing more +flexibility in how you write the entry: .PP -The reverse operation is possible using \f[V]--infer-costs\f[R], which -detects transactions written with equity conversion postings and adds -cost notation to them: +\f[B]Variant 5\f[R] .IP .nf \f[C] -2022-01-01 - assets:dollars $-135 - equity:conversion $135 - equity:conversion €-100 - assets:euros €100 +2022-01-01 one hundred euros purchased at $1.35 each + assets:dollars $-135 + equity:conversion $135 + equity:conversion €-100 + assets:euros €100 \[at] $1.35 \f[R] .fi +.PP +All the other variants above can (usually) be rewritten to this final +form with: .IP .nf \f[C] -$ hledger print --infer-costs -2022-01-01 - assets:dollars $-135 \[at]\[at] €100 - equity:conversion $135 - equity:conversion €-100 - assets:euros €100 +$ hledger print -x --infer-costs --infer-equity \f[R] .fi .PP ---infer-costs is useful when combined with -B/--cost, allowing cost -reporting even when transactions have been recorded using equity -postings: +Downsides: +.IP \[bu] 2 +This was added in hledger-1.29 and is still somewhat experimental. +.IP \[bu] 2 +The precise format of the journal entry becomes more important. +If hledger can\[aq]t detect and match up the cost and equity postings, +it will give a transaction balancing error. +.IP \[bu] 2 +The add command does not yet accept this kind of entry (#2056). +.IP \[bu] 2 +This is the most verbose form. +.SS Requirements for detecting equity conversion postings +.PP +\f[V]--infer-costs\f[R] has certain requirements (unlike +\f[V]--infer-equity\f[R], which always works). +It will infer costs only in transactions with: +.IP \[bu] 2 +Two non-equity postings, in different commodities. +Their order is significant: the cost will be added to the first of them. +.IP \[bu] 2 +Two postings to equity conversion accounts, next to one another, which +balance the two non-equity postings. +This balancing is checked to the same precision (number of decimal +places) used in the conversion posting\[aq]s amount. +Equity conversion accounts are: +.RS 2 +.IP \[bu] 2 +any accounts declared with account type +\f[V]V\f[R]/\f[V]Conversion\f[R], or their subaccounts +.IP \[bu] 2 +otherwise, accounts named \f[V]equity:conversion\f[R], +\f[V]equity:trade\f[R], or \f[V]equity:trading\f[R], or their +subaccounts. +.RE +.PP +And multiple such four-posting groups can coexist within a single +transaction. +When \f[V]--infer-costs\f[R] fails, it does not infer a cost in that +transaction, and does not raise an error (ie, it infers costs where it +can). +.PP +Reading variant 5 journal entries, combining cost notation and equity +postings, has all the same requirements. +When reading such an entry fails, hledger raises an \[dq]unbalanced +transaction\[dq] error. +.SS Infer cost and equity by default ? +.PP +Should \f[V]--infer-costs\f[R] and \f[V]--infer-equity\f[R] be enabled +by default ? +Try using them always, eg with a shell alias: .IP .nf \f[C] -$ hledger print --infer-costs -B -2009-01-01 - assets:dollars €-100 - assets:euros €100 +alias h=\[dq]hledger --infer-equity --infer-costs\[dq] \f[R] .fi .PP -Notes: +and let us know what problems you find. .PP -For \f[V]--infer-costs\f[R] to work, an exchange must consist of four -postings: -.IP "1." 3 -two non-equity postings -.IP "2." 3 -two equity postings, next to one another -.IP "3." 3 -the equity accounts must be declared, with account type -\f[V]V\f[R]/\f[V]Conversion\f[R] (or if they are not declared, they must -be named \f[V]equity:conversion\f[R], \f[V]equity:trade\f[R], -\f[V]equity:trading\f[R] or subaccounts of these) -.IP "4." 3 -the equity postings\[aq] amounts must exactly match the non-equity -postings\[aq] amounts. -.PP -Multiple such exchanges can coexist within a single transaction. -.PP -When inferring cost, the order of postings matters: the cost is added to -the first of the non-equity postings involved in the exchange, in the -commodity of the last non-equity posting involved in the exchange. -If you don\[aq]t want to write your postings in the required order, you -can use explicit cost notation instead. -.PP ---infer-equity and --infer-costs can be used together, if you have a -mixture of both notations in your journal. -.SS When to infer cost/equity -.PP -Inferring equity postings or costs is still fairly new, so not enabled -by default. -We\[aq]re not sure yet if that should change. -Here are two suggestions to try, experience reports welcome: -.IP "1." 3 -When you use -B, always use --infer-costs as well. -Eg: \f[V]hledger bal -B --infer-costs\f[R] -.IP "2." 3 -Always run hledger with both flags enabled. -Eg: \f[V]alias hl=\[dq]hledger --infer-equity --infer-costs\[dq]\f[R] -.SS How to record conversions -.PP -Essentially there are four ways to record a conversion transaction in -hledger. -Here are all of them, with pros and cons. -.SS Conversion with implicit cost -.PP -Let\[aq]s assume 100 EUR is converted to 120 USD. -You can just record the outflow (100 EUR) and inflow (120 USD) in the -appropriate asset account: -.IP -.nf -\f[C] -2021-01-01 - assets:cash -100 EUR - assets:cash 120 USD -\f[R] -.fi -.PP -hledger will assume this transaction is balanced, inferring that the -conversion rate must be 1 EUR = 1.20 USD. -You can see the inferred rate by using \f[V]hledger print -x\f[R]. -.PP -Pro: -.IP \[bu] 2 -Concise, easy -.PP -Con: -.IP \[bu] 2 -Less error checking - typos in amounts or commodity symbols may not be -detected -.IP \[bu] 2 -Conversion rate is not clear -.IP \[bu] 2 -Disturbs the accounting equation, unless you add the --infer-equity flag -.PP -You can prevent accidental implicit conversions due to a mistyped -commodity symbol, by using \f[V]hledger check commodities\f[R]. -.PP -You can prevent implicit conversions entirely, by using -\f[V]hledger check balancednoautoconversion\f[R], or -\f[V]-s/--strict\f[R]. -.SS Conversion with explicit cost -.PP -You can add the conversion rate using \[at] notation: -.IP -.nf -\f[C] -2021-01-01 - assets:cash -100 EUR \[at] 1.20 USD - assets:cash 120 USD -\f[R] -.fi -.PP -Now hledger will check that 100 * 1.20 = 120, and would report an error -otherwise. -.PP -Pro: -.IP \[bu] 2 -Still concise -.IP \[bu] 2 -Makes the conversion rate clear -.IP \[bu] 2 -Provides more error checking -.PP -Con: -.IP \[bu] 2 -Disturbs the accounting equation, unless you add the --infer-equity flag -.SS Conversion with equity postings -.PP -In strict double entry bookkeeping, the above transaction is not -balanced in EUR or in USD, since some EUR disappears, and some USD -appears. -This violates the accounting equation (A+L+E=0), and prevents reports -like \f[V]balancesheetequity\f[R] from showing a zero total. -.PP -The proper way to make it balance is to add a balancing posting for each -commodity, using an equity account: -.IP -.nf -\f[C] -2021-01-01 - assets:cash -100 EUR - equity:conversion 100 EUR - equity:conversion -120 USD - assets:cash 120 USD -\f[R] -.fi -.PP -Pro: -.IP \[bu] 2 -Preserves the accounting equation -.IP \[bu] 2 -Keeps track of conversions and related gains/losses in one place -.IP \[bu] 2 -Standard, works in any double entry accounting system -.PP -Con: -.IP \[bu] 2 -More verbose -.IP \[bu] 2 -Conversion rate is not obvious -.IP \[bu] 2 -Cost reporting requires adding the --infer-costs flag -.SS Conversion with equity postings and explicit cost -.PP -Here both equity postings and \[at] notation are used together. -.IP -.nf -\f[C] -2021-01-01 - assets:cash -100 EUR \[at] 1.20 USD - equity:conversion 100 EUR - equity:conversion -120 USD - assets:cash 120 USD -\f[R] -.fi -.PP -Pro: -.IP \[bu] 2 -Preserves the accounting equation -.IP \[bu] 2 -Keeps track of conversions and related gains/losses in one place -.IP \[bu] 2 -Makes the conversion rate clear -.IP \[bu] 2 -Provides more error checking -.PP -Con: -.IP \[bu] 2 -Most verbose -.IP \[bu] 2 -Not compatible with ledger -.SS Cost tips -.IP \[bu] 2 -Recording the cost/conversion rate explicitly is good because it makes -that clear and helps detect errors. -.IP \[bu] 2 -Recording equity postings is good because it is correct bookkeeping and -preserves the accounting equation. -.IP \[bu] 2 -Combining these is possible. -.IP \[bu] 2 -When you want to see the cost (or sale proceeds) of things, use -\f[V]-B\f[R] (short form of \f[V]--cost\f[R]). -.IP \[bu] 2 -If you use conversion postings without cost notation, add -\f[V]--infer-costs\f[R] also. -.IP \[bu] 2 -If you use cost notation without conversion postings, and you want to -see a balanced balance sheet or print correct journal entries, use -\f[V]--infer-equity\f[R]. -.IP \[bu] 2 -Conversion to cost is performed before valuation (described next). -.SH Valuation +.SH Value reporting .PP Instead of reporting amounts in their original commodity, hledger can convert them to cost/sale amount (using the conversion rate recorded in @@ -7394,8 +7268,9 @@ If both occur on the same day, the P directive takes precedence. .PP There is a downside: value reports can sometimes be affected in confusing/undesired ways by your journal entries. -If this happens to you, read all of this Valuation section carefully, -and try adding \f[V]--debug\f[R] or \f[V]--debug=2\f[R] to troubleshoot. +If this happens to you, read all of this Value reporting section +carefully, and try adding \f[V]--debug\f[R] or \f[V]--debug=2\f[R] to +troubleshoot. .PP \f[V]--infer-market-prices\f[R] can infer market prices from: .IP \[bu] 2 @@ -9038,7 +8913,7 @@ are independent options which can both be used at once) .IP \[bu] 2 \f[V]-X COMM/--exchange COMM\f[R] : like --value=end,COMM .PP -See Cost reporting and Valuation for more about these. +See Cost reporting and Value reporting for more about these. .SS Combining balance report types .PP Most combinations of these options should produce reasonable reports, @@ -9501,7 +9376,7 @@ throughout the report period possibly restricted by a period specified in the periodic transaction rule. .RE -.SS Data layout +.SS Balance report layout .PP The \f[V]--layout\f[R] option affects how balance reports show multi-commodity amounts and commodity symbols, which can improve @@ -9698,6 +9573,12 @@ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout= .fi .RE .IP \[bu] 2 +Note: bare layout will sometimes display an extra row for the no-symbol +commodity, because of zero amounts (hledger treats zeroes as +commodity-less, usually). +This can break \f[V]hledger-bar\f[R] confusingly (workaround: add a +\f[V]cur:\f[R] query to exclude the no-symbol row). +.IP \[bu] 2 Tidy layout produces normalised \[dq]tidy data\[dq], where every variable has its own column and each row represents a single data point. See @@ -9984,9 +9865,10 @@ commands, including \f[V]check\f[R]: \f[B]parseable\f[R] - data files are well-formed and can be successfully parsed .IP \[bu] 2 -\f[B]balancedwithautoconversion\f[R] - all transactions are balanced, -inferring missing amounts where necessary, and possibly converting -commodities using costs or automatically-inferred costs +\f[B]autobalanced\f[R] - all transactions are balanced, after converting +to cost. +Missing amounts and missing costs are inferred automatically where +possible. .IP \[bu] 2 \f[B]assertions\f[R] - all balance assertions in the journal are passing. @@ -10004,8 +9886,9 @@ declared .IP \[bu] 2 \f[B]commodities\f[R] - all commodity symbols used have been declared .IP \[bu] 2 -\f[B]balancednoautoconversion\f[R] - transactions are balanced, possibly -using explicit costs but not inferred ones +\f[B]balanced\f[R] - all transactions are balanced after converting to +cost, without inferring missing costs. +If conversion costs are required, they must be explicit. .SS Other checks .PP These checks can be run only by giving their names as arguments to @@ -10019,7 +9902,7 @@ file \f[B]payees\f[R] - all payees used by transactions have been declared .IP \[bu] 2 \f[B]recentassertions\f[R] - all accounts with balance assertions have a -balance assertion no more than 7 days before their latest posting +balance assertion within 7 days of their latest posting .IP \[bu] 2 \f[B]tags\f[R] - all tags used by transactions have been declared .IP \[bu] 2 @@ -10040,17 +9923,17 @@ See: Cookbook -> Scripting. .SS More about specific checks .PP \f[V]hledger check recentassertions\f[R] will complain if any -balance-asserted account does not have a balance assertion within 7 days -before its latest posting. +balance-asserted account has postings more than 7 days after its latest +balance assertion. This aims to prevent the situation where you are regularly updating your journal, but forgetting to check your balances against the real world, then one day must dig back through months of data to find an error. It assumes that adding a balance assertion requires/reminds you to check the real-world balance. -That may not be true if you auto-generate balance assertions from bank -data; in that case, I recommend to import transactions uncleared, then -use the manual-review-and-mark-cleared phase as a reminder to check the -latest assertions against real-world balances. +(That may not be true if you auto-generate balance assertions from bank +data; in that case, I recommend to import transactions uncleared, and +when you manually review and clear them, also check the latest assertion +against the real-world balance.) .SS close .PP (equity) @@ -10541,6 +10424,8 @@ up\[dq] to a certain date. .PP Note deduplication (and updating of state files) can also be done by \f[V]print --new\f[R], but this is less often used. +.PP +Related: CSV > Working with CSV > Deduplicating, importing. .SS Import testing .PP With \f[V]--dry-run\f[R], the transactions that will be imported are @@ -10763,8 +10648,8 @@ $ hledger print assets:cash | hledger -f- -I reg expenses:food There are some situations where print\[aq]s output can become unparseable: .IP \[bu] 2 -Valuation affects posting amounts but not balance assertion or balance -assignment amounts, potentially causing those to fail. +Value reporting affects posting amounts but not balance assertion or +balance assignment amounts, potentially causing those to fail. .IP \[bu] 2 Auto postings can generate postings with too many missing amounts. .IP \[bu] 2 diff --git a/hledger/hledger.info b/hledger/hledger.info index 99e77ce0b..6b8fdc59f 100644 --- a/hledger/hledger.info +++ b/hledger/hledger.info @@ -101,7 +101,7 @@ file" and "Setting opening balances" sections in PART 5: COMMON TASKS. * Forecasting:: * Budgeting:: * Cost reporting:: -* Valuation:: +* Value reporting:: * PART 4 COMMANDS:: * PART 5 COMMON TASKS:: * BUGS:: @@ -765,16 +765,16 @@ File: hledger.info, Node: Output format, Next: Commodity styles, Prev: Output Some commands offer other kinds of output, not just text on the terminal. Here are those commands and the formats currently supported: -- txt csv html json sql ------------------------------------------------------------------------------ -aregister Y Y Y Y -balance Y _1_ Y _1_ Y _1,2_ Y -balancesheet Y _1_ Y _1_ Y _1_ Y -balancesheetequity Y _1_ Y _1_ Y _1_ Y -cashflow Y _1_ Y _1_ Y _1_ Y -incomestatement Y _1_ Y _1_ Y _1_ Y -print Y Y Y Y -register Y Y Y +- txt csv html json sql +------------------------------------------------------------------------------- +aregister Y Y Y Y +balance Y _1_ Y _1_ Y _1,2_ Y +balancesheet Y _1_ Y _1_ Y _1_ Y +balancesheetequityY _1_ Y _1_ Y _1_ Y +cashflow Y _1_ Y _1_ Y _1_ Y +incomestatement Y _1_ Y _1_ Y _1_ Y +print Y Y Y Y +register Y Y Y * _1 Also affected by the balance commands' '--layout' option._ * _2 'balance' does not support html output without a report interval @@ -1699,7 +1699,7 @@ implicitly: assets:dollars $-135 ; for $135 Amounts can be converted to cost at report time using the '-B/--cost' -flag; this is discussed more in the ˜COST REPORTING section. +flag; this is discussed more in the Cost reporting section. Note that the cost normally should be a positive amount, though it's not required to be. This can be a little confusing, see discussion at @@ -2361,8 +2361,8 @@ tag's value should be one of the five main account types: * 'C' or 'Cash' (a subtype of Asset, indicating liquid assets for the cashflow report) - * 'V' or 'Conversion' (a subtype of Equity, for conversions (see COST - REPORTING).) + * 'V' or 'Conversion' (a subtype of Equity, for conversions (see Cost + reporting).) Here is a typical set of account type declarations: @@ -2820,7 +2820,7 @@ P 2009-01-01 € $1.35 P 2010-01-01 € $1.40 The '-V', '-X' and '--value' flags use these market prices to show -amount values in another commodity. See Valuation. +amount values in another commodity. See Value reporting.  File: hledger.info, Node: payee directive, Next: tag directive, Prev: P directive, Up: Journal @@ -3200,9 +3200,10 @@ trustworthy in an audit. * Menu: * Balance assignments and prices:: +* Balance assignments and multiple files::  -File: hledger.info, Node: Balance assignments and prices, Up: Balance assignments +File: hledger.info, Node: Balance assignments and prices, Next: Balance assignments and multiple files, Up: Balance assignments 9.28.1.1 Balance assignments and prices ....................................... @@ -3217,6 +3218,16 @@ $ hledger print --explicit 2019-01-01 (a) $1 @ €2 = $1 @ €2 + +File: hledger.info, Node: Balance assignments and multiple files, Prev: Balance assignments and prices, Up: Balance assignments + +9.28.1.2 Balance assignments and multiple files +............................................... + +Balance assignments handle multiple files like balance assertions. They +see balance from other files previously included from the current file, +but not from previous sibling or parent files. +  File: hledger.info, Node: Bracketed posting dates, Next: D directive, Prev: Balance assignments, Up: Other syntax @@ -3715,7 +3726,7 @@ File: hledger.info, Node: newest-first, Next: intra-day-reversed, Prev: timez =================== hledger tries to ensure that the generated transactions will be ordered -chronologically, including intra-day transactions. Usually it can +chronologically, including same-day transactions. Usually it can auto-detect how the CSV records are ordered. But if it encounters CSV where all records are on the same date, it assumes that the records are oldest first. If in fact the CSV's records are normally newest first, @@ -3737,18 +3748,16 @@ File: hledger.info, Node: intra-day-reversed, Next: decimal-mark, Prev: newes 10.8 'intra-day-reversed' ========================= -CSV records for each day are sometimes ordered in reverse compared to -the overall date order. Eg, here dates are newest first, but the -transactions on each date are oldest first: +If CSV records within a single day are ordered opposite to the overall +record order, you can add the 'intra-day-reversed' rule to improve the +order of journal entries. Eg, here the overall record order is newest +first, but same-day records are oldest first: 2022-10-02, txn 3... 2022-10-02, txn 4... 2022-10-01, txn 1... 2022-10-01, txn 2... - In this situation, add the 'intra-day-reversed' rule, and hledger -will compensate, improving the order of transactions. - # transactions within each day are reversed with respect to the overall date order intra-day-reversed @@ -3977,72 +3986,57 @@ File: hledger.info, Node: amount field, Next: currency field, Prev: account f 10.12.8 amount field -------------------- -Amount setting can get a bit complex. Assigning to 'amount' is -sufficient for simple transactions, but there are four field name -variants you can use for different situations: +There are several ways to set posting amounts from CSV, useful in +different situations. - * *'amountN' sets a specific posting's amount from one CSV field or - arbitrary value.* - Assigning to 'amountN' sets the amount of the Nth posting - and - also causes that posting to be generated. N is most often 1 or 2 - but can go up to 99, potentially generating a 99-posting - transaction. (Posting numbers don't have to be consecutive; higher - posting numbers can sometimes be useful with conditional rules, to - ensure a certain ordering of postings.) + 1. *'amount'* is the oldest and simplest. Assigning to this sets the + amount of the first and second postings. In the second posting, + the amount will be negated; also, if it has a cost attached, it + will be converted to cost. - * *'amountN-in/-out' sets a specific posting's amount from two CSV - fields.* - When the amount is provided as two CSV fields - "Debit"/"Credit", - "Deposit"/"Withdrawal", "Money In"/"Money Out" or similar - assign - those fields to 'amountN-in' and 'amountN-out' respectively (or - possibly the other way round, depending on signs). This will set - the Nth posting's amount to whichever of the two CSV field values - is non-zero. Some notes: + 2. *'amount-in'* and *'amount-out'* work exactly like the above, but + should be used when the CSV has two amount fields (such as "Debit" + and "Credit", or "Inflow" and "Outflow"). Whichever field has a + non-zero value will be used as the amount of the first and second + postings. Here are some tips to avoid confusion: - * Don't mix 'amountN' and 'amountN-in'/'-out'. When you have - one CSV amount field, use 'amountN'. When you have two CSV - amount fields, use 'amountN-in'/'amountN-out'. - * 'amountN-in' and 'amountN-out' are always used together, as a - pair. Assign to both of them. - * They do not generate two separate postings; rather, they - generate the Nth posting's single amount, from the value found - in one or other of the two CSV fields. - * In each record, at least one of the two CSV fields must - contain a zero amount or be empty. - * hledger assumes the two CSV fields contain unsigned numbers, - and it will automatically negate the -out amount. - * This variant can be convenient, but it doesn't handle every - two-amount-field situation; if you need more flexibility, use - an 'if' rule (see "Setting amounts" below). + * It's not "amount-in for posting 1 and amount-out for posting + 2", it is "extract a single amount from the amount-in or + amount-out field, and use that for posting 1 and (negated) for + posting 2". + * Don't use both 'amount' and 'amount-in'/'amount-out' in the + same rules file; choose based on whether the amount is in a + single CSV field or spread across two fields. + * In each record, at most one of the two CSV fields should + contain a non-zero amount; the other field must contain a zero + or nothing. + * hledger assumes both CSV fields contain unsigned numbers, and + it automatically negates the amount-out values. + * If the data doesn't fit these requirements, you'll probably + need an if rule (see below). - The other two variants are older and considered legacy syntax, but -can still be convenient sometimes: + 3. *'amountN'* (where N is a number from 1 to 99) sets the amount of + only a single posting: the Nth posting in the transaction. You'll + usually need at least two such assignments to make a balanced + transaction. You can also generate more than two postings, to + represent more complex transactions. The posting numbers don't + have to be consecutive; with if rules, higher posting numbers can + be useful to ensure a certain order of postings. - * *'amount' sets posting 1 and 2's amounts from one CSV field or - value.* - Assigning to 'amount', with no posting number, + 4. *'amountN-in'* and *'amountN-out'* work exactly like the above, but + should be used when the CSV has two amount fields. This is + analogous to 'amount-in' and 'amount-out', and those tips also + apply here. - * sets posting 1's amount (like 'amount1') - * sets posting 2's amount to the same amount but with opposite - sign; and also converts it to cost if it has a cost price - * can be overridden by 'amount1' and/or 'amount2' assignments. - (This helps with incremental migration of old rules files to - the newer syntax.) + 5. Remember that a 'fields' list can also do assignments. So in a + fields list if you name a CSV field "amount", that counts as + assigning to 'amount'. (If you don't want that, call it something + else in the fields list, like "amount_".) - * *'amount-in/-out' sets posting 1 and 2's amounts from two CSV - fields.* - Assigning 'amount-in' and 'amount-out', with no posting numbers, to - two CSV fields reads whichever of the two values is non-zero as the - amount, and then sets the first two posting amounts as above. - - We recommend using only one of these variants within a rules file, -rather than mixing them. And remember that a 'fields' list can also do -assignments, so eg naming a CSV field "amount" counts as an assignment -to 'amount'; if you don't want that, call it something else, like -"amount_". - - In addition to this section, please see also the tips beginning at -"Working with CSV > Setting amounts" below. + 6. The above don't handle every situation; if you need more + flexibility, use an 'if' rule to set amounts conditionally. See + "Working with CSV > Setting amounts" below for more on this and on + amount-setting generally.  File: hledger.info, Node: currency field, Next: balance field, Prev: amount field, Up: Field names @@ -4459,8 +4453,8 @@ File: hledger.info, Node: Setting amounts, Next: Amount signs, Prev: Deduplic 10.18.9 Setting amounts ----------------------- -Continuing from amount field above, here are more tips on handling -various amount-setting situations: +Continuing from amount field above, here are more tips for +amount-setting: 1. *If the amount is in a single CSV field:* @@ -4477,20 +4471,20 @@ various amount-setting situations: if %Type deposit amount1 %Amount - 2. *If the amount is in one of two CSV fields (eg Debit and Credit):* + 2. *If the amount is in two CSV fields (such as Debit and Credit, or + In and Out):* a. *If both fields are unsigned:* - Assign the fields to 'amountN-in' and 'amountN-out'. This - sets posting N's amount to whichever of these has a non-zero - value. If it's the -out value, the amount will be negated. + Assign one field to 'amountN-in' and the other to + 'amountN-out'. hledger will automatically negate the "out" + field, and will use whichever field value is non-zero as + posting N's amount. b. *If either field is signed:* - Use a conditional rule to flip the sign when needed. Eg - below, the -out value already has a minus sign so we undo - hledger's automatic negating by negating once more (but only - if the field is non-empty, so that we don't leave a minus sign - by itself): + You will probably need to override hledger's sign for one or + the other field, as in the following example: + # Negate the -out value, but only if it is not empty: fields date, description, amount1-in, amount1-out if %amount1-out [1-9] amount1-out -%amount1-out @@ -6100,121 +6094,167 @@ bal -M --budget --forecast ...' See also: Budgeting and Forecasting.  -File: hledger.info, Node: Cost reporting, Next: Valuation, Prev: Budgeting, Up: Top +File: hledger.info, Node: Cost reporting, Next: Value reporting, Prev: Budgeting, Up: Top 21 Cost reporting ***************** -This section is about recording the cost of things, in transactions -where one commodity is exchanged for another. Eg an exchange of -currency, or a stock purchase or sale. First, a quick glossary: - - * Conversion - an exchange of one currency or commodity for another. - Eg a foreign currency exchange, or a purchase or sale of stock or - cryptocurrency. - - * Conversion transaction - a transaction involving one or more - conversions. - - * Conversion rate - the cost per unit of one commodity in the other, - ie the exchange rate. - - * Cost - how much of one commodity was paid to acquire the other. - And more generally, in hledger docs: the amount exchanged in the - "secondary" commodity (usually your base currency), whether in a - purchase or a sale, and whether expressed per unit or in total. - Also, the "@/@@ PRICE" notation used to represent this. +In some transactions - for example a currency conversion, or a purchase +or sale of stock - one commodity is exchanged for another. In these +transactions there is a conversion rate, also called the cost (when +buying) or selling price (when selling). In hledger docs we just say +"cost", for convenience; feel free to mentally translate to "conversion +rate" or "selling price" if helpful. * Menu: -* -B Convert to cost:: +* Recording costs:: +* Reporting at cost:: * Equity conversion postings:: -* Inferring equity postings from cost:: -* Inferring cost from equity postings:: -* When to infer cost/equity:: -* How to record conversions:: -* Cost tips:: +* Inferring equity conversion postings:: +* Combining costs and equity conversion postings:: +* Requirements for detecting equity conversion postings:: +* Infer cost and equity by default ?::  -File: hledger.info, Node: -B Convert to cost, Next: Equity conversion postings, Up: Cost reporting +File: hledger.info, Node: Recording costs, Next: Reporting at cost, Up: Cost reporting -21.1 -B: Convert to cost -======================== +21.1 Recording costs +==================== -As discussed in JOURNAL > Costs, when recording a transaction you can -also record the amount's cost in another commodity, by adding '@ -UNITPRICE' or '@@ TOTALPRICE'. +We'll explore several ways of recording transactions involving costs. +These are also summarised at hledger Cookbook > Cost notation. - Then you can see a report with amounts converted to cost, by adding -the '-B/--cost' flag. (Mnemonic: "B" from "cost Basis", as in Ledger). -Eg: + Costs can be recorded explicitly in the journal, using the '@ +UNITCOST' or '@@ TOTALCOST' notation described in Journal > Costs: + + *Variant 1* 2022-01-01 - assets:dollars $-135 ; 135 dollars is exchanged for.. - assets:euros €100 @ $1.35 ; one hundred euros purchased at $1.35 each + assets:dollars $-135 + assets:euros €100 @ $1.35 ; $1.35 per euro (unit cost) -$ hledger bal -N - $-135 assets:dollars - €100 assets:euros -$ hledger bal -N -B - $-135 assets:dollars - $135 assets:euros # <- the euros' cost - - Notes: - - -B is sensitive to the order of postings when a cost is inferred: the -inferred price will be in the commodity of the last amount. So if -example 3's postings are reversed, while the transaction is equivalent, --B shows something different: + *Variant 2* 2022-01-01 - assets:dollars $-135 ; 135 dollars sold - assets:euros €100 ; for 100 euros + assets:dollars $-135 + assets:euros €100 @@ $135 ; $135 total cost -$ hledger bal -N -B - €-100 assets:dollars # <- the dollars' selling price - €100 assets:euros + Typically, writing the unit cost (variant 1) is preferable; it can be +more effort, requiring more attention to decimal digits; but it reveals +the per-unit cost basis, and makes stock sales easier. - The @/@@ cost notation is convenient, but has some drawbacks: it does -not truly balance the transaction, so it disrupts the accounting -equation and tends to causes a non-zero total in balance reports. + Costs can also be left implicit, and hledger will infer the cost that +is consistent with a balanced transaction: + + *Variant 3* + +2022-01-01 + assets:dollars $-135 + assets:euros €100 + + Here, hledger will attach a '@@ €100' cost to the first amount (you +can see it with 'hledger print -x'). This form looks convenient, but +there are downsides: + + * It sacrifices some error checking. For example, if you + accidentally wrote €10 instead of €100, hledger would not be able + to detect the mistake. + + * It is sensitive to the order of postings - if they were reversed, a + different entry would be inferred and reports would be different. + + * The per-unit cost basis is not easy to read. + + So generally this kind of entry is not recommended. You can make +sure you have none of these by using '-s' (strict mode), or by running +'hledger check balanced'.  -File: hledger.info, Node: Equity conversion postings, Next: Inferring equity postings from cost, Prev: -B Convert to cost, Up: Cost reporting +File: hledger.info, Node: Reporting at cost, Next: Equity conversion postings, Prev: Recording costs, Up: Cost reporting -21.2 Equity conversion postings +21.2 Reporting at cost +====================== + +Now when you add the '-B'/'--cost' flag to reports ("B" is from Ledger's +-B/-basis/-cost flag), any amounts which have been annotated with costs +will be converted to their cost's commodity (in the report output). Ie +they will be displayed "at cost" or "at sale price". + + Some things to note: + + * Costs are attached to specific posting amounts in specific + transactions, and once recorded they do not change. This contrasts + with market prices, which are ambient and fluctuating. + + * Conversion to cost is performed before conversion to market value + (described below). + + +File: hledger.info, Node: Equity conversion postings, Next: Inferring equity conversion postings, Prev: Reporting at cost, Up: Cost reporting + +21.3 Equity conversion postings =============================== -By contrast, conventional double entry bookkeeping (DEB) uses a -different notation: an extra pair of equity postings to balance -conversion transactions. In this style, the above entry might be -written: +There is a problem with the entries above - they are not conventional +Double Entry Bookkeeping (DEB) notation, and because of the "magical" +transformation of one commodity into another, they cause an imbalance in +the Accounting Equation. This shows up as a non-zero grand total in +balance reports like 'hledger bse'. -2022-01-01 one hundred euros purchased at $1.35 each + For most hledger users, this doesn't matter in practice and can +safely be ignored ! But if you'd like to learn more, keep reading. + + Conventional DEB uses an extra pair of equity postings to balance the +transaction. Of course you can do this in hledger as well: + + *Variant 4* + +2022-01-01 assets:dollars $-135 + assets:euros €100 equity:conversion $135 equity:conversion €-100 - assets:euros €100 - This style is more correct, but it's also more verbose and makes cost -reporting more difficult for PTA tools. + Now the transaction is perfectly balanced according to standard DEB, +and 'hledger bse''s total will not be disrupted. - Happily, current hledger can read either notation, or convert one to -the other when needed, so you can use the one you prefer. + And, hledger can still infer the cost for cost reporting, but it's +not done by default - you must add the '--infer-costs' flag like so: - You can even use cost notation and equivalent conversion postings at -the same time, for clarity. hledger will ignore the redundancy. But be -sure the cost and conversion posting amounts match, or you'll see a -not-so-clear transaction balancing error message. +$ hledger print --infer-costs +2022-01-01 one hundred euros purchased at $1.35 each + assets:dollars $-135 @@ €100 + assets:euros €100 + equity:conversion $135 + equity:conversion €-100 + +$ hledger bal --infer-costs -B + €-100 assets:dollars + €100 assets:euros +-------------------- + 0 + + Here are some downsides of this kind of entry: + + * The per-unit cost basis is not easy to read. + + * Instead of '-B' you must remember to type '-B --infer-costs'. + + * '--infer-costs' works only where hledger can identify the two + equity:conversion postings and match them up with the two + non-equity postings. So writing the journal entry in a particular + format becomes more important. More on this below.  -File: hledger.info, Node: Inferring equity postings from cost, Next: Inferring cost from equity postings, Prev: Equity conversion postings, Up: Cost reporting +File: hledger.info, Node: Inferring equity conversion postings, Next: Combining costs and equity conversion postings, Prev: Equity conversion postings, Up: Cost reporting -21.3 Inferring equity postings from cost -======================================== +21.4 Inferring equity conversion postings +========================================= -With '--infer-equity', hledger detects transactions written with PTA -cost notation and adds equity conversion postings to them: +Can we go in the other direction ? Yes, if you have transactions +written with the @/@@ cost notation, hledger can infer the missing +equity postings, if you add the '--infer-equity' flag. Eg: 2022-01-01 assets:dollars -$135 @@ -6224,250 +6264,99 @@ $ hledger print --infer-equity 2022-01-01 assets:dollars $-135 assets:euros €100 @ $1.35 - equity:conversion:$-€:€ €-100 ; generated-posting: - equity:conversion:$-€:$ $135.00 ; generated-posting: + equity:conversion:$-€:€ €-100 + equity:conversion:$-€:$ $135.00 - The conversion account names can be changed with the conversion -account type declaration. - - -infer-equity is useful when when transactions have been recorded -using cost notation, to help preserve the accounting equation and -balance reports' zero total, or to produce more conventional journal -entries for sharing with non-PTA-users. + The equity account names will be "equity:conversion:A-B:A" and +"equity:conversion:A-B:B" where A is the alphabetically first commodity +symbol. You can customise the "equity:conversion" part by declaring an +account with the 'V'/'Conversion' account type.  -File: hledger.info, Node: Inferring cost from equity postings, Next: When to infer cost/equity, Prev: Inferring equity postings from cost, Up: Cost reporting +File: hledger.info, Node: Combining costs and equity conversion postings, Next: Requirements for detecting equity conversion postings, Prev: Inferring equity conversion postings, Up: Cost reporting -21.4 Inferring cost from equity postings -======================================== +21.5 Combining costs and equity conversion postings +=================================================== -The reverse operation is possible using '--infer-costs', which detects -transactions written with equity conversion postings and adds cost -notation to them: +Finally, you can use both the @/@@ cost notation and equity postings at +the same time. This in theory gives the best of all worlds - preserving +the accounting equation, revealing the per-unit cost basis, and +providing more flexibility in how you write the entry: -2022-01-01 - assets:dollars $-135 - equity:conversion $135 - equity:conversion €-100 - assets:euros €100 + *Variant 5* -$ hledger print --infer-costs -2022-01-01 - assets:dollars $-135 @@ €100 - equity:conversion $135 - equity:conversion €-100 - assets:euros €100 +2022-01-01 one hundred euros purchased at $1.35 each + assets:dollars $-135 + equity:conversion $135 + equity:conversion €-100 + assets:euros €100 @ $1.35 - -infer-costs is useful when combined with -B/-cost, allowing cost -reporting even when transactions have been recorded using equity -postings: + All the other variants above can (usually) be rewritten to this final +form with: -$ hledger print --infer-costs -B -2009-01-01 - assets:dollars €-100 - assets:euros €100 +$ hledger print -x --infer-costs --infer-equity - Notes: + Downsides: - For '--infer-costs' to work, an exchange must consist of four -postings: + * This was added in hledger-1.29 and is still somewhat experimental. - 1. two non-equity postings - 2. two equity postings, next to one another - 3. the equity accounts must be declared, with account type - 'V'/'Conversion' (or if they are not declared, they must be named - 'equity:conversion', 'equity:trade', 'equity:trading' or - subaccounts of these) - 4. the equity postings' amounts must exactly match the non-equity - postings' amounts. + * The precise format of the journal entry becomes more important. If + hledger can't detect and match up the cost and equity postings, it + will give a transaction balancing error. - Multiple such exchanges can coexist within a single transaction. + * The add command does not yet accept this kind of entry (#2056). - When inferring cost, the order of postings matters: the cost is added -to the first of the non-equity postings involved in the exchange, in the -commodity of the last non-equity posting involved in the exchange. If -you don't want to write your postings in the required order, you can use -explicit cost notation instead. - - -infer-equity and -infer-costs can be used together, if you have a -mixture of both notations in your journal. + * This is the most verbose form.  -File: hledger.info, Node: When to infer cost/equity, Next: How to record conversions, Prev: Inferring cost from equity postings, Up: Cost reporting +File: hledger.info, Node: Requirements for detecting equity conversion postings, Next: Infer cost and equity by default ?, Prev: Combining costs and equity conversion postings, Up: Cost reporting -21.5 When to infer cost/equity -============================== +21.6 Requirements for detecting equity conversion postings +========================================================== -Inferring equity postings or costs is still fairly new, so not enabled -by default. We're not sure yet if that should change. Here are two -suggestions to try, experience reports welcome: +'--infer-costs' has certain requirements (unlike '--infer-equity', which +always works). It will infer costs only in transactions with: - 1. When you use -B, always use -infer-costs as well. Eg: 'hledger bal - -B --infer-costs' + * Two non-equity postings, in different commodities. Their order is + significant: the cost will be added to the first of them. - 2. Always run hledger with both flags enabled. Eg: 'alias hl="hledger - --infer-equity --infer-costs"' + * Two postings to equity conversion accounts, next to one another, + which balance the two non-equity postings. This balancing is + checked to the same precision (number of decimal places) used in + the conversion posting's amount. Equity conversion accounts are: + + * any accounts declared with account type 'V'/'Conversion', or + their subaccounts + * otherwise, accounts named 'equity:conversion', 'equity:trade', + or 'equity:trading', or their subaccounts. + + And multiple such four-posting groups can coexist within a single +transaction. When '--infer-costs' fails, it does not infer a cost in +that transaction, and does not raise an error (ie, it infers costs where +it can). + + Reading variant 5 journal entries, combining cost notation and equity +postings, has all the same requirements. When reading such an entry +fails, hledger raises an "unbalanced transaction" error.  -File: hledger.info, Node: How to record conversions, Next: Cost tips, Prev: When to infer cost/equity, Up: Cost reporting +File: hledger.info, Node: Infer cost and equity by default ?, Prev: Requirements for detecting equity conversion postings, Up: Cost reporting -21.6 How to record conversions -============================== +21.7 Infer cost and equity by default ? +======================================= -Essentially there are four ways to record a conversion transaction in -hledger. Here are all of them, with pros and cons. +Should '--infer-costs' and '--infer-equity' be enabled by default ? Try +using them always, eg with a shell alias: -* Menu: +alias h="hledger --infer-equity --infer-costs" -* Conversion with implicit cost:: -* Conversion with explicit cost:: -* Conversion with equity postings:: -* Conversion with equity postings and explicit cost:: + and let us know what problems you find.  -File: hledger.info, Node: Conversion with implicit cost, Next: Conversion with explicit cost, Up: How to record conversions +File: hledger.info, Node: Value reporting, Next: PART 4 COMMANDS, Prev: Cost reporting, Up: Top -21.6.1 Conversion with implicit cost ------------------------------------- - -Let's assume 100 EUR is converted to 120 USD. You can just record the -outflow (100 EUR) and inflow (120 USD) in the appropriate asset account: - -2021-01-01 - assets:cash -100 EUR - assets:cash 120 USD - - hledger will assume this transaction is balanced, inferring that the -conversion rate must be 1 EUR = 1.20 USD. You can see the inferred rate -by using 'hledger print -x'. - - Pro: - - * Concise, easy - - Con: - - * Less error checking - typos in amounts or commodity symbols may not - be detected - * Conversion rate is not clear - * Disturbs the accounting equation, unless you add the -infer-equity - flag - - You can prevent accidental implicit conversions due to a mistyped -commodity symbol, by using 'hledger check commodities'. - - You can prevent implicit conversions entirely, by using 'hledger -check balancednoautoconversion', or '-s/--strict'. - - -File: hledger.info, Node: Conversion with explicit cost, Next: Conversion with equity postings, Prev: Conversion with implicit cost, Up: How to record conversions - -21.6.2 Conversion with explicit cost ------------------------------------- - -You can add the conversion rate using @ notation: - -2021-01-01 - assets:cash -100 EUR @ 1.20 USD - assets:cash 120 USD - - Now hledger will check that 100 * 1.20 = 120, and would report an -error otherwise. - - Pro: - - * Still concise - * Makes the conversion rate clear - * Provides more error checking - - Con: - - * Disturbs the accounting equation, unless you add the -infer-equity - flag - - -File: hledger.info, Node: Conversion with equity postings, Next: Conversion with equity postings and explicit cost, Prev: Conversion with explicit cost, Up: How to record conversions - -21.6.3 Conversion with equity postings --------------------------------------- - -In strict double entry bookkeeping, the above transaction is not -balanced in EUR or in USD, since some EUR disappears, and some USD -appears. This violates the accounting equation (A+L+E=0), and prevents -reports like 'balancesheetequity' from showing a zero total. - - The proper way to make it balance is to add a balancing posting for -each commodity, using an equity account: - -2021-01-01 - assets:cash -100 EUR - equity:conversion 100 EUR - equity:conversion -120 USD - assets:cash 120 USD - - Pro: - - * Preserves the accounting equation - * Keeps track of conversions and related gains/losses in one place - * Standard, works in any double entry accounting system - - Con: - - * More verbose - * Conversion rate is not obvious - * Cost reporting requires adding the -infer-costs flag - - -File: hledger.info, Node: Conversion with equity postings and explicit cost, Prev: Conversion with equity postings, Up: How to record conversions - -21.6.4 Conversion with equity postings and explicit cost --------------------------------------------------------- - -Here both equity postings and @ notation are used together. - -2021-01-01 - assets:cash -100 EUR @ 1.20 USD - equity:conversion 100 EUR - equity:conversion -120 USD - assets:cash 120 USD - - Pro: - - * Preserves the accounting equation - * Keeps track of conversions and related gains/losses in one place - * Makes the conversion rate clear - * Provides more error checking - - Con: - - * Most verbose - * Not compatible with ledger - - -File: hledger.info, Node: Cost tips, Prev: How to record conversions, Up: Cost reporting - -21.7 Cost tips -============== - - * Recording the cost/conversion rate explicitly is good because it - makes that clear and helps detect errors. - * Recording equity postings is good because it is correct bookkeeping - and preserves the accounting equation. - * Combining these is possible. - * When you want to see the cost (or sale proceeds) of things, use - '-B' (short form of '--cost'). - * If you use conversion postings without cost notation, add - '--infer-costs' also. - * If you use cost notation without conversion postings, and you want - to see a balanced balance sheet or print correct journal entries, - use '--infer-equity'. - * Conversion to cost is performed before valuation (described next). - - -File: hledger.info, Node: Valuation, Next: PART 4 COMMANDS, Prev: Cost reporting, Up: Top - -22 Valuation -************ +22 Value reporting +****************** Instead of reporting amounts in their original commodity, hledger can convert them to cost/sale amount (using the conversion rate recorded in @@ -6491,7 +6380,7 @@ and '-X COMMODITY' options, and often one of these is all you need: * Effect of valuation on reports::  -File: hledger.info, Node: -V Value, Next: -X Value in specified commodity, Up: Valuation +File: hledger.info, Node: -V Value, Next: -X Value in specified commodity, Up: Value reporting 22.1 -V: Value ============== @@ -6501,7 +6390,7 @@ _valuation commodity_, using the market prices in effect on the _valuation date(s)_, if any. More on these in a minute.  -File: hledger.info, Node: -X Value in specified commodity, Next: Valuation date, Prev: -V Value, Up: Valuation +File: hledger.info, Node: -X Value in specified commodity, Next: Valuation date, Prev: -V Value, Up: Value reporting 22.2 -X: Value in specified commodity ===================================== @@ -6511,7 +6400,7 @@ currency you want to convert to, and it tries to convert everything to that.  -File: hledger.info, Node: Valuation date, Next: Finding market price, Prev: -X Value in specified commodity, Up: Valuation +File: hledger.info, Node: Valuation date, Next: Finding market price, Prev: -X Value in specified commodity, Up: Value reporting 22.3 Valuation date =================== @@ -6528,7 +6417,7 @@ valuation date is the journal's end date. of the period, by default.  -File: hledger.info, Node: Finding market price, Next: --infer-market-prices market prices from transactions, Prev: Valuation date, Up: Valuation +File: hledger.info, Node: Finding market price, Next: --infer-market-prices market prices from transactions, Prev: Valuation date, Up: Value reporting 22.4 Finding market price ========================= @@ -6562,7 +6451,7 @@ possibilities, it will give up (with a "gave up" message visible in converted.  -File: hledger.info, Node: --infer-market-prices market prices from transactions, Next: Valuation commodity, Prev: Finding market price, Up: Valuation +File: hledger.info, Node: --infer-market-prices market prices from transactions, Next: Valuation commodity, Prev: Finding market price, Up: Value reporting 22.5 -infer-market-prices: market prices from transactions ========================================================== @@ -6580,7 +6469,7 @@ the same day, the P directive takes precedence. There is a downside: value reports can sometimes be affected in confusing/undesired ways by your journal entries. If this happens to -you, read all of this Valuation section carefully, and try adding +you, read all of this Value reporting section carefully, and try adding '--debug' or '--debug=2' to troubleshoot. '--infer-market-prices' can infer market prices from: @@ -6648,7 +6537,7 @@ P 2022-01-03 B A -1 P 2022-01-03 B A -1.0  -File: hledger.info, Node: Valuation commodity, Next: Simple valuation examples, Prev: --infer-market-prices market prices from transactions, Up: Valuation +File: hledger.info, Node: Valuation commodity, Next: Simple valuation examples, Prev: --infer-market-prices market prices from transactions, Up: Value reporting 22.6 Valuation commodity ======================== @@ -6687,7 +6576,7 @@ follows, in this order of preference: converted.  -File: hledger.info, Node: Simple valuation examples, Next: --value Flexible valuation, Prev: Valuation commodity, Up: Valuation +File: hledger.info, Node: Simple valuation examples, Next: --value Flexible valuation, Prev: Valuation commodity, Up: Value reporting 22.7 Simple valuation examples ============================== @@ -6722,7 +6611,7 @@ $ hledger -f t.j bal -N euros -V $103.00 assets:euros  -File: hledger.info, Node: --value Flexible valuation, Next: More valuation examples, Prev: Simple valuation examples, Up: Valuation +File: hledger.info, Node: --value Flexible valuation, Next: More valuation examples, Prev: Simple valuation examples, Up: Value reporting 22.8 -value: Flexible valuation =============================== @@ -6764,7 +6653,7 @@ part: a comma, then the target commodity's symbol. Eg: this commodity, deducing market prices as described above.  -File: hledger.info, Node: More valuation examples, Next: Interaction of valuation and queries, Prev: --value Flexible valuation, Up: Valuation +File: hledger.info, Node: More valuation examples, Next: Interaction of valuation and queries, Prev: --value Flexible valuation, Up: Value reporting 22.9 More valuation examples ============================ @@ -6878,7 +6767,7 @@ $ hledger print -X A b -0.50A  -File: hledger.info, Node: Interaction of valuation and queries, Next: Effect of valuation on reports, Prev: More valuation examples, Up: Valuation +File: hledger.info, Node: Interaction of valuation and queries, Next: Effect of valuation on reports, Prev: More valuation examples, Up: Value reporting 22.10 Interaction of valuation and queries ========================================== @@ -6899,7 +6788,7 @@ the following happens. See: 1625  -File: hledger.info, Node: Effect of valuation on reports, Prev: Interaction of valuation and queries, Up: Valuation +File: hledger.info, Node: Effect of valuation on reports, Prev: Interaction of valuation and queries, Up: Value reporting 22.11 Effect of valuation on reports ==================================== @@ -7048,7 +6937,7 @@ _report interval_ subperiods).  -File: hledger.info, Node: PART 4 COMMANDS, Next: PART 5 COMMON TASKS, Prev: Valuation, Up: Top +File: hledger.info, Node: PART 4 COMMANDS, Next: PART 5 COMMON TASKS, Prev: Value reporting, Up: Top 23 PART 4: COMMANDS ******************* @@ -7482,7 +7371,7 @@ more control, then use 'balance'. * Balance change end balance:: * Balance report types:: * Budget report:: -* Data layout:: +* Balance report layout:: * Useful balance reports::  @@ -8002,7 +7891,7 @@ displaying the report. It is one of: * '-V/--market' : like -value=end * '-X COMM/--exchange COMM' : like -value=end,COMM - See Cost reporting and Valuation for more about these. + See Cost reporting and Value reporting for more about these.  File: hledger.info, Node: Combining balance report types, Prev: Valuation type, Up: Balance report types @@ -8044,7 +7933,7 @@ Accumulation:v YYYY-MM-DD end  -File: hledger.info, Node: Budget report, Next: Data layout, Prev: Balance report types, Up: balance +File: hledger.info, Node: Budget report, Next: Balance report layout, Prev: Balance report types, Up: balance 23.6.14 Budget report --------------------- @@ -8385,10 +8274,10 @@ time if you want. Here are some differences between them, as of hledger transaction rule.  -File: hledger.info, Node: Data layout, Next: Useful balance reports, Prev: Budget report, Up: balance +File: hledger.info, Node: Balance report layout, Next: Useful balance reports, Prev: Budget report, Up: balance -23.6.15 Data layout -------------------- +23.6.15 Balance report layout +----------------------------- The '--layout' option affects how balance reports show multi-commodity amounts and commodity symbols, which can improve readability. It can @@ -8494,6 +8383,12 @@ tidy Y "total","VEA","36.00" "total","VHT","294.00" + * Note: bare layout will sometimes display an extra row for the + no-symbol commodity, because of zero amounts (hledger treats zeroes + as commodity-less, usually). This can break 'hledger-bar' + confusingly (workaround: add a 'cur:' query to exclude the + no-symbol row). + * Tidy layout produces normalised "tidy data", where every variable has its own column and each row represents a single data point. See @@ -8520,7 +8415,7 @@ tidy Y "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"  -File: hledger.info, Node: Useful balance reports, Prev: Data layout, Up: balance +File: hledger.info, Node: Useful balance reports, Prev: Balance report layout, Up: balance 23.6.16 Useful balance reports ------------------------------ @@ -8760,9 +8655,9 @@ commands, including 'check': * *parseable* - data files are well-formed and can be successfully parsed - * *balancedwithautoconversion* - all transactions are balanced, - inferring missing amounts where necessary, and possibly converting - commodities using costs or automatically-inferred costs + * *autobalanced* - all transactions are balanced, after converting to + cost. Missing amounts and missing costs are inferred automatically + where possible. * *assertions* - all balance assertions in the journal are passing. (This check can be disabled with '-I'/'--ignore-assertions'.) @@ -8782,8 +8677,9 @@ flag is used. Or, they can be run by giving their names as arguments to * *commodities* - all commodity symbols used have been declared - * *balancednoautoconversion* - transactions are balanced, possibly - using explicit costs but not inferred ones + * *balanced* - all transactions are balanced after converting to + cost, without inferring missing costs. If conversion costs are + required, they must be explicit.  File: hledger.info, Node: Other checks, Next: Custom checks, Prev: Strict checks, Up: check @@ -8800,7 +8696,7 @@ therefore optional: * *payees* - all payees used by transactions have been declared * *recentassertions* - all accounts with balance assertions have a - balance assertion no more than 7 days before their latest posting + balance assertion within 7 days of their latest posting * *tags* - all tags used by transactions have been declared @@ -8831,16 +8727,16 @@ File: hledger.info, Node: More about specific checks, Prev: Custom checks, Up ---------------------------------- 'hledger check recentassertions' will complain if any balance-asserted -account does not have a balance assertion within 7 days before its -latest posting. This aims to prevent the situation where you are -regularly updating your journal, but forgetting to check your balances -against the real world, then one day must dig back through months of -data to find an error. It assumes that adding a balance assertion -requires/reminds you to check the real-world balance. That may not be -true if you auto-generate balance assertions from bank data; in that -case, I recommend to import transactions uncleared, then use the -manual-review-and-mark-cleared phase as a reminder to check the latest -assertions against real-world balances. +account has postings more than 7 days after its latest balance +assertion. This aims to prevent the situation where you are regularly +updating your journal, but forgetting to check your balances against the +real world, then one day must dig back through months of data to find an +error. It assumes that adding a balance assertion requires/reminds you +to check the real-world balance. (That may not be true if you +auto-generate balance assertions from bank data; in that case, I +recommend to import transactions uncleared, and when you manually review +and clear them, also check the latest assertion against the real-world +balance.)  File: hledger.info, Node: close, Next: codes, Prev: check, Up: PART 4 COMMANDS @@ -9310,6 +9206,8 @@ certain date. Note deduplication (and updating of state files) can also be done by 'print --new', but this is less often used. + Related: CSV > Working with CSV > Deduplicating, importing. +  File: hledger.info, Node: Import testing, Next: Importing balance assignments, Prev: Deduplication, Up: import @@ -9528,8 +9426,8 @@ $ hledger print assets:cash | hledger -f- -I reg expenses:food There are some situations where print's output can become unparseable: - * Valuation affects posting amounts but not balance assertion or - balance assignment amounts, potentially causing those to fail. + * Value reporting affects posting amounts but not balance assertion + or balance assignment amounts, potentially causing those to fail. * Auto postings can generate postings with too many missing amounts. * Account aliases can generate bad account names. @@ -10720,640 +10618,634 @@ See hledger and Ledger for full details.  Tag Table: Node: Top210 -Node: PART 1 USER INTERFACE3782 -Ref: #part-1-user-interface3921 -Node: Input3921 -Ref: #input4031 -Node: Data formats4980 -Ref: #data-formats5093 -Node: Standard input6526 -Ref: #standard-input6666 -Node: Multiple files6893 -Ref: #multiple-files7032 -Node: Strict mode7630 -Ref: #strict-mode7740 -Node: Commands8464 -Ref: #commands8566 -Node: Add-on commands9633 -Ref: #add-on-commands9735 -Node: Options10851 -Ref: #options10963 -Node: General help options11291 -Ref: #general-help-options11437 -Node: General input options11719 -Ref: #general-input-options11901 -Node: General reporting options12603 -Ref: #general-reporting-options12764 -Node: Command line tips16154 -Ref: #command-line-tips16284 -Node: Option repetition16543 -Ref: #option-repetition16687 -Node: Special characters16791 -Ref: #special-characters16964 -Node: Single escaping shell metacharacters17127 -Ref: #single-escaping-shell-metacharacters17368 -Node: Double escaping regular expression metacharacters17971 -Ref: #double-escaping-regular-expression-metacharacters18282 -Node: Triple escaping for add-on commands18808 -Ref: #triple-escaping-for-add-on-commands19068 -Node: Less escaping19712 -Ref: #less-escaping19866 -Node: Unicode characters20190 -Ref: #unicode-characters20365 -Node: Regular expressions21777 -Ref: #regular-expressions21950 -Node: Argument files23694 -Ref: #argument-files23830 -Node: Output24327 -Ref: #output24439 -Node: Output destination24566 -Ref: #output-destination24697 -Node: Output format25122 -Ref: #output-format25268 -Node: CSV output26806 -Ref: #csv-output26922 -Node: HTML output27025 -Ref: #html-output27163 -Node: JSON output27257 -Ref: #json-output27395 -Node: SQL output28317 -Ref: #sql-output28433 -Node: Commodity styles29168 -Ref: #commodity-styles29308 -Node: Colour29907 -Ref: #colour30025 -Node: Box-drawing30429 -Ref: #box-drawing30547 -Node: Paging30837 -Ref: #paging30951 -Node: Debug output31904 -Ref: #debug-output32010 -Node: Environment32673 -Ref: #environment32797 -Node: PART 2 DATA FORMATS33341 -Ref: #part-2-data-formats33484 -Node: Journal33484 -Ref: #journal33593 -Node: Journal cheatsheet34250 -Ref: #journal-cheatsheet34389 -Node: About journal format38374 -Ref: #about-journal-format38534 -Node: Comments40150 -Ref: #comments40280 -Node: Transactions41096 -Ref: #transactions41219 -Node: Dates42233 -Ref: #dates42340 -Node: Simple dates42385 -Ref: #simple-dates42501 -Node: Posting dates43001 -Ref: #posting-dates43119 -Node: Status44088 -Ref: #status44189 -Node: Code45897 -Ref: #code46000 -Node: Description46232 -Ref: #description46363 -Node: Payee and note46683 -Ref: #payee-and-note46789 -Node: Transaction comments47124 -Ref: #transaction-comments47277 -Node: Postings47640 -Ref: #postings47773 -Node: Account names48768 -Ref: #account-names48898 -Node: Amounts50572 -Ref: #amounts50687 -Node: Decimal marks digit group marks51672 -Ref: #decimal-marks-digit-group-marks51847 -Node: Commodity52861 -Ref: #commodity53048 -Node: Directives influencing number parsing and display54000 -Ref: #directives-influencing-number-parsing-and-display54259 -Node: Commodity display style54711 -Ref: #commodity-display-style54917 -Node: Rounding57086 -Ref: #rounding57204 -Node: Costs57503 -Ref: #costs57619 -Node: Other cost/lot notations59817 -Ref: #other-costlot-notations59949 -Node: Balance assertions62538 -Ref: #balance-assertions62689 -Node: Assertions and ordering63772 -Ref: #assertions-and-ordering63961 -Node: Assertions and multiple included files64661 -Ref: #assertions-and-multiple-included-files64921 -Node: Assertions and multiple -f files65421 -Ref: #assertions-and-multiple--f-files65672 -Node: Assertions and commodities66069 -Ref: #assertions-and-commodities66291 -Node: Assertions and prices67471 -Ref: #assertions-and-prices67677 -Node: Assertions and subaccounts68104 -Ref: #assertions-and-subaccounts68325 -Node: Assertions and virtual postings68649 -Ref: #assertions-and-virtual-postings68887 -Node: Assertions and auto postings69019 -Ref: #assertions-and-auto-postings69249 -Node: Assertions and precision69894 -Ref: #assertions-and-precision70076 -Node: Posting comments70343 -Ref: #posting-comments70489 -Node: Tags70866 -Ref: #tags70980 -Node: Tag values72173 -Ref: #tag-values72262 -Node: Directives73021 -Ref: #directives73148 -Node: Directives and multiple files74478 -Ref: #directives-and-multiple-files74656 -Node: Directive effects75423 -Ref: #directive-effects75577 -Node: account directive78590 -Ref: #account-directive78746 -Node: Account comments80144 -Ref: #account-comments80294 -Node: Account subdirectives80802 -Ref: #account-subdirectives80993 -Node: Account error checking81135 -Ref: #account-error-checking81333 -Node: Account display order82522 -Ref: #account-display-order82710 -Node: Account types83811 -Ref: #account-types83952 -Node: alias directive87579 -Ref: #alias-directive87740 -Node: Basic aliases88790 -Ref: #basic-aliases88921 -Node: Regex aliases89665 -Ref: #regex-aliases89822 -Node: Combining aliases90712 -Ref: #combining-aliases90890 -Node: Aliases and multiple files92166 -Ref: #aliases-and-multiple-files92370 -Node: end aliases directive92949 -Ref: #end-aliases-directive93168 -Node: Aliases can generate bad account names93317 -Ref: #aliases-can-generate-bad-account-names93565 -Node: Aliases and account types94150 -Ref: #aliases-and-account-types94342 -Node: commodity directive95038 -Ref: #commodity-directive95212 -Node: Commodity error checking97786 -Ref: #commodity-error-checking97932 -Node: decimal-mark directive98447 -Ref: #decimal-mark-directive98629 -Node: include directive99026 -Ref: #include-directive99190 -Node: P directive100114 -Ref: #p-directive100259 -Node: payee directive101142 -Ref: #payee-directive101291 -Node: tag directive101607 -Ref: #tag-directive101762 -Node: Periodic transactions102230 -Ref: #periodic-transactions102395 -Node: Periodic rule syntax104101 -Ref: #periodic-rule-syntax104279 -Node: Periodic rules and relative dates104924 -Ref: #periodic-rules-and-relative-dates105190 -Node: Two spaces between period expression and description!105701 -Ref: #two-spaces-between-period-expression-and-description105978 -Node: Auto postings106662 -Ref: #auto-postings106810 -Node: Auto postings and multiple files109247 -Ref: #auto-postings-and-multiple-files109411 -Node: Auto postings and dates109812 -Ref: #auto-postings-and-dates110060 -Node: Auto postings and transaction balancing / inferred amounts / balance assertions110235 -Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions110591 -Node: Auto posting tags111094 -Ref: #auto-posting-tags111376 -Node: Auto postings on forecast transactions only112012 -Ref: #auto-postings-on-forecast-transactions-only112258 -Node: Other syntax112505 -Ref: #other-syntax112621 -Node: Balance assignments113248 -Ref: #balance-assignments113404 -Node: Balance assignments and prices114734 -Ref: #balance-assignments-and-prices114902 -Node: Bracketed posting dates115113 -Ref: #bracketed-posting-dates115297 -Node: D directive115811 -Ref: #d-directive115979 -Node: apply account directive117579 -Ref: #apply-account-directive117759 -Node: Y directive118446 -Ref: #y-directive118606 -Node: Secondary dates119434 -Ref: #secondary-dates119588 -Node: Star comments120402 -Ref: #star-comments120562 -Node: Valuation expressions121094 -Ref: #valuation-expressions121271 -Node: Virtual postings121393 -Ref: #virtual-postings121570 -Node: Other Ledger directives123007 -Ref: #other-ledger-directives123170 -Node: CSV123736 -Ref: #csv123829 -Node: CSV rules cheatsheet125909 -Ref: #csv-rules-cheatsheet126038 -Node: source127836 -Ref: #source127959 -Node: separator128839 -Ref: #separator128952 -Node: skip129492 -Ref: #skip129600 -Node: date-format130144 -Ref: #date-format130265 -Node: timezone130989 -Ref: #timezone131112 -Node: newest-first132117 -Ref: #newest-first132255 -Node: intra-day-reversed132833 -Ref: #intra-day-reversed132987 -Node: decimal-mark133480 -Ref: #decimal-mark133621 -Node: fields list133960 -Ref: #fields-list134099 -Node: Field assignment135770 -Ref: #field-assignment135914 -Node: Field names136941 -Ref: #field-names137072 -Node: date field138275 -Ref: #date-field138393 -Node: date2 field138441 -Ref: #date2-field138582 -Node: status field138638 -Ref: #status-field138781 -Node: code field138830 -Ref: #code-field138975 -Node: description field139020 -Ref: #description-field139180 -Node: comment field139239 -Ref: #comment-field139394 -Node: account field139687 -Ref: #account-field139837 -Node: amount field140407 -Ref: #amount-field140556 -Node: currency field143932 -Ref: #currency-field144085 -Node: balance field144342 -Ref: #balance-field144474 -Node: if block144846 -Ref: #if-block144967 -Node: Matchers146375 -Ref: #matchers146489 -Node: if table147971 -Ref: #if-table148093 -Node: balance-type149515 -Ref: #balance-type149644 -Node: include150344 -Ref: #include150471 -Node: Working with CSV150915 -Ref: #working-with-csv151062 -Node: Rapid feedback151469 -Ref: #rapid-feedback151602 -Node: Valid CSV152054 -Ref: #valid-csv152200 -Node: File Extension152932 -Ref: #file-extension153105 -Node: Reading CSV from standard input153669 -Ref: #reading-csv-from-standard-input153893 -Node: Reading multiple CSV files154057 -Ref: #reading-multiple-csv-files154288 -Node: Reading files specified by rule154529 -Ref: #reading-files-specified-by-rule154757 -Node: Valid transactions155928 -Ref: #valid-transactions156127 -Node: Deduplicating importing156755 -Ref: #deduplicating-importing156950 -Node: Setting amounts157986 -Ref: #setting-amounts158157 -Node: Amount signs160622 -Ref: #amount-signs160792 -Node: Setting currency/commodity161689 -Ref: #setting-currencycommodity161893 -Node: Amount decimal places163067 -Ref: #amount-decimal-places163273 -Node: Referencing other fields163585 -Ref: #referencing-other-fields163798 -Node: How CSV rules are evaluated164695 -Ref: #how-csv-rules-are-evaluated164912 -Node: Well factored rules166365 -Ref: #well-factored-rules166533 -Node: CSV rules examples166857 -Ref: #csv-rules-examples166992 -Node: Bank of Ireland167057 -Ref: #bank-of-ireland167194 -Node: Coinbase168656 -Ref: #coinbase168794 -Node: Amazon169841 -Ref: #amazon169966 -Node: Paypal171685 -Ref: #paypal171793 -Node: Timeclock179437 -Ref: #timeclock179542 -Node: Timedot181720 -Ref: #timedot181843 -Node: PART 3 REPORTING CONCEPTS186712 -Ref: #part-3-reporting-concepts186876 -Node: Time periods186876 -Ref: #time-periods187010 -Node: Report start & end date187128 -Ref: #report-start-end-date187280 -Node: Smart dates188939 -Ref: #smart-dates189092 -Node: Report intervals190960 -Ref: #report-intervals191115 -Node: Date adjustment191533 -Ref: #date-adjustment191693 -Node: Period expressions192544 -Ref: #period-expressions192685 -Node: Period expressions with a report interval194449 -Ref: #period-expressions-with-a-report-interval194683 -Node: More complex report intervals194897 -Ref: #more-complex-report-intervals195142 -Node: Multiple weekday intervals196943 -Ref: #multiple-weekday-intervals197132 -Node: Depth197954 -Ref: #depth198056 -Node: Queries198352 -Ref: #queries198454 -Node: Query types199579 -Ref: #query-types199700 -Node: Combining query terms203036 -Ref: #combining-query-terms203213 -Node: Queries and command options204481 -Ref: #queries-and-command-options204680 -Node: Queries and valuation204929 -Ref: #queries-and-valuation205124 -Node: Querying with account aliases205353 -Ref: #querying-with-account-aliases205564 -Node: Querying with cost or value205694 -Ref: #querying-with-cost-or-value205871 -Node: Pivoting206172 -Ref: #pivoting206286 -Node: Generating data208063 -Ref: #generating-data208195 -Node: Forecasting209778 -Ref: #forecasting209903 -Node: --forecast210434 -Ref: #forecast210565 -Node: Inspecting forecast transactions211611 -Ref: #inspecting-forecast-transactions211813 -Node: Forecast reports212943 -Ref: #forecast-reports213116 -Node: Forecast tags214052 -Ref: #forecast-tags214212 -Node: Forecast period in detail214672 -Ref: #forecast-period-in-detail214866 -Node: Forecast troubleshooting215760 -Ref: #forecast-troubleshooting215928 -Node: Budgeting216831 -Ref: #budgeting216951 -Node: Cost reporting217388 -Ref: #cost-reporting217516 -Node: -B Convert to cost218623 -Ref: #b-convert-to-cost218779 -Node: Equity conversion postings220171 -Ref: #equity-conversion-postings220385 -Node: Inferring equity postings from cost221276 -Ref: #inferring-equity-postings-from-cost221525 -Node: Inferring cost from equity postings222336 -Ref: #inferring-cost-from-equity-postings222584 -Node: When to infer cost/equity224351 -Ref: #when-to-infer-costequity224569 -Node: How to record conversions224965 -Ref: #how-to-record-conversions225157 -Node: Conversion with implicit cost225448 -Ref: #conversion-with-implicit-cost225653 -Node: Conversion with explicit cost226530 -Ref: #conversion-with-explicit-cost226775 -Node: Conversion with equity postings227192 -Ref: #conversion-with-equity-postings227461 -Node: Conversion with equity postings and explicit cost228280 -Ref: #conversion-with-equity-postings-and-explicit-cost228547 -Node: Cost tips229009 -Ref: #cost-tips229135 -Node: Valuation229841 -Ref: #valuation229965 -Node: -V Value230739 -Ref: #v-value230865 -Node: -X Value in specified commodity231060 -Ref: #x-value-in-specified-commodity231255 -Node: Valuation date231404 -Ref: #valuation-date231575 -Node: Finding market price232012 -Ref: #finding-market-price232217 -Node: --infer-market-prices market prices from transactions233387 -Ref: #infer-market-prices-market-prices-from-transactions233663 -Node: Valuation commodity236419 -Ref: #valuation-commodity236632 -Node: Simple valuation examples237845 -Ref: #simple-valuation-examples238043 -Node: --value Flexible valuation238702 -Ref: #value-flexible-valuation238906 -Node: More valuation examples240550 -Ref: #more-valuation-examples240759 -Node: Interaction of valuation and queries242758 -Ref: #interaction-of-valuation-and-queries242999 -Node: Effect of valuation on reports243471 -Ref: #effect-of-valuation-on-reports243668 -Node: PART 4 COMMANDS251365 -Ref: #part-4-commands251508 -Node: Commands overview251887 -Ref: #commands-overview252021 -Node: DATA ENTRY252200 -Ref: #data-entry252324 -Node: DATA CREATION252523 -Ref: #data-creation252677 -Node: DATA MANAGEMENT252795 -Ref: #data-management252960 -Node: REPORTS FINANCIAL253081 -Ref: #reports-financial253256 -Node: REPORTS VERSATILE253561 -Ref: #reports-versatile253734 -Node: REPORTS BASIC253987 -Ref: #reports-basic254139 -Node: HELP254648 -Ref: #help254770 -Node: ADD-ONS254880 -Ref: #add-ons254986 -Node: accounts255565 -Ref: #accounts255698 -Node: activity257585 -Ref: #activity257704 -Node: add258078 -Ref: #add258188 -Node: aregister260999 -Ref: #aregister261120 -Node: aregister and custom posting dates264008 -Ref: #aregister-and-custom-posting-dates264174 -Node: balance264726 -Ref: #balance264852 -Node: balance features265827 -Ref: #balance-features265967 -Node: Simple balance report267926 -Ref: #simple-balance-report268111 -Node: Balance report line format269736 -Ref: #balance-report-line-format269938 -Node: Filtered balance report272096 -Ref: #filtered-balance-report272288 -Node: List or tree mode272615 -Ref: #list-or-tree-mode272783 -Node: Depth limiting274128 -Ref: #depth-limiting274294 -Node: Dropping top-level accounts274895 -Ref: #dropping-top-level-accounts275095 -Node: Showing declared accounts275405 -Ref: #showing-declared-accounts275604 -Node: Sorting by amount276135 -Ref: #sorting-by-amount276302 -Node: Percentages276972 -Ref: #percentages277131 -Node: Multi-period balance report277679 -Ref: #multi-period-balance-report277879 -Node: Balance change end balance280154 -Ref: #balance-change-end-balance280363 -Node: Balance report types281791 -Ref: #balance-report-types281972 -Node: Calculation type282470 -Ref: #calculation-type282625 -Node: Accumulation type283174 -Ref: #accumulation-type283354 -Node: Valuation type284256 -Ref: #valuation-type284444 -Node: Combining balance report types285439 -Ref: #combining-balance-report-types285633 -Node: Budget report287471 -Ref: #budget-report287623 -Node: Budget report start date293277 -Ref: #budget-report-start-date293455 -Node: Budgets and subaccounts294787 -Ref: #budgets-and-subaccounts294994 -Node: Selecting budget goals298434 -Ref: #selecting-budget-goals298633 -Node: Budget vs forecast299668 -Ref: #budget-vs-forecast299827 -Node: Data layout301457 -Ref: #data-layout301607 -Node: Useful balance reports309502 -Ref: #useful-balance-reports309652 -Node: balancesheet310737 -Ref: #balancesheet310882 -Node: balancesheetequity312202 -Ref: #balancesheetequity312360 -Node: cashflow313749 -Ref: #cashflow313880 -Node: check315308 -Ref: #check315422 -Node: Basic checks316224 -Ref: #basic-checks316344 -Node: Strict checks316864 -Ref: #strict-checks317007 -Node: Other checks317430 -Ref: #other-checks317572 -Node: Custom checks318135 -Ref: #custom-checks318292 -Node: More about specific checks318709 -Ref: #more-about-specific-checks318871 -Node: close319599 -Ref: #close319710 -Node: close and balance assertions323175 -Ref: #close-and-balance-assertions323353 -Node: Example retain earnings324504 -Ref: #example-retain-earnings324721 -Node: Example migrate balances to a new file325153 -Ref: #example-migrate-balances-to-a-new-file325418 -Node: Example excluding closing/opening transactions325994 -Ref: #example-excluding-closingopening-transactions326243 -Node: codes327461 -Ref: #codes327578 -Node: commodities328442 -Ref: #commodities328570 -Node: demo328640 -Ref: #demo328761 -Node: descriptions329677 -Ref: #descriptions329807 -Node: diff330098 -Ref: #diff330213 -Node: files331255 -Ref: #files331364 -Node: help331505 -Ref: #help-1331614 -Node: import332987 -Ref: #import333110 -Node: Deduplication334196 -Ref: #deduplication334321 -Node: Import testing336215 -Ref: #import-testing336380 -Node: Importing balance assignments337223 -Ref: #importing-balance-assignments337429 -Node: Commodity display styles338078 -Ref: #commodity-display-styles338251 -Node: incomestatement338380 -Ref: #incomestatement338522 -Node: notes339843 -Ref: #notes339965 -Node: payees340327 -Ref: #payees340442 -Node: prices340961 -Ref: #prices341076 -Node: print341374 -Ref: #print341489 -Node: register346827 -Ref: #register346949 -Node: Custom register output351980 -Ref: #custom-register-output352111 -Node: rewrite353448 -Ref: #rewrite353566 -Node: Re-write rules in a file355464 -Ref: #re-write-rules-in-a-file355627 -Node: Diff output format356776 -Ref: #diff-output-format356959 -Node: rewrite vs print --auto358051 -Ref: #rewrite-vs.-print---auto358211 -Node: roi358767 -Ref: #roi358874 -Node: Spaces and special characters in --inv and --pnl360595 -Ref: #spaces-and-special-characters-in---inv-and---pnl360835 -Node: Semantics of --inv and --pnl361323 -Ref: #semantics-of---inv-and---pnl361562 -Node: IRR and TWR explained363412 -Ref: #irr-and-twr-explained363572 -Node: stats366658 -Ref: #stats366766 -Node: tags368153 -Ref: #tags-1368260 -Node: test369269 -Ref: #test369362 -Node: PART 5 COMMON TASKS370104 -Ref: #part-5-common-tasks370250 -Node: Getting help370548 -Ref: #getting-help370689 -Node: Constructing command lines371449 -Ref: #constructing-command-lines371650 -Node: Starting a journal file372307 -Ref: #starting-a-journal-file372509 -Node: Setting LEDGER_FILE373711 -Ref: #setting-ledger_file373903 -Node: Setting opening balances374860 -Ref: #setting-opening-balances375061 -Node: Recording transactions378202 -Ref: #recording-transactions378391 -Node: Reconciling378947 -Ref: #reconciling379099 -Node: Reporting381356 -Ref: #reporting381505 -Node: Migrating to a new file385490 -Ref: #migrating-to-a-new-file385647 -Node: BUGS385946 -Ref: #bugs386036 -Node: Troubleshooting386915 -Ref: #troubleshooting387015 +Node: PART 1 USER INTERFACE3788 +Ref: #part-1-user-interface3927 +Node: Input3927 +Ref: #input4037 +Node: Data formats4986 +Ref: #data-formats5099 +Node: Standard input6532 +Ref: #standard-input6672 +Node: Multiple files6899 +Ref: #multiple-files7038 +Node: Strict mode7636 +Ref: #strict-mode7746 +Node: Commands8470 +Ref: #commands8572 +Node: Add-on commands9639 +Ref: #add-on-commands9741 +Node: Options10857 +Ref: #options10969 +Node: General help options11297 +Ref: #general-help-options11443 +Node: General input options11725 +Ref: #general-input-options11907 +Node: General reporting options12609 +Ref: #general-reporting-options12770 +Node: Command line tips16160 +Ref: #command-line-tips16290 +Node: Option repetition16549 +Ref: #option-repetition16693 +Node: Special characters16797 +Ref: #special-characters16970 +Node: Single escaping shell metacharacters17133 +Ref: #single-escaping-shell-metacharacters17374 +Node: Double escaping regular expression metacharacters17977 +Ref: #double-escaping-regular-expression-metacharacters18288 +Node: Triple escaping for add-on commands18814 +Ref: #triple-escaping-for-add-on-commands19074 +Node: Less escaping19718 +Ref: #less-escaping19872 +Node: Unicode characters20196 +Ref: #unicode-characters20371 +Node: Regular expressions21783 +Ref: #regular-expressions21956 +Node: Argument files23700 +Ref: #argument-files23836 +Node: Output24333 +Ref: #output24445 +Node: Output destination24572 +Ref: #output-destination24703 +Node: Output format25128 +Ref: #output-format25274 +Node: CSV output26871 +Ref: #csv-output26987 +Node: HTML output27090 +Ref: #html-output27228 +Node: JSON output27322 +Ref: #json-output27460 +Node: SQL output28382 +Ref: #sql-output28498 +Node: Commodity styles29233 +Ref: #commodity-styles29373 +Node: Colour29972 +Ref: #colour30090 +Node: Box-drawing30494 +Ref: #box-drawing30612 +Node: Paging30902 +Ref: #paging31016 +Node: Debug output31969 +Ref: #debug-output32075 +Node: Environment32738 +Ref: #environment32862 +Node: PART 2 DATA FORMATS33406 +Ref: #part-2-data-formats33549 +Node: Journal33549 +Ref: #journal33658 +Node: Journal cheatsheet34315 +Ref: #journal-cheatsheet34454 +Node: About journal format38439 +Ref: #about-journal-format38599 +Node: Comments40215 +Ref: #comments40345 +Node: Transactions41161 +Ref: #transactions41284 +Node: Dates42298 +Ref: #dates42405 +Node: Simple dates42450 +Ref: #simple-dates42566 +Node: Posting dates43066 +Ref: #posting-dates43184 +Node: Status44153 +Ref: #status44254 +Node: Code45962 +Ref: #code46065 +Node: Description46297 +Ref: #description46428 +Node: Payee and note46748 +Ref: #payee-and-note46854 +Node: Transaction comments47189 +Ref: #transaction-comments47342 +Node: Postings47705 +Ref: #postings47838 +Node: Account names48833 +Ref: #account-names48963 +Node: Amounts50637 +Ref: #amounts50752 +Node: Decimal marks digit group marks51737 +Ref: #decimal-marks-digit-group-marks51912 +Node: Commodity52926 +Ref: #commodity53113 +Node: Directives influencing number parsing and display54065 +Ref: #directives-influencing-number-parsing-and-display54324 +Node: Commodity display style54776 +Ref: #commodity-display-style54982 +Node: Rounding57151 +Ref: #rounding57269 +Node: Costs57568 +Ref: #costs57684 +Node: Other cost/lot notations59880 +Ref: #other-costlot-notations60012 +Node: Balance assertions62601 +Ref: #balance-assertions62752 +Node: Assertions and ordering63835 +Ref: #assertions-and-ordering64024 +Node: Assertions and multiple included files64724 +Ref: #assertions-and-multiple-included-files64984 +Node: Assertions and multiple -f files65484 +Ref: #assertions-and-multiple--f-files65735 +Node: Assertions and commodities66132 +Ref: #assertions-and-commodities66354 +Node: Assertions and prices67534 +Ref: #assertions-and-prices67740 +Node: Assertions and subaccounts68167 +Ref: #assertions-and-subaccounts68388 +Node: Assertions and virtual postings68712 +Ref: #assertions-and-virtual-postings68950 +Node: Assertions and auto postings69082 +Ref: #assertions-and-auto-postings69312 +Node: Assertions and precision69957 +Ref: #assertions-and-precision70139 +Node: Posting comments70406 +Ref: #posting-comments70552 +Node: Tags70929 +Ref: #tags71043 +Node: Tag values72236 +Ref: #tag-values72325 +Node: Directives73084 +Ref: #directives73211 +Node: Directives and multiple files74541 +Ref: #directives-and-multiple-files74719 +Node: Directive effects75486 +Ref: #directive-effects75640 +Node: account directive78653 +Ref: #account-directive78809 +Node: Account comments80207 +Ref: #account-comments80357 +Node: Account subdirectives80865 +Ref: #account-subdirectives81056 +Node: Account error checking81198 +Ref: #account-error-checking81396 +Node: Account display order82585 +Ref: #account-display-order82773 +Node: Account types83874 +Ref: #account-types84015 +Node: alias directive87642 +Ref: #alias-directive87803 +Node: Basic aliases88853 +Ref: #basic-aliases88984 +Node: Regex aliases89728 +Ref: #regex-aliases89885 +Node: Combining aliases90775 +Ref: #combining-aliases90953 +Node: Aliases and multiple files92229 +Ref: #aliases-and-multiple-files92433 +Node: end aliases directive93012 +Ref: #end-aliases-directive93231 +Node: Aliases can generate bad account names93380 +Ref: #aliases-can-generate-bad-account-names93628 +Node: Aliases and account types94213 +Ref: #aliases-and-account-types94405 +Node: commodity directive95101 +Ref: #commodity-directive95275 +Node: Commodity error checking97849 +Ref: #commodity-error-checking97995 +Node: decimal-mark directive98510 +Ref: #decimal-mark-directive98692 +Node: include directive99089 +Ref: #include-directive99253 +Node: P directive100177 +Ref: #p-directive100322 +Node: payee directive101211 +Ref: #payee-directive101360 +Node: tag directive101676 +Ref: #tag-directive101831 +Node: Periodic transactions102299 +Ref: #periodic-transactions102464 +Node: Periodic rule syntax104170 +Ref: #periodic-rule-syntax104348 +Node: Periodic rules and relative dates104993 +Ref: #periodic-rules-and-relative-dates105259 +Node: Two spaces between period expression and description!105770 +Ref: #two-spaces-between-period-expression-and-description106047 +Node: Auto postings106731 +Ref: #auto-postings106879 +Node: Auto postings and multiple files109316 +Ref: #auto-postings-and-multiple-files109480 +Node: Auto postings and dates109881 +Ref: #auto-postings-and-dates110129 +Node: Auto postings and transaction balancing / inferred amounts / balance assertions110304 +Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions110660 +Node: Auto posting tags111163 +Ref: #auto-posting-tags111445 +Node: Auto postings on forecast transactions only112081 +Ref: #auto-postings-on-forecast-transactions-only112327 +Node: Other syntax112574 +Ref: #other-syntax112690 +Node: Balance assignments113317 +Ref: #balance-assignments113473 +Node: Balance assignments and prices114846 +Ref: #balance-assignments-and-prices115061 +Node: Balance assignments and multiple files115272 +Ref: #balance-assignments-and-multiple-files115503 +Node: Bracketed posting dates115696 +Ref: #bracketed-posting-dates115880 +Node: D directive116394 +Ref: #d-directive116562 +Node: apply account directive118162 +Ref: #apply-account-directive118342 +Node: Y directive119029 +Ref: #y-directive119189 +Node: Secondary dates120017 +Ref: #secondary-dates120171 +Node: Star comments120985 +Ref: #star-comments121145 +Node: Valuation expressions121677 +Ref: #valuation-expressions121854 +Node: Virtual postings121976 +Ref: #virtual-postings122153 +Node: Other Ledger directives123590 +Ref: #other-ledger-directives123753 +Node: CSV124319 +Ref: #csv124412 +Node: CSV rules cheatsheet126492 +Ref: #csv-rules-cheatsheet126621 +Node: source128419 +Ref: #source128542 +Node: separator129422 +Ref: #separator129535 +Node: skip130075 +Ref: #skip130183 +Node: date-format130727 +Ref: #date-format130848 +Node: timezone131572 +Ref: #timezone131695 +Node: newest-first132700 +Ref: #newest-first132838 +Node: intra-day-reversed133415 +Ref: #intra-day-reversed133569 +Node: decimal-mark134017 +Ref: #decimal-mark134158 +Node: fields list134497 +Ref: #fields-list134636 +Node: Field assignment136307 +Ref: #field-assignment136451 +Node: Field names137478 +Ref: #field-names137609 +Node: date field138812 +Ref: #date-field138930 +Node: date2 field138978 +Ref: #date2-field139119 +Node: status field139175 +Ref: #status-field139318 +Node: code field139367 +Ref: #code-field139512 +Node: description field139557 +Ref: #description-field139717 +Node: comment field139776 +Ref: #comment-field139931 +Node: account field140224 +Ref: #account-field140374 +Node: amount field140944 +Ref: #amount-field141093 +Node: currency field143785 +Ref: #currency-field143938 +Node: balance field144195 +Ref: #balance-field144327 +Node: if block144699 +Ref: #if-block144820 +Node: Matchers146228 +Ref: #matchers146342 +Node: if table147824 +Ref: #if-table147946 +Node: balance-type149368 +Ref: #balance-type149497 +Node: include150197 +Ref: #include150324 +Node: Working with CSV150768 +Ref: #working-with-csv150915 +Node: Rapid feedback151322 +Ref: #rapid-feedback151455 +Node: Valid CSV151907 +Ref: #valid-csv152053 +Node: File Extension152785 +Ref: #file-extension152958 +Node: Reading CSV from standard input153522 +Ref: #reading-csv-from-standard-input153746 +Node: Reading multiple CSV files153910 +Ref: #reading-multiple-csv-files154141 +Node: Reading files specified by rule154382 +Ref: #reading-files-specified-by-rule154610 +Node: Valid transactions155781 +Ref: #valid-transactions155980 +Node: Deduplicating importing156608 +Ref: #deduplicating-importing156803 +Node: Setting amounts157839 +Ref: #setting-amounts158010 +Node: Amount signs160368 +Ref: #amount-signs160538 +Node: Setting currency/commodity161435 +Ref: #setting-currencycommodity161639 +Node: Amount decimal places162813 +Ref: #amount-decimal-places163019 +Node: Referencing other fields163331 +Ref: #referencing-other-fields163544 +Node: How CSV rules are evaluated164441 +Ref: #how-csv-rules-are-evaluated164658 +Node: Well factored rules166111 +Ref: #well-factored-rules166279 +Node: CSV rules examples166603 +Ref: #csv-rules-examples166738 +Node: Bank of Ireland166803 +Ref: #bank-of-ireland166940 +Node: Coinbase168402 +Ref: #coinbase168540 +Node: Amazon169587 +Ref: #amazon169712 +Node: Paypal171431 +Ref: #paypal171539 +Node: Timeclock179183 +Ref: #timeclock179288 +Node: Timedot181466 +Ref: #timedot181589 +Node: PART 3 REPORTING CONCEPTS186458 +Ref: #part-3-reporting-concepts186622 +Node: Time periods186622 +Ref: #time-periods186756 +Node: Report start & end date186874 +Ref: #report-start-end-date187026 +Node: Smart dates188685 +Ref: #smart-dates188838 +Node: Report intervals190706 +Ref: #report-intervals190861 +Node: Date adjustment191279 +Ref: #date-adjustment191439 +Node: Period expressions192290 +Ref: #period-expressions192431 +Node: Period expressions with a report interval194195 +Ref: #period-expressions-with-a-report-interval194429 +Node: More complex report intervals194643 +Ref: #more-complex-report-intervals194888 +Node: Multiple weekday intervals196689 +Ref: #multiple-weekday-intervals196878 +Node: Depth197700 +Ref: #depth197802 +Node: Queries198098 +Ref: #queries198200 +Node: Query types199325 +Ref: #query-types199446 +Node: Combining query terms202782 +Ref: #combining-query-terms202959 +Node: Queries and command options204227 +Ref: #queries-and-command-options204426 +Node: Queries and valuation204675 +Ref: #queries-and-valuation204870 +Node: Querying with account aliases205099 +Ref: #querying-with-account-aliases205310 +Node: Querying with cost or value205440 +Ref: #querying-with-cost-or-value205617 +Node: Pivoting205918 +Ref: #pivoting206032 +Node: Generating data207809 +Ref: #generating-data207941 +Node: Forecasting209524 +Ref: #forecasting209649 +Node: --forecast210180 +Ref: #forecast210311 +Node: Inspecting forecast transactions211357 +Ref: #inspecting-forecast-transactions211559 +Node: Forecast reports212689 +Ref: #forecast-reports212862 +Node: Forecast tags213798 +Ref: #forecast-tags213958 +Node: Forecast period in detail214418 +Ref: #forecast-period-in-detail214612 +Node: Forecast troubleshooting215506 +Ref: #forecast-troubleshooting215674 +Node: Budgeting216577 +Ref: #budgeting216697 +Node: Cost reporting217134 +Ref: #cost-reporting217268 +Node: Recording costs217929 +Ref: #recording-costs218065 +Node: Reporting at cost219656 +Ref: #reporting-at-cost219831 +Node: Equity conversion postings220421 +Ref: #equity-conversion-postings220635 +Node: Inferring equity conversion postings223066 +Ref: #inferring-equity-conversion-postings223329 +Node: Combining costs and equity conversion postings224081 +Ref: #combining-costs-and-equity-conversion-postings224391 +Node: Requirements for detecting equity conversion postings225379 +Ref: #requirements-for-detecting-equity-conversion-postings225701 +Node: Infer cost and equity by default ?226901 +Ref: #infer-cost-and-equity-by-default227130 +Node: Value reporting227338 +Ref: #value-reporting227480 +Node: -V Value228254 +Ref: #v-value228386 +Node: -X Value in specified commodity228581 +Ref: #x-value-in-specified-commodity228782 +Node: Valuation date228931 +Ref: #valuation-date229108 +Node: Finding market price229545 +Ref: #finding-market-price229756 +Node: --infer-market-prices market prices from transactions230926 +Ref: #infer-market-prices-market-prices-from-transactions231208 +Node: Valuation commodity233970 +Ref: #valuation-commodity234189 +Node: Simple valuation examples235402 +Ref: #simple-valuation-examples235606 +Node: --value Flexible valuation236265 +Ref: #value-flexible-valuation236475 +Node: More valuation examples238119 +Ref: #more-valuation-examples238334 +Node: Interaction of valuation and queries240333 +Ref: #interaction-of-valuation-and-queries240580 +Node: Effect of valuation on reports241052 +Ref: #effect-of-valuation-on-reports241255 +Node: PART 4 COMMANDS248952 +Ref: #part-4-commands249101 +Node: Commands overview249480 +Ref: #commands-overview249614 +Node: DATA ENTRY249793 +Ref: #data-entry249917 +Node: DATA CREATION250116 +Ref: #data-creation250270 +Node: DATA MANAGEMENT250388 +Ref: #data-management250553 +Node: REPORTS FINANCIAL250674 +Ref: #reports-financial250849 +Node: REPORTS VERSATILE251154 +Ref: #reports-versatile251327 +Node: REPORTS BASIC251580 +Ref: #reports-basic251732 +Node: HELP252241 +Ref: #help252363 +Node: ADD-ONS252473 +Ref: #add-ons252579 +Node: accounts253158 +Ref: #accounts253291 +Node: activity255178 +Ref: #activity255297 +Node: add255671 +Ref: #add255781 +Node: aregister258592 +Ref: #aregister258713 +Node: aregister and custom posting dates261601 +Ref: #aregister-and-custom-posting-dates261767 +Node: balance262319 +Ref: #balance262445 +Node: balance features263430 +Ref: #balance-features263570 +Node: Simple balance report265529 +Ref: #simple-balance-report265714 +Node: Balance report line format267339 +Ref: #balance-report-line-format267541 +Node: Filtered balance report269699 +Ref: #filtered-balance-report269891 +Node: List or tree mode270218 +Ref: #list-or-tree-mode270386 +Node: Depth limiting271731 +Ref: #depth-limiting271897 +Node: Dropping top-level accounts272498 +Ref: #dropping-top-level-accounts272698 +Node: Showing declared accounts273008 +Ref: #showing-declared-accounts273207 +Node: Sorting by amount273738 +Ref: #sorting-by-amount273905 +Node: Percentages274575 +Ref: #percentages274734 +Node: Multi-period balance report275282 +Ref: #multi-period-balance-report275482 +Node: Balance change end balance277757 +Ref: #balance-change-end-balance277966 +Node: Balance report types279394 +Ref: #balance-report-types279575 +Node: Calculation type280073 +Ref: #calculation-type280228 +Node: Accumulation type280777 +Ref: #accumulation-type280957 +Node: Valuation type281859 +Ref: #valuation-type282047 +Node: Combining balance report types283048 +Ref: #combining-balance-report-types283242 +Node: Budget report285080 +Ref: #budget-report285242 +Node: Budget report start date290896 +Ref: #budget-report-start-date291074 +Node: Budgets and subaccounts292406 +Ref: #budgets-and-subaccounts292613 +Node: Selecting budget goals296053 +Ref: #selecting-budget-goals296252 +Node: Budget vs forecast297287 +Ref: #budget-vs-forecast297446 +Node: Balance report layout299076 +Ref: #balance-report-layout299256 +Node: Useful balance reports307441 +Ref: #useful-balance-reports307601 +Node: balancesheet308686 +Ref: #balancesheet308831 +Node: balancesheetequity310151 +Ref: #balancesheetequity310309 +Node: cashflow311698 +Ref: #cashflow311829 +Node: check313257 +Ref: #check313371 +Node: Basic checks314173 +Ref: #basic-checks314293 +Node: Strict checks314780 +Ref: #strict-checks314923 +Node: Other checks315403 +Ref: #other-checks315545 +Node: Custom checks316098 +Ref: #custom-checks316255 +Node: More about specific checks316672 +Ref: #more-about-specific-checks316834 +Node: close317540 +Ref: #close317651 +Node: close and balance assertions321116 +Ref: #close-and-balance-assertions321294 +Node: Example retain earnings322445 +Ref: #example-retain-earnings322662 +Node: Example migrate balances to a new file323094 +Ref: #example-migrate-balances-to-a-new-file323359 +Node: Example excluding closing/opening transactions323935 +Ref: #example-excluding-closingopening-transactions324184 +Node: codes325402 +Ref: #codes325519 +Node: commodities326383 +Ref: #commodities326511 +Node: demo326581 +Ref: #demo326702 +Node: descriptions327618 +Ref: #descriptions327748 +Node: diff328039 +Ref: #diff328154 +Node: files329196 +Ref: #files329305 +Node: help329446 +Ref: #help-1329555 +Node: import330928 +Ref: #import331051 +Node: Deduplication332137 +Ref: #deduplication332262 +Node: Import testing334220 +Ref: #import-testing334385 +Node: Importing balance assignments335228 +Ref: #importing-balance-assignments335434 +Node: Commodity display styles336083 +Ref: #commodity-display-styles336256 +Node: incomestatement336385 +Ref: #incomestatement336527 +Node: notes337848 +Ref: #notes337970 +Node: payees338332 +Ref: #payees338447 +Node: prices338966 +Ref: #prices339081 +Node: print339379 +Ref: #print339494 +Node: register344838 +Ref: #register344960 +Node: Custom register output349991 +Ref: #custom-register-output350122 +Node: rewrite351459 +Ref: #rewrite351577 +Node: Re-write rules in a file353475 +Ref: #re-write-rules-in-a-file353638 +Node: Diff output format354787 +Ref: #diff-output-format354970 +Node: rewrite vs print --auto356062 +Ref: #rewrite-vs.-print---auto356222 +Node: roi356778 +Ref: #roi356885 +Node: Spaces and special characters in --inv and --pnl358606 +Ref: #spaces-and-special-characters-in---inv-and---pnl358846 +Node: Semantics of --inv and --pnl359334 +Ref: #semantics-of---inv-and---pnl359573 +Node: IRR and TWR explained361423 +Ref: #irr-and-twr-explained361583 +Node: stats364669 +Ref: #stats364777 +Node: tags366164 +Ref: #tags-1366271 +Node: test367280 +Ref: #test367373 +Node: PART 5 COMMON TASKS368115 +Ref: #part-5-common-tasks368261 +Node: Getting help368559 +Ref: #getting-help368700 +Node: Constructing command lines369460 +Ref: #constructing-command-lines369661 +Node: Starting a journal file370318 +Ref: #starting-a-journal-file370520 +Node: Setting LEDGER_FILE371722 +Ref: #setting-ledger_file371914 +Node: Setting opening balances372871 +Ref: #setting-opening-balances373072 +Node: Recording transactions376213 +Ref: #recording-transactions376402 +Node: Reconciling376958 +Ref: #reconciling377110 +Node: Reporting379367 +Ref: #reporting379516 +Node: Migrating to a new file383501 +Ref: #migrating-to-a-new-file383658 +Node: BUGS383957 +Ref: #bugs384047 +Node: Troubleshooting384926 +Ref: #troubleshooting385026  End Tag Table diff --git a/hledger/hledger.txt b/hledger/hledger.txt index 4fc8d9bc0..e6df317ef 100644 --- a/hledger/hledger.txt +++ b/hledger/hledger.txt @@ -1,8 +1,6 @@ HLEDGER(1) hledger User Manuals HLEDGER(1) - - NAME hledger - robust, friendly plain text accounting (CLI version) @@ -20,10 +18,10 @@ DESCRIPTION This manual is for hledger's command line interface, version 1.30.99. It also describes the common options, file formats and concepts used by - all hledger programs. It might accidentally teach you some bookkeep- - ing/accounting as well! You don't need to know everything in here to - use hledger productively, but when you have a question about function- - ality, this doc should answer it. It is detailed, so do skip ahead or + all hledger programs. It might accidentally teach you some bookkeep- + ing/accounting as well! You don't need to know everything in here to + use hledger productively, but when you have a question about function- + ality, this doc should answer it. It is detailed, so do skip ahead or skim when needed. You can read it on hledger.org, or as an info manual or man page on your system. You can also get it from hledger itself with @@ -31,8 +29,8 @@ DESCRIPTION The main function of the hledger CLI is to read plain text files de- scribing financial transactions, crunch the numbers, and print a useful - report on the terminal (or save it as HTML, CSV, JSON or SQL). Many - reports are available, as subcommands. hledger will also detect other + report on the terminal (or save it as HTML, CSV, JSON or SQL). Many + reports are available, as subcommands. hledger will also detect other hledger-* executables as extra subcommands. hledger usually reads from (and appends to) a journal file specified by @@ -91,32 +89,32 @@ Input perhaps with version control. Also, starting a new journal file each year is common (it's not required, but helps keep things fast and or- ganised). So we usually configure a different journal file, by setting - the LEDGER_FILE environment variable, to something like ~/fi- - nance/2023.journal. For more about how to do that on your system, see + the LEDGER_FILE environment variable, to something like ~/fi- + nance/2023.journal. For more about how to do that on your system, see Common tasks > Setting LEDGER_FILE. Data formats - Usually the data file is in hledger's journal format, but it can be in + 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 + 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 CSV/SSV/TSV/character-separated values, .csv .ssv .tsv + csv CSV/SSV/TSV/character-separated values, .csv .ssv .tsv for data import .csv.rules .ssv.rules .tsv.rules These formats are described in more detail 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 + 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. @@ -136,7 +134,7 @@ Input $ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:- Multiple files - You can specify multiple -f options, to read multiple files as one big + You can specify multiple -f options, to read multiple files as one big journal. When doing this, note that certain features (described below) will be affected: @@ -171,13 +169,13 @@ Input o Are all commodity conversions declared explicitly ? - You can use the check command to run individual checks -- the ones + You can use the check command to run individual checks -- the ones listed above and some more. Commands - hledger provides various subcommands for getting things done. Most of - these commands do not change the journal file; they just read it and - output a report. A few commands assist with adding data and file man- + hledger provides various subcommands for getting things done. Most of + these commands do not change the journal file; they just read it and + output a report. A few commands assist with adding data and file man- agement. To show the commands list, run hledger with no arguments. The commands @@ -199,23 +197,23 @@ Commands nal, run hledger CMD -h. Eg: hledger bal -h. Add-on commands - In addition to the built-in commands, you can install add-on commands: - programs or scripts named "hledger-SOMETHING", which will also appear - in hledger's commands list. If you used the hledger-install script, - you will have several add-ons installed already. Some more can be - found in hledger's bin/ directory, documented at + In addition to the built-in commands, you can install add-on commands: + programs or scripts named "hledger-SOMETHING", which will also appear + in hledger's commands list. If you used the hledger-install script, + you will have several add-ons installed already. Some more can be + found in hledger's bin/ directory, documented at https://hledger.org/scripts.html. More precisely, add-on commands are programs or scripts in your shell's PATH, whose name starts with "hledger-" and ends with no extension or a - recognised extension (".bat", ".com", ".exe", ".hs", ".js", ".lhs", - ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"), and (on unix + recognised extension (".bat", ".com", ".exe", ".hs", ".js", ".lhs", + ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"), and (on unix and mac) which has executable permission for the current user. You can run add-on commands using hledger, much like built-in commands: hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]. But note the double - hyphen argument, required before add-on-specific options. Eg: hledger - ui -- --watch or hledger web -- --serve. If this causes difficulty, + hyphen argument, required before add-on-specific options. Eg: hledger + ui -- --watch or hledger web -- --serve. If this causes difficulty, you can always run the add-on directly, without using hledger: hledger- ui --watch or hledger-web --serve. @@ -264,7 +262,7 @@ Options assignments) -s --strict - do extra error checking (check that all posted accounts are de- + do extra error checking (check that all posted accounts are de- clared) General reporting options @@ -292,7 +290,7 @@ Options multiperiod/multicolumn report by year -p --period=PERIODEXP - set start date, end date, and/or reporting interval all at once + set start date, end date, and/or reporting interval all at once using period expressions syntax --date2 @@ -383,19 +381,19 @@ Options Some reporting options can also be written as query arguments. Command line tips - Here are some details useful to know about for hledger command lines + Here are some details useful to know about for hledger command lines (and elsewhere). Feel free to skip this section until you need it. Option repetition - If options are repeated in a command line, hledger will generally use + If options are repeated in a command line, hledger will generally use the last (right-most) occurence. 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- + 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' @@ -404,17 +402,17 @@ Command line tips $ hledger register credit\ card - Windows users should keep in mind that cmd treats single quote as a - regular character, so you should be using double quotes exclusively. + Windows users should keep in mind that cmd treats single quote as a + regular character, so you should be using double quotes exclusively. PowerShell treats both single and double quotes as quotes. 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 + 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:'\$' @@ -424,7 +422,7 @@ Command line tips $ hledger balance cur:\\$ Triple escaping (for add-on commands) - When you use hledger to run an external add-on command (described be- + 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 @@ -450,7 +448,7 @@ Command line tips 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 + command line, where shell-escaping is not needed, so there you should use one less level of escaping. Those places include: o an @argumentfile @@ -464,23 +462,23 @@ Command line tips 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 + 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- + 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- + 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..) + 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 @@ -570,16 +568,17 @@ Output Some commands offer other kinds of output, not just text on the termi- nal. Here are those commands and the formats currently supported: - - txt csv html json sql + - txt csv html json sql -------------------------------------------------------------------------------------- - aregister Y Y Y Y - balance Y 1 Y 1 Y 1,2 Y - balancesheet Y 1 Y 1 Y 1 Y - balancesheetequity Y 1 Y 1 Y 1 Y - cashflow Y 1 Y 1 Y 1 Y - incomestatement Y 1 Y 1 Y 1 Y - print Y Y Y Y - register Y Y Y + aregister Y Y Y Y + balance Y 1 Y 1 Y 1,2 Y + balancesheet Y 1 Y 1 Y 1 Y + balancesheete- Y 1 Y 1 Y 1 Y + quity + cashflow Y 1 Y 1 Y 1 Y + incomestatement Y 1 Y 1 Y 1 Y + print Y Y Y Y + register Y Y Y o 1 Also affected by the balance commands' --layout option. @@ -613,16 +612,16 @@ Output JSON output o This is not yet much used; real-world feedback is welcome. - o Our JSON is rather large and verbose, since it is a faithful repre- - sentation of hledger's internal data types. To understand the JSON, - read the Haskell type definitions, which are mostly in + o Our JSON is rather large and verbose, since it is a faithful repre- + sentation 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 + 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 @@ -646,12 +645,12 @@ Output or drop tables completely as otherwise your postings will be duped. Commodity styles - When displaying amounts, hledger infers a standard display style for + When displaying amounts, hledger infers a standard display style for each commodity/currency, as described below in Commodity display style. If needed, this can be overridden by a -c/--commodity-style option (ex- cept for cost amounts and amounts displayed by the print command, which - are always displayed with all decimal digits). For example, the fol- + are always displayed with all decimal digits). For example, the fol- lowing will force dollar amounts to be displayed as shown: $ hledger print -c '$1.000,0' @@ -695,12 +694,12 @@ Output o when viewing manuals with hledger help or hledger --man. - Note the pager is expected to handle ANSI codes, which hledger uses eg + Note the pager is expected to handle ANSI codes, which hledger uses eg for bold emphasis. For the common pager less (and its more compatibil- ity mode), we add R to the LESS and MORE environment variables to make this work. If you use a different pager, you might need to configure it similarly, to avoid seeing junk on screen (let us know). Otherwise, - you can set the NO_COLOR environment variable to 1 to disable all ANSI + you can set the NO_COLOR environment variable to 1 to disable all ANSI output (see Colour). Debug output @@ -710,8 +709,8 @@ Output to 9 (maximum output). Typically you would start with 1 and increase until you are seeing enough. Debug output goes to stderr, and is not affected by -o/--output-file (unless you redirect stderr to stdout, eg: - 2>&1). It will be interleaved with normal output, which can help re- - veal when parts of the code are evaluated. To capture debug output in + 2>&1). It will be interleaved with normal output, which can help re- + veal when parts of the code are evaluated. To capture debug output in a log file instead, you can usually redirect stderr, eg: hledger bal --debug=3 2>hledger.log @@ -719,20 +718,20 @@ Output Environment These environment variables affect hledger: - COLUMNS This is normally set by your terminal; some hledger commands - (register) will format their output to this width. If not set, they + COLUMNS This is normally set by your terminal; some hledger commands + (register) will format their output to this width. If not set, they will try to use the available terminal width. - LEDGER_FILE The main journal file to use when not specified with + LEDGER_FILE The main journal file to use when not specified with -f/--file. Default: $HOME/.hledger.journal. - NO_COLOR If this environment variable is set (with any value), hledger - will not use ANSI color codes in terminal output, unless overridden by + NO_COLOR If this environment variable is set (with any value), hledger + will not use ANSI color codes in terminal output, unless overridden by an explicit --color/--colour option. PART 2: DATA FORMATS Journal - hledger's default file format, representing a General Journal. Here's + hledger's default file format, representing a General Journal. Here's a cheatsheet/mini-tutorial, or you can skip ahead to About journal for- mat. @@ -827,8 +826,8 @@ Journal About journal format 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 + 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 @@ -836,22 +835,22 @@ Journal hledger's journal format is compatible with most of Ledger's journal format, but not all of it. The differences and interoperation tips are - described at hledger and Ledger. With some care, and by avoiding in- - compatible features, you can keep your hledger journal readable by - Ledger and vice versa. This can useful eg for comparing the behaviour + described at hledger and Ledger. With some care, and by avoiding in- + compatible features, you can keep your hledger journal readable by + Ledger and vice versa. This can useful eg for comparing the behaviour of one app against the other. 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 + 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 + Here's a description of each part of the file format (and hledger's data model). A hledger journal file can contain three kinds of thing: file comments, @@ -860,7 +859,7 @@ Journal Comments Lines in the journal will be ignored if they begin with a hash (#) or a - semicolon (;). (See also Other syntax.) hledger will also ignore re- + semicolon (;). (See also Other syntax.) hledger will also ignore re- gions beginning with a comment line and ending with an end comment line (or file end). Here's a suggestion for choosing between them: @@ -900,7 +899,7 @@ Journal 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 + 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 @@ -917,17 +916,17 @@ Journal 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 Y directive, or the cur- + omitted, in which case it will be inferred from the context: the cur- + rent transaction, the default year set with a Y directive, or the cur- rent 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 + (The UI also accepts simple dates, as well as the more flexible smart dates documented in the hledger manual.) Posting dates - You can give individual postings a different date from their parent - transaction, by adding a posting comment containing a tag (see below) + 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 @@ -973,10 +972,10 @@ Journal 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 + 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. + What "uncleared", "pending", and "cleared" actually mean is up to you. Here's one suggestion: status meaning @@ -987,7 +986,7 @@ Journal 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 + 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. @@ -1002,7 +1001,7 @@ Journal 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 + wish, or left blank. Transaction descriptions can be queried, unlike comments. Payee and note @@ -1039,17 +1038,17 @@ Journal 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 + 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. + Be sure to note the unusual two-space delimiter between account name + and amount. This makes it easy to write account names containing + spaces. But if you accidentally leave only one space (or tab) before + the amount, the amount will be considered part of the account name. Account names - Accounts are the main way of categorising things in hledger. As in - Double Entry Bookkeeping, they can represent real world accounts (such + Accounts are the main way of categorising things in hledger. As in + Double Entry Bookkeeping, they can represent real world accounts (such as a bank account), or more abstract categories such as "money borrowed from Frank" or "money spent on electricity". @@ -1060,7 +1059,7 @@ Journal For more precise reporting, we usually divide the top level accounts into more detailed subaccounts, by writing a full colon between account - name parts. For example, from the account names assets:bank:checking + name parts. For example, from the account names assets:bank:checking and expenses:food, hledger will infer this hierarchy of five accounts: assets @@ -1082,23 +1081,23 @@ Journal names relatively simple may be best when starting out. Account names may be capitalised or not; they may contain letters, num- - bers, symbols, or single spaces. Note, when an account name and an - amount are written on the same line, they must be separated by two or + bers, symbols, or single spaces. Note, when an account name and an + amount are written on the same line, they must be separated by two or more spaces (or tabs). - Parentheses or brackets enclosing the full account name indicate vir- - tual postings, described below. Parentheses or brackets internal to + Parentheses or brackets enclosing the full account name indicate vir- + tual postings, described below. Parentheses or brackets internal to the account name have no special meaning. - Account names can be altered temporarily or permanently by account + Account names can be altered temporarily or permanently by account aliases. Amounts - After the account name, there is usually an amount. (Important: be- + 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- + hledger's amount format is flexible, supporting several international + formats. Here are some examples. Amounts have a number (the "quan- tity"): 1 @@ -1112,13 +1111,13 @@ Journal 3 "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- + 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 + One or more spaces between the sign and the number are acceptable when parsing (but they won't be displayed in output): + $1 @@ -1135,8 +1134,8 @@ Journal 1.23 1,23456780000009 - 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, + 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 @@ -1156,34 +1155,34 @@ Journal To prevent confusing parsing mistakes and undetected typos, especially if your data contains digit group marks (eg, thousands separators), we recommend explicitly declaring the decimal mark character in each jour- - nal file, using a directive at the top of the file. The decimal-mark - directive is best, otherwise commodity directives will also work. + nal file, using a directive at the top of the file. The decimal-mark + directive is best, otherwise commodity directives will also work. These are described below. Commodity - Amounts in hledger have both a "quantity", which is a signed decimal + Amounts in hledger have both a "quantity", which is a signed decimal number, and a "commodity", which is a currency symbol, stock ticker, or any word or phrase describing something you are tracking. If the commodity name contains non-letters (spaces, numbers, or punctu- - ation), you must always write it inside double quotes ("green apples", + ation), you must always write it inside double quotes ("green apples", "ABC123"). - If you write just a bare number, that too will have a commodity, with + If you write just a bare number, that too will have a commodity, with name ""; we call that the "no-symbol commodity". - Actually, hledger combines these single-commodity amounts into more - powerful multi-commodity amounts, which are what it works with most of - the time. A multi-commodity amount could be, eg: 1 USD, 2 EUR, 3.456 - TSLA. In practice, you will only see multi-commodity amounts in + Actually, hledger combines these single-commodity amounts into more + powerful multi-commodity amounts, which are what it works with most of + the time. A multi-commodity amount could be, eg: 1 USD, 2 EUR, 3.456 + TSLA. In practice, you will only see multi-commodity amounts in hledger's output; you can't write them directly in the journal file. - (If you are writing scripts or working with hledger's internals, these + (If you are writing scripts or working with hledger's internals, these are the Amount and MixedAmount types.) Directives influencing number parsing and display - You can add decimal-mark and commodity directives to the journal, to - declare and control these things more explicitly and precisely. These + You can add decimal-mark and commodity directives to the journal, to + declare and control these things more explicitly and precisely. These are described below, but here's a quick example: # the decimal mark character used by all amounts in this file (all commodities) @@ -1203,16 +1202,16 @@ Journal A commodity's display style is inferred as follows. - First, if a default commodity is declared with D, this commodity and + First, if a default commodity is declared with D, this commodity and its style is applied to any no-symbol amounts in the journal. - Then each commodity's style is inferred from one of the following, in + Then each commodity's style is inferred from one of the following, in order of preference: - o The commodity directive for that commodity (including the no-symbol + o The commodity directive for that commodity (including the no-symbol commodity), if any. - o The amounts in that commodity seen in the journal's transactions. + o The amounts in that commodity seen in the journal's transactions. (Posting amounts only; prices and periodic or auto rules are ignored, currently.) @@ -1234,11 +1233,11 @@ Journal ferred using a cost). If you find this causing problems, use a commod- ity directive to fix the display style. - To summarise: each commodity's amounts will be normalised to (a) the - style declared by a commodity directive, or (b) the style of the first - posting amount in the journal, with the first-seen digit group style - and the maximum-seen number of decimal places. So if your reports are - showing amounts in a way you don't like, eg with too many decimal + To summarise: each commodity's amounts will be normalised to (a) the + style declared by a commodity directive, or (b) the style of the first + posting amount in the journal, with the first-seen digit group style + and the maximum-seen number of decimal places. So if your reports are + showing amounts in a way you don't like, eg with too many decimal places, use a commodity directive. Some examples: # declare euro, dollar, bitcoin and no-symbol commodities and set their @@ -1248,7 +1247,7 @@ Journal commodity 1000.00000000 BTC commodity 1 000. - The inferred commodity style can be overridden by supplying a command + The inferred commodity style can be overridden by supplying a command line option. Rounding @@ -1270,7 +1269,7 @@ Journal "cost", with the understanding that the transaction could be a purchase or a sale.) - Costs are usually written explicitly with @ or @@, but can also be in- + Costs are usually written explicitly with @ or @@, but can also be in- ferred automatically for simple multi-commodity transactions. Note, if costs are inferred, the order of postings is significant; the first posting will have a cost attached, in the commodity of the second. @@ -1300,30 +1299,30 @@ Journal assets:euros 100 ; one hundred euros purchased assets:dollars $-135 ; for $135 - Amounts can be converted to cost at report time using the -B/--cost - flag; this is discussed more in the COST REPORTING section. + Amounts can be converted to cost at report time using the -B/--cost + flag; this is discussed more in the Cost reporting section. - Note that the cost normally should be a positive amount, though it's - not required to be. This can be a little confusing, see discussion at + Note that the cost normally should be a positive amount, though it's + not required to be. This can be a little confusing, see discussion at --infer-market-prices: market prices from transactions. Other cost/lot notations - A slight digression for Ledger and Beancount users. Ledger has a num- + A slight digression for Ledger and Beancount users. Ledger has a num- ber of cost/lot-related notations: o @ UNITCOST and @@ TOTALCOST o expresses a conversion rate, as in hledger - o when buying, also creates a lot than can be selected at selling + o when buying, also creates a lot than can be selected at selling time o (@) UNITCOST and (@@) TOTALCOST (virtual cost) - o like the above, but also means "this cost was exceptional, don't + o like the above, but also means "this cost was exceptional, don't use it when inferring market prices". - Currently, hledger treats the above like @ and @@; the parentheses are + Currently, hledger treats the above like @ and @@; the parentheses are ignored. o {=FIXEDUNITCOST} and {{=FIXEDTOTALCOST}} (fixed price) @@ -1379,18 +1378,18 @@ Journal o expresses the selling price for transaction balancing - Currently, hledger accepts the {UNITCOST}/{{TOTALCOST}} notation but + Currently, hledger accepts the {UNITCOST}/{{TOTALCOST}} notation but ignores it. - o variations: {}, {YYYY-MM-DD}, {"LABEL"}, {UNITCOST, "LABEL"}, {UNIT- + o variations: {}, {YYYY-MM-DD}, {"LABEL"}, {UNITCOST, "LABEL"}, {UNIT- COST, YYYY-MM-DD, "LABEL"} etc. Currently, hledger rejects these. 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 + 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 @@ -1406,31 +1405,31 @@ Journal 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 + for reading Ledger files. (Note: this flag currently does not disable balance assignments, described 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- + 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. + 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 multiple included files - Multiple files included with the include directive are processed as if - concatenated into one file, preserving their order and the posting or- - der within each file. It means that balance assertions in later files + Multiple files included with the include directive are processed as if + concatenated into one file, preserving their order and the posting or- + der within each file. It means that balance assertions in later files will see balance from earlier files. - And if you have multiple postings to an account on the same day, split - across multiple files, and you want to assert the account's balance on + And if you have multiple postings to an account on the same day, split + across multiple files, and you want to assert the account's balance on that day, you'll need to put the assertion in the right file - the last one in the sequence, probably. @@ -1440,13 +1439,13 @@ Journal ance from earlier files. This can be useful when you do not want prob- lems in earlier files to disrupt valid assertions in later files. - If you do want assertions to see balance from earlier files, use in- + If you do want assertions to see balance from earlier files, use in- clude, or concatenate the files temporarily. 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 + 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 @@ -1454,7 +1453,7 @@ Journal You can make a stronger "total" balance assertion by writing a double equals sign (== EXPECTEDBALANCE). This asserts that there are no other - commodities in the account besides the asserted one (or at least, that + commodities in the account besides the asserted one (or at least, that their balance is 0). 2013/1/1 @@ -1493,15 +1492,15 @@ Journal 2019/1/1 (a) $1 @ 1 = $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- + 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 + 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 @@ -1531,15 +1530,15 @@ Journal avoid auto postings entirely). 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- + 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. Posting comments - Text following ;, at the end of a posting line, and/or on indented - lines immediately below it, form comments for that posting. They are - reproduced by print but otherwise ignored, except they may contain + Text following ;, at the end of a posting line, and/or on indented + lines immediately below it, form comments for that posting. They are + reproduced by print but otherwise ignored, except they may contain tags, which are not ignored. 2012-01-01 @@ -1549,7 +1548,7 @@ Journal ; a second comment line for posting 2 Tags - Tags are a way to add extra labels or labelled data to transactions, + Tags are a way to add extra labels or labelled data to transactions, postings, or accounts, which you can then search or pivot on. They are written as a word (optionally hyphenated) immediately followed @@ -1570,16 +1569,16 @@ Journal And transactions also acquire tags from their postings (and postings' accounts). So in the example above, the expenses posting effectively has all four tags (by inheriting from account and transaction), and the - transaction also has all four tags (by acquiring from the expenses + transaction also has all four tags (by acquiring from the expenses posting). - You can list tag names with hledger tags [NAMEREGEX], or match by tag + You can list tag names with hledger tags [NAMEREGEX], or match by tag name with a tag:NAMEREGEX query. Tag values - Tags can have a value, which is any text after the colon up until a - comma or end of line (with surrounding whitespace removed). Note this - means that hledger tag values can not contain commas. Eg in the fol- + Tags can have a value, which is any text after the colon up until a + comma or end of line (with surrounding whitespace removed). Note this + means that hledger tag values can not contain commas. Eg in the fol- lowing posting, the three tags' values are "value 1", "value 2", and "" (empty) respectively: @@ -1599,7 +1598,7 @@ Journal that modify hledger's behaviour. Some directives can have more spe- cific subdirectives, indented below them. hledger's directives are similar to Ledger's in many cases, but there are also many differences. - Directives are not required, but can be useful. Here are the main di- + Directives are not required, but can be useful. Here are the main di- rectives: purpose directive @@ -1607,16 +1606,16 @@ Journal READING DATA: Rewrite account names alias Comment out sections of the file comment - Declare file's decimal mark, to help decimal-mark + Declare file's decimal mark, to help decimal-mark parse amounts accurately Include other data files include GENERATING DATA: - Generate recurring transactions or bud- ~ + Generate recurring transactions or bud- ~ get goals - Generate extra postings on existing = + Generate extra postings on existing = transactions CHECKING FOR ERRORS: - Define valid entities to provide more account, commodity, payee, tag + Define valid entities to provide more account, commodity, payee, tag error checking REPORTING: Declare accounts' type and display order account @@ -1624,22 +1623,22 @@ Journal Declare market prices P Directives and multiple files - Directives vary in their scope, ie which journal entries and which in- + Directives vary in their scope, ie which journal entries and which in- put files they affect. Most often, a directive will affect the follow- ing entries and included files if any, until the end of the current file - and no further. You might find this inconvenient! For example, - alias directives do not affect parent or sibling files. But there are + alias directives do not affect parent or sibling files. But there are usually workarounds; for example, put alias directives in your top-most file, before including other files. The restriction, though it may be annoying at first, is in a good cause; it allows reports to be stable and deterministic, independent of - the order of input. Without it, reports could show different numbers - depending on the order of -f options, or the positions of include di- + the order of input. Without it, reports could show different numbers + depending on the order of -f options, or the positions of include di- rectives in your files. Directive effects - Here are all hledger's directives, with their effects and scope sum- + Here are all hledger's directives, with their effects and scope sum- marised - nine main directives, plus four others which we consider non- essential: @@ -1648,32 +1647,24 @@ Journal tive file end? -------------------------------------------------------------------------------------- - ac- Declares an account, for checking all entries in all files; and N + ac- Declares an account, for checking all entries in all files; and N count its display order and type. Subdirectives: any text, ignored. - alias Rewrites account names, in following entries until end of cur- Y + alias Rewrites account names, in following entries until end of cur- Y rent file or end aliases. Command line equivalent: --alias com- Ignores part of the journal file, until end of current file or Y ment end comment. - - - - - - - - com- Declares up to four things: 1. a commodity symbol, for checking N,Y,N,N - mod- all amounts in all files 2. the decimal mark for parsing + mod- all amounts in all files 2. the decimal mark for parsing ity amounts of this commodity, in the following entries until end of current file (if there is no decimal-mark directive) 3. and the - display style for amounts of this commodity 4. which is also - the precision to use for balanced-transaction checking in this - commodity. Takes precedence over D. Subdirectives: format - (Ledger-compatible syntax). Command line equivalent: -c/--com- + display style for amounts of this commodity 4. which is also + the precision to use for balanced-transaction checking in this + commodity. Takes precedence over D. Subdirectives: format + (Ledger-compatible syntax). Command line equivalent: -c/--com- modity-style deci- Declares the decimal mark, for parsing amounts of all commodi- Y mal- ties in following entries until next decimal-mark or end of cur- - mark rent file. Included files can override. Takes precedence over + mark rent file. Included files can override. Takes precedence over commodity and D. in- Includes entries and directives from another file, as if they N clude were written inline. Command line alternative: multiple @@ -1681,20 +1672,20 @@ Journal payee Declares a payee name, for checking all entries in all files. N P Declares the market price of a commodity on some date, for value N reports. - ~ Declares a periodic transaction rule that generates future N - (tilde) transactions with --forecast and budget goals with balance + ~ Declares a periodic transaction rule that generates future N + (tilde) transactions with --forecast and budget goals with balance --budget. Other syntax: - apply Prepends a common parent account to all account names, in fol- Y + apply Prepends a common parent account to all account names, in fol- Y account lowing entries until end of current file or end apply account. - D Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N - there is no commodity directive for this commodity: its decimal + D Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N + there is no commodity directive for this commodity: its decimal mark, balancing precision, and display style, as above. - Y Sets a default year to use for any yearless dates, in following Y + Y Sets a default year to use for any yearless dates, in following Y entries until end of current file. - = Declares an auto posting rule that generates extra postings on partly - (equals) matched transactions with --auto, in current, parent, and child + = Declares an auto posting rule that generates extra postings on partly + (equals) matched transactions with --auto, in current, parent, and child files (but not sibling files, see #1212). Other Other directives from Ledger's file format are accepted but ig- Ledger nored. @@ -1703,7 +1694,7 @@ Journal account directive account directives can be used to declare accounts (ie, the places that - amounts are transferred from and to). Though not required, these dec- + 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- @@ -1721,11 +1712,11 @@ Journal o They can store additional account information as comments, or as tags which can be used to filter or pivot reports. - o They can help hledger know your accounts' types (asset, liability, - equity, revenue, expense), affecting reports like balancesheet and + o They can help hledger know your accounts' types (asset, liability, + equity, revenue, expense), affecting reports like balancesheet and incomestatement. - They are written as the word account followed by a hledger-style ac- + They are written as the word account followed by a hledger-style ac- count name, eg: account assets:bank:checking @@ -1738,11 +1729,11 @@ Journal Account comments Text following two or more spaces and ; at the end of an account direc- - tive line, and/or following ; on indented lines immediately below it, - form comments for that account. They are ignored except they may con- + tive line, and/or following ; on indented lines immediately below it, + form comments for that account. They are ignored except they may con- tain tags, which are not ignored. - The two-space requirement for same-line account comments is because ; + The two-space requirement for same-line account comments is because ; is allowed in account names. account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon @@ -1750,16 +1741,16 @@ Journal ; some tags - type:A, acctnum:12345 Account subdirectives - Ledger-style indented subdirectives are also accepted, but currently + Ledger-style indented subdirectives are also accepted, but currently ignored: account assets:bank:checking format subdirective is ignored Account error checking - By default, accounts need not be declared; they come into existence - when a posting references them. This is convenient, but it means - hledger can't warn you when you mis-spell an account name in the jour- + By default, accounts need not be declared; they come into existence + when a posting references them. This is convenient, but it means + hledger can't warn you when you mis-spell an account name in the jour- nal. Usually you'll find that error later, as an extra account in bal- ance reports, or an incorrect balance when reconciling. @@ -1772,19 +1763,19 @@ Journal 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 + 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- + o Accounts can only be declared in journal files, but will affect in- cluded files of all types. - o It's currently not possible to declare "all possible subaccounts" + o It's currently not possible to declare "all possible subaccounts" with a wildcard; every account posted to must be declared. Account display order - The order in which account directives are written influences the order - in which accounts appear in reports, hledger-ui, hledger-web etc. By + The order in which account directives are written influences the order + in which accounts appear in reports, hledger-ui, hledger-web etc. By default accounts appear in alphabetical order, but if you add these ac- count directives to the journal file: @@ -1810,10 +1801,10 @@ Journal account other:zoo - would influence the position of zoo among other's subaccounts, but not + 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) + 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 @@ -1822,7 +1813,7 @@ Journal Account types hledger knows that accounts come in several types: assets, liabilities, - expenses and so on. This enables easy reports like balancesheet and + expenses and so on. This enables easy reports like balancesheet and incomestatement, and filtering by account type with the type: query. As a convenience, hledger will detect these account types automatically @@ -1849,8 +1840,8 @@ Journal o C or Cash (a subtype of Asset, indicating liquid assets for the cash- flow report) - o V or Conversion (a subtype of Equity, for conversions (see COST RE- - PORTING).) + o V or Conversion (a subtype of Equity, for conversions (see Cost re- + porting).) Here is a typical set of account type declarations: @@ -1867,7 +1858,7 @@ Journal Here are some tips for working with account types. - o The rules for inferring types from account names are as follows. + o The rules for inferring types from account names are as follows. These are just a convenience that sometimes help new users get going; if they don't work for you, just ignore them and declare your account types. See also Regular expressions. @@ -1882,7 +1873,7 @@ Journal ^(income|revenue)s?(:|$) | Revenue ^expenses?(:|$) | Expense - o If you declare any account types, it's a good idea to declare an ac- + o If you declare any account types, it's a good idea to declare an ac- count for all of the account types, because a mixture of declared and name-inferred types can disrupt certain reports. @@ -1890,17 +1881,17 @@ Journal Rewriting accounts > Aliases and account types. o As mentioned above, subaccounts will inherit a type from their parent - account. More precisely, an account's type is decided by the first + account. More precisely, an account's type is decided by the first of these that exists: 1. A type: declaration for this account. - 2. A type: declaration in the parent accounts above it, preferring + 2. A type: declaration in the parent accounts above it, preferring the nearest. 3. An account type inferred from this account's name. - 4. An account type inferred from a parent account's name, preferring + 4. An account type inferred from a parent account's name, preferring the nearest parent. 5. Otherwise, it will have no type. @@ -1926,7 +1917,7 @@ Journal 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- + do not affect account names being entered via hledger add or hledger- web. Account aliases are very powerful. They are generally easy to use cor- @@ -1936,9 +1927,9 @@ Journal 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 (but note: not sibling or parent files). The spaces + 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 (but note: not sibling or parent files). The spaces around the = are optional: alias OLD = NEW @@ -1983,21 +1974,21 @@ Journal option argument), so it can contain trailing whitespace. Combining aliases - You can define as many aliases as you like, using journal directives + 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 + 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 + 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 + 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 + 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: @@ -2008,20 +1999,20 @@ Journal 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- + 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 + 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 + 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- + account aliases defined in a.aliases will not affect b.journal. In- cluding the aliases doesn't work either: include a.aliases @@ -2049,7 +2040,7 @@ Journal end aliases Aliases can generate bad account names - Be aware that account aliases can produce malformed account names, + Be aware that account aliases can produce malformed account names, which could cause confusing reports or invalid print output. For exam- ple, you could erase all account names: @@ -2107,10 +2098,10 @@ Journal 3. It declares how to render the commodity's amounts when displaying output - the decimal mark, any digit group marks, the number of dec- - imal places, symbol placement and so on. (Cf Commodity display + imal places, symbol placement and so on. (Cf Commodity display style) - You will run into one of the problems solved by commodity directives + You will run into one of the problems solved by commodity directives sooner or later, so we recommend using them, for robust and predictable parsing and display. @@ -2169,7 +2160,7 @@ Journal Note, this disallows amounts without a commodity symbol, because cur- rently it's not possible (?) to declare the "no-symbol" commodity with - a directive. This is one exception for convenience: zero amounts are + a directive. This is one exception for convenience: zero amounts are always allowed to have no commodity symbol. decimal-mark directive @@ -2183,20 +2174,20 @@ Journal decimal-mark , - This prevents any ambiguity when parsing numbers in the file, so we - recommend it, especially if the file contains digit group marks (eg + This prevents any ambiguity when parsing numbers in the file, so we + recommend it, especially if the file contains digit group marks (eg thousands separators). include directive - You can pull in the content of additional files by writing an include + 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 + 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 + 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. @@ -2205,8 +2196,8 @@ Journal *.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 + 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- @@ -2215,7 +2206,7 @@ Journal P directive The P directive declares a market price, which is a conversion rate be- - tween two commodities on a certain date. This allows value reports to + tween two commodities on a certain date. This allows value reports to convert amounts of one commodity to their value in another, on or after that date. These prices are often obtained from a stock exchange, cryptocurrency exchange, the or foreign exchange market. @@ -2235,8 +2226,8 @@ Journal # and $1.40 from 2010-01-01 onward: P 2010-01-01 $1.40 - The -V, -X and --value flags use these market prices to show amount - values in another commodity. See Valuation. + The -V, -X and --value flags use these market prices to show amount + values in another commodity. See Value reporting. payee directive payee PAYEE NAME @@ -2262,7 +2253,7 @@ Journal The "tags" check will report an error if any undeclared tag name is used. It is quite easy to accidentally create a tag through normal use - of colons in comments(#comments]; if you want to prevent this, you can + of colons in comments(#comments]; if you want to prevent this, you can declare and check your tags . Periodic transactions @@ -2295,7 +2286,7 @@ Journal error. 7. Other period expressions with an interval are automatically expanded - to cover a whole number of that interval. (This is done to improve + 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 2023/01, which is equivalent to ~ every 10th day of month from @@ -2363,8 +2354,8 @@ Journal enced by the matched posting's amount. This can be useful for generat- ing tax postings with a standard percentage, for example. - Note that depending on generated data is not ideal for financial - records (it's less portable, less future-proof, less auditable by oth- + Note that depending on generated data is not ideal for financial + records (it's less portable, less future-proof, less auditable by oth- ers, and less robust, since other features like balance assertions will depend on using or not using --auto). @@ -2386,7 +2377,7 @@ Journal 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 + 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. @@ -2394,8 +2385,8 @@ Journal 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 + 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' @@ -2446,12 +2437,12 @@ Journal tions Currently, auto postings are added: - o after missing amounts are inferred, and transactions are checked for + 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 + 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. @@ -2465,7 +2456,7 @@ Journal 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 + 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. @@ -2478,24 +2469,24 @@ Journal tion was modified "just now". Auto postings on forecast transactions only - Tip: you can can make auto postings that will apply to forecast trans- - actions but not recorded transactions, by adding tag:_generated-trans- - action to their QUERY. This can be useful when generating new journal + Tip: you can can make auto postings that will apply to forecast trans- + actions but not recorded transactions, by adding tag:_generated-trans- + action to their QUERY. This can be useful when generating new journal entries to be saved in the journal. Other syntax - hledger journal format supports quite a few other features, mainly to - make interoperating with or converting from Ledger easier. Note some - of the features below are powerful and can be useful in special cases, - but in general, features in this section are considered less important - or even not recommended for most users. Downsides are mentioned to + hledger journal format supports quite a few other features, mainly to + make interoperating with or converting from Ledger easier. Note some + of the features below are powerful and can be useful in special cases, + but in general, features in this section are considered less important + or even not recommended for most users. Downsides are mentioned to help you decide if you want to use them. 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 + 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 @@ -2519,7 +2510,7 @@ Journal Downsides: using balance assignments makes your journal less explicit; to know the exact amount posted, you have to run hledger or do the cal- - culations yourself, instead of just reading it. Also balance assign- + culations yourself, instead of just reading it. Also balance assign- ments' forcing of balances can hide errors. These things make your fi- nancial data less portable, less future-proof, and less trustworthy in an audit. @@ -2535,8 +2526,13 @@ Journal 2019-01-01 (a) $1 @ 2 = $1 @ 2 + Balance assignments and multiple files + Balance assignments handle multiple files like balance assertions. + They see balance from other files previously included from the current + file, but not from previous sibling or parent files. + Bracketed posting dates - For setting posting dates and secondary posting dates, Ledger's brack- + For setting posting dates and secondary posting dates, Ledger's brack- eted date syntax is also supported: [DATE], [DATE=DATE2] or [=DATE2] in posting comments. hledger will attempt to parse any square-bracketed sequence of the 0123456789/-.= characters in this way. With this syn- @@ -2608,11 +2604,11 @@ Journal Account names entered via hledger add or hledger-web are not affected. - Account aliases, if any, are applied after the parent account is + Account aliases, if any, are applied after the parent account is prepended. - Downsides: this can make your financial data less explicit, less porta- - ble, and less trustworthy in an audit. + Downsides: this can make your financial data less explicit, less + portable, and less trustworthy in an audit. Y directive Y YEAR @@ -2621,7 +2617,7 @@ Journal year YEAR apply year YEAR - The space is optional. This sets a default year to be used for subse- + The space is optional. This sets a default year to be used for subse- quent dates which don't specify a year. Eg: Y2009 ; set default year to 2009 @@ -2642,9 +2638,9 @@ Journal Downsides: omitting the year (from primary transaction dates, at least) makes your financial data less explicit, less portable, and less trust- - worthy in an audit. Such dates can get separated from their corre- - sponding Y directive, eg when evaluating a region of the journal in - your editor. A missing Y directive makes reports dependent on today's + worthy in an audit. Such dates can get separated from their corre- + sponding Y directive, eg when evaluating a region of the journal in + your editor. A missing Y directive makes reports dependent on today's date. Secondary dates @@ -2660,37 +2656,37 @@ Journal Downsides: makes your financial data more complicated, less portable, and less trustworthy in an audit. Keeping the meaning of the two dates - consistent requires discipline, and you have to remember which report- - ing mode is appropriate for a given report. Posting dates are simpler + consistent requires discipline, and you have to remember which report- + ing mode is appropriate for a given report. Posting dates are simpler and better. Star comments - Lines beginning with * (star/asterisk) are also comment lines. This + Lines beginning with * (star/asterisk) are also comment lines. This feature allows Emacs users to insert org headings in their journal, al- lowing them to fold/unfold/navigate it like an outline when viewed with org mode. - Downsides: another, unconventional comment syntax to learn. Decreases - your journal's portability. And switching to Emacs org mode just for - folding/unfolding meant losing the benefits of ledger mode; nowadays - you can add outshine mode to ledger mode to get folding without losing + Downsides: another, unconventional comment syntax to learn. Decreases + your journal's portability. And switching to Emacs org mode just for + folding/unfolding meant losing the benefits of ledger mode; nowadays + you can add outshine mode to ledger mode to get folding without losing ledger mode's features. Valuation expressions - Ledger allows a valuation function or value to be written in double + Ledger allows a valuation function or value to be written in double parentheses after an amount. hledger ignores these. Virtual postings - A posting with parentheses around the account name ((some:account)) is - called a unbalanced virtual posting. Such postings do not participate - in transaction balancing. (And if you write them without an amount, a - zero amount is always inferred.) These can occasionally be convenient - for special circumstances, but they violate double entry bookkeeping - and make your data less portable across applications, so many people + A posting with parentheses around the account name ((some:account)) is + called a unbalanced virtual posting. Such postings do not participate + in transaction balancing. (And if you write them without an amount, a + zero amount is always inferred.) These can occasionally be convenient + for special circumstances, but they violate double entry bookkeeping + and make your data less portable across applications, so many people avoid using them at all. - A posting with brackets around the account name ([some:account]) is - called a balanced virtual posting. The balanced virtual postings in a + A posting with brackets around the account name ([some:account]) is + called a balanced virtual posting. The balanced virtual postings in a transaction must add up to zero, just like ordinary postings, but sepa- rately from them. These are not part of double entry bookkeeping ei- ther, but they are at least balanced. An example: @@ -2709,7 +2705,7 @@ Journal Other Ledger directives These other Ledger directives are currently accepted but ignored. This - allows hledger to read more Ledger files, but be aware that hledger's + allows hledger to read more Ledger files, but be aware that hledger's reports may differ from Ledger's if you use these. apply fixed COMM AMT @@ -2730,17 +2726,17 @@ Journal value EXPR --command-line-flags - See also https://hledger.org/ledger.html for a detailed hledger/Ledger + See also https://hledger.org/ledger.html for a detailed hledger/Ledger syntax comparison. CSV - hledger can read CSV files (Character Separated Value - usually comma, - semicolon, or tab) containing dated records, automatically converting + hledger can read CSV files (Character Separated Value - usually comma, + semicolon, or tab) containing dated records, automatically converting each record into a transaction. (To learn about writing CSV, see CSV output.) - For best error messages when reading CSV/TSV/SSV files, make sure they + For best error messages when reading CSV/TSV/SSV files, make sure they have a corresponding .csv, .tsv or .ssv file extension or use a hledger file prefix (see File Extension below). @@ -2753,12 +2749,12 @@ CSV By default hledger looks for a rules file named like the CSV file with an extra .rules extension, in the same directory. Eg when asked to read foo/FILE.csv, hledger looks for foo/FILE.csv.rules. You can spec- - ify a different rules file with the --rules-file option. If no rules - file is found, hledger will create a sample rules file, which you'll + ify a different rules file with the --rules-file option. If no rules + file is found, hledger will create a sample rules file, which you'll need to adjust. - 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 + 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 @@ -2782,49 +2778,49 @@ CSV The following kinds of rule can appear in the rules file, in any order. (Blank lines and lines beginning with # or ; or * are ignored.) - source optionally declare which file to read data + source optionally declare which file to read data from - separator declare the field separator, instead of rely- + separator declare the field separator, instead of rely- ing on file extension skip skip one or more header lines at start of file date-format declare how to parse CSV dates/date-times - timezone declare the time zone of ambiguous CSV date- + timezone declare the time zone of ambiguous CSV date- times - newest-first improve txn order when: there are multiple + newest-first improve txn order when: there are multiple records, newest first, all with the same date - intra-day-reversed improve txn order when: same-day txns are in + intra-day-reversed improve txn order when: same-day txns are in opposite order to the overall file - decimal-mark declare the decimal mark used in CSV amounts, + decimal-mark declare the decimal mark used in CSV amounts, when ambiguous - fields list name CSV fields for easy reference, and op- + fields list name CSV fields for easy reference, and op- tionally assign their values to hledger fields - Field assignment assign a CSV value or interpolated text value + Field assignment assign a CSV value or interpolated text value to a hledger field if block conditionally assign values to hledger fields, or skip a record or end (skip rest of file) if table conditionally assign values to hledger fields, using compact syntax - balance-type select which type of balance assertions/as- + balance-type select which type of balance assertions/as- signments to generate include inline another CSV rules file - Working with CSV tips can be found below, including How CSV rules are + Working with CSV tips can be found below, including How CSV rules are evaluated. source - If you tell hledger to read a csv file with -f foo.csv, it will look - for rules in foo.csv.rules. Or, you can tell it to read the rules - file, with -f foo.csv.rules, and it will look for data in foo.csv + If you tell hledger to read a csv file with -f foo.csv, it will look + for rules in foo.csv.rules. Or, you can tell it to read the rules + file, with -f foo.csv.rules, and it will look for data in foo.csv (since 1.30). - These are mostly equivalent, but the second method provides some extra - features. For one, the data file can be missing, without causing an - error; it is just considered empty. And, you can specify a different + These are mostly equivalent, but the second method provides some extra + features. For one, the data file can be missing, without causing an + error; it is just considered empty. And, you can specify a different data file by adding a "source" rule: source ./Checking1.csv - If you specify just a file name with no path, hledger will look for it + If you specify just a file name with no path, hledger will look for it in your system's downloads directory (~/Downloads, currently): source Checking1.csv @@ -2859,14 +2855,14 @@ CSV skip skip N - The word skip followed by a number (or no number, meaning 1) tells - hledger to ignore this many non-empty lines at the start of the input - data. You'll need this whenever your CSV data contains header lines. - Note, empty and blank lines are skipped automatically, so you don't + The word skip followed by a number (or no number, meaning 1) tells + hledger to ignore this many non-empty lines at the start of the input + data. You'll need this whenever your CSV data contains header lines. + Note, empty and blank lines are skipped automatically, so you don't need to count those. - skip has a second meaning: it can be used inside if blocks (described - below), to skip one or more records whenever the condition is true. + skip has a second meaning: it can be used inside if blocks (described + below), to skip one or more records whenever the condition is true. Records skipped in this way are ignored, except they are still required to be valid CSV. @@ -2899,11 +2895,11 @@ CSV When CSV contains date-times that are implicitly in some time zone other than yours, but containing no explicit time zone information, you - can use this rule to declare the CSV's native time zone, which helps + can use this rule to declare the CSV's native time zone, which helps prevent off-by-one dates. - When the CSV date-times do contain time zone information, you don't - need this rule; instead, use %Z in date-format (or %z, %EZ, %Ez; see + When the CSV date-times do contain time zone information, you don't + need this rule; instead, use %Z in date-format (or %z, %EZ, %Ez; see the formatTime link above). In either of these cases, hledger will do a time-zone-aware conversion, @@ -2920,10 +2916,10 @@ CSV newest-first hledger tries to ensure that the generated transactions will be ordered - chronologically, including intra-day transactions. Usually it can - auto-detect how the CSV records are ordered. But if it encounters CSV - where all records are on the same date, it assumes that the records are - oldest first. If in fact the CSV's records are normally newest first, + chronologically, including same-day transactions. Usually it can auto- + detect how the CSV records are ordered. But if it encounters CSV where + all records are on the same date, it assumes that the records are old- + est first. If in fact the CSV's records are normally newest first, like: 2022-10-01, txn 3... @@ -2937,18 +2933,16 @@ CSV newest-first intra-day-reversed - CSV records for each day are sometimes ordered in reverse compared to - the overall date order. Eg, here dates are newest first, but the - transactions on each date are oldest first: + If CSV records within a single day are ordered opposite to the overall + record order, you can add the intra-day-reversed rule to improve the + order of journal entries. Eg, here the overall record order is newest + first, but same-day records are oldest first: 2022-10-02, txn 3... 2022-10-02, txn 4... 2022-10-01, txn 1... 2022-10-01, txn 2... - In this situation, add the intra-day-reversed rule, and hledger will - compensate, improving the order of transactions. - # transactions within each day are reversed with respect to the overall date order intra-day-reversed @@ -2971,17 +2965,17 @@ CSV A fields list (the word fields followed by comma-separated field names) is optional, but convenient. It does two things: - 1. It names the CSV field in each column. This can be convenient if - you are referencing them in other rules, so you can say %SomeField + 1. It names the CSV field in each column. This can be convenient if + you are referencing them in other rules, so you can say %SomeField instead of remembering %13. - 2. Whenever you use one of the special hledger field names (described - below), it assigns the CSV value in this position to that hledger - field. This is the quickest way to populate hledger's fields and + 2. Whenever you use one of the special hledger field names (described + below), it assigns the CSV value in this position to that hledger + field. This is the quickest way to populate hledger's fields and build a 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 + 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 @@ -3015,11 +3009,11 @@ CSV hledger fields. They can be used instead of or in addition to a fields list (see above). - To assign a value to a hledger field, write the field name (any of the - standard hledger field/pseudo-field names, defined below), a space, - followed by a text value on the same line. This text value may inter- - polate CSV fields, referenced by their 1-based position in the CSV - record (%N), or by the name they were given in the fields list (%CSV- + To assign a value to a hledger field, write the field name (any of the + standard hledger field/pseudo-field names, defined below), a space, + followed by a text value on the same line. This text value may inter- + polate CSV fields, referenced by their 1-based position in the CSV + record (%N), or by the name they were given in the fields list (%CSV- FIELD). Some examples: @@ -3032,18 +3026,18 @@ CSV Tips: - o Interpolation strips outer whitespace (so a CSV value like " 1 " be- + o Interpolation strips outer whitespace (so a CSV value like " 1 " be- comes 1 when interpolated) (#1051). - o Interpolations always refer to a CSV field - you can't interpolate a + o Interpolations always refer to a CSV field - you can't interpolate a hledger field. (See Referencing other fields below). Field names - Note the two kinds of field names mentioned here, and used only in + Note the two kinds of field names mentioned here, and used only in hledger CSV rules files: - 1. CSV field names (CSVFIELD in these docs): you can optionally name - the CSV columns for easy reference (since hledger doesn't yet auto- + 1. CSV field names (CSVFIELD in these docs): you can optionally name + the CSV columns for easy reference (since hledger doesn't yet auto- matically recognise column headings in a CSV file), by writing arbi- trary names in a fields list, eg: @@ -3098,86 +3092,69 @@ CSV Assigning to accountN, where N is 1 to 99, sets the account name of the Nth posting, and causes that posting to be generated. - 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 + 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, in conditional rules. - 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" + 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 field - Amount setting can get a bit complex. Assigning to amount is suffi- - cient for simple transactions, but there are four field name variants - you can use for different situations: + There are several ways to set posting amounts from CSV, useful in dif- + ferent situations. - o amountN sets a specific posting's amount from one CSV field or arbi- - trary value. - Assigning to amountN sets the amount of the Nth posting - and also - causes that posting to be generated. N is most often 1 or 2 but can go - up to 99, potentially generating a 99-posting transaction. (Posting - numbers don't have to be consecutive; higher posting numbers can some- - times be useful with conditional rules, to ensure a certain ordering of - postings.) + 1. amount is the oldest and simplest. Assigning to this sets the + amount of the first and second postings. In the second posting, the + amount will be negated; also, if it has a cost attached, it will be + converted to cost. - o amountN-in/-out sets a specific posting's amount from two CSV fields. - When the amount is provided as two CSV fields - "Debit"/"Credit", "De- - posit"/"Withdrawal", "Money In"/"Money Out" or similar - assign those - fields to amountN-in and amountN-out respectively (or possibly the - other way round, depending on signs). This will set the Nth posting's - amount to whichever of the two CSV field values is non-zero. Some - notes: + 2. amount-in and amount-out work exactly like the above, but should be + used when the CSV has two amount fields (such as "Debit" and + "Credit", or "Inflow" and "Outflow"). Whichever field has a non- + zero value will be used as the amount of the first and second post- + ings. Here are some tips to avoid confusion: - o Don't mix amountN and amountN-in/-out. When you have one CSV - amount field, use amountN. When you have two CSV amount fields, - use amountN-in/amountN-out. + o It's not "amount-in for posting 1 and amount-out for posting 2", + it is "extract a single amount from the amount-in or amount-out + field, and use that for posting 1 and (negated) for posting 2". - o amountN-in and amountN-out are always used together, as a pair. - Assign to both of them. + o Don't use both amount and amount-in/amount-out in the same rules + file; choose based on whether the amount is in a single CSV field + or spread across two fields. - o They do not generate two separate postings; rather, they generate - the Nth posting's single amount, from the value found in one or - other of the two CSV fields. + o In each record, at most one of the two CSV fields should contain + a non-zero amount; the other field must contain a zero or noth- + ing. - o In each record, at least one of the two CSV fields must contain a - zero amount or be empty. + o hledger assumes both CSV fields contain unsigned numbers, and it + automatically negates the amount-out values. - o hledger assumes the two CSV fields contain unsigned numbers, and it - will automatically negate the -out amount. + o If the data doesn't fit these requirements, you'll probably need + an if rule (see below). - o This variant can be convenient, but it doesn't handle every two- - amount-field situation; if you need more flexibility, use an if - rule (see "Setting amounts" below). + 3. amountN (where N is a number from 1 to 99) sets the amount of only a + single posting: the Nth posting in the transaction. You'll usually + need at least two such assignments to make a balanced transaction. + You can also generate more than two postings, to represent more com- + plex transactions. The posting numbers don't have to be consecu- + tive; with if rules, higher posting numbers can be useful to ensure + a certain order of postings. - The other two variants are older and considered legacy syntax, but can - still be convenient sometimes: + 4. amountN-in and amountN-out work exactly like the above, but should + be used when the CSV has two amount fields. This is analogous to + amount-in and amount-out, and those tips also apply here. - o amount sets posting 1 and 2's amounts from one CSV field or value. - Assigning to amount, with no posting number, + 5. Remember that a fields list can also do assignments. So in a fields + list if you name a CSV field "amount", that counts as assigning to + amount. (If you don't want that, call it something else in the + fields list, like "amount_".) - o sets posting 1's amount (like amount1) - - o sets posting 2's amount to the same amount but with opposite sign; - and also converts it to cost if it has a cost price - - o can be overridden by amount1 and/or amount2 assignments. (This - helps with incremental migration of old rules files to the newer - syntax.) - - o amount-in/-out sets posting 1 and 2's amounts from two CSV fields. - Assigning amount-in and amount-out, with no posting numbers, to two CSV - fields reads whichever of the two values is non-zero as the amount, and - then sets the first two posting amounts as above. - - We recommend using only one of these variants within a rules file, - rather than mixing them. And remember that a fields list can also do - assignments, so eg naming a CSV field "amount" counts as an assignment - to amount; if you don't want that, call it something else, like - "amount_". - - In addition to this section, please see also the tips beginning at - "Working with CSV > Setting amounts" below. + 6. The above don't handle every situation; if you need more flexibil- + ity, use an if rule to set amounts conditionally. See "Working with + CSV > Setting amounts" below for more on this and on amount-setting + generally. currency field currency sets a currency symbol, to be prepended to all postings' @@ -3193,20 +3170,20 @@ CSV balance is a compatibility spelling for hledger <1.17; it is equivalent to balance1. - You can adjust the type of assertion/assignment with the balance-type + You can adjust the type of assertion/assignment with the balance-type rule (see below). See Tips below for more about setting amounts and currency. if block - Rules can be applied conditionally, depending on patterns in the CSV - data. This allows flexibility; in particular, it is how you can cate- - gorise transactions, selecting an appropriate account name based on - their description (for example). There are two ways to write condi- - tional rules: "if blocks", described here, and "if tables", described + Rules can be applied conditionally, depending on patterns in the CSV + data. This allows flexibility; in particular, it is how you can cate- + gorise transactions, selecting an appropriate account name based on + their description (for example). There are two ways to write condi- + tional rules: "if blocks", described here, and "if tables", described below. - An if block is the word if and one or more "matcher" expressions (can + An if block is the word if and one or more "matcher" expressions (can be a word or phrase), one per line, starting either on the same or next line; followed by one or more indented rules. Eg, @@ -3337,7 +3314,7 @@ CSV balance-type Balance assertions generated by assigning to balanceN are of the simple - = type by default, which is a single-commodity, subaccount-excluding + = 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 @@ -3419,15 +3396,15 @@ CSV if needed. Reading CSV from standard input - You'll need the file format prefix when reading CSV from stdin also, + You'll need the file format prefix when reading CSV from stdin also, since hledger assumes journal format by default. Eg: $ cat foo.dat | hledger -f ssv:- print 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 + 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. Reading files specified by rule @@ -3438,7 +3415,7 @@ CSV browser's download directory. This feature was added in hledger 1.30, so you won't see it in most CSV - rules examples. But it helps remove some of the busywork of managing + rules examples. But it helps remove some of the busywork of managing CSV downloads. Most of your financial institutions's default CSV file- names are different and can be recognised by a glob pattern. So you can put a rule like source Checking1*.csv in foo-checking.csv.rules, @@ -3449,17 +3426,17 @@ CSV 2. Run hledger import foo-checking.csv.rules to import any new transac- tions - After import, you can: discard the CSV, or leave it where it is for a - while, or move it into your archives, as you prefer. If you do noth- - ing, next time your browser will save something like Checking1-2.csv, - and hledger will use that because of the * wild card and because it is + After import, you can: discard the CSV, or leave it where it is for a + while, or move it into your archives, as you prefer. If you do noth- + ing, next time your browser will save something like Checking1-2.csv, + and hledger will use that because of the * wild card and because it is the most recent. 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 + 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, @@ -3496,16 +3473,16 @@ CSV o https://plaintextaccounting.org -> data import/conversion Setting amounts - Continuing from amount field above, here are more tips on handling var- - ious amount-setting situations: + Continuing from amount field above, here are more tips for amount-set- + ting: 1. If the amount is in a single CSV field: a. If its sign indicates direction of flow: - Assign it to amountN, to set the Nth posting's amount. N is usu- + Assign it to amountN, to set the Nth posting's amount. N is usu- ally 1 or 2 but can go up to 99. b. If another field indicates direction of flow: - Use one or more conditional rules to set the appropriate amount + Use one or more conditional rules to set the appropriate amount sign. Eg: # assume a withdrawal unless Type contains "deposit": @@ -3513,18 +3490,18 @@ CSV if %Type deposit amount1 %Amount - 2. If the amount is in one of two CSV fields (eg Debit and Credit): + 2. If the amount is in two CSV fields (such as Debit and Credit, or In + and Out): a. If both fields are unsigned: - Assign the fields to amountN-in and amountN-out. This sets posting - N's amount to whichever of these has a non-zero value. If it's the - -out value, the amount will be negated. + Assign one field to amountN-in and the other to amountN-out. + hledger will automatically negate the "out" field, and will use + whichever field value is non-zero as posting N's amount. b. If either field is signed: - Use a conditional rule to flip the sign when needed. Eg below, the - -out value already has a minus sign so we undo hledger's automatic - negating by negating once more (but only if the field is non-empty, - so that we don't leave a minus sign by itself): + You will probably need to override hledger's sign for one or the + other field, as in the following example: + # Negate the -out value, but only if it is not empty: fields date, description, amount1-in, amount1-out if %amount1-out [1-9] amount1-out -%amount1-out @@ -3616,7 +3593,7 @@ CSV expenses:unknown 123.00 USD income:unknown -123.00 USD - Note we used a temporary field name (cur) that is not currency - that + Note we used a temporary field name (cur) that is not currency - that would trigger the prepending effect, which we don't want here. Amount decimal places @@ -3624,13 +3601,13 @@ CSV amount1 influence commodity display styles, such as the number of deci- mal places displayed in reports. - The original amounts as written in the CSV file do not affect display + The original amounts as written in the CSV file do not affect display style (because we don't yet reliably know their commodity). 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 + 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" @@ -3642,7 +3619,7 @@ CSV # 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- + Here, since there's no CSV amount1 field, %amount1 will produce a lit- eral "amount1": fields date,description,csvamount @@ -3650,7 +3627,7 @@ CSV # Can't interpolate amount1 here comment %amount1 - When there are multiple field assignments to the same hledger field, + 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: @@ -3681,30 +3658,30 @@ CSV 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 + 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 + 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- + o compute a value for each hledger field - either the one that was as- signed to it (and interpolate the %CSVFIELD references), or a default o generate a hledger transaction (journal entry) 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 + 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. Well factored rules - Some things than can help reduce duplication and complexity in rules + Some things than can help reduce duplication and complexity in rules files: - o Extracting common rules usable with multiple CSV files into a com- + o Extracting common rules usable with multiple CSV files into a com- mon.rules, and adding include common.rules to each CSV's rules file. o Splitting if blocks into smaller if blocks, extracting the frequently @@ -3783,7 +3760,7 @@ CSV 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 + 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" @@ -3835,7 +3812,7 @@ CSV expenses:fees $1.00 Paypal - Here's a real-world rules file for (customised) Paypal CSV, with some + 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" @@ -3986,12 +3963,12 @@ CSV Timeclock The time logging format of timeclock.el, as read by hledger. - hledger can read time logs in timeclock format. As with Ledger, these + 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). Lines beginning with + the time is always interpreted as a local time). Lines beginning with # or ; or *, and blank lines, are ignored. i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags: @@ -3999,9 +3976,9 @@ Timeclock 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 + 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 @@ -4022,7 +3999,7 @@ Timeclock 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- + 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 @@ -4030,18 +4007,18 @@ Timeclock `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 + rely on a "timeclock" executable which I think is just the ledger 2 executable renamed. Timedot - timedot format is hledger's human-friendly time logging format. Com- + timedot format is hledger's human-friendly time logging format. Com- pared to timeclock format, it is o convenient for quick, approximate, and retroactive time logging o readable: you can see at a glance where time was spent. - A timedot file contains a series of day entries, which might look like + A timedot file contains a series of day entries, which might look like this: 2023-05-01 @@ -4064,31 +4041,31 @@ Timedot A transaction begins with a non-indented simple date (Y-M-D, Y/M/D, or Y.M.D). It can optionally be preceded by one or more stars and a space, for Emacs org mode compatibility. It can optionally be followed - on the same line by a transaction description, and/or a transaction + on the same line by a transaction description, and/or a transaction comment following a semicolon. After the date line are zero or more time postings, consisting of: - o an account name - any hledger-style account name, optionally hierar- + o an account name - any hledger-style account name, optionally hierar- chical, optionally indented. - o two or more spaces - a field separator, required if there is an + o two or more spaces - a field separator, required if there is an amount (as in journal format). - o an optional timedot amount - dots representing quarter hours, or a + o an optional timedot amount - dots representing quarter hours, or a number representing hours, optionally with a unit suffix. o an optional posting comment following a semicolon. Timedot amounts can be: - o dots: zero or more period characters (.), each representing 0.25. + o dots: zero or more period characters (.), each representing 0.25. Spaces are ignored and can be used for grouping. Eg: .... .. o or a number. Eg: 1.5 - o or a number immediately followed by a unit symbol s, m, h, d, w, mo, - or y. These are interpreted as seconds, minutes, hours, days weeks, + o or a number immediately followed by a unit symbol s, m, h, d, w, mo, + or y. These are interpreted as seconds, minutes, hours, days weeks, months or years, and converted to hours, assuming: 60s = 1m, 60m = 1h, 24h = 1d, 7d = 1w, 30d = 1mo, 365d = 1y. Eg 90m is parsed as 1.5. @@ -4195,8 +4172,8 @@ Time periods 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, + 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 (below). @@ -4223,7 +4200,7 @@ Time periods (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- + date:2016/3/17.. the above written as queries instead (.. can also be re- placed with -) date:..12/1 date:thismonth.. @@ -4244,9 +4221,6 @@ Time periods 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 @@ -4277,7 +4251,7 @@ Time periods transaction rules, which are not affected by --today.) Report intervals - A report interval can be specified so that reports like register, bal- + A report interval can be specified so that reports like register, bal- ance or activity become multi-period, showing each subperiod as a sepa- rate row or column. @@ -4310,31 +4284,31 @@ Time periods last period the same length as the others. By contrast, start/end dates which have been specified explicitly, with - -b, -e, -p or date:, will not be adjusted (since hledger 1.29). This - makes it possible to specify non-standard report periods, but it also - means that if you are specifying a start date, you should pick one - that's on a period boundary if you want to see simple report period + -b, -e, -p or date:, will not be adjusted (since hledger 1.29). This + makes it possible to specify non-standard report periods, but it also + means that if you are specifying a start date, you should pick one + that's on a period boundary if you want to see simple report period headings. Period expressions - The -p/--period option specifies a period expression, which is a com- + The -p/--period option specifies a period expression, which is a com- pact way of expressing a start date, end date, and/or report interval. - Here's a period expression with a start and end date (specifying the + Here's a period expression with a start and end date (specifying the first quarter of 2009): -p "from 2009/1/1 to 2009/4/1" - Several keywords like "from" and "to" are supported for readability; - these are optional. "to" can also be written as ".." or "-". The spa- - ces are also optional, as long as you don't run two dates together. So - the following are equivalent to the above: + Several keywords like "from" and "to" are supported for readability; + these are optional. "to" can also be written as ".." or "-". The + spaces are also optional, as long as you don't run two dates together. + So the following 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, these are also + Dates are smart dates, so if the current year is 2009, these are also equivalent to the above: -p "1/1 4/1" @@ -4390,10 +4364,10 @@ Time periods Weekly on a custom day: - o every Nth day of week (th, nd, rd, or st are all accepted after the + o every Nth day of week (th, nd, rd, or st are all accepted after the number) - o every WEEKDAYNAME (full or three-letter english weekday name, case + o every WEEKDAYNAME (full or three-letter english weekday name, case insensitive) Monthly on a custom day: @@ -4406,7 +4380,7 @@ Time periods o every MM/DD [of year] (month number and day of month number) - o every MONTHNAME DDth [of year] (full or three-letter english month + o every MONTHNAME DDth [of year] (full or three-letter english month name, case insensitive, and day of month number) o every DDth MONTHNAME [of year] (equivalent to the above) @@ -4419,21 +4393,21 @@ Time periods 2009/03" -p "every 2nd day of week" periods will go from Tue to Tue -p "every Tue" same - -p "every 15th day" period boundaries will be on 15th of each + -p "every 15th day" period boundaries will be on 15th of each month - -p "every 2nd Monday" period boundaries will be on second Monday + -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 + -p "every 11/05" yearly periods with boundaries on 5th of November -p "every 5th November" same -p "every Nov 5th" same - Show historical balances at end of the 15th day of each month (N is an + Show historical balances at end of the 15th day of each month (N is an end date, exclusive as always): $ hledger balance -H -p "every 16th day" - Group postings from the start of wednesday to end of the following + Group postings from the start of wednesday to end of the following tuesday (N is both (inclusive) start date and (exclusive) end date): $ hledger register checking -p "every 3rd day of week" @@ -4462,9 +4436,9 @@ Time periods day" Depth - With the --depth NUM option (short form: -NUM), reports will show ac- - counts only to the specified depth, hiding deeper subaccounts. Use - this when you want a summary with less detail. This flag has the same + With the --depth NUM option (short form: -NUM), reports will show ac- + counts only to the specified depth, hiding deeper subaccounts. Use + this when you want a summary with less detail. This flag has the same effect as a depth: query argument: depth:2, --depth=2 or -2 are equiva- lent. @@ -4510,7 +4484,7 @@ Queries prefixed with not: to convert them into a negative match. acct:REGEX, REGEX - Match account names containing this (case insensitive) regular expres- + Match account names containing this (case insensitive) regular expres- sion. This is the default query type when there is no prefix, and reg- ular expression syntax is typically not needed, so usually we just write an account name substring, like expenses or food. @@ -4519,7 +4493,7 @@ Queries Match postings with a single-commodity amount equal to, less than, or greater than N. (Postings with multi-commodity amounts are not tested and will always match.) The comparison has two modes: if N is preceded - by a + or - sign (or is 0), the two signed numbers are compared. Oth- + by a + or - sign (or is 0), the two signed numbers are compared. Oth- erwise, the absolute magnitudes are compared, ignoring sign. code:REGEX @@ -4527,10 +4501,10 @@ Queries cur:REGEX Match postings or transactions including any amounts whose cur- - rency/commodity symbol is fully matched by REGEX. (For a partial - match, use .*REGEX.*). Note, to match special characters which are - regex-significant, you need to escape them with \. And for characters - which are significant to your shell you may need one more level of es- + rency/commodity symbol is fully matched by REGEX. (For a partial + match, use .*REGEX.*). Note, to match special characters which are + regex-significant, you need to escape them with \. And for characters + which are significant to your shell you may need one more level of es- caping. So eg to match the dollar sign: hledger print cur:\\$. @@ -4538,7 +4512,7 @@ Queries Match transaction descriptions. date:PERIODEXPR - Match dates (or with the --date2 flag, secondary dates) within the + Match dates (or with the --date2 flag, secondary dates) within the specified period. PERIODEXPR is a period expression with no report in- terval. Examples: date:2016, date:thismonth, date:2/1-2/15, date:2021-07-27..nextquarter. @@ -4560,7 +4534,7 @@ Queries whole description if there's no |). payee:REGEX - Match transaction payee/payer names (the part of the description left + Match transaction payee/payer names (the part of the description left of |, or the whole description if there's no |). real:, real:0 @@ -4570,8 +4544,8 @@ Queries Match unmarked, pending, or cleared transactions respectively. type:TYPECODES - Match by account type (see Declaring accounts > Account types). TYPE- - CODES is one or more of the single-letter account type codes ALERXCV, + Match by account type (see Declaring accounts > Account types). TYPE- + CODES is one or more of the single-letter account type codes ALERXCV, case insensitive. Note type:A and type:E will also match their respec- tive subtypes C (Cash) and V (Conversion). Certain kinds of account alias can disrupt account types, see Rewriting accounts > Aliases and @@ -4590,11 +4564,11 @@ Queries o Transactions also acquire the tags of their postings. (inacct:ACCTNAME - A special query term used automatically in hledger-web only: tells + A special query term used automatically in hledger-web only: tells hledger-web to show the transaction register for an account.) Combining query terms - When given multiple space-separated query terms, most commands select + When given multiple space-separated query terms, most commands select things which match: o any of the description terms AND @@ -4615,13 +4589,13 @@ Queries o match all the other terms. - We also support more complex boolean queries with the 'expr:' prefix. - This allows one to combine queries using one of three operators: AND, + We also support more complex boolean queries with the 'expr:' prefix. + This allows one to combine queries using one of three operators: AND, OR, and NOT, where NOT is different syntax for 'not:'. Examples of such queries are: - o Match transactions with 'cool' in the description AND with the 'A' + o Match transactions with 'cool' in the description AND with the 'A' tag expr:"desc:cool AND tag:A" @@ -4640,13 +4614,13 @@ Queries Queries and command options Some queries can also be expressed as command-line options: depth:2 is equivalent to --depth 2, date:2023 is equivalent to -p 2023, etc. When - you mix command options and query arguments, generally the resulting + you mix command options and query arguments, generally the resulting query is their intersection. Queries and valuation - When amounts are converted to other commodities in cost or value re- - ports, cur: and amt: match the old commodity symbol and the old amount - quantity, not the new ones (except in hledger 1.22.0 where it's re- + When amounts are converted to other commodities in cost or value re- + ports, cur: and amt: match the old commodity symbol and the old amount + quantity, not the new ones (except in hledger 1.22.0 where it's re- versed, see #1625). Querying with account aliases @@ -4656,19 +4630,19 @@ Queries Querying with cost or value When amounts are converted to other commodities in cost or value re- ports, note that cur: matches the new commodity symbol, and not the old - one, and amt: matches the new quantity, and not the old one. Note: - this changed in hledger 1.22, previously it was the reverse, see the + one, and amt: matches the new quantity, and not the old one. Note: + this changed in hledger 1.22, previously it was the reverse, see the discussion at #1625. Pivoting - Normally, hledger groups and sums amounts within each account. The - --pivot FIELD option substitutes some other transaction field for ac- - count names, causing amounts to be grouped and summed by that field's - value instead. FIELD can be any of the transaction fields acct, sta- - tus, code, desc, payee, note, or a tag name. When pivoting on a tag - and a posting has multiple values of that tag, only the first value is - displayed. Values containing colon:separated:parts will be displayed - hierarchically, like account names. Multiple, colon-delimited fields + Normally, hledger groups and sums amounts within each account. The + --pivot FIELD option substitutes some other transaction field for ac- + count names, causing amounts to be grouped and summed by that field's + value instead. FIELD can be any of the transaction fields acct, sta- + tus, code, desc, payee, note, or a tag name. When pivoting on a tag + and a posting has multiple values of that tag, only the first value is + displayed. Values containing colon:separated:parts will be displayed + hierarchically, like account names. Multiple, colon-delimited fields can be pivoted simultaneously, generating a hierarchical account name. Some examples: @@ -4700,7 +4674,7 @@ Pivoting -------------------- -2 EUR - Another way (the acct: query matches against the pivoted "account + Another way (the acct: query matches against the pivoted "account name"): $ hledger balance --pivot member acct:. @@ -4718,15 +4692,15 @@ Pivoting Generating data hledger has several features for generating data, such as: - o Periodic transaction rules can generate single or repeating transac- - tions following a template. These are usually dated in the future, - eg to help with forecasting. They are activated by the --forecast + o Periodic transaction rules can generate single or repeating transac- + tions following a template. These are usually dated in the future, + eg to help with forecasting. They are activated by the --forecast option. - o The balance command's --budget option uses these same periodic rules + o The balance command's --budget option uses these same periodic rules to generate goals for the budget report. - o Auto posting rules can generate extra postings on certain matched + o Auto posting rules can generate extra postings on certain matched transactions. They are always applied to forecast transactions; with the --auto flag they are applied to transactions recorded in the journal as well. @@ -4736,15 +4710,15 @@ Generating data @/@@ costs from conversion equity postings. Generated data of this kind is temporary, existing only at report time. - But you can see it in the output of hledger print, and you can save - that to your journal, in effect converting it from temporary generated - data to permanent recorded data. This could be useful as a data entry + But you can see it in the output of hledger print, and you can save + that to your journal, in effect converting it from temporary generated + data to permanent recorded data. This could be useful as a data entry aid. - If you are wondering what data is being generated and why, add the - --verbose-tags flag. In hledger print output you will see extra tags - like generated-transaction, generated-posting, and modified on gener- - ated/modified data. Also, even without --verbose-tags, generated data + If you are wondering what data is being generated and why, add the + --verbose-tags flag. In hledger print output you will see extra tags + like generated-transaction, generated-posting, and modified on gener- + ated/modified data. Also, even without --verbose-tags, generated data always has equivalen hidden tags (with an underscore prefix), so eg you could match generated transactions with tag:_generated-transaction. @@ -4765,13 +4739,13 @@ Forecasting change many forecasted transactions. (These same rules can also gener- ate budget goals, described in Budgeting.) - Forecast transactions usually start after ordinary transactions end. + Forecast transactions usually start after ordinary transactions end. By default, they begin after your latest-dated ordinary transaction, or today, whichever is later, and they end six months from today. (The exact rules are a little more complicated, and are given below.) This is the "forecast period", which need not be the same as the report - period. You can override it - eg to forecast farther into the future, + period. You can override it - eg to forecast farther into the future, or to force forecast transactions to overlap your ordinary transactions - by giving the --forecast option a period expression argument, like --forecast=..2099 or --forecast=2023-02-15... Note that the = is re- @@ -4812,7 +4786,7 @@ Forecasting expenses:rent $1000 Here there are no ordinary transactions, so the forecasted transactions - begin on the first occurence after today's date. (You won't normally + begin on the first occurence after today's date. (You won't normally use --today; it's just to make these examples reproducible.) Forecast reports @@ -4836,14 +4810,14 @@ Forecasting || $1000 $1000 $1000 $1000 $1000 Forecast tags - Forecast transactions generated by --forecast have a hidden tag, _gen- - erated-transaction. So if you ever need to match forecast transac- + Forecast transactions generated by --forecast have a hidden tag, _gen- + erated-transaction. So if you ever need to match forecast transac- tions, you could use tag:_generated-transaction (or just tag:generated) in a query. For troubleshooting, you can add the --verbose-tags flag. Then, visi- ble generated-transaction tags will be added also, so you can view them - with the print command. Their value indicates which periodic rule was + with the print command. Their value indicates which periodic rule was responsible. Forecast period, in detail @@ -4890,13 +4864,13 @@ Forecasting o Test with print --forecast. - o Check for typos or too-restrictive start/end dates in your periodic + o Check for typos or too-restrictive start/end dates in your periodic transaction rule. - o Leave at least 2 spaces between the rule's period expression and de- + o Leave at least 2 spaces between the rule's period expression and de- scription fields. - o Check for future-dated ordinary transactions suppressing forecasted + o Check for future-dated ordinary transactions suppressing forecasted transactions. o Try setting explicit report start and/or end dates with -b, -e, -p or @@ -4925,89 +4899,132 @@ Budgeting See also: Budgeting and Forecasting. Cost reporting - This section is about recording the cost of things, in transactions - where one commodity is exchanged for another. Eg an exchange of cur- - rency, or a stock purchase or sale. First, a quick glossary: + In some transactions - for example a currency conversion, or a purchase + or sale of stock - one commodity is exchanged for another. In these + transactions there is a conversion rate, also called the cost (when + buying) or selling price (when selling). In hledger docs we just say + "cost", for convenience; feel free to mentally translate to "conversion + rate" or "selling price" if helpful. - o Conversion - an exchange of one currency or commodity for another. - Eg a foreign currency exchange, or a purchase or sale of stock or - cryptocurrency. + Recording costs + We'll explore several ways of recording transactions involving costs. + These are also summarised at hledger Cookbook > Cost notation. - o Conversion transaction - a transaction involving one or more conver- - sions. + Costs can be recorded explicitly in the journal, using the @ UNITCOST + or @@ TOTALCOST notation described in Journal > Costs: - o Conversion rate - the cost per unit of one commodity in the other, ie - the exchange rate. - - o Cost - how much of one commodity was paid to acquire the other. And - more generally, in hledger docs: the amount exchanged in the "sec- - ondary" commodity (usually your base currency), whether in a purchase - or a sale, and whether expressed per unit or in total. Also, the - "@/@@ PRICE" notation used to represent this. - - -B: Convert to cost - As discussed in JOURNAL > Costs, when recording a transaction you can - also record the amount's cost in another commodity, by adding @ UNIT- - PRICE or @@ TOTALPRICE. - - Then you can see a report with amounts converted to cost, by adding the - -B/--cost flag. (Mnemonic: "B" from "cost Basis", as in Ledger). Eg: + Variant 1 2022-01-01 - assets:dollars $-135 ; 135 dollars is exchanged for.. - assets:euros 100 @ $1.35 ; one hundred euros purchased at $1.35 each + assets:dollars $-135 + assets:euros 100 @ $1.35 ; $1.35 per euro (unit cost) - $ hledger bal -N - $-135 assets:dollars - 100 assets:euros - $ hledger bal -N -B - $-135 assets:dollars - $135 assets:euros # <- the euros' cost - - Notes: - - -B is sensitive to the order of postings when a cost is inferred: the - inferred price will be in the commodity of the last amount. So if ex- - ample 3's postings are reversed, while the transaction is equivalent, - -B shows something different: + Variant 2 2022-01-01 - assets:dollars $-135 ; 135 dollars sold - assets:euros 100 ; for 100 euros + assets:dollars $-135 + assets:euros 100 @@ $135 ; $135 total cost - $ hledger bal -N -B - -100 assets:dollars # <- the dollars' selling price - 100 assets:euros + Typically, writing the unit cost (variant 1) is preferable; it can be + more effort, requiring more attention to decimal digits; but it reveals + the per-unit cost basis, and makes stock sales easier. - The @/@@ cost notation is convenient, but has some drawbacks: it does - not truly balance the transaction, so it disrupts the accounting equa- - tion and tends to causes a non-zero total in balance reports. + Costs can also be left implicit, and hledger will infer the cost that + is consistent with a balanced transaction: + + Variant 3 + + 2022-01-01 + assets:dollars $-135 + assets:euros 100 + + Here, hledger will attach a @@ 100 cost to the first amount (you can + see it with hledger print -x). This form looks convenient, but there + are downsides: + + o It sacrifices some error checking. For example, if you accidentally + wrote 10 instead of 100, hledger would not be able to detect the mis- + take. + + o It is sensitive to the order of postings - if they were reversed, a + different entry would be inferred and reports would be different. + + o The per-unit cost basis is not easy to read. + + So generally this kind of entry is not recommended. You can make sure + you have none of these by using -s (strict mode), or by running hledger + check balanced. + + Reporting at cost + Now when you add the -B/--cost flag to reports ("B" is from Ledger's + -B/--basis/--cost flag), any amounts which have been annotated with + costs will be converted to their cost's commodity (in the report out- + put). Ie they will be displayed "at cost" or "at sale price". + + Some things to note: + + o Costs are attached to specific posting amounts in specific transac- + tions, and once recorded they do not change. This contrasts with + market prices, which are ambient and fluctuating. + + o Conversion to cost is performed before conversion to market value + (described below). Equity conversion postings - By contrast, conventional double entry bookkeeping (DEB) uses a differ- - ent notation: an extra pair of equity postings to balance conversion - transactions. In this style, the above entry might be written: + There is a problem with the entries above - they are not conventional + Double Entry Bookkeeping (DEB) notation, and because of the "magical" + transformation of one commodity into another, they cause an imbalance + in the Accounting Equation. This shows up as a non-zero grand total in + balance reports like hledger bse. - 2022-01-01 one hundred euros purchased at $1.35 each + For most hledger users, this doesn't matter in practice and can safely + be ignored ! But if you'd like to learn more, keep reading. + + Conventional DEB uses an extra pair of equity postings to balance the + transaction. Of course you can do this in hledger as well: + + Variant 4 + + 2022-01-01 assets:dollars $-135 + assets:euros 100 equity:conversion $135 equity:conversion -100 - assets:euros 100 - This style is more correct, but it's also more verbose and makes cost - reporting more difficult for PTA tools. + Now the transaction is perfectly balanced according to standard DEB, + and hledger bse's total will not be disrupted. - Happily, current hledger can read either notation, or convert one to - the other when needed, so you can use the one you prefer. + And, hledger can still infer the cost for cost reporting, but it's not + done by default - you must add the --infer-costs flag like so: - You can even use cost notation and equivalent conversion postings at - the same time, for clarity. hledger will ignore the redundancy. But - be sure the cost and conversion posting amounts match, or you'll see a - not-so-clear transaction balancing error message. + $ hledger print --infer-costs + 2022-01-01 one hundred euros purchased at $1.35 each + assets:dollars $-135 @@ 100 + assets:euros 100 + equity:conversion $135 + equity:conversion -100 - Inferring equity postings from cost - With --infer-equity, hledger detects transactions written with PTA cost - notation and adds equity conversion postings to them: + $ hledger bal --infer-costs -B + -100 assets:dollars + 100 assets:euros + -------------------- + 0 + + Here are some downsides of this kind of entry: + + o The per-unit cost basis is not easy to read. + + o Instead of -B you must remember to type -B --infer-costs. + + o --infer-costs works only where hledger can identify the two eq- + uity:conversion postings and match them up with the two non-equity + postings. So writing the journal entry in a particular format be- + comes more important. More on this below. + + Inferring equity conversion postings + Can we go in the other direction ? Yes, if you have transactions writ- + ten with the @/@@ cost notation, hledger can infer the missing equity + postings, if you add the --infer-equity flag. Eg: 2022-01-01 assets:dollars -$135 @@ -5017,261 +5034,123 @@ Cost reporting 2022-01-01 assets:dollars $-135 assets:euros 100 @ $1.35 - equity:conversion:$-: -100 ; generated-posting: - equity:conversion:$-:$ $135.00 ; generated-posting: + equity:conversion:$-: -100 + equity:conversion:$-:$ $135.00 - The conversion account names can be changed with the conversion account - type declaration. + The equity account names will be "equity:conversion:A-B:A" and "eq- + uity:conversion:A-B:B" where A is the alphabetically first commodity + symbol. You can customise the "equity:conversion" part by declaring an + account with the V/Conversion account type. - --infer-equity is useful when when transactions have been recorded us- - ing cost notation, to help preserve the accounting equation and balance - reports' zero total, or to produce more conventional journal entries - for sharing with non-PTA-users. + Combining costs and equity conversion postings + Finally, you can use both the @/@@ cost notation and equity postings at + the same time. This in theory gives the best of all worlds - preserv- + ing the accounting equation, revealing the per-unit cost basis, and + providing more flexibility in how you write the entry: - Inferring cost from equity postings - The reverse operation is possible using --infer-costs, which detects - transactions written with equity conversion postings and adds cost no- - tation to them: + Variant 5 - 2022-01-01 - assets:dollars $-135 - equity:conversion $135 - equity:conversion -100 - assets:euros 100 + 2022-01-01 one hundred euros purchased at $1.35 each + assets:dollars $-135 + equity:conversion $135 + equity:conversion -100 + assets:euros 100 @ $1.35 - $ hledger print --infer-costs - 2022-01-01 - assets:dollars $-135 @@ 100 - equity:conversion $135 - equity:conversion -100 - assets:euros 100 + All the other variants above can (usually) be rewritten to this final + form with: - --infer-costs is useful when combined with -B/--cost, allowing cost re- - porting even when transactions have been recorded using equity post- - ings: + $ hledger print -x --infer-costs --infer-equity - $ hledger print --infer-costs -B - 2009-01-01 - assets:dollars -100 - assets:euros 100 + Downsides: - Notes: + o This was added in hledger-1.29 and is still somewhat experimental. - For --infer-costs to work, an exchange must consist of four postings: + o The precise format of the journal entry becomes more important. If + hledger can't detect and match up the cost and equity postings, it + will give a transaction balancing error. - 1. two non-equity postings + o The add command does not yet accept this kind of entry (#2056). - 2. two equity postings, next to one another + o This is the most verbose form. - 3. the equity accounts must be declared, with account type V/Conversion - (or if they are not declared, they must be named equity:conversion, - equity:trade, equity:trading or subaccounts of these) + Requirements for detecting equity conversion postings + --infer-costs has certain requirements (unlike --infer-equity, which + always works). It will infer costs only in transactions with: - 4. the equity postings' amounts must exactly match the non-equity post- - ings' amounts. + o Two non-equity postings, in different commodities. Their order is + significant: the cost will be added to the first of them. - Multiple such exchanges can coexist within a single transaction. + o Two postings to equity conversion accounts, next to one another, + which balance the two non-equity postings. This balancing is checked + to the same precision (number of decimal places) used in the conver- + sion posting's amount. Equity conversion accounts are: - When inferring cost, the order of postings matters: the cost is added - to the first of the non-equity postings involved in the exchange, in - the commodity of the last non-equity posting involved in the exchange. - If you don't want to write your postings in the required order, you can - use explicit cost notation instead. + o any accounts declared with account type V/Conversion, or their sub- + accounts - --infer-equity and --infer-costs can be used together, if you have a - mixture of both notations in your journal. + o otherwise, accounts named equity:conversion, equity:trade, or eq- + uity:trading, or their subaccounts. - When to infer cost/equity - Inferring equity postings or costs is still fairly new, so not enabled - by default. We're not sure yet if that should change. Here are two - suggestions to try, experience reports welcome: + And multiple such four-posting groups can coexist within a single + transaction. When --infer-costs fails, it does not infer a cost in + that transaction, and does not raise an error (ie, it infers costs + where it can). - 1. When you use -B, always use --infer-costs as well. Eg: hledger bal - -B --infer-costs + Reading variant 5 journal entries, combining cost notation and equity + postings, has all the same requirements. When reading such an entry + fails, hledger raises an "unbalanced transaction" error. - 2. Always run hledger with both flags enabled. Eg: alias hl="hledger - --infer-equity --infer-costs" + Infer cost and equity by default ? + Should --infer-costs and --infer-equity be enabled by default ? Try + using them always, eg with a shell alias: - How to record conversions - Essentially there are four ways to record a conversion transaction in - hledger. Here are all of them, with pros and cons. + alias h="hledger --infer-equity --infer-costs" - Conversion with implicit cost - Let's assume 100 EUR is converted to 120 USD. You can just record the - outflow (100 EUR) and inflow (120 USD) in the appropriate asset ac- - count: + and let us know what problems you find. - 2021-01-01 - assets:cash -100 EUR - assets:cash 120 USD - - hledger will assume this transaction is balanced, inferring that the - conversion rate must be 1 EUR = 1.20 USD. You can see the inferred - rate by using hledger print -x. - - Pro: - - o Concise, easy - - Con: - - o Less error checking - typos in amounts or commodity symbols may not - be detected - - o Conversion rate is not clear - - o Disturbs the accounting equation, unless you add the --infer-equity - flag - - You can prevent accidental implicit conversions due to a mistyped com- - modity symbol, by using hledger check commodities. - - You can prevent implicit conversions entirely, by using hledger check - balancednoautoconversion, or -s/--strict. - - Conversion with explicit cost - You can add the conversion rate using @ notation: - - 2021-01-01 - assets:cash -100 EUR @ 1.20 USD - assets:cash 120 USD - - Now hledger will check that 100 * 1.20 = 120, and would report an error - otherwise. - - Pro: - - o Still concise - - o Makes the conversion rate clear - - o Provides more error checking - - Con: - - o Disturbs the accounting equation, unless you add the --infer-equity - flag - - Conversion with equity postings - In strict double entry bookkeeping, the above transaction is not bal- - anced in EUR or in USD, since some EUR disappears, and some USD ap- - pears. This violates the accounting equation (A+L+E=0), and prevents - reports like balancesheetequity from showing a zero total. - - The proper way to make it balance is to add a balancing posting for - each commodity, using an equity account: - - 2021-01-01 - assets:cash -100 EUR - equity:conversion 100 EUR - equity:conversion -120 USD - assets:cash 120 USD - - Pro: - - o Preserves the accounting equation - - o Keeps track of conversions and related gains/losses in one place - - o Standard, works in any double entry accounting system - - Con: - - o More verbose - - o Conversion rate is not obvious - - o Cost reporting requires adding the --infer-costs flag - - Conversion with equity postings and explicit cost - Here both equity postings and @ notation are used together. - - 2021-01-01 - assets:cash -100 EUR @ 1.20 USD - equity:conversion 100 EUR - equity:conversion -120 USD - assets:cash 120 USD - - Pro: - - o Preserves the accounting equation - - o Keeps track of conversions and related gains/losses in one place - - o Makes the conversion rate clear - - o Provides more error checking - - Con: - - o Most verbose - - o Not compatible with ledger - - Cost tips - o Recording the cost/conversion rate explicitly is good because it - makes that clear and helps detect errors. - - o Recording equity postings is good because it is correct bookkeeping - and preserves the accounting equation. - - o Combining these is possible. - - o When you want to see the cost (or sale proceeds) of things, use -B - (short form of --cost). - - o If you use conversion postings without cost notation, add --infer- - costs also. - - o If you use cost notation without conversion postings, and you want to - see a balanced balance sheet or print correct journal entries, use - --infer-equity. - - o Conversion to cost is performed before valuation (described next). - -Valuation +Value reporting Instead of reporting amounts in their original commodity, hledger can convert them to cost/sale amount (using the conversion rate recorded in - the transaction), and/or to market value (using some market price on a - certain date). This is controlled by the --value=TYPE[,COMMODITY] op- - tion, which will be described below. We also provide the simpler -V + the transaction), and/or to market value (using some market price on a + certain date). This is controlled by the --value=TYPE[,COMMODITY] op- + tion, which will be described below. We also provide the simpler -V and -X COMMODITY options, and often one of these is all you need: -V: Value - The -V/--market flag converts amounts to market value in their default + 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 + 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 + 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 + 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 + For multiperiod reports, each column/period is valued on the last day of the period, by default. Finding market price - To convert a commodity A to its market value in another commodity B, - hledger looks for a suitable market price (exchange rate) as follows, + 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 + 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-market-prices flag) inferred from costs. 2. A reverse market price: the inverse of a declared or inferred market price from B to A. - 3. A forward chain of market prices: a synthetic price formed by com- + 3. 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. @@ -5300,16 +5179,16 @@ Valuation the same day, the P directive takes precedence. 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. + ing/undesired ways by your journal entries. If this happens to you, + read all of this Value reporting section carefully, and try adding + --debug or --debug=2 to troubleshoot. --infer-market-prices 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. + 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 multicommodity transactions with equity postings, if cost is inferred @@ -5326,8 +5205,8 @@ Valuation o --value=then,EUR --infer-market-prices, not --value=then --infer-mar- ket-prices - Signed costs and market prices can be confusing. For reference, here - is the current behaviour, since hledger 1.25. (If you think it should + Signed costs and market prices can be confusing. For reference, here + is the current behaviour, since hledger 1.25. (If you think it should work differently, see #1870.) 2022-01-01 Positive Unit prices @@ -5463,7 +5342,7 @@ Valuation 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. + 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. @@ -5560,7 +5439,7 @@ Valuation 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 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 @@ -5576,7 +5455,7 @@ Valuation b -0.50A Interaction of valuation and queries - When matching postings based on queries in the presence of valuation, + When matching postings based on queries in the presence of valuation, the following happens. 1. The query is separated into two parts: @@ -5626,12 +5505,6 @@ Valuation posting cost value at re- value at posting value at re- value at amounts port or date port or DATE/today journal end journal end - - - - - - summary summarised value at pe- sum of postings value at pe- value at posting cost riod ends in interval, val- riod ends DATE/today amounts ued at interval @@ -5645,8 +5518,8 @@ Valuation balance (bs, bse, cf, is) - balance sums of value at re- value at posting value at re- value at - changes costs port end or date port or DATE/today of + balance sums of value at re- value at posting value at re- value at + changes costs port end or date port or DATE/today of today of journal end sums of post- sums of of sums of ings postings postings @@ -5689,7 +5562,7 @@ Valuation (--bud- balances balances ances balances get) row to- sums, aver- sums, aver- sums, averages of sums, aver- sums, aver- - tals, row ages of dis- ages of dis- displayed values ages of dis- ages of dis- + tals, row ages of dis- ages of dis- displayed values ages of dis- ages of dis- averages played val- played val- played val- played values (-T, -A) ues ues ues column sums of dis- sums of dis- sums of displayed sums of dis- sums of dis- @@ -5809,7 +5682,7 @@ PART 4: COMMANDS ADD-ONS And here are some typical add-on commands. Some of these are installed - by the hledger-install script. If installed, they will appear in + by the hledger-install script. If installed, they will appear in hledger's commands list: o ui - run hledger's terminal UI @@ -5822,7 +5695,7 @@ PART 4: COMMANDS o stockquotes - download market prices from AlphaVantage - o Scripts and add-ons - check-fancyassertions, edit, fifo, git, move, + o Scripts and add-ons - check-fancyassertions, edit, fifo, git, move, pijul, plot, and more.. Next, each command is described in detail, in alphabetical order. @@ -5830,8 +5703,8 @@ PART 4: COMMANDS accounts Show account names. - This command lists account names. By default it shows all known ac- - counts, either used in transactions or declared with account direc- + This command lists account names. By default it shows all known ac- + counts, either used in transactions or declared with account direc- tives. With query arguments, only matched account names and account names ref- @@ -5842,19 +5715,19 @@ PART 4: COMMANDS the accounts used but not declared (--undeclared), or the first account matched by an account name pattern, if any (--find). - 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 components. Account names can be depth- + 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 components. Account names can be depth- clipped with depth:N or --depth N or -N. - With --types, it also shows each account's type, if it's known. (See + With --types, it also shows each account's type, if it's known. (See Declaring accounts > Account types.) - With --positions, it also shows the file and line number of each ac- - count's declaration, if any, and the account's overall declaration or- + With --positions, it also shows the file and line number of each ac- + count's declaration, if any, and the account's overall declaration or- der; these may be useful when troubleshooting account display order. - With --directives, it adds the account keyword, showing valid account + With --directives, it adds the account keyword, showing valid account directives which can be pasted into a journal file. This is useful to- gether with --undeclared when updating your account declarations to satisfy hledger check accounts. @@ -5907,24 +5780,24 @@ PART 4: COMMANDS import). 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 + 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 + 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, pay- - ees/descriptions, dates (yesterday, today, tomorrow). If the input + o The tab key will auto-complete whenever possible - accounts, pay- + ees/descriptions, 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 + 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. @@ -5933,7 +5806,7 @@ PART 4: COMMANDS 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 + o Input prompts are displayed in a different colour when the terminal supports it. Example (see https://hledger.org/add.html for a detailed tutorial): @@ -5963,13 +5836,13 @@ PART 4: COMMANDS Starting the next transaction (. or ctrl-D/ctrl-C to quit) Date [2015/05/22]: $ - On Microsoft Windows, the add command makes sure that no part of the + 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 (areg) - Show the transactions and running historical balance of a single ac- + Show the transactions and running historical balance of a single ac- count, with each transaction displayed as one line. aregister shows the overall transactions affecting a particular account @@ -5977,14 +5850,14 @@ PART 4: COMMANDS this account. Transactions before the report start date are always in- cluded in the running balance (--historical mode is always on). - This is a more "real world", bank-like view than the register command - (which shows individual postings, possibly from multiple accounts, not + This is a more "real world", bank-like view than the register command + (which shows individual postings, possibly from multiple accounts, not necessarily in historical mode). As a quick rule of thumb: - use areg- ister for reviewing and reconciling real-world asset/liability accounts - use register for reviewing detailed revenues/expenses. - aregister requires one argument: the account to report on. You can - write either the full account name, or a case-insensitive regular ex- + aregister requires one argument: the account to report on. You can + write either the full account name, or a case-insensitive regular ex- pression which will select the alphabetically first matched account. When there are multiple matches, the alphabetically-first choice can be @@ -6001,30 +5874,30 @@ PART 4: COMMANDS tions shown. Note some queries will disturb the running balance, caus- ing it to be different from the account's real-world running balance. - An example: this shows the transactions and historical running balance + An example: this shows the transactions and historical running balance during july, in the first account whose name contains "checking": $ hledger areg checking date:jul Each aregister line item shows: - o the transaction's date (or the relevant posting's date if different, + o the transaction's date (or the relevant posting's date if different, see below) - o the names of all the other account(s) involved in this transaction + o the names of all the other account(s) involved in this transaction (probably abbreviated) o the total change to this account's balance from this transaction o the account's historical running balance after this transaction. - Transactions making a net change of zero are not shown by default; add + Transactions making a net change of zero are not shown by default; add the -E/--empty flag to show them. - For performance reasons, column widths are chosen based on the first - 1000 lines; this means unusually wide values in later lines can cause - visual discontinuities as column widths are adjusted. If you want to - ensure perfect alignment, at the cost of more time and memory, use the + For performance reasons, column widths are chosen based on the first + 1000 lines; this means unusually wide values in later lines can cause + visual discontinuities as column widths are adjusted. If you want to + ensure perfect alignment, at the cost of more time and memory, use the --align-all flag. This command also supports the output destination and output format op- @@ -6037,8 +5910,8 @@ PART 4: COMMANDS 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 + 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. balance @@ -6046,8 +5919,8 @@ PART 4: COMMANDS Show accounts and their balances. - balance is one of hledger's oldest and most versatile commands, for - listing account balances, balance changes, values, value changes and + balance is one of hledger's oldest and most versatile commands, for + listing account balances, balance changes, values, value changes and more, during one time period or many. Generally it shows a table, with rows representing accounts, and columns representing periods. @@ -6057,8 +5930,8 @@ PART 4: COMMANDS trol, then use balance. balance features - Here's a quick overview of the balance command's features, followed by - more detailed descriptions and examples. Many of these work with the + Here's a quick overview of the balance command's features, followed by + more detailed descriptions and examples. Many of these work with the higher-level commands as well. balance can show.. @@ -6111,7 +5984,7 @@ PART 4: COMMANDS ..with.. - o totals (-T), averages (-A), percentages (-%), inverted sign (--in- + o totals (-T), averages (-A), percentages (-%), inverted sign (--in- vert) o rows and columns swapped (--transpose) @@ -6155,7 +6028,7 @@ PART 4: COMMANDS 0 Accounts with a zero balance (and no non-zero subaccounts, in tree mode - - see below) are hidden by default. Use -E/--empty to show them (re- + - see below) are hidden by default. Use -E/--empty to show them (re- vealing assets:bank:checking here): $ hledger -f examples/sample.journal bal -E @@ -6170,7 +6043,7 @@ PART 4: COMMANDS -------------------- 0 - The total of the amounts displayed is shown as the last line, unless + The total of the amounts displayed is shown as the last line, unless -N/--no-total is used. Balance report line format @@ -6204,14 +6077,14 @@ PART 4: COMMANDS 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 + 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- + 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) @@ -6228,18 +6101,18 @@ PART 4: COMMANDS o %(total) - the account's total - o %-20.20(account) - the account's name, left justified, padded to 20 + 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 + 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 + o %20(total) %2(depth_spacer)%-(account) - the default format for the single-column balance report Filtered balance report - You can show fewer accounts, a different time period, totals from + You can show fewer accounts, a different time period, totals from cleared transactions only, etc. by using query arguments or options to limit the postings being matched. Eg: @@ -6272,12 +6145,12 @@ PART 4: COMMANDS Notes: o "Boring" accounts are combined with their subaccount for more compact - output, unless --no-elide is used. Boring accounts have no balance - of their own and just one subaccount (eg assets:bank and liabilities + output, unless --no-elide is used. Boring accounts have no balance + of their own and just one subaccount (eg assets:bank and liabilities above). - o All balances shown are "inclusive", ie including the balances from - all subaccounts. Note this means some repetition in the output, + o All balances shown are "inclusive", ie including the balances from + all subaccounts. Note this means some repetition in the output, which requires explanation when sharing reports with non-plaintextac- counting-users. A tree mode report's final total is the sum of the top-level balances shown, not of all the balances shown. @@ -6314,8 +6187,8 @@ PART 4: COMMANDS $2 Showing declared accounts - With --declared, accounts which have been declared with an account di- - rective will be included in the balance report, even if they have no + With --declared, accounts which have been declared with an account di- + rective will be included in the balance report, even if they have no transactions. (Since they will have a zero balance, you will also need -E/--empty to see them.) @@ -6327,20 +6200,20 @@ PART 4: COMMANDS counts yet. Sorting by amount - With -S/--sort-amount, accounts with the largest (most positive) bal- - ances are shown first. Eg: hledger bal expenses -MAS shows your big- - gest averaged monthly expenses first. When more than one commodity is - present, they will be sorted by the alphabetically earliest commodity - first, and then by subsequent commodities (if an amount is missing a - commodity, it is treated as 0). + With -S/--sort-amount, accounts with the largest (most positive) bal- + ances are shown first. Eg: hledger bal expenses -MAS shows your + biggest averaged monthly expenses first. When more than one commodity + is present, they will be sorted by the alphabetically earliest commod- + ity first, and then by subsequent commodities (if an amount is missing + a commodity, it is treated as 0). - 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 higher-level reports, + 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 higher-level reports, which flip the sign automatically. Eg: hledger incomestatement -MAS). Percentages - With -%/--percent, balance reports show each account's value expressed + With -%/--percent, balance reports show each account's value expressed as a percentage of the (column) total. Note it is not useful to calculate percentages if the amounts in a col- @@ -6409,28 +6282,28 @@ PART 4: COMMANDS o Reduce the terminal's font size - o View with a pager like less, eg: hledger bal -D --color=yes | less + o View with a pager like less, eg: hledger bal -D --color=yes | less -RS - o Output as CSV and use a CSV viewer like visidata (hledger bal -D -O - csv | vd -f csv), Emacs' csv-mode (M-x csv-mode, C-c C-a), or a + o Output as CSV and use a CSV viewer like visidata (hledger bal -D -O + csv | vd -f csv), Emacs' csv-mode (M-x csv-mode, C-c C-a), or a spreadsheet (hledger bal -D -o a.csv && open a.csv) - o Output as HTML and view with a browser: hledger bal -D -o a.html && + o Output as HTML and view with a browser: hledger bal -D -o a.html && open a.html Balance change, end balance - It's important to be clear on the meaning of the numbers shown in bal- + It's important to be clear on the meaning of the numbers shown in bal- ance reports. Here is some terminology we use: - A balance change is the net amount added to, or removed from, an ac- + A balance change is the net amount added to, or removed from, an ac- count during some period. - An end balance is the amount accumulated in an account as of some date - (and some time, but hledger doesn't store that; assume end of day in + An end balance is the amount accumulated in an account as of some date + (and some time, but hledger doesn't store that; assume end of day in your timezone). It is the sum of previous balance changes. - We call it a historical end balance if it includes all balance changes + We call it a historical end balance if it includes all balance changes since the account was created. For a real world account, this means it will match the "historical record", eg the balances reported in your bank statements or bank web UI. (If they are correct!) @@ -6439,11 +6312,11 @@ PART 4: COMMANDS revenues and expenses, and historical end balances are what you want to see when reviewing or reconciling asset, liability and equity accounts. - balance shows balance changes by default. To see accurate historical + balance shows balance changes by default. To see accurate historical end balances: - 1. Initialise account starting balances with an "opening balances" - transaction (a transfer from equity to the account), unless the + 1. Initialise account starting balances with an "opening balances" + transaction (a transfer from equity to the account), unless the journal covers the account's full lifetime. 2. Include all of of the account's prior postings in the report, by not @@ -6452,14 +6325,14 @@ PART 4: COMMANDS ings.) Balance report types - The balance command is quite flexible; here is the full detail on how - to control what it reports. If the following seems complicated, don't - worry - this is for advanced reporting, and it does take time and ex- + The balance command is quite flexible; here is the full detail on how + to control what it reports. If the following seems complicated, don't + worry - this is for advanced reporting, and it does take time and ex- perimentation to get familiar with all the report modes. There are three important option groups: - hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE] + hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE] ... Calculation type @@ -6471,73 +6344,73 @@ PART 4: COMMANDS each account/period) o --valuechange : show the change in period-end historical balance val- - ues (caused by deposits, withdrawals, and/or market price fluctua- + ues (caused by deposits, withdrawals, and/or market price fluctua- tions) - o --gain : show the unrealised capital gain/loss, (the current valued + o --gain : show the unrealised capital gain/loss, (the current valued balance minus each amount's original cost) o --count : show the count of postings Accumulation type - How amounts should accumulate across report periods. Another way to - say it: which time period's postings should contribute to each cell's + How amounts should accumulate across report periods. Another way to + say it: which time period's postings should contribute to each cell's calculation. It is one of: - o --change : calculate with postings from column start to column end, - ie "just this column". Typically used to see revenues/expenses. + o --change : calculate with postings from column start to column end, + ie "just this column". Typically used to see revenues/expenses. (default for balance, incomestatement) - o --cumulative : calculate with postings from report start to column - end, ie "previous columns plus this column". Typically used to show + o --cumulative : calculate with postings from report start to column + end, ie "previous columns plus this column". Typically used to show changes accumulated since the report's start date. Not often used. - o --historical/-H : calculate with postings from journal start to col- - umn end, ie "all postings from before report start date until this - column's end". Typically used to see historical end balances of as- - sets/liabilities/equity. (default for balancesheet, balancesheete- + o --historical/-H : calculate with postings from journal start to col- + umn end, ie "all postings from before report start date until this + column's end". Typically used to see historical end balances of as- + sets/liabilities/equity. (default for balancesheet, balancesheete- quity, cashflow) Valuation type - Which kind of value or cost conversion should be applied, if any, be- + Which kind of value or cost conversion should be applied, if any, be- fore displaying the report. It is one of: o no valuation type : don't convert to cost or value (default) - o --value=cost[,COMM] : convert amounts to cost (then optionally to + o --value=cost[,COMM] : convert amounts to cost (then optionally to some other commodity) - o --value=then[,COMM] : convert amounts to market value on transaction + o --value=then[,COMM] : convert amounts to market value on transaction dates - o --value=end[,COMM] : convert amounts to market value on period end + o --value=end[,COMM] : convert amounts to market value on period end date(s) (default with --valuechange, --gain) o --value=now[,COMM] : convert amounts to market value on today's date - o --value=YYYY-MM-DD[,COMM] : convert amounts to market value on an- + o --value=YYYY-MM-DD[,COMM] : convert amounts to market value on an- other date or one of the equivalent simpler flags: - o -B/--cost : like --value=cost (though, note --cost and --value are + o -B/--cost : like --value=cost (though, note --cost and --value are independent options which can both be used at once) o -V/--market : like --value=end o -X COMM/--exchange COMM : like --value=end,COMM - See Cost reporting and Valuation for more about these. + See Cost reporting and Value reporting for more about these. Combining balance report types - Most combinations of these options should produce reasonable reports, - but if you find any that seem wrong or misleading, let us know. The + Most combinations of these options should produce reasonable reports, + but if you find any that seem wrong or misleading, let us know. The following restrictions are applied: o --valuechange implies --value=end - o --valuechange makes --change the default when used with the bal- + o --valuechange makes --change the default when used with the bal- ancesheet/balancesheetequity commands o --cumulative or --historical disables --row-total/-T @@ -6553,24 +6426,24 @@ PART 4: COMMANDS --change change in period sum of posting- period-end DATE-value of date market val- value of change change in pe- ues in period in period riod - --cumu- change from re- sum of posting- period-end DATE-value of - lative port start to date market val- value of change change from + --cumu- change from re- sum of posting- period-end DATE-value of + lative port start to date market val- value of change change from period end ues from report from report report start start to period start to period to period end end end --his- change from sum of posting- period-end DATE-value of - torical journal start to date market val- value of change change from - /-H period end (his- ues from journal from journal journal start + torical journal start to date market val- value of change change from + /-H period end (his- ues from journal from journal journal start torical end bal- start to period start to period to period end ance) end end Budget report The --budget report type activates extra columns showing any budget goals for each account and period. The budget goals are defined by pe- - riodic transactions. This is useful for comparing planned and actual + riodic transactions. This is useful for comparing planned and actual income, expenses, time usage, etc. - For example, you can take average monthly expenses in the common ex- + For example, you can take average monthly expenses in the common ex- pense categories to construct a minimal monthly budget: ;; Budget @@ -6615,25 +6488,25 @@ PART 4: COMMANDS ----------------------++---------------------------------------------------- || 0 [ 0] 0 [ 0] - This is different from a normal balance report in several ways. Cur- + This is different from a normal balance report in several ways. Cur- rently: - o Accounts with budget goals during the report period, and their par- + o Accounts with budget goals during the report period, and their par- ents, are shown. o Their subaccounts are not shown (regardless of the depth setting). - o Accounts without budget goals, if any, are aggregated and shown as + o Accounts without budget goals, if any, are aggregated and shown as "". - o Amounts are always inclusive (subaccount-including), even in list + o Amounts are always inclusive (subaccount-including), even in list mode. - o After each actual amount, the corresponding goal amount and percent- + o After each actual amount, the corresponding goal amount and percent- age of goal reached are also shown, in square brackets. - This means that the numbers displayed will not always add up! Eg - above, the expenses actual amount includes the gifts and supplies + This means that the numbers displayed will not always add up! Eg + above, the expenses actual amount includes the gifts and supplies transactions, but the expenses:gifts and expenses:supplies accounts are not shown, as they have no budget amounts declared. @@ -6694,10 +6567,10 @@ PART 4: COMMANDS 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 + 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 @@ -6716,9 +6589,9 @@ PART 4: COMMANDS --------------++------------ || $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 + 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 @@ -6731,7 +6604,7 @@ PART 4: COMMANDS || $400 [80% of $500] Budgets and subaccounts - You can add budgets to any account in your account hierarchy. If you + 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. @@ -6752,7 +6625,7 @@ PART 4: COMMANDS 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 + 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: @@ -6778,9 +6651,9 @@ PART 4: COMMANDS 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- + 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: @@ -6815,20 +6688,20 @@ PART 4: COMMANDS Selecting budget goals The budget report evaluates periodic transaction rules to generate spe- - cial "goal transactions", which generate the goal amounts for each ac- - count in each report subperiod. When troubleshooting, you can use + cial "goal transactions", which generate the goal amounts for each ac- + count in each report subperiod. When troubleshooting, you can use print --forecast to show these as forecasted transactions: $ hledger print --forecast=BUDGETREPORTPERIOD tag:generated - By default, the budget report uses all available periodic transaction - rules to generate goals. This includes rules with a different report - interval from your report. Eg if you have daily, weekly and monthly - periodic rules, all of these will contribute to the goals in a monthly + By default, the budget report uses all available periodic transaction + rules to generate goals. This includes rules with a different report + interval from your report. Eg if you have daily, weekly and monthly + periodic rules, all of these will contribute to the goals in a monthly budget report. - You can select a subset of periodic rules by providing an argument to - the --budget flag. --budget=DESCPAT will match all periodic rules + You can select a subset of periodic rules by providing an argument to + the --budget flag. --budget=DESCPAT will match all periodic rules whose description contains DESCPAT, a case-insensitive substring (not a regular expression or query). This means you can give your periodic rules descriptions (remember that two spaces are needed), and then se- @@ -6853,26 +6726,26 @@ PART 4: COMMANDS o forecast transactions are visible in any report, like ordinary trans- actions - o budget goal transactions are invisible except for the goal amounts + o budget goal transactions are invisible except for the goal amounts they produce in --budget reports. Periodic transaction rules: o --forecast uses all available periodic transaction rules - o --budget uses all periodic rules (--budget) or a selected subset + o --budget uses all periodic rules (--budget) or a selected subset (--budget=DESCPAT) Period of generated transactions: o --forecast generates forecast transactions - o from after the last regular transaction to the end of the report + o from after the last regular transaction to the end of the report period (--forecast) o or, during a specified period (--forecast=PERIODEXPR) - o possibly further restricted by a period specified in the periodic + o possibly further restricted by a period specified in the periodic transaction rule o and always restricted within the bounds of the report period @@ -6881,12 +6754,12 @@ PART 4: COMMANDS o throughout the report period - o possibly restricted by a period specified in the periodic transac- + o possibly restricted by a period specified in the periodic transac- tion rule. - Data layout - The --layout option affects how balance reports show multi-commodity - amounts and commodity symbols, which can improve readability. It can + Balance report layout + The --layout option affects how balance reports show multi-commodity + amounts and commodity symbols, which can improve readability. It can also normalise the data for easy consumption by other programs. It has four possible values: @@ -6898,10 +6771,10 @@ PART 4: COMMANDS o --layout=bare: commodity symbols are in their own column, amounts are bare numbers - o --layout=tidy: data is normalised to easily-consumed "tidy" form, + o --layout=tidy: data is normalised to easily-consumed "tidy" form, with one row per data value - Here are the --layout modes supported by each output format; note only + Here are the --layout modes supported by each output format; note only CSV output supports all of them: - txt csv html json sql @@ -6924,7 +6797,7 @@ PART 4: COMMANDS ------------------++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT - o Limited wide layout. A width limit reduces the width, but some com- + o Limited wide layout. A width limit reduces the width, but some com- modities will be hidden: $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32 @@ -6936,7 +6809,7 @@ PART 4: COMMANDS ------------------++--------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. - o Tall layout. Each commodity gets a new line (may be different in + o Tall layout. Each commodity gets a new line (may be different in each column), and account names are repeated: $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall @@ -6956,7 +6829,7 @@ PART 4: COMMANDS || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA || 18.00 VHT 294.00 VHT - o Bare layout. Commodity symbols are kept in one column, each commod- + o Bare layout. Commodity symbols are kept in one column, each commod- ity gets its own report row, account names are repeated: $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare @@ -6976,7 +6849,7 @@ PART 4: COMMANDS || VEA 12.00 10.00 14.00 36.00 || VHT 106.00 18.00 170.00 294.00 - o Bare layout also affects CSV output, which is useful for producing + o Bare layout also affects CSV output, which is useful for producing data that is easier to consume, eg for making charts: $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare @@ -6992,8 +6865,13 @@ PART 4: COMMANDS "total","VEA","36.00" "total","VHT","294.00" + o Note: bare layout will sometimes display an extra row for the no-sym- + bol commodity, because of zero amounts (hledger treats zeroes as com- + modity-less, usually). This can break hledger-bar confusingly + (workaround: add a cur: query to exclude the no-symbol row). + o Tidy layout produces normalised "tidy data", where every variable has - its own column and each row represents a single data point. See + its own column and each row represents a single data point. See https://cran.r-project.org/web/packages/tidyr/vignettes/tidy- data.html for more. This is the easiest kind of data for other soft- ware to consume. Here's how it looks: @@ -7020,25 +6898,25 @@ PART 4: COMMANDS Some frequently used balance options/reports are: o bal -M revenues expenses - Show revenues/expenses in each month. Also available as the incomes- + Show revenues/expenses in each month. Also available as the incomes- tatement command. o bal -M -H assets liabilities - Show historical asset/liability balances at each month end. Also + Show historical asset/liability balances at each month end. Also available as the balancesheet command. o bal -M -H assets liabilities equity - Show historical asset/liability/equity balances at each month end. + Show historical asset/liability/equity balances at each month end. Also available as the balancesheetequity command. o bal -M assets not:receivable - Show changes to liquid assets in each month. Also available as the + Show changes to liquid assets in each month. Also available as the cashflow command. Also: o bal -M expenses -2 -SA - Show monthly expenses summarised to depth 2 and sorted by average + Show monthly expenses summarised to depth 2 and sorted by average amount. o bal -M --budget expenses @@ -7054,7 +6932,7 @@ PART 4: COMMANDS balancesheet (bs) - This command displays a balance sheet, showing historical ending bal- + 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. @@ -7086,9 +6964,9 @@ PART 4: COMMANDS 0 This command is a higher-level variant of the balance command, and sup- - ports many of that command's features, such as multi-period reports. - It is similar to hledger balance -H assets liabilities, but with - smarter account detection, and liabilities displayed with their sign + ports many of that command's features, such as multi-period reports. + It is similar to hledger balance -H assets liabilities, but with + smarter account detection, and liabilities displayed with their sign flipped. This command also supports the output destination and output format op- @@ -7134,27 +7012,27 @@ PART 4: COMMANDS 0 This command is a higher-level variant of the balance command, and sup- - ports many of that command's features, such as multi-period reports. + ports many of that command's features, such as multi-period reports. It is similar to hledger balance -H assets liabilities equity, but with smarter account detection, and liabilities/equity displayed with their sign flipped. This command also supports the output destination and output format op- - tions The output formats supported are txt, csv, html, and (experimen- + tions The output formats supported are txt, csv, html, and (experimen- tal) json. cashflow (cf) - This command displays a cashflow statement, showing the inflows and - outflows affecting "cash" (ie, liquid, easily convertible) assets. - Amounts are shown with normal positive sign, as in conventional finan- + This command displays a cashflow statement, showing the inflows and + outflows affecting "cash" (ie, liquid, easily convertible) assets. + Amounts are shown with normal positive sign, as in conventional finan- cial statements. - This report shows accounts declared with the Cash type (see account + This report shows accounts declared with the Cash type (see account types). Or if no such accounts are declared, it shows accounts - o under a top-level account named asset (case insensitive, plural al- + o under a top-level account named asset (case insensitive, plural al- lowed) o whose name contains some variation of cash, bank, checking or saving. @@ -7183,8 +7061,8 @@ PART 4: COMMANDS $-1 This command is a higher-level variant of the balance command, and sup- - ports many of that command's features, such as multi-period reports. - It is similar to hledger balance assets not:fixed not:investment + ports many of that command's features, such as multi-period reports. + It is similar to hledger balance assets not:fixed not:investment not:receivable, but with smarter account detection. This command also supports the output destination and output format op- @@ -7217,11 +7095,11 @@ PART 4: COMMANDS o parseable - data files are well-formed and can be successfully parsed - o balancedwithautoconversion - all transactions are balanced, inferring - missing amounts where necessary, and possibly converting commodities - using costs or automatically-inferred costs + o autobalanced - all transactions are balanced, after converting to + cost. Missing amounts and missing costs are inferred automatically + where possible. - o assertions - all balance assertions in the journal are passing. + o assertions - all balance assertions in the journal are passing. (This check can be disabled with -I/--ignore-assertions.) Strict checks @@ -7233,33 +7111,34 @@ PART 4: COMMANDS o commodities - all commodity symbols used have been declared - o balancednoautoconversion - transactions are balanced, possibly using - explicit costs but not inferred ones + o balanced - all transactions are balanced after converting to cost, + without inferring missing costs. If conversion costs are required, + they must be explicit. Other checks - These checks can be run only by giving their names as arguments to - check. They are more specialised and not desirable for everyone, + These checks can be run only by giving their names as arguments to + check. They are more specialised and not desirable for everyone, therefore optional: o ordereddates - transactions are ordered by date within each file o payees - all payees used by transactions have been declared - o recentassertions - all accounts with balance assertions have a bal- - ance assertion no more than 7 days before their latest posting + o recentassertions - all accounts with balance assertions have a bal- + ance assertion within 7 days of their latest posting o tags - all tags used by transactions have been declared o uniqueleafnames - all account leaf names are unique Custom checks - A few more checks are are available as separate add-on commands, in + A few more checks are are available as separate add-on commands, in https://github.com/simonmichael/hledger/tree/master/bin: - o hledger-check-tagfiles - all tag values containing / (a forward + o hledger-check-tagfiles - all tag values containing / (a forward slash) exist as file paths - o hledger-check-fancyassertions - more complex balance assertions are + o hledger-check-fancyassertions - more complex balance assertions are passing You could make similar scripts to perform your own custom checks. See: @@ -7267,26 +7146,26 @@ PART 4: COMMANDS More about specific checks hledger check recentassertions will complain if any balance-asserted - account does not have a balance assertion within 7 days before its lat- - est posting. This aims to prevent the situation where you are regu- - larly updating your journal, but forgetting to check your balances - against the real world, then one day must dig back through months of - data to find an error. It assumes that adding a balance assertion re- - quires/reminds you to check the real-world balance. That may not be - true if you auto-generate balance assertions from bank data; in that - case, I recommend to import transactions uncleared, then use the man- - ual-review-and-mark-cleared phase as a reminder to check the latest as- - sertions against real-world balances. + account has postings more than 7 days after its latest balance asser- + tion. This aims to prevent the situation where you are regularly up- + dating your journal, but forgetting to check your balances against the + real world, then one day must dig back through months of data to find + an error. It assumes that adding a balance assertion requires/reminds + you to check the real-world balance. (That may not be true if you + auto-generate balance assertions from bank data; in that case, I recom- + mend to import transactions uncleared, and when you manually review and + clear them, also check the latest assertion against the real-world bal- + ance.) close (equity) - Generate transactions which transfer account balances to and/or from - another account (typically equity). This can be useful for migrating - balances to a new journal file, or for merging earnings into equity at + Generate transactions which transfer account balances to and/or from + another account (typically equity). This can be useful for migrating + balances to a new journal file, or for merging earnings into equity at end of accounting period. - By default, it prints a transaction that zeroes out ALE accounts (as- + By default, it prints a transaction that zeroes out ALE accounts (as- set, liability, equity accounts; this requires account types to be con- figured); or if ACCTQUERY is provided, the accounts matched by that. @@ -7312,15 +7191,15 @@ PART 4: COMMANDS other out, preserving correct balances during multi-file reporting. 4. With --retain, it prints a "retain earnings" transaction that trans- - fers RX (revenue and expense) balances to equity:retained earnings. - Businesses traditionally do this at the end of each accounting pe- - riod; it is less necessary with computer-based accounting, but it - could still be useful if you want to see the accounting equation + fers RX (revenue and expense) balances to equity:retained earnings. + Businesses traditionally do this at the end of each accounting pe- + riod; it is less necessary with computer-based accounting, but it + could still be useful if you want to see the accounting equation (A=L+E) satisfied. In all modes, the defaults can be overridden: - o the transaction descriptions can be changed with --close-desc=DESC + o the transaction descriptions can be changed with --close-desc=DESC and --open-desc=DESC o the account to transfer to/from can be changed with --close-acct=ACCT @@ -7337,42 +7216,42 @@ PART 4: COMMANDS explicitly, and if it involves multiple commodities, a separate posting will be generated for each of them (similar to print -x). - With --show-costs, any amount costs are shown, with separate postings + With --show-costs, any amount costs are shown, with separate postings for each cost. This is currently the best way to view investment lots. If you have many currency conversion or investment transactions, it can generate very large journal entries. - With --interleaved, each individual transfer is shown with source and - destination postings next to each other. This could be useful for + With --interleaved, each individual transfer is shown with source and + destination postings next to each other. This could be useful for troubleshooting. - The default closing date is yesterday, or the journal's end date, - whichever is later. You can change this by specifying a report end - date with -e. The last day of the report period will be the closing - date, eg -e 2024 means "close on 2023-12-31". The opening date is al- + The default closing date is yesterday, or the journal's end date, + whichever is later. You can change this by specifying a report end + date with -e. The last day of the report period will be the closing + date, eg -e 2024 means "close on 2023-12-31". The opening date is al- ways the day after the closing date. close and balance assertions - Balance assertions will be generated, verifying that the accounts have - been reset to zero (and then restored to their previous balances, if + Balance assertions will be generated, verifying that the accounts have + been reset to zero (and then restored to their previous balances, if there is an opening transaction). - These provide useful error checking, but you can ignore them temporar- + These provide useful error checking, but you can ignore them temporar- ily with -I, or remove them if you prefer. - You probably should avoid filtering transactions by status or realness - (-C, -R, status:), or generating postings (--auto), with this command, + You probably should avoid filtering transactions by status or realness + (-C, -R, status:), or generating postings (--auto), with this command, since the balance assertions would depend on these. - Note custom posting dates spanning the file boundary will disrupt the + Note custom posting dates spanning the file boundary will disrupt the balance assertions: 2023-12-30 a purchase made in december, cleared in january expenses:food 5 assets:bank:checking -5 ; date: 2023-01-02 - To solve that you can transfer the money to and from a temporary ac- - count, in effect splitting the multi-day transaction into two single- + To solve that you can transfer the money to and from a temporary ac- + count, in effect splitting the multi-day transaction into two single- day transactions: ; in 2022.journal: @@ -7459,9 +7338,9 @@ PART 4: COMMANDS 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 + 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 @@ -7514,10 +7393,10 @@ PART 4: COMMANDS eg -s4 to play at 4x original speed or -s.5 to play at half speed. The default speed is 2x. - Other asciinema options can be added following a double dash, eg -- + Other asciinema options can be added following a double dash, eg -- -i.1 to limit pauses or -- -h to list asciinema's other options. - During playback, several keys are available: SPACE to pause/unpause, . + During playback, several keys are available: SPACE to pause/unpause, . to step forward (while paused), CTRL-c quit. Examples: @@ -7569,13 +7448,13 @@ PART 4: COMMANDS These transactions are in the second file only: files - List all files included in the journal. With a REGEX argument, only + List all files included in the journal. With a REGEX argument, only file names matching the regular expression (case sensitive) are shown. help - Show the hledger user manual in the terminal, with info, man, or a - pager. With a TOPIC argument, open it at that topic if possible. - TOPIC can be any heading in the manual, or a heading prefix, case in- + Show the hledger user manual in the terminal, with info, man, or a + pager. With a TOPIC argument, open it at that topic if possible. + TOPIC can be any heading in the manual, or a heading prefix, case in- sensitive. Eg: commands, print, forecast, journal, amount, "auto post- ings". @@ -7590,9 +7469,9 @@ PART 4: COMMANDS found, or the command is run non-interactively, it just prints the man- ual to stdout. - If using info, note that version 6 or greater is needed for TOPIC - lookup. If you are on mac you will likely have info 4.8, and should - consider installing a newer version, eg with brew install texinfo + If using info, note that version 6 or greater is needed for TOPIC + lookup. If you are on mac you will likely have info 4.8, and should + consider installing a newer version, eg with brew install texinfo (#1770). Examples @@ -7603,17 +7482,17 @@ PART 4: COMMANDS $ hledger help -m journal # show it with man, even if info is installed import - Read new transactions added to each FILE since last run, and add them - to the journal. Or with --dry-run, just print the transactions that - would be added. Or with --catchup, just mark all of the FILEs' trans- + Read new transactions added to each FILE since last run, and add them + to the journal. Or with --dry-run, just print the transactions that + would be added. Or with --catchup, just mark all of the FILEs' trans- actions as imported, without actually importing any. - This command may append new transactions to the main journal file - (which should be in journal format). Existing transactions are not - changed. This is one of the few hledger commands that writes to the + This command may append new transactions to the main journal file + (which should be in journal format). Existing transactions are not + changed. This is one of the few hledger commands that writes to the journal file (see also add). - Unlike other hledger commands, with import the journal file is an out- + Unlike other hledger commands, with import the journal file is an out- put file, and will be modified, though only by appending (existing data will not be changed). The input files are specified as arguments, so to import one or more CSV files to your main journal, you will run @@ -7623,10 +7502,10 @@ PART 4: COMMANDS common import source, and these docs focus on that case. Deduplication - As a convenience import does deduplication while reading transactions. + As a convenience import does deduplication while reading transactions. This does not mean "ignore transactions that look the same", but rather "ignore transactions that have been seen before". This is intended for - when you are periodically importing foreign data which may contain al- + when you are periodically importing foreign data which may contain al- ready-imported transactions. So eg, if every day you download bank CSV files containing redundant data, you can safely run hledger import bank.csv and only new transactions will be imported. (import is idem- @@ -7646,25 +7525,27 @@ PART 4: COMMANDS These are often true of CSV files representing transactions, or true enough so that it works pretty well in practice. 1 is important, but violations of 2 and 3 amongst the old transactions won't matter (and if - you import often, the new transactions will be few, so less likely to + you import often, the new transactions will be few, so less likely to be the ones affected). - hledger remembers the latest date processed in each input file by sav- + hledger remembers the latest date processed in each input file by sav- ing a hidden ".latest" state file in the same directory. Eg when read- ing finance/bank.csv, it will look for and update the finance/.lat- est.bank.csv state file. The format is simple: one or more lines con- - taining the same ISO-format date (YYYY-MM-DD), meaning "I have pro- - cessed transactions up to this date, and this many of them on that + taining the same ISO-format date (YYYY-MM-DD), meaning "I have + processed transactions up to this date, and this many of them on that date." Normally you won't see or manipulate these state files yourself. - But if needed, you can delete them to reset the state (making all - transactions "new"), or you can construct them to "catch up" to a cer- + But if needed, you can delete them to reset the state (making all + transactions "new"), or you can construct them to "catch up" to a cer- tain date. - Note deduplication (and updating of state files) can also be done by + Note deduplication (and updating of state files) can also be done by print --new, but this is less often used. + Related: CSV > Working with CSV > Deduplicating, importing. + Import testing - With --dry-run, the transactions that will be imported are printed to + With --dry-run, the transactions that will be imported are printed to the terminal, without updating your journal or state files. The output is valid journal format, like the print command, so you can re-parse it. Eg, to see any importable transactions which CSV rules have not @@ -7688,12 +7569,12 @@ PART 4: COMMANDS 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 + 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, + (If you think import should leave amounts implicit like print does, please test it and send a pull request.) Commodity display styles @@ -7707,9 +7588,9 @@ PART 4: COMMANDS penses during one or more periods. Amounts are shown with normal posi- tive sign, as in conventional financial statements. - This report shows accounts declared with the Revenue or Expense type - (see account types). Or if no such accounts are declared, it shows - top-level accounts named revenue or income or expense (case insensi- + This report shows accounts declared with the Revenue or Expense type + (see account types). Or if no such accounts are declared, it shows + top-level accounts named revenue or income or expense (case insensi- tive, plurals allowed) and their subaccounts. Example: @@ -7738,7 +7619,7 @@ PART 4: COMMANDS This command is a higher-level variant of the balance command, and sup- ports many of that command's features, such as multi-period reports. It is similar to hledger balance '(revenues|income)' expenses, but with - smarter account detection, and revenues/income displayed with their + smarter account detection, and revenues/income displayed with their sign flipped. This command also supports the output destination and output format op- @@ -7749,8 +7630,8 @@ PART 4: COMMANDS 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 | + 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: @@ -7762,14 +7643,14 @@ PART 4: COMMANDS payees List the unique payee/payer names that appear in transactions. - This command lists unique payee/payer names which have been declared - with payee directives (--declared), used in transaction descriptions + This command lists unique payee/payer names which have been declared + with payee directives (--declared), used in transaction descriptions (--used), or both (the default). - The payee/payer is the part of the transaction description before a | + The payee/payer is the part of the transaction description before a | character (or if there is no |, the whole description). - You can add query arguments to select a subset of transactions. This + You can add query arguments to select a subset of transactions. This implies --used. Example: @@ -7780,7 +7661,7 @@ PART 4: COMMANDS Person A prices - Print market price directives from the journal. With --infer-market- + Print market price directives from the journal. With --infer-market- prices, generate additional market prices from costs. With --infer-re- verse-prices, also generate market prices by inverting known prices. Prices can be filtered by a query. Price amounts are displayed with @@ -7792,15 +7673,15 @@ PART 4: COMMANDS The print command displays full journal entries (transactions) from the journal file, sorted by date (or with --date2, by secondary date). - Amounts are shown mostly normalised to commodity display style, eg the - placement of commodity symbols will be consistent. All of their deci- + Amounts are shown mostly normalised to commodity display style, eg the + placement of commodity symbols will be consistent. All of their deci- mal places are shown, as in the original journal entry (with one alter- ation: in some cases trailing zeroes are added.) Amounts are shown right-aligned within each transaction (but not across all transactions). - Directives and inter-transaction comments are not shown, currently. + Directives and inter-transaction comments are not shown, currently. This means the print command is somewhat lossy, and if you are using it to reformat your journal you should take care to also copy over the di- rectives and file-level comments. @@ -7829,7 +7710,7 @@ PART 4: COMMANDS liabilities:debts $1 assets:bank:checking $-1 - print's output is usually a valid hledger journal, and you can process + 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: @@ -7839,8 +7720,8 @@ PART 4: COMMANDS There are some situations where print's output can become unparseable: - o Valuation affects posting amounts but not balance assertion or bal- - ance assignment amounts, potentially causing those to fail. + o Value reporting affects posting amounts but not balance assertion or + balance assignment amounts, potentially causing those to fail. o Auto postings can generate postings with too many missing amounts. @@ -7874,7 +7755,7 @@ PART 4: COMMANDS mand. (See import's docs for details.) This command also supports the output destination and output format op- - tions The output formats supported are txt, csv, and (experimental) + tions The output formats supported are txt, csv, and (experimental) json and sql. Here's an example of print's CSV output: @@ -7893,7 +7774,7 @@ PART 4: COMMANDS "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 + 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 @@ -7905,8 +7786,8 @@ PART 4: COMMANDS (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 + 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.) register @@ -7922,7 +7803,7 @@ PART 4: COMMANDS 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 + It is typically used with a query selecting a particular account, to see that account's activity: $ hledger register checking @@ -7933,14 +7814,14 @@ PART 4: COMMANDS With --date2, it shows and sorts by secondary date instead. - For performance reasons, column widths are chosen based on the first - 1000 lines; this means unusually wide values in later lines can cause - visual discontinuities as column widths are adjusted. If you want to - ensure perfect alignment, at the cost of more time and memory, use the + For performance reasons, column widths are chosen based on the first + 1000 lines; this means unusually wide values in later lines can cause + visual discontinuities as column widths are adjusted. If you want to + ensure perfect alignment, at the cost of more time and memory, use the --align-all flag. - The --historical/-H flag adds the balance from any undisplayed prior - postings to the running total. This is useful when you want to see + 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 @@ -7950,7 +7831,7 @@ PART 4: COMMANDS The --depth option limits the amount of sub-account detail displayed. - The --average/-A flag shows the running average posting amount instead + 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- @@ -7961,7 +7842,7 @@ PART 4: COMMANDS 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- + bers. It's also useful to show postings on the checking account to- gether with the related account: $ hledger register --related --invert assets:checking @@ -8032,7 +7913,7 @@ PART 4: COMMANDS $ 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) + tions The output formats supported are txt, csv, and (experimental) json. rewrite @@ -8041,7 +7922,7 @@ PART 4: COMMANDS --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 + 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. @@ -8072,7 +7953,7 @@ PART 4: COMMANDS 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- + 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. @@ -8093,7 +7974,7 @@ PART 4: COMMANDS budget:gifts *-1 assets:budget *1 - Note that '=' (equality symbol) that is used instead of date in trans- + 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. @@ -8172,21 +8053,21 @@ PART 4: COMMANDS could be an empty query (--pnl "" or --pnl STR where STR does not match any of your accounts). - 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 + 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. - Price directives will be taken into account if you supply appropriate + Price directives will be taken into account if you supply appropriate --cost or --value flags (see VALUATION). 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- + 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 + 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. @@ -8217,9 +8098,9 @@ PART 4: COMMANDS to your investment. Transactions not matching --inv will be ignored. In these transactions, ROI will conside postings that match --inv to be - "investment postings" and other postings (not matching --inv) will be - sorted into two categories: "cash flow" and "profit and loss", as ROI - needs to know which part of the investment value is your contributions + "investment postings" and other postings (not matching --inv) will be + sorted into two categories: "cash flow" and "profit and loss", as ROI + needs to know which part of the investment value is your contributions and which is due to the return on investment. o "Cash flow" is depositing or withdrawing money, buying or selling as- @@ -8267,7 +8148,7 @@ PART 4: COMMANDS 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 + 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. @@ -8275,15 +8156,15 @@ PART 4: COMMANDS 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 a compound annual rate of return that investment is + 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 a compound annual rate of return that investment is expected to generate. - As mentioned before, in-flows and out-flows would be any cash that you + 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 the postings that match the query in the--inv argument and NOT match the query in the--pnl argument. @@ -8302,7 +8183,7 @@ PART 4: COMMANDS discounted cash flow analysis before. Implementation of IRR in hledger should produce results that match the XIRR formula in Excel. - Second way to compute rate of return that roi command implements is + 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, out-flows and value changes, to compute rate of return per each period @@ -8312,7 +8193,7 @@ PART 4: COMMANDS 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 + in "unit price" over the reporting period gives you rate of return of your investment. References: @@ -8323,21 +8204,21 @@ PART 4: COMMANDS o Explanation of TWR - o Examples of computing IRR and TWR and discussion of the limitations + o Examples of computing IRR and TWR and discussion of the limitations of both metrics stats Show journal and performance 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 + 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. - At the end, it shows (in the terminal) the overall run time and number - of transactions processed per second. Note these are approximate and - will vary based on machine, current load, data size, hledger version, - haskell lib versions, GHC version.. but they may be of interest. The - stats command's run time is similar to that of a single-column balance + At the end, it shows (in the terminal) the overall run time and number + of transactions processed per second. Note these are approximate and + will vary based on machine, current load, data size, hledger version, + haskell lib versions, GHC version.. but they may be of interest. The + stats command's run time is similar to that of a single-column balance report. Example: @@ -8367,22 +8248,22 @@ PART 4: COMMANDS This command lists the tag names used in the journal, whether on trans- actions, postings, or account declarations. - With a TAGREGEX argument, only tag names matching this regular expres- + With a TAGREGEX argument, only tag names matching this regular expres- sion (case insensitive, infix matched) are shown. - With QUERY arguments, only transactions and accounts matching this + With QUERY arguments, only transactions and accounts matching this query are considered. If the query involves transaction fields (date:, desc:, amt:, ...), the search is restricted to the matched transactions and their accounts. - With the --values flag, the tags' unique non-empty values are listed + With the --values flag, the tags' unique non-empty values are listed instead. With -E/--empty, blank/empty values are also shown. - With --parsed, tags or values are shown in the order they were parsed, - with duplicates included. (Except, tags from account declarations are + With --parsed, tags or values are shown in the order they were parsed, + with duplicates included. (Except, tags from account declarations are always shown first.) - Tip: remember, accounts also acquire tags from their parents, postings + Tip: remember, accounts also acquire tags from their parents, postings also acquire tags from their account and transaction, transactions also acquire tags from their postings. @@ -8426,8 +8307,8 @@ PART 5: COMMON TASKS $ hledger help --help # find out more about the help command To view manuals and introductory docs on the web, visit - https://hledger.org. Chat and mail list support and discussion ar- - chives can be found at https://hledger.org/support. + https://hledger.org. Chat and mail list support and discussion + archives can be found at https://hledger.org/support. Constructing command lines hledger has a flexible command line interface. We strive to keep it @@ -8505,7 +8386,7 @@ PART 5: COMMON TASKS chine). On Windows, see https://www.java.com/en/download/help/path.html, or try - running these commands in a powershell window (let us know if it per- + running these commands in a powershell window (let us know if it per- sists across a reboot, and if you need to be an Administrator): > CD @@ -8513,11 +8394,11 @@ PART 5: COMMON TASKS > SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal" 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 + 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 + 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 @@ -8637,8 +8518,8 @@ PART 5: COMMON TASKS 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 + 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- @@ -8651,12 +8532,12 @@ PART 5: COMMON TASKS 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, + 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 2023-01-15 and paycheck - If you're using version control, this can be another good time to com- + If you're using version control, this can be another good time to com- mit: $ git commit -m 'txns' 2023.journal @@ -8728,7 +8609,7 @@ PART 5: COMMON TASKS -------------------- 0 - Show only asset and liability balances, as a flat list, limited to + Show only asset and liability balances, as a flat list, limited to depth 2: $ hledger bal assets liabilities -2 @@ -8738,7 +8619,7 @@ PART 5: COMMON TASKS -------------------- $4055 - Show the same thing without negative numbers, formatted as a simple + Show the same thing without negative numbers, formatted as a simple balance sheet: $ hledger bs -2 @@ -8807,22 +8688,22 @@ PART 5: COMMON TASKS 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 + 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. BUGS We welcome bug reports in the hledger issue tracker (shortcut: - http://bugs.hledger.org), or on the #hledger chat or hledger mail list + http://bugs.hledger.org), or on the #hledger chat or hledger mail list (https://hledger.org/support). Some known issues and limitations: - The need to precede add-on command options with -- when invoked from + The need to precede add-on command options with -- when invoked from hledger is awkward. (See Command options, Constructing command lines.) - A UTF-8-aware system locale must be configured to work with non-ascii + A UTF-8-aware system locale must be configured to work with non-ascii data. (See Unicode characters, Troubleshooting.) On Microsoft Windows, depending whether you are running in a CMD window @@ -8840,7 +8721,7 @@ BUGS PATH issues: I get an error like "No command 'hledger' found" Depending how you installed hledger, the executables may not be in your - shell's PATH. Eg on unix systems, stack installs hledger in ~/.lo- + shell's PATH. Eg on unix systems, stack installs hledger in ~/.lo- cal/bin and cabal installs it in ~/.cabal/bin. You may need to add one of these directories to your shell's PATH, and/or open a new terminal window. @@ -8849,13 +8730,13 @@ BUGS it o LEDGER_FILE should be a real environment variable, not just a shell variable. Eg on unix, the command env | grep LEDGER_FILE should show - it. You may need to use export (see https://stackover- + it. You may need to use export (see https://stackover- flow.com/a/7411509). - o You may need to force your shell to see the new configuration. A + o You may need to force your shell to see the new configuration. A simple way is to close your terminal window and open a new one. - LANG issues: I get errors like "Illegal byte sequence" or "Invalid or + LANG issues: I get errors like "Illegal byte sequence" or "Invalid or incomplete multibyte or wide character" or "commitAndReleaseBuffer: in- valid argument (invalid character)" Programs compiled with GHC (hledger, haskell build tools, etc.) need @@ -8896,6 +8777,4 @@ LICENSE SEE ALSO hledger(1), hledger-ui(1), hledger-web(1), ledger(1) - - -hledger-1.30.99 June 2023 HLEDGER(1) +hledger-1.30.99 August 2023 HLEDGER(1)