hledger 1.22.1 → 1.22.2
raw patch · 18 files changed
+15462/−15341 lines, 18 filesdep ~hledger-libPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: hledger-lib
API changes (from Hackage documentation)
- Hledger.Cli.Utils: journalAddForecast :: CliOpts -> Journal -> Journal
Files
- CHANGES.md +50/−0
- Hledger/Cli/CliOptions.hs +1/−1
- Hledger/Cli/Commands/Aregister.hs +2/−2
- Hledger/Cli/Commands/Aregister.txt +24/−36
- Hledger/Cli/Utils.hs +3/−44
- embeddedfiles/hledger-ui.1 +2/−2
- embeddedfiles/hledger-ui.info +1/−1
- embeddedfiles/hledger-ui.txt +2/−2
- embeddedfiles/hledger-web.1 +2/−2
- embeddedfiles/hledger-web.info +1/−1
- embeddedfiles/hledger-web.txt +2/−2
- embeddedfiles/hledger.1 +131/−104
- embeddedfiles/hledger.info +484/−469
- embeddedfiles/hledger.txt +7067/−7047
- hledger.1 +131/−104
- hledger.cabal +8/−8
- hledger.info +484/−469
- hledger.txt +7067/−7047
CHANGES.md view
@@ -9,6 +9,35 @@ User-visible changes in the hledger command line tool and library. +# 1.22.2 2021-08-07++Breaking changes++- aregister no longer hides future transactions by default.+ This is a consequence of the fix for + [#1638](https://github.com/simonmichael/hledger/issues/1638). + It makes aregister consistent, so we think it's a reasonable change.+ So if you have future-dated transactions in your journal which you+ don't want reported, you now must exclude them with `-e tomorrow` or+ `date:-tomorrow` in the command, as with other reports.+ (Stephen Morgan)++Improvements++- Timedot format's doc has been rewritten.++Fixes++- Make balance assignments in forecasted transactions work again+ (broken in 1.22.1).+ Forecast transactions are now generated early and processed+ in the same way as other transactions.+ ([#1638](https://github.com/simonmichael/hledger/issues/1638), Stephen Morgan)++- aregister preserves the order of same-day transactions again+ (broken in 1.22.1).+ ([#1642](https://github.com/simonmichael/hledger/issues/1642), Stephen Morgan)+ # 1.22.1 2021-08-02 Improvements@@ -23,6 +52,27 @@ - Allow megaparsec 9.1 Fixes++- `cur:` and `amt:` queries now match the original amounts before+ valuation and cost conversion, as they did before hledger 1.22. We+ believe this is the more useful behaviour in practice. + (#1625, Stephen Morgan)++- Queries now work better with `register --related`, no longer showing+ duplicate postings when more than one posting in a transaction is+ matched. + (#1629, Stephen Morgan)++- Valuation now works with `register --related`. + (#1630, Stephen Morgan)++- Auto posting rules now also see inferred amounts,+ not just explicit amounts. + (#1412, Stephen Morgan)++- The aregister command now properly ignores a `depth:` argument. + It might now also behave more correctly with valuation or `--txn-dates`.+ (#1634, Stephen Morgan) - Our info manuals now have more robust directory metadata (no subdirectory path), making them more likely to be linked in your
Hledger/Cli/CliOptions.hs view
@@ -454,7 +454,7 @@ -- Also records the terminal width, if supported. rawOptsToCliOpts :: RawOpts -> IO CliOpts rawOptsToCliOpts rawopts = do- let iopts = rawOptsToInputOpts rawopts+ iopts <- rawOptsToInputOpts rawopts rspec <- rawOptsToReportSpec rawopts mcolumns <- readMay <$> getEnvSafe "COLUMNS" mtermwidth <-
Hledger/Cli/Commands/Aregister.hs view
@@ -66,7 +66,7 @@ -- | Print an account register report for a specified account. aregister :: CliOpts -> Journal -> IO ()-aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do+aregister opts@CliOpts{rawopts_=rawopts,inputopts_=iopts,reportspec_=rspec} j = do d <- getCurrentDay -- the first argument specifies the account, any remaining arguments are a filter query (apat,querystring) <- case listofstringopt "args" rawopts of@@ -92,7 +92,7 @@ rspec' = rspec{ rsQuery=simplifyQuery $ And [queryFromFlags ropts', argsquery] , rsOpts=ropts' }- reportq = And [rsQuery rspec', excludeforecastq (isJust $ forecast_ ropts')]+ reportq = And [rsQuery rspec', excludeforecastq (isJust $ forecast_ iopts)] where -- As in RegisterScreen, why ? XXX -- Except in forecast mode, exclude future/forecast transactions.
Hledger/Cli/Commands/Aregister.txt view
@@ -1,37 +1,40 @@ aregister, areg -Show the transactions and running historical balance in an account, with-each line item representing one transaction.+Show the transactions and running historical balance of a single+account, with each transaction displayed as one line. _FLAGS -aregister shows the transactions affecting a particular account and its-subaccounts, with each line item representing a whole transaction - as-in bank statements, hledger-ui, hledger-web and other accounting apps.--Note this is unlike the register command, which shows individual-postings and does not always show a single account or a historical-balance.--A reminder, "historical" balances include any balance from transactions-before the report start date, so (if opening balances are recorded-correctly) aregister will show the real-world balances of an account, as-you would see in a bank statement.+aregister shows the overall transactions affecting a particular account+(and any subaccounts). Each report line represents one transaction in+this account. Transactions before the report start date are always+included in the running balance (--historical mode is always on). -As a quick rule of thumb, use aregister for reconciling real-world-asset/liability accounts and register for reviewing detailed-revenues/expenses.+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+aregister for reviewing and reconciling real-world asset/liability+accounts - use register for reviewing detailed revenues/expenses. -aregister shows the register for just one account (and its subaccounts).-This account must be specified as the first argument. You can write+aregister requires one argument: the account to report on. You can write either the full account name, or a case-insensitive regular expression which will select the alphabetically first matched account. (Eg if you have assets:aaa:checking and assets:bbb:checking accounts, hledger areg checking would select assets:aaa:checking.) +Transactions involving subaccounts of this account will also be shown.+aregister ignores depth limits, so its final total will always match a+balance report with similar arguments.+ Any additional arguments form a query which will filter the transactions-shown.+shown. Note some queries will disturb the running balance, causing it to+be different from the account's real-world 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: - the transaction's date (or the relevant posting's date if different,@@ -44,11 +47,8 @@ Transactions making a net change of zero are not shown by default; add the -E/--empty flag to show them. -aregister ignores a depth limit, so its final total will always match a-balance report with similar arguments.- This command also supports the output destination and output format-options The output formats supported are txt, csv, and json.+options. The output formats supported are txt, csv, and json. aregister and custom posting dates @@ -61,15 +61,3 @@ To filter strictly by transaction date instead, add the --txn-dates flag. If you use this flag and some of your postings have custom dates, it's probably best to assume the running balance is wrong.--Examples:--Show all transactions and historical running balance in the first-account whose name contains "checking":--$ hledger areg checking--Show transactions and historical running balance in all asset accounts-during july:--$ hledger areg assets date:jul
Hledger/Cli/Utils.hs view
@@ -15,7 +15,6 @@ writeOutput, writeOutputLazyText, journalTransform,- journalAddForecast, journalReload, journalReloadIfChanged, journalFileIsNewer,@@ -38,7 +37,7 @@ import qualified Data.Text.IO as T import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.IO as TL-import Data.Time (UTCTime, Day, addDays)+import Data.Time (UTCTime, Day) import Safe (readMay, headMay) import System.Console.CmdArgs import System.Directory (getModificationTime, getDirectoryContents, copyFile, doesFileExist)@@ -86,13 +85,14 @@ -- - pivoting account names (--pivot) -- - anonymising (--anonymise). --+-- This will return an error message if the query in any auto posting rule fails+-- to parse, or the generated transactions are not balanced. journalTransform :: CliOpts -> Journal -> Journal journalTransform opts = anonymiseByOpts opts -- - converting amounts to market value (--value) -- . journalApplyValue ropts . pivotByOpts opts- . journalAddForecast opts -- | Apply the pivot transformation on a journal, if option is present. pivotByOpts :: CliOpts -> Journal -> Journal@@ -107,47 +107,6 @@ if anon_ . inputopts_ $ opts then anon else id---- | Generate periodic transactions from all periodic transaction rules in the journal.--- These transactions are added to the in-memory Journal (but not the on-disk file).------ When --auto is active, auto posting rules will be applied to the--- generated transactions. If the query in any auto posting rule fails--- to parse, this function will raise an error.------ The start & end date for generated periodic transactions are determined in--- a somewhat complicated way; see the hledger manual -> Periodic transactions.----journalAddForecast :: CliOpts -> Journal -> Journal-journalAddForecast CliOpts{inputopts_=iopts, reportspec_=rspec} j =- case forecast_ ropts of- Nothing -> j- Just _ -> either error id $ do -- PARTIAL:- forecasttxns <- addAutoTxns =<< mapM (balanceTransaction (balancingopts_ iopts))- [ txnTieKnot t | pt <- jperiodictxns j- , t <- runPeriodicTransaction pt forecastspan- , spanContainsDate forecastspan (tdate t)- ]- journalBalanceTransactions (balancingopts_ iopts) j{ jtxns = concat [jtxns j, forecasttxns] }- >>= journalApplyCommodityStyles- where- today = rsToday rspec- ropts = rsOpts rspec-- -- "They can start no earlier than: the day following the latest normal transaction in the journal (or today if there are none)."- mjournalend = dbg2 "journalEndDate" $ journalEndDate False j -- ignore secondary dates- forecastbeginDefault = dbg2 "forecastbeginDefault" $ fromMaybe today mjournalend-- -- "They end on or before the specified report end date, or 180 days from today if unspecified."- mspecifiedend = dbg2 "specifieddates" $ reportPeriodLastDay rspec- forecastendDefault = dbg2 "forecastendDefault" $ fromMaybe (addDays 180 today) mspecifiedend-- forecastspan = dbg2 "forecastspan" $- spanDefaultsFrom- (fromMaybe nulldatespan $ dbg2 "forecastspan flag" $ forecast_ ropts)- (DateSpan (Just forecastbeginDefault) (Just forecastendDefault))-- addAutoTxns = if auto_ iopts then modifyTransactions today (jtxnmodifiers j) else return -- | Write some output to stdout or to a file selected by --output-file. -- If the file exists it will be overwritten.
embeddedfiles/hledger-ui.1 view
@@ -1,5 +1,5 @@ -.TH "HLEDGER-UI" "1" "August 2021" "hledger-ui-1.22.1 " "hledger User Manuals"+.TH "HLEDGER-UI" "1" "August 2021" "hledger-ui-1.22.2 " "hledger User Manuals" @@ -7,7 +7,7 @@ .PP hledger-ui is a terminal interface (TUI) for the hledger accounting tool.-This manual is for hledger-ui 1.22.1.+This manual is for hledger-ui 1.22.2. .SH SYNOPSIS .PP \f[C]hledger-ui [OPTIONS] [QUERYARGS]\f[R]
embeddedfiles/hledger-ui.info view
@@ -12,7 +12,7 @@ ************* hledger-ui is a terminal interface (TUI) for the hledger accounting-tool. This manual is for hledger-ui 1.22.1.+tool. This manual is for hledger-ui 1.22.2. 'hledger-ui [OPTIONS] [QUERYARGS]' 'hledger ui -- [OPTIONS] [QUERYARGS]'
embeddedfiles/hledger-ui.txt view
@@ -5,7 +5,7 @@ NAME hledger-ui is a terminal interface (TUI) for the hledger accounting- tool. This manual is for hledger-ui 1.22.1.+ tool. This manual is for hledger-ui 1.22.2. SYNOPSIS hledger-ui [OPTIONS] [QUERYARGS]@@ -504,4 +504,4 @@ -hledger-ui-1.22.1 August 2021 HLEDGER-UI(1)+hledger-ui-1.22.2 August 2021 HLEDGER-UI(1)
embeddedfiles/hledger-web.1 view
@@ -1,12 +1,12 @@ -.TH "HLEDGER-WEB" "1" "August 2021" "hledger-web-1.22.1 " "hledger User Manuals"+.TH "HLEDGER-WEB" "1" "August 2021" "hledger-web-1.22.2 " "hledger User Manuals" .SH NAME .PP hledger-web is a web interface (WUI) for the hledger accounting tool.-This manual is for hledger-web 1.22.1.+This manual is for hledger-web 1.22.2. .SH SYNOPSIS .PP \f[C]hledger-web [OPTIONS]\f[R]
embeddedfiles/hledger-web.info view
@@ -12,7 +12,7 @@ ************** hledger-web is a web interface (WUI) for the hledger accounting tool.-This manual is for hledger-web 1.22.1.+This manual is for hledger-web 1.22.2. 'hledger-web [OPTIONS]' 'hledger web -- [OPTIONS]'
embeddedfiles/hledger-web.txt view
@@ -5,7 +5,7 @@ NAME hledger-web is a web interface (WUI) for the hledger accounting tool.- This manual is for hledger-web 1.22.1.+ This manual is for hledger-web 1.22.2. SYNOPSIS hledger-web [OPTIONS]@@ -556,4 +556,4 @@ -hledger-web-1.22.1 August 2021 HLEDGER-WEB(1)+hledger-web-1.22.2 August 2021 HLEDGER-WEB(1)
embeddedfiles/hledger.1 view
@@ -1,6 +1,6 @@ .\"t -.TH "HLEDGER" "1" "August 2021" "hledger-1.22.1 " "hledger User Manuals"+.TH "HLEDGER" "1" "August 2021" "hledger-1.22.2 " "hledger User Manuals" @@ -9,7 +9,7 @@ This is the command-line interface (CLI) for the hledger accounting tool. Here we also describe hledger\[aq]s concepts and file formats.-This manual is for hledger 1.22.1.+This manual is for hledger 1.22.2. .SH SYNOPSIS .PP \f[C]hledger\f[R]@@ -2511,30 +2511,23 @@ .P .PD .PP-Show the transactions and running historical balance in an account, with-each line item representing one transaction.-.PP-\f[C]aregister\f[R] shows the transactions affecting a particular-account and its subaccounts, with each line item representing a whole-transaction - as in bank statements, hledger-ui, hledger-web and other-accounting apps.-.PP-Note this is unlike the \f[C]register\f[R] command, which shows-individual postings and does not always show a single account or a-historical balance.+Show the transactions and running historical balance of a single+account, with each transaction displayed as one line. .PP-A reminder, \[dq]historical\[dq] balances include any balance from-transactions before the report start date, so (if opening balances are-recorded correctly) \f[C]aregister\f[R] will show the real-world-balances of an account, as you would see in a bank statement.+\f[C]aregister\f[R] shows the overall transactions affecting a+particular account (and any subaccounts).+Each report line represents one transaction in this account.+Transactions before the report start date are always included in the+running balance (\f[C]--historical\f[R] mode is always on). .PP-As a quick rule of thumb, use \f[C]aregister\f[R] for reconciling-real-world asset/liability accounts and \f[C]register\f[R] for reviewing-detailed revenues/expenses.+This is a more \[dq]real world\[dq], bank-like view than the+\f[C]register\f[R] command (which shows individual postings, possibly+from multiple accounts, not necessarily in historical mode).+As a quick rule of thumb: - use \f[C]aregister\f[R] for reviewing and+reconciling real-world asset/liability accounts - use \f[C]register\f[R]+for reviewing detailed revenues/expenses. .PP-\f[C]aregister\f[R] shows the register for just one account (and its-subaccounts).-This account must be specified as the first argument.+\f[C]aregister\f[R] requires one argument: the account to report on. You can write either the full account name, or a case-insensitive regular expression which will select the alphabetically first matched account.@@ -2542,9 +2535,25 @@ \f[C]assets:bbb:checking\f[R] accounts, \f[C]hledger areg checking\f[R] would select \f[C]assets:aaa:checking\f[R].) .PP+Transactions involving subaccounts of this account will also be shown.+\f[C]aregister\f[R] ignores depth limits, so its final total will always+match a balance report with similar arguments.+.PP Any additional arguments form a query which will filter the transactions shown.+Note some queries will disturb the running balance, causing it to be+different from the account\[aq]s real-world running balance. .PP+An example: this shows the transactions and historical running balance+during july, in the first account whose name contains+\[dq]checking\[dq]:+.IP+.nf+\f[C]+$ hledger areg checking date:jul+\f[R]+.fi+.PP Each \f[C]aregister\f[R] line item shows: .IP \[bu] 2 the transaction\[aq]s date (or the relevant posting\[aq]s date if@@ -2560,12 +2569,10 @@ Transactions making a net change of zero are not shown by default; add the \f[C]-E/--empty\f[R] flag to show them. .PP-\f[C]aregister\f[R] ignores a depth limit, so its final total will-always match a balance report with similar arguments.-.PP This command also supports the output destination and output format-options The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R],-and \f[C]json\f[R].+options.+The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R], and+\f[C]json\f[R]. .SS aregister and custom posting dates .PP Transactions whose date is outside the report period can still be shown,@@ -2579,26 +2586,6 @@ \f[C]--txn-dates\f[R] flag. If you use this flag and some of your postings have custom dates, it\[aq]s probably best to assume the running balance is wrong.-.PP-Examples:-.PP-Show all transactions and historical running balance in the first-account whose name contains \[dq]checking\[dq]:-.IP-.nf-\f[C]-$ hledger areg checking-\f[R]-.fi-.PP-Show transactions and historical running balance in all asset accounts-during july:-.IP-.nf-\f[C]-$ hledger areg assets date:jul-\f[R]-.fi .SS balance .PP balance, bal@@ -8851,70 +8838,111 @@ ledger 2 executable renamed. .SH TIMEDOT FORMAT .PP-hledger\[aq]s human-friendly time logging format.+\f[C]timedot\f[R] format is hledger\[aq]s human-friendly time logging+format.+Compared to \f[C]timeclock\f[R] format, it is+.IP \[bu] 2+convenient for quick, approximate, and retroactive time logging+.IP \[bu] 2+readable: you can see at a glance where time was spent. .PP-Timedot is a plain text format for logging dated, categorised quantities-(of time, usually), supported by hledger.-It is convenient for approximate and retroactive time logging, eg when-the real-time clock-in/out required with a timeclock file is too precise-or too interruptive.-It can be formatted like a bar chart, making clear at a glance where-time was spent.+A timedot file contains a series of day entries, which might look like+this:+.IP+.nf+\f[C]+2021-08-04+hom:errands .... ....+fos:hledger:timedot .. ; docs+per:admin:finance +\f[R]+.fi .PP-Though called \[dq]timedot\[dq], this format is read by hledger as-commodityless quantities, so it could be used to represent dated-quantities other than time.-In the docs below we\[aq]ll assume it\[aq]s time.+hledger reads this as three time transactions on this day, with each dot+representing a quarter-hour spent:+.IP+.nf+\f[C]+$ hledger -f a.timedot print # .timedot file extension activates the timedot reader+2021-08-04 *+ (hom:errands) 2.00++2021-08-04 *+ (fos:hledger:timedot) 0.50++2021-08-04 *+ (per:admin:finance) 0+\f[R]+.fi .PP-A timedot file contains a series of day entries.-A day entry begins with a non-indented hledger-style simple date (Y-M-D,-Y/M/D, Y.M.D..) Any additional text on the same line is used as a-transaction description for this day.+A day entry begins with a date line:+.IP \[bu] 2+a non-indented \f[B]simple date\f[R] (Y-M-D, Y/M/D, or Y.M.D). .PP-This is followed by optionally-indented timelog items for that day, one-per line.-Each timelog item is a note, usually a hledger:style:account:name-representing a time category, followed by two or more spaces, and a-quantity.-Each timelog item generates a hledger transaction.+Optionally this can be followed on the same line by+.IP \[bu] 2+a common \f[B]transaction description\f[R] for this day+.IP \[bu] 2+a common \f[B]transaction comment\f[R] for this day, after a semicolon+(\f[C];\f[R]). .PP-Quantities can be written as:+After the date line are zero or more optionally-indented time+transaction lines, consisting of: .IP \[bu] 2-dots: a sequence of dots (.) representing quarter hours.-Spaces may optionally be used for grouping.-Eg: ....-\&..+an \f[B]account name\f[R] - any word or phrase, usually a hledger-style+account name. .IP \[bu] 2-an integral or decimal number, representing hours.-Eg: 1.5+\f[B]two or more spaces\f[R] - a field separator, required if there is+an amount (as in journal format). .IP \[bu] 2-an integral or decimal number immediately followed by a unit symbol-\f[C]s\f[R], \f[C]m\f[R], \f[C]h\f[R], \f[C]d\f[R], \f[C]w\f[R],-\f[C]mo\f[R], or \f[C]y\f[R], representing seconds, minutes, hours, days-weeks, months or years respectively.-Eg: 90m.-The following equivalencies are assumed, currently: 1m = 60s, 1h = 60m,-1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.+a \f[B]timedot amount\f[R] - dots representing quarter hours, or a+number representing hours.+.IP \[bu] 2+an optional \f[B]comment\f[R] beginning with semicolon.+This is ignored. .PP-There is some flexibility allowing notes and todo lists to be kept right-in the time log, if needed:+In more detail, timedot amounts can be: .IP \[bu] 2-Blank lines and lines beginning with \f[C]#\f[R] or \f[C];\f[R] are+\f[B]dots\f[R]: zero or more period characters, each representing one+quarter-hour.+Spaces are ignored and can be used for grouping.+Eg: \f[C].... ..\f[R]+.IP \[bu] 2+a \f[B]number\f[R], representing hours.+Eg: \f[C]1.5\f[R]+.IP \[bu] 2+a \f[B]number immediately followed by a unit symbol\f[R] \f[C]s\f[R],+\f[C]m\f[R], \f[C]h\f[R], \f[C]d\f[R], \f[C]w\f[R], \f[C]mo\f[R], or+\f[C]y\f[R], representing seconds, minutes, hours, days weeks, months or+years.+Eg \f[C]1.5h\f[R] or \f[C]90m\f[R].+The following equivalencies are assumed:+.PD 0+.P+.PD+\f[C]60s\f[R] = \f[C]1m\f[R], \f[C]60m\f[R] = \f[C]1h\f[R],+\f[C]24h\f[R] = \f[C]1d\f[R], \f[C]7d\f[R] = \f[C]1w\f[R], \f[C]30d\f[R]+= \f[C]1mo\f[R], \f[C]365d\f[R] = \f[C]1y\f[R].+(This unit will not be visible in the generated transaction amount,+which is always in hours.)+.PP+There is some added flexibility to help with keeping time log data in+the same file as your notes, todo lists, etc.:+.IP \[bu] 2+Lines beginning with \f[C]#\f[R] or \f[C];\f[R], and blank lines, are ignored. .IP \[bu] 2-Lines not ending with a double-space and quantity are parsed as items-taking no time, which will not appear in balance reports by default.-(Add -E to see them.)+Lines not ending with a double-space and amount are parsed as+transactions with zero amount.+(Most hledger reports hide these by default; add -E to see them.) .IP \[bu] 2-Org mode headlines (lines beginning with one or more \f[C]*\f[R]-followed by a space) can be used as date lines or timelog items (the-stars are ignored).-Also all org headlines before the first date line are ignored.-This means org users can manage their timelog as an org outline (eg-using org-mode/orgstruct-mode in Emacs), for organisation, faster-navigation, controlling visibility etc.+One or more stars (\f[C]*\f[R]) followed by a space, at the start of a+line, is ignored.+So date lines or time transaction lines can also be Org-mode headlines.+.IP \[bu] 2+All Org-mode headlines before the first date line are ignored. .PP-Examples:+More examples: .IP .nf \f[C]@@ -8972,7 +9000,7 @@ .IP .nf \f[C]-$ hledger -f t.timedot print date:2016/2/2+$ hledger -f a.timedot print date:2016/2/2 2016-02-02 * (inc:client1) 2.00 @@ -8983,7 +9011,7 @@ .IP .nf \f[C]-$ hledger -f t.timedot bal --daily --tree+$ hledger -f a.timedot bal --daily --tree Balance changes in 2016-02-01-2016-02-03: || 2016-02-01d 2016-02-02d 2016-02-03d @@ -9000,8 +9028,7 @@ \f[R] .fi .PP-I prefer to use period for separating account components.-We can make this work with an account alias:+Using period instead of colon as account name separator: .IP .nf \f[C]@@ -9013,7 +9040,7 @@ .IP .nf \f[C]-$ hledger -f t.timedot --alias /\[rs]\[rs]./=: bal date:2016/2/4 --tree+$ hledger -f a.timedot --alias /\[rs]\[rs]./=: bal --tree 4.50 fos 4.00 hledger:timedot 0.50 ledger@@ -9022,7 +9049,7 @@ \f[R] .fi .PP-Here is a sample.timedot.+A sample.timedot file. .SH COMMON TASKS .PP Here are some quick examples of how to do some basic tasks with hledger.
embeddedfiles/hledger.info view
@@ -13,7 +13,7 @@ This is the command-line interface (CLI) for the hledger accounting tool. Here we also describe hledger's concepts and file formats. This-manual is for hledger 1.22.1.+manual is for hledger 1.22.2. 'hledger' @@ -2000,38 +2000,43 @@ aregister, areg - Show the transactions and running historical balance in an account,-with each line item representing one transaction.-- 'aregister' shows the transactions affecting a particular account and-its subaccounts, with each line item representing a whole transaction --as in bank statements, hledger-ui, hledger-web and other accounting-apps.-- Note this is unlike the 'register' command, which shows individual-postings and does not always show a single account or a historical-balance.+ Show the transactions and running historical balance of a single+account, with each transaction displayed as one line. - A reminder, "historical" balances include any balance from-transactions before the report start date, so (if opening balances are-recorded correctly) 'aregister' will show the real-world balances of an-account, as you would see in a bank statement.+ 'aregister' shows the overall transactions affecting a particular+account (and any subaccounts). Each report line represents one+transaction in this account. Transactions before the report start date+are always included in the running balance ('--historical' mode is+always on). - As a quick rule of thumb, use 'aregister' for reconciling real-world-asset/liability accounts and 'register' for reviewing detailed+ 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 'aregister' for reviewing and reconciling real-world+asset/liability accounts - use 'register' for reviewing detailed revenues/expenses. - 'aregister' shows the register for just one account (and its-subaccounts). This account must be specified as the first argument.-You can write either the full account name, or a case-insensitive-regular expression which will select the alphabetically first matched-account. (Eg if you have 'assets:aaa:checking' and-'assets:bbb:checking' accounts, 'hledger areg checking' would select-'assets:aaa:checking'.)+ 'aregister' requires one argument: the account to report on. You can+write either the full account name, or a case-insensitive regular+expression which will select the alphabetically first matched account.+(Eg if you have 'assets:aaa:checking' and 'assets:bbb:checking'+accounts, 'hledger areg checking' would select 'assets:aaa:checking'.) + Transactions involving subaccounts of this account will also be+shown. 'aregister' ignores depth limits, so its final total will always+match a balance report with similar arguments.+ Any additional arguments form a query which will filter the-transactions shown.+transactions shown. Note some queries will disturb the running balance,+causing it to be different from the account's real-world 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: * the transaction's date (or the relevant posting's date if@@ -2044,11 +2049,8 @@ Transactions making a net change of zero are not shown by default; add the '-E/--empty' flag to show them. - 'aregister' ignores a depth limit, so its final total will always-match a balance report with similar arguments.- This command also supports the output destination and output format-options The output formats supported are 'txt', 'csv', and 'json'.+options. The output formats supported are 'txt', 'csv', and 'json'. * Menu: @@ -2070,18 +2072,6 @@ flag. If you use this flag and some of your postings have custom dates, it's probably best to assume the running balance is wrong. - Examples:-- Show all transactions and historical running balance in the first-account whose name contains "checking":--$ hledger areg checking-- Show transactions and historical running balance in all asset-accounts during july:--$ hledger areg assets date:jul- File: hledger.info, Node: balance, Next: balancesheet, Prev: aregister, Up: COMMANDS @@ -7807,61 +7797,87 @@ 15 TIMEDOT FORMAT ***************** -hledger's human-friendly time logging format.+'timedot' format is hledger's human-friendly time logging format.+Compared to 'timeclock' format, it is - Timedot is a plain text format for logging dated, categorised-quantities (of time, usually), supported by hledger. It is convenient-for approximate and retroactive time logging, eg when the real-time-clock-in/out required with a timeclock file is too precise or too-interruptive. It can be formatted like a bar chart, making clear at a-glance where time was spent.+ * convenient for quick, approximate, and retroactive time logging+ * readable: you can see at a glance where time was spent. - Though called "timedot", this format is read by hledger as-commodityless quantities, so it could be used to represent dated-quantities other than time. In the docs below we'll assume it's time.+ A timedot file contains a series of day entries, which might look+like this: - A timedot file contains a series of day entries. A day entry begins-with a non-indented hledger-style simple date (Y-M-D, Y/M/D, Y.M.D..)-Any additional text on the same line is used as a transaction-description for this day.+2021-08-04+hom:errands .... ....+fos:hledger:timedot .. ; docs+per:admin:finance - This is followed by optionally-indented timelog items for that day,-one per line. Each timelog item is a note, usually a-hledger:style:account:name representing a time category, followed by two-or more spaces, and a quantity. Each timelog item generates a hledger-transaction.+ hledger reads this as three time transactions on this day, with each+dot representing a quarter-hour spent: - Quantities can be written as:+$ hledger -f a.timedot print # .timedot file extension activates the timedot reader+2021-08-04 *+ (hom:errands) 2.00 - * dots: a sequence of dots (.) representing quarter hours. Spaces- may optionally be used for grouping. Eg: .... ..+2021-08-04 *+ (fos:hledger:timedot) 0.50 - * an integral or decimal number, representing hours. Eg: 1.5+2021-08-04 *+ (per:admin:finance) 0 - * an integral or decimal number immediately followed by a unit symbol- 's', 'm', 'h', 'd', 'w', 'mo', or 'y', representing seconds,- minutes, hours, days weeks, months or years respectively. Eg: 90m.- The following equivalencies are assumed, currently: 1m = 60s, 1h =- 60m, 1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.+ A day entry begins with a date line: - There is some flexibility allowing notes and todo lists to be kept-right in the time log, if needed:+ * a non-indented *simple date* (Y-M-D, Y/M/D, or Y.M.D). - * Blank lines and lines beginning with '#' or ';' are ignored.+ Optionally this can be followed on the same line by - * Lines not ending with a double-space and quantity are parsed as- items taking no time, which will not appear in balance reports by- default. (Add -E to see them.)+ * a common *transaction description* for this day+ * a common *transaction comment* for this day, after a semicolon+ (';'). - * Org mode headlines (lines beginning with one or more '*' followed- by a space) can be used as date lines or timelog items (the stars- are ignored). Also all org headlines before the first date line- are ignored. This means org users can manage their timelog as an- org outline (eg using org-mode/orgstruct-mode in Emacs), for- organisation, faster navigation, controlling visibility etc.+ After the date line are zero or more optionally-indented time+transaction lines, consisting of: - Examples:+ * an *account name* - any word or phrase, usually a hledger-style+ account name.+ * *two or more spaces* - a field separator, required if there is an+ amount (as in journal format).+ * a *timedot amount* - dots representing quarter hours, or a number+ representing hours.+ * an optional *comment* beginning with semicolon. This is ignored. + In more detail, timedot amounts can be:++ * *dots*: zero or more period characters, each representing one+ quarter-hour. Spaces are ignored and can be used for grouping.+ Eg: '.... ..'++ * a *number*, representing hours. Eg: '1.5'++ * a *number immediately followed by a unit symbol* 's', 'm', 'h',+ 'd', 'w', 'mo', or 'y', representing seconds, minutes, hours, days+ weeks, months or years. Eg '1.5h' or '90m'. The following+ equivalencies are assumed:+ '60s' = '1m', '60m' = '1h', '24h' = '1d', '7d' = '1w', '30d' =+ '1mo', '365d' = '1y'. (This unit will not be visible in the+ generated transaction amount, which is always in hours.)++ There is some added flexibility to help with keeping time log data in+the same file as your notes, todo lists, etc.:++ * Lines beginning with '#' or ';', and blank lines, are ignored.++ * Lines not ending with a double-space and amount are parsed as+ transactions with zero amount. (Most hledger reports hide these by+ default; add -E to see them.)++ * One or more stars ('*') followed by a space, at the start of a+ line, is ignored. So date lines or time transaction lines can also+ be Org-mode headlines.++ * All Org-mode headlines before the first date line are ignored.++ More examples:+ # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc. 2016/2/1 inc:client1 .... .... .... .... .... ....@@ -7900,14 +7916,14 @@ Reporting: -$ hledger -f t.timedot print date:2016/2/2+$ hledger -f a.timedot print date:2016/2/2 2016-02-02 * (inc:client1) 2.00 2016-02-02 * (biz:research) 0.25 -$ hledger -f t.timedot bal --daily --tree+$ hledger -f a.timedot bal --daily --tree Balance changes in 2016-02-01-2016-02-03: || 2016-02-01d 2016-02-02d 2016-02-03d @@ -7922,21 +7938,20 @@ ------------++---------------------------------------- || 7.75 2.25 8.00 - I prefer to use period for separating account components. We can-make this work with an account alias:+ Using period instead of colon as account name separator: 2016/2/4 fos.hledger.timedot 4 fos.ledger .. -$ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4 --tree+$ hledger -f a.timedot --alias /\\./=: bal --tree 4.50 fos 4.00 hledger:timedot 0.50 ledger -------------------- 4.50 - Here is a sample.timedot.+ A sample.timedot file. File: hledger.info, Node: COMMON TASKS, Next: LIMITATIONS, Prev: TIMEDOT FORMAT, Up: Top@@ -8567,386 +8582,386 @@ Ref: #add65805 Node: aregister68598 Ref: #aregister68712-Node: aregister and custom posting dates70910-Ref: #aregister-and-custom-posting-dates71076-Node: balance71897-Ref: #balance72016-Node: balance features72931-Ref: #balance-features73071-Node: Simple balance report74728-Ref: #simple-balance-report74910-Node: Filtered balance report76363-Ref: #filtered-balance-report76550-Node: List or tree mode76850-Ref: #list-or-tree-mode77018-Node: Depth limiting78336-Ref: #depth-limiting78502-Node: Multi-period balance report79263-Ref: #multi-period-balance-report79455-Node: Sorting by amount81707-Ref: #sorting-by-amount81876-Node: Percentages82342-Ref: #percentages82498-Node: Balance change end balance83432-Ref: #balance-change-end-balance83623-Node: Balance report types85051-Ref: #balance-report-types85241-Node: Useful balance reports89314-Ref: #useful-balance-reports89495-Node: Budget report90580-Ref: #budget-report90764-Node: Budget report start date96003-Ref: #budget-report-start-date96172-Node: Nested budgets97504-Ref: #nested-budgets97653-Node: Customising single-period balance reports101093-Ref: #customising-single-period-balance-reports101302-Node: balancesheet103450-Ref: #balancesheet103588-Node: balancesheetequity104887-Ref: #balancesheetequity105038-Node: cashflow106418-Ref: #cashflow106542-Node: check107688-Ref: #check107793-Node: Basic checks108427-Ref: #basic-checks108545-Node: Strict checks109096-Ref: #strict-checks109237-Node: Other checks109673-Ref: #other-checks109813-Node: Custom checks110170-Ref: #custom-checks110290-Node: close110707-Ref: #close110811-Node: close usage112333-Ref: #close-usage112428-Node: codes115241-Ref: #codes115351-Node: commodities116063-Ref: #commodities116192-Node: descriptions116274-Ref: #descriptions116404-Node: diff116708-Ref: #diff116816-Node: files117863-Ref: #files117965-Node: help118112-Ref: #help118214-Node: import118941-Ref: #import119057-Node: Deduplication119922-Ref: #deduplication120047-Node: Import testing121941-Ref: #import-testing122106-Node: Importing balance assignments122594-Ref: #importing-balance-assignments122800-Node: Commodity display styles123449-Ref: #commodity-display-styles123622-Node: incomestatement123751-Ref: #incomestatement123886-Node: notes125191-Ref: #notes125306-Node: payees125674-Ref: #payees125782-Node: prices126308-Ref: #prices126416-Node: print126757-Ref: #print126869-Node: print-unique132184-Ref: #print-unique132312-Node: register132597-Ref: #register132726-Node: Custom register output137172-Ref: #custom-register-output137303-Node: register-match138640-Ref: #register-match138776-Node: rewrite139127-Ref: #rewrite139244-Node: Re-write rules in a file141150-Ref: #re-write-rules-in-a-file141313-Node: Diff output format142462-Ref: #diff-output-format142645-Node: rewrite vs print --auto143737-Ref: #rewrite-vs.-print---auto143897-Node: roi144453-Ref: #roi144553-Node: Spaces and special characters in --inv and --pnl146239-Ref: #spaces-and-special-characters-in---inv-and---pnl146479-Node: Semantics of --inv and --pnl146967-Ref: #semantics-of---inv-and---pnl147206-Node: IRR and TWR explained149056-Ref: #irr-and-twr-explained149216-Node: stats152284-Ref: #stats152385-Node: tags153173-Ref: #tags153273-Node: test153792-Ref: #test153908-Node: About add-on commands154655-Ref: #about-add-on-commands154792-Node: JOURNAL FORMAT155923-Ref: #journal-format156051-Node: Transactions158247-Ref: #transactions158362-Node: Dates159376-Ref: #dates159492-Node: Simple dates159557-Ref: #simple-dates159677-Node: Secondary dates160186-Ref: #secondary-dates160334-Node: Posting dates161670-Ref: #posting-dates161793-Node: Status163165-Ref: #status163275-Node: Code164983-Ref: #code165095-Node: Description165327-Ref: #description165455-Node: Payee and note165775-Ref: #payee-and-note165883-Node: Comments166218-Ref: #comments166340-Node: Tags167534-Ref: #tags-1167645-Node: Postings169038-Ref: #postings169162-Node: Virtual postings170188-Ref: #virtual-postings170299-Node: Account names171604-Ref: #account-names171741-Node: Amounts172229-Ref: #amounts172366-Node: Decimal marks digit group marks173322-Ref: #decimal-marks-digit-group-marks173499-Node: Commodity174371-Ref: #commodity174531-Node: Commodity directives175483-Ref: #commodity-directives175657-Node: Commodity display style176144-Ref: #commodity-display-style176323-Node: Rounding178431-Ref: #rounding178551-Node: Transaction prices178963-Ref: #transaction-prices179129-Node: Lot prices lot dates181560-Ref: #lot-prices-lot-dates181743-Node: Balance assertions182231-Ref: #balance-assertions182409-Node: Assertions and ordering183442-Ref: #assertions-and-ordering183624-Node: Assertions and included files184324-Ref: #assertions-and-included-files184561-Node: Assertions and multiple -f options184894-Ref: #assertions-and-multiple--f-options185144-Node: Assertions and commodities185276-Ref: #assertions-and-commodities185502-Node: Assertions and prices186659-Ref: #assertions-and-prices186867-Node: Assertions and subaccounts187307-Ref: #assertions-and-subaccounts187530-Node: Assertions and virtual postings187854-Ref: #assertions-and-virtual-postings188090-Node: Assertions and precision188232-Ref: #assertions-and-precision188419-Node: Balance assignments188686-Ref: #balance-assignments188856-Node: Balance assignments and prices190020-Ref: #balance-assignments-and-prices190186-Node: Directives190410-Ref: #directives190573-Node: Directives and multiple files195927-Ref: #directives-and-multiple-files196123-Node: Comment blocks196787-Ref: #comment-blocks196964-Node: Including other files197140-Ref: #including-other-files197314-Node: Default year198238-Ref: #default-year198396-Node: Declaring payees198803-Ref: #declaring-payees198969-Node: Declaring commodities199215-Ref: #declaring-commodities199396-Node: Commodity error checking201776-Ref: #commodity-error-checking201926-Node: Default commodity202183-Ref: #default-commodity202363-Node: Declaring market prices203239-Ref: #declaring-market-prices203428-Node: Declaring accounts204241-Ref: #declaring-accounts204421-Node: Account error checking205623-Ref: #account-error-checking205789-Node: Account comments206968-Ref: #account-comments207152-Node: Account subdirectives207576-Ref: #account-subdirectives207761-Node: Account types208074-Ref: #account-types208248-Node: Declaring account types208984-Ref: #declaring-account-types209163-Node: Auto-detected account types209813-Ref: #auto-detected-account-types210054-Node: Interference from auto-detected account types211014-Ref: #interference-from-auto-detected-account-types211291-Node: Old account type syntax211774-Ref: #old-account-type-syntax211971-Node: Account display order212271-Ref: #account-display-order212431-Node: Rewriting accounts213582-Ref: #rewriting-accounts213761-Node: Basic aliases214518-Ref: #basic-aliases214654-Node: Regex aliases215398-Ref: #regex-aliases215560-Node: Combining aliases216279-Ref: #combining-aliases216462-Node: Aliases and multiple files217738-Ref: #aliases-and-multiple-files217937-Node: end aliases218516-Ref: #end-aliases218663-Node: Default parent account218764-Ref: #default-parent-account218954-Node: Periodic transactions219838-Ref: #periodic-transactions220021-Node: Periodic rule syntax221938-Ref: #periodic-rule-syntax222138-Node: Two spaces between period expression and description!222842-Ref: #two-spaces-between-period-expression-and-description223155-Node: Forecasting with periodic transactions223839-Ref: #forecasting-with-periodic-transactions224138-Node: Budgeting with periodic transactions226193-Ref: #budgeting-with-periodic-transactions226426-Node: Auto postings226835-Ref: #auto-postings226971-Node: Auto postings and multiple files229150-Ref: #auto-postings-and-multiple-files229348-Node: Auto postings and dates229557-Ref: #auto-postings-and-dates229825-Node: Auto postings and transaction balancing / inferred amounts / balance assertions230000-Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions230345-Node: Auto posting tags230687-Ref: #auto-posting-tags230896-Node: CSV FORMAT231532-Ref: #csv-format231660-Node: Examples234289-Ref: #examples234392-Node: Basic234600-Ref: #basic234702-Node: Bank of Ireland235244-Ref: #bank-of-ireland235381-Node: Amazon236843-Ref: #amazon236963-Node: Paypal238682-Ref: #paypal238778-Node: CSV rules246422-Ref: #csv-rules246540-Node: skip246873-Ref: #skip246973-Node: fields list247348-Ref: #fields-list247487-Node: field assignment248990-Ref: #field-assignment249142-Node: Field names250070-Ref: #field-names250210-Node: date field250590-Ref: #date-field250710-Node: date2 field250758-Ref: #date2-field250901-Node: status field250957-Ref: #status-field251102-Node: code field251151-Ref: #code-field251298-Node: description field251343-Ref: #description-field251505-Node: comment field251564-Ref: #comment-field251721-Node: account field251936-Ref: #account-field252088-Node: amount field252663-Ref: #amount-field252814-Node: currency field254059-Ref: #currency-field254214-Node: balance field254471-Ref: #balance-field254605-Node: separator254977-Ref: #separator255109-Node: if block255649-Ref: #if-block255776-Node: Matching the whole record256177-Ref: #matching-the-whole-record256354-Node: Matching individual fields257157-Ref: #matching-individual-fields257363-Node: Combining matchers257587-Ref: #combining-matchers257785-Node: Rules applied on successful match258098-Ref: #rules-applied-on-successful-match258291-Node: if table258945-Ref: #if-table259066-Node: end260804-Ref: #end260918-Node: date-format261142-Ref: #date-format261276-Node: decimal-mark262272-Ref: #decimal-mark262419-Node: newest-first262758-Ref: #newest-first262901-Node: include263584-Ref: #include263717-Node: balance-type264161-Ref: #balance-type264283-Node: Tips264983-Ref: #tips265074-Node: Rapid feedback265373-Ref: #rapid-feedback265492-Node: Valid CSV265952-Ref: #valid-csv266084-Node: File Extension266276-Ref: #file-extension266430-Node: Reading multiple CSV files266859-Ref: #reading-multiple-csv-files267046-Node: Valid transactions267287-Ref: #valid-transactions267467-Node: Deduplicating importing268095-Ref: #deduplicating-importing268276-Node: Setting amounts269309-Ref: #setting-amounts269466-Node: Amount signs271907-Ref: #amount-signs272061-Node: Setting currency/commodity272748-Ref: #setting-currencycommodity272936-Node: Amount decimal places274110-Ref: #amount-decimal-places274302-Node: Referencing other fields274614-Ref: #referencing-other-fields274813-Node: How CSV rules are evaluated275710-Ref: #how-csv-rules-are-evaluated275885-Node: TIMECLOCK FORMAT277336-Ref: #timeclock-format277476-Node: TIMEDOT FORMAT279537-Ref: #timedot-format279675-Node: COMMON TASKS283951-Ref: #common-tasks284080-Node: Getting help284487-Ref: #getting-help284621-Node: Constructing command lines285174-Ref: #constructing-command-lines285368-Node: Starting a journal file286065-Ref: #starting-a-journal-file286265-Node: Setting opening balances287453-Ref: #setting-opening-balances287651-Node: Recording transactions290792-Ref: #recording-transactions290974-Node: Reconciling291530-Ref: #reconciling291675-Node: Reporting293932-Ref: #reporting294074-Node: Migrating to a new file298073-Ref: #migrating-to-a-new-file298223-Node: LIMITATIONS298522-Ref: #limitations298650-Node: TROUBLESHOOTING299393-Ref: #troubleshooting299508+Node: aregister and custom posting dates71077+Ref: #aregister-and-custom-posting-dates71243+Node: balance71795+Ref: #balance71914+Node: balance features72829+Ref: #balance-features72969+Node: Simple balance report74626+Ref: #simple-balance-report74808+Node: Filtered balance report76261+Ref: #filtered-balance-report76448+Node: List or tree mode76748+Ref: #list-or-tree-mode76916+Node: Depth limiting78234+Ref: #depth-limiting78400+Node: Multi-period balance report79161+Ref: #multi-period-balance-report79353+Node: Sorting by amount81605+Ref: #sorting-by-amount81774+Node: Percentages82240+Ref: #percentages82396+Node: Balance change end balance83330+Ref: #balance-change-end-balance83521+Node: Balance report types84949+Ref: #balance-report-types85139+Node: Useful balance reports89212+Ref: #useful-balance-reports89393+Node: Budget report90478+Ref: #budget-report90662+Node: Budget report start date95901+Ref: #budget-report-start-date96070+Node: Nested budgets97402+Ref: #nested-budgets97551+Node: Customising single-period balance reports100991+Ref: #customising-single-period-balance-reports101200+Node: balancesheet103348+Ref: #balancesheet103486+Node: balancesheetequity104785+Ref: #balancesheetequity104936+Node: cashflow106316+Ref: #cashflow106440+Node: check107586+Ref: #check107691+Node: Basic checks108325+Ref: #basic-checks108443+Node: Strict checks108994+Ref: #strict-checks109135+Node: Other checks109571+Ref: #other-checks109711+Node: Custom checks110068+Ref: #custom-checks110188+Node: close110605+Ref: #close110709+Node: close usage112231+Ref: #close-usage112326+Node: codes115139+Ref: #codes115249+Node: commodities115961+Ref: #commodities116090+Node: descriptions116172+Ref: #descriptions116302+Node: diff116606+Ref: #diff116714+Node: files117761+Ref: #files117863+Node: help118010+Ref: #help118112+Node: import118839+Ref: #import118955+Node: Deduplication119820+Ref: #deduplication119945+Node: Import testing121839+Ref: #import-testing122004+Node: Importing balance assignments122492+Ref: #importing-balance-assignments122698+Node: Commodity display styles123347+Ref: #commodity-display-styles123520+Node: incomestatement123649+Ref: #incomestatement123784+Node: notes125089+Ref: #notes125204+Node: payees125572+Ref: #payees125680+Node: prices126206+Ref: #prices126314+Node: print126655+Ref: #print126767+Node: print-unique132082+Ref: #print-unique132210+Node: register132495+Ref: #register132624+Node: Custom register output137070+Ref: #custom-register-output137201+Node: register-match138538+Ref: #register-match138674+Node: rewrite139025+Ref: #rewrite139142+Node: Re-write rules in a file141048+Ref: #re-write-rules-in-a-file141211+Node: Diff output format142360+Ref: #diff-output-format142543+Node: rewrite vs print --auto143635+Ref: #rewrite-vs.-print---auto143795+Node: roi144351+Ref: #roi144451+Node: Spaces and special characters in --inv and --pnl146137+Ref: #spaces-and-special-characters-in---inv-and---pnl146377+Node: Semantics of --inv and --pnl146865+Ref: #semantics-of---inv-and---pnl147104+Node: IRR and TWR explained148954+Ref: #irr-and-twr-explained149114+Node: stats152182+Ref: #stats152283+Node: tags153071+Ref: #tags153171+Node: test153690+Ref: #test153806+Node: About add-on commands154553+Ref: #about-add-on-commands154690+Node: JOURNAL FORMAT155821+Ref: #journal-format155949+Node: Transactions158145+Ref: #transactions158260+Node: Dates159274+Ref: #dates159390+Node: Simple dates159455+Ref: #simple-dates159575+Node: Secondary dates160084+Ref: #secondary-dates160232+Node: Posting dates161568+Ref: #posting-dates161691+Node: Status163063+Ref: #status163173+Node: Code164881+Ref: #code164993+Node: Description165225+Ref: #description165353+Node: Payee and note165673+Ref: #payee-and-note165781+Node: Comments166116+Ref: #comments166238+Node: Tags167432+Ref: #tags-1167543+Node: Postings168936+Ref: #postings169060+Node: Virtual postings170086+Ref: #virtual-postings170197+Node: Account names171502+Ref: #account-names171639+Node: Amounts172127+Ref: #amounts172264+Node: Decimal marks digit group marks173220+Ref: #decimal-marks-digit-group-marks173397+Node: Commodity174269+Ref: #commodity174429+Node: Commodity directives175381+Ref: #commodity-directives175555+Node: Commodity display style176042+Ref: #commodity-display-style176221+Node: Rounding178329+Ref: #rounding178449+Node: Transaction prices178861+Ref: #transaction-prices179027+Node: Lot prices lot dates181458+Ref: #lot-prices-lot-dates181641+Node: Balance assertions182129+Ref: #balance-assertions182307+Node: Assertions and ordering183340+Ref: #assertions-and-ordering183522+Node: Assertions and included files184222+Ref: #assertions-and-included-files184459+Node: Assertions and multiple -f options184792+Ref: #assertions-and-multiple--f-options185042+Node: Assertions and commodities185174+Ref: #assertions-and-commodities185400+Node: Assertions and prices186557+Ref: #assertions-and-prices186765+Node: Assertions and subaccounts187205+Ref: #assertions-and-subaccounts187428+Node: Assertions and virtual postings187752+Ref: #assertions-and-virtual-postings187988+Node: Assertions and precision188130+Ref: #assertions-and-precision188317+Node: Balance assignments188584+Ref: #balance-assignments188754+Node: Balance assignments and prices189918+Ref: #balance-assignments-and-prices190084+Node: Directives190308+Ref: #directives190471+Node: Directives and multiple files195825+Ref: #directives-and-multiple-files196021+Node: Comment blocks196685+Ref: #comment-blocks196862+Node: Including other files197038+Ref: #including-other-files197212+Node: Default year198136+Ref: #default-year198294+Node: Declaring payees198701+Ref: #declaring-payees198867+Node: Declaring commodities199113+Ref: #declaring-commodities199294+Node: Commodity error checking201674+Ref: #commodity-error-checking201824+Node: Default commodity202081+Ref: #default-commodity202261+Node: Declaring market prices203137+Ref: #declaring-market-prices203326+Node: Declaring accounts204139+Ref: #declaring-accounts204319+Node: Account error checking205521+Ref: #account-error-checking205687+Node: Account comments206866+Ref: #account-comments207050+Node: Account subdirectives207474+Ref: #account-subdirectives207659+Node: Account types207972+Ref: #account-types208146+Node: Declaring account types208882+Ref: #declaring-account-types209061+Node: Auto-detected account types209711+Ref: #auto-detected-account-types209952+Node: Interference from auto-detected account types210912+Ref: #interference-from-auto-detected-account-types211189+Node: Old account type syntax211672+Ref: #old-account-type-syntax211869+Node: Account display order212169+Ref: #account-display-order212329+Node: Rewriting accounts213480+Ref: #rewriting-accounts213659+Node: Basic aliases214416+Ref: #basic-aliases214552+Node: Regex aliases215296+Ref: #regex-aliases215458+Node: Combining aliases216177+Ref: #combining-aliases216360+Node: Aliases and multiple files217636+Ref: #aliases-and-multiple-files217835+Node: end aliases218414+Ref: #end-aliases218561+Node: Default parent account218662+Ref: #default-parent-account218852+Node: Periodic transactions219736+Ref: #periodic-transactions219919+Node: Periodic rule syntax221836+Ref: #periodic-rule-syntax222036+Node: Two spaces between period expression and description!222740+Ref: #two-spaces-between-period-expression-and-description223053+Node: Forecasting with periodic transactions223737+Ref: #forecasting-with-periodic-transactions224036+Node: Budgeting with periodic transactions226091+Ref: #budgeting-with-periodic-transactions226324+Node: Auto postings226733+Ref: #auto-postings226869+Node: Auto postings and multiple files229048+Ref: #auto-postings-and-multiple-files229246+Node: Auto postings and dates229455+Ref: #auto-postings-and-dates229723+Node: Auto postings and transaction balancing / inferred amounts / balance assertions229898+Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions230243+Node: Auto posting tags230585+Ref: #auto-posting-tags230794+Node: CSV FORMAT231430+Ref: #csv-format231558+Node: Examples234187+Ref: #examples234290+Node: Basic234498+Ref: #basic234600+Node: Bank of Ireland235142+Ref: #bank-of-ireland235279+Node: Amazon236741+Ref: #amazon236861+Node: Paypal238580+Ref: #paypal238676+Node: CSV rules246320+Ref: #csv-rules246438+Node: skip246771+Ref: #skip246871+Node: fields list247246+Ref: #fields-list247385+Node: field assignment248888+Ref: #field-assignment249040+Node: Field names249968+Ref: #field-names250108+Node: date field250488+Ref: #date-field250608+Node: date2 field250656+Ref: #date2-field250799+Node: status field250855+Ref: #status-field251000+Node: code field251049+Ref: #code-field251196+Node: description field251241+Ref: #description-field251403+Node: comment field251462+Ref: #comment-field251619+Node: account field251834+Ref: #account-field251986+Node: amount field252561+Ref: #amount-field252712+Node: currency field253957+Ref: #currency-field254112+Node: balance field254369+Ref: #balance-field254503+Node: separator254875+Ref: #separator255007+Node: if block255547+Ref: #if-block255674+Node: Matching the whole record256075+Ref: #matching-the-whole-record256252+Node: Matching individual fields257055+Ref: #matching-individual-fields257261+Node: Combining matchers257485+Ref: #combining-matchers257683+Node: Rules applied on successful match257996+Ref: #rules-applied-on-successful-match258189+Node: if table258843+Ref: #if-table258964+Node: end260702+Ref: #end260816+Node: date-format261040+Ref: #date-format261174+Node: decimal-mark262170+Ref: #decimal-mark262317+Node: newest-first262656+Ref: #newest-first262799+Node: include263482+Ref: #include263615+Node: balance-type264059+Ref: #balance-type264181+Node: Tips264881+Ref: #tips264972+Node: Rapid feedback265271+Ref: #rapid-feedback265390+Node: Valid CSV265850+Ref: #valid-csv265982+Node: File Extension266174+Ref: #file-extension266328+Node: Reading multiple CSV files266757+Ref: #reading-multiple-csv-files266944+Node: Valid transactions267185+Ref: #valid-transactions267365+Node: Deduplicating importing267993+Ref: #deduplicating-importing268174+Node: Setting amounts269207+Ref: #setting-amounts269364+Node: Amount signs271805+Ref: #amount-signs271959+Node: Setting currency/commodity272646+Ref: #setting-currencycommodity272834+Node: Amount decimal places274008+Ref: #amount-decimal-places274200+Node: Referencing other fields274512+Ref: #referencing-other-fields274711+Node: How CSV rules are evaluated275608+Ref: #how-csv-rules-are-evaluated275783+Node: TIMECLOCK FORMAT277234+Ref: #timeclock-format277374+Node: TIMEDOT FORMAT279435+Ref: #timedot-format279573+Node: COMMON TASKS284135+Ref: #common-tasks284264+Node: Getting help284671+Ref: #getting-help284805+Node: Constructing command lines285358+Ref: #constructing-command-lines285552+Node: Starting a journal file286249+Ref: #starting-a-journal-file286449+Node: Setting opening balances287637+Ref: #setting-opening-balances287835+Node: Recording transactions290976+Ref: #recording-transactions291158+Node: Reconciling291714+Ref: #reconciling291859+Node: Reporting294116+Ref: #reporting294258+Node: Migrating to a new file298257+Ref: #migrating-to-a-new-file298407+Node: LIMITATIONS298706+Ref: #limitations298834+Node: TROUBLESHOOTING299577+Ref: #troubleshooting299692 End Tag Table
embeddedfiles/hledger.txt view
@@ -6,7050 +6,7070 @@ NAME This is the command-line interface (CLI) for the hledger accounting tool. Here we also describe hledger's concepts and file formats. This- manual is for hledger 1.22.1.--SYNOPSIS- hledger-- hledger [-f FILE] COMMAND [OPTIONS] [ARGS]-- hledger [-f FILE] ADDONCMD -- [OPTIONS] [ARGS]--DESCRIPTION- hledger is a reliable, cross-platform set of programs for tracking- money, time, or any other commodity, using double-entry accounting and- a simple, editable file format. hledger is inspired by and largely- compatible with ledger(1).-- The basic function of the hledger CLI is to read a plain text file- describing financial transactions (in accounting terms, a general jour-- nal) and print useful reports on standard output, or export them as- CSV. hledger can also read some other file formats such as CSV files,- translating them to journal format. Additionally, hledger lists other- hledger-* executables found in the user's $PATH and can invoke them as- subcommands.-- hledger reads data from one or more files in hledger journal, time-- clock, timedot, or CSV format specified with -f, or $LEDGER_FILE, or- $HOME/.hledger.journal (on windows, perhaps- C:/Users/USER/.hledger.journal). If using $LEDGER_FILE, note this must- be a real environment variable, not a shell variable. You can specify- standard input with -f-.-- Transactions are dated movements of money between two (or more) named- accounts, and are recorded with journal entries like this:-- 2015/10/16 bought food- expenses:food $10- assets:cash-- Most users use a text editor to edit the journal, usually with an edi-- tor mode such as ledger-mode for added convenience. hledger's interac-- tive add command is another way to record new transactions. hledger- never changes existing transactions.-- To get started, you can either save some entries like the above in- ~/.hledger.journal, or run hledger add and follow the prompts. Then- try some commands like hledger print or hledger balance. Run hledger- with no arguments for a list of commands.--OPTIONS- General options- To see general usage help, including general options which are sup-- ported by most hledger commands, run hledger -h.-- General help options:-- -h --help- show general or COMMAND help-- --man show general or COMMAND user manual with man-- --info show general or COMMAND user manual with info-- --version- show general or ADDONCMD version-- --debug[=N]- show debug output (levels 1-9, default: 1)-- General input options:-- -f FILE --file=FILE- use a different input file. For stdin, use - (default:- $LEDGER_FILE or $HOME/.hledger.journal)-- --rules-file=RULESFILE- Conversion rules file to use when reading CSV (default:- FILE.rules)-- --separator=CHAR- Field separator to expect when reading CSV (default: ',')-- --alias=OLD=NEW- rename accounts named OLD to NEW-- --anon anonymize accounts and payees-- --pivot FIELDNAME- use some other field or tag for the account name-- -I --ignore-assertions- disable balance assertion checks (note: does not disable balance- assignments)-- -s --strict- do extra error checking (check that all posted accounts are- declared)-- General reporting options:-- -b --begin=DATE- include postings/txns on or after this date (will be adjusted to- preceding subperiod start when using a report interval)-- -e --end=DATE- include postings/txns before this date (will be adjusted to fol-- lowing subperiod end when using a report interval)-- -D --daily- multiperiod/multicolumn report by day-- -W --weekly- multiperiod/multicolumn report by week-- -M --monthly- multiperiod/multicolumn report by month-- -Q --quarterly- multiperiod/multicolumn report by quarter-- -Y --yearly- multiperiod/multicolumn report by year-- -p --period=PERIODEXP- set start date, end date, and/or reporting interval all at once- using period expressions syntax-- --date2- match the secondary date instead (see command help for other- effects)-- -U --unmarked- include only unmarked postings/txns (can combine with -P or -C)-- -P --pending- include only pending postings/txns-- -C --cleared- include only cleared postings/txns-- -R --real- include only non-virtual postings-- -NUM --depth=NUM- hide/aggregate accounts or postings more than NUM levels deep-- -E --empty- show items with zero amount, normally hidden (and vice-versa in- hledger-ui/hledger-web)-- -B --cost- convert amounts to their cost/selling amount at transaction time-- -V --market- convert amounts to their market value in default valuation com-- modities-- -X --exchange=COMM- convert amounts to their market value in commodity COMM-- --value- convert amounts to cost or market value, more flexibly than- -B/-V/-X-- --infer-market-prices- use transaction prices (recorded with @ or @@) as additional- market prices, as if they were P directives-- --auto apply automated posting rules to modify transactions.-- --forecast- generate future transactions from periodic transaction rules,- for the next 6 months or till report end date. In hledger-ui,- also make ordinary future transactions visible.-- --color=WHEN (or --colour=WHEN)- Should color-supporting commands use ANSI color codes in text- output. 'auto' (default): whenever stdout seems to be a color-- supporting terminal. 'always' or 'yes': always, useful eg when- piping output into 'less -R'. 'never' or 'no': never. A- NO_COLOR environment variable overrides this.-- When a reporting option appears more than once in the command line, the- last one takes precedence.-- Some reporting options can also be written as query arguments.-- Command options- To see options for a particular command, including command-specific- options, run: hledger COMMAND -h.-- Command-specific options must be written after the command name, eg:- hledger print -x.-- Additionally, if the command is an add-on, you may need to put its- options after a double-hyphen, eg: hledger ui -- --watch. Or, you can- run the add-on executable directly: hledger-ui --watch.-- Command arguments- Most hledger commands accept arguments after the command name, which- are often a query, filtering the data in some way.-- You can save a set of command line options/arguments in a file, and- then reuse them by writing @FILENAME as a command line argument. Eg:- hledger bal @foo.args. (To prevent this, eg if you have an argument- that begins with a literal @, precede it with --, eg: hledger bal --- @ARG).-- Inside the argument file, each line should contain just one option or- argument. Avoid the use of spaces, except inside quotes (or you'll see- a confusing error). Between a flag and its argument, use = (or noth-- ing). Bad:-- assets depth:2- -X USD-- Good:-- assets- depth:2- -X=USD-- For special characters (see below), use one less level of quoting than- you would at the command prompt. Bad:-- -X"$"-- Good:-- -X$-- See also: Save frequently used options.-- Special characters- Single escaping (shell metacharacters)- In shell command lines, characters significant to your shell - such as- spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want- hledger to see them. This is done by enclosing them in single or dou-- ble quotes, or by writing a backslash before them. Eg to match an- account name containing a space:-- $ hledger register 'credit card'-- or:-- $ 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.- 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- using the bash shell:-- $ hledger balance cur:'\$'-- or:-- $ hledger balance cur:\\$-- Triple escaping (for add-on commands)- When you use hledger to run an external add-on command (described- below), one level of shell-escaping is lost from any options or argu-- ments intended for by the add-on command, so those need an extra level- of shell-escaping. Eg to match a literal $ sign while using the bash- shell and running an add-on command (ui):-- $ hledger ui cur:'\\$'-- or:-- $ hledger ui cur:\\\\$-- If you wondered why four backslashes, perhaps this helps:--- unescaped: $- escaped: \$- double-escaped: \\$- triple-escaped: \\\\$-- Or, you can avoid the extra escaping by running the add-on executable- directly:-- $ hledger-ui cur:\\$-- Less escaping- Options and arguments are sometimes used in places other than the shell- command line, where shell-escaping is not needed, so there you should- use one less level of escaping. Those places include:-- o an @argumentfile-- o hledger-ui's filter field-- o hledger-web's search form-- o GHCI's prompt (used by developers).-- Unicode characters- hledger is expected to handle non-ascii characters correctly:-- o they should be parsed correctly in input files and on the command- line, by all hledger tools (add, iadd, hledger-web's search/add/edit- forms, etc.)-- o they should be displayed correctly by all hledger tools, and on-- screen alignment should be preserved.-- This requires a well-configured environment. Here are some tips:-- o A system locale must be configured, and it must be one that can- decode the characters being used. In bash, you can set a locale like- this: export LANG=en_US.UTF-8. There are some more details in Trou-- bleshooting. This step is essential - without it, hledger will quit- on encountering a non-ascii character (as with all GHC-compiled pro-- grams).-- o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)- must support unicode-- o the terminal must be using a font which includes the required unicode- glyphs-- o the terminal should be configured to display wide characters as dou-- ble width (for report alignment)-- o on Windows, for best results you should run hledger in the same kind- of environment in which it was built. Eg hledger built in the stan-- dard CMD.EXE environment (like the binaries on our download page)- might show display problems when run in a cygwin or msys terminal,- and vice versa. (See eg #961).-- Regular expressions- hledger uses regular expressions in a number of places:-- o query terms, on the command line and in the hledger-web search form:- REGEX, desc:REGEX, cur:REGEX, tag:...=REGEX-- o CSV rules conditional blocks: if REGEX ...-- o account alias directives and options: alias /REGEX/ = REPLACEMENT,- --alias /REGEX/=REPLACEMENT-- hledger's regular expressions come from the regex-tdfa library. If- they're not doing what you expect, it's important to know exactly what- they support:-- 1. they are case insensitive-- 2. they are infix matching (they do not need to match the entire thing- being matched)-- 3. they are POSIX ERE (extended regular expressions)-- 4. they also support GNU word boundaries (\b, \B, \<, \>)-- 5. they do not support backreferences; if you write \1, it will match- the digit 1. Except when doing text replacement, eg in account- aliases, where backreferences can be used in the replacement string- to reference capturing groups in the search regexp.-- 6. they do not support mode modifiers ((?s)), character classes (\w,- \d), or anything else not mentioned above.-- Some things to note:-- o In the alias directive and --alias option, regular expressions must- be enclosed in forward slashes (/REGEX/). Elsewhere in hledger,- these are not required.-- o In queries, to match a regular expression metacharacter like $ as a- literal character, prepend a backslash. Eg to search for amounts- with the dollar sign in hledger-web, write cur:\$.-- o On the command line, some metacharacters like $ have a special mean-- ing to the shell and so must be escaped at least once more. See Spe-- cial characters.--ENVIRONMENT- LEDGER_FILE The journal file path when not specified with -f. Default:- ~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour-- nal).-- A typical value is ~/DIR/YYYY.journal, where DIR is a version-con-- trolled finance directory and YYYY is the current year. Or ~/DIR/cur-- rent.journal, where current.journal is a symbolic link to YYYY.journal.-- On Mac computers, you can set this and other environment variables in a- more thorough way that also affects applications started from the GUI- (say, an Emacs dock icon). Eg on MacOS Catalina I have a- ~/.MacOSX/environment.plist file containing-- {- "LEDGER_FILE" : "~/finance/current.journal"- }-- To see the effect you may need to killall Dock, or reboot.-- COLUMNS The screen width used by the register command. Default: the- full terminal width.-- NO_COLOR If this variable exists with any value, hledger will not use- ANSI color codes in terminal output. This overrides the- --color/--colour option.--DATA FILES- hledger reads transactions from one or more data files. The default- data file is $HOME/.hledger.journal (or on Windows, something like- C:/Users/USER/.hledger.journal).-- You can override this with the $LEDGER_FILE environment variable:-- $ setenv LEDGER_FILE ~/finance/2016.journal- $ hledger stats-- or with one or more -f/--file options:-- $ hledger -f /some/file -f another_file stats-- The file name - means standard input:-- $ cat some.journal | hledger -f--- Data formats- Usually the data file is in hledger's journal format, but it can be in- any of the supported file formats, which currently are:--- Reader: Reads: Used for file exten-- sions:- ------------------------------------------------------------------------------ journal hledger journal files and some Ledger .journal .j .hledger- journals, for transactions .ledger- time- timeclock files, for precise time log- .timeclock- clock ging- timedot timedot files, for approximate time .timedot- logging- csv comma/semicolon/tab/other-separated .csv .ssv .tsv- values, for data import-- These formats are described in their own sections, below.-- hledger detects the format automatically based on the file extensions- shown above. If it can't recognise the file extension, it assumes- journal format. So for non-journal files, it's important to use a- recognised file extension, so as to either read successfully or to show- relevant error messages.-- You can also force a specific reader/format by prefixing the file path- with the format and a colon. Eg, to read a .dat file as csv format:-- $ hledger -f csv:/some/csv-file.dat stats-- Or to read stdin (-) as timeclock format:-- $ echo 'i 2009/13/1 08:00:00' | hledger print -ftimeclock:--- Multiple files- You can specify multiple -f options, to read multiple files as one big- journal. There are some limitations with this:-- o most directives do not affect sibling files-- o balance assertions will not see any account balances from previous- files-- If you need either of those things, you can-- o use a single parent file which includes the others-- o or concatenate the files into one before reading, eg: cat a.journal- b.journal | hledger -f- CMD.-- Strict mode- hledger checks input files for valid data. By default, the most impor-- tant errors are detected, while still accepting easy journal files- without a lot of declarations:-- o Are the input files parseable, with valid syntax ?-- o Are all transactions balanced ?-- o Do all balance assertions pass ?-- With the -s/--strict flag, additional checks are performed:-- o Are all accounts posted to, declared with an account directive ?- (Account error checking)-- o Are all commodities declared with a commodity directive ? (Commodity- error checking)-- o Are all commodity conversions declared explicitly ?-- You can also use the check command to run these and some additional- checks.--TIME PERIODS- Smart dates- hledger's user interfaces accept a flexible "smart date" syntax. Smart- dates allow some english words, can be relative to today's date, and- can have less-significant date parts omitted (defaulting to 1).-- Examples:--- 2004/10/1, 2004-01-01, exact date, several separators allowed. Year- 2004.9.1 is 4+ digits, month is 1-12, day is 1-31- 2004 start of year- 2004/10 start of month- 10/1 month and day in current year- 21 day in current month- october, oct start of month in current year- yesterday, today, tomor- -1, 0, 1 days from today- row- last/this/next -1, 0, 1 periods from the current period- day/week/month/quar-- ter/year- 20181201 8 digit YYYYMMDD with valid year month and day- 201812 6 digit YYYYMM with valid year and month-- Counterexamples - malformed digit sequences might give surprising- results:--- 201813 6 digits with an invalid month is parsed as start of- 6-digit year- 20181301 8 digits with an invalid month is parsed as start of- 8-digit year- 20181232 8 digits with an invalid day gives an error- 201801012 9+ digits beginning with a valid YYYYMMDD gives an error--- Report start & end date- By default, most hledger reports will show the full span of time repre-- sented by the journal data. The report start date will be the earliest- transaction or posting date, and the report end date will be the latest- transaction, posting, or market price date.-- Often you will want to see a shorter time span, such as the current- month. You can specify a start and/or end date using -b/--begin,- -e/--end, -p/--period or a date: query (described below). All of these- accept the smart date syntax.-- Some notes:-- o As in Ledger, end dates are exclusive, so you need to write the date- after the last day you want to include.-- o As noted in reporting options: among start/end dates specified with- options, the last (i.e. right-most) option takes precedence.-- o The effective report start and end dates are the intersection of the- start/end dates from options and that from date: queries. That is,- date:2019-01 date:2019 -p'2000 to 2030' yields January 2019, the- smallest common time span.-- o A report interval (see below) will adjust start/end dates, when- needed, so that they fall on subperiod boundaries.-- Examples:--- -b 2016/3/17 begin on St. Patrick's day 2016- -e 12/1 end at the start of december 1st of the current year- (11/30 will be the last date included)- -b thismonth all transactions on or after the 1st of the current month- -p thismonth all transactions in the current month- date:2016/3/17.. the above written as queries instead (.. can also be- replaced with -)- date:..12/1- date:thismonth..- date:thismonth-- Report intervals- A report interval can be specified so that commands like register, bal-- ance and activity become multi-period, showing each subperiod as a sep-- arate row or column.-- The following "standard" report intervals can be enabled by using their- corresponding flag:-- -D/--daily, -W/--weekly, -M/--monthly, -Q/--quarterly, -Y/--yearly.-- These standard intervals always start on natural interval boundaries:- eg --weekly starts on mondays, --monthly starts on the first of the- month, --yearly always starts on January 1st, etc.-- Certain more complex intervals, and more flexible boundary dates, can- be specified by -p/--period. These are described in period expres-- sions, below.-- Report intervals can only be specified by the flags above, and not by- query arguments, currently.-- Report intervals have another effect: multi-period reports are always- expanded to fill a whole number of subperiods. So if you use a report- interval (other than --daily), and you have specified a start or end- date, you may notice those dates being overridden (ie, the report- starts earlier than your requested start date, or ends later than your- requested end date). This is done to ensure "full" first and last sub-- periods, so that all subperiods' numbers are comparable.-- Period expressions- The -p/--period option accepts period expressions, a shorthand way of- expressing a start date, end date, and/or report interval all at once.-- Here's a basic period expression specifying the first quarter of 2009.- Note, hledger always treats start dates as inclusive and end dates as- exclusive:-- -p "from 2009/1/1 to 2009/4/1"-- Keywords like "from" and "to" are optional, and so are the spaces, as- long as you don't run two dates together. "to" can also be written as- ".." or "-". These are equivalent to the above:--- -p "2009/1/1 2009/4/1"- -p2009/1/1to2009/4/1- -p2009/1/1..2009/4/1-- Dates are smart dates, so if the current year is 2009, the above can- also be written as:--- -p "1/1 4/1"-- -p "january-apr"- -p "this year to 4/1"-- If you specify only one date, the missing start or end date will be the- earliest or latest transaction in your journal:--- -p "from 2009/1/1" everything after january- 1, 2009- -p "from 2009/1" the same- -p "from 2009" the same- -p "to 2009" everything before january- 1, 2009-- A single date with no "from" or "to" defines both the start and end- date like so:--- -p "2009" the year 2009; equivalent- to "2009/1/1 to 2010/1/1"- -p "2009/1" the month of jan; equiva-- lent to "2009/1/1 to- 2009/2/1"- -p "2009/1/1" just that day; equivalent- to "2009/1/1 to 2009/1/2"-- Or you can specify a single quarter like so:--- -p "2009Q1" first quarter of 2009,- equivalent to "2009/1/1 to- 2009/4/1"- -p "q4" fourth quarter of the cur-- rent year-- The argument of -p can also begin with, or be, a report interval- expression. The basic report intervals are daily, weekly, monthly,- quarterly, or yearly, which have the same effect as the -D,-W,-M,-Q, or- -Y flags. Between report interval and start/end dates (if any), the- word in is optional. Examples:--- -p "weekly from 2009/1/1 to 2009/4/1"- -p "monthly in 2008"- -p "quarterly"-- Note that weekly, monthly, quarterly and yearly intervals will always- start on the first day on week, month, quarter or year accordingly, and- will end on the last day of same period, even if associated period- expression specifies different explicit start and end date.-- For example:--- -p "weekly from 2009/1/1 starts on 2008/12/29, closest preceding Mon-- to 2009/4/1" day- -p "monthly in starts on 2018/11/01- 2008/11/25"- -p "quarterly from starts on 2009/04/01, ends on 2009/06/30,- 2009-05-05 to 2009-06-01" which are first and last days of Q2 2009- -p "yearly from starts on 2009/01/01, first day of 2009- 2009-12-29"-- The following more complex report intervals are also supported:- biweekly, fortnightly, bimonthly, every day|week|month|quarter|year,- every N days|weeks|months|quarters|years.-- All of these will start on the first day of the requested period and- end on the last one, as described above.-- Examples:--- -p "bimonthly from 2008" periods will have boundaries on 2008/01/01,- 2008/03/01, ...- -p "every 2 weeks" starts on closest preceding Monday- -p "every 5 month from periods will have boundaries on 2009/03/01,- 2009/03" 2009/08/01, ...-- If you want intervals that start on arbitrary day of your choosing and- span a week, month or year, you need to use any of the following:-- every Nth day of week, every WEEKDAYNAME (eg- mon|tue|wed|thu|fri|sat|sun), every Nth day [of month], every Nth WEEK-- DAYNAME [of month], every MM/DD [of year], every Nth MMM [of year],- every MMM Nth [of year].-- Examples:--- -p "every 2nd day of periods will go from Tue to Tue- week"- -p "every Tue" same- -p "every 15th day" period boundaries will be on 15th of each- month- -p "every 2nd Monday" period boundaries will be on second Monday of- each month- -p "every 11/05" yearly periods with boundaries on 5th of Nov- -p "every 5th Nov" same- -p "every Nov 5th" same-- Show historical balances at end of 15th each month (N is exclusive end- date):-- hledger balance -H -p "every 16th day"-- Group postings from start of wednesday to end of next tuesday (N is- start date and exclusive end date):-- hledger register checking -p "every 3rd day of week"--DEPTH- With the --depth N option (short form: -N), commands like account, bal-- ance and register will show only the uppermost accounts in the account- tree, down to level N. Use this when you want a summary with less- detail. This flag has the same effect as a depth: query argument (so- -2, --depth=2 or depth:2 are equivalent).--QUERIES- One of hledger's strengths is being able to quickly report on a precise- subset of your data. Most hledger commands accept optional query argu-- ments to restrict their scope. The syntax is as follows:-- o Zero or more space-separated query terms. These are most often- account name substrings:-- utilities food:groceries-- o Terms with spaces or other special characters should be enclosed in- quotes:-- "personal care"-- o Regular expressions are also supported:-- "^expenses\b" "accounts (payable|receivable)"-- o Add a query type prefix to match other parts of the data:-- date:202012- desc:amazon cur:USD amt:">100" status:-- o Add a not: prefix to negate a term:-- not:cur:USD-- Query types- Here are the types of query term available. Remember these can also be- prefixed with not: to convert them into a negative match.-- acct:REGEX, REGEX- 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.-- amt:N, amt:<N, amt:<=N, amt:>N, amt:>=N- 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-- erwise, the absolute magnitudes are compared, ignoring sign.-- code:REGEX- Match by transaction code (eg check number).-- cur:REGEX- Match postings or transactions including any amounts whose cur-- rency/commodity symbol is fully matched by REGEX. (For a 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- escaping. So eg to match the dollar sign:- hledger print cur:\\$.-- desc:REGEX- Match transaction descriptions.-- date:PERIODEXPR- Match dates (or with the --date2 flag, secondary dates) within the- specified period. PERIODEXPR is a period expression with no report- interval. Examples:- date:2016, date:thismonth, date:2/1-2/15, date:2021-07-27..nextquarter.-- date2:PERIODEXPR- Match secondary dates within the specified period (independent of the- --date2 flag).-- depth:N- Match (or display, depending on command) accounts at or above this- depth.-- note:REGEX- Match transaction notes (the part of the description right of |, or the- whole description if there's no |).-- payee:REGEX- Match transaction payee/payer names (the part of the description left- of |, or the whole description if there's no |).-- real:, real:0- Match real or virtual postings respectively.-- status:, status:!, status:*- Match unmarked, pending, or cleared transactions respectively.-- tag:REGEX[=REGEX]- Match by tag name, and optionally also by tag value. (To match only by- value, use tag:.=REGEX.) Note that postings also inherit tags from- their transaction, and transactions also acquire tags from their post-- ings, when querying.-- (inacct:ACCTNAME- A special query term used automatically in hledger-web only: tells- hledger-web to show the transaction register for an account.)-- Combining query terms- Most commands select things which match:-- o any of the description terms AND-- o any of the account terms AND-- o any of the status terms AND-- o all the other terms.-- while the print command shows transactions which:-- o match any of the description terms AND-- o have any postings matching any of the positive account terms AND-- o have no postings matching any of the negative account terms AND-- o match all the other terms.-- You can do more powerful queries (such as AND-ing two like terms) by- running a first query with print, and piping the result into a second- hledger command. Eg: how much of food expenses was paid with cash ?-- $ hledger print assets:cash | hledger f- -I balance expenses:food-- If you are interested in full boolean expressions for queries, see- #203.-- Queries and command options- Some queries can also be expressed as command-line options: depth:2 is- equivalent to --depth 2, date:2020 is equivalent to -p 2020, etc. When- you mix command options and query arguments, generally the resulting- query is their intersection.-- Queries and account aliases- When account names are rewritten with --alias or alias, acct: will- match either the old or the new account name.-- Queries and valuation- When amounts are converted to other commodities in cost or value- reports, 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- reversed, see #1625).-- Querying with account aliases- When account names are rewritten with --alias or alias, note that acct:- will match either the old or the new account name.-- Querying with cost or value- When amounts are converted to other commodities in cost or value- reports, 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- discussion at #1625.--COSTING- The -B/--cost flag converts amounts to their cost or sale amount at- transaction time, if they have a transaction price specified. If this- flag is supplied, hledger will perform cost conversion first, and will- apply any market price valuations (if requested) afterwards.--VALUATION- Instead of reporting amounts in their original commodity, hledger can- convert them to cost/sale amount (using the conversion rate recorded in- the transaction), and/or to market value (using some market price on a- certain date). This is controlled by the --value=TYPE[,COMMODITY]- option, 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- valuation commodity, using the market prices in effect on the valuation- date(s), if any. More on these in a minute.-- -X: Value in specified commodity- The -X/--exchange=COMM option is like -V, except you tell it which cur-- rency you want to convert to, and it tries to convert everything to- that.-- Valuation date- Since market prices can change from day to day, market value reports- have a valuation date (or more than one), which determines which market- prices will be used.-- For single period reports, if an explicit report end date is specified,- that will be used as the valuation date; otherwise the valuation date- is the journal's end date.-- For multiperiod reports, each column/period is valued on the last day- of the period, by default.-- Market prices- To convert a commodity A to its market value in another commodity B,- hledger looks for a suitable market price (exchange rate) as follows,- in this order of preference :-- 1. A declared market price or inferred market price: A's latest market- price in B on or before the valuation date as declared by a P direc-- tive, or (with the --infer-market-price flag) inferred from transac-- tion prices.-- 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-- bining the shortest chain of "forward" (only 1 above) market prices,- leading from A to B.-- 4. Any chain of market prices: a chain of any market prices, including- both forward and reverse prices (1 and 2 above), leading from A to- B.-- There is a limit to the length of these price chains; if hledger- reaches that length without finding a complete chain or exhausting all- possibilities, it will give up (with a "gave up" message visible in- --debug=2 output). That limit is currently 1000.-- Amounts for which no suitable market price can be found, are not con-- verted.-- --infer-market-price: market prices from transactions- Normally, market value in hledger is fully controlled by, and requires,- P directives in your journal. Since adding and updating those can be a- chore, and since transactions usually take place at close to market- value, why not use the recorded transaction prices as additional market- prices (as Ledger does) ? We could produce value reports without need-- ing P directives at all.-- Adding the --infer-market-price flag to -V, -X or --value enables this.- So for example, hledger bs -V --infer-market-price will get market- prices both from P directives and from transactions. (And if both- occur on 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.-- --infer-market-price can infer market prices from:-- o multicommodity transactions with explicit prices (@/@@)-- o multicommodity transactions with implicit prices (no @, two commodi-- ties, unbalanced). (With these, the order of postings matters.- hledger print -x can be useful for troubleshooting.)-- o but not, currently, from "more correct" multicommodity transactions- (no @, multiple commodities, balanced).-- Valuation commodity- When you specify a valuation commodity (-X COMM or --value TYPE,COMM):- hledger will convert all amounts to COMM, wherever it can find a suit-- able market price (including by reversing or chaining prices).-- When you leave the valuation commodity unspecified (-V or --value- TYPE):- For each commodity A, hledger picks a default valuation commodity as- follows, in this order of preference:-- 1. The price commodity from the latest P-declared market price for A on- or before valuation date.-- 2. The price commodity from the latest P-declared market price for A on- any date. (Allows conversion to proceed when there are inferred- prices before the valuation date.)-- 3. If there are no P directives at all (any commodity or date) and the- --infer-market-price flag is used: the price commodity from the lat-- est transaction-inferred price for A on or before valuation date.-- This means:-- o If you have P directives, they determine which commodities -V will- convert, and to what.-- o If you have no P directives, and use the --infer-market-price flag,- transaction prices determine it.-- Amounts for which no valuation commodity can be found are not con-- verted.-- Simple valuation examples- Here are some quick examples of -V:-- ; one euro is worth this many dollars from nov 1- P 2016/11/01 EUR $1.10-- ; purchase some euros on nov 3- 2016/11/3- assets:euros EUR100- assets:checking-- ; the euro is worth fewer dollars by dec 21- P 2016/12/21 EUR $1.03-- How many euros do I have ?-- $ hledger -f t.j bal -N euros- EUR100 assets:euros-- What are they worth at end of nov 3 ?-- $ hledger -f t.j bal -N euros -V -e 2016/11/4- $110.00 assets:euros-- What are they worth after 2016/12/21 ? (no report end date specified,- defaults to today)-- $ hledger -f t.j bal -N euros -V- $103.00 assets:euros-- --value: Flexible valuation- -V and -X are special cases of the more general --value option:-- --value=TYPE[,COMM] TYPE is then, end, now or YYYY-MM-DD.- COMM is an optional commodity symbol.- Shows amounts converted to:- - default valuation commodity (or COMM) using market prices at posting dates- - default valuation commodity (or COMM) using market prices at period end(s)- - default valuation commodity (or COMM) using current market prices- - default valuation commodity (or COMM) using market prices at some date-- The TYPE part selects cost or value and valuation date:-- --value=then- Convert amounts to their value in the default valuation commod-- ity, using market prices on each posting's date.-- --value=end- Convert amounts to their value in the default valuation commod-- ity, using market prices on the last day of the report period- (or if unspecified, the journal's end date); or in multiperiod- reports, market prices on the last day of each subperiod.-- --value=now- Convert amounts to their value in the default valuation commod-- ity using current market prices (as of when report is gener-- ated).-- --value=YYYY-MM-DD- Convert amounts to their value in the default valuation commod-- ity using market prices on this date.-- To select a different valuation commodity, add the optional ,COMM part:- a comma, then the target commodity's symbol. Eg: --value=now,EUR.- hledger will do its best to convert amounts to this commodity, deducing- market prices as described above.-- More valuation examples- Here are some examples showing the effect of --value, as seen with- print:-- P 2000-01-01 A 1 B- P 2000-02-01 A 2 B- P 2000-03-01 A 3 B- P 2000-04-01 A 4 B-- 2000-01-01- (a) 1 A @ 5 B-- 2000-02-01- (a) 1 A @ 6 B-- 2000-03-01- (a) 1 A @ 7 B-- Show the cost of each posting:-- $ hledger -f- print --cost- 2000-01-01- (a) 5 B-- 2000-02-01- (a) 6 B-- 2000-03-01- (a) 7 B-- Show the value as of the last day of the report period (2000-02-29):-- $ hledger -f- print --value=end date:2000/01-2000/03- 2000-01-01- (a) 2 B-- 2000-02-01- (a) 2 B-- With no report period specified, that shows the value as of the last- day of the journal (2000-03-01):-- $ hledger -f- print --value=end- 2000-01-01- (a) 3 B-- 2000-02-01- (a) 3 B-- 2000-03-01- (a) 3 B-- Show the current value (the 2000-04-01 price is still in effect today):-- $ hledger -f- print --value=now- 2000-01-01- (a) 4 B-- 2000-02-01- (a) 4 B-- 2000-03-01- (a) 4 B-- Show the value on 2000/01/15:-- $ hledger -f- print --value=2000-01-15- 2000-01-01- (a) 1 B-- 2000-02-01- (a) 1 B-- 2000-03-01- (a) 1 B-- You may need to explicitly set a commodity's display style, when- reverse prices are used. Eg this output might be surprising:-- P 2000-01-01 A 2B-- 2000-01-01- a 1B- b-- $ hledger print -x -X A- 2000-01-01- a 0- b 0-- Explanation: because there's no amount or commodity directive specify-- ing a display style for A, 0.5A gets the default style, which shows no- decimal digits. Because the displayed amount looks like zero, the com-- modity symbol and minus sign are not displayed either. Adding a com-- modity directive sets a more useful display style for A:-- P 2000-01-01 A 2B- commodity 0.00A-- 2000-01-01- a 1B- b-- $ hledger print -X A- 2000-01-01- a 0.50A- b -0.50A-- Effect of valuation on reports- Here is a reference for how valuation is supposed to affect each part- of hledger's reports (and a glossary). (It's wide, you'll have to- scroll sideways.) It may be useful when troubleshooting. If you find- problems, please report them, ideally with a reproducible example.- Related: #329, #1083.--- Report -B, --cost -V, -X --value=then --value=end --value=DATE,- type --value=now- ------------------------------------------------------------------------------------------------ print- posting cost value at value at posting value at value at- amounts report end date report or DATE/today- or today journal end- balance unchanged unchanged unchanged unchanged unchanged- asser-- tions/assign-- ments-- register- starting bal- cost value at day valued at day value at day value at- ance (-H) before each historical before DATE/today- report or posting was made report or- journal journal- start start- posting cost value at value at posting value at value at- amounts report end date report or DATE/today- or today journal end- summary post- summarised value at sum of postings value at value at- ing amounts cost period ends in interval, val- period ends DATE/today- with report ued at interval- interval start- running sum/average sum/average sum/average of sum/average sum/average- total/average of displayed of displayed displayed values of displayed of displayed- values values values values---- balance (bs,- bse, cf, is)- balance sums of value at value at posting value at value at- changes costs report end date report or DATE/today of- or today of journal end sums of post-- sums of of sums of ings- postings postings- budget like balance like balance like balance like bal- like balance- amounts changes changes changes ances changes- (--budget)- grand total sum of dis- sum of dis- sum of displayed sum of dis- sum of dis-- played val- played val- valued played val- played values- ues ues ues-- balance (bs,- bse, cf, is)- with report- interval- starting bal- sums of value at sums of values of value at sums of post-- ances (-H) costs of report start postings before report start ings before- postings of sums of report start at of sums of report start- before all postings respective post- all postings- report start before ing dates before- report start report start- balance sums of same as sums of values of balance value at- changes (bal, costs of --value=end postings in change in DATE/today of- is, bs postings in period at respec- each period, sums of post-- --change, cf period tive posting valued at ings- --change) dates period ends- end balances sums of same as sums of values of period end value at- (bal -H, is costs of --value=end postings from balances, DATE/today of- --H, bs, cf) postings before period valued at sums of post-- from before start to period period ends ings- report start end at respective- to period posting dates- end- budget like balance like balance like balance like bal- like balance- amounts changes/end changes/end changes/end bal- ances changes/end- (--budget) balances balances ances balances- row totals, sums, aver- sums, aver- sums, averages of sums, aver- sums, aver-- row averages ages of dis- ages of dis- displayed values ages of dis- ages of dis-- (-T, -A) played val- played val- played val- played values- ues ues ues- column totals sums of dis- sums of dis- sums of displayed sums of dis- sums of dis-- played val- played val- values played val- played values- ues ues ues- grand total, sum, average sum, average sum, average of sum, average sum, average- grand average of column of column column totals of column of column- totals totals totals totals--- --cumulative is omitted to save space, it works like -H but with a zero- starting balance.-- Glossary:-- cost calculated using price(s) recorded in the transaction(s).-- value market value using available market price declarations, or the- unchanged amount if no conversion rate can be found.-- report start- the first day of the report period specified with -b or -p or- date:, otherwise today.-- report or journal start- the first day of the report period specified with -b or -p or- date:, otherwise the earliest transaction date in the journal,- otherwise today.-- report end- the last day of the report period specified with -e or -p or- date:, otherwise today.-- report or journal end- the last day of the report period specified with -e or -p or- date:, otherwise the latest transaction date in the journal,- otherwise today.-- report interval- a flag (-D/-W/-M/-Q/-Y) or period expression that activates the- report's multi-period mode (whether showing one or many subperi-- ods).--PIVOTING- Normally hledger sums amounts, and organizes them in a hierarchy, based- on account name. The --pivot FIELD option causes it to sum and orga-- nize hierarchy based on the value of some other field instead. FIELD- can be: code, description, payee, note, or the full name (case insensi-- tive) of any tag. As with account names, values containing colon:sepa-- rated:parts will be displayed hierarchically in reports.-- --pivot is a general option affecting all reports; you can think of- hledger transforming the journal before any other processing, replacing- every posting's account name with the value of the specified field on- that posting, inheriting it from the transaction or using a blank value- if it's not present.-- An example:-- 2016/02/16 Member Fee Payment- assets:bank account 2 EUR- income:member fees -2 EUR ; member: John Doe-- Normal balance report showing account names:-- $ hledger balance- 2 EUR assets:bank account- -2 EUR income:member fees- --------------------- 0-- Pivoted balance report, using member: tag values instead:-- $ hledger balance --pivot member- 2 EUR- -2 EUR John Doe- --------------------- 0-- One way to show only amounts with a member: value (using a query,- described below):-- $ hledger balance --pivot member tag:member=.- -2 EUR John Doe- --------------------- -2 EUR-- Another way (the acct: query matches against the pivoted "account- name"):-- $ hledger balance --pivot member acct:.- -2 EUR John Doe- --------------------- -2 EUR--OUTPUT- Output destination- hledger commands send their output to the terminal by default. You can- of course redirect this, eg into a file, using standard shell syntax:-- $ hledger print > foo.txt-- Some commands (print, register, stats, the balance commands) also pro-- vide the -o/--output-file option, which does the same thing without- needing the shell. Eg:-- $ hledger print -o foo.txt- $ hledger print -o - # write to stdout (the default)-- hledger can optionally produce debug output (if enabled with- --debug=N); this goes to stderr, and is not affected by -o/--output-- file. If you need to capture it, use shell redirects, eg: hledger bal- --debug=3 >file 2>&1.-- Output format- Some commands (print, register, the balance commands) offer a choice of- output format. In addition to the usual plain text format (txt), there- are CSV (csv), HTML (html), JSON (json) and SQL (sql). This is con-- trolled by the -O/--output-format option:-- $ hledger print -O csv-- or, by a file extension specified with -o/--output-file:-- $ hledger balancesheet -o foo.html # write HTML to foo.html-- The -O option can be used to override the file extension if needed:-- $ hledger balancesheet -o foo.txt -O html # write HTML to foo.txt-- Some notes about JSON output:-- o This feature is marked experimental, and not yet much used; you- should expect our JSON to evolve. Real-world feedback is welcome.-- o Our JSON is rather large and verbose, as it is quite a faithful rep-- resentation of hledger's internal data types. To understand the- JSON, read the Haskell type definitions, which are mostly in- https://github.com/simonmichael/hledger/blob/master/hledger-- lib/Hledger/Data/Types.hs.-- o hledger represents quantities as Decimal values storing up to 255- significant digits, eg for repeating decimals. Such numbers can- arise in practice (from automatically-calculated transaction prices),- and would break most JSON consumers. So in JSON, we show quantities- as simple Numbers with at most 10 decimal places. We don't limit the- number of integer digits, but that part is under your control. We- hope this approach will not cause problems in practice; if you find- otherwise, please let us know. (Cf #1195)-- Notes about SQL output:-- o SQL output is also marked experimental, and much like JSON could use- real-world feedback.-- o SQL output is expected to work with sqlite, MySQL and PostgreSQL-- o SQL output is structured with the expectations that statements will- be executed in the empty database. If you already have tables cre-- ated via SQL output of hledger, you would probably want to either- clear tables of existing data (via delete or truncate SQL statements)- or drop tables completely as otherwise your postings will be duped.--COMMANDS- hledger provides a number of commands for producing reports and manag-- ing your data. Run hledger with no arguments to list the commands- available, and hledger CMD to run a command. CMD can be the full com-- mand name, or its standard abbreviation shown in the commands list, or- any unambiguous prefix of the name. Eg: hledger bal.-- Here are the built-in commands, with the most often-used in bold:-- Data entry:-- These data entry commands are the only ones which can modify your jour-- nal file.-- o add - add transactions using guided prompts-- o import - add any new transactions from other files (eg csv)-- Data management:-- o check - check for various kinds of issue in the data-- o close (equity) - generate balance-resetting transactions-- o diff - compare account transactions in two journal files-- o rewrite - generate extra postings, similar to print --auto-- Financial statements:-- o aregister (areg) - show transactions in a particular account-- o balancesheet (bs) - show assets, liabilities and net worth-- o balancesheetequity (bse) - show assets, liabilities and equity-- o cashflow (cf) - show changes in liquid assets-- o incomestatement (is) - show revenues and expenses-- o roi - show return on investments-- Miscellaneous reports:-- o accounts - show account names-- o activity - show postings-per-interval bar charts-- o balance (bal) - show balance changes/end balances/budgets in any- accounts-- o codes - show transaction codes-- o commodities - show commodity/currency symbols-- o descriptions - show unique transaction descriptions-- o files - show input file paths-- o help - show hledger user manuals in several formats-- o notes - show unique note segments of transaction descriptions-- o payees - show unique payee segments of transaction descriptions-- o prices - show market price records-- o print - show transactions (journal entries)-- o print-unique - show only transactions with unique descriptions-- o register (reg) - show postings in one or more accounts & running- total-- o register-match - show a recent posting that best matches a descrip-- tion-- o stats - show journal statistics-- o tags - show tag names-- o test - run self tests-- Add-on commands:-- Programs or scripts named hledger-SOMETHING in your PATH are add-on- commands; these appear in the commands list with a + mark. Two of- these are maintained and released with hledger:-- o ui - an efficient terminal interface (TUI) for hledger-- o web - a simple web interface (WUI) for hledger-- And these add-ons are maintained separately:-- o iadd - a more interactive alternative for the add command-- o interest - generates interest transactions according to various- schemes-- o stockquotes - downloads market prices for your commodities from- AlphaVantage (experimental)-- Next, the detailed command docs, in alphabetical order.-- accounts- accounts- Show account names.-- This command lists account names, either declared with account direc-- tives (--declared), posted to (--used), or both (the default). With- query arguments, only matched account names and account names refer-- enced by matched postings are shown. It shows a flat list by default.- With --tree, it uses indentation to show the account hierarchy. In- flat mode you can add --drop N to omit the first few account name com-- ponents. Account names can be depth-clipped with depth:N or --depth N- or -N.-- Examples:-- $ hledger accounts- assets:bank:checking- assets:bank:saving- assets:cash- expenses:food- expenses:supplies- income:gifts- income:salary- liabilities:debts-- activity- activity- Show an ascii barchart of posting counts per interval.-- The activity command displays an ascii histogram showing transaction- counts by day, week, month or other reporting interval (by day is the- default). With query arguments, it counts only matched transactions.-- Examples:-- $ hledger activity --quarterly- 2008-01-01 **- 2008-04-01 *******- 2008-07-01- 2008-10-01 **-- add- add- Prompt for transactions and add them to the journal. Any arguments- will be used as default inputs for the first N prompts.-- Many hledger users edit their journals directly with a text editor, or- generate them from CSV. For more interactive data entry, there is the- add command, which prompts interactively on the console for new trans-- actions, and appends them to the journal file (if there are multiple -f- FILE options, the first file is used.) Existing transactions are not- changed. This is the only hledger command that writes to the journal- file.-- To use it, just run hledger add and follow the prompts. You can add as- many transactions as you like; when you are finished, enter . or press- control-d or control-c to exit.-- Features:-- o add tries to provide useful defaults, using the most similar (by- description) recent transaction (filtered by the query, if any) as a- template.-- o You can also set the initial defaults with command line arguments.-- o Readline-style edit keys can be used during data entry.-- o The tab key will auto-complete whenever possible - accounts, descrip-- tions, dates (yesterday, today, tomorrow). If the input area is- empty, it will insert the default value.-- o If the journal defines a default commodity, it will be added to any- bare numbers entered.-- o A parenthesised transaction code may be entered following a date.-- o Comments and tags may be entered following a description or amount.-- o If you make a mistake, enter < at any prompt to go one step backward.-- o Input prompts are displayed in a different colour when the terminal- supports it.-- Example (see the tutorial for a detailed explanation):-- $ hledger add- Adding transactions to journal file /src/hledger/examples/sample.journal- Any command line arguments will be used as defaults.- Use tab key to complete, readline keys to edit, enter to accept defaults.- An optional (CODE) may follow transaction dates.- An optional ; COMMENT may follow descriptions or amounts.- If you make a mistake, enter < at any prompt to go one step backward.- To end a transaction, enter . when prompted.- To quit, enter . at a date prompt or press control-d or control-c.- Date [2015/05/22]:- Description: supermarket- Account 1: expenses:food- Amount 1: $10- Account 2: assets:checking- Amount 2 [$-10.0]:- Account 3 (or . or enter to finish this transaction): .- 2015/05/22 supermarket- expenses:food $10- assets:checking $-10.0-- Save this transaction to the journal ? [y]:- Saved.- Starting the next transaction (. or ctrl-D/ctrl-C to quit)- Date [2015/05/22]: <CTRL-D> $-- On Microsoft Windows, the add command makes sure that no part of the- file path ends with a period, as that would cause problems (#1056).-- aregister- aregister, areg-- Show the transactions and running historical balance in an account,- with each line item representing one transaction.-- aregister shows the transactions affecting a particular account and its- subaccounts, with each line item representing a whole transaction - as- in bank statements, hledger-ui, hledger-web and other accounting apps.-- Note this is unlike the register command, which shows individual post-- ings and does not always show a single account or a historical balance.-- A reminder, "historical" balances include any balance from transactions- before the report start date, so (if opening balances are recorded cor-- rectly) aregister will show the real-world balances of an account, as- you would see in a bank statement.-- As a quick rule of thumb, use aregister for reconciling real-world- asset/liability accounts and register for reviewing detailed rev-- enues/expenses.-- aregister shows the register for just one account (and its subac-- counts). This account must be specified as the first argument. You- can write either the full account name, or a case-insensitive regular- expression which will select the alphabetically first matched account.- (Eg if you have assets:aaa:checking and assets:bbb:checking accounts,- hledger areg checking would select assets:aaa:checking.)-- Any additional arguments form a query which will filter the transac-- tions shown.-- Each aregister line item shows:-- 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- (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- the -E/--empty flag to show them.-- aregister ignores a depth limit, so its final total will always match a- balance report with similar arguments.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, and json.-- aregister and custom posting dates- Transactions whose date is outside the report period can still be- shown, if they have a posting to this account dated inside the report- period. (And in this case it's the posting date that is shown.) This- ensures that aregister can show an accurate historical running balance,- matching the one shown by register -H with the same arguments.-- To filter strictly by transaction date instead, add the --txn-dates- flag. If you use this flag and some of your postings have custom- dates, it's probably best to assume the running balance is wrong.-- Examples:-- Show all transactions and historical running balance in the first- account whose name contains "checking":-- $ hledger areg checking-- Show transactions and historical running balance in all asset accounts- during july:-- $ hledger areg assets date:jul-- balance- balance, bal- Show accounts and their balances.-- 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.-- Note there are some higher-level variants of the balance command with- convenient defaults, which can be simpler to use: balancesheet, bal-- ancesheetequity, cashflow and incomestatement. When you need more con-- 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- higher-level commands as well.-- balance can show..-- o accounts as a list (-l) or a tree (-t)-- o optionally depth-limited (-[1-9])-- o sorted by declaration order and name, or by amount-- ..and their..-- o balance changes (the default)-- o or actual and planned balance changes (--budget)-- o or value of balance changes (-V)-- o or change of balance values (--valuechange)-- ..in..-- o one time period (the whole journal period by default)-- o or multiple periods (-D, -W, -M, -Q, -Y, -p INTERVAL)-- ..either..-- o per period (the default)-- o or accumulated since report start date (--cumulative)-- o or accumulated since account creation (--historical/-H)-- ..possibly converted to..-- o cost (--value=cost[,COMM]/--cost/-B)-- o or market value, as of transaction dates (--value=then[,COMM])-- o or at period ends (--value=end[,COMM])-- o or now (--value=now)-- o or at some other date (--value=YYYY-MM-DD)-- ..with..-- o totals (-T), averages (-A), percentages (-%), inverted sign- (--invert)-- o rows and columns swapped (--transpose)-- o another field used as account name (--pivot)-- o custom-formatted line items (single-period reports only) (--format)-- This command supports the output destination and output format options,- with output formats txt, csv, json, and (multi-period reports only:)- html. In txt output in a colour-supporting terminal, negative amounts- are shown in red.-- Simple balance report- With no arguments, balance shows a list of all accounts and their- change of balance - ie, the sum of posting amounts, both inflows and- outflows - during the entire period of the journal. For real-world- accounts, this should also match their end balance at the end of the- journal period (more on this below).-- Accounts are sorted by declaration order if any, and then alphabeti-- cally by account name. For instance, using examples/sample.journal:-- $ hledger bal- $1 assets:bank:saving- $-2 assets:cash- $1 expenses:food- $1 expenses:supplies- $-1 income:gifts- $-1 income:salary- $1 liabilities:debts- --------------------- 0-- 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- (revealing assets:bank:checking here):-- $ hledger -f examples/sample.journal bal -E- 0 assets:bank:checking- $1 assets:bank:saving- $-2 assets:cash- $1 expenses:food- $1 expenses:supplies- $-1 income:gifts- $-1 income:salary- $1 liabilities:debts- --------------------- 0-- The total of the amounts displayed is shown as the last line, unless- -N/--no-total is used.-- Filtered balance report- 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:-- $ hledger bal --cleared assets date:200806- $-2 assets:cash- --------------------- $-2-- List or tree mode- By default, or with -l/--flat, accounts are shown as a flat list with- their full names visible, as in the examples above.-- With -t/--tree, the account hierarchy is shown, with subaccounts'- "leaf" names indented below their parent:-- $ hledger balance- $-1 assets- $1 bank:saving- $-2 cash- $2 expenses- $1 food- $1 supplies- $-2 income- $-1 gifts- $-1 salary- $1 liabilities:debts- --------------------- 0-- 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- above).-- 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.-- o Each group of sibling accounts (ie, under a common parent) is sorted- separately.-- Depth limiting- With a depth:N query, or --depth N option, or just -N, balance reports- will show accounts only to the specified depth, hiding the deeper sub-- accounts. Account balances at the depth limit always include the bal-- ances from any hidden subaccounts (even in list mode). This can be- useful for getting an overview. Eg, limiting to depth 1:-- $ hledger balance -N -1- $-1 assets- $2 expenses- $-2 income- $1 liabilities-- You can also hide top-level account name parts, using --drop N. This- can be useful for hiding repetitive top-level account names:-- $ hledger bal expenses --drop 1- $1 food- $1 supplies- --------------------- $2--- Multi-period balance report- With a report interval (set by the -D/--daily, -W/--weekly,- -M/--monthly, -Q/--quarterly, -Y/--yearly, or -p/--period flag), bal-- ance shows a tabular report, with columns representing successive time- periods (and a title):-- $ hledger balance --quarterly income expenses -E- Balance changes in 2008:-- || 2008q1 2008q2 2008q3 2008q4- ===================++=================================- expenses:food || 0 $1 0 0- expenses:supplies || 0 $1 0 0- income:gifts || 0 $-1 0 0- income:salary || $-1 0 0 0- -------------------++---------------------------------- || $-1 $1 0 0-- Notes:-- o The report's start/end dates will be expanded, if necessary, to fully- encompass the displayed subperiods (so that the first and last subpe-- riods have the same duration as the others).-- o Leading and trailing periods (columns) containing all zeroes are not- shown, unless -E/--empty is used.-- o Accounts (rows) containing all zeroes are not shown, unless- -E/--empty is used.-- o Amounts with many commodities are shown in abbreviated form, unless- --no-elide is used. (experimental)-- o Average and/or total columns can be added with the -A/--average and- -T/--row-total flags.-- o The --transpose flag can be used to exchange rows and columns.-- o The --pivot FIELD option causes a different transaction field to be- used as "account name". See PIVOTING.-- Multi-period reports with many periods can be too wide for easy viewing- in the terminal. Here are some ways to handle that:-- o Hide the totals row with -N/--no-total-- o Convert to a single currency with -V-- o Maximize the terminal window-- o Reduce the terminal's font size-- 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- 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 &&- open a.html-- 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.-- Revenues and liability balances are typically negative, however, so -S- shows these in reverse order. To work around this, you can add- --invert to flip the signs. (Or, use one of the higher-level reports,- which flip the sign automatically. Eg: hledger incomestatement -MAS).--- Percentages- With -%/--percent, balance reports show each account's value expressed- as a percentage of the (column) total:-- $ hledger bal expenses -Q -%- Balance changes in 2008:-- || 2008Q1 2008Q2 2008Q3 2008Q4- ===================++=================================- expenses:food || 0 50.0 % 0 0- expenses:supplies || 0 50.0 % 0 0- -------------------++---------------------------------- || 0 100.0 % 0 0-- Note it is not useful to calculate percentages if the amounts in a col-- umn have mixed signs. In this case, make a separate report for each- sign, eg:-- $ hledger bal -% amt:`>0`- $ hledger bal -% amt:`<0`-- Similarly, if the amounts in a column have mixed commodities, convert- them to one commodity with -B, -V, -X or --value, or make a separate- report for each commodity:-- $ hledger bal -% cur:\\$- $ hledger bal -% cur:EUR-- Balance change, end balance- 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- account 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- your timezone). It is the sum of previous 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!)-- In general, balance changes are what you want to see when reviewing- revenues and expenses, and historical end balances are what you want to- see when reviewing or reconciling asset, liability and equity accounts.-- 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- journal covers the account's full lifetime.-- 2. Include all of of the account's prior postings in the report, by not- specifying a report start date, or by using the -H/--historical- flag. (-H causes report start date to be ignored when summing post-- ings.)-- Balance report types- For more flexible reporting, there are three important option groups:-- hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]- ...-- The first two are the most important: calculation type selects the- basic calculation to perform for each table cell, while accumulation- type says which postings should be included in each cell's calculation.- Typically one or both of these are selected by default, so you don't- need to write them explicitly. A valuation type can be added if you- want to convert the basic report to value or cost.-- Calculation type:- The basic calculation to perform for each table cell. It is one of:-- o --sum : sum the posting amounts (default)-- o --budget : like --sum but also show a goal amount-- o --valuechange : show the change in period-end historical balance val-- ues-- Accumulation type:- Which postings should be included in each cell's calculation. It is- one of:-- o --change : postings from column start to column end, ie within the- cell's period. Typically used to see revenues/expenses. (default- for balance, incomestatement)-- o --cumulative : postings from report start to column end, eg to show- changes accumulated since the report's start date. Rarely used.-- o --historical/-H : postings from journal start to column end, ie all- postings from account creation to the end of the cell's period. Typ-- ically used to see historical end balances of assets/liabili-- ties/equity. (default for balancesheet, balancesheetequity, cash-- flow)-- Valuation type:- Which kind of valuation, valuation date(s) and optionally a target val-- uation commodity to use. It is one of:-- o no valuation, show amounts in their original commodities (default)-- o --value=cost[,COMM] : no valuation, show amounts converted to cost-- o --value=then[,COMM] : show value at transaction dates-- o --value=end[,COMM] : show value at period end date(s) (default with- --valuechange)-- o --value=now[,COMM] : show value at today's date-- o --value=YYYY-MM-DD[,COMM] : show value at another date-- or one of their aliases: --cost/-B, --market/-V or --exchange/-X.-- 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-- ancesheet/balancesheetequity commands-- o --cumulative or --historical disables --row-total/-T-- For reference, here is what the combinations of accumulation and valua-- tion show:--- Valua- no valuation --value= then --value= end --value= YYYY-- tion: MM-DD /now- >Accumu-- lation:- v- ------------------------------------------------------------------------------------- --change change in period sum of posting- period-end DATE-value of- date market val- value of change change in- ues in period in period period- --cumu- change from sum of posting- period-end DATE-value of- lative report 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 end bal- start to period start to period to period end- ance) end end-- Useful balance reports- Some frequently used balance options/reports are:-- o bal -M revenues expenses- 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- available as the balancesheet command.-- o bal -M -H assets liabilities equity- 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- cashflow command.-- Also:-- o bal -M expenses -2 -SA- Show monthly expenses summarised to depth 2 and sorted by average- amount.-- o bal -M --budget expenses- Show monthly expenses and budget goals.-- o bal -M --valuechange investments- Show monthly change in market value of investment assets.-- o bal investments --valuechange -D date:lastweek amt:'>1000' -STA- [--invert]- Show top gainers [or losers] last week-- Budget report- The --budget report type activates extra columns showing any budget- goals for each account and period. The budget goals are defined by- periodic transactions. This is very useful for comparing planned and- actual income, expenses, time usage, etc.-- For example, you can take average monthly expenses in the common- expense categories to construct a minimal monthly budget:-- ;; Budget- ~ monthly- income $2000- expenses:food $400- expenses:bus $50- expenses:movies $30- assets:bank:checking-- ;; Two months worth of expenses- 2017-11-01- income $1950- expenses:food $396- expenses:bus $49- expenses:movies $30- expenses:supplies $20- assets:bank:checking-- 2017-12-01- income $2100- expenses:food $412- expenses:bus $53- expenses:gifts $100- assets:bank:checking-- You can now see a monthly budget report:-- $ hledger balance -M --budget- Budget performance in 2017/11/01-2017/12/31:-- || Nov Dec- ======================++====================================================- assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- expenses || $495 [ 103% of $480] $565 [ 118% of $480]- expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]- expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]- expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]- income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]- ----------------------++----------------------------------------------------- || 0 [ 0] 0 [ 0]-- This is different from a normal balance report in several ways:-- o Only accounts with budget goals during the report period are shown,- by default.-- o In each column, in square brackets after the actual amount, budget- goal amounts are shown, and the actual/goal percentage. (Note: bud-- get goals should be in the same commodity as the actual amount.)-- o All parent accounts are always shown, even in list mode. Eg assets,- assets:bank, and expenses above.-- o Amounts always include all subaccounts, budgeted or unbudgeted, even- in list mode.-- This means that the numbers displayed will not always add up! Eg above,- the expenses actual amount includes the gifts and supplies transac-- tions, but the expenses:gifts and expenses:supplies accounts are not- shown, as they have no budget amounts declared.-- This can be confusing. When you need to make things clearer, use the- -E/--empty flag, which will reveal all accounts including unbudgeted- ones, giving the full picture. Eg:-- $ hledger balance -M --budget --empty- Budget performance in 2017/11/01-2017/12/31:-- || Nov Dec- ======================++====================================================- assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- expenses || $495 [ 103% of $480] $565 [ 118% of $480]- expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]- expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]- expenses:gifts || 0 $100- expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]- expenses:supplies || $20 0- income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]- ----------------------++----------------------------------------------------- || 0 [ 0] 0 [ 0]-- You can roll over unspent budgets to next period with --cumulative:-- $ hledger balance -M --budget --cumulative- Budget performance in 2017/11/01-2017/12/31:-- || Nov Dec- ======================++====================================================- assets || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]- assets:bank || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]- assets:bank:checking || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]- expenses || $495 [ 103% of $480] $1060 [ 110% of $960]- expenses:bus || $49 [ 98% of $50] $102 [ 102% of $100]- expenses:food || $396 [ 99% of $400] $808 [ 101% of $800]- expenses:movies || $30 [ 100% of $30] $30 [ 50% of $60]- income || $1950 [ 98% of $2000] $4050 [ 101% of $4000]- ----------------------++----------------------------------------------------- || 0 [ 0] 0 [ 0]-- For more examples and notes, see Budgeting.-- Budget report start date- This might be a bug, but for now: when making budget reports, it's a- good idea to explicitly set the report's start date to the first day of- a reporting period, because a periodic rule like ~ monthly generates- its transactions on the 1st of each month, and if your journal has no- regular transactions on the 1st, the default report start date could- exclude that budget goal, which can be a little surprising. Eg here- the default report period is just the day of 2020-01-15:-- ~ monthly in 2020- (expenses:food) $500-- 2020-01-15- expenses:food $400- assets:checking-- $ hledger bal expenses --budget- Budget performance in 2020-01-15:-- || 2020-01-15- ==============++============- <unbudgeted> || $400- --------------++------------- || $400-- To avoid this, specify the budget report's period, or at least the- start date, with -b/-e/-p/date:, to ensure it includes the budget goal- transactions (periodic transactions) that you want. Eg, adding -b- 2020/1/1 to the above:-- $ hledger bal expenses --budget -b 2020/1/1- Budget performance in 2020-01-01..2020-01-15:-- || 2020-01-01..2020-01-15- ===============++========================- expenses:food || $400 [80% of $500]- ---------------++------------------------- || $400 [80% of $500]-- Nested budgets- You can add budgets to any account in your account hierarchy. If you- have budgets on both parent account and some of its children, then bud-- get(s) of the child account(s) would be added to the budget of their- parent, much like account balances behave.-- In the most simple case this means that once you add a budget to any- account, all its parents would have budget as well.-- To illustrate this, consider the following budget:-- ~ monthly from 2019/01- expenses:personal $1,000.00- expenses:personal:electronics $100.00- liabilities-- With this, monthly budget for electronics is defined to be $100 and- budget for personal expenses is an additional $1000, which implicitly- means that budget for both expenses:personal and expenses is $1100.-- Transactions in expenses:personal:electronics will be counted both- towards its $100 budget and $1100 of expenses:personal , and transac-- tions in any other subaccount of expenses:personal would be counted- towards only towards the budget of expenses:personal.-- For example, let's consider these transactions:-- ~ monthly from 2019/01- expenses:personal $1,000.00- expenses:personal:electronics $100.00- liabilities-- 2019/01/01 Google home hub- expenses:personal:electronics $90.00- liabilities $-90.00-- 2019/01/02 Phone screen protector- expenses:personal:electronics:upgrades $10.00- liabilities-- 2019/01/02 Weekly train ticket- expenses:personal:train tickets $153.00- liabilities-- 2019/01/03 Flowers- expenses:personal $30.00- liabilities-- As you can see, we have transactions in expenses:personal:electron-- ics:upgrades and expenses:personal:train tickets, and since both of- these accounts are without explicitly defined budget, these transac-- tions would be counted towards budgets of expenses:personal:electronics- and expenses:personal accordingly:-- $ hledger balance --budget -M- Budget performance in 2019/01:-- || Jan- ===============================++===============================- expenses || $283.00 [ 26% of $1100.00]- expenses:personal || $283.00 [ 26% of $1100.00]- expenses:personal:electronics || $100.00 [ 100% of $100.00]- liabilities || $-283.00 [ 26% of $-1100.00]- -------------------------------++-------------------------------- || 0 [ 0]-- And with --empty, we can get a better picture of budget allocation and- consumption:-- $ hledger balance --budget -M --empty- Budget performance in 2019/01:-- || Jan- ========================================++===============================- expenses || $283.00 [ 26% of $1100.00]- expenses:personal || $283.00 [ 26% of $1100.00]- expenses:personal:electronics || $100.00 [ 100% of $100.00]- expenses:personal:electronics:upgrades || $10.00- expenses:personal:train tickets || $153.00- liabilities || $-283.00 [ 26% of $-1100.00]- ----------------------------------------++-------------------------------- || 0 [ 0]-- Customising single-period balance reports- For single-period balance reports displayed in the terminal (only), you- can use --format FMT to customise the format and content of each line.- Eg:-- $ hledger balance --format "%20(account) %12(total)"- assets $-1- bank:saving $1- cash $-2- expenses $2- food $1- supplies $1- income $-2- gifts $-1- salary $-1- liabilities:debts $1- ---------------------------------- 0-- The FMT format string (plus a newline) specifies the formatting applied- to each account/balance pair. It may contain any suitable text, with- data fields interpolated like so:-- %[MIN][.MAX](FIELDNAME)-- o MIN pads with spaces to at least this width (optional)-- o MAX truncates at this width (optional)-- o FIELDNAME must be enclosed in parentheses, and can be one of:-- o depth_spacer - a number of spaces equal to the account's depth, or- if MIN is specified, MIN * depth spaces.-- o account - the account's name-- o total - the account's balance/posted total, right justified-- Also, FMT can begin with an optional prefix to control how multi-com-- modity amounts are rendered:-- o %_ - render on multiple lines, bottom-aligned (the default)-- o %^ - render on multiple lines, top-aligned-- o %, - render on one line, comma-separated-- There are some quirks. Eg in one-line mode, %(depth_spacer) has no- effect, instead %(account) has indentation built in. Experimentation- may be needed to get pleasing results.-- Some example formats:-- o %(total) - the account's total-- o %-20.20(account) - the account's name, left justified, padded to 20- characters and clipped at 20 characters-- o %,%-50(account) %25(total) - account name padded to 50 characters,- total padded to 20 characters, with multiple commodities rendered on- one line-- o %20(total) %2(depth_spacer)%-(account) - the default format for the- single-column balance report-- balancesheet- balancesheet, bs- This command displays a balance sheet, showing historical ending bal-- ances of asset and liability accounts. (To see equity as well, use the- balancesheetequity command.) Amounts are shown with normal positive- sign, as in conventional financial statements.-- The asset and liability accounts shown are those accounts declared with- the Asset or Cash or Liability type, or otherwise all accounts under a- top-level asset or liability account (case insensitive, plurals- allowed).-- Example:-- $ hledger balancesheet- Balance Sheet-- Assets:- $-1 assets- $1 bank:saving- $-2 cash- --------------------- $-1-- Liabilities:- $1 liabilities:debts- --------------------- $1-- Total:- --------------------- 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- flipped.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, html, and (experi-- mental) json.-- balancesheetequity- balancesheetequity, bse- This command displays a balance sheet, showing historical ending bal-- ances of asset, liability and equity accounts. Amounts are shown with- normal positive sign, as in conventional financial statements.-- The asset, liability and equity accounts shown are those accounts- declared with the Asset, Cash, Liability or Equity type, or otherwise- all accounts under a top-level asset, liability or equity account (case- insensitive, plurals allowed).-- Example:-- $ hledger balancesheetequity- Balance Sheet With Equity-- Assets:- $-2 assets- $1 bank:saving- $-3 cash- --------------------- $-2-- Liabilities:- $1 liabilities:debts- --------------------- $1-- Equity:- $1 equity:owner- --------------------- $1-- Total:- --------------------- 0-- This command 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 equity, but with- smarter account detection, and liabilities/equity displayed with their- sign flipped.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, html, and (experi-- mental) json.-- cashflow- cashflow, cf- This command displays a cashflow statement, showing the inflows and- outflows affecting "cash" (ie, liquid) assets. Amounts are shown with- normal positive sign, as in conventional financial statements.-- The "cash" accounts shown are those accounts declared with the Cash- type, or otherwise all accounts under a top-level asset account (case- insensitive, plural allowed) which do not have fixed, investment,- receivable or A/R in their name.-- Example:-- $ hledger cashflow- Cashflow Statement-- Cash flows:- $-1 assets- $1 bank:saving- $-2 cash- --------------------- $-1-- Total:- --------------------- $-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- not:receivable, but with smarter account detection.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, html, and (experi-- mental) json.-- check- check- Check for various kinds of errors in your data.-- hledger provides a number of built-in error checks to help prevent- problems in your data. Some of these are run automatically; or, you- can use this check command to run them on demand, with no output and a- zero exit code if all is well. Specify their names (or a prefix) as- argument(s).-- Some examples:-- hledger check # basic checks- hledger check -s # basic + strict checks- hledger check ordereddates payees # basic + two other checks-- Here are the checks currently available:-- Basic checks- These checks are always run automatically, by (almost) all hledger com-- mands, including check:-- 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 transaction prices or automatically-inferred transaction prices-- o assertions - all balance assertions in the journal are passing.- (This check can be disabled with -I/--ignore-assertions.)-- Strict checks- These additional checks are run when the -s/--strict (strict mode) flag- is used. Or, they can be run by giving their names as arguments to- check:-- o accounts - all account names used by transactions have been declared-- o commodities - all commodity symbols used have been declared-- o balancednoautoconversion - transactions are balanced, possibly using- explicit transaction prices but not inferred ones-- 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,- therefore optional:-- o ordereddates - transactions are ordered by date within each file-- o payees - all payees 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- https://github.com/simonmichael/hledger/tree/master/bin:-- o hledger-check-tagfiles - all tag values containing / (a forward- slash) exist as file paths-- o hledger-check-fancyassertions - more complex balance assertions are- passing-- You could make similar scripts to perform your own custom checks. See:- Cookbook -> Scripting.-- close- close, equity- Prints a "closing balances" transaction and an "opening balances"- transaction that bring account balances to and from zero, respectively.- These can be added to your journal file(s), eg to bring asset/liability- balances forward into a new journal file, or to close out rev-- enues/expenses to retained earnings at the end of a period.-- You can print just one of these transactions by using the --close or- --open flag. You can customise their descriptions with the --close-- desc and --open-desc options.-- One amountless posting to "equity:opening/closing balances" is added to- balance the transactions, by default. You can customise this account- name with --close-acct and --open-acct; if you specify only one of- these, it will be used for both.-- With --x/--explicit, the equity posting's amount will be shown. And if- it involves multiple commodities, a posting for each commodity will be- shown, as with the print command.-- With --interleaved, the equity postings are shown next to the postings- they balance, which makes troubleshooting easier.-- By default, transaction prices in the journal are ignored when generat-- ing the closing/opening transactions. With --show-costs, this cost- information is preserved (balance -B reports will be unchanged after- the transition). Separate postings are generated for each cost in each- commodity. Note this can generate very large journal entries, if you- have many foreign currency or investment transactions.-- close usage- If you split your journal files by time (eg yearly), you will typically- run this command at the end of the year, and save the closing transac-- tion as last entry of the old file, and the opening transaction as the- first entry of the new file. This makes the files self contained, so- that correct balances are reported no matter which of them are loaded.- Ie, if you load just one file, the balances are initialised correctly;- or if you load several files, the redundant closing/opening transac-- tions cancel each other out. (They will show up in print or register- reports; you can exclude them with a query like not:desc:'(open-- ing|closing) balances'.)-- If you're running a business, you might also use this command to "close- the books" at the end of an accounting period, transferring income- statement account balances to retained earnings. (You may want to- change the equity account name to something like "equity:retained earn-- ings".)-- By default, the closing transaction is dated yesterday, the balances- are calculated as of end of yesterday, and the opening transaction is- dated today. To close on some other date, use: hledger close -e OPEN-- INGDATE. Eg, to close/open on the 2018/2019 boundary, use -e 2019.- You can also use -p or date:PERIOD (any starting date is ignored).-- Both transactions will include balance assertions for the- closed/reopened accounts. You probably shouldn't use status or real-- ness filters (like -C or -R or status:) with this command, or the gen-- erated balance assertions will depend on these flags. Likewise, if you- run this command with --auto, the balance assertions will probably- always require --auto.-- Examples:-- Carrying asset/liability balances into a new file for 2019:-- $ hledger close -f 2018.journal -e 2019 assets liabilities --open- # (copy/paste the output to the start of your 2019 journal file)- $ hledger close -f 2018.journal -e 2019 assets liabilities --close- # (copy/paste the output to the end of your 2018 journal file)-- Now:-- $ hledger bs -f 2019.journal # one file - balances are correct- $ hledger bs -f 2018.journal -f 2019.journal # two files - balances still correct- $ hledger bs -f 2018.journal not:desc:closing # to see year-end balances, must exclude closing txn-- Transactions spanning the closing date can complicate matters, breaking- balance assertions:-- 2018/12/30 a purchase made in 2018, clearing the following year- expenses:food 5- assets:bank:checking -5 ; [2019/1/2]-- Here's one way to resolve that:-- ; in 2018.journal:- 2018/12/30 a purchase made in 2018, clearing the following year- expenses:food 5- liabilities:pending-- ; in 2019.journal:- 2019/1/2 clearance of last year's pending transactions- liabilities:pending 5 = 0- assets:checking-- codes- codes- List the codes seen in transactions, in the order parsed.-- This command prints the value of each transaction's code field, in the- order transactions were parsed. The transaction code is an optional- value written in parentheses between the date and description, often- used to store a cheque number, order number or similar.-- Transactions aren't required to have a code, and missing or empty codes- will not be shown by default. With the -E/--empty flag, they will be- printed as blank lines.-- You can add a query to select a subset of transactions.-- Examples:-- 1/1 (123)- (a) 1-- 1/1 ()- (a) 1-- 1/1- (a) 1-- 1/1 (126)- (a) 1-- $ hledger codes- 123- 124- 126-- $ hledger codes -E- 123- 124--- 126-- commodities- commodities- List all commodity/currency symbols used or declared in the journal.-- descriptions- descriptions- List the unique descriptions that appear in transactions.-- This command lists the unique descriptions that appear in transactions,- in alphabetic order. You can add a query to select a subset of trans-- actions.-- Example:-- $ hledger descriptions- Store Name- Gas Station | Petrol- Person A-- diff- diff- Compares a particular account's transactions in two input files. It- shows any transactions to this account which are in one file but not in- the other.-- More precisely, for each posting affecting this account in either file,- it looks for a corresponding posting in the other file which posts the- same amount to the same account (ignoring date, description, etc.)- Since postings not transactions are compared, this also works when mul-- tiple bank transactions have been combined into a single journal entry.-- This is useful eg if you have downloaded an account's transactions from- your bank (eg as CSV data). When hledger and your bank disagree about- the account balance, you can compare the bank data with your journal to- find out the cause.-- Examples:-- $ hledger diff -f $LEDGER_FILE -f bank.csv assets:bank:giro- These transactions are in the first file only:-- 2014/01/01 Opening Balances- assets:bank:giro EUR ...- ...- equity:opening balances EUR -...-- These transactions are in the second file only:-- files- files- List all files included in the journal. With a REGEX argument, only- file names matching the regular expression (case sensitive) are shown.-- help- help- Show the hledger user manual in one of several formats, optionally- positioned at a given TOPIC (if possible). TOPIC is any heading, or- heading prefix, in the manual. Some examples: commands, print, 'auto- postings', periodic.-- This command shows the user manual built in to this hledger version.- It can be useful if the correct version of the hledger manual, or the- usual viewing tools, are not installed on your system.-- By default it uses the best viewer it can find in $PATH, in this order:- info, man, $PAGER (unless a topic is specified), less, or stdout. When- run non-interactively, it always uses stdout. Or you can select a par-- ticular viewer with the -i (info), -m (man), or -p (pager) flags.-- import- import- Read new transactions added to each FILE since last run, and add them- to the main journal file. Or with --dry-run, just print the transac-- tions that would be added. Or with --catchup, just mark all of the- FILEs' transactions as imported, without actually importing any.-- 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- hledger import bank.csv or perhaps hledger import *.csv.-- Note you can import from any file format, though CSV files are the most- common import source, and these docs focus on that case.-- Deduplication- 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- already-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-- potent.)-- Since the items being read (CSV records, eg) often do not come with- unique identifiers, hledger detects new transactions by date, assuming- that:-- 1. new items always have the newest dates-- 2. item dates do not change across reads-- 3. and items with the same date remain in the same relative order- across reads.-- 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- be the ones affected).-- 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- 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-- tain date.-- Note deduplication (and updating of state files) can also be done by- print --new, but this is less often used.-- Import testing- 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- categorised:-- $ hledger import --dry bank.csv | hledger -f- -I print unknown-- or (live updating):-- $ ls bank.csv* | entr bash -c 'echo ====; hledger import --dry bank.csv | hledger -f- -I print unknown'-- Importing balance assignments- Entries added by import will have their posting amounts made explicit- (like hledger print -x). This means that any balance assignments in- imported files must be evaluated; but, imported files don't get to see- the main file's account balances. As a result, importing entries with- balance assignments (eg from an institution that provides only balances- and not posting amounts) will probably generate incorrect posting- amounts. To avoid this problem, use print instead of import:-- $ hledger print IMPORTFILE [--new] >> $LEDGER_FILE-- (If you think import should leave amounts implicit like print does,- please test it and send a pull request.)-- Commodity display styles- Imported amounts will be formatted according to the canonical commodity- styles (declared or inferred) in the main journal file.-- incomestatement- incomestatement, is-- This command displays an income statement, showing revenues and- expenses during one or more periods. Amounts are shown with normal- positive sign, as in conventional financial statements.-- The revenue and expense accounts shown are those accounts declared with- the Revenue or Expense type, or otherwise all accounts under a top-- level revenue or income or expense account (case insensitive, plurals- allowed).-- Example:-- $ hledger incomestatement- Income Statement-- Revenues:- $-2 income- $-1 gifts- $-1 salary- --------------------- $-2-- Expenses:- $2 expenses- $1 food- $1 supplies- --------------------- $2-- Total:- --------------------- 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 '(revenues|income)' expenses, but with- smarter account detection, and revenues/income displayed with their- sign flipped.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, html, and (experi-- mental) json.-- notes- notes- List the unique notes that appear in transactions.-- This command lists the unique notes that appear in transactions, in- alphabetic order. You can add a query to select a subset of transac-- tions. The note is the part of the transaction description after a |- character (or if there is no |, the whole description).-- Example:-- $ hledger notes- Petrol- Snacks-- payees- payees- List the unique payee/payer names that appear in transactions.-- This command lists 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 |- character (or if there is no |, the whole description).-- You can add query arguments to select a subset of transactions. This- implies --used.-- Example:-- $ hledger payees- Store Name- Gas Station- Person A-- prices- prices- Print market price directives from the journal. With --costs, also- print synthetic market prices based on transaction prices. With- --inverted-costs, also print inverse prices based on transaction- prices. Prices (and postings providing prices) can be filtered by a- query. Price amounts are always displayed with their full precision.-- print- print- Show transaction journal entries, sorted by date.-- The print command displays full journal entries (transactions) from the- journal file, sorted by date (or with --date2, by secondary date).-- Amounts are shown 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.- This means the print command is somewhat lossy, and if you are using it- to reformat your journal you should take care to also copy over the- directives and file-level comments.-- Eg:-- $ hledger print- 2008/01/01 income- assets:bank:checking $1- income:salary $-1-- 2008/06/01 gift- assets:bank:checking $1- income:gifts $-1-- 2008/06/02 save- assets:bank:saving $1- assets:bank:checking $-1-- 2008/06/03 * eat & shop- expenses:food $1- expenses:supplies $1- assets:cash $-2-- 2008/12/31 * pay off- liabilities:debts $1- assets:bank:checking $-1-- print's output is usually a valid hledger journal, and you can process- it again with a second hledger command. This can be useful for certain- kinds of search, eg:-- # Show running total of food expenses paid from cash.- # -f- reads from stdin. -I/--ignore-assertions is sometimes needed.- $ hledger print assets:cash | hledger -f- -I reg expenses:food-- There are some situations where print's output can become unparseable:-- o Valuation affects posting amounts but not balance assertion or bal-- ance assignment amounts, potentially causing those to fail.-- o Auto postings can generate postings with too many missing amounts.-- Normally, the journal entry's explicit or implicit amount style is pre-- served. For example, when an amount is omitted in the journal, it will- not appear in the output. Similarly, when a transaction price is- implied but not written, it will not appear in the output. You can use- the -x/--explicit flag to make all amounts and transaction prices- explicit, which can be useful for troubleshooting or for making your- journal more readable and robust against data entry errors. -x is also- implied by using any of -B,-V,-X,--value.-- Note, -x/--explicit will cause postings with a multi-commodity amount- (these can arise when a multi-commodity transaction has an implicit- amount) to be split into multiple single-commodity postings, keeping- the output parseable.-- With -B/--cost, amounts with transaction prices are converted to cost- using that price. This can be used for troubleshooting.-- With -m/--match and a STR argument, print will show at most one trans-- action: the one one whose description is most similar to STR, and is- most recent. STR should contain at least two characters. If there is- no similar-enough match, no transaction will be shown.-- With --new, hledger prints only transactions it has not seen on a pre-- vious run. This uses the same deduplication system as the import com-- mand. (See import's docs for details.)-- This command also supports the output destination and output format- options The output formats supported are txt, csv, and (experimental)- json and sql.-- Here's an example of print's CSV output:-- $ hledger print -Ocsv- "txnidx","date","date2","status","code","description","comment","account","amount","commodity","credit","debit","posting-status","posting-comment"- "1","2008/01/01","","","","income","","assets:bank:checking","1","$","","1","",""- "1","2008/01/01","","","","income","","income:salary","-1","$","1","","",""- "2","2008/06/01","","","","gift","","assets:bank:checking","1","$","","1","",""- "2","2008/06/01","","","","gift","","income:gifts","-1","$","1","","",""- "3","2008/06/02","","","","save","","assets:bank:saving","1","$","","1","",""- "3","2008/06/02","","","","save","","assets:bank:checking","-1","$","1","","",""- "4","2008/06/03","","*","","eat & shop","","expenses:food","1","$","","1","",""- "4","2008/06/03","","*","","eat & shop","","expenses:supplies","1","$","","1","",""- "4","2008/06/03","","*","","eat & shop","","assets:cash","-2","$","2","","",""- "5","2008/12/31","","*","","pay off","","liabilities:debts","1","$","","1","",""- "5","2008/12/31","","*","","pay off","","assets:bank:checking","-1","$","1","","",""-- o There is one CSV record per posting, with the parent transaction's- fields repeated.-- o The "txnidx" (transaction index) field shows which postings belong to- the same transaction. (This number might change if transactions are- reordered within the file, files are parsed/included in a different- order, etc.)-- o The amount is separated into "commodity" (the symbol) and "amount"- (numeric quantity) fields.-- o The numeric amount is repeated in either the "credit" or "debit" col-- umn, for convenience. (Those names are not accurate in the account-- ing sense; it just puts negative amounts under credit and zero or- greater amounts under debit.)-- print-unique- print-unique- Print transactions which do not reuse an already-seen description.-- Example:-- $ cat unique.journal- 1/1 test- (acct:one) 1- 2/2 test- (acct:two) 2- $ LEDGER_FILE=unique.journal hledger print-unique- (-f option not supported)- 2015/01/01 test- (acct:one) 1-- register- register, reg- Show postings and their running total.-- The register command displays matched postings, across all accounts, in- date order, with their running total or running historical balance.- (See also the aregister command, which shows matched transactions in a- specific account.)-- register normally shows line per posting, but note that multi-commodity- amounts will occupy multiple lines (one line per commodity).-- It is typically used with a query selecting a particular account, to- see that account's activity:-- $ hledger register checking- 2008/01/01 income assets:bank:checking $1 $1- 2008/06/01 gift assets:bank:checking $1 $2- 2008/06/02 save assets:bank:checking $-1 $1- 2008/12/31 pay off assets:bank:checking $-1 0-- With --date2, it shows and sorts by secondary date instead.-- The --historical/-H flag adds the balance from any undisplayed prior- postings to the running total. This is useful when you want to see- only recent activity, with a historically accurate running balance:-- $ hledger register checking -b 2008/6 --historical- 2008/06/01 gift assets:bank:checking $1 $2- 2008/06/02 save assets:bank:checking $-1 $1- 2008/12/31 pay off assets:bank:checking $-1 0-- The --depth option limits the amount of sub-account detail displayed.-- The --average/-A flag shows the running average posting amount instead- of the running total (so, the final number displayed is the average for- the whole report period). This flag implies --empty (see below). It- is affected by --historical. It works best when showing just one- account and one commodity.-- The --related/-r flag shows the other postings in the transactions of- the postings which would normally be shown.-- The --invert flag negates all amounts. For example, it can be used on- an income account where amounts are normally displayed as negative num-- bers. It's also useful to show postings on the checking account- together with the related account:-- $ hledger register --related --invert assets:checking-- With a reporting interval, register shows summary postings, one per- interval, aggregating the postings to each account:-- $ hledger register --monthly income- 2008/01 income:salary $-1 $-1- 2008/06 income:gifts $-1 $-2-- Periods with no activity, and summary postings with a zero amount, are- not shown by default; use the --empty/-E flag to see them:-- $ hledger register --monthly income -E- 2008/01 income:salary $-1 $-1- 2008/02 0 $-1- 2008/03 0 $-1- 2008/04 0 $-1- 2008/05 0 $-1- 2008/06 income:gifts $-1 $-2- 2008/07 0 $-2- 2008/08 0 $-2- 2008/09 0 $-2- 2008/10 0 $-2- 2008/11 0 $-2- 2008/12 0 $-2-- Often, you'll want to see just one line per interval. The --depth- option helps with this, causing subaccounts to be aggregated:-- $ hledger register --monthly assets --depth 1h- 2008/01 assets $1 $1- 2008/06 assets $-1 0- 2008/12 assets $-1 $-1-- Note when using report intervals, if you specify start/end dates these- will be adjusted outward if necessary to contain a whole number of- intervals. This ensures that the first and last intervals are full- length and comparable to the others in the report.-- Custom register output- register uses the full terminal width by default, except on windows.- You can override this by setting the COLUMNS environment variable (not- a bash shell variable) or by using the --width/-w option.-- The description and account columns normally share the space equally- (about half of (width - 40) each). You can adjust this by adding a- description width as part of --width's argument, comma-separated:- --width W,D . Here's a diagram (won't display correctly in --help):-- <--------------------------------- width (W) ---------------------------------->- date (10) description (D) account (W-41-D) amount (12) balance (12)- DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA-- and some examples:-- $ hledger reg # use terminal width (or 80 on windows)- $ hledger reg -w 100 # use width 100- $ COLUMNS=100 hledger reg # set with one-time environment variable- $ export COLUMNS=100; hledger reg # set till session end (or window resize)- $ hledger reg -w 100,40 # set overall width 100, description width 40- $ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40-- This command also supports the output destination and output format- options The output formats supported are txt, csv, and (experimental)- json.-- register-match- register-match- Print the one posting whose transaction description is closest to DESC,- in the style of the register command. If there are multiple equally- good matches, it shows the most recent. Query options (options, not- arguments) can be used to restrict the search space. Helps ledger-- autosync detect already-seen transactions when importing.-- rewrite- rewrite- Print all transactions, rewriting the postings of matched transactions.- For now the only rewrite available is adding new postings, like print- --auto.-- This is a start at a generic rewriter of transaction entries. It reads- the default journal and prints the transactions, like print, but adds- one or more specified postings to any transactions matching QUERY. The- posting amounts can be fixed, or a multiplier of the existing transac-- tion's first posting amount.-- Examples:-- $ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'- $ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'- $ hledger-rewrite.hs -f rewrites.hledger-- rewrites.hledger may consist of entries like:-- = ^income amt:<0 date:2017- (liabilities:tax) *0.33 ; tax on income- (reserve:grocery) *0.25 ; reserve 25% for grocery- (reserve:) *0.25 ; reserve 25% for grocery-- Note the single quotes to protect the dollar sign from bash, and the- two spaces between account and amount.-- More:-- $ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...- $ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'- $ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'- $ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'-- Argument for --add-posting option is a usual posting of transaction- with an exception for amount specification. More precisely, you can- use '*' (star symbol) before the amount to indicate that that this is a- factor for an amount of original matched posting. If the amount- includes a commodity name, the new posting amount will be in the new- commodity; otherwise, it will be in the matched posting amount's com-- modity.-- Re-write rules in a file- During the run this tool will execute so called "Automated Transac-- tions" found in any journal it process. I.e instead of specifying this- operations in command line you can put them in a journal file.-- $ rewrite-rules.journal-- Make contents look like this:-- = ^income- (liabilities:tax) *.33-- = expenses:gifts- budget:gifts *-1- assets:budget *1-- Note that '=' (equality symbol) that is used instead of date in trans-- actions you usually write. It indicates the query by which you want to- match the posting to add new ones.-- $ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal-- This is something similar to the commands pipeline:-- $ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \- | hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \- --add-posting 'assets:budget *1' \- > rewritten-tidy-output.journal-- It is important to understand that relative order of such entries in- journal is important. You can re-use result of previously added post-- ings.-- Diff output format- To use this tool for batch modification of your journal files you may- find useful output in form of unified diff.-- $ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'-- Output might look like:-- --- /tmp/examples/sample.journal- +++ /tmp/examples/sample.journal- @@ -18,3 +18,4 @@- 2008/01/01 income- - assets:bank:checking $1- + assets:bank:checking $1- income:salary- + (liabilities:tax) 0- @@ -22,3 +23,4 @@- 2008/06/01 gift- - assets:bank:checking $1- + assets:bank:checking $1- income:gifts- + (liabilities:tax) 0-- If you'll pass this through patch tool you'll get transactions contain-- ing the posting that matches your query be updated. Note that multiple- files might be update according to list of input files specified via- --file options and include directives inside of these files.-- Be careful. Whole transaction being re-formatted in a style of output- from hledger print.-- See also:-- https://github.com/simonmichael/hledger/issues/99-- rewrite vs. print --auto- This command predates print --auto, and currently does much the same- thing, but with these differences:-- o with multiple files, rewrite lets rules in any file affect all other- files. print --auto uses standard directive scoping; rules affect- only child files.-- o rewrite's query limits which transactions can be rewritten; all are- printed. print --auto's query limits which transactions are printed.-- o rewrite applies rules specified on command line or in the journal.- print --auto applies rules specified in the journal.-- roi- roi- Shows the time-weighted (TWR) and money-weighted (IRR) rate of return- on your investments.-- At a minimum, you need to supply a query (which could be just an- account name) to select your investment(s) with --inv, and another- query to identify your profit and loss transactions with --pnl.-- If you do not record changes in the value of your investment manually,- or do not require computation of time-weighted return (TWR), --pnl- 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- display, regardless of the length of reporting interval.-- 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- becomes negative at some point in time.-- o Error (SearchFailed): Failed to find solution for Internal Rate of- Return (IRR). Either search does not converge to a solution, or con-- verges too slowly.-- Examples:-- o Using roi to compute total return of investment in stocks:- https://github.com/simonmichael/hledger/blob/master/examples/roi-- unrealised.ledger-- o Cookbook -> Return on Investment-- Spaces and special characters in --inv and --pnl- Note that --inv and --pnl's argument is a query, and queries could have- several space-separated terms (see QUERIES).-- To indicate that all search terms form single command-line argument,- you will need to put them in quotes (see Special characters):-- $ hledger roi --inv 'term1 term2 term3 ...'-- If any query terms contain spaces themselves, you will need an extra- level of nested quoting, eg:-- $ hledger roi --inv="'Assets:Test 1'" --pnl="'Equity:Unrealized Profit and Loss'"-- Semantics of --inv and --pnl- Query supplied to --inv has to match all transactions that are related- 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- and which is due to the return on investment.-- o "Cash flow" is depositing or withdrawing money, buying or selling- assets, or otherwise converting between your investment commodity and- any other commodity. Example:-- 2019-01-01 Investing in Snake Oil- assets:cash -$100- investment:snake oil-- 2020-01-01 Selling my Snake Oil- assets:cash $10- investment:snake oil = 0-- o "Profit and loss" is change in the value of your investment:-- 2019-06-01 Snake Oil falls in value- investment:snake oil = $57- equity:unrealized profit or loss-- All non-investment postings are assumed to be "cash flow", unless they- match --pnl query. Changes in value of your investment due to "profit- and loss" postings will be considered as part of your investment- return.-- Example: if you use --inv snake --pnl equity:unrealized, then postings- in the example below would be classifed as:-- 2019-01-01 Snake Oil #1- assets:cash -$100 ; cash flow posting- investment:snake oil ; investment posting-- 2019-03-01 Snake Oil #2- equity:unrealized pnl -$100 ; profit and loss posting- snake oil ; investment posting-- 2019-07-01 Snake Oil #3- equity:unrealized pnl ; profit and loss posting- cash -$100 ; cash flow posting- snake oil $50 ; investment posting-- IRR and TWR explained- "ROI" stands for "return on investment". Traditionally this was com-- puted as a difference between current value of investment and its ini-- tial value, expressed in percentage of the initial value.-- However, this approach is only practical in simple cases, where invest-- ments receives no in-flows or out-flows of money, and where rate of- growth is fixed over time. For more complex scenarios you need differ-- ent ways to compute rate of return, and this command implements two of- them: IRR and TWR.-- Internal rate of return, or "IRR" (also called "money-weighted rate of- return") takes into account effects of in-flows and out-flows.- Naively, if you are withdrawing from your investment, your future gains- would be smaller (in absolute numbers), and will be a smaller percent-- age of your initial investment, and if you are adding to your invest-- ment, you will receive bigger absolute gains (but probably at the same- rate of return). IRR is a way to compute rate of return for each- period between in-flow or out-flow of money, and then combine them in a- way that gives you a compound annual rate of return that investment is- expected to generate.-- 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.-- If you manually record changes in the value of your investment as- transactions that balance them against "profit and loss" (or "unreal-- ized gains") account or use price directives, then in order for IRR to- compute the precise effect of your in-flows and out-flows on the rate- of return, you will need to record the value of your investement on or- close to the days when in- or out-flows occur.-- In technical terms, IRR uses the same approach as computation of net- present value, and tries to find a discount rate that makes net present- value of all the cash flows of your investment to add up to zero. This- could be hard to wrap your head around, especially if you haven't done- discounted cash flow analysis before. 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- 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- and then a compound rate of return. However, internal workings of TWR- are quite different.-- TWR represents your investment as an imaginary "unit fund" where in-- flows/ out-flows lead to buying or selling "units" of your investment- and changes in its value change the value of "investment unit". Change- in "unit price" over the reporting period gives you rate of return of- your investment.-- References: * Explanation of rate of return * Explanation of IRR *- Explanation of TWR * Examples of computing IRR and TWR and discussion- of the limitations of both metrics-- stats- stats- Show some journal statistics.-- The stats command displays summary information for the whole journal,- or a matched part of it. With a reporting interval, it shows a report- for each report period.-- Example:-- $ hledger stats- Main journal file : /src/hledger/examples/sample.journal- Included journal files :- Transactions span : 2008-01-01 to 2009-01-01 (366 days)- Last transaction : 2008-12-31 (2333 days ago)- Transactions : 5 (0.0 per day)- Transactions last 30 days: 0 (0.0 per day)- Transactions last 7 days : 0 (0.0 per day)- Payees/descriptions : 5- Accounts : 8 (depth 3)- Commodities : 1 ($)- Market prices : 12 ($)-- This command also supports output destination and output format selec-- tion.-- tags- tags- List the unique tag names used in the journal. With a TAGREGEX argu-- ment, only tag names matching the regular expression (case insensitive)- are shown. With QUERY arguments, only transactions matching the query- are considered.-- With the --values flag, the tags' unique values are listed instead.-- With --parsed flag, all tags or values are shown in the order they are- parsed from the input data, including duplicates.-- With -E/--empty, any blank/empty values will also be shown, otherwise- they are omitted.-- test- test- Run built-in unit tests.-- This command runs the unit tests built in to hledger and hledger-lib,- printing the results on stdout. If any test fails, the exit code will- be non-zero.-- This is mainly used by hledger developers, but you can also use it to- sanity-check the installed hledger executable on your platform. All- tests are expected to pass - if you ever see a failure, please report- as a bug!-- This command also accepts tasty test runner options, written after a --- (double hyphen). Eg to run only the tests in Hledger.Data.Amount, with- ANSI colour codes disabled:-- $ hledger test -- -pData.Amount --color=never-- For help on these, see https://github.com/feuerbach/tasty#options (--- --help currently doesn't show them).-- About add-on commands- Add-on commands are programs or scripts in your PATH-- o whose name starts with hledger--- o whose name ends with a recognised file extension: .bat,.com,.exe,- .hs,.lhs,.pl,.py,.rb,.rkt,.sh or none-- o and (on unix, mac) which are executable by the current user.-- Add-ons are a relatively easy way to add local features or experiment- with new ideas. They can be written in any language, but haskell- scripts have a big advantage: they can use the same hledger library- functions that built-in commands use for command-line options, parsing- and reporting. Some experimental/example add-on scripts can be found- in the hledger repo's bin/ directory.-- Note in a hledger command line, add-on command flags must have a double- dash (--) preceding them. Eg you must write:-- $ hledger web -- --serve-- and not:-- $ hledger web --serve-- (because the --serve flag belongs to hledger-web, not hledger).-- The -h/--help and --version flags don't require --.-- If you have any trouble with this, remember you can always run the add-- on program directly, eg:-- $ hledger-web --serve--JOURNAL FORMAT- hledger's default file format, representing a General Journal.-- hledger's usual data source is a plain text file containing journal- entries in hledger journal format. This file represents a standard- accounting general journal. I use file names ending in .journal, but- that's not required. The journal file contains a number of transaction- entries, each describing a transfer of money (or any commodity) between- two or more named accounts, in a simple format readable by both hledger- and humans.-- hledger's journal format is a compatible subset, mostly, of ledger's- journal format, so hledger can work with compatible ledger journal- files as well. It's safe, and encouraged, to run both hledger and- ledger on the same journal file, eg to validate the results you're get-- ting.-- You can use hledger without learning any more about this file; just use- the add or web or import commands to create and update it.-- Many users, though, edit the journal file with a text editor, and track- changes with a version control system such as git. Editor addons such- as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and- hledger-vscode for Visual Studio Code, make this easier, adding colour,- formatting, tab completion, and useful commands. See Editor configura-- tion at hledger.org for the full list.-- Here's a description of each part of the file format (and hledger's- data model). These are mostly in the order you'll use them, but in- some cases related concepts have been grouped together for easy refer-- ence, or linked before they are introduced, so feel free to skip over- anything that looks unnecessary right now.-- Transactions- Transactions are the main unit of information in a journal file. They- represent events, typically a movement of some quantity of commodities- between two or more named accounts.-- Each transaction is recorded as a journal entry, beginning with a sim-- ple date in column 0. This can be followed by any of the following- optional fields, separated by spaces:-- o a status character (empty, !, or *)-- o a code (any short number or text, enclosed in parentheses)-- o a description (any remaining text until end of line or a semicolon)-- o a comment (any remaining text following a semicolon until end of- line, and any following indented lines beginning with a semicolon)-- o 0 or more indented posting lines, describing what was transferred and- the accounts involved (indented comment lines are also allowed, but- not blank lines or non-indented lines).-- Here's a simple journal file containing one transaction:-- 2008/01/01 income- assets:bank:checking $1- income:salary $-1-- Dates- Simple dates- Dates in the journal file use simple dates format: YYYY-MM-DD or- YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be- omitted, in which case it will be inferred from the context: the cur-- rent transaction, the default year set with a default year directive,- or the current date when the command is run. Some examples:- 2010-01-31, 2010/01/31, 2010.1.31, 1/31.-- (The UI also accepts simple dates, as well as the more flexible smart- dates documented in the hledger manual.)-- Secondary dates- Real-life transactions sometimes involve more than one date - eg the- date you write a cheque, and the date it clears in your bank. When you- want to model this, for more accurate daily balances, you can specify- individual posting dates.-- Or, you can use the older secondary date feature (Ledger calls it aux-- iliary date or effective date). Note: we support this for compatibil-- ity, but I usually recommend avoiding this feature; posting dates are- almost always clearer and simpler.-- A secondary date is written after the primary date, following an equals- sign. If the year is omitted, the primary date's year is assumed.- When running reports, the primary (left) date is used by default, but- with the --date2 flag (or --aux-date or --effective), the secondary- (right) date will be used instead.-- The meaning of secondary dates is up to you, but it's best to follow a- consistent rule. Eg "primary = the bank's clearing date, secondary =- date the transaction was initiated, if different", as shown here:-- 2010/2/23=2/19 movie ticket- expenses:cinema $10- assets:checking-- $ hledger register checking- 2010-02-23 movie ticket assets:checking $-10 $-10-- $ hledger register checking --date2- 2010-02-19 movie ticket assets:checking $-10 $-10-- Posting dates- You can give individual postings a different date from their parent- transaction, by adding a posting comment containing a tag (see below)- like date:DATE. This is probably the best way to control posting dates- precisely. Eg in this example the expense should appear in May- reports, and the deduction from checking should be reported on 6/1 for- easy bank reconciliation:-- 2015/5/30- expenses:food $10 ; food purchased on saturday 5/30- assets:checking ; bank cleared it on monday, date:6/1-- $ hledger -f t.j register food- 2015-05-30 expenses:food $10 $10-- $ hledger -f t.j register checking- 2015-06-01 assets:checking $-10 $-10-- DATE should be a simple date; if the year is not specified it will use- the year of the transaction's date. You can set the secondary date- similarly, with date2:DATE2. The date: or date2: tags must have a- valid simple date value if they are present, eg a date: tag with no- value is not allowed.-- Ledger's earlier, more compact bracketed date syntax is also supported:- [DATE], [DATE=DATE2] or [=DATE2]. hledger will attempt to parse any- square-bracketed sequence of the 0123456789/-.= characters in this way.- With this syntax, DATE infers its year from the transaction and DATE2- infers its year from DATE.-- Status- Transactions, or individual postings within a transaction, can have a- status mark, which is a single character before the transaction- description or posting account name, separated from it by a space,- indicating one of three statuses:--- mark status- ------------------- unmarked- ! pending- * cleared-- When reporting, you can filter by status with the -U/--unmarked,- -P/--pending, and -C/--cleared flags; or the status:, status:!, and- status:* queries; or the U, P, C keys in hledger-ui.-- Note, in Ledger and in older versions of hledger, the "unmarked" state- is called "uncleared". As of hledger 1.3 we have renamed it to- unmarked for clarity.-- To replicate Ledger and old hledger's behaviour of also matching pend-- ing, combine -U and -P.-- Status marks are optional, but can be helpful eg for reconciling with- real-world accounts. Some editor modes provide highlighting and short-- cuts for working with status. Eg in Emacs ledger-mode, you can toggle- transaction status with C-c C-e, or posting status with C-c C-c.-- What "uncleared", "pending", and "cleared" actually mean is up to you.- Here's one suggestion:--- status meaning- --------------------------------------------------------------------------- uncleared recorded but not yet reconciled; needs review- pending tentatively reconciled (if needed, eg during a big reconcil-- iation)- cleared complete, reconciled as far as possible, and considered cor-- rect-- With this scheme, you would use -PC to see the current balance at your- bank, -U to see things which will probably hit your bank soon (like- uncashed checks), and no flags to see the most up-to-date state of your- finances.-- Code- After the status mark, but before the description, you can optionally- write a transaction "code", enclosed in parentheses. This is a good- place to record a check number, or some other important transaction id- or reference number.-- Description- A transaction's description is the rest of the line following the date- and status mark (or until a comment begins). Sometimes called the- "narration" in traditional bookkeeping, it can be used for whatever you- wish, or left blank. Transaction descriptions can be queried, unlike- comments.-- Payee and note- You can optionally include a | (pipe) character in descriptions to sub-- divide the description into separate fields for payee/payer name on the- left (up to the first |) and an additional note field on the right- (after the first |). This may be worthwhile if you need to do more- precise querying and pivoting by payee or by note.-- Comments- Lines in the journal beginning with a semicolon (;) or hash (#) or star- (*) are comments, and will be ignored. (Star comments cause org-mode- nodes to be ignored, allowing emacs users to fold and navigate their- journals with org-mode or orgstruct-mode.)-- You can attach comments to a transaction by writing them after the- description and/or indented on the following lines (before the post-- ings). Similarly, you can attach comments to an individual posting by- writing them after the amount and/or indented on the following lines.- Transaction and posting comments must begin with a semicolon (;).-- Some examples:-- # a file comment- ; another file comment- * also a file comment, useful in org/orgstruct mode-- comment- A multiline file comment, which continues- until a line containing just "end comment"- (or end of file).- end comment-- 2012/5/14 something ; a transaction comment- ; the transaction comment, continued- posting1 1 ; a comment for posting 1- posting2- ; a comment for posting 2- ; another comment line for posting 2- ; a file comment (because not indented)-- You can also comment larger regions of a file using comment and end- comment directives.-- Tags- Tags are a way to add extra labels or labelled data to postings and- transactions, which you can then search or pivot on.-- A simple tag is a word (which may contain hyphens) followed by a full- colon, written inside a transaction or posting comment line:-- 2017/1/16 bought groceries ; sometag:-- Tags can have a value, which is the text after the colon, up to the- next comma or end of line, with leading/trailing whitespace removed:-- expenses:food $10 ; a-posting-tag: the tag value-- Note this means hledger's tag values can not contain commas or new-- lines. Ending at commas means you can write multiple short tags on one- line, comma separated:-- assets:checking ; a comment containing tag1:, tag2: some value ...-- Here,-- o "a comment containing" is just comment text, not a tag-- o "tag1" is a tag with no value-- o "tag2" is another tag, whose value is "some value ..."-- Tags in a transaction comment affect the transaction and all of its- postings, while tags in a posting comment affect only that posting.- For example, the following transaction has three tags (A, TAG2, third-- tag) and the posting has four (those plus posting-tag):-- 1/1 a transaction ; A:, TAG2:- ; third-tag: a third transaction tag, <- with a value- (a) $1 ; posting-tag:-- Tags are like Ledger's metadata feature, except hledger's tag values- are simple strings.-- Postings- A posting is an addition of some amount to, or removal of some amount- from, an account. Each posting line begins with at least one space or- tab (2 or 4 spaces is common), followed by:-- o (optional) a status character (empty, !, or *), followed by a space-- o (required) an account name (any text, optionally containing single- spaces, until end of line or a double space)-- o (optional) two or more spaces or tabs followed by an amount.-- Positive amounts are being added to the account, negative amounts are- being removed.-- The amounts within a transaction must always sum up to zero. As a con-- venience, one amount may be left blank; it will be inferred so as to- balance the transaction.-- Be sure to note the unusual two-space delimiter between account name- and amount. This makes it easy to write account names containing spa-- ces. But if you accidentally leave only one space (or tab) before the- amount, the amount will be considered part of the account name.-- Virtual postings- A posting with a parenthesised account name is called a virtual posting- or unbalanced posting, which means it is exempt from the usual rule- that a transaction's postings must balance add up to zero.-- This is not part of double entry accounting, so you might choose to- avoid this feature. Or you can use it sparingly for certain special- cases where it can be convenient. Eg, you could set opening balances- without using a balancing equity account:-- 1/1 opening balances- (assets:checking) $1000- (assets:savings) $2000-- A posting with a bracketed account name is called a balanced virtual- posting. The balanced virtual postings in a transaction must add up to- zero (separately from other postings). Eg:-- 1/1 buy food with cash, update budget envelope subaccounts, & something else- assets:cash $-10 ; <- these balance- expenses:food $7 ; <-- expenses:food $3 ; <-- [assets:checking:budget:food] $-10 ; <- and these balance- [assets:checking:available] $10 ; <-- (something:else) $5 ; <- not required to balance-- Ordinary non-parenthesised, non-bracketed postings are called real- postings. You can exclude virtual postings from reports with the- -R/--real flag or real:1 query.-- Account names- Account names typically have several parts separated by a full colon,- from which hledger derives a hierarchical chart of accounts. They can- be anything you like, but in finance there are traditionally five top-- level accounts: assets, liabilities, revenue, expenses, and equity.-- Account names may contain single spaces, eg: assets:accounts receiv-- able. Because of this, they must always be followed by two or more- spaces (or newline).-- Account names can be aliased.-- Amounts- After the account name, there is usually an amount. (Important:- between account name and amount, there must be two or more spaces.)-- hledger's amount format is flexible, supporting several international- formats. Here are some examples. Amounts have a number (the "quan-- tity"):-- 1-- ..and usually a currency symbol or commodity name (more on this below),- to the left or right of the quantity, with or without a separating- space:-- $1- 4000 AAPL- 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-- modity symbol:-- -$1- $-1-- One or more spaces between the sign and the number are acceptable when- parsing (but they won't be displayed in output):-- + $1- $- 1-- Scientific E notation is allowed:-- 1E-6- EUR 1E3-- Decimal marks, digit group marks- A decimal mark can be written as a period or a comma:-- 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, comma, or period (different from the decimal mark):-- $1,000,000.00- EUR 2.000.000,00- INR 9,99,99,999.00- 1 000 000.9455-- Note, a number containing a single digit group mark and no decimal mark- is ambiguous. Are these digit group marks or decimal marks ?-- 1,000- 1.000-- If you don't tell it otherwise, hledger will assume both of the above- are decimal marks, parsing both numbers as 1. To prevent confusion and- undetected typos, we recommend adding commodity directives at the top- of your journal file to explicitly declare the decimal mark (and- optionally a digit group mark) for each commodity. Read on for more- about this.-- Commodity- 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",- "ABC123").-- 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- 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- are the Amount and MixedAmount types.)-- Commodity directives- You can add commodity directives to the journal, preferably at the top,- to declare your commodities and help with number parsing (see above)- and display (see below). These are optional, but recommended. They- are described in more detail in JOURNAL FORMAT -> Declaring commodi-- ties. Here's a quick example:-- # number format and display style for $, EUR, INR and the no-symbol commodity:- commodity $1,000.00- commodity EUR 1.000,00- commodity INR 9,99,99,999.00- commodity 1 000 000.9455--- Commodity display style- For the amounts in each commodity, hledger chooses a consistent display- style to use in most reports. (Exceptions: price amounts, and all- amounts displayed by the print command, are displayed with all of their- decimal digits visible.)-- A commodity's display style is inferred as follows.-- 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- order of preference:-- 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.- (Posting amounts only; prices and periodic or auto rules are ignored,- currently.)-- o The built-in fallback style, which looks like this: $1000.00. (Sym-- bol on the left, period decimal mark, two decimal places.)-- A style is inferred from journal amounts as follows:-- o Use the general style (decimal mark, symbol placement) of the first- amount-- o Use the first-seen digit group style (digit group mark, digit group- sizes), if any-- o Use the maximum number of decimal places of all.-- Transaction price amounts don't affect the commodity display style- directly, but occasionally they can do so indirectly (eg when a post-- ing's amount is inferred using a transaction price). If you find this- causing problems, use a commodity 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- places, use a commodity directive. Some examples:-- # declare euro, dollar, bitcoin and no-symbol commodities and set their- # input number formats and output display styles:- commodity EUR 1.000,- commodity $1000.00- commodity 1000.00000000 BTC- commodity 1 000.-- Rounding- Amounts are stored internally as decimal numbers with up to 255 decimal- places, and displayed with the number of decimal places specified by- the commodity display style. Note, hledger uses banker's rounding: it- rounds to the nearest even number, eg 0.5 displayed with zero decimal- places is "0"). (Guaranteed since hledger 1.17.1; in older versions- this could vary if hledger was built with Decimal < 0.5.1.)-- Transaction prices- Within a transaction, you can note an amount's price in another commod-- ity. This can be used to document the cost (in a purchase) or selling- price (in a sale). For example, transaction prices are useful to- record purchases of a foreign currency. Note transaction prices are- fixed at the time of the transaction, and do not change over time. See- also market prices, which represent prevailing exchange rates on a cer-- tain date.-- There are several ways to record a transaction price:-- 1. Write the price per unit, as @ UNITPRICE after the amount:-- 2009/1/1- assets:euros EUR100 @ $1.35 ; one hundred euros purchased at $1.35 each- assets:dollars ; balancing amount is -$135.00-- 2. Write the total price, as @@ TOTALPRICE after the amount:-- 2009/1/1- assets:euros EUR100 @@ $135 ; one hundred euros purchased at $135 for the lot- assets:dollars-- 3. Specify amounts for all postings, using exactly two commodities, and- let hledger infer the price that balances the transaction:-- 2009/1/1- assets:euros EUR100 ; one hundred euros purchased- assets:dollars $-135 ; for $135-- 4. Like 1, but the @ is parenthesised, i.e. (@); this is for compati-- bility with Ledger journals (Virtual posting costs), and is equiva-- lent to 1 in hledger.-- 5. Like 2, but as in 4 the @@ is parenthesised, i.e. (@@); in hledger,- this is equivalent to 2.-- Use the -B/--cost flag to convert amounts to their transaction price's- commodity, if any. (mnemonic: "B" is from "cost Basis", as in Ledger).- Eg here is how -B affects the balance report for the example above:-- $ hledger bal -N --flat- $-135 assets:dollars- EUR100 assets:euros- $ hledger bal -N --flat -B- $-135 assets:dollars- $135 assets:euros # <- the euros' cost-- Note -B is sensitive to the order of postings when a transaction price- is inferred: the inferred price will be in the commodity of the last- amount. So if example 3's postings are reversed, while the transaction- is equivalent, -B shows something different:-- 2009/1/1- assets:dollars $-135 ; 135 dollars sold- assets:euros EUR100 ; for 100 euros-- $ hledger bal -N --flat -B- EUR-100 assets:dollars # <- the dollars' selling price- EUR100 assets:euros-- Lot prices, lot dates- Ledger allows another kind of price, lot price (four variants: {UNIT-- PRICE}, {{TOTALPRICE}}, {=FIXEDUNITPRICE}, {{=FIXEDTOTALPRICE}}),- and/or a lot date ([DATE]) to be specified. These are normally used to- select a lot when selling investments. hledger will parse these, for- compatibility with Ledger journals, but currently ignores them. A- transaction price, lot price and/or lot date may appear in any order,- after the posting amount and before the balance assertion if any.-- Balance assertions- hledger supports Ledger-style balance assertions in journal files.- These look like, for example, = EXPECTEDBALANCE following a posting's- amount. Eg here we assert the expected dollar balance in accounts a- and b after each posting:-- 2013/1/1- a $1 =$1- b =$-1-- 2013/1/2- a $1 =$2- b $-1 =$-2-- After reading a journal file, hledger will check all balance assertions- and report an error if any of them fail. Balance assertions can pro-- tect you from, eg, inadvertently disrupting reconciled balances while- cleaning up old entries. You can disable them temporarily with the- -I/--ignore-assertions flag, which can be useful for troubleshooting or- for reading Ledger files. (Note: this flag currently does not disable- balance assignments, below).-- Assertions and ordering- hledger sorts an account's postings and assertions first by date and- then (for postings on the same day) by parse order. Note this is dif-- ferent from Ledger, which sorts assertions only by parse order. (Also,- Ledger assertions do not see the accumulated effect of repeated post-- ings to the same account within a transaction.)-- So, hledger balance assertions keep working if you reorder differently-- dated transactions within the journal. But if you reorder same-dated- transactions or postings, assertions might break and require updating.- This order dependence does bring an advantage: precise control over the- order of postings and assertions within a day, so you can assert intra-- day balances.-- Assertions and included files- With included files, things are a little more complicated. Including- preserves the ordering of postings and assertions. If you have multi-- ple postings to an account on the same day, split across different- files, and you also want to assert the account's balance on the same- day, you'll have to put the assertion in the right file.-- Assertions and multiple -f options- Balance assertions don't work well across files specified with multiple- -f options. Use include or concatenate the files instead.-- Assertions and commodities- The asserted balance must be a simple single-commodity amount, and in- fact the assertion checks only this commodity's balance within the- (possibly multi-commodity) account balance. This is how assertions- work in Ledger also. We could call this a "partial" balance assertion.-- To assert the balance of more than one commodity in an account, you can- write multiple postings, each asserting one commodity's balance.-- You can make a stronger "total" balance assertion by writing a double- equals sign (== EXPECTEDBALANCE). This asserts that there are no other- unasserted commodities in the account (or, that their balance is 0).-- 2013/1/1- a $1- a 1EUR- b $-1- c -1EUR-- 2013/1/2 ; These assertions succeed- a 0 = $1- a 0 = 1EUR- b 0 == $-1- c 0 == -1EUR-- 2013/1/3 ; This assertion fails as 'a' also contains 1EUR- a 0 == $1-- It's not yet possible to make a complete assertion about a balance that- has multiple commodities. One workaround is to isolate each commodity- into its own subaccount:-- 2013/1/1- a:usd $1- a:euro 1EUR- b-- 2013/1/2- a 0 == 0- a:usd 0 == $1- a:euro 0 == 1EUR-- Assertions and prices- Balance assertions ignore transaction prices, and should normally be- written without one:-- 2019/1/1- (a) $1 @ EUR1 = $1-- We do allow prices to be written there, however, and print shows them,- even though they don't affect whether the assertion passes or fails.- This is for backward compatibility (hledger's close command used to- generate balance assertions with prices), and because balance assign-- ments do use them (see below).-- Assertions and subaccounts- The balance assertions above (= and ==) do not count the balance from- subaccounts; they check the account's exclusive balance only. You can- assert the balance including subaccounts by writing =* or ==*, eg:-- 2019/1/1- equity:opening balances- checking:a 5- checking:b 5- checking 1 ==* 11-- Assertions and virtual postings- Balance assertions are checked against all postings, both real and vir-- tual. They are not affected by the --real/-R flag or real: query.-- Assertions and precision- Balance assertions compare the exactly calculated amounts, which are- not always what is shown by reports. Eg a commodity directive may- limit the display precision, but this will not affect balance asser-- tions. Balance assertion failure messages show exact amounts.-- Balance assignments- Ledger-style balance assignments are also supported. These are like- balance assertions, but with no posting amount on the left side of the- equals sign; instead it is calculated automatically so as to satisfy- the assertion. This can be a convenience during data entry, eg when- setting opening balances:-- ; starting a new journal, set asset account balances- 2016/1/1 opening balances- assets:checking = $409.32- assets:savings = $735.24- assets:cash = $42- equity:opening balances-- or when adjusting a balance to reality:-- ; no cash left; update balance, record any untracked spending as a generic expense- 2016/1/15- assets:cash = $0- expenses:misc-- The calculated amount depends on the account's balance in the commodity- at that point (which depends on the previously-dated postings of the- commodity to that account since the last balance assertion or assign-- ment). Note that using balance assignments makes your journal a little- less explicit; to know the exact amount posted, you have to run hledger- or do the calculations yourself, instead of just reading it.-- Balance assignments and prices- A transaction price in a balance assignment will cause the calculated- amount to have that price attached:-- 2019/1/1- (a) = $1 @ EUR2-- $ hledger print --explicit- 2019-01-01- (a) $1 @ EUR2 = $1 @ EUR2-- Directives- A directive is a line in the journal beginning with a special keyword,- that influences how the journal is processed. hledger's directives are- based on a subset of Ledger's, but there are many differences (and also- some differences between hledger versions).-- Directives' behaviour and interactions can get a little bit complex, so- here is a table summarising the directives and their effects, with- links to more detailed docs.--- direc- end subdi- purpose can affect (as of- tive directive rec- 2018/06)- tives- ------------------------------------------------------------------------------------- account any document account names, all entries in all- text declare account types & dis- files, before or- play order after- alias end rewrite account names following entries- aliases until end of cur-- rent file or end- directive- apply end apply prepend a common parent to following entries- account account account names until end of cur-- rent file or end- directive- comment end com- ignore part of journal following entries- ment until end of cur-- rent file or end- directive- commod- format declare a commodity and its number notation:- ity number notation & display following entries- style until end of cur-- rent file; display- style: amounts of- that commodity in- reports- D declare a commodity to be default commodity:- used for commodityless following commod-- amounts, and its number ityless entries- notation & display style until end of cur-- rent file; number- notation: following- entries in that- commodity until end- of current file;- display style:- amounts of that- commodity in- reports- include include entries/directives what the included- from another file directives affect- payee declare a payee name following entries- until end of cur-- rent file- P declare a market price for a amounts of that- commodity commodity in- reports, when -V is- used- Y declare a year for yearless following entries- dates until end of cur-- rent file- = declare an auto posting all entries in par-- rule, adding postings to ent/current/child- other transactions files (but not sib-- ling files, see- #1212)-- And some definitions:--- subdi- optional indented directive line immediately following a parent- rec- directive- tive- number how to interpret numbers when parsing journal entries (the iden-- nota- tity of the decimal separator character). (Currently each com-- tion modity can have its own notation, even in the same file.)--- dis- how to display amounts of a commodity in reports (symbol side- play and spacing, digit groups, decimal separator, decimal places)- style- direc- which entries and (when there are multiple files) which files- tive are affected by a directive- scope-- As you can see, directives vary in which journal entries and files they- affect, and whether they are focussed on input (parsing) or output- (reports). Some directives have multiple effects.-- Directives and multiple files- If you use multiple -f/--file options, or the include directive,- hledger will process multiple input files. But note that directives- which affect input (see above) typically last only until the end of the- file in which they occur.-- This may seem inconvenient, but it's intentional; it makes reports sta-- ble and deterministic, independent of the order of input. Otherwise- you could see different numbers if you happened to write -f options in- a different order, or if you moved includes around while cleaning up- your files.-- It can be surprising though; for example, it means that alias direc-- tives do not affect parent or sibling files (see below).-- Comment blocks- A line containing just comment starts a commented region of the file,- and a line containing just end comment (or the end of the current file)- ends it. See also comments.-- Including other files- You can pull in the content of additional files by writing an include- directive, like this:-- include FILEPATH-- Only journal files can include, and only journal, timeclock or timedot- files can be included (not CSV files, currently).-- If the file path does not begin with a slash, it is relative to the- current file's folder.-- A tilde means home directory, eg: include ~/main.journal.-- The path may contain glob patterns to match multiple files, eg: include- *.journal.-- There is limited support for recursive wildcards: **/ (the slash is- required) matches 0 or more subdirectories. It's not super convenient- since you have to avoid include cycles and including directories, but- this can be done, eg: include */**/*.journal.-- The path may also be prefixed to force a specific file format, overrid-- ing the file extension (as described in hledger.1 -> Input files):- include timedot:~/notes/2020*.md.-- Default year- You can set a default year to be used for subsequent dates which don't- specify a year. This is a line beginning with Y followed by the year.- Eg:-- Y2009 ; set default year to 2009-- 12/15 ; equivalent to 2009/12/15- expenses 1- assets-- Y2010 ; change default year to 2010-- 2009/1/30 ; specifies the year, not affected- expenses 1- assets-- 1/31 ; equivalent to 2010/1/31- expenses 1- assets-- Declaring payees- The payee directive can be used to declare a limited set of payees- which may appear in transaction descriptions. The "payees" check will- report an error if any transaction refers to a payee that has not been- declared. Eg:-- payee Whole Foods-- Declaring commodities- You can use commodity directives to declare your commodities. In fact- the commodity directive performs several functions at once:-- 1. It declares commodities which may be used in the journal. This can- optionally be enforced, providing useful error checking. (Cf Com-- modity error checking)-- 2. It declares which decimal mark character (period or comma), to- expect when parsing input - useful to disambiguate international- number formats in your data. Without this, hledger will parse both- 1,000 and 1.000 as 1. (Cf Amounts)-- 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- style)-- 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.-- Generally you should put them at the top of your journal file (since- for function 2, they affect only following amounts, cf #793).-- A commodity directive is just the word commodity followed by a sample- amount, like this:-- ;commodity SAMPLEAMOUNT-- commodity $1000.00- commodity 1,000.0000 AAAA ; optional same-line comment-- It may also be written on multiple lines, and use the format subdirec-- tive, as in Ledger. Note in this case the commodity symbol appears- twice; it must be the same in both places:-- ;commodity SYMBOL- ; format SAMPLEAMOUNT-- ; display indian rupees with currency name on the left,- ; thousands, lakhs and crores comma-separated,- ; period as decimal point, and two decimal places.- commodity INR- format INR 1,00,00,000.00-- Remember that if the commodity symbol contains spaces, numbers, or- punctuation, it must be enclosed in double quotes (cf Commodity).-- The amount's quantity does not matter; only the format is significant.- It must include a decimal mark - either a period or a comma - followed- by 0 or more decimal digits.-- A few more examples:-- # number formats for $, EUR, INR and the no-symbol commodity:- commodity $1,000.00- commodity EUR 1.000,00- commodity INR 9,99,99,999.0- commodity 1 000 000.-- Note hledger normally uses banker's rounding, so 0.5 displayed with- zero decimal digits is "0". (More at Commodity display style.)-- Commodity error checking- In strict mode, enabled with the -s/--strict flag, hledger will report- an error if a commodity symbol is used that has not been declared by a- commodity directive. This works similarly to account error checking,- see the notes there for more details.-- Default commodity- The D directive sets a default commodity, to be used for any subsequent- commodityless amounts (ie, plain numbers) seen while parsing the jour-- nal. This effect lasts until the next D directive, or the end of the- journal.-- For compatibility/historical reasons, D also acts like a commodity- directive (setting the commodity's decimal mark for parsing and display- style for output).-- As with commodity, the amount must include a decimal mark (either- period or comma). If both commodity and D directives are used for the- same commodity, the commodity style takes precedence.-- The syntax is D AMOUNT. Eg:-- ; commodity-less amounts should be treated as dollars- ; (and displayed with the dollar sign on the left, thousands separators and two decimal places)- D $1,000.00-- 1/1- a 5 ; <- commodity-less amount, parsed as $5 and displayed as $5.00- b-- Declaring market prices- The P directive declares a market price, which is an exchange rate- between two commodities on a certain date. (In Ledger, they are called- "historical prices".) These are often obtained from a stock exchange,- cryptocurrency exchange, or the foreign exchange market.-- The format is:-- P DATE COMMODITY1SYMBOL COMMODITY2AMOUNT-- DATE is a simple date, COMMODITY1SYMBOL is the symbol of the commodity- being priced, and COMMODITY2AMOUNT is the amount (symbol and quantity)- of commodity 2 that one unit of commodity 1 is worth on this date.- Examples:-- # one euro was worth $1.35 from 2009-01-01 onward:- P 2009-01-01 EUR $1.35-- # and $1.40 from 2010-01-01 onward:- P 2010-01-01 EUR $1.40-- The -V, -X and --value flags use these market prices to show amount- values in another commodity. See Valuation.-- Declaring accounts- account directives can be used to declare accounts (ie, the places that- amounts are transferred from and to). Though not required, these dec-- larations can provide several benefits:-- o They can document your intended chart of accounts, providing a refer-- ence.-- o They can help hledger know your accounts' types (asset, liability,- equity, revenue, expense), useful for reports like balancesheet and- incomestatement.-- o They control account display order in reports, allowing non-alpha-- betic sorting (eg Revenues to appear above Expenses).-- o They can store extra information about accounts (account numbers,- notes, etc.)-- o They help with account name completion in the add command, hledger-- iadd, hledger-web, ledger-mode etc.-- o In strict mode, they restrict which accounts may be posted to by- transactions, which helps detect typos.-- The simplest form is just the word account followed by a hledger-style- account name, eg this account directive declares the assets:bank:check-- ing account:-- account assets:bank:checking-- Account error checking- By default, accounts come into existence when a transaction references- them by name. This is convenient, but it means hledger can't warn you- when you mis-spell an account name in the journal. Usually you'll find- the error later, as an extra account in balance reports, or an incor-- rect balance when reconciling.-- In strict mode, enabled with the -s/--strict flag, hledger will report- an error if any transaction uses an account name that has not been- declared by an account directive. Some notes:-- o The declaration is case-sensitive; transactions must use the correct- account name capitalisation.-- o The account directive's scope is "whole file and below" (see direc-- tives). This means it affects all of the current file, and any files- it includes, but not parent or sibling files. The position of- account 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- included files in other formats).-- o It's currently not possible to declare "all possible subaccounts"- with a wildcard; every account posted to must be declared.-- Account comments- Comments, beginning with a semicolon, can be added:-- o on the same line, after two or more spaces (because ; is allowed in- account names)-- o on the next lines, indented-- An example of both:-- account assets:bank:checking ; same-line comment, note 2+ spaces before ;- ; next-line comment- ; another with tag, acctno:12345 (not used yet)-- Same-line comments are not supported by Ledger, or hledger <1.13.-- Account subdirectives- We also allow (and ignore) Ledger-style indented subdirectives, just- for compatibility.:-- account assets:bank:checking- format blah blah ; <- subdirective, ignored-- Here is the full syntax of account directives:-- account ACCTNAME [ACCTTYPE] [;COMMENT]- [;COMMENTS]- [LEDGER-STYLE SUBDIRECTIVES, IGNORED]-- Account types- hledger recognises five main types of account, corresponding to the- account classes in the accounting equation:-- Asset, Liability, Equity, Revenue, Expense.-- These account types are important for controlling which accounts appear- in the balancesheet, balancesheetequity, incomestatement reports (and- probably for other things in future).-- Additionally, we recognise the Cash type, which is also an Asset, and- which causes accounts to appear in the cashflow report. ("Cash" here- means liquid assets, eg bank balances but typically not investments or- receivables.)-- Declaring account types- Generally, to make these reports work you should declare your top-level- accounts and their types, using account directives with type: tags.-- The tag's value should be one of: Asset, Liability, Equity, Revenue,- Expense, Cash, A, L, E, R, X, C (all case insensitive). The type is- inherited by all subaccounts except where they override it. Here's a- complete example:-- account assets ; type: Asset- account assets:bank ; type: Cash- account assets:cash ; type: Cash- account liabilities ; type: Liability- account equity ; type: Equity- account revenues ; type: Revenue- account expenses ; type: Expense-- Auto-detected account types- If you happen to use common english top-level account names, you may- not need to declare account types, as they will be detected automati-- cally using the following rules:-- If account's name matches this regular expression: | its type is:- ------------------------------------------------------------------- | ------------- ^assets?(:|$) |- and does not contain regexp (investment|receivable|:A/R|:fixed) | Cash- otherwise | Asset- ^(debts?|liabilit(y|ies))(:|$) | Liability- ^equity(:|$) | Equity- ^(income|revenue)s?(:|$) | Revenue- ^expenses?(:|$) | Expense-- Even so, explicit declarations may be a good idea, for clarity and pre-- dictability.-- Interference from auto-detected account types- If you assign any account type, it's a good idea to assign all of them,- to prevent any confusion from mixing declared and auto-detected types.- Although it's unlikely to happen in real life, here's an example: with- the following journal, balancesheetequity shows "liabilities" in both- Liabilities and Equity sections. Declaring another account as- type:Liability would fix it:-- account liabilities ; type:Equity-- 2020-01-01- assets 1- liabilities 1- equity -2-- Old account type syntax- In some hledger journals you might instead see this old syntax (the- letters ALERX, separated from the account name by two or more spaces);- this is deprecated and may be removed soon:-- account assets A- account liabilities L- account equity E- account revenues R- account expenses X-- Account display order- Account directives also set the order in which accounts are displayed,- eg in reports, the hledger-ui accounts screen, and the hledger-web- sidebar. By default accounts are listed in alphabetical order. But if- you have these account directives in the journal:-- account assets- account liabilities- account equity- account revenues- account expenses-- you'll see those accounts displayed in declaration order, not alphabet-- ically:-- $ hledger accounts -1- assets- liabilities- equity- revenues- expenses-- Undeclared accounts, if any, are displayed last, in alphabetical order.-- Note that sorting is done at each level of the account tree (within- each group of sibling accounts under the same parent). And currently,- this directive:-- account other:zoo-- would influence the position of zoo among other's subaccounts, but not- the position of other among the top-level accounts. This means:-- o you will sometimes declare parent accounts (eg account other above)- that you don't intend to post to, just to customize their display- order-- o sibling accounts stay together (you couldn't display x:y in between- a:b and a:c).-- Rewriting accounts- You can define account alias rules which rewrite your account names, or- parts of them, before generating reports. This can be useful for:-- o expanding shorthand account names to their full form, allowing easier- data entry and a less verbose journal-- o adapting old journals to your current chart of accounts-- o experimenting with new account organisations, like a new hierarchy or- combining two accounts into one-- o customising reports-- Account aliases also rewrite account names in account directives. They- do not affect account names being entered via hledger add or hledger-- web.-- See also Rewrite account names.-- Basic aliases- To set an account alias, use the alias directive in your journal file.- This affects all subsequent journal entries in the current file or its- included files (but note: not sibling or parent files). The spaces- around the = are optional:-- alias OLD = NEW-- Or, you can use the --alias 'OLD=NEW' option on the command line. This- affects all entries. It's useful for trying out aliases interactively.-- OLD and NEW are case sensitive full account names. hledger will- replace any occurrence of the old account name with the new one. Sub-- accounts are also affected. Eg:-- alias checking = assets:bank:wells fargo:checking- ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"-- Regex aliases- There is also a more powerful variant that uses a regular expression,- indicated by the forward slashes:-- alias /REGEX/ = REPLACEMENT-- or --alias '/REGEX/=REPLACEMENT'.-- REGEX is a case-insensitive regular expression. Anywhere it matches- inside an account name, the matched part will be replaced by REPLACE-- MENT. If REGEX contains parenthesised match groups, these can be ref-- erenced by the usual numeric backreferences in REPLACEMENT. Eg:-- alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3- ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"-- Also note that REPLACEMENT continues to the end of line (or on command- line, to end of option argument), so it can contain trailing white-- space.-- Combining aliases- You can define as many aliases as you like, using journal directives- and/or command line options.-- Recursive aliases - where an account name is rewritten by one alias,- then by another alias, and so on - are allowed. Each alias sees the- effect of previously applied aliases.-- In such cases it can be important to understand which aliases will be- applied and in which order. For (each account name in) each journal- entry, we apply:-- 1. alias directives preceding the journal entry, most recently parsed- first (ie, reading upward from the journal entry, bottom to top)-- 2. --alias options, in the order they appeared on the command line- (left to right).-- In other words, for (an account name in) a given journal entry:-- o the nearest alias declaration before/above the entry is applied first-- o the next alias before/above that will be be applied next, and so on-- o aliases defined after/below the entry do not affect it.-- This gives nearby aliases precedence over distant ones, and helps pro-- vide semantic stability - aliases will keep working the same way inde-- pendent of which files are being read and in which order.-- In case of trouble, adding --debug=6 to the command line will show- which aliases are being applied when.-- Aliases and multiple files- As explained at Directives and multiple files, alias directives do not- affect parent or sibling files. Eg in this command,-- hledger -f a.aliases -f b.journal-- account aliases defined in a.aliases will not affect b.journal.- Including the aliases doesn't work either:-- include a.aliases-- 2020-01-01 ; not affected by a.aliases- foo 1- bar-- This means that account aliases should usually be declared at the start- of your top-most file, like this:-- alias foo=Foo- alias bar=Bar-- 2020-01-01 ; affected by aliases above- foo 1- bar-- include c.journal ; also affected-- end aliases- You can clear (forget) all currently defined aliases with the end- aliases directive:-- end aliases-- Default parent account- You can specify a parent account which will be prepended to all- accounts within a section of the journal. Use the apply account and- end apply account directives like so:-- apply account home-- 2010/1/1- food $10- cash-- end apply account-- which is equivalent to:-- 2010/01/01- home:food $10- home:cash $-10-- If end apply account is omitted, the effect lasts to the end of the- file. Included files are also affected, eg:-- apply account business- include biz.journal- end apply account- apply account personal- include personal.journal-- Prior to hledger 1.0, legacy account and end spellings were also sup-- ported.-- A default parent account also affects account directives. It does not- affect account names being entered via hledger add or hledger-web. If- account aliases are present, they are applied after the default parent- account.-- Periodic transactions- Periodic transaction rules describe transactions that recur. They- allow hledger to generate temporary future transactions to help with- forecasting, so you don't have to write out each one in the journal,- and it's easy to try out different forecasts.-- Periodic transactions can be a little tricky, so before you use them,- read this whole section - or at least these tips:-- 1. Two spaces accidentally added or omitted will cause you trouble -- read about this below.-- 2. For troubleshooting, show the generated transactions with hledger- print --forecast tag:generated or hledger register --forecast- tag:generated.-- 3. Forecasted transactions will begin only after the last non-fore-- casted transaction's date.-- 4. Forecasted transactions will end 6 months from today, by default.- See below for the exact start/end rules.-- 5. period expressions can be tricky. Their documentation needs- improvement, but is worth studying.-- 6. Some period expressions with a repeating interval must begin on a- natural boundary of that interval. Eg in weekly from DATE, DATE- must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an- error.-- 7. Other period expressions with an interval are automatically expanded- to cover a whole number of that interval. (This is done to improve- reports, but it also affects periodic transactions. Yes, it's a bit- inconsistent with the above.) Eg: ~ every 10th day of month from- 2020/01, which is equivalent to ~ every 10th day of month from- 2020/01/01, will be adjusted to start on 2019/12/10.-- Periodic transaction rules also have a second meaning: they are used to- define budget goals, shown in budget reports.-- Periodic rule syntax- A periodic transaction rule looks like a normal journal entry, with the- date replaced by a tilde (~) followed by a period expression (mnemonic:- ~ looks like a recurring sine wave.):-- ~ monthly- expenses:rent $2000- assets:bank:checking-- There is an additional constraint on the period expression: the start- date must fall on a natural boundary of the interval. Eg monthly from- 2018/1/1 is valid, but monthly from 2018/1/15 is not.-- Partial or relative dates (M/D, D, tomorrow, last week) in the period- expression can work (useful or not). They will be relative to today's- date, unless a Y default year directive is in effect, in which case- they will be relative to Y/1/1.-- Two spaces between period expression and description!- If the period expression is followed by a transaction description,- these must be separated by two or more spaces. This helps hledger know- where the period expression ends, so that descriptions can not acciden-- tally alter their meaning, as in this example:-- ; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020"- ; ||- ; vv- ~ every 2 months in 2020, we will review- assets:bank:checking $1500- income:acme inc-- So,-- o Do write two spaces between your period expression and your transac-- tion description, if any.-- o Don't accidentally write two spaces in the middle of your period- expression.-- Forecasting with periodic transactions- The --forecast flag activates any periodic transaction rules in the- journal. They will generate temporary recurring transactions, which- are not saved in the journal, but will appear in all reports (eg- print). This can be useful for estimating balances into the future, or- experimenting with different scenarios. Or, it can be used as a data- entry aid: describe recurring transactions, and every so often copy the- output of print --forecast into the journal.-- These transactions will have an extra tag indicating which periodic- rule generated them: generated-transaction:~ PERIODICEXPR. And a simi-- lar, hidden tag (beginning with an underscore) which, because it's- never displayed by print, can be used to match transactions generated- "just now": _generated-transaction:~ PERIODICEXPR.-- Periodic transactions are generated within some forecast period. By- default, this-- o begins on the later of-- o the report start date if specified with -b/-p/date:-- o the day after the latest normal (non-periodic) transaction in the- journal, or today if there are no normal transactions.-- o ends on the report end date if specified with -e/-p/date:, or 6- months (180 days) from today.-- This means that periodic transactions will begin only after the latest- recorded transaction. And a recorded transaction dated in the future- can prevent generation of periodic transactions. (You can avoid that- by writing the future transaction as a one-time periodic rule instead -- put tilde before the date, eg ~ YYYY-MM-DD ...).-- Or, you can set your own arbitrary "forecast period", which can overlap- recorded transactions, and need not be in the future, by providing an- option argument, like --forecast=PERIODEXPR. Note the equals sign is- required, a space won't work. PERIODEXPR is a period expression, which- can specify the start date, end date, or both, like in a date: query.- (See also hledger.1 -> Report start & end date). Some examples:- --forecast=202001-202004, --forecast=jan-, --forecast=2020.-- Budgeting with periodic transactions- With the --budget flag, currently supported by the balance command,- each periodic transaction rule declares recurring budget goals for the- specified accounts. Eg the first example above declares a goal of- spending $2000 on rent (and also, a goal of depositing $2000 into- checking) every month. Goals and actual performance can then be com-- pared in budget reports.-- See also: Budgeting and Forecasting.--- Auto postings- "Automated postings" or "auto postings" are extra postings which get- added automatically to transactions which match certain queries,- defined by "auto posting rules", when you use the --auto flag.-- An auto posting rule looks a bit like a transaction:-- = QUERY- ACCOUNT AMOUNT- ...- ACCOUNT [AMOUNT]-- except the first line is an equals sign (mnemonic: = suggests match-- ing), followed by a query (which matches existing postings), and each- "posting" line describes a posting to be generated, and the posting- amounts can be:-- o a normal amount with a commodity symbol, eg $2. This will be used- as-is.-- o a number, eg 2. The commodity symbol (if any) from the matched post-- ing will be added to this.-- o a numeric multiplier, eg *2 (a star followed by a number N). The- matched posting's amount (and total price, if any) will be multiplied- by N.-- o a multiplier with a commodity symbol, eg *$2 (a star, number N, and- symbol S). The matched posting's amount will be multiplied by N, and- its commodity symbol will be replaced with S.-- Any query term containing spaces must be enclosed in single or double- quotes, as on the command line. Eg, note the quotes around the second- query term below:-- = expenses:groceries 'expenses:dining out'- (budget:funds:dining out) *-1-- Some examples:-- ; every time I buy food, schedule a dollar donation- = expenses:food- (liabilities:charity) $-1-- ; when I buy a gift, also deduct that amount from a budget envelope subaccount- = expenses:gifts- assets:checking:gifts *-1- assets:checking *1-- 2017/12/1- expenses:food $10- assets:checking-- 2017/12/14- expenses:gifts $20- assets:checking-- $ hledger print --auto- 2017-12-01- expenses:food $10- assets:checking- (liabilities:charity) $-1-- 2017-12-14- expenses:gifts $20- assets:checking- assets:checking:gifts -$20- assets:checking $20-- Auto postings and multiple files- An auto posting rule can affect any transaction in the current file, or- in any parent file or child file. Note, currently it will not affect- sibling files (when multiple -f/--file are used - see #1212).-- Auto postings and dates- A posting date (or secondary date) in the matched posting, or (taking- precedence) a posting date in the auto posting rule itself, will also- be used in the generated posting.-- Auto postings and transaction balancing / inferred amounts / balance asser-- tions- Currently, auto postings are added:-- o after missing amounts are inferred, and transactions are checked for- balancedness,-- o but before balance assertions are checked.-- Note this means that journal entries must be balanced both before and- after auto postings are added. This changed in hledger 1.12+; see #893- for background.-- Auto posting tags- Automated postings will have some extra tags:-- o generated-posting:= QUERY - shows this was generated by an auto post-- ing rule, and the query-- o _generated-posting:= QUERY - a hidden tag, which does not appear in- hledger's output. This can be used to match postings generated "just- now", rather than generated in the past and saved to the journal.-- Also, any transaction that has been changed by auto posting rules will- have these tags added:-- o modified: - this transaction was modified-- o _modified: - a hidden tag not appearing in the comment; this transac-- tion was modified "just now".--CSV FORMAT- How hledger reads CSV data, and the CSV rules file format.-- hledger can read CSV files (Character Separated Value - usually comma,- semicolon, or tab) containing dated records as if they were journal- files, automatically converting each CSV record into a transaction.-- (To learn about writing CSV, see CSV output.)-- We describe each CSV file's format with a corresponding rules file. By- default this is named like the CSV file with a .rules extension added.- Eg when reading FILE.csv, hledger also looks for FILE.csv.rules in the- same directory as FILE.csv. You can specify a different rules file- with the --rules-file option. If a rules file is not found, hledger- will create a sample rules file, which you'll need to adjust.-- This file contains rules describing the CSV data (header line, fields- layout, date format etc.), and how to construct hledger journal entries- (transactions) from it. Often there will also be a list of conditional- rules for categorising transactions based on their descriptions.- Here's an overview of the CSV rules; these are described more fully- below, after the examples:--- skip skip one or more header lines or matched CSV- records--- fields list name CSV fields, assign them to hledger- fields- field assignment assign a value to one hledger field, with- interpolation- Field names hledger field names, used in the fields list- and field assignments- separator a custom field separator- if block apply some rules to CSV records matched by- patterns- if table apply some rules to CSV records matched by- patterns, alternate syntax- end skip the remaining CSV records- date-format how to parse dates in CSV records- decimal-mark the decimal mark used in CSV amounts, if- ambiguous- newest-first disambiguate record order when there's only- one date- include inline another CSV rules file- balance-type choose which type of balance assignments to- use-- Note, for best error messages when reading CSV files, use a .csv, .tsv- or .ssv file extension or file prefix - see File Extension below.-- There's an introductory Convert CSV files tutorial on hledger.org.-- Examples- Here are some sample hledger CSV rules files. See also the full col-- lection at:- https://github.com/simonmichael/hledger/tree/master/examples/csv-- Basic- At minimum, the rules file must identify the date and amount fields,- and often it also specifies the date format and how many header lines- there are. Here's a simple CSV file and a rules file for it:-- Date, Description, Id, Amount- 12/11/2019, Foo, 123, 10.23-- # basic.csv.rules- skip 1- fields date, description, _, amount- date-format %d/%m/%Y-- $ hledger print -f basic.csv- 2019-11-12 Foo- expenses:unknown 10.23- income:unknown -10.23-- Default account names are chosen, since we didn't set them.-- Bank of Ireland- Here's a CSV with two amount fields (Debit and Credit), and a balance- field, which we can use to add balance assertions, which is not neces-- sary but provides extra error checking:-- Date,Details,Debit,Credit,Balance- 07/12/2012,LODGMENT 529898,,10.0,131.21- 07/12/2012,PAYMENT,5,,126-- # bankofireland-checking.csv.rules-- # skip the header line- skip-- # name the csv fields, and assign some of them as journal entry fields- fields date, description, amount-out, amount-in, balance-- # We generate balance assertions by assigning to "balance"- # above, but you may sometimes need to remove these because:- #- # - the CSV balance differs from the true balance,- # by up to 0.0000000000005 in my experience- #- # - it is sometimes calculated based on non-chronological ordering,- # eg when multiple transactions clear on the same day-- # date is in UK/Ireland format- date-format %d/%m/%Y-- # set the currency- currency EUR-- # set the base account for all txns- account1 assets:bank:boi:checking-- $ hledger -f bankofireland-checking.csv print- 2012-12-07 LODGMENT 529898- assets:bank:boi:checking EUR10.0 = EUR131.2- income:unknown EUR-10.0-- 2012-12-07 PAYMENT- assets:bank:boi:checking EUR-5.0 = EUR126.0- expenses:unknown EUR5.0-- The balance assertions don't raise an error above, because we're read-- ing directly from CSV, but they will be checked if these entries are- imported into a journal file.-- Amazon- Here we convert amazon.com order history, and use an if block to gener-- ate a third posting if there's a fee. (In practice you'd probably get- this data from your bank instead, but it's an example.)-- "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"- "Jul 29, 2012","Payment","To","Foo.","Completed","$20.00","$0.00","16000000000000DGLNJPI1P9B8DKPVHL"- "Jul 30, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$1.00","17LA58JSKRD4HDGLNJPI1P9B8DKPVHL"-- # amazon-orders.csv.rules-- # skip one header line- skip 1-- # name the csv fields, and assign the transaction's date, amount and code.- # Avoided the "status" and "amount" hledger field names to prevent confusion.- fields date, _, toorfrom, name, amzstatus, amzamount, fees, code-- # how to parse the date- date-format %b %-d, %Y-- # combine two fields to make the description- description %toorfrom %name-- # save the status as a tag- comment status:%amzstatus-- # set the base account for all transactions- account1 assets:amazon- # leave amount1 blank so it can balance the other(s).- # I'm assuming amzamount excludes the fees, don't remember-- # set a generic account2- account2 expenses:misc- amount2 %amzamount- # and maybe refine it further:- #include categorisation.rules-- # add a third posting for fees, but only if they are non-zero.- if %fees [1-9]- account3 expenses:fees- amount3 %fees-- $ hledger -f amazon-orders.csv print- 2012-07-29 (16000000000000DGLNJPI1P9B8DKPVHL) To Foo. ; status:Completed- assets:amazon- expenses:misc $20.00-- 2012-07-30 (17LA58JSKRD4HDGLNJPI1P9B8DKPVHL) To Adapteva, Inc. ; status:Completed- assets:amazon- expenses:misc $25.00- expenses:fees $1.00-- Paypal- Here's a real-world rules file for (customised) Paypal CSV, with some- Paypal-specific rules, and a second rules file included:-- "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"- "10/01/2019","03:46:20","PDT","Calm Radio","Subscription Payment","Completed","USD","-6.99","0.00","-6.99","simon@joyful.com","memberships@calmradio.com","60P57143A8206782E","MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month","","I-R8YLY094FJYR","","-6.99",""- "10/01/2019","03:46:20","PDT","","Bank Deposit to PP Account ","Pending","USD","6.99","0.00","6.99","","simon@joyful.com","0TU1544T080463733","","","60P57143A8206782E","","0.00",""- "10/01/2019","08:57:01","PDT","Patreon","PreApproved Payment Bill User Payment","Completed","USD","-7.00","0.00","-7.00","simon@joyful.com","support@patreon.com","2722394R5F586712G","Patreon* Membership","","B-0PG93074E7M86381M","","-7.00",""- "10/01/2019","08:57:01","PDT","","Bank Deposit to PP Account ","Pending","USD","7.00","0.00","7.00","","simon@joyful.com","71854087RG994194F","Patreon* Membership","","2722394R5F586712G","","0.00",""- "10/19/2019","03:02:12","PDT","Wikimedia Foundation, Inc.","Subscription Payment","Completed","USD","-2.00","0.00","-2.00","simon@joyful.com","tle@wikimedia.org","K9U43044RY432050M","Monthly donation to the Wikimedia Foundation","","I-R5C3YUS3285L","","-2.00",""- "10/19/2019","03:02:12","PDT","","Bank Deposit to PP Account ","Pending","USD","2.00","0.00","2.00","","simon@joyful.com","3XJ107139A851061F","","","K9U43044RY432050M","","0.00",""- "10/22/2019","05:07:06","PDT","Noble Benefactor","Subscription Payment","Completed","USD","10.00","-0.59","9.41","noble@bene.fac.tor","simon@joyful.com","6L8L1662YP1334033","Joyful Systems","","I-KC9VBGY2GWDB","","9.41",""-- # paypal-custom.csv.rules-- # Tips:- # Export from Activity -> Statements -> Custom -> Activity download- # Suggested transaction type: "Balance affecting"- # Paypal's default fields in 2018 were:- # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Shipping Address","Address Status","Item Title","Item ID","Shipping and Handling Amount","Insurance Amount","Sales Tax","Option 1 Name","Option 1 Value","Option 2 Name","Option 2 Value","Reference Txn ID","Invoice Number","Custom Number","Quantity","Receipt ID","Balance","Address Line 1","Address Line 2/District/Neighborhood","Town/City","State/Province/Region/County/Territory/Prefecture/Republic","Zip/Postal Code","Country","Contact Phone Number","Subject","Note","Country Code","Balance Impact"- # This rules file assumes the following more detailed fields, configured in "Customize report fields":- # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"-- fields date, time, timezone, description_, type, status_, currency, grossamount, feeamount, netamount, fromemail, toemail, code, itemtitle, itemid, referencetxnid, receiptid, balance, note-- skip 1-- date-format %-m/%-d/%Y-- # ignore some paypal events- if- In Progress- Temporary Hold- Update to- skip-- # add more fields to the description- description %description_ %itemtitle-- # save some other fields as tags- comment itemid:%itemid, fromemail:%fromemail, toemail:%toemail, time:%time, type:%type, status:%status_-- # convert to short currency symbols- if %currency USD- currency $- if %currency EUR- currency E- if %currency GBP- currency P-- # generate postings-- # the first posting will be the money leaving/entering my paypal account- # (negative means leaving my account, in all amount fields)- account1 assets:online:paypal- amount1 %netamount-- # the second posting will be money sent to/received from other party- # (account2 is set below)- amount2 -%grossamount-- # if there's a fee, add a third posting for the money taken by paypal.- if %feeamount [1-9]- account3 expenses:banking:paypal- amount3 -%feeamount- comment3 business:-- # choose an account for the second posting-- # override the default account names:- # if the amount is positive, it's income (a debit)- if %grossamount ^[^-]- account2 income:unknown- # if negative, it's an expense (a credit)- if %grossamount ^-- account2 expenses:unknown-- # apply common rules for setting account2 & other tweaks- include common.rules-- # apply some overrides specific to this csv-- # Transfers from/to bank. These are usually marked Pending,- # which can be disregarded in this case.- if- Bank Account- Bank Deposit to PP Account- description %type for %referencetxnid %itemtitle- account2 assets:bank:wf:pchecking- account1 assets:online:paypal-- # Currency conversions- if Currency Conversion- account2 equity:currency conversion-- # common.rules-- if- darcs- noble benefactor- account2 revenues:foss donations:darcshub- comment2 business:-- if- Calm Radio- account2 expenses:online:apps-- if- electronic frontier foundation- Patreon- wikimedia- Advent of Code- account2 expenses:dues-- if Google- account2 expenses:online:apps- description google | music-- $ hledger -f paypal-custom.csv print- 2019-10-01 (60P57143A8206782E) Calm Radio MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month ; itemid:, fromemail:simon@joyful.com, toemail:memberships@calmradio.com, time:03:46:20, type:Subscription Payment, status:Completed- assets:online:paypal $-6.99 = $-6.99- expenses:online:apps $6.99-- 2019-10-01 (0TU1544T080463733) Bank Deposit to PP Account for 60P57143A8206782E ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:46:20, type:Bank Deposit to PP Account, status:Pending- assets:online:paypal $6.99 = $0.00- assets:bank:wf:pchecking $-6.99-- 2019-10-01 (2722394R5F586712G) Patreon Patreon* Membership ; itemid:, fromemail:simon@joyful.com, toemail:support@patreon.com, time:08:57:01, type:PreApproved Payment Bill User Payment, status:Completed- assets:online:paypal $-7.00 = $-7.00- expenses:dues $7.00-- 2019-10-01 (71854087RG994194F) Bank Deposit to PP Account for 2722394R5F586712G Patreon* Membership ; itemid:, fromemail:, toemail:simon@joyful.com, time:08:57:01, type:Bank Deposit to PP Account, status:Pending- assets:online:paypal $7.00 = $0.00- assets:bank:wf:pchecking $-7.00-- 2019-10-19 (K9U43044RY432050M) Wikimedia Foundation, Inc. Monthly donation to the Wikimedia Foundation ; itemid:, fromemail:simon@joyful.com, toemail:tle@wikimedia.org, time:03:02:12, type:Subscription Payment, status:Completed- assets:online:paypal $-2.00 = $-2.00- expenses:dues $2.00- expenses:banking:paypal ; business:-- 2019-10-19 (3XJ107139A851061F) Bank Deposit to PP Account for K9U43044RY432050M ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:02:12, type:Bank Deposit to PP Account, status:Pending- assets:online:paypal $2.00 = $0.00- assets:bank:wf:pchecking $-2.00-- 2019-10-22 (6L8L1662YP1334033) Noble Benefactor Joyful Systems ; itemid:, fromemail:noble@bene.fac.tor, toemail:simon@joyful.com, time:05:07:06, type:Subscription Payment, status:Completed- assets:online:paypal $9.41 = $9.41- revenues:foss donations:darcshub $-10.00 ; business:- expenses:banking:paypal $0.59 ; business:-- CSV rules- The following kinds of rule can appear in the rules file, in any order.- Blank lines and lines beginning with # or ; are ignored.-- skip- skip N-- The word "skip" followed by a number (or no number, meaning 1) tells- hledger to ignore this many non-empty lines preceding the CSV data.- (Empty/blank lines are skipped automatically.) You'll need this when-- ever your CSV data contains header lines.-- It also has a second purpose: it can be used inside if blocks to ignore- certain CSV records (described below).-- fields list- fields FIELDNAME1, FIELDNAME2, ...-- A fields list (the word "fields" followed by comma-separated field- names) is the quick way to assign CSV field values to hledger fields.- (The other way is field assignments, see below.) A fields list does- does two things:-- 1. It names the CSV fields. This is optional, but can be convenient- later for interpolating them.-- 2. Whenever you use a standard hledger field name (defined below), the- CSV value is assigned to that part of the hledger transaction.-- Here's an example that says "use the 1st, 2nd and 4th fields as the- transaction's date, description and amount; name the last two fields- for later reference; and ignore the others":-- fields date, description, , amount, , , somefield, anotherfield-- Tips:-- o The fields list always use commas, even if your CSV data uses another- separator character.-- o Currently there must be least two items in the list (at least one- comma).-- o Field names may not contain spaces. Spaces before/after field names- are optional.-- o If the CSV contains column headings, it's a good idea to use these,- suitably modified, as the basis for your field names (eg lower-cased,- with underscores instead of spaces).-- o If some heading names match standard hledger fields, but you don't- want to set the hledger fields directly, alter those names, eg by- appending an underscore.-- o Fields you don't care about can be given a dummy name (eg: _ ), or no- name.-- field assignment- HLEDGERFIELDNAME FIELDVALUE-- Field assignments are the more flexible way to assign CSV values to- hledger fields. They can be used instead of or in addition to a fields- list (see above).-- 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-- FIELDNAME).-- Some examples:-- # set the amount to the 4th CSV field, with " USD" appended- amount %4 USD-- # combine three fields to make a comment, containing note: and date: tags- comment note: %somefield - %anotherfield, date: %1-- Tips:-- o Interpolation strips outer whitespace (so a CSV value like " 1 "- becomes 1 when interpolated) (#1051).-- o See also Tips below.-- Field names- Here are the standard hledger field (and pseudo-field) names, which you- can use in a fields list and in field assignments. For more about the- transaction parts they refer to, see Transactions.-- date field- Assigning to date sets the transaction date.-- date2 field- date2 sets the transaction's secondary date, if any.-- status field- status sets the transaction's status, if any.-- code field- code sets the transaction's code, if any.-- description field- description sets the transaction's description, if any.-- comment field- comment sets the transaction's comment, if any.-- commentN, where N is a number, sets the Nth posting's comment.-- Tips: - Only single-line comments can be assigned. - Comments can con-- tain tags, as usual.-- account field- 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- each transaction's description, and in conditional blocks.-- If a posting's account name is left unset but its amount is set (see- below), a default account name will be chosen (like "expenses:unknown"- or "income:unknown").-- amount field- amountN sets the amount of the Nth posting, and causes that posting to- be generated. By assigning to amount1, amount2, ... etc. you can- generate up to 99 postings.-- amountN-in and amountN-out can be used instead, if the CSV uses sepa-- rate fields for debits and credits (inflows and outflows). hledger- assumes both of these CSV fields are unsigned, and will automatically- negate the "-out" value. If they are signed, see "Setting amounts"- below.-- amount, or amount-in and amount-out are a legacy mode, to keep pre-- hledger-1.17 CSV rules files working (and for occasional convenience).- They are suitable only for two-posting transactions; they set both- posting 1's and posting 2's amount. Posting 2's amount will be- negated, and also converted to cost if there's a transaction price.-- If you have an existing rules file using the unnumbered form, you might- want to use the numbered form in certain conditional blocks, without- having to update and retest all the old rules. To facilitate this,- posting 1 ignores amount/amount-in/amount-out if any of- amount1/amount1-in/amount1-out are assigned, and posting 2 ignores them- if any of amount2/amount2-in/amount2-out are assigned, avoiding con-- flicts.-- currency field- currency sets a currency symbol, to be prepended to all postings'- amounts. You can use this if the CSV amounts do not have a currency- symbol, eg if it is in a separate column.-- currencyN prepends a currency symbol to just the Nth posting's amount.-- balance field- balanceN sets a balance assertion amount (or if the posting amount is- left empty, a balance assignment) on posting N.-- 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- rule (see below).-- See Tips below for more about setting amounts and currency.-- separator- You can use the separator rule to read other kinds of character-sepa-- rated data. The argument is any single separator character, or the- words tab or space (case insensitive). Eg, for comma-separated values- (CSV):-- separator ,-- or for semicolon-separated values (SSV):-- separator ;-- or for tab-separated values (TSV):-- separator TAB-- If the input file has a .csv, .ssv or .tsv file extension (or a csv:,- ssv:, tsv: prefix), the appropriate separator will be inferred automat-- ically, and you won't need this rule.-- if block- if MATCHER- RULE-- if- MATCHER- MATCHER- MATCHER- RULE- RULE-- Conditional blocks ("if blocks") are a block of rules that are applied- only to CSV records which match certain patterns. They are often used- for customising account names based on transaction descriptions.-- Matching the whole record- Each MATCHER can be a record matcher, which looks like this:-- REGEX-- REGEX is a case-insensitive regular expression that tries to match any-- where within the CSV record. It is a POSIX ERE (extended regular- expression) that also supports GNU word boundaries (\b, \B, \<, \>),- and nothing else. If you have trouble, be sure to check our doc:- https://hledger.org/hledger.html#regular-expressions-- Important note: the record that is matched is not the original record,- but a synthetic one, with any enclosing double quotes (but not enclos-- ing whitespace) removed, and always comma-separated (which means that a- field containing a comma will appear like two fields). Eg, if the- original record is 2020-01-01; "Acme, Inc."; 1,000, the REGEX will- actually see 2020-01-01,Acme, Inc., 1,000).-- Matching individual fields- Or, MATCHER can be a field matcher, like this:-- %CSVFIELD REGEX-- which matches just the content of a particular CSV field. CSVFIELD is- a percent sign followed by the field's name or column number, like- %date or %1.-- Combining matchers- A single matcher can be written on the same line as the "if"; or multi-- ple matchers can be written on the following lines, non-indented. Mul-- tiple matchers are OR'd (any one of them can match), unless one begins- with an & symbol, in which case it is AND'ed with the previous matcher.-- if- MATCHER- & MATCHER- RULE-- Rules applied on successful match- After the patterns there should be one or more rules to apply, all- indented by at least one space. Three kinds of rule are allowed in- conditional blocks:-- o field assignments (to set a hledger field)-- o skip (to skip the matched CSV record)-- o end (to skip all remaining CSV records).-- Examples:-- # if the CSV record contains "groceries", set account2 to "expenses:groceries"- if groceries- account2 expenses:groceries-- # if the CSV record contains any of these patterns, set account2 and comment as shown- if- monthly service fee- atm transaction fee- banking thru software- account2 expenses:business:banking- comment XXX deductible ? check it-- if table- if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn- MATCHER1,VALUE11,VALUE12,...,VALUE1n- MATCHER2,VALUE21,VALUE22,...,VALUE2n- MATCHER3,VALUE31,VALUE32,...,VALUE3n- <empty line>-- Conditional tables ("if tables") are a different syntax to specify- field assignments that will be applied only to CSV records which match- certain patterns.-- MATCHER could be either field or record matcher, as described above.- When MATCHER matches, values from that row would be assigned to the CSV- fields named on the if line, in the same order.-- Therefore if table is exactly equivalent to a sequence of of if blocks:-- if MATCHER1- CSVFIELDNAME1 VALUE11- CSVFIELDNAME2 VALUE12- ...- CSVFIELDNAMEn VALUE1n-- if MATCHER2- CSVFIELDNAME1 VALUE21- CSVFIELDNAME2 VALUE22- ...- CSVFIELDNAMEn VALUE2n-- if MATCHER3- CSVFIELDNAME1 VALUE31- CSVFIELDNAME2 VALUE32- ...- CSVFIELDNAMEn VALUE3n-- Each line starting with MATCHER should contain enough (possibly empty)- values for all the listed fields.-- Rules would be checked and applied in the order they are listed in the- table and, like with if blocks, later rules (in the same or another ta-- ble) or if blocks could override the effect of any rule.-- Instead of ',' you can use a variety of other non-alphanumeric charac-- ters as a separator. First character after if is taken to be the sepa-- rator for the rest of the table. It is the responsibility of the user- to ensure that separator does not occur inside MATCHERs and values -- there is no way to escape separator.-- Example:-- if,account2,comment- atm transaction fee,expenses:business:banking,deductible? check it- %description groceries,expenses:groceries,- 2020/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out-- end- This rule can be used inside if blocks (only), to make hledger stop- reading this CSV file and move on to the next input file, or to command- execution. Eg:-- # ignore everything following the first empty record- if ,,,,- end-- date-format- date-format DATEFMT-- This is a helper for the date (and date2) fields. If your CSV dates- are not formatted like YYYY-MM-DD, YYYY/MM/DD or YYYY.MM.DD, you'll- need to add a date-format rule describing them with a strptime date- parsing pattern, which must parse the CSV date value completely. Some- examples:-- # MM/DD/YY- date-format %m/%d/%y-- # D/M/YYYY- # The - makes leading zeros optional.- date-format %-d/%-m/%Y-- # YYYY-Mmm-DD- date-format %Y-%h-%d-- # M/D/YYYY HH:MM AM some other junk- # Note the time and junk must be fully parsed, though only the date is used.- date-format %-m/%-d/%Y %l:%M %p some other junk-- For the supported strptime syntax, see:- https://hackage.haskell.org/package/time/docs/Data-Time-For-- mat.html#v:formatTime-- Note that although you can parse date-times which include a time zone,- that time zone is ignored; it will not change the date that is parsed.- This means when reading CSV data with times not in your local time- zone, dates can be "off by one".-- decimal-mark- decimal-mark .-- or:-- decimal-mark ,-- hledger automatically accepts either period or comma as a decimal mark- when parsing numbers (cf Amounts). However if any numbers in the CSV- contain digit group marks, such as thousand-separating commas, you- should declare the decimal mark explicitly with this rule, to avoid- misparsed numbers.-- newest-first- hledger always sorts the generated transactions by date. Transactions- on the same date should appear in the same order as their CSV records,- as hledger can usually auto-detect whether the CSV's normal order is- oldest first or newest first. But if all of the following are true:-- o the CSV might sometimes contain just one day of data (all records- having the same date)-- o the CSV records are normally in reverse chronological order (newest- at the top)-- o and you care about preserving the order of same-day transactions-- then, you should add the newest-first rule as a hint. Eg:-- # tell hledger explicitly that the CSV is normally newest first- newest-first-- include- include RULESFILE-- This includes the contents of another CSV rules file at this point.- RULESFILE is an absolute file path or a path relative to the current- file's directory. This can be useful for sharing common rules between- several rules files, eg:-- # someaccount.csv.rules-- ## someaccount-specific rules- fields date,description,amount- account1 assets:someaccount- account2 expenses:misc-- ## common rules- include categorisation.rules-- balance-type- Balance assertions generated by assigning to balanceN are of the simple- = type by default, which is a single-commodity, subaccount-excluding- assertion. You may find the subaccount-including variants more useful,- eg if you have created some virtual subaccounts of checking to help- with budgeting. You can select a different type of assertion with the- balance-type rule:-- # balance assertions will consider all commodities and all subaccounts- balance-type ==*-- Here are the balance assertion types for quick reference:-- = single commodity, exclude subaccounts- =* single commodity, include subaccounts- == multi commodity, exclude subaccounts- ==* multi commodity, include subaccounts-- Tips- Rapid feedback- It's a good idea to get rapid feedback while creating/troubleshooting- CSV rules. Here's a good way, using entr from http://eradman.com/entr-- project :-- $ ls foo.csv* | entr bash -c 'echo ----; hledger -f foo.csv print desc:SOMEDESC'-- A desc: query (eg) is used to select just one, or a few, transactions- of interest. "bash -c" is used to run multiple commands, so we can- echo a separator each time the command re-runs, making it easier to- read the output.-- Valid CSV- hledger accepts CSV conforming to RFC 4180. When CSV values are- enclosed in quotes, note:-- o they must be double quotes (not single quotes)-- o spaces outside the quotes are not allowed-- File Extension- To help hledger identify the format and show the right error messages,- CSV/SSV/TSV files should normally be named with a .csv, .ssv or .tsv- filename extension. Or, the file path should be prefixed with csv:,- ssv: or tsv:. Eg:-- $ hledger -f foo.ssv print-- or:-- $ cat foo | hledger -f ssv:- foo-- You can override the file extension with a separator rule if needed.- See also: Input files in the hledger manual.-- Reading multiple CSV files- If you use multiple -f options to read multiple CSV files at once,- hledger will look for a correspondingly-named rules file for each CSV- file. But if you use the --rules-file option, that rules file will be- used for all the CSV files.-- Valid transactions- After reading a CSV file, hledger post-processes and validates the gen-- erated journal entries as it would for a journal file - balancing them,- applying balance assignments, and canonicalising amount styles. Any- errors at this stage will be reported in the usual way, displaying the- problem entry.-- There is one exception: balance assertions, if you have generated them,- will not be checked, since normally these will work only when the CSV- data is part of the main journal. If you do need to check balance- assertions generated from CSV right away, pipe into another hledger:-- $ hledger -f file.csv print | hledger -f- print-- Deduplicating, importing- When you download a CSV file periodically, eg to get your latest bank- transactions, the new file may overlap with the old one, containing- some of the same records.-- The import command will (a) detect the new transactions, and (b) append- just those transactions to your main journal. It is idempotent, so you- don't have to remember how many times you ran it or with which version- of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This- is the easiest way to import CSV data. Eg:-- # download the latest CSV files, then run this command.- # Note, no -f flags needed here.- $ hledger import *.csv [--dry]-- This method works for most CSV files. (Where records have a stable- chronological order, and new records appear only at the new end.)-- A number of other tools and workflows, hledger-specific and otherwise,- exist for converting, deduplicating, classifying and managing CSV data.- See:-- o https://hledger.org -> sidebar -> real world setups-- o https://plaintextaccounting.org -> data import/conversion-- Setting amounts- Some tips on using the amount-setting rules discussed above.-- Here are the ways to set a posting's amount:-- 1. If the CSV has a single amount field:- Assign (via a fields list or a field assignment) to amountN. This sets- the Nth posting's amount. N is usually 1 or 2 but can go up to 99.-- 2. If the CSV has separate amount fields for debit & credit (in & out):-- a. If both fields are unsigned:- Assign to amountN-in and amountN-out. This sets posting N's amount- to whichever of these has a non-zero value, and negates the "-out"- value.-- b. If either field is signed (can contain a minus sign):- Use a conditional rule to flip the sign (of non-empty values).- Since hledger always negates amountN-out, if it was already nega-- tive, we must undo that by negating once more (but only if the- field is non-empty):-- fields date, description, amount1-in, amount1-out- if %amount1-out [1-9]- amount1-out -%amount1-out-- c. If both fields, or neither field, can contain a non-zero value:- hledger normally expects exactly one of the fields to have a non-- zero value. Eg, the amountN-in/amountN-out rules would reject- value pairs like these:-- "", ""- "0", "0"- "1", "none"-- So, use smarter conditional rules to set the amount from the appro-- priate field. Eg, these rules would make it use only the value- containing non-zero digits, handling the above:-- fields date, description, in, out- if %in [1-9]- amount1 %in- if %out [1-9]- amount1 %out-- 3. If you are stuck with hledger <1.17, or you want posting 2's amount- converted to cost:- Assign to amount (or to amount-in and amount-out). (The old numberless- syntax, which sets amount1 and amount2.)-- 4. If the CSV has the balance instead of the transaction amount:- Assign to balanceN, which sets posting N's amount indirectly via a bal-- ance assignment. (Old syntax: balance, equivalent to balance1.)-- o If hledger guesses the wrong default account name:- When setting the amount via balance assertion, hledger may guess- the wrong default account name. So, set the account name explic-- itly, eg:-- fields date, description, balance1- account1 assets:checking-- Amount signs- There is some special handling for amount signs, to simplify parsing- and sign-flipping:-- o If an amount value begins with a plus sign:- that will be removed: +AMT becomes AMT-- o If an amount value is parenthesised:- it will be de-parenthesised and sign-flipped: (AMT) becomes -AMT-- o If an amount value has two minus signs (or two sets of parentheses,- or a minus sign and parentheses):- they cancel out and will be removed: --AMT or -(AMT) becomes AMT-- o If an amount value contains just a sign (or just a set of parenthe-- ses):- that is removed, making it an empty value. "+" or "-" or "()" becomes- "".-- Setting currency/commodity- If the currency/commodity symbol is included in the CSV's amount- field(s):-- 2020-01-01,foo,$123.00-- you don't have to do anything special for the commodity symbol, it will- be assigned as part of the amount. Eg:-- fields date,description,amount-- 2020-01-01 foo- expenses:unknown $123.00- income:unknown $-123.00-- If the currency is provided as a separate CSV field:-- 2020-01-01,foo,USD,123.00-- You can assign that to the currency pseudo-field, which has the special- effect of prepending itself to every amount in the transaction (on the- left, with no separating space):-- fields date,description,currency,amount-- 2020-01-01 foo- expenses:unknown USD123.00- income:unknown USD-123.00-- Or, you can use a field assignment to construct the amount yourself,- with more control. Eg to put the symbol on the right, and separated by- a space:-- fields date,description,cur,amt- amount %amt %cur-- 2020-01-01 foo- expenses:unknown 123.00 USD- income:unknown -123.00 USD-- Note we used a temporary field name (cur) that is not currency - that- would trigger the prepending effect, which we don't want here.-- Amount decimal places- Like amounts in a journal file, the amounts generated by CSV rules like- 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- 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- hledger field:-- # Name the third CSV field "amount1"- fields date,description,amount1-- # Set hledger's amount1 to the CSV amount1 field followed by USD- amount1 %amount1 USD-- # Set comment to the CSV amount1 (not the amount1 assigned above)- comment %amount1-- Here, since there's no CSV amount1 field, %amount1 will produce a lit-- eral "amount1":-- fields date,description,csvamount- amount1 %csvamount USD- # Can't interpolate amount1 here- comment %amount1-- When there are multiple field assignments to the same hledger field,- only the last one takes effect. Here, comment's value will be be B, or- C if "something" is matched, but never A:-- comment A- comment B- if something- comment C-- How CSV rules are evaluated- Here's how to think of CSV rules being evaluated (if you really need- to). First,-- o include - all includes are inlined, from top to bottom, depth first.- (At each include point the file is inlined and scanned for further- includes, recursively, before proceeding.)-- Then "global" rules are evaluated, top to bottom. If a rule is- repeated, the last one wins:-- o skip (at top level)-- o date-format-- o newest-first-- o fields - names the CSV fields, optionally sets up initial assignments- to hledger fields-- Then for each CSV record in turn:-- o test all if blocks. If any of them contain a end rule, skip all- remaining CSV records. Otherwise if any of them contain a skip rule,- skip that many CSV records. If there are multiple matched skip- rules, the first one wins.-- o collect all field assignments at top level and in matched if blocks.- When there are multiple assignments for a field, keep only the last- one.-- o compute a value for each hledger field - either the one that was- assigned to it (and interpolate the %CSVFIELDNAME references), or a- default-- o generate a synthetic hledger transaction from these values.-- This is all part of the CSV reader, one of several readers hledger can- use to parse input files. When all files have been read successfully,- the transactions are passed as input to whichever hledger command the- user specified.--TIMECLOCK FORMAT- The time logging format of timeclock.el, as read by hledger.-- hledger can read time logs in timeclock format. As with Ledger, these- are (a subset of) timeclock.el's format, containing clock-in and clock-- out entries as in the example below. The date is a simple date. The- time format is HH:MM[:SS][+-ZZZZ]. Seconds and timezone are optional.- The timezone, if present, must be four digits and is ignored (currently- the time is always interpreted as a local time).-- i 2015/03/30 09:00:00 some:account name optional description after two spaces- o 2015/03/30 09:20:00- i 2015/03/31 22:21:45 another account- o 2015/04/01 02:00:34-- hledger treats each clock-in/clock-out pair as a transaction posting- some number of hours to an account. Or if the session spans more than- one day, it is split into several transactions, one for each day. For- the above time log, hledger print generates these journal entries:-- $ hledger -f t.timeclock print- 2015-03-30 * optional description after two spaces- (some:account name) 0.33h-- 2015-03-31 * 22:21-23:59- (another account) 1.64h-- 2015-04-01 * 00:00-02:00- (another account) 2.01h-- Here is a sample.timeclock to download and some queries to try:-- $ hledger -f sample.timeclock balance # current time balances- $ hledger -f sample.timeclock register -p 2009/3 # sessions in march 2009- $ hledger -f sample.timeclock register -p weekly --depth 1 --empty # time summary by week-- To generate time logs, ie to clock in and clock out, you could:-- o use emacs and the built-in timeclock.el, or the extended timeclock-- x.el and perhaps the extras in ledgerutils.el-- o at the command line, use these bash aliases: shell alias ti="echo- i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o- `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"-- o or use the old ti and to scripts in the ledger 2.x repository. These- rely on a "timeclock" executable which I think is just the ledger 2- executable renamed.--TIMEDOT FORMAT- hledger's human-friendly time logging format.-- Timedot is a plain text format for logging dated, categorised quanti-- ties (of time, usually), supported by hledger. It is convenient for- approximate and retroactive time logging, eg when the real-time clock-- in/out required with a timeclock file is too precise or too interrup-- tive. It can be formatted like a bar chart, making clear at a glance- where time was spent.-- Though called "timedot", this format is read by hledger as commodity-- less quantities, so it could be used to represent dated quantities- other than time. In the docs below we'll assume it's time.-- A timedot file contains a series of day entries. A day entry begins- with a non-indented hledger-style simple date (Y-M-D, Y/M/D, Y.M.D..)- Any additional text on the same line is used as a transaction descrip-- tion for this day.-- This is followed by optionally-indented timelog items for that day, one- per line. Each timelog item is a note, usually a- hledger:style:account:name representing a time category, followed by- two or more spaces, and a quantity. Each timelog item generates a- hledger transaction.-- Quantities can be written as:-- o dots: a sequence of dots (.) representing quarter hours. Spaces may- optionally be used for grouping. Eg: .... ..-- o an integral or decimal number, representing hours. Eg: 1.5-- o an integral or decimal number immediately followed by a unit symbol- s, m, h, d, w, mo, or y, representing seconds, minutes, hours, days- weeks, months or years respectively. Eg: 90m. The following equiva-- lencies are assumed, currently: 1m = 60s, 1h = 60m, 1d = 24h, 1w =- 7d, 1mo = 30d, 1y=365d.-- There is some flexibility allowing notes and todo lists to be kept- right in the time log, if needed:-- o Blank lines and lines beginning with # or ; are ignored.-- o Lines not ending with a double-space and quantity are parsed as items- taking no time, which will not appear in balance reports by default.- (Add -E to see them.)-- o Org mode headlines (lines beginning with one or more * followed by a- space) can be used as date lines or timelog items (the stars are- ignored). Also all org headlines before the first date line are- ignored. This means org users can manage their timelog as an org- outline (eg using org-mode/orgstruct-mode in Emacs), for organisa-- tion, faster navigation, controlling visibility etc.-- Examples:-- # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.- 2016/2/1- inc:client1 .... .... .... .... .... ....- fos:haskell .... ..- biz:research .-- 2016/2/2- inc:client1 .... ....- biz:research .-- 2016/2/3- inc:client1 4- fos:hledger 3- biz:research 1-- * Time log- ** 2020-01-01- *** adm:time .- *** adm:finance .-- * 2020 Work Diary- ** Q1- *** 2020-02-29- **** DONE- 0700 yoga- **** UNPLANNED- **** BEGUN- hom:chores- cleaning ...- water plants- outdoor - one full watering can- indoor - light watering- **** TODO- adm:planning: trip- *** LATER-- Reporting:-- $ hledger -f t.timedot print date:2016/2/2- 2016-02-02 *- (inc:client1) 2.00-- 2016-02-02 *- (biz:research) 0.25-- $ hledger -f t.timedot bal --daily --tree- Balance changes in 2016-02-01-2016-02-03:-- || 2016-02-01d 2016-02-02d 2016-02-03d- ============++========================================- biz || 0.25 0.25 1.00- research || 0.25 0.25 1.00- fos || 1.50 0 3.00- haskell || 1.50 0 0- hledger || 0 0 3.00- inc || 6.00 2.00 4.00- client1 || 6.00 2.00 4.00- ------------++----------------------------------------- || 7.75 2.25 8.00-- I prefer to use period for separating account components. We can make- this work with an account alias:-- 2016/2/4- fos.hledger.timedot 4- fos.ledger ..-- $ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4 --tree- 4.50 fos- 4.00 hledger:timedot- 0.50 ledger- --------------------- 4.50-- Here is a sample.timedot.--COMMON TASKS- Here are some quick examples of how to do some basic tasks with- hledger. For more details, see the reference section below, the- hledger_journal(5) manual, or the more extensive docs at- https://hledger.org.-- Getting help- $ hledger # show available commands- $ hledger --help # show common options- $ hledger CMD --help # show common and command options, and command help- $ hledger help # show available manuals/topics- $ hledger help hledger # show hledger manual as info/man/text (auto-chosen)- $ hledger help journal --man # show the journal manual as a man page- $ hledger help --help # show more detailed help for the help command-- Find more docs, chat, mail list, reddit, issue tracker:- https://hledger.org#help-feedback-- Constructing command lines- hledger has an extensive and powerful command line interface. We- strive to keep it simple and ergonomic, but you may run into one of the- confusing real world details described in OPTIONS, below. If that hap-- pens, here are some tips that may help:-- o command-specific options must go after the command (it's fine to put- all options there) (hledger CMD OPTS ARGS)-- o running add-on executables directly simplifies command line parsing- (hledger-ui OPTS ARGS)-- o enclose "problematic" args in single quotes-- o if needed, also add a backslash to hide regular expression metachar-- acters from the shell-- o to see how a misbehaving command is being parsed, add --debug=2.-- Starting a journal file- hledger looks for your accounting data in a journal file,- $HOME/.hledger.journal by default:-- $ hledger stats- The hledger journal file "/Users/simon/.hledger.journal" was not found.- Please create it first, eg with "hledger add" or a text editor.- Or, specify an existing journal file with -f or LEDGER_FILE.-- You can override this by setting the LEDGER_FILE environment variable.- It's a good practice to keep this important file under version control,- and to start a new file each year. So you could do something like- this:-- $ mkdir ~/finance- $ cd ~/finance- $ git init- Initialized empty Git repository in /Users/simon/finance/.git/- $ touch 2020.journal- $ echo "export LEDGER_FILE=$HOME/finance/2020.journal" >> ~/.bashrc- $ source ~/.bashrc- $ hledger stats- Main file : /Users/simon/finance/2020.journal- Included files :- Transactions span : to (0 days)- Last transaction : none- Transactions : 0 (0.0 per day)- Transactions last 30 days: 0 (0.0 per day)- Transactions last 7 days : 0 (0.0 per day)- Payees/descriptions : 0- Accounts : 0 (depth 0)- Commodities : 0 ()- Market prices : 0 ()-- Setting opening balances- Pick a starting date for which you can look up the balances of some- real-world assets (bank accounts, wallet..) and liabilities (credit- cards..).-- To avoid a lot of data entry, you may want to start with just one or- two accounts, like your checking account or cash wallet; and pick a- recent starting date, like today or the start of the week. You can- always come back later and add more accounts and older transactions, eg- going back to january 1st.-- Add an opening balances transaction to the journal, declaring the bal-- ances on this date. Here are two ways to do it:-- o The first way: open the journal in any text editor and save an entry- like this:-- 2020-01-01 * opening balances- assets:bank:checking $1000 = $1000- assets:bank:savings $2000 = $2000- assets:cash $100 = $100- liabilities:creditcard $-50 = $-50- equity:opening/closing balances-- These are start-of-day balances, ie whatever was in the account at- the end of the previous day.-- The * after the date is an optional status flag. Here it means- "cleared & confirmed".-- The currency symbols are optional, but usually a good idea as you'll- be dealing with multiple currencies sooner or later.-- The = amounts are optional balance assertions, providing extra error- checking.-- o The second way: run hledger add and follow the prompts to record a- similar transaction:-- $ hledger add- Adding transactions to journal file /Users/simon/finance/2020.journal- Any command line arguments will be used as defaults.- Use tab key to complete, readline keys to edit, enter to accept defaults.- An optional (CODE) may follow transaction dates.- An optional ; COMMENT may follow descriptions or amounts.- If you make a mistake, enter < at any prompt to go one step backward.- To end a transaction, enter . when prompted.- To quit, enter . at a date prompt or press control-d or control-c.- Date [2020-02-07]: 2020-01-01- Description: * opening balances- Account 1: assets:bank:checking- Amount 1: $1000- Account 2: assets:bank:savings- Amount 2 [$-1000]: $2000- Account 3: assets:cash- Amount 3 [$-3000]: $100- Account 4: liabilities:creditcard- Amount 4 [$-3100]: $-50- Account 5: equity:opening/closing balances- Amount 5 [$-3050]:- Account 6 (or . or enter to finish this transaction): .- 2020-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050-- Save this transaction to the journal ? [y]:- Saved.- Starting the next transaction (. or ctrl-D/ctrl-C to quit)- Date [2020-01-01]: .-- If you're using version control, this could be a good time to commit- the journal. Eg:-- $ git commit -m 'initial balances' 2020.journal-- Recording transactions- As you spend or receive money, you can record these transactions using- one of the methods above (text editor, hledger add) or by using the- hledger-iadd or hledger-web add-ons, or by using the import command to- convert CSV data downloaded from your bank.-- Here are some simple transactions, see the hledger_journal(5) manual- and hledger.org for more ideas:-- 2020/1/10 * gift received- assets:cash $20- income:gifts-- 2020.1.12 * farmers market- expenses:food $13- assets:cash-- 2020-01-15 paycheck- income:salary- assets:bank:checking $1000-- Reconciling- Periodically you should reconcile - compare your hledger-reported bal-- ances against external sources of truth, like bank statements or your- bank's website - to be sure that your ledger accurately represents the- real-world balances (and, that the real-world institutions have not- made a mistake!). This gets easy and fast with (1) practice and (2)- frequency. If you do it daily, it can take 2-10 minutes. If you let- it pile up, expect it to take longer as you hunt down errors and dis-- crepancies.-- A typical workflow:-- 1. Reconcile cash. Count what's in your wallet. Compare with what- hledger reports (hledger bal cash). If they are different, try to- remember the missing transaction, or look for the error in the- already-recorded transactions. A register report can be helpful- (hledger reg cash). If you can't find the error, add an adjustment- transaction. Eg if you have $105 after the above, and can't explain- the missing $2, it could be:-- 2020-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- 2. Reconcile checking. Log in to your bank's website. Compare today's- (cleared) balance with hledger's cleared balance (hledger bal check-- ing -C). If they are different, track down the error or record the- missing transaction(s) or add an adjustment transaction, similar to- the above. Unlike the cash case, you can usually compare the trans-- action history and running balance from your bank with the one- reported by hledger reg checking -C. This will be easier if you- generally record transaction dates quite similar to your bank's- clearing dates.-- 3. Repeat for other asset/liability accounts.-- Tip: instead of the register command, use hledger-ui to see a live-- updating register while you edit the journal: hledger-ui --watch --reg-- ister checking -C-- After reconciling, it could be a good time to mark the reconciled- transactions' status as "cleared and confirmed", if you want to track- that, by adding the * marker. Eg in the paycheck transaction above,- insert * between 2020-01-15 and paycheck-- If you're using version control, this can be another good time to com-- mit:-- $ git commit -m 'txns' 2020.journal-- Reporting- Here are some basic reports.-- Show all transactions:-- $ hledger print- 2020-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050-- 2020-01-10 * gift received- assets:cash $20- income:gifts-- 2020-01-12 * farmers market- expenses:food $13- assets:cash-- 2020-01-15 * paycheck- income:salary- assets:bank:checking $1000-- 2020-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- Show account names, and their hierarchy:-- $ hledger accounts --tree- assets- bank- checking- savings- cash- equity- opening/closing balances- expenses- food- misc- income- gifts- salary- liabilities- creditcard-- Show all account totals:-- $ hledger balance- $4105 assets- $4000 bank- $2000 checking- $2000 savings- $105 cash- $-3050 equity:opening/closing balances- $15 expenses- $13 food- $2 misc- $-1020 income- $-20 gifts- $-1000 salary- $-50 liabilities:creditcard- --------------------- 0-- Show only asset and liability balances, as a flat list, limited to- depth 2:-- $ hledger bal assets liabilities --flat -2- $4000 assets:bank- $105 assets:cash- $-50 liabilities:creditcard- --------------------- $4055-- Show the same thing without negative numbers, formatted as a simple- balance sheet:-- $ hledger bs --flat -2- Balance Sheet 2020-01-16-- || 2020-01-16- ========================++============- Assets ||- ------------------------++------------- assets:bank || $4000- assets:cash || $105- ------------------------++------------- || $4105- ========================++============- Liabilities ||- ------------------------++------------- liabilities:creditcard || $50- ------------------------++------------- || $50- ========================++============- Net: || $4055-- The final total is your "net worth" on the end date. (Or use bse for a- full balance sheet with equity.)-- Show income and expense totals, formatted as an income statement:-- hledger is- Income Statement 2020-01-01-2020-01-16-- || 2020-01-01-2020-01-16- ===============++=======================- Revenues ||- ---------------++------------------------ income:gifts || $20- income:salary || $1000- ---------------++------------------------ || $1020- ===============++=======================- Expenses ||- ---------------++------------------------ expenses:food || $13- expenses:misc || $2- ---------------++------------------------ || $15- ===============++=======================- Net: || $1005-- The final total is your net income during this period.-- Show transactions affecting your wallet, with running total:-- $ hledger register cash- 2020-01-01 opening balances assets:cash $100 $100- 2020-01-10 gift received assets:cash $20 $120- 2020-01-12 farmers market assets:cash $-13 $107- 2020-01-16 adjust cash assets:cash $-2 $105-- Show weekly posting counts as a bar chart:-- $ hledger activity -W- 2019-12-30 *****- 2020-01-06 ****- 2020-01-13 ****-- Migrating to a new file- At the end of the year, you may want to continue your journal in a new- file, so that old transactions don't slow down or clutter your reports,- and to help ensure the integrity of your accounting history. See the- close command.-- If using version control, don't forget to git add the new file.--LIMITATIONS- The need to precede add-on command options with -- when invoked from- hledger is awkward.-- When input data contains non-ascii characters, a suitable system locale- must be configured (or there will be an unhelpful error). Eg on POSIX,- set LANG to something other than C.-- In a Microsoft Windows CMD window, non-ascii characters and colours are- not supported.-- On Windows, non-ascii characters may not display correctly when running- a hledger built in CMD in MSYS/CYGWIN, or vice-versa.-- In a Cygwin/MSYS/Mintty window, the tab key is not supported in hledger- add.-- Not all of Ledger's journal file syntax is supported. See file format- differences.-- On large data files, hledger is slower and uses more memory than- Ledger.--TROUBLESHOOTING- Here are some issues you might encounter when you run hledger (and- remember you can also seek help from the IRC channel, mail list or bug- tracker):-- Successfully installed, but "No command 'hledger' found"- stack and cabal install binaries into a special directory, which should- be added to your PATH environment variable. Eg on unix-like systems,- that is ~/.local/bin and ~/.cabal/bin respectively.-- I set a custom LEDGER_FILE, but hledger is still using the default file- LEDGER_FILE should be a real environment variable, not just a shell- variable. The command env | grep LEDGER_FILE should show it. You may- need to use export. Here's an explanation.-- Getting errors like "Illegal byte sequence" or "Invalid or incomplete- multibyte or wide character" or "commitAndReleaseBuffer: invalid argu-- ment (invalid character)"- Programs compiled with GHC (hledger, haskell build tools, etc.) need to- have a UTF-8-aware locale configured in the environment, otherwise they- will fail with these kinds of errors when they encounter non-ascii- characters.-- To fix it, set the LANG environment variable to some locale which sup-- ports UTF-8. The locale you choose must be installed on your system.-- Here's an example of setting LANG temporarily, on Ubuntu GNU/Linux:-- $ file my.journal- my.journal: UTF-8 Unicode text # the file is UTF8-encoded- $ echo $LANG- C # LANG is set to the default locale, which does not support UTF8- $ locale -a # which locales are installed ?- C- en_US.utf8 # here's a UTF8-aware one we can use- POSIX- $ LANG=en_US.utf8 hledger -f my.journal print # ensure it is used for this command-- If available, C.UTF-8 will also work. If your preferred locale isn't- listed by locale -a, you might need to install it. Eg on- Ubuntu/Debian:-- $ apt-get install language-pack-fr- $ locale -a- C- en_US.utf8- fr_BE.utf8- fr_CA.utf8- fr_CH.utf8- fr_FR.utf8- fr_LU.utf8- POSIX- $ LANG=fr_FR.utf8 hledger -f my.journal print-- Here's how you could set it permanently, if you use a bash shell:-- $ echo "export LANG=en_US.utf8" >>~/.bash_profile- $ bash --login-- Exact spelling and capitalisation may be important. Note the differ-- ence on MacOS (UTF-8, not utf8). Some platforms (eg ubuntu) allow- variant spellings, but others (eg macos) require it to be exact:-- $ locale -a | grep -iE en_us.*utf- en_US.UTF-8- $ LANG=en_US.UTF-8 hledger -f my.journal print----REPORTING BUGS- Report bugs at http://bugs.hledger.org (or on the #hledger IRC channel- or hledger mail list)---AUTHORS- Simon Michael <simon@joyful.com> and contributors---COPYRIGHT- Copyright (C) 2007-2020 Simon Michael.- Released under GNU GPL v3 or later.---SEE ALSO- hledger(1), hledger-ui(1), hledger-web(1), ledger(1)----hledger-1.22.1 August 2021 HLEDGER(1)+ manual is for hledger 1.22.2.++SYNOPSIS+ hledger++ hledger [-f FILE] COMMAND [OPTIONS] [ARGS]++ hledger [-f FILE] ADDONCMD -- [OPTIONS] [ARGS]++DESCRIPTION+ hledger is a reliable, cross-platform set of programs for tracking+ money, time, or any other commodity, using double-entry accounting and+ a simple, editable file format. hledger is inspired by and largely+ compatible with ledger(1).++ The basic function of the hledger CLI is to read a plain text file+ describing financial transactions (in accounting terms, a general jour-+ nal) and print useful reports on standard output, or export them as+ CSV. hledger can also read some other file formats such as CSV files,+ translating them to journal format. Additionally, hledger lists other+ hledger-* executables found in the user's $PATH and can invoke them as+ subcommands.++ hledger reads data from one or more files in hledger journal, time-+ clock, timedot, or CSV format specified with -f, or $LEDGER_FILE, or+ $HOME/.hledger.journal (on windows, perhaps+ C:/Users/USER/.hledger.journal). If using $LEDGER_FILE, note this must+ be a real environment variable, not a shell variable. You can specify+ standard input with -f-.++ Transactions are dated movements of money between two (or more) named+ accounts, and are recorded with journal entries like this:++ 2015/10/16 bought food+ expenses:food $10+ assets:cash++ Most users use a text editor to edit the journal, usually with an edi-+ tor mode such as ledger-mode for added convenience. hledger's interac-+ tive add command is another way to record new transactions. hledger+ never changes existing transactions.++ To get started, you can either save some entries like the above in+ ~/.hledger.journal, or run hledger add and follow the prompts. Then+ try some commands like hledger print or hledger balance. Run hledger+ with no arguments for a list of commands.++OPTIONS+ General options+ To see general usage help, including general options which are sup-+ ported by most hledger commands, run hledger -h.++ General help options:++ -h --help+ show general or COMMAND help++ --man show general or COMMAND user manual with man++ --info show general or COMMAND user manual with info++ --version+ show general or ADDONCMD version++ --debug[=N]+ show debug output (levels 1-9, default: 1)++ General input options:++ -f FILE --file=FILE+ use a different input file. For stdin, use - (default:+ $LEDGER_FILE or $HOME/.hledger.journal)++ --rules-file=RULESFILE+ Conversion rules file to use when reading CSV (default:+ FILE.rules)++ --separator=CHAR+ Field separator to expect when reading CSV (default: ',')++ --alias=OLD=NEW+ rename accounts named OLD to NEW++ --anon anonymize accounts and payees++ --pivot FIELDNAME+ use some other field or tag for the account name++ -I --ignore-assertions+ disable balance assertion checks (note: does not disable balance+ assignments)++ -s --strict+ do extra error checking (check that all posted accounts are+ declared)++ General reporting options:++ -b --begin=DATE+ include postings/txns on or after this date (will be adjusted to+ preceding subperiod start when using a report interval)++ -e --end=DATE+ include postings/txns before this date (will be adjusted to fol-+ lowing subperiod end when using a report interval)++ -D --daily+ multiperiod/multicolumn report by day++ -W --weekly+ multiperiod/multicolumn report by week++ -M --monthly+ multiperiod/multicolumn report by month++ -Q --quarterly+ multiperiod/multicolumn report by quarter++ -Y --yearly+ multiperiod/multicolumn report by year++ -p --period=PERIODEXP+ set start date, end date, and/or reporting interval all at once+ using period expressions syntax++ --date2+ match the secondary date instead (see command help for other+ effects)++ -U --unmarked+ include only unmarked postings/txns (can combine with -P or -C)++ -P --pending+ include only pending postings/txns++ -C --cleared+ include only cleared postings/txns++ -R --real+ include only non-virtual postings++ -NUM --depth=NUM+ hide/aggregate accounts or postings more than NUM levels deep++ -E --empty+ show items with zero amount, normally hidden (and vice-versa in+ hledger-ui/hledger-web)++ -B --cost+ convert amounts to their cost/selling amount at transaction time++ -V --market+ convert amounts to their market value in default valuation com-+ modities++ -X --exchange=COMM+ convert amounts to their market value in commodity COMM++ --value+ convert amounts to cost or market value, more flexibly than+ -B/-V/-X++ --infer-market-prices+ use transaction prices (recorded with @ or @@) as additional+ market prices, as if they were P directives++ --auto apply automated posting rules to modify transactions.++ --forecast+ generate future transactions from periodic transaction rules,+ for the next 6 months or till report end date. In hledger-ui,+ also make ordinary future transactions visible.++ --color=WHEN (or --colour=WHEN)+ Should color-supporting commands use ANSI color codes in text+ output. 'auto' (default): whenever stdout seems to be a color-+ supporting terminal. 'always' or 'yes': always, useful eg when+ piping output into 'less -R'. 'never' or 'no': never. A+ NO_COLOR environment variable overrides this.++ When a reporting option appears more than once in the command line, the+ last one takes precedence.++ Some reporting options can also be written as query arguments.++ Command options+ To see options for a particular command, including command-specific+ options, run: hledger COMMAND -h.++ Command-specific options must be written after the command name, eg:+ hledger print -x.++ Additionally, if the command is an add-on, you may need to put its+ options after a double-hyphen, eg: hledger ui -- --watch. Or, you can+ run the add-on executable directly: hledger-ui --watch.++ Command arguments+ Most hledger commands accept arguments after the command name, which+ are often a query, filtering the data in some way.++ You can save a set of command line options/arguments in a file, and+ then reuse them by writing @FILENAME as a command line argument. Eg:+ hledger bal @foo.args. (To prevent this, eg if you have an argument+ that begins with a literal @, precede it with --, eg: hledger bal --+ @ARG).++ Inside the argument file, each line should contain just one option or+ argument. Avoid the use of spaces, except inside quotes (or you'll see+ a confusing error). Between a flag and its argument, use = (or noth-+ ing). Bad:++ assets depth:2+ -X USD++ Good:++ assets+ depth:2+ -X=USD++ For special characters (see below), use one less level of quoting than+ you would at the command prompt. Bad:++ -X"$"++ Good:++ -X$++ See also: Save frequently used options.++ Special characters+ Single escaping (shell metacharacters)+ In shell command lines, characters significant to your shell - such as+ spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want+ hledger to see them. This is done by enclosing them in single or dou-+ ble quotes, or by writing a backslash before them. Eg to match an+ account name containing a space:++ $ hledger register 'credit card'++ or:++ $ 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.+ 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+ using the bash shell:++ $ hledger balance cur:'\$'++ or:++ $ hledger balance cur:\\$++ Triple escaping (for add-on commands)+ When you use hledger to run an external add-on command (described+ below), one level of shell-escaping is lost from any options or argu-+ ments intended for by the add-on command, so those need an extra level+ of shell-escaping. Eg to match a literal $ sign while using the bash+ shell and running an add-on command (ui):++ $ hledger ui cur:'\\$'++ or:++ $ hledger ui cur:\\\\$++ If you wondered why four backslashes, perhaps this helps:+++ unescaped: $+ escaped: \$+ double-escaped: \\$+ triple-escaped: \\\\$++ Or, you can avoid the extra escaping by running the add-on executable+ directly:++ $ hledger-ui cur:\\$++ Less escaping+ Options and arguments are sometimes used in places other than the shell+ command line, where shell-escaping is not needed, so there you should+ use one less level of escaping. Those places include:++ o an @argumentfile++ o hledger-ui's filter field++ o hledger-web's search form++ o GHCI's prompt (used by developers).++ Unicode characters+ hledger is expected to handle non-ascii characters correctly:++ o they should be parsed correctly in input files and on the command+ line, by all hledger tools (add, iadd, hledger-web's search/add/edit+ forms, etc.)++ o they should be displayed correctly by all hledger tools, and on-+ screen alignment should be preserved.++ This requires a well-configured environment. Here are some tips:++ o A system locale must be configured, and it must be one that can+ decode the characters being used. In bash, you can set a locale like+ this: export LANG=en_US.UTF-8. There are some more details in Trou-+ bleshooting. This step is essential - without it, hledger will quit+ on encountering a non-ascii character (as with all GHC-compiled pro-+ grams).++ o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)+ must support unicode++ o the terminal must be using a font which includes the required unicode+ glyphs++ o the terminal should be configured to display wide characters as dou-+ ble width (for report alignment)++ o on Windows, for best results you should run hledger in the same kind+ of environment in which it was built. Eg hledger built in the stan-+ dard CMD.EXE environment (like the binaries on our download page)+ might show display problems when run in a cygwin or msys terminal,+ and vice versa. (See eg #961).++ Regular expressions+ hledger uses regular expressions in a number of places:++ o query terms, on the command line and in the hledger-web search form:+ REGEX, desc:REGEX, cur:REGEX, tag:...=REGEX++ o CSV rules conditional blocks: if REGEX ...++ o account alias directives and options: alias /REGEX/ = REPLACEMENT,+ --alias /REGEX/=REPLACEMENT++ hledger's regular expressions come from the regex-tdfa library. If+ they're not doing what you expect, it's important to know exactly what+ they support:++ 1. they are case insensitive++ 2. they are infix matching (they do not need to match the entire thing+ being matched)++ 3. they are POSIX ERE (extended regular expressions)++ 4. they also support GNU word boundaries (\b, \B, \<, \>)++ 5. they do not support backreferences; if you write \1, it will match+ the digit 1. Except when doing text replacement, eg in account+ aliases, where backreferences can be used in the replacement string+ to reference capturing groups in the search regexp.++ 6. they do not support mode modifiers ((?s)), character classes (\w,+ \d), or anything else not mentioned above.++ Some things to note:++ o In the alias directive and --alias option, regular expressions must+ be enclosed in forward slashes (/REGEX/). Elsewhere in hledger,+ these are not required.++ o In queries, to match a regular expression metacharacter like $ as a+ literal character, prepend a backslash. Eg to search for amounts+ with the dollar sign in hledger-web, write cur:\$.++ o On the command line, some metacharacters like $ have a special mean-+ ing to the shell and so must be escaped at least once more. See Spe-+ cial characters.++ENVIRONMENT+ LEDGER_FILE The journal file path when not specified with -f. Default:+ ~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour-+ nal).++ A typical value is ~/DIR/YYYY.journal, where DIR is a version-con-+ trolled finance directory and YYYY is the current year. Or ~/DIR/cur-+ rent.journal, where current.journal is a symbolic link to YYYY.journal.++ On Mac computers, you can set this and other environment variables in a+ more thorough way that also affects applications started from the GUI+ (say, an Emacs dock icon). Eg on MacOS Catalina I have a+ ~/.MacOSX/environment.plist file containing++ {+ "LEDGER_FILE" : "~/finance/current.journal"+ }++ To see the effect you may need to killall Dock, or reboot.++ COLUMNS The screen width used by the register command. Default: the+ full terminal width.++ NO_COLOR If this variable exists with any value, hledger will not use+ ANSI color codes in terminal output. This overrides the+ --color/--colour option.++DATA FILES+ hledger reads transactions from one or more data files. The default+ data file is $HOME/.hledger.journal (or on Windows, something like+ C:/Users/USER/.hledger.journal).++ You can override this with the $LEDGER_FILE environment variable:++ $ setenv LEDGER_FILE ~/finance/2016.journal+ $ hledger stats++ or with one or more -f/--file options:++ $ hledger -f /some/file -f another_file stats++ The file name - means standard input:++ $ cat some.journal | hledger -f-++ Data formats+ Usually the data file is in hledger's journal format, but it can be in+ any of the supported file formats, which currently are:+++ Reader: Reads: Used for file exten-+ sions:+ -----------------------------------------------------------------------------+ journal hledger journal files and some Ledger .journal .j .hledger+ journals, for transactions .ledger+ time- timeclock files, for precise time log- .timeclock+ clock ging+ timedot timedot files, for approximate time .timedot+ logging+ csv comma/semicolon/tab/other-separated .csv .ssv .tsv+ values, for data import++ These formats are described in their own sections, below.++ hledger detects the format automatically based on the file extensions+ shown above. If it can't recognise the file extension, it assumes+ journal format. So for non-journal files, it's important to use a+ recognised file extension, so as to either read successfully or to show+ relevant error messages.++ You can also force a specific reader/format by prefixing the file path+ with the format and a colon. Eg, to read a .dat file as csv format:++ $ hledger -f csv:/some/csv-file.dat stats++ Or to read stdin (-) as timeclock format:++ $ echo 'i 2009/13/1 08:00:00' | hledger print -ftimeclock:-++ Multiple files+ You can specify multiple -f options, to read multiple files as one big+ journal. There are some limitations with this:++ o most directives do not affect sibling files++ o balance assertions will not see any account balances from previous+ files++ If you need either of those things, you can++ o use a single parent file which includes the others++ o or concatenate the files into one before reading, eg: cat a.journal+ b.journal | hledger -f- CMD.++ Strict mode+ hledger checks input files for valid data. By default, the most impor-+ tant errors are detected, while still accepting easy journal files+ without a lot of declarations:++ o Are the input files parseable, with valid syntax ?++ o Are all transactions balanced ?++ o Do all balance assertions pass ?++ With the -s/--strict flag, additional checks are performed:++ o Are all accounts posted to, declared with an account directive ?+ (Account error checking)++ o Are all commodities declared with a commodity directive ? (Commodity+ error checking)++ o Are all commodity conversions declared explicitly ?++ You can also use the check command to run these and some additional+ checks.++TIME PERIODS+ Smart dates+ hledger's user interfaces accept a flexible "smart date" syntax. Smart+ dates allow some english words, can be relative to today's date, and+ can have less-significant date parts omitted (defaulting to 1).++ Examples:+++ 2004/10/1, 2004-01-01, exact date, several separators allowed. Year+ 2004.9.1 is 4+ digits, month is 1-12, day is 1-31+ 2004 start of year+ 2004/10 start of month+ 10/1 month and day in current year+ 21 day in current month+ october, oct start of month in current year+ yesterday, today, tomor- -1, 0, 1 days from today+ row+ last/this/next -1, 0, 1 periods from the current period+ day/week/month/quar-+ ter/year+ 20181201 8 digit YYYYMMDD with valid year month and day+ 201812 6 digit YYYYMM with valid year and month++ Counterexamples - malformed digit sequences might give surprising+ results:+++ 201813 6 digits with an invalid month is parsed as start of+ 6-digit year+ 20181301 8 digits with an invalid month is parsed as start of+ 8-digit year+ 20181232 8 digits with an invalid day gives an error+ 201801012 9+ digits beginning with a valid YYYYMMDD gives an error+++ Report start & end date+ By default, most hledger reports will show the full span of time repre-+ sented by the journal data. The report start date will be the earliest+ transaction or posting date, and the report end date will be the latest+ transaction, posting, or market price date.++ Often you will want to see a shorter time span, such as the current+ month. You can specify a start and/or end date using -b/--begin,+ -e/--end, -p/--period or a date: query (described below). All of these+ accept the smart date syntax.++ Some notes:++ o As in Ledger, end dates are exclusive, so you need to write the date+ after the last day you want to include.++ o As noted in reporting options: among start/end dates specified with+ options, the last (i.e. right-most) option takes precedence.++ o The effective report start and end dates are the intersection of the+ start/end dates from options and that from date: queries. That is,+ date:2019-01 date:2019 -p'2000 to 2030' yields January 2019, the+ smallest common time span.++ o A report interval (see below) will adjust start/end dates, when+ needed, so that they fall on subperiod boundaries.++ Examples:+++ -b 2016/3/17 begin on St. Patrick's day 2016+ -e 12/1 end at the start of december 1st of the current year+ (11/30 will be the last date included)+ -b thismonth all transactions on or after the 1st of the current month+ -p thismonth all transactions in the current month+ date:2016/3/17.. the above written as queries instead (.. can also be+ replaced with -)+ date:..12/1+ date:thismonth..+ date:thismonth++ Report intervals+ A report interval can be specified so that commands like register, bal-+ ance and activity become multi-period, showing each subperiod as a sep-+ arate row or column.++ The following "standard" report intervals can be enabled by using their+ corresponding flag:++ -D/--daily, -W/--weekly, -M/--monthly, -Q/--quarterly, -Y/--yearly.++ These standard intervals always start on natural interval boundaries:+ eg --weekly starts on mondays, --monthly starts on the first of the+ month, --yearly always starts on January 1st, etc.++ Certain more complex intervals, and more flexible boundary dates, can+ be specified by -p/--period. These are described in period expres-+ sions, below.++ Report intervals can only be specified by the flags above, and not by+ query arguments, currently.++ Report intervals have another effect: multi-period reports are always+ expanded to fill a whole number of subperiods. So if you use a report+ interval (other than --daily), and you have specified a start or end+ date, you may notice those dates being overridden (ie, the report+ starts earlier than your requested start date, or ends later than your+ requested end date). This is done to ensure "full" first and last sub-+ periods, so that all subperiods' numbers are comparable.++ Period expressions+ The -p/--period option accepts period expressions, a shorthand way of+ expressing a start date, end date, and/or report interval all at once.++ Here's a basic period expression specifying the first quarter of 2009.+ Note, hledger always treats start dates as inclusive and end dates as+ exclusive:++ -p "from 2009/1/1 to 2009/4/1"++ Keywords like "from" and "to" are optional, and so are the spaces, as+ long as you don't run two dates together. "to" can also be written as+ ".." or "-". These are equivalent to the above:+++ -p "2009/1/1 2009/4/1"+ -p2009/1/1to2009/4/1+ -p2009/1/1..2009/4/1++ Dates are smart dates, so if the current year is 2009, the above can+ also be written as:+++ -p "1/1 4/1"++ -p "january-apr"+ -p "this year to 4/1"++ If you specify only one date, the missing start or end date will be the+ earliest or latest transaction in your journal:+++ -p "from 2009/1/1" everything after january+ 1, 2009+ -p "from 2009/1" the same+ -p "from 2009" the same+ -p "to 2009" everything before january+ 1, 2009++ A single date with no "from" or "to" defines both the start and end+ date like so:+++ -p "2009" the year 2009; equivalent+ to "2009/1/1 to 2010/1/1"+ -p "2009/1" the month of jan; equiva-+ lent to "2009/1/1 to+ 2009/2/1"+ -p "2009/1/1" just that day; equivalent+ to "2009/1/1 to 2009/1/2"++ Or you can specify a single quarter like so:+++ -p "2009Q1" first quarter of 2009,+ equivalent to "2009/1/1 to+ 2009/4/1"+ -p "q4" fourth quarter of the cur-+ rent year++ The argument of -p can also begin with, or be, a report interval+ expression. The basic report intervals are daily, weekly, monthly,+ quarterly, or yearly, which have the same effect as the -D,-W,-M,-Q, or+ -Y flags. Between report interval and start/end dates (if any), the+ word in is optional. Examples:+++ -p "weekly from 2009/1/1 to 2009/4/1"+ -p "monthly in 2008"+ -p "quarterly"++ Note that weekly, monthly, quarterly and yearly intervals will always+ start on the first day on week, month, quarter or year accordingly, and+ will end on the last day of same period, even if associated period+ expression specifies different explicit start and end date.++ For example:+++ -p "weekly from 2009/1/1 starts on 2008/12/29, closest preceding Mon-+ to 2009/4/1" day+ -p "monthly in starts on 2018/11/01+ 2008/11/25"+ -p "quarterly from starts on 2009/04/01, ends on 2009/06/30,+ 2009-05-05 to 2009-06-01" which are first and last days of Q2 2009+ -p "yearly from starts on 2009/01/01, first day of 2009+ 2009-12-29"++ The following more complex report intervals are also supported:+ biweekly, fortnightly, bimonthly, every day|week|month|quarter|year,+ every N days|weeks|months|quarters|years.++ All of these will start on the first day of the requested period and+ end on the last one, as described above.++ Examples:+++ -p "bimonthly from 2008" periods will have boundaries on 2008/01/01,+ 2008/03/01, ...+ -p "every 2 weeks" starts on closest preceding Monday+ -p "every 5 month from periods will have boundaries on 2009/03/01,+ 2009/03" 2009/08/01, ...++ If you want intervals that start on arbitrary day of your choosing and+ span a week, month or year, you need to use any of the following:++ every Nth day of week, every WEEKDAYNAME (eg+ mon|tue|wed|thu|fri|sat|sun), every Nth day [of month], every Nth WEEK-+ DAYNAME [of month], every MM/DD [of year], every Nth MMM [of year],+ every MMM Nth [of year].++ Examples:+++ -p "every 2nd day of periods will go from Tue to Tue+ week"+ -p "every Tue" same+ -p "every 15th day" period boundaries will be on 15th of each+ month+ -p "every 2nd Monday" period boundaries will be on second Monday of+ each month+ -p "every 11/05" yearly periods with boundaries on 5th of Nov+ -p "every 5th Nov" same+ -p "every Nov 5th" same++ Show historical balances at end of 15th each month (N is exclusive end+ date):++ hledger balance -H -p "every 16th day"++ Group postings from start of wednesday to end of next tuesday (N is+ start date and exclusive end date):++ hledger register checking -p "every 3rd day of week"++DEPTH+ With the --depth N option (short form: -N), commands like account, bal-+ ance and register will show only the uppermost accounts in the account+ tree, down to level N. Use this when you want a summary with less+ detail. This flag has the same effect as a depth: query argument (so+ -2, --depth=2 or depth:2 are equivalent).++QUERIES+ One of hledger's strengths is being able to quickly report on a precise+ subset of your data. Most hledger commands accept optional query argu-+ ments to restrict their scope. The syntax is as follows:++ o Zero or more space-separated query terms. These are most often+ account name substrings:++ utilities food:groceries++ o Terms with spaces or other special characters should be enclosed in+ quotes:++ "personal care"++ o Regular expressions are also supported:++ "^expenses\b" "accounts (payable|receivable)"++ o Add a query type prefix to match other parts of the data:++ date:202012- desc:amazon cur:USD amt:">100" status:++ o Add a not: prefix to negate a term:++ not:cur:USD++ Query types+ Here are the types of query term available. Remember these can also be+ prefixed with not: to convert them into a negative match.++ acct:REGEX, REGEX+ 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.++ amt:N, amt:<N, amt:<=N, amt:>N, amt:>=N+ 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-+ erwise, the absolute magnitudes are compared, ignoring sign.++ code:REGEX+ Match by transaction code (eg check number).++ cur:REGEX+ Match postings or transactions including any amounts whose cur-+ rency/commodity symbol is fully matched by REGEX. (For a 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+ escaping. So eg to match the dollar sign:+ hledger print cur:\\$.++ desc:REGEX+ Match transaction descriptions.++ date:PERIODEXPR+ Match dates (or with the --date2 flag, secondary dates) within the+ specified period. PERIODEXPR is a period expression with no report+ interval. Examples:+ date:2016, date:thismonth, date:2/1-2/15, date:2021-07-27..nextquarter.++ date2:PERIODEXPR+ Match secondary dates within the specified period (independent of the+ --date2 flag).++ depth:N+ Match (or display, depending on command) accounts at or above this+ depth.++ note:REGEX+ Match transaction notes (the part of the description right of |, or the+ whole description if there's no |).++ payee:REGEX+ Match transaction payee/payer names (the part of the description left+ of |, or the whole description if there's no |).++ real:, real:0+ Match real or virtual postings respectively.++ status:, status:!, status:*+ Match unmarked, pending, or cleared transactions respectively.++ tag:REGEX[=REGEX]+ Match by tag name, and optionally also by tag value. (To match only by+ value, use tag:.=REGEX.) Note that postings also inherit tags from+ their transaction, and transactions also acquire tags from their post-+ ings, when querying.++ (inacct:ACCTNAME+ A special query term used automatically in hledger-web only: tells+ hledger-web to show the transaction register for an account.)++ Combining query terms+ Most commands select things which match:++ o any of the description terms AND++ o any of the account terms AND++ o any of the status terms AND++ o all the other terms.++ while the print command shows transactions which:++ o match any of the description terms AND++ o have any postings matching any of the positive account terms AND++ o have no postings matching any of the negative account terms AND++ o match all the other terms.++ You can do more powerful queries (such as AND-ing two like terms) by+ running a first query with print, and piping the result into a second+ hledger command. Eg: how much of food expenses was paid with cash ?++ $ hledger print assets:cash | hledger f- -I balance expenses:food++ If you are interested in full boolean expressions for queries, see+ #203.++ Queries and command options+ Some queries can also be expressed as command-line options: depth:2 is+ equivalent to --depth 2, date:2020 is equivalent to -p 2020, etc. When+ you mix command options and query arguments, generally the resulting+ query is their intersection.++ Queries and account aliases+ When account names are rewritten with --alias or alias, acct: will+ match either the old or the new account name.++ Queries and valuation+ When amounts are converted to other commodities in cost or value+ reports, 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+ reversed, see #1625).++ Querying with account aliases+ When account names are rewritten with --alias or alias, note that acct:+ will match either the old or the new account name.++ Querying with cost or value+ When amounts are converted to other commodities in cost or value+ reports, 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+ discussion at #1625.++COSTING+ The -B/--cost flag converts amounts to their cost or sale amount at+ transaction time, if they have a transaction price specified. If this+ flag is supplied, hledger will perform cost conversion first, and will+ apply any market price valuations (if requested) afterwards.++VALUATION+ Instead of reporting amounts in their original commodity, hledger can+ convert them to cost/sale amount (using the conversion rate recorded in+ the transaction), and/or to market value (using some market price on a+ certain date). This is controlled by the --value=TYPE[,COMMODITY]+ option, 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+ valuation commodity, using the market prices in effect on the valuation+ date(s), if any. More on these in a minute.++ -X: Value in specified commodity+ The -X/--exchange=COMM option is like -V, except you tell it which cur-+ rency you want to convert to, and it tries to convert everything to+ that.++ Valuation date+ Since market prices can change from day to day, market value reports+ have a valuation date (or more than one), which determines which market+ prices will be used.++ For single period reports, if an explicit report end date is specified,+ that will be used as the valuation date; otherwise the valuation date+ is the journal's end date.++ For multiperiod reports, each column/period is valued on the last day+ of the period, by default.++ Market prices+ To convert a commodity A to its market value in another commodity B,+ hledger looks for a suitable market price (exchange rate) as follows,+ in this order of preference :++ 1. A declared market price or inferred market price: A's latest market+ price in B on or before the valuation date as declared by a P direc-+ tive, or (with the --infer-market-price flag) inferred from transac-+ tion prices.++ 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-+ bining the shortest chain of "forward" (only 1 above) market prices,+ leading from A to B.++ 4. Any chain of market prices: a chain of any market prices, including+ both forward and reverse prices (1 and 2 above), leading from A to+ B.++ There is a limit to the length of these price chains; if hledger+ reaches that length without finding a complete chain or exhausting all+ possibilities, it will give up (with a "gave up" message visible in+ --debug=2 output). That limit is currently 1000.++ Amounts for which no suitable market price can be found, are not con-+ verted.++ --infer-market-price: market prices from transactions+ Normally, market value in hledger is fully controlled by, and requires,+ P directives in your journal. Since adding and updating those can be a+ chore, and since transactions usually take place at close to market+ value, why not use the recorded transaction prices as additional market+ prices (as Ledger does) ? We could produce value reports without need-+ ing P directives at all.++ Adding the --infer-market-price flag to -V, -X or --value enables this.+ So for example, hledger bs -V --infer-market-price will get market+ prices both from P directives and from transactions. (And if both+ occur on 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.++ --infer-market-price can infer market prices from:++ o multicommodity transactions with explicit prices (@/@@)++ o multicommodity transactions with implicit prices (no @, two commodi-+ ties, unbalanced). (With these, the order of postings matters.+ hledger print -x can be useful for troubleshooting.)++ o but not, currently, from "more correct" multicommodity transactions+ (no @, multiple commodities, balanced).++ Valuation commodity+ When you specify a valuation commodity (-X COMM or --value TYPE,COMM):+ hledger will convert all amounts to COMM, wherever it can find a suit-+ able market price (including by reversing or chaining prices).++ When you leave the valuation commodity unspecified (-V or --value+ TYPE):+ For each commodity A, hledger picks a default valuation commodity as+ follows, in this order of preference:++ 1. The price commodity from the latest P-declared market price for A on+ or before valuation date.++ 2. The price commodity from the latest P-declared market price for A on+ any date. (Allows conversion to proceed when there are inferred+ prices before the valuation date.)++ 3. If there are no P directives at all (any commodity or date) and the+ --infer-market-price flag is used: the price commodity from the lat-+ est transaction-inferred price for A on or before valuation date.++ This means:++ o If you have P directives, they determine which commodities -V will+ convert, and to what.++ o If you have no P directives, and use the --infer-market-price flag,+ transaction prices determine it.++ Amounts for which no valuation commodity can be found are not con-+ verted.++ Simple valuation examples+ Here are some quick examples of -V:++ ; one euro is worth this many dollars from nov 1+ P 2016/11/01 EUR $1.10++ ; purchase some euros on nov 3+ 2016/11/3+ assets:euros EUR100+ assets:checking++ ; the euro is worth fewer dollars by dec 21+ P 2016/12/21 EUR $1.03++ How many euros do I have ?++ $ hledger -f t.j bal -N euros+ EUR100 assets:euros++ What are they worth at end of nov 3 ?++ $ hledger -f t.j bal -N euros -V -e 2016/11/4+ $110.00 assets:euros++ What are they worth after 2016/12/21 ? (no report end date specified,+ defaults to today)++ $ hledger -f t.j bal -N euros -V+ $103.00 assets:euros++ --value: Flexible valuation+ -V and -X are special cases of the more general --value option:++ --value=TYPE[,COMM] TYPE is then, end, now or YYYY-MM-DD.+ COMM is an optional commodity symbol.+ Shows amounts converted to:+ - default valuation commodity (or COMM) using market prices at posting dates+ - default valuation commodity (or COMM) using market prices at period end(s)+ - default valuation commodity (or COMM) using current market prices+ - default valuation commodity (or COMM) using market prices at some date++ The TYPE part selects cost or value and valuation date:++ --value=then+ Convert amounts to their value in the default valuation commod-+ ity, using market prices on each posting's date.++ --value=end+ Convert amounts to their value in the default valuation commod-+ ity, using market prices on the last day of the report period+ (or if unspecified, the journal's end date); or in multiperiod+ reports, market prices on the last day of each subperiod.++ --value=now+ Convert amounts to their value in the default valuation commod-+ ity using current market prices (as of when report is gener-+ ated).++ --value=YYYY-MM-DD+ Convert amounts to their value in the default valuation commod-+ ity using market prices on this date.++ To select a different valuation commodity, add the optional ,COMM part:+ a comma, then the target commodity's symbol. Eg: --value=now,EUR.+ hledger will do its best to convert amounts to this commodity, deducing+ market prices as described above.++ More valuation examples+ Here are some examples showing the effect of --value, as seen with+ print:++ P 2000-01-01 A 1 B+ P 2000-02-01 A 2 B+ P 2000-03-01 A 3 B+ P 2000-04-01 A 4 B++ 2000-01-01+ (a) 1 A @ 5 B++ 2000-02-01+ (a) 1 A @ 6 B++ 2000-03-01+ (a) 1 A @ 7 B++ Show the cost of each posting:++ $ hledger -f- print --cost+ 2000-01-01+ (a) 5 B++ 2000-02-01+ (a) 6 B++ 2000-03-01+ (a) 7 B++ Show the value as of the last day of the report period (2000-02-29):++ $ hledger -f- print --value=end date:2000/01-2000/03+ 2000-01-01+ (a) 2 B++ 2000-02-01+ (a) 2 B++ With no report period specified, that shows the value as of the last+ day of the journal (2000-03-01):++ $ hledger -f- print --value=end+ 2000-01-01+ (a) 3 B++ 2000-02-01+ (a) 3 B++ 2000-03-01+ (a) 3 B++ Show the current value (the 2000-04-01 price is still in effect today):++ $ hledger -f- print --value=now+ 2000-01-01+ (a) 4 B++ 2000-02-01+ (a) 4 B++ 2000-03-01+ (a) 4 B++ Show the value on 2000/01/15:++ $ hledger -f- print --value=2000-01-15+ 2000-01-01+ (a) 1 B++ 2000-02-01+ (a) 1 B++ 2000-03-01+ (a) 1 B++ You may need to explicitly set a commodity's display style, when+ reverse prices are used. Eg this output might be surprising:++ P 2000-01-01 A 2B++ 2000-01-01+ a 1B+ b++ $ hledger print -x -X A+ 2000-01-01+ a 0+ b 0++ Explanation: because there's no amount or commodity directive specify-+ ing a display style for A, 0.5A gets the default style, which shows no+ decimal digits. Because the displayed amount looks like zero, the com-+ modity symbol and minus sign are not displayed either. Adding a com-+ modity directive sets a more useful display style for A:++ P 2000-01-01 A 2B+ commodity 0.00A++ 2000-01-01+ a 1B+ b++ $ hledger print -X A+ 2000-01-01+ a 0.50A+ b -0.50A++ Effect of valuation on reports+ Here is a reference for how valuation is supposed to affect each part+ of hledger's reports (and a glossary). (It's wide, you'll have to+ scroll sideways.) It may be useful when troubleshooting. If you find+ problems, please report them, ideally with a reproducible example.+ Related: #329, #1083.+++ Report -B, --cost -V, -X --value=then --value=end --value=DATE,+ type --value=now+ -----------------------------------------------------------------------------------------------+ print+ posting cost value at value at posting value at value at+ amounts report end date report or DATE/today+ or today journal end+ balance unchanged unchanged unchanged unchanged unchanged+ asser-+ tions/assign-+ ments++ register+ starting bal- cost value at day valued at day value at day value at+ ance (-H) before each historical before DATE/today+ report or posting was made report or+ journal journal+ start start+ posting cost value at value at posting value at value at+ amounts report end date report or DATE/today+ or today journal end+ summary post- summarised value at sum of postings value at value at+ ing amounts cost period ends in interval, val- period ends DATE/today+ with report ued at interval+ interval start+ running sum/average sum/average sum/average of sum/average sum/average+ total/average of displayed of displayed displayed values of displayed of displayed+ values values values values++++ balance (bs,+ bse, cf, is)+ balance sums of value at value at posting value at value at+ changes costs report end date report or DATE/today of+ or today of journal end sums of post-+ sums of of sums of ings+ postings postings+ budget like balance like balance like balance like bal- like balance+ amounts changes changes changes ances changes+ (--budget)+ grand total sum of dis- sum of dis- sum of displayed sum of dis- sum of dis-+ played val- played val- valued played val- played values+ ues ues ues++ balance (bs,+ bse, cf, is)+ with report+ interval+ starting bal- sums of value at sums of values of value at sums of post-+ ances (-H) costs of report start postings before report start ings before+ postings of sums of report start at of sums of report start+ before all postings respective post- all postings+ report start before ing dates before+ report start report start+ balance sums of same as sums of values of balance value at+ changes (bal, costs of --value=end postings in change in DATE/today of+ is, bs postings in period at respec- each period, sums of post-+ --change, cf period tive posting valued at ings+ --change) dates period ends+ end balances sums of same as sums of values of period end value at+ (bal -H, is costs of --value=end postings from balances, DATE/today of+ --H, bs, cf) postings before period valued at sums of post-+ from before start to period period ends ings+ report start end at respective+ to period posting dates+ end+ budget like balance like balance like balance like bal- like balance+ amounts changes/end changes/end changes/end bal- ances changes/end+ (--budget) balances balances ances balances+ row totals, sums, aver- sums, aver- sums, averages of sums, aver- sums, aver-+ row averages ages of dis- ages of dis- displayed values ages of dis- ages of dis-+ (-T, -A) played val- played val- played val- played values+ ues ues ues+ column totals sums of dis- sums of dis- sums of displayed sums of dis- sums of dis-+ played val- played val- values played val- played values+ ues ues ues+ grand total, sum, average sum, average sum, average of sum, average sum, average+ grand average of column of column column totals of column of column+ totals totals totals totals+++ --cumulative is omitted to save space, it works like -H but with a zero+ starting balance.++ Glossary:++ cost calculated using price(s) recorded in the transaction(s).++ value market value using available market price declarations, or the+ unchanged amount if no conversion rate can be found.++ report start+ the first day of the report period specified with -b or -p or+ date:, otherwise today.++ report or journal start+ the first day of the report period specified with -b or -p or+ date:, otherwise the earliest transaction date in the journal,+ otherwise today.++ report end+ the last day of the report period specified with -e or -p or+ date:, otherwise today.++ report or journal end+ the last day of the report period specified with -e or -p or+ date:, otherwise the latest transaction date in the journal,+ otherwise today.++ report interval+ a flag (-D/-W/-M/-Q/-Y) or period expression that activates the+ report's multi-period mode (whether showing one or many subperi-+ ods).++PIVOTING+ Normally hledger sums amounts, and organizes them in a hierarchy, based+ on account name. The --pivot FIELD option causes it to sum and orga-+ nize hierarchy based on the value of some other field instead. FIELD+ can be: code, description, payee, note, or the full name (case insensi-+ tive) of any tag. As with account names, values containing colon:sepa-+ rated:parts will be displayed hierarchically in reports.++ --pivot is a general option affecting all reports; you can think of+ hledger transforming the journal before any other processing, replacing+ every posting's account name with the value of the specified field on+ that posting, inheriting it from the transaction or using a blank value+ if it's not present.++ An example:++ 2016/02/16 Member Fee Payment+ assets:bank account 2 EUR+ income:member fees -2 EUR ; member: John Doe++ Normal balance report showing account names:++ $ hledger balance+ 2 EUR assets:bank account+ -2 EUR income:member fees+ --------------------+ 0++ Pivoted balance report, using member: tag values instead:++ $ hledger balance --pivot member+ 2 EUR+ -2 EUR John Doe+ --------------------+ 0++ One way to show only amounts with a member: value (using a query,+ described below):++ $ hledger balance --pivot member tag:member=.+ -2 EUR John Doe+ --------------------+ -2 EUR++ Another way (the acct: query matches against the pivoted "account+ name"):++ $ hledger balance --pivot member acct:.+ -2 EUR John Doe+ --------------------+ -2 EUR++OUTPUT+ Output destination+ hledger commands send their output to the terminal by default. You can+ of course redirect this, eg into a file, using standard shell syntax:++ $ hledger print > foo.txt++ Some commands (print, register, stats, the balance commands) also pro-+ vide the -o/--output-file option, which does the same thing without+ needing the shell. Eg:++ $ hledger print -o foo.txt+ $ hledger print -o - # write to stdout (the default)++ hledger can optionally produce debug output (if enabled with+ --debug=N); this goes to stderr, and is not affected by -o/--output-+ file. If you need to capture it, use shell redirects, eg: hledger bal+ --debug=3 >file 2>&1.++ Output format+ Some commands (print, register, the balance commands) offer a choice of+ output format. In addition to the usual plain text format (txt), there+ are CSV (csv), HTML (html), JSON (json) and SQL (sql). This is con-+ trolled by the -O/--output-format option:++ $ hledger print -O csv++ or, by a file extension specified with -o/--output-file:++ $ hledger balancesheet -o foo.html # write HTML to foo.html++ The -O option can be used to override the file extension if needed:++ $ hledger balancesheet -o foo.txt -O html # write HTML to foo.txt++ Some notes about JSON output:++ o This feature is marked experimental, and not yet much used; you+ should expect our JSON to evolve. Real-world feedback is welcome.++ o Our JSON is rather large and verbose, as it is quite a faithful rep-+ resentation of hledger's internal data types. To understand the+ JSON, read the Haskell type definitions, which are mostly in+ https://github.com/simonmichael/hledger/blob/master/hledger-+ lib/Hledger/Data/Types.hs.++ o hledger represents quantities as Decimal values storing up to 255+ significant digits, eg for repeating decimals. Such numbers can+ arise in practice (from automatically-calculated transaction prices),+ and would break most JSON consumers. So in JSON, we show quantities+ as simple Numbers with at most 10 decimal places. We don't limit the+ number of integer digits, but that part is under your control. We+ hope this approach will not cause problems in practice; if you find+ otherwise, please let us know. (Cf #1195)++ Notes about SQL output:++ o SQL output is also marked experimental, and much like JSON could use+ real-world feedback.++ o SQL output is expected to work with sqlite, MySQL and PostgreSQL++ o SQL output is structured with the expectations that statements will+ be executed in the empty database. If you already have tables cre-+ ated via SQL output of hledger, you would probably want to either+ clear tables of existing data (via delete or truncate SQL statements)+ or drop tables completely as otherwise your postings will be duped.++COMMANDS+ hledger provides a number of commands for producing reports and manag-+ ing your data. Run hledger with no arguments to list the commands+ available, and hledger CMD to run a command. CMD can be the full com-+ mand name, or its standard abbreviation shown in the commands list, or+ any unambiguous prefix of the name. Eg: hledger bal.++ Here are the built-in commands, with the most often-used in bold:++ Data entry:++ These data entry commands are the only ones which can modify your jour-+ nal file.++ o add - add transactions using guided prompts++ o import - add any new transactions from other files (eg csv)++ Data management:++ o check - check for various kinds of issue in the data++ o close (equity) - generate balance-resetting transactions++ o diff - compare account transactions in two journal files++ o rewrite - generate extra postings, similar to print --auto++ Financial statements:++ o aregister (areg) - show transactions in a particular account++ o balancesheet (bs) - show assets, liabilities and net worth++ o balancesheetequity (bse) - show assets, liabilities and equity++ o cashflow (cf) - show changes in liquid assets++ o incomestatement (is) - show revenues and expenses++ o roi - show return on investments++ Miscellaneous reports:++ o accounts - show account names++ o activity - show postings-per-interval bar charts++ o balance (bal) - show balance changes/end balances/budgets in any+ accounts++ o codes - show transaction codes++ o commodities - show commodity/currency symbols++ o descriptions - show unique transaction descriptions++ o files - show input file paths++ o help - show hledger user manuals in several formats++ o notes - show unique note segments of transaction descriptions++ o payees - show unique payee segments of transaction descriptions++ o prices - show market price records++ o print - show transactions (journal entries)++ o print-unique - show only transactions with unique descriptions++ o register (reg) - show postings in one or more accounts & running+ total++ o register-match - show a recent posting that best matches a descrip-+ tion++ o stats - show journal statistics++ o tags - show tag names++ o test - run self tests++ Add-on commands:++ Programs or scripts named hledger-SOMETHING in your PATH are add-on+ commands; these appear in the commands list with a + mark. Two of+ these are maintained and released with hledger:++ o ui - an efficient terminal interface (TUI) for hledger++ o web - a simple web interface (WUI) for hledger++ And these add-ons are maintained separately:++ o iadd - a more interactive alternative for the add command++ o interest - generates interest transactions according to various+ schemes++ o stockquotes - downloads market prices for your commodities from+ AlphaVantage (experimental)++ Next, the detailed command docs, in alphabetical order.++ accounts+ accounts+ Show account names.++ This command lists account names, either declared with account direc-+ tives (--declared), posted to (--used), or both (the default). With+ query arguments, only matched account names and account names refer-+ enced by matched postings are shown. It shows a flat list by default.+ With --tree, it uses indentation to show the account hierarchy. In+ flat mode you can add --drop N to omit the first few account name com-+ ponents. Account names can be depth-clipped with depth:N or --depth N+ or -N.++ Examples:++ $ hledger accounts+ assets:bank:checking+ assets:bank:saving+ assets:cash+ expenses:food+ expenses:supplies+ income:gifts+ income:salary+ liabilities:debts++ activity+ activity+ Show an ascii barchart of posting counts per interval.++ The activity command displays an ascii histogram showing transaction+ counts by day, week, month or other reporting interval (by day is the+ default). With query arguments, it counts only matched transactions.++ Examples:++ $ hledger activity --quarterly+ 2008-01-01 **+ 2008-04-01 *******+ 2008-07-01+ 2008-10-01 **++ add+ add+ Prompt for transactions and add them to the journal. Any arguments+ will be used as default inputs for the first N prompts.++ Many hledger users edit their journals directly with a text editor, or+ generate them from CSV. For more interactive data entry, there is the+ add command, which prompts interactively on the console for new trans-+ actions, and appends them to the journal file (if there are multiple -f+ FILE options, the first file is used.) Existing transactions are not+ changed. This is the only hledger command that writes to the journal+ file.++ To use it, just run hledger add and follow the prompts. You can add as+ many transactions as you like; when you are finished, enter . or press+ control-d or control-c to exit.++ Features:++ o add tries to provide useful defaults, using the most similar (by+ description) recent transaction (filtered by the query, if any) as a+ template.++ o You can also set the initial defaults with command line arguments.++ o Readline-style edit keys can be used during data entry.++ o The tab key will auto-complete whenever possible - accounts, descrip-+ tions, dates (yesterday, today, tomorrow). If the input area is+ empty, it will insert the default value.++ o If the journal defines a default commodity, it will be added to any+ bare numbers entered.++ o A parenthesised transaction code may be entered following a date.++ o Comments and tags may be entered following a description or amount.++ o If you make a mistake, enter < at any prompt to go one step backward.++ o Input prompts are displayed in a different colour when the terminal+ supports it.++ Example (see the tutorial for a detailed explanation):++ $ hledger add+ Adding transactions to journal file /src/hledger/examples/sample.journal+ Any command line arguments will be used as defaults.+ Use tab key to complete, readline keys to edit, enter to accept defaults.+ An optional (CODE) may follow transaction dates.+ An optional ; COMMENT may follow descriptions or amounts.+ If you make a mistake, enter < at any prompt to go one step backward.+ To end a transaction, enter . when prompted.+ To quit, enter . at a date prompt or press control-d or control-c.+ Date [2015/05/22]:+ Description: supermarket+ Account 1: expenses:food+ Amount 1: $10+ Account 2: assets:checking+ Amount 2 [$-10.0]:+ Account 3 (or . or enter to finish this transaction): .+ 2015/05/22 supermarket+ expenses:food $10+ assets:checking $-10.0++ Save this transaction to the journal ? [y]:+ Saved.+ Starting the next transaction (. or ctrl-D/ctrl-C to quit)+ Date [2015/05/22]: <CTRL-D> $++ On Microsoft Windows, the add command makes sure that no part of the+ file path ends with a period, as that would cause problems (#1056).++ aregister+ aregister, areg++ Show the transactions and running historical balance of a single+ account, with each transaction displayed as one line.++ aregister shows the overall transactions affecting a particular account+ (and any subaccounts). Each report line represents one transaction in+ this account. Transactions before the report start date are always+ included in the running balance (--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+ 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+ expression which will select the alphabetically first matched account.+ (Eg if you have assets:aaa:checking and assets:bbb:checking accounts,+ hledger areg checking would select assets:aaa:checking.)++ Transactions involving subaccounts of this account will also be shown.+ aregister ignores depth limits, so its final total will always match a+ balance report with similar arguments.++ Any additional arguments form a query which will filter the transac-+ 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+ 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,+ see below)++ 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+ the -E/--empty flag to show them.++ This command also supports the output destination and output format+ options. The output formats supported are txt, csv, and json.++ aregister and custom posting dates+ Transactions whose date is outside the report period can still be+ shown, if they have a posting to this account dated inside the report+ period. (And in this case it's the posting date that is shown.) This+ ensures that aregister can show an accurate historical running balance,+ matching the one shown by register -H with the same arguments.++ To filter strictly by transaction date instead, add the --txn-dates+ flag. If you use this flag and some of your postings have custom+ dates, it's probably best to assume the running balance is wrong.++ balance+ balance, bal+ 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+ more, during one time period or many. Generally it shows a table, with+ rows representing accounts, and columns representing periods.++ Note there are some higher-level variants of the balance command with+ convenient defaults, which can be simpler to use: balancesheet, bal-+ ancesheetequity, cashflow and incomestatement. When you need more con-+ 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+ higher-level commands as well.++ balance can show..++ o accounts as a list (-l) or a tree (-t)++ o optionally depth-limited (-[1-9])++ o sorted by declaration order and name, or by amount++ ..and their..++ o balance changes (the default)++ o or actual and planned balance changes (--budget)++ o or value of balance changes (-V)++ o or change of balance values (--valuechange)++ ..in..++ o one time period (the whole journal period by default)++ o or multiple periods (-D, -W, -M, -Q, -Y, -p INTERVAL)++ ..either..++ o per period (the default)++ o or accumulated since report start date (--cumulative)++ o or accumulated since account creation (--historical/-H)++ ..possibly converted to..++ o cost (--value=cost[,COMM]/--cost/-B)++ o or market value, as of transaction dates (--value=then[,COMM])++ o or at period ends (--value=end[,COMM])++ o or now (--value=now)++ o or at some other date (--value=YYYY-MM-DD)++ ..with..++ o totals (-T), averages (-A), percentages (-%), inverted sign+ (--invert)++ o rows and columns swapped (--transpose)++ o another field used as account name (--pivot)++ o custom-formatted line items (single-period reports only) (--format)++ This command supports the output destination and output format options,+ with output formats txt, csv, json, and (multi-period reports only:)+ html. In txt output in a colour-supporting terminal, negative amounts+ are shown in red.++ Simple balance report+ With no arguments, balance shows a list of all accounts and their+ change of balance - ie, the sum of posting amounts, both inflows and+ outflows - during the entire period of the journal. For real-world+ accounts, this should also match their end balance at the end of the+ journal period (more on this below).++ Accounts are sorted by declaration order if any, and then alphabeti-+ cally by account name. For instance, using examples/sample.journal:++ $ hledger bal+ $1 assets:bank:saving+ $-2 assets:cash+ $1 expenses:food+ $1 expenses:supplies+ $-1 income:gifts+ $-1 income:salary+ $1 liabilities:debts+ --------------------+ 0++ 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+ (revealing assets:bank:checking here):++ $ hledger -f examples/sample.journal bal -E+ 0 assets:bank:checking+ $1 assets:bank:saving+ $-2 assets:cash+ $1 expenses:food+ $1 expenses:supplies+ $-1 income:gifts+ $-1 income:salary+ $1 liabilities:debts+ --------------------+ 0++ The total of the amounts displayed is shown as the last line, unless+ -N/--no-total is used.++ Filtered balance report+ 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:++ $ hledger bal --cleared assets date:200806+ $-2 assets:cash+ --------------------+ $-2++ List or tree mode+ By default, or with -l/--flat, accounts are shown as a flat list with+ their full names visible, as in the examples above.++ With -t/--tree, the account hierarchy is shown, with subaccounts'+ "leaf" names indented below their parent:++ $ hledger balance+ $-1 assets+ $1 bank:saving+ $-2 cash+ $2 expenses+ $1 food+ $1 supplies+ $-2 income+ $-1 gifts+ $-1 salary+ $1 liabilities:debts+ --------------------+ 0++ 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+ above).++ 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.++ o Each group of sibling accounts (ie, under a common parent) is sorted+ separately.++ Depth limiting+ With a depth:N query, or --depth N option, or just -N, balance reports+ will show accounts only to the specified depth, hiding the deeper sub-+ accounts. Account balances at the depth limit always include the bal-+ ances from any hidden subaccounts (even in list mode). This can be+ useful for getting an overview. Eg, limiting to depth 1:++ $ hledger balance -N -1+ $-1 assets+ $2 expenses+ $-2 income+ $1 liabilities++ You can also hide top-level account name parts, using --drop N. This+ can be useful for hiding repetitive top-level account names:++ $ hledger bal expenses --drop 1+ $1 food+ $1 supplies+ --------------------+ $2+++ Multi-period balance report+ With a report interval (set by the -D/--daily, -W/--weekly,+ -M/--monthly, -Q/--quarterly, -Y/--yearly, or -p/--period flag), bal-+ ance shows a tabular report, with columns representing successive time+ periods (and a title):++ $ hledger balance --quarterly income expenses -E+ Balance changes in 2008:++ || 2008q1 2008q2 2008q3 2008q4+ ===================++=================================+ expenses:food || 0 $1 0 0+ expenses:supplies || 0 $1 0 0+ income:gifts || 0 $-1 0 0+ income:salary || $-1 0 0 0+ -------------------++---------------------------------+ || $-1 $1 0 0++ Notes:++ o The report's start/end dates will be expanded, if necessary, to fully+ encompass the displayed subperiods (so that the first and last subpe-+ riods have the same duration as the others).++ o Leading and trailing periods (columns) containing all zeroes are not+ shown, unless -E/--empty is used.++ o Accounts (rows) containing all zeroes are not shown, unless+ -E/--empty is used.++ o Amounts with many commodities are shown in abbreviated form, unless+ --no-elide is used. (experimental)++ o Average and/or total columns can be added with the -A/--average and+ -T/--row-total flags.++ o The --transpose flag can be used to exchange rows and columns.++ o The --pivot FIELD option causes a different transaction field to be+ used as "account name". See PIVOTING.++ Multi-period reports with many periods can be too wide for easy viewing+ in the terminal. Here are some ways to handle that:++ o Hide the totals row with -N/--no-total++ o Convert to a single currency with -V++ o Maximize the terminal window++ o Reduce the terminal's font size++ 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+ 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 &&+ open a.html++ 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.++ Revenues and liability balances are typically negative, however, so -S+ shows these in reverse order. To work around this, you can add+ --invert to flip the signs. (Or, use one of the higher-level reports,+ which flip the sign automatically. Eg: hledger incomestatement -MAS).+++ Percentages+ With -%/--percent, balance reports show each account's value expressed+ as a percentage of the (column) total:++ $ hledger bal expenses -Q -%+ Balance changes in 2008:++ || 2008Q1 2008Q2 2008Q3 2008Q4+ ===================++=================================+ expenses:food || 0 50.0 % 0 0+ expenses:supplies || 0 50.0 % 0 0+ -------------------++---------------------------------+ || 0 100.0 % 0 0++ Note it is not useful to calculate percentages if the amounts in a col-+ umn have mixed signs. In this case, make a separate report for each+ sign, eg:++ $ hledger bal -% amt:`>0`+ $ hledger bal -% amt:`<0`++ Similarly, if the amounts in a column have mixed commodities, convert+ them to one commodity with -B, -V, -X or --value, or make a separate+ report for each commodity:++ $ hledger bal -% cur:\\$+ $ hledger bal -% cur:EUR++ Balance change, end balance+ 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+ account 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+ your timezone). It is the sum of previous 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!)++ In general, balance changes are what you want to see when reviewing+ revenues and expenses, and historical end balances are what you want to+ see when reviewing or reconciling asset, liability and equity accounts.++ 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+ journal covers the account's full lifetime.++ 2. Include all of of the account's prior postings in the report, by not+ specifying a report start date, or by using the -H/--historical+ flag. (-H causes report start date to be ignored when summing post-+ ings.)++ Balance report types+ For more flexible reporting, there are three important option groups:++ hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]+ ...++ The first two are the most important: calculation type selects the+ basic calculation to perform for each table cell, while accumulation+ type says which postings should be included in each cell's calculation.+ Typically one or both of these are selected by default, so you don't+ need to write them explicitly. A valuation type can be added if you+ want to convert the basic report to value or cost.++ Calculation type:+ The basic calculation to perform for each table cell. It is one of:++ o --sum : sum the posting amounts (default)++ o --budget : like --sum but also show a goal amount++ o --valuechange : show the change in period-end historical balance val-+ ues++ Accumulation type:+ Which postings should be included in each cell's calculation. It is+ one of:++ o --change : postings from column start to column end, ie within the+ cell's period. Typically used to see revenues/expenses. (default+ for balance, incomestatement)++ o --cumulative : postings from report start to column end, eg to show+ changes accumulated since the report's start date. Rarely used.++ o --historical/-H : postings from journal start to column end, ie all+ postings from account creation to the end of the cell's period. Typ-+ ically used to see historical end balances of assets/liabili-+ ties/equity. (default for balancesheet, balancesheetequity, cash-+ flow)++ Valuation type:+ Which kind of valuation, valuation date(s) and optionally a target val-+ uation commodity to use. It is one of:++ o no valuation, show amounts in their original commodities (default)++ o --value=cost[,COMM] : no valuation, show amounts converted to cost++ o --value=then[,COMM] : show value at transaction dates++ o --value=end[,COMM] : show value at period end date(s) (default with+ --valuechange)++ o --value=now[,COMM] : show value at today's date++ o --value=YYYY-MM-DD[,COMM] : show value at another date++ or one of their aliases: --cost/-B, --market/-V or --exchange/-X.++ 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-+ ancesheet/balancesheetequity commands++ o --cumulative or --historical disables --row-total/-T++ For reference, here is what the combinations of accumulation and valua-+ tion show:+++ Valua- no valuation --value= then --value= end --value= YYYY-+ tion: MM-DD /now+ >Accumu-+ lation:+ v+ ------------------------------------------------------------------------------------++++ --change change in period sum of posting- period-end DATE-value of+ date market val- value of change change in+ ues in period in period period+ --cumu- change from sum of posting- period-end DATE-value of+ lative report 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 end bal- start to period start to period to period end+ ance) end end++ Useful balance reports+ Some frequently used balance options/reports are:++ o bal -M revenues expenses+ 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+ available as the balancesheet command.++ o bal -M -H assets liabilities equity+ 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+ cashflow command.++ Also:++ o bal -M expenses -2 -SA+ Show monthly expenses summarised to depth 2 and sorted by average+ amount.++ o bal -M --budget expenses+ Show monthly expenses and budget goals.++ o bal -M --valuechange investments+ Show monthly change in market value of investment assets.++ o bal investments --valuechange -D date:lastweek amt:'>1000' -STA+ [--invert]+ Show top gainers [or losers] last week++ Budget report+ The --budget report type activates extra columns showing any budget+ goals for each account and period. The budget goals are defined by+ periodic transactions. This is very useful for comparing planned and+ actual income, expenses, time usage, etc.++ For example, you can take average monthly expenses in the common+ expense categories to construct a minimal monthly budget:++ ;; Budget+ ~ monthly+ income $2000+ expenses:food $400+ expenses:bus $50+ expenses:movies $30+ assets:bank:checking++ ;; Two months worth of expenses+ 2017-11-01+ income $1950+ expenses:food $396+ expenses:bus $49+ expenses:movies $30+ expenses:supplies $20+ assets:bank:checking++ 2017-12-01+ income $2100+ expenses:food $412+ expenses:bus $53+ expenses:gifts $100+ assets:bank:checking++ You can now see a monthly budget report:++ $ hledger balance -M --budget+ Budget performance in 2017/11/01-2017/12/31:++ || Nov Dec+ ======================++====================================================+ assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ expenses || $495 [ 103% of $480] $565 [ 118% of $480]+ expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]+ expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]+ expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]+ income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]+ ----------------------++----------------------------------------------------+ || 0 [ 0] 0 [ 0]++ This is different from a normal balance report in several ways:++ o Only accounts with budget goals during the report period are shown,+ by default.++ o In each column, in square brackets after the actual amount, budget+ goal amounts are shown, and the actual/goal percentage. (Note: bud-+ get goals should be in the same commodity as the actual amount.)++ o All parent accounts are always shown, even in list mode. Eg assets,+ assets:bank, and expenses above.++ o Amounts always include all subaccounts, budgeted or unbudgeted, even+ in list mode.++ This means that the numbers displayed will not always add up! Eg above,+ the expenses actual amount includes the gifts and supplies transac-+ tions, but the expenses:gifts and expenses:supplies accounts are not+ shown, as they have no budget amounts declared.++ This can be confusing. When you need to make things clearer, use the+ -E/--empty flag, which will reveal all accounts including unbudgeted+ ones, giving the full picture. Eg:++ $ hledger balance -M --budget --empty+ Budget performance in 2017/11/01-2017/12/31:++ || Nov Dec+ ======================++====================================================+ assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ expenses || $495 [ 103% of $480] $565 [ 118% of $480]+ expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]+ expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]+ expenses:gifts || 0 $100+ expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]+ expenses:supplies || $20 0+ income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]+ ----------------------++----------------------------------------------------+ || 0 [ 0] 0 [ 0]++ You can roll over unspent budgets to next period with --cumulative:++ $ hledger balance -M --budget --cumulative+ Budget performance in 2017/11/01-2017/12/31:++ || Nov Dec+ ======================++====================================================+ assets || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]+ assets:bank || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]+ assets:bank:checking || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]+ expenses || $495 [ 103% of $480] $1060 [ 110% of $960]+ expenses:bus || $49 [ 98% of $50] $102 [ 102% of $100]+ expenses:food || $396 [ 99% of $400] $808 [ 101% of $800]+ expenses:movies || $30 [ 100% of $30] $30 [ 50% of $60]+ income || $1950 [ 98% of $2000] $4050 [ 101% of $4000]+ ----------------------++----------------------------------------------------+ || 0 [ 0] 0 [ 0]++ For more examples and notes, see Budgeting.++ Budget report start date+ This might be a bug, but for now: when making budget reports, it's a+ good idea to explicitly set the report's start date to the first day of+ a reporting period, because a periodic rule like ~ monthly generates+ its transactions on the 1st of each month, and if your journal has no+ regular transactions on the 1st, the default report start date could+ exclude that budget goal, which can be a little surprising. Eg here+ the default report period is just the day of 2020-01-15:++ ~ monthly in 2020+ (expenses:food) $500++ 2020-01-15+ expenses:food $400+ assets:checking++ $ hledger bal expenses --budget+ Budget performance in 2020-01-15:++ || 2020-01-15+ ==============++============+ <unbudgeted> || $400+ --------------++------------+ || $400++ To avoid this, specify the budget report's period, or at least the+ start date, with -b/-e/-p/date:, to ensure it includes the budget goal+ transactions (periodic transactions) that you want. Eg, adding -b+ 2020/1/1 to the above:++ $ hledger bal expenses --budget -b 2020/1/1+ Budget performance in 2020-01-01..2020-01-15:++ || 2020-01-01..2020-01-15+ ===============++========================+ expenses:food || $400 [80% of $500]+ ---------------++------------------------+ || $400 [80% of $500]++ Nested budgets+ You can add budgets to any account in your account hierarchy. If you+ have budgets on both parent account and some of its children, then bud-+ get(s) of the child account(s) would be added to the budget of their+ parent, much like account balances behave.++ In the most simple case this means that once you add a budget to any+ account, all its parents would have budget as well.++ To illustrate this, consider the following budget:++ ~ monthly from 2019/01+ expenses:personal $1,000.00+ expenses:personal:electronics $100.00+ liabilities++ With this, monthly budget for electronics is defined to be $100 and+ budget for personal expenses is an additional $1000, which implicitly+ means that budget for both expenses:personal and expenses is $1100.++ Transactions in expenses:personal:electronics will be counted both+ towards its $100 budget and $1100 of expenses:personal , and transac-+ tions in any other subaccount of expenses:personal would be counted+ towards only towards the budget of expenses:personal.++ For example, let's consider these transactions:++ ~ monthly from 2019/01+ expenses:personal $1,000.00+ expenses:personal:electronics $100.00+ liabilities++ 2019/01/01 Google home hub+ expenses:personal:electronics $90.00+ liabilities $-90.00++ 2019/01/02 Phone screen protector+ expenses:personal:electronics:upgrades $10.00+ liabilities++ 2019/01/02 Weekly train ticket+ expenses:personal:train tickets $153.00+ liabilities++ 2019/01/03 Flowers+ expenses:personal $30.00+ liabilities++ As you can see, we have transactions in expenses:personal:electron-+ ics:upgrades and expenses:personal:train tickets, and since both of+ these accounts are without explicitly defined budget, these transac-+ tions would be counted towards budgets of expenses:personal:electronics+ and expenses:personal accordingly:++ $ hledger balance --budget -M+ Budget performance in 2019/01:++ || Jan+ ===============================++===============================+ expenses || $283.00 [ 26% of $1100.00]+ expenses:personal || $283.00 [ 26% of $1100.00]+ expenses:personal:electronics || $100.00 [ 100% of $100.00]+ liabilities || $-283.00 [ 26% of $-1100.00]+ -------------------------------++-------------------------------+ || 0 [ 0]++ And with --empty, we can get a better picture of budget allocation and+ consumption:++ $ hledger balance --budget -M --empty+ Budget performance in 2019/01:++ || Jan+ ========================================++===============================+ expenses || $283.00 [ 26% of $1100.00]+ expenses:personal || $283.00 [ 26% of $1100.00]+ expenses:personal:electronics || $100.00 [ 100% of $100.00]+ expenses:personal:electronics:upgrades || $10.00+ expenses:personal:train tickets || $153.00+ liabilities || $-283.00 [ 26% of $-1100.00]+ ----------------------------------------++-------------------------------+ || 0 [ 0]++ Customising single-period balance reports+ For single-period balance reports displayed in the terminal (only), you+ can use --format FMT to customise the format and content of each line.+ Eg:++ $ hledger balance --format "%20(account) %12(total)"+ assets $-1+ bank:saving $1+ cash $-2+ expenses $2+ food $1+ supplies $1+ income $-2+ gifts $-1+ salary $-1+ liabilities:debts $1+ ---------------------------------+ 0++ The FMT format string (plus a newline) specifies the formatting applied+ to each account/balance pair. It may contain any suitable text, with+ data fields interpolated like so:++ %[MIN][.MAX](FIELDNAME)++ o MIN pads with spaces to at least this width (optional)++ o MAX truncates at this width (optional)++ o FIELDNAME must be enclosed in parentheses, and can be one of:++ o depth_spacer - a number of spaces equal to the account's depth, or+ if MIN is specified, MIN * depth spaces.++ o account - the account's name++ o total - the account's balance/posted total, right justified++ Also, FMT can begin with an optional prefix to control how multi-com-+ modity amounts are rendered:++ o %_ - render on multiple lines, bottom-aligned (the default)++ o %^ - render on multiple lines, top-aligned++ o %, - render on one line, comma-separated++ There are some quirks. Eg in one-line mode, %(depth_spacer) has no+ effect, instead %(account) has indentation built in. Experimentation+ may be needed to get pleasing results.++ Some example formats:++ o %(total) - the account's total++ o %-20.20(account) - the account's name, left justified, padded to 20+ characters and clipped at 20 characters++ o %,%-50(account) %25(total) - account name padded to 50 characters,+ total padded to 20 characters, with multiple commodities rendered on+ one line++ o %20(total) %2(depth_spacer)%-(account) - the default format for the+ single-column balance report++ balancesheet+ balancesheet, bs+ This command displays a balance sheet, showing historical ending bal-+ ances of asset and liability accounts. (To see equity as well, use the+ balancesheetequity command.) Amounts are shown with normal positive+ sign, as in conventional financial statements.++ The asset and liability accounts shown are those accounts declared with+ the Asset or Cash or Liability type, or otherwise all accounts under a+ top-level asset or liability account (case insensitive, plurals+ allowed).++ Example:++ $ hledger balancesheet+ Balance Sheet++ Assets:+ $-1 assets+ $1 bank:saving+ $-2 cash+ --------------------+ $-1++ Liabilities:+ $1 liabilities:debts+ --------------------+ $1++ Total:+ --------------------+ 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+ flipped.++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, html, and (experi-+ mental) json.++ balancesheetequity+ balancesheetequity, bse+ This command displays a balance sheet, showing historical ending bal-+ ances of asset, liability and equity accounts. Amounts are shown with+ normal positive sign, as in conventional financial statements.++ The asset, liability and equity accounts shown are those accounts+ declared with the Asset, Cash, Liability or Equity type, or otherwise+ all accounts under a top-level asset, liability or equity account (case+ insensitive, plurals allowed).++ Example:++ $ hledger balancesheetequity+ Balance Sheet With Equity++ Assets:+ $-2 assets+ $1 bank:saving+ $-3 cash+ --------------------+ $-2++ Liabilities:+ $1 liabilities:debts+ --------------------+ $1++ Equity:+ $1 equity:owner+ --------------------+ $1++ Total:+ --------------------+ 0++ This command 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 equity, but with+ smarter account detection, and liabilities/equity displayed with their+ sign flipped.++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, html, and (experi-+ mental) json.++ cashflow+ cashflow, cf+ This command displays a cashflow statement, showing the inflows and+ outflows affecting "cash" (ie, liquid) assets. Amounts are shown with+ normal positive sign, as in conventional financial statements.++ The "cash" accounts shown are those accounts declared with the Cash+ type, or otherwise all accounts under a top-level asset account (case+ insensitive, plural allowed) which do not have fixed, investment,+ receivable or A/R in their name.++ Example:++ $ hledger cashflow+ Cashflow Statement++ Cash flows:+ $-1 assets+ $1 bank:saving+ $-2 cash+ --------------------+ $-1++ Total:+ --------------------+ $-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+ not:receivable, but with smarter account detection.++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, html, and (experi-+ mental) json.++ check+ check+ Check for various kinds of errors in your data.++ hledger provides a number of built-in error checks to help prevent+ problems in your data. Some of these are run automatically; or, you+ can use this check command to run them on demand, with no output and a+ zero exit code if all is well. Specify their names (or a prefix) as+ argument(s).++ Some examples:++ hledger check # basic checks+ hledger check -s # basic + strict checks+ hledger check ordereddates payees # basic + two other checks++ Here are the checks currently available:++ Basic checks+ These checks are always run automatically, by (almost) all hledger com-+ mands, including check:++ 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 transaction prices or automatically-inferred transaction prices++ o assertions - all balance assertions in the journal are passing.+ (This check can be disabled with -I/--ignore-assertions.)++ Strict checks+ These additional checks are run when the -s/--strict (strict mode) flag+ is used. Or, they can be run by giving their names as arguments to+ check:++ o accounts - all account names used by transactions have been declared++ o commodities - all commodity symbols used have been declared++ o balancednoautoconversion - transactions are balanced, possibly using+ explicit transaction prices but not inferred ones++ 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,+ therefore optional:++ o ordereddates - transactions are ordered by date within each file++ o payees - all payees 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+ https://github.com/simonmichael/hledger/tree/master/bin:++ o hledger-check-tagfiles - all tag values containing / (a forward+ slash) exist as file paths++ o hledger-check-fancyassertions - more complex balance assertions are+ passing++ You could make similar scripts to perform your own custom checks. See:+ Cookbook -> Scripting.++ close+ close, equity+ Prints a "closing balances" transaction and an "opening balances"+ transaction that bring account balances to and from zero, respectively.+ These can be added to your journal file(s), eg to bring asset/liability+ balances forward into a new journal file, or to close out rev-+ enues/expenses to retained earnings at the end of a period.++ You can print just one of these transactions by using the --close or+ --open flag. You can customise their descriptions with the --close-+ desc and --open-desc options.++ One amountless posting to "equity:opening/closing balances" is added to+ balance the transactions, by default. You can customise this account+ name with --close-acct and --open-acct; if you specify only one of+ these, it will be used for both.++ With --x/--explicit, the equity posting's amount will be shown. And if+ it involves multiple commodities, a posting for each commodity will be+ shown, as with the print command.++ With --interleaved, the equity postings are shown next to the postings+ they balance, which makes troubleshooting easier.++ By default, transaction prices in the journal are ignored when generat-+ ing the closing/opening transactions. With --show-costs, this cost+ information is preserved (balance -B reports will be unchanged after+ the transition). Separate postings are generated for each cost in each+ commodity. Note this can generate very large journal entries, if you+ have many foreign currency or investment transactions.++ close usage+ If you split your journal files by time (eg yearly), you will typically+ run this command at the end of the year, and save the closing transac-+ tion as last entry of the old file, and the opening transaction as the+ first entry of the new file. This makes the files self contained, so+ that correct balances are reported no matter which of them are loaded.+ Ie, if you load just one file, the balances are initialised correctly;+ or if you load several files, the redundant closing/opening transac-+ tions cancel each other out. (They will show up in print or register+ reports; you can exclude them with a query like not:desc:'(open-+ ing|closing) balances'.)++ If you're running a business, you might also use this command to "close+ the books" at the end of an accounting period, transferring income+ statement account balances to retained earnings. (You may want to+ change the equity account name to something like "equity:retained earn-+ ings".)++ By default, the closing transaction is dated yesterday, the balances+ are calculated as of end of yesterday, and the opening transaction is+ dated today. To close on some other date, use: hledger close -e OPEN-+ INGDATE. Eg, to close/open on the 2018/2019 boundary, use -e 2019.+ You can also use -p or date:PERIOD (any starting date is ignored).++ Both transactions will include balance assertions for the+ closed/reopened accounts. You probably shouldn't use status or real-+ ness filters (like -C or -R or status:) with this command, or the gen-+ erated balance assertions will depend on these flags. Likewise, if you+ run this command with --auto, the balance assertions will probably+ always require --auto.++ Examples:++ Carrying asset/liability balances into a new file for 2019:++ $ hledger close -f 2018.journal -e 2019 assets liabilities --open+ # (copy/paste the output to the start of your 2019 journal file)+ $ hledger close -f 2018.journal -e 2019 assets liabilities --close+ # (copy/paste the output to the end of your 2018 journal file)++ Now:++ $ hledger bs -f 2019.journal # one file - balances are correct+ $ hledger bs -f 2018.journal -f 2019.journal # two files - balances still correct+ $ hledger bs -f 2018.journal not:desc:closing # to see year-end balances, must exclude closing txn++ Transactions spanning the closing date can complicate matters, breaking+ balance assertions:++ 2018/12/30 a purchase made in 2018, clearing the following year+ expenses:food 5+ assets:bank:checking -5 ; [2019/1/2]++ Here's one way to resolve that:++ ; in 2018.journal:+ 2018/12/30 a purchase made in 2018, clearing the following year+ expenses:food 5+ liabilities:pending++ ; in 2019.journal:+ 2019/1/2 clearance of last year's pending transactions+ liabilities:pending 5 = 0+ assets:checking++ codes+ codes+ List the codes seen in transactions, in the order parsed.++ This command prints the value of each transaction's code field, in the+ order transactions were parsed. The transaction code is an optional+ value written in parentheses between the date and description, often+ used to store a cheque number, order number or similar.++ Transactions aren't required to have a code, and missing or empty codes+ will not be shown by default. With the -E/--empty flag, they will be+ printed as blank lines.++ You can add a query to select a subset of transactions.++ Examples:++ 1/1 (123)+ (a) 1++ 1/1 ()+ (a) 1++ 1/1+ (a) 1++ 1/1 (126)+ (a) 1++ $ hledger codes+ 123+ 124+ 126++ $ hledger codes -E+ 123+ 124+++ 126++ commodities+ commodities+ List all commodity/currency symbols used or declared in the journal.++ descriptions+ descriptions+ List the unique descriptions that appear in transactions.++ This command lists the unique descriptions that appear in transactions,+ in alphabetic order. You can add a query to select a subset of trans-+ actions.++ Example:++ $ hledger descriptions+ Store Name+ Gas Station | Petrol+ Person A++ diff+ diff+ Compares a particular account's transactions in two input files. It+ shows any transactions to this account which are in one file but not in+ the other.++ More precisely, for each posting affecting this account in either file,+ it looks for a corresponding posting in the other file which posts the+ same amount to the same account (ignoring date, description, etc.)+ Since postings not transactions are compared, this also works when mul-+ tiple bank transactions have been combined into a single journal entry.++ This is useful eg if you have downloaded an account's transactions from+ your bank (eg as CSV data). When hledger and your bank disagree about+ the account balance, you can compare the bank data with your journal to+ find out the cause.++ Examples:++ $ hledger diff -f $LEDGER_FILE -f bank.csv assets:bank:giro+ These transactions are in the first file only:++ 2014/01/01 Opening Balances+ assets:bank:giro EUR ...+ ...+ equity:opening balances EUR -...++ These transactions are in the second file only:++ files+ files+ List all files included in the journal. With a REGEX argument, only+ file names matching the regular expression (case sensitive) are shown.++ help+ help+ Show the hledger user manual in one of several formats, optionally+ positioned at a given TOPIC (if possible). TOPIC is any heading, or+ heading prefix, in the manual. Some examples: commands, print, 'auto+ postings', periodic.++ This command shows the user manual built in to this hledger version.+ It can be useful if the correct version of the hledger manual, or the+ usual viewing tools, are not installed on your system.++ By default it uses the best viewer it can find in $PATH, in this order:+ info, man, $PAGER (unless a topic is specified), less, or stdout. When+ run non-interactively, it always uses stdout. Or you can select a par-+ ticular viewer with the -i (info), -m (man), or -p (pager) flags.++ import+ import+ Read new transactions added to each FILE since last run, and add them+ to the main journal file. Or with --dry-run, just print the transac-+ tions that would be added. Or with --catchup, just mark all of the+ FILEs' transactions as imported, without actually importing any.++ 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+ hledger import bank.csv or perhaps hledger import *.csv.++ Note you can import from any file format, though CSV files are the most+ common import source, and these docs focus on that case.++ Deduplication+ 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+ already-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-+ potent.)++ Since the items being read (CSV records, eg) often do not come with+ unique identifiers, hledger detects new transactions by date, assuming+ that:++ 1. new items always have the newest dates++ 2. item dates do not change across reads++ 3. and items with the same date remain in the same relative order+ across reads.++ 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+ be the ones affected).++ 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+ 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-+ tain date.++ Note deduplication (and updating of state files) can also be done by+ print --new, but this is less often used.++ Import testing+ 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+ categorised:++ $ hledger import --dry bank.csv | hledger -f- -I print unknown++ or (live updating):++ $ ls bank.csv* | entr bash -c 'echo ====; hledger import --dry bank.csv | hledger -f- -I print unknown'++ Importing balance assignments+ Entries added by import will have their posting amounts made explicit+ (like hledger print -x). This means that any balance assignments in+ imported files must be evaluated; but, imported files don't get to see+ the main file's account balances. As a result, importing entries with+ balance assignments (eg from an institution that provides only balances+ and not posting amounts) will probably generate incorrect posting+ amounts. To avoid this problem, use print instead of import:++ $ hledger print IMPORTFILE [--new] >> $LEDGER_FILE++ (If you think import should leave amounts implicit like print does,+ please test it and send a pull request.)++ Commodity display styles+ Imported amounts will be formatted according to the canonical commodity+ styles (declared or inferred) in the main journal file.++ incomestatement+ incomestatement, is++ This command displays an income statement, showing revenues and+ expenses during one or more periods. Amounts are shown with normal+ positive sign, as in conventional financial statements.++ The revenue and expense accounts shown are those accounts declared with+ the Revenue or Expense type, or otherwise all accounts under a top-+ level revenue or income or expense account (case insensitive, plurals+ allowed).++ Example:++ $ hledger incomestatement+ Income Statement++ Revenues:+ $-2 income+ $-1 gifts+ $-1 salary+ --------------------+ $-2++ Expenses:+ $2 expenses+ $1 food+ $1 supplies+ --------------------+ $2++ Total:+ --------------------+ 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 '(revenues|income)' expenses, but with+ smarter account detection, and revenues/income displayed with their+ sign flipped.++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, html, and (experi-+ mental) json.++ notes+ notes+ List the unique notes that appear in transactions.++ This command lists the unique notes that appear in transactions, in+ alphabetic order. You can add a query to select a subset of transac-+ tions. The note is the part of the transaction description after a |+ character (or if there is no |, the whole description).++ Example:++ $ hledger notes+ Petrol+ Snacks++ payees+ payees+ List the unique payee/payer names that appear in transactions.++ This command lists 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 |+ character (or if there is no |, the whole description).++ You can add query arguments to select a subset of transactions. This+ implies --used.++ Example:++ $ hledger payees+ Store Name+ Gas Station+ Person A++ prices+ prices+ Print market price directives from the journal. With --costs, also+ print synthetic market prices based on transaction prices. With+ --inverted-costs, also print inverse prices based on transaction+ prices. Prices (and postings providing prices) can be filtered by a+ query. Price amounts are always displayed with their full precision.++ print+ print+ Show transaction journal entries, sorted by date.++ The print command displays full journal entries (transactions) from the+ journal file, sorted by date (or with --date2, by secondary date).++ Amounts are shown 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.+ This means the print command is somewhat lossy, and if you are using it+ to reformat your journal you should take care to also copy over the+ directives and file-level comments.++ Eg:++ $ hledger print+ 2008/01/01 income+ assets:bank:checking $1+ income:salary $-1++ 2008/06/01 gift+ assets:bank:checking $1+ income:gifts $-1++ 2008/06/02 save+ assets:bank:saving $1+ assets:bank:checking $-1++ 2008/06/03 * eat & shop+ expenses:food $1+ expenses:supplies $1+ assets:cash $-2++ 2008/12/31 * pay off+ liabilities:debts $1+ assets:bank:checking $-1++ print's output is usually a valid hledger journal, and you can process+ it again with a second hledger command. This can be useful for certain+ kinds of search, eg:++ # Show running total of food expenses paid from cash.+ # -f- reads from stdin. -I/--ignore-assertions is sometimes needed.+ $ hledger print assets:cash | hledger -f- -I reg expenses:food++ There are some situations where print's output can become unparseable:++ o Valuation affects posting amounts but not balance assertion or bal-+ ance assignment amounts, potentially causing those to fail.++ o Auto postings can generate postings with too many missing amounts.++ Normally, the journal entry's explicit or implicit amount style is pre-+ served. For example, when an amount is omitted in the journal, it will+ not appear in the output. Similarly, when a transaction price is+ implied but not written, it will not appear in the output. You can use+ the -x/--explicit flag to make all amounts and transaction prices+ explicit, which can be useful for troubleshooting or for making your+ journal more readable and robust against data entry errors. -x is also+ implied by using any of -B,-V,-X,--value.++ Note, -x/--explicit will cause postings with a multi-commodity amount+ (these can arise when a multi-commodity transaction has an implicit+ amount) to be split into multiple single-commodity postings, keeping+ the output parseable.++ With -B/--cost, amounts with transaction prices are converted to cost+ using that price. This can be used for troubleshooting.++ With -m/--match and a STR argument, print will show at most one trans-+ action: the one one whose description is most similar to STR, and is+ most recent. STR should contain at least two characters. If there is+ no similar-enough match, no transaction will be shown.++ With --new, hledger prints only transactions it has not seen on a pre-+ vious run. This uses the same deduplication system as the import com-+ mand. (See import's docs for details.)++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, and (experimental)+ json and sql.++ Here's an example of print's CSV output:++ $ hledger print -Ocsv+ "txnidx","date","date2","status","code","description","comment","account","amount","commodity","credit","debit","posting-status","posting-comment"+ "1","2008/01/01","","","","income","","assets:bank:checking","1","$","","1","",""+ "1","2008/01/01","","","","income","","income:salary","-1","$","1","","",""+ "2","2008/06/01","","","","gift","","assets:bank:checking","1","$","","1","",""+ "2","2008/06/01","","","","gift","","income:gifts","-1","$","1","","",""+ "3","2008/06/02","","","","save","","assets:bank:saving","1","$","","1","",""+ "3","2008/06/02","","","","save","","assets:bank:checking","-1","$","1","","",""+ "4","2008/06/03","","*","","eat & shop","","expenses:food","1","$","","1","",""+ "4","2008/06/03","","*","","eat & shop","","expenses:supplies","1","$","","1","",""+ "4","2008/06/03","","*","","eat & shop","","assets:cash","-2","$","2","","",""+ "5","2008/12/31","","*","","pay off","","liabilities:debts","1","$","","1","",""+ "5","2008/12/31","","*","","pay off","","assets:bank:checking","-1","$","1","","",""++ o There is one CSV record per posting, with the parent transaction's+ fields repeated.++ o The "txnidx" (transaction index) field shows which postings belong to+ the same transaction. (This number might change if transactions are+ reordered within the file, files are parsed/included in a different+ order, etc.)++ o The amount is separated into "commodity" (the symbol) and "amount"+ (numeric quantity) fields.++ o The numeric amount is repeated in either the "credit" or "debit" col-+ umn, for convenience. (Those names are not accurate in the account-+ ing sense; it just puts negative amounts under credit and zero or+ greater amounts under debit.)++ print-unique+ print-unique+ Print transactions which do not reuse an already-seen description.++ Example:++ $ cat unique.journal+ 1/1 test+ (acct:one) 1+ 2/2 test+ (acct:two) 2+ $ LEDGER_FILE=unique.journal hledger print-unique+ (-f option not supported)+ 2015/01/01 test+ (acct:one) 1++ register+ register, reg+ Show postings and their running total.++ The register command displays matched postings, across all accounts, in+ date order, with their running total or running historical balance.+ (See also the aregister command, which shows matched transactions in a+ specific account.)++ register normally shows line per posting, but note that multi-commodity+ amounts will occupy multiple lines (one line per commodity).++ It is typically used with a query selecting a particular account, to+ see that account's activity:++ $ hledger register checking+ 2008/01/01 income assets:bank:checking $1 $1+ 2008/06/01 gift assets:bank:checking $1 $2+ 2008/06/02 save assets:bank:checking $-1 $1+ 2008/12/31 pay off assets:bank:checking $-1 0++ With --date2, it shows and sorts by secondary date instead.++ The --historical/-H flag adds the balance from any undisplayed prior+ postings to the running total. This is useful when you want to see+ only recent activity, with a historically accurate running balance:++ $ hledger register checking -b 2008/6 --historical+ 2008/06/01 gift assets:bank:checking $1 $2+ 2008/06/02 save assets:bank:checking $-1 $1+ 2008/12/31 pay off assets:bank:checking $-1 0++ The --depth option limits the amount of sub-account detail displayed.++ The --average/-A flag shows the running average posting amount instead+ of the running total (so, the final number displayed is the average for+ the whole report period). This flag implies --empty (see below). It+ is affected by --historical. It works best when showing just one+ account and one commodity.++ The --related/-r flag shows the other postings in the transactions of+ the postings which would normally be shown.++ The --invert flag negates all amounts. For example, it can be used on+ an income account where amounts are normally displayed as negative num-+ bers. It's also useful to show postings on the checking account+ together with the related account:++ $ hledger register --related --invert assets:checking++ With a reporting interval, register shows summary postings, one per+ interval, aggregating the postings to each account:++ $ hledger register --monthly income+ 2008/01 income:salary $-1 $-1+ 2008/06 income:gifts $-1 $-2++ Periods with no activity, and summary postings with a zero amount, are+ not shown by default; use the --empty/-E flag to see them:++ $ hledger register --monthly income -E+ 2008/01 income:salary $-1 $-1+ 2008/02 0 $-1+ 2008/03 0 $-1+ 2008/04 0 $-1+ 2008/05 0 $-1+ 2008/06 income:gifts $-1 $-2+ 2008/07 0 $-2+ 2008/08 0 $-2+ 2008/09 0 $-2+ 2008/10 0 $-2+ 2008/11 0 $-2+ 2008/12 0 $-2++ Often, you'll want to see just one line per interval. The --depth+ option helps with this, causing subaccounts to be aggregated:++ $ hledger register --monthly assets --depth 1h+ 2008/01 assets $1 $1+ 2008/06 assets $-1 0+ 2008/12 assets $-1 $-1++ Note when using report intervals, if you specify start/end dates these+ will be adjusted outward if necessary to contain a whole number of+ intervals. This ensures that the first and last intervals are full+ length and comparable to the others in the report.++ Custom register output+ register uses the full terminal width by default, except on windows.+ You can override this by setting the COLUMNS environment variable (not+ a bash shell variable) or by using the --width/-w option.++ The description and account columns normally share the space equally+ (about half of (width - 40) each). You can adjust this by adding a+ description width as part of --width's argument, comma-separated:+ --width W,D . Here's a diagram (won't display correctly in --help):++ <--------------------------------- width (W) ---------------------------------->+ date (10) description (D) account (W-41-D) amount (12) balance (12)+ DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA++ and some examples:++ $ hledger reg # use terminal width (or 80 on windows)+ $ hledger reg -w 100 # use width 100+ $ COLUMNS=100 hledger reg # set with one-time environment variable+ $ export COLUMNS=100; hledger reg # set till session end (or window resize)+ $ hledger reg -w 100,40 # set overall width 100, description width 40+ $ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, and (experimental)+ json.++ register-match+ register-match+ Print the one posting whose transaction description is closest to DESC,+ in the style of the register command. If there are multiple equally+ good matches, it shows the most recent. Query options (options, not+ arguments) can be used to restrict the search space. Helps ledger-+ autosync detect already-seen transactions when importing.++ rewrite+ rewrite+ Print all transactions, rewriting the postings of matched transactions.+ For now the only rewrite available is adding new postings, like print+ --auto.++ This is a start at a generic rewriter of transaction entries. It reads+ the default journal and prints the transactions, like print, but adds+ one or more specified postings to any transactions matching QUERY. The+ posting amounts can be fixed, or a multiplier of the existing transac-+ tion's first posting amount.++ Examples:++ $ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'+ $ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'+ $ hledger-rewrite.hs -f rewrites.hledger++ rewrites.hledger may consist of entries like:++ = ^income amt:<0 date:2017+ (liabilities:tax) *0.33 ; tax on income+ (reserve:grocery) *0.25 ; reserve 25% for grocery+ (reserve:) *0.25 ; reserve 25% for grocery++ Note the single quotes to protect the dollar sign from bash, and the+ two spaces between account and amount.++ More:++ $ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...+ $ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'+ $ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'+ $ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'++ Argument for --add-posting option is a usual posting of transaction+ with an exception for amount specification. More precisely, you can+ use '*' (star symbol) before the amount to indicate that that this is a+ factor for an amount of original matched posting. If the amount+ includes a commodity name, the new posting amount will be in the new+ commodity; otherwise, it will be in the matched posting amount's com-+ modity.++ Re-write rules in a file+ During the run this tool will execute so called "Automated Transac-+ tions" found in any journal it process. I.e instead of specifying this+ operations in command line you can put them in a journal file.++ $ rewrite-rules.journal++ Make contents look like this:++ = ^income+ (liabilities:tax) *.33++ = expenses:gifts+ budget:gifts *-1+ assets:budget *1++ Note that '=' (equality symbol) that is used instead of date in trans-+ actions you usually write. It indicates the query by which you want to+ match the posting to add new ones.++ $ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal++ This is something similar to the commands pipeline:++ $ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \+ | hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \+ --add-posting 'assets:budget *1' \+ > rewritten-tidy-output.journal++ It is important to understand that relative order of such entries in+ journal is important. You can re-use result of previously added post-+ ings.++ Diff output format+ To use this tool for batch modification of your journal files you may+ find useful output in form of unified diff.++ $ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'++ Output might look like:++ --- /tmp/examples/sample.journal+ +++ /tmp/examples/sample.journal+ @@ -18,3 +18,4 @@+ 2008/01/01 income+ - assets:bank:checking $1+ + assets:bank:checking $1+ income:salary+ + (liabilities:tax) 0+ @@ -22,3 +23,4 @@+ 2008/06/01 gift+ - assets:bank:checking $1+ + assets:bank:checking $1+ income:gifts+ + (liabilities:tax) 0++ If you'll pass this through patch tool you'll get transactions contain-+ ing the posting that matches your query be updated. Note that multiple+ files might be update according to list of input files specified via+ --file options and include directives inside of these files.++ Be careful. Whole transaction being re-formatted in a style of output+ from hledger print.++ See also:++ https://github.com/simonmichael/hledger/issues/99++ rewrite vs. print --auto+ This command predates print --auto, and currently does much the same+ thing, but with these differences:++ o with multiple files, rewrite lets rules in any file affect all other+ files. print --auto uses standard directive scoping; rules affect+ only child files.++ o rewrite's query limits which transactions can be rewritten; all are+ printed. print --auto's query limits which transactions are printed.++ o rewrite applies rules specified on command line or in the journal.+ print --auto applies rules specified in the journal.++ roi+ roi+ Shows the time-weighted (TWR) and money-weighted (IRR) rate of return+ on your investments.++ At a minimum, you need to supply a query (which could be just an+ account name) to select your investment(s) with --inv, and another+ query to identify your profit and loss transactions with --pnl.++ If you do not record changes in the value of your investment manually,+ or do not require computation of time-weighted return (TWR), --pnl+ 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+ display, regardless of the length of reporting interval.++ 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+ becomes negative at some point in time.++ o Error (SearchFailed): Failed to find solution for Internal Rate of+ Return (IRR). Either search does not converge to a solution, or con-+ verges too slowly.++ Examples:++ o Using roi to compute total return of investment in stocks:+ https://github.com/simonmichael/hledger/blob/master/examples/roi-+ unrealised.ledger++ o Cookbook -> Return on Investment++ Spaces and special characters in --inv and --pnl+ Note that --inv and --pnl's argument is a query, and queries could have+ several space-separated terms (see QUERIES).++ To indicate that all search terms form single command-line argument,+ you will need to put them in quotes (see Special characters):++ $ hledger roi --inv 'term1 term2 term3 ...'++ If any query terms contain spaces themselves, you will need an extra+ level of nested quoting, eg:++ $ hledger roi --inv="'Assets:Test 1'" --pnl="'Equity:Unrealized Profit and Loss'"++ Semantics of --inv and --pnl+ Query supplied to --inv has to match all transactions that are related+ 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+ and which is due to the return on investment.++ o "Cash flow" is depositing or withdrawing money, buying or selling+ assets, or otherwise converting between your investment commodity and+ any other commodity. Example:++ 2019-01-01 Investing in Snake Oil+ assets:cash -$100+ investment:snake oil++ 2020-01-01 Selling my Snake Oil+ assets:cash $10+ investment:snake oil = 0++ o "Profit and loss" is change in the value of your investment:++ 2019-06-01 Snake Oil falls in value+ investment:snake oil = $57+ equity:unrealized profit or loss++ All non-investment postings are assumed to be "cash flow", unless they+ match --pnl query. Changes in value of your investment due to "profit+ and loss" postings will be considered as part of your investment+ return.++ Example: if you use --inv snake --pnl equity:unrealized, then postings+ in the example below would be classifed as:++ 2019-01-01 Snake Oil #1+ assets:cash -$100 ; cash flow posting+ investment:snake oil ; investment posting++ 2019-03-01 Snake Oil #2+ equity:unrealized pnl -$100 ; profit and loss posting+ snake oil ; investment posting++ 2019-07-01 Snake Oil #3+ equity:unrealized pnl ; profit and loss posting+ cash -$100 ; cash flow posting+ snake oil $50 ; investment posting++ IRR and TWR explained+ "ROI" stands for "return on investment". Traditionally this was com-+ puted as a difference between current value of investment and its ini-+ tial value, expressed in percentage of the initial value.++ However, this approach is only practical in simple cases, where invest-+ ments receives no in-flows or out-flows of money, and where rate of+ growth is fixed over time. For more complex scenarios you need differ-+ ent ways to compute rate of return, and this command implements two of+ them: IRR and TWR.++ Internal rate of return, or "IRR" (also called "money-weighted rate of+ return") takes into account effects of in-flows and out-flows.+ Naively, if you are withdrawing from your investment, your future gains+ would be smaller (in absolute numbers), and will be a smaller percent-+ age of your initial investment, and if you are adding to your invest-+ ment, you will receive bigger absolute gains (but probably at the same+ rate of return). IRR is a way to compute rate of return for each+ period between in-flow or out-flow of money, and then combine them in a+ way that gives you a compound annual rate of return that investment is+ expected to generate.++ 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.++ If you manually record changes in the value of your investment as+ transactions that balance them against "profit and loss" (or "unreal-+ ized gains") account or use price directives, then in order for IRR to+ compute the precise effect of your in-flows and out-flows on the rate+ of return, you will need to record the value of your investement on or+ close to the days when in- or out-flows occur.++ In technical terms, IRR uses the same approach as computation of net+ present value, and tries to find a discount rate that makes net present+ value of all the cash flows of your investment to add up to zero. This+ could be hard to wrap your head around, especially if you haven't done+ discounted cash flow analysis before. 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+ 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+ and then a compound rate of return. However, internal workings of TWR+ are quite different.++ TWR represents your investment as an imaginary "unit fund" where in-+ flows/ out-flows lead to buying or selling "units" of your investment+ and changes in its value change the value of "investment unit". Change+ in "unit price" over the reporting period gives you rate of return of+ your investment.++ References: * Explanation of rate of return * Explanation of IRR *+ Explanation of TWR * Examples of computing IRR and TWR and discussion+ of the limitations of both metrics++ stats+ stats+ Show some journal statistics.++ The stats command displays summary information for the whole journal,+ or a matched part of it. With a reporting interval, it shows a report+ for each report period.++ Example:++ $ hledger stats+ Main journal file : /src/hledger/examples/sample.journal+ Included journal files :+ Transactions span : 2008-01-01 to 2009-01-01 (366 days)+ Last transaction : 2008-12-31 (2333 days ago)+ Transactions : 5 (0.0 per day)+ Transactions last 30 days: 0 (0.0 per day)+ Transactions last 7 days : 0 (0.0 per day)+ Payees/descriptions : 5+ Accounts : 8 (depth 3)+ Commodities : 1 ($)+ Market prices : 12 ($)++ This command also supports output destination and output format selec-+ tion.++ tags+ tags+ List the unique tag names used in the journal. With a TAGREGEX argu-+ ment, only tag names matching the regular expression (case insensitive)+ are shown. With QUERY arguments, only transactions matching the query+ are considered.++ With the --values flag, the tags' unique values are listed instead.++ With --parsed flag, all tags or values are shown in the order they are+ parsed from the input data, including duplicates.++ With -E/--empty, any blank/empty values will also be shown, otherwise+ they are omitted.++ test+ test+ Run built-in unit tests.++ This command runs the unit tests built in to hledger and hledger-lib,+ printing the results on stdout. If any test fails, the exit code will+ be non-zero.++ This is mainly used by hledger developers, but you can also use it to+ sanity-check the installed hledger executable on your platform. All+ tests are expected to pass - if you ever see a failure, please report+ as a bug!++ This command also accepts tasty test runner options, written after a --+ (double hyphen). Eg to run only the tests in Hledger.Data.Amount, with+ ANSI colour codes disabled:++ $ hledger test -- -pData.Amount --color=never++ For help on these, see https://github.com/feuerbach/tasty#options (--+ --help currently doesn't show them).++ About add-on commands+ Add-on commands are programs or scripts in your PATH++ o whose name starts with hledger-++ o whose name ends with a recognised file extension: .bat,.com,.exe,+ .hs,.lhs,.pl,.py,.rb,.rkt,.sh or none++ o and (on unix, mac) which are executable by the current user.++ Add-ons are a relatively easy way to add local features or experiment+ with new ideas. They can be written in any language, but haskell+ scripts have a big advantage: they can use the same hledger library+ functions that built-in commands use for command-line options, parsing+ and reporting. Some experimental/example add-on scripts can be found+ in the hledger repo's bin/ directory.++ Note in a hledger command line, add-on command flags must have a double+ dash (--) preceding them. Eg you must write:++ $ hledger web -- --serve++ and not:++ $ hledger web --serve++ (because the --serve flag belongs to hledger-web, not hledger).++ The -h/--help and --version flags don't require --.++ If you have any trouble with this, remember you can always run the add-+ on program directly, eg:++ $ hledger-web --serve++JOURNAL FORMAT+ hledger's default file format, representing a General Journal.++ hledger's usual data source is a plain text file containing journal+ entries in hledger journal format. This file represents a standard+ accounting general journal. I use file names ending in .journal, but+ that's not required. The journal file contains a number of transaction+ entries, each describing a transfer of money (or any commodity) between+ two or more named accounts, in a simple format readable by both hledger+ and humans.++ hledger's journal format is a compatible subset, mostly, of ledger's+ journal format, so hledger can work with compatible ledger journal+ files as well. It's safe, and encouraged, to run both hledger and+ ledger on the same journal file, eg to validate the results you're get-+ ting.++ You can use hledger without learning any more about this file; just use+ the add or web or import commands to create and update it.++ Many users, though, edit the journal file with a text editor, and track+ changes with a version control system such as git. Editor addons such+ as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and+ hledger-vscode for Visual Studio Code, make this easier, adding colour,+ formatting, tab completion, and useful commands. See Editor configura-+ tion at hledger.org for the full list.++ Here's a description of each part of the file format (and hledger's+ data model). These are mostly in the order you'll use them, but in+ some cases related concepts have been grouped together for easy refer-+ ence, or linked before they are introduced, so feel free to skip over+ anything that looks unnecessary right now.++ Transactions+ Transactions are the main unit of information in a journal file. They+ represent events, typically a movement of some quantity of commodities+ between two or more named accounts.++ Each transaction is recorded as a journal entry, beginning with a sim-+ ple date in column 0. This can be followed by any of the following+ optional fields, separated by spaces:++ o a status character (empty, !, or *)++ o a code (any short number or text, enclosed in parentheses)++ o a description (any remaining text until end of line or a semicolon)++ o a comment (any remaining text following a semicolon until end of+ line, and any following indented lines beginning with a semicolon)++ o 0 or more indented posting lines, describing what was transferred and+ the accounts involved (indented comment lines are also allowed, but+ not blank lines or non-indented lines).++ Here's a simple journal file containing one transaction:++ 2008/01/01 income+ assets:bank:checking $1+ income:salary $-1++ Dates+ Simple dates+ Dates in the journal file use simple dates format: YYYY-MM-DD or+ YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be+ omitted, in which case it will be inferred from the context: the cur-+ rent transaction, the default year set with a default year directive,+ or the current date when the command is run. Some examples:+ 2010-01-31, 2010/01/31, 2010.1.31, 1/31.++ (The UI also accepts simple dates, as well as the more flexible smart+ dates documented in the hledger manual.)++ Secondary dates+ Real-life transactions sometimes involve more than one date - eg the+ date you write a cheque, and the date it clears in your bank. When you+ want to model this, for more accurate daily balances, you can specify+ individual posting dates.++ Or, you can use the older secondary date feature (Ledger calls it aux-+ iliary date or effective date). Note: we support this for compatibil-+ ity, but I usually recommend avoiding this feature; posting dates are+ almost always clearer and simpler.++ A secondary date is written after the primary date, following an equals+ sign. If the year is omitted, the primary date's year is assumed.+ When running reports, the primary (left) date is used by default, but+ with the --date2 flag (or --aux-date or --effective), the secondary+ (right) date will be used instead.++ The meaning of secondary dates is up to you, but it's best to follow a+ consistent rule. Eg "primary = the bank's clearing date, secondary =+ date the transaction was initiated, if different", as shown here:++ 2010/2/23=2/19 movie ticket+ expenses:cinema $10+ assets:checking++ $ hledger register checking+ 2010-02-23 movie ticket assets:checking $-10 $-10++ $ hledger register checking --date2+ 2010-02-19 movie ticket assets:checking $-10 $-10++ Posting dates+ You can give individual postings a different date from their parent+ transaction, by adding a posting comment containing a tag (see below)+ like date:DATE. This is probably the best way to control posting dates+ precisely. Eg in this example the expense should appear in May+ reports, and the deduction from checking should be reported on 6/1 for+ easy bank reconciliation:++ 2015/5/30+ expenses:food $10 ; food purchased on saturday 5/30+ assets:checking ; bank cleared it on monday, date:6/1++ $ hledger -f t.j register food+ 2015-05-30 expenses:food $10 $10++ $ hledger -f t.j register checking+ 2015-06-01 assets:checking $-10 $-10++ DATE should be a simple date; if the year is not specified it will use+ the year of the transaction's date. You can set the secondary date+ similarly, with date2:DATE2. The date: or date2: tags must have a+ valid simple date value if they are present, eg a date: tag with no+ value is not allowed.++ Ledger's earlier, more compact bracketed date syntax is also supported:+ [DATE], [DATE=DATE2] or [=DATE2]. hledger will attempt to parse any+ square-bracketed sequence of the 0123456789/-.= characters in this way.+ With this syntax, DATE infers its year from the transaction and DATE2+ infers its year from DATE.++ Status+ Transactions, or individual postings within a transaction, can have a+ status mark, which is a single character before the transaction+ description or posting account name, separated from it by a space,+ indicating one of three statuses:+++ mark status+ ------------------+ unmarked+ ! pending+ * cleared++ When reporting, you can filter by status with the -U/--unmarked,+ -P/--pending, and -C/--cleared flags; or the status:, status:!, and+ status:* queries; or the U, P, C keys in hledger-ui.++ Note, in Ledger and in older versions of hledger, the "unmarked" state+ is called "uncleared". As of hledger 1.3 we have renamed it to+ unmarked for clarity.++ To replicate Ledger and old hledger's behaviour of also matching pend-+ ing, combine -U and -P.++ Status marks are optional, but can be helpful eg for reconciling with+ real-world accounts. Some editor modes provide highlighting and short-+ cuts for working with status. Eg in Emacs ledger-mode, you can toggle+ transaction status with C-c C-e, or posting status with C-c C-c.++ What "uncleared", "pending", and "cleared" actually mean is up to you.+ Here's one suggestion:+++ status meaning+ --------------------------------------------------------------------------+ uncleared recorded but not yet reconciled; needs review+ pending tentatively reconciled (if needed, eg during a big reconcil-+ iation)+ cleared complete, reconciled as far as possible, and considered cor-+ rect++ With this scheme, you would use -PC to see the current balance at your+ bank, -U to see things which will probably hit your bank soon (like+ uncashed checks), and no flags to see the most up-to-date state of your+ finances.++ Code+ After the status mark, but before the description, you can optionally+ write a transaction "code", enclosed in parentheses. This is a good+ place to record a check number, or some other important transaction id+ or reference number.++ Description+ A transaction's description is the rest of the line following the date+ and status mark (or until a comment begins). Sometimes called the+ "narration" in traditional bookkeeping, it can be used for whatever you+ wish, or left blank. Transaction descriptions can be queried, unlike+ comments.++ Payee and note+ You can optionally include a | (pipe) character in descriptions to sub-+ divide the description into separate fields for payee/payer name on the+ left (up to the first |) and an additional note field on the right+ (after the first |). This may be worthwhile if you need to do more+ precise querying and pivoting by payee or by note.++ Comments+ Lines in the journal beginning with a semicolon (;) or hash (#) or star+ (*) are comments, and will be ignored. (Star comments cause org-mode+ nodes to be ignored, allowing emacs users to fold and navigate their+ journals with org-mode or orgstruct-mode.)++ You can attach comments to a transaction by writing them after the+ description and/or indented on the following lines (before the post-+ ings). Similarly, you can attach comments to an individual posting by+ writing them after the amount and/or indented on the following lines.+ Transaction and posting comments must begin with a semicolon (;).++ Some examples:++ # a file comment+ ; another file comment+ * also a file comment, useful in org/orgstruct mode++ comment+ A multiline file comment, which continues+ until a line containing just "end comment"+ (or end of file).+ end comment++ 2012/5/14 something ; a transaction comment+ ; the transaction comment, continued+ posting1 1 ; a comment for posting 1+ posting2+ ; a comment for posting 2+ ; another comment line for posting 2+ ; a file comment (because not indented)++ You can also comment larger regions of a file using comment and end+ comment directives.++ Tags+ Tags are a way to add extra labels or labelled data to postings and+ transactions, which you can then search or pivot on.++ A simple tag is a word (which may contain hyphens) followed by a full+ colon, written inside a transaction or posting comment line:++ 2017/1/16 bought groceries ; sometag:++ Tags can have a value, which is the text after the colon, up to the+ next comma or end of line, with leading/trailing whitespace removed:++ expenses:food $10 ; a-posting-tag: the tag value++ Note this means hledger's tag values can not contain commas or new-+ lines. Ending at commas means you can write multiple short tags on one+ line, comma separated:++ assets:checking ; a comment containing tag1:, tag2: some value ...++ Here,++ o "a comment containing" is just comment text, not a tag++ o "tag1" is a tag with no value++ o "tag2" is another tag, whose value is "some value ..."++ Tags in a transaction comment affect the transaction and all of its+ postings, while tags in a posting comment affect only that posting.+ For example, the following transaction has three tags (A, TAG2, third-+ tag) and the posting has four (those plus posting-tag):++ 1/1 a transaction ; A:, TAG2:+ ; third-tag: a third transaction tag, <- with a value+ (a) $1 ; posting-tag:++ Tags are like Ledger's metadata feature, except hledger's tag values+ are simple strings.++ Postings+ A posting is an addition of some amount to, or removal of some amount+ from, an account. Each posting line begins with at least one space or+ tab (2 or 4 spaces is common), followed by:++ o (optional) a status character (empty, !, or *), followed by a space++ o (required) an account name (any text, optionally containing single+ spaces, until end of line or a double space)++ o (optional) two or more spaces or tabs followed by an amount.++ Positive amounts are being added to the account, negative amounts are+ being removed.++ The amounts within a transaction must always sum up to zero. As a con-+ venience, one amount may be left blank; it will be inferred so as to+ balance the transaction.++ Be sure to note the unusual two-space delimiter between account name+ and amount. This makes it easy to write account names containing spa-+ ces. But if you accidentally leave only one space (or tab) before the+ amount, the amount will be considered part of the account name.++ Virtual postings+ A posting with a parenthesised account name is called a virtual posting+ or unbalanced posting, which means it is exempt from the usual rule+ that a transaction's postings must balance add up to zero.++ This is not part of double entry accounting, so you might choose to+ avoid this feature. Or you can use it sparingly for certain special+ cases where it can be convenient. Eg, you could set opening balances+ without using a balancing equity account:++ 1/1 opening balances+ (assets:checking) $1000+ (assets:savings) $2000++ A posting with a bracketed account name is called a balanced virtual+ posting. The balanced virtual postings in a transaction must add up to+ zero (separately from other postings). Eg:++ 1/1 buy food with cash, update budget envelope subaccounts, & something else+ assets:cash $-10 ; <- these balance+ expenses:food $7 ; <-+ expenses:food $3 ; <-+ [assets:checking:budget:food] $-10 ; <- and these balance+ [assets:checking:available] $10 ; <-+ (something:else) $5 ; <- not required to balance++ Ordinary non-parenthesised, non-bracketed postings are called real+ postings. You can exclude virtual postings from reports with the+ -R/--real flag or real:1 query.++ Account names+ Account names typically have several parts separated by a full colon,+ from which hledger derives a hierarchical chart of accounts. They can+ be anything you like, but in finance there are traditionally five top-+ level accounts: assets, liabilities, revenue, expenses, and equity.++ Account names may contain single spaces, eg: assets:accounts receiv-+ able. Because of this, they must always be followed by two or more+ spaces (or newline).++ Account names can be aliased.++ Amounts+ After the account name, there is usually an amount. (Important:+ between account name and amount, there must be two or more spaces.)++ hledger's amount format is flexible, supporting several international+ formats. Here are some examples. Amounts have a number (the "quan-+ tity"):++ 1++ ..and usually a currency symbol or commodity name (more on this below),+ to the left or right of the quantity, with or without a separating+ space:++ $1+ 4000 AAPL+ 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-+ modity symbol:++ -$1+ $-1++ One or more spaces between the sign and the number are acceptable when+ parsing (but they won't be displayed in output):++ + $1+ $- 1++ Scientific E notation is allowed:++ 1E-6+ EUR 1E3++ Decimal marks, digit group marks+ A decimal mark can be written as a period or a comma:++ 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, comma, or period (different from the decimal mark):++ $1,000,000.00+ EUR 2.000.000,00+ INR 9,99,99,999.00+ 1 000 000.9455++ Note, a number containing a single digit group mark and no decimal mark+ is ambiguous. Are these digit group marks or decimal marks ?++ 1,000+ 1.000++ If you don't tell it otherwise, hledger will assume both of the above+ are decimal marks, parsing both numbers as 1. To prevent confusion and+ undetected typos, we recommend adding commodity directives at the top+ of your journal file to explicitly declare the decimal mark (and+ optionally a digit group mark) for each commodity. Read on for more+ about this.++ Commodity+ 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",+ "ABC123").++ 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+ 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+ are the Amount and MixedAmount types.)++ Commodity directives+ You can add commodity directives to the journal, preferably at the top,+ to declare your commodities and help with number parsing (see above)+ and display (see below). These are optional, but recommended. They+ are described in more detail in JOURNAL FORMAT -> Declaring commodi-+ ties. Here's a quick example:++ # number format and display style for $, EUR, INR and the no-symbol commodity:+ commodity $1,000.00+ commodity EUR 1.000,00+ commodity INR 9,99,99,999.00+ commodity 1 000 000.9455+++ Commodity display style+ For the amounts in each commodity, hledger chooses a consistent display+ style to use in most reports. (Exceptions: price amounts, and all+ amounts displayed by the print command, are displayed with all of their+ decimal digits visible.)++ A commodity's display style is inferred as follows.++ 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+ order of preference:++ 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.+ (Posting amounts only; prices and periodic or auto rules are ignored,+ currently.)++ o The built-in fallback style, which looks like this: $1000.00. (Sym-+ bol on the left, period decimal mark, two decimal places.)++ A style is inferred from journal amounts as follows:++ o Use the general style (decimal mark, symbol placement) of the first+ amount++ o Use the first-seen digit group style (digit group mark, digit group+ sizes), if any++ o Use the maximum number of decimal places of all.++ Transaction price amounts don't affect the commodity display style+ directly, but occasionally they can do so indirectly (eg when a post-+ ing's amount is inferred using a transaction price). If you find this+ causing problems, use a commodity 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+ places, use a commodity directive. Some examples:++ # declare euro, dollar, bitcoin and no-symbol commodities and set their+ # input number formats and output display styles:+ commodity EUR 1.000,+ commodity $1000.00+ commodity 1000.00000000 BTC+ commodity 1 000.++ Rounding+ Amounts are stored internally as decimal numbers with up to 255 decimal+ places, and displayed with the number of decimal places specified by+ the commodity display style. Note, hledger uses banker's rounding: it+ rounds to the nearest even number, eg 0.5 displayed with zero decimal+ places is "0"). (Guaranteed since hledger 1.17.1; in older versions+ this could vary if hledger was built with Decimal < 0.5.1.)++ Transaction prices+ Within a transaction, you can note an amount's price in another commod-+ ity. This can be used to document the cost (in a purchase) or selling+ price (in a sale). For example, transaction prices are useful to+ record purchases of a foreign currency. Note transaction prices are+ fixed at the time of the transaction, and do not change over time. See+ also market prices, which represent prevailing exchange rates on a cer-+ tain date.++ There are several ways to record a transaction price:++ 1. Write the price per unit, as @ UNITPRICE after the amount:++ 2009/1/1+ assets:euros EUR100 @ $1.35 ; one hundred euros purchased at $1.35 each+ assets:dollars ; balancing amount is -$135.00++ 2. Write the total price, as @@ TOTALPRICE after the amount:++ 2009/1/1+ assets:euros EUR100 @@ $135 ; one hundred euros purchased at $135 for the lot+ assets:dollars++ 3. Specify amounts for all postings, using exactly two commodities, and+ let hledger infer the price that balances the transaction:++ 2009/1/1+ assets:euros EUR100 ; one hundred euros purchased+ assets:dollars $-135 ; for $135++ 4. Like 1, but the @ is parenthesised, i.e. (@); this is for compati-+ bility with Ledger journals (Virtual posting costs), and is equiva-+ lent to 1 in hledger.++ 5. Like 2, but as in 4 the @@ is parenthesised, i.e. (@@); in hledger,+ this is equivalent to 2.++ Use the -B/--cost flag to convert amounts to their transaction price's+ commodity, if any. (mnemonic: "B" is from "cost Basis", as in Ledger).+ Eg here is how -B affects the balance report for the example above:++ $ hledger bal -N --flat+ $-135 assets:dollars+ EUR100 assets:euros+ $ hledger bal -N --flat -B+ $-135 assets:dollars+ $135 assets:euros # <- the euros' cost++ Note -B is sensitive to the order of postings when a transaction price+ is inferred: the inferred price will be in the commodity of the last+ amount. So if example 3's postings are reversed, while the transaction+ is equivalent, -B shows something different:++ 2009/1/1+ assets:dollars $-135 ; 135 dollars sold+ assets:euros EUR100 ; for 100 euros++ $ hledger bal -N --flat -B+ EUR-100 assets:dollars # <- the dollars' selling price+ EUR100 assets:euros++ Lot prices, lot dates+ Ledger allows another kind of price, lot price (four variants: {UNIT-+ PRICE}, {{TOTALPRICE}}, {=FIXEDUNITPRICE}, {{=FIXEDTOTALPRICE}}),+ and/or a lot date ([DATE]) to be specified. These are normally used to+ select a lot when selling investments. hledger will parse these, for+ compatibility with Ledger journals, but currently ignores them. A+ transaction price, lot price and/or lot date may appear in any order,+ after the posting amount and before the balance assertion if any.++ Balance assertions+ hledger supports Ledger-style balance assertions in journal files.+ These look like, for example, = EXPECTEDBALANCE following a posting's+ amount. Eg here we assert the expected dollar balance in accounts a+ and b after each posting:++ 2013/1/1+ a $1 =$1+ b =$-1++ 2013/1/2+ a $1 =$2+ b $-1 =$-2++ After reading a journal file, hledger will check all balance assertions+ and report an error if any of them fail. Balance assertions can pro-+ tect you from, eg, inadvertently disrupting reconciled balances while+ cleaning up old entries. You can disable them temporarily with the+ -I/--ignore-assertions flag, which can be useful for troubleshooting or+ for reading Ledger files. (Note: this flag currently does not disable+ balance assignments, below).++ Assertions and ordering+ hledger sorts an account's postings and assertions first by date and+ then (for postings on the same day) by parse order. Note this is dif-+ ferent from Ledger, which sorts assertions only by parse order. (Also,+ Ledger assertions do not see the accumulated effect of repeated post-+ ings to the same account within a transaction.)++ So, hledger balance assertions keep working if you reorder differently-+ dated transactions within the journal. But if you reorder same-dated+ transactions or postings, assertions might break and require updating.+ This order dependence does bring an advantage: precise control over the+ order of postings and assertions within a day, so you can assert intra-+ day balances.++ Assertions and included files+ With included files, things are a little more complicated. Including+ preserves the ordering of postings and assertions. If you have multi-+ ple postings to an account on the same day, split across different+ files, and you also want to assert the account's balance on the same+ day, you'll have to put the assertion in the right file.++ Assertions and multiple -f options+ Balance assertions don't work well across files specified with multiple+ -f options. Use include or concatenate the files instead.++ Assertions and commodities+ The asserted balance must be a simple single-commodity amount, and in+ fact the assertion checks only this commodity's balance within the+ (possibly multi-commodity) account balance. This is how assertions+ work in Ledger also. We could call this a "partial" balance assertion.++ To assert the balance of more than one commodity in an account, you can+ write multiple postings, each asserting one commodity's balance.++ You can make a stronger "total" balance assertion by writing a double+ equals sign (== EXPECTEDBALANCE). This asserts that there are no other+ unasserted commodities in the account (or, that their balance is 0).++ 2013/1/1+ a $1+ a 1EUR+ b $-1+ c -1EUR++ 2013/1/2 ; These assertions succeed+ a 0 = $1+ a 0 = 1EUR+ b 0 == $-1+ c 0 == -1EUR++ 2013/1/3 ; This assertion fails as 'a' also contains 1EUR+ a 0 == $1++ It's not yet possible to make a complete assertion about a balance that+ has multiple commodities. One workaround is to isolate each commodity+ into its own subaccount:++ 2013/1/1+ a:usd $1+ a:euro 1EUR+ b++ 2013/1/2+ a 0 == 0+ a:usd 0 == $1+ a:euro 0 == 1EUR++ Assertions and prices+ Balance assertions ignore transaction prices, and should normally be+ written without one:++ 2019/1/1+ (a) $1 @ EUR1 = $1++ We do allow prices to be written there, however, and print shows them,+ even though they don't affect whether the assertion passes or fails.+ This is for backward compatibility (hledger's close command used to+ generate balance assertions with prices), and because balance assign-+ ments do use them (see below).++ Assertions and subaccounts+ The balance assertions above (= and ==) do not count the balance from+ subaccounts; they check the account's exclusive balance only. You can+ assert the balance including subaccounts by writing =* or ==*, eg:++ 2019/1/1+ equity:opening balances+ checking:a 5+ checking:b 5+ checking 1 ==* 11++ Assertions and virtual postings+ Balance assertions are checked against all postings, both real and vir-+ tual. They are not affected by the --real/-R flag or real: query.++ Assertions and precision+ Balance assertions compare the exactly calculated amounts, which are+ not always what is shown by reports. Eg a commodity directive may+ limit the display precision, but this will not affect balance asser-+ tions. Balance assertion failure messages show exact amounts.++ Balance assignments+ Ledger-style balance assignments are also supported. These are like+ balance assertions, but with no posting amount on the left side of the+ equals sign; instead it is calculated automatically so as to satisfy+ the assertion. This can be a convenience during data entry, eg when+ setting opening balances:++ ; starting a new journal, set asset account balances+ 2016/1/1 opening balances+ assets:checking = $409.32+ assets:savings = $735.24+ assets:cash = $42+ equity:opening balances++ or when adjusting a balance to reality:++ ; no cash left; update balance, record any untracked spending as a generic expense+ 2016/1/15+ assets:cash = $0+ expenses:misc++ The calculated amount depends on the account's balance in the commodity+ at that point (which depends on the previously-dated postings of the+ commodity to that account since the last balance assertion or assign-+ ment). Note that using balance assignments makes your journal a little+ less explicit; to know the exact amount posted, you have to run hledger+ or do the calculations yourself, instead of just reading it.++ Balance assignments and prices+ A transaction price in a balance assignment will cause the calculated+ amount to have that price attached:++ 2019/1/1+ (a) = $1 @ EUR2++ $ hledger print --explicit+ 2019-01-01+ (a) $1 @ EUR2 = $1 @ EUR2++ Directives+ A directive is a line in the journal beginning with a special keyword,+ that influences how the journal is processed. hledger's directives are+ based on a subset of Ledger's, but there are many differences (and also+ some differences between hledger versions).++ Directives' behaviour and interactions can get a little bit complex, so+ here is a table summarising the directives and their effects, with+ links to more detailed docs.+++ direc- end subdi- purpose can affect (as of+ tive directive rec- 2018/06)+ tives+ ------------------------------------------------------------------------------------+ account any document account names, all entries in all+ text declare account types & dis- files, before or+ play order after+++++ alias end rewrite account names following entries+ aliases until end of cur-+ rent file or end+ directive+ apply end apply prepend a common parent to following entries+ account account account names until end of cur-+ rent file or end+ directive+ comment end com- ignore part of journal following entries+ ment until end of cur-+ rent file or end+ directive+ commod- format declare a commodity and its number notation:+ ity number notation & display following entries+ style until end of cur-+ rent file; display+ style: amounts of+ that commodity in+ reports+ D declare a commodity to be default commodity:+ used for commodityless following commod-+ amounts, and its number ityless entries+ notation & display style until end of cur-+ rent file; number+ notation: following+ entries in that+ commodity until end+ of current file;+ display style:+ amounts of that+ commodity in+ reports+ include include entries/directives what the included+ from another file directives affect+ payee declare a payee name following entries+ until end of cur-+ rent file+ P declare a market price for a amounts of that+ commodity commodity in+ reports, when -V is+ used+ Y declare a year for yearless following entries+ dates until end of cur-+ rent file+ = declare an auto posting all entries in par-+ rule, adding postings to ent/current/child+ other transactions files (but not sib-+ ling files, see+ #1212)++ And some definitions:+++ subdi- optional indented directive line immediately following a parent+ rec- directive+ tive+ number how to interpret numbers when parsing journal entries (the iden-+ nota- tity of the decimal separator character). (Currently each com-+ tion modity can have its own notation, even in the same file.)+ dis- how to display amounts of a commodity in reports (symbol side+ play and spacing, digit groups, decimal separator, decimal places)+ style+ direc- which entries and (when there are multiple files) which files+ tive are affected by a directive+ scope++ As you can see, directives vary in which journal entries and files they+ affect, and whether they are focussed on input (parsing) or output+ (reports). Some directives have multiple effects.++ Directives and multiple files+ If you use multiple -f/--file options, or the include directive,+ hledger will process multiple input files. But note that directives+ which affect input (see above) typically last only until the end of the+ file in which they occur.++ This may seem inconvenient, but it's intentional; it makes reports sta-+ ble and deterministic, independent of the order of input. Otherwise+ you could see different numbers if you happened to write -f options in+ a different order, or if you moved includes around while cleaning up+ your files.++ It can be surprising though; for example, it means that alias direc-+ tives do not affect parent or sibling files (see below).++ Comment blocks+ A line containing just comment starts a commented region of the file,+ and a line containing just end comment (or the end of the current file)+ ends it. See also comments.++ Including other files+ You can pull in the content of additional files by writing an include+ directive, like this:++ include FILEPATH++ Only journal files can include, and only journal, timeclock or timedot+ files can be included (not CSV files, currently).++ If the file path does not begin with a slash, it is relative to the+ current file's folder.++ A tilde means home directory, eg: include ~/main.journal.++ The path may contain glob patterns to match multiple files, eg: include+ *.journal.++ There is limited support for recursive wildcards: **/ (the slash is+ required) matches 0 or more subdirectories. It's not super convenient+ since you have to avoid include cycles and including directories, but+ this can be done, eg: include */**/*.journal.++ The path may also be prefixed to force a specific file format, overrid-+ ing the file extension (as described in hledger.1 -> Input files):+ include timedot:~/notes/2020*.md.++ Default year+ You can set a default year to be used for subsequent dates which don't+ specify a year. This is a line beginning with Y followed by the year.+ Eg:++ Y2009 ; set default year to 2009++ 12/15 ; equivalent to 2009/12/15+ expenses 1+ assets++ Y2010 ; change default year to 2010++ 2009/1/30 ; specifies the year, not affected+ expenses 1+ assets++ 1/31 ; equivalent to 2010/1/31+ expenses 1+ assets++ Declaring payees+ The payee directive can be used to declare a limited set of payees+ which may appear in transaction descriptions. The "payees" check will+ report an error if any transaction refers to a payee that has not been+ declared. Eg:++ payee Whole Foods++ Declaring commodities+ You can use commodity directives to declare your commodities. In fact+ the commodity directive performs several functions at once:++ 1. It declares commodities which may be used in the journal. This can+ optionally be enforced, providing useful error checking. (Cf Com-+ modity error checking)++ 2. It declares which decimal mark character (period or comma), to+ expect when parsing input - useful to disambiguate international+ number formats in your data. Without this, hledger will parse both+ 1,000 and 1.000 as 1. (Cf Amounts)++ 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+ style)++ 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.++ Generally you should put them at the top of your journal file (since+ for function 2, they affect only following amounts, cf #793).++ A commodity directive is just the word commodity followed by a sample+ amount, like this:++ ;commodity SAMPLEAMOUNT++ commodity $1000.00+ commodity 1,000.0000 AAAA ; optional same-line comment++ It may also be written on multiple lines, and use the format subdirec-+ tive, as in Ledger. Note in this case the commodity symbol appears+ twice; it must be the same in both places:++ ;commodity SYMBOL+ ; format SAMPLEAMOUNT++ ; display indian rupees with currency name on the left,+ ; thousands, lakhs and crores comma-separated,+ ; period as decimal point, and two decimal places.+ commodity INR+ format INR 1,00,00,000.00++ Remember that if the commodity symbol contains spaces, numbers, or+ punctuation, it must be enclosed in double quotes (cf Commodity).++ The amount's quantity does not matter; only the format is significant.+ It must include a decimal mark - either a period or a comma - followed+ by 0 or more decimal digits.++ A few more examples:++ # number formats for $, EUR, INR and the no-symbol commodity:+ commodity $1,000.00+ commodity EUR 1.000,00+ commodity INR 9,99,99,999.0+ commodity 1 000 000.++ Note hledger normally uses banker's rounding, so 0.5 displayed with+ zero decimal digits is "0". (More at Commodity display style.)++ Commodity error checking+ In strict mode, enabled with the -s/--strict flag, hledger will report+ an error if a commodity symbol is used that has not been declared by a+ commodity directive. This works similarly to account error checking,+ see the notes there for more details.++ Default commodity+ The D directive sets a default commodity, to be used for any subsequent+ commodityless amounts (ie, plain numbers) seen while parsing the jour-+ nal. This effect lasts until the next D directive, or the end of the+ journal.++ For compatibility/historical reasons, D also acts like a commodity+ directive (setting the commodity's decimal mark for parsing and display+ style for output).++ As with commodity, the amount must include a decimal mark (either+ period or comma). If both commodity and D directives are used for the+ same commodity, the commodity style takes precedence.++ The syntax is D AMOUNT. Eg:++ ; commodity-less amounts should be treated as dollars+ ; (and displayed with the dollar sign on the left, thousands separators and two decimal places)+ D $1,000.00++ 1/1+ a 5 ; <- commodity-less amount, parsed as $5 and displayed as $5.00+ b++ Declaring market prices+ The P directive declares a market price, which is an exchange rate+ between two commodities on a certain date. (In Ledger, they are called+ "historical prices".) These are often obtained from a stock exchange,+ cryptocurrency exchange, or the foreign exchange market.++ The format is:++ P DATE COMMODITY1SYMBOL COMMODITY2AMOUNT++ DATE is a simple date, COMMODITY1SYMBOL is the symbol of the commodity+ being priced, and COMMODITY2AMOUNT is the amount (symbol and quantity)+ of commodity 2 that one unit of commodity 1 is worth on this date.+ Examples:++ # one euro was worth $1.35 from 2009-01-01 onward:+ P 2009-01-01 EUR $1.35++ # and $1.40 from 2010-01-01 onward:+ P 2010-01-01 EUR $1.40++ The -V, -X and --value flags use these market prices to show amount+ values in another commodity. See Valuation.++ Declaring accounts+ account directives can be used to declare accounts (ie, the places that+ amounts are transferred from and to). Though not required, these dec-+ larations can provide several benefits:++ o They can document your intended chart of accounts, providing a refer-+ ence.++ o They can help hledger know your accounts' types (asset, liability,+ equity, revenue, expense), useful for reports like balancesheet and+ incomestatement.++ o They control account display order in reports, allowing non-alpha-+ betic sorting (eg Revenues to appear above Expenses).++ o They can store extra information about accounts (account numbers,+ notes, etc.)++ o They help with account name completion in the add command, hledger-+ iadd, hledger-web, ledger-mode etc.++ o In strict mode, they restrict which accounts may be posted to by+ transactions, which helps detect typos.++ The simplest form is just the word account followed by a hledger-style+ account name, eg this account directive declares the assets:bank:check-+ ing account:++ account assets:bank:checking++ Account error checking+ By default, accounts come into existence when a transaction references+ them by name. This is convenient, but it means hledger can't warn you+ when you mis-spell an account name in the journal. Usually you'll find+ the error later, as an extra account in balance reports, or an incor-+ rect balance when reconciling.++ In strict mode, enabled with the -s/--strict flag, hledger will report+ an error if any transaction uses an account name that has not been+ declared by an account directive. Some notes:++ o The declaration is case-sensitive; transactions must use the correct+ account name capitalisation.++ o The account directive's scope is "whole file and below" (see direc-+ tives). This means it affects all of the current file, and any files+ it includes, but not parent or sibling files. The position of+ account 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+ included files in other formats).++ o It's currently not possible to declare "all possible subaccounts"+ with a wildcard; every account posted to must be declared.++ Account comments+ Comments, beginning with a semicolon, can be added:++ o on the same line, after two or more spaces (because ; is allowed in+ account names)++ o on the next lines, indented++ An example of both:++ account assets:bank:checking ; same-line comment, note 2+ spaces before ;+ ; next-line comment+ ; another with tag, acctno:12345 (not used yet)++ Same-line comments are not supported by Ledger, or hledger <1.13.++ Account subdirectives+ We also allow (and ignore) Ledger-style indented subdirectives, just+ for compatibility.:++ account assets:bank:checking+ format blah blah ; <- subdirective, ignored++ Here is the full syntax of account directives:++ account ACCTNAME [ACCTTYPE] [;COMMENT]+ [;COMMENTS]+ [LEDGER-STYLE SUBDIRECTIVES, IGNORED]++ Account types+ hledger recognises five main types of account, corresponding to the+ account classes in the accounting equation:++ Asset, Liability, Equity, Revenue, Expense.++ These account types are important for controlling which accounts appear+ in the balancesheet, balancesheetequity, incomestatement reports (and+ probably for other things in future).++ Additionally, we recognise the Cash type, which is also an Asset, and+ which causes accounts to appear in the cashflow report. ("Cash" here+ means liquid assets, eg bank balances but typically not investments or+ receivables.)++ Declaring account types+ Generally, to make these reports work you should declare your top-level+ accounts and their types, using account directives with type: tags.++ The tag's value should be one of: Asset, Liability, Equity, Revenue,+ Expense, Cash, A, L, E, R, X, C (all case insensitive). The type is+ inherited by all subaccounts except where they override it. Here's a+ complete example:++ account assets ; type: Asset+ account assets:bank ; type: Cash+ account assets:cash ; type: Cash+ account liabilities ; type: Liability+ account equity ; type: Equity+ account revenues ; type: Revenue+ account expenses ; type: Expense++ Auto-detected account types+ If you happen to use common english top-level account names, you may+ not need to declare account types, as they will be detected automati-+ cally using the following rules:++ If account's name matches this regular expression: | its type is:+ ------------------------------------------------------------------- | ------------+ ^assets?(:|$) |+ and does not contain regexp (investment|receivable|:A/R|:fixed) | Cash+ otherwise | Asset+ ^(debts?|liabilit(y|ies))(:|$) | Liability+ ^equity(:|$) | Equity+ ^(income|revenue)s?(:|$) | Revenue+ ^expenses?(:|$) | Expense++ Even so, explicit declarations may be a good idea, for clarity and pre-+ dictability.++ Interference from auto-detected account types+ If you assign any account type, it's a good idea to assign all of them,+ to prevent any confusion from mixing declared and auto-detected types.+ Although it's unlikely to happen in real life, here's an example: with+ the following journal, balancesheetequity shows "liabilities" in both+ Liabilities and Equity sections. Declaring another account as+ type:Liability would fix it:++ account liabilities ; type:Equity++ 2020-01-01+ assets 1+ liabilities 1+ equity -2++ Old account type syntax+ In some hledger journals you might instead see this old syntax (the+ letters ALERX, separated from the account name by two or more spaces);+ this is deprecated and may be removed soon:++ account assets A+ account liabilities L+ account equity E+ account revenues R+ account expenses X++ Account display order+ Account directives also set the order in which accounts are displayed,+ eg in reports, the hledger-ui accounts screen, and the hledger-web+ sidebar. By default accounts are listed in alphabetical order. But if+ you have these account directives in the journal:++ account assets+ account liabilities+ account equity+ account revenues+ account expenses++ you'll see those accounts displayed in declaration order, not alphabet-+ ically:++ $ hledger accounts -1+ assets+ liabilities+ equity+ revenues+ expenses++ Undeclared accounts, if any, are displayed last, in alphabetical order.++ Note that sorting is done at each level of the account tree (within+ each group of sibling accounts under the same parent). And currently,+ this directive:++ account other:zoo++ would influence the position of zoo among other's subaccounts, but not+ the position of other among the top-level accounts. This means:++ o you will sometimes declare parent accounts (eg account other above)+ that you don't intend to post to, just to customize their display+ order++ o sibling accounts stay together (you couldn't display x:y in between+ a:b and a:c).++ Rewriting accounts+ You can define account alias rules which rewrite your account names, or+ parts of them, before generating reports. This can be useful for:++ o expanding shorthand account names to their full form, allowing easier+ data entry and a less verbose journal++ o adapting old journals to your current chart of accounts++ o experimenting with new account organisations, like a new hierarchy or+ combining two accounts into one++ o customising reports++ Account aliases also rewrite account names in account directives. They+ do not affect account names being entered via hledger add or hledger-+ web.++ See also Rewrite account names.++ Basic aliases+ To set an account alias, use the alias directive in your journal file.+ This affects all subsequent journal entries in the current file or its+ included files (but note: not sibling or parent files). The spaces+ around the = are optional:++ alias OLD = NEW++ Or, you can use the --alias 'OLD=NEW' option on the command line. This+ affects all entries. It's useful for trying out aliases interactively.++ OLD and NEW are case sensitive full account names. hledger will+ replace any occurrence of the old account name with the new one. Sub-+ accounts are also affected. Eg:++ alias checking = assets:bank:wells fargo:checking+ ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"++ Regex aliases+ There is also a more powerful variant that uses a regular expression,+ indicated by the forward slashes:++ alias /REGEX/ = REPLACEMENT++ or --alias '/REGEX/=REPLACEMENT'.++ REGEX is a case-insensitive regular expression. Anywhere it matches+ inside an account name, the matched part will be replaced by REPLACE-+ MENT. If REGEX contains parenthesised match groups, these can be ref-+ erenced by the usual numeric backreferences in REPLACEMENT. Eg:++ alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3+ ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"++ Also note that REPLACEMENT continues to the end of line (or on command+ line, to end of option argument), so it can contain trailing white-+ space.++ Combining aliases+ You can define as many aliases as you like, using journal directives+ and/or command line options.++ Recursive aliases - where an account name is rewritten by one alias,+ then by another alias, and so on - are allowed. Each alias sees the+ effect of previously applied aliases.++ In such cases it can be important to understand which aliases will be+ applied and in which order. For (each account name in) each journal+ entry, we apply:++ 1. alias directives preceding the journal entry, most recently parsed+ first (ie, reading upward from the journal entry, bottom to top)++ 2. --alias options, in the order they appeared on the command line+ (left to right).++ In other words, for (an account name in) a given journal entry:++ o the nearest alias declaration before/above the entry is applied first++ o the next alias before/above that will be be applied next, and so on++ o aliases defined after/below the entry do not affect it.++ This gives nearby aliases precedence over distant ones, and helps pro-+ vide semantic stability - aliases will keep working the same way inde-+ pendent of which files are being read and in which order.++ In case of trouble, adding --debug=6 to the command line will show+ which aliases are being applied when.++ Aliases and multiple files+ As explained at Directives and multiple files, alias directives do not+ affect parent or sibling files. Eg in this command,++ hledger -f a.aliases -f b.journal++ account aliases defined in a.aliases will not affect b.journal.+ Including the aliases doesn't work either:++ include a.aliases++ 2020-01-01 ; not affected by a.aliases+ foo 1+ bar++ This means that account aliases should usually be declared at the start+ of your top-most file, like this:++ alias foo=Foo+ alias bar=Bar++ 2020-01-01 ; affected by aliases above+ foo 1+ bar++ include c.journal ; also affected++ end aliases+ You can clear (forget) all currently defined aliases with the end+ aliases directive:++ end aliases++ Default parent account+ You can specify a parent account which will be prepended to all+ accounts within a section of the journal. Use the apply account and+ end apply account directives like so:++ apply account home++ 2010/1/1+ food $10+ cash++ end apply account++ which is equivalent to:++ 2010/01/01+ home:food $10+ home:cash $-10++ If end apply account is omitted, the effect lasts to the end of the+ file. Included files are also affected, eg:++ apply account business+ include biz.journal+ end apply account+ apply account personal+ include personal.journal++ Prior to hledger 1.0, legacy account and end spellings were also sup-+ ported.++ A default parent account also affects account directives. It does not+ affect account names being entered via hledger add or hledger-web. If+ account aliases are present, they are applied after the default parent+ account.++ Periodic transactions+ Periodic transaction rules describe transactions that recur. They+ allow hledger to generate temporary future transactions to help with+ forecasting, so you don't have to write out each one in the journal,+ and it's easy to try out different forecasts.++ Periodic transactions can be a little tricky, so before you use them,+ read this whole section - or at least these tips:++ 1. Two spaces accidentally added or omitted will cause you trouble -+ read about this below.++ 2. For troubleshooting, show the generated transactions with hledger+ print --forecast tag:generated or hledger register --forecast+ tag:generated.++ 3. Forecasted transactions will begin only after the last non-fore-+ casted transaction's date.++ 4. Forecasted transactions will end 6 months from today, by default.+ See below for the exact start/end rules.++ 5. period expressions can be tricky. Their documentation needs+ improvement, but is worth studying.++ 6. Some period expressions with a repeating interval must begin on a+ natural boundary of that interval. Eg in weekly from DATE, DATE+ must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an+ error.++ 7. Other period expressions with an interval are automatically expanded+ to cover a whole number of that interval. (This is done to improve+ reports, but it also affects periodic transactions. Yes, it's a bit+ inconsistent with the above.) Eg: ~ every 10th day of month from+ 2020/01, which is equivalent to ~ every 10th day of month from+ 2020/01/01, will be adjusted to start on 2019/12/10.++ Periodic transaction rules also have a second meaning: they are used to+ define budget goals, shown in budget reports.++ Periodic rule syntax+ A periodic transaction rule looks like a normal journal entry, with the+ date replaced by a tilde (~) followed by a period expression (mnemonic:+ ~ looks like a recurring sine wave.):++ ~ monthly+ expenses:rent $2000+ assets:bank:checking++ There is an additional constraint on the period expression: the start+ date must fall on a natural boundary of the interval. Eg monthly from+ 2018/1/1 is valid, but monthly from 2018/1/15 is not.++ Partial or relative dates (M/D, D, tomorrow, last week) in the period+ expression can work (useful or not). They will be relative to today's+ date, unless a Y default year directive is in effect, in which case+ they will be relative to Y/1/1.++ Two spaces between period expression and description!+ If the period expression is followed by a transaction description,+ these must be separated by two or more spaces. This helps hledger know+ where the period expression ends, so that descriptions can not acciden-+ tally alter their meaning, as in this example:++ ; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020"+ ; ||+ ; vv+ ~ every 2 months in 2020, we will review+ assets:bank:checking $1500+ income:acme inc++ So,++ o Do write two spaces between your period expression and your transac-+ tion description, if any.++ o Don't accidentally write two spaces in the middle of your period+ expression.++ Forecasting with periodic transactions+ The --forecast flag activates any periodic transaction rules in the+ journal. They will generate temporary recurring transactions, which+ are not saved in the journal, but will appear in all reports (eg+ print). This can be useful for estimating balances into the future, or+ experimenting with different scenarios. Or, it can be used as a data+ entry aid: describe recurring transactions, and every so often copy the+ output of print --forecast into the journal.++ These transactions will have an extra tag indicating which periodic+ rule generated them: generated-transaction:~ PERIODICEXPR. And a simi-+ lar, hidden tag (beginning with an underscore) which, because it's+ never displayed by print, can be used to match transactions generated+ "just now": _generated-transaction:~ PERIODICEXPR.++ Periodic transactions are generated within some forecast period. By+ default, this++ o begins on the later of++ o the report start date if specified with -b/-p/date:++ o the day after the latest normal (non-periodic) transaction in the+ journal, or today if there are no normal transactions.++ o ends on the report end date if specified with -e/-p/date:, or 6+ months (180 days) from today.++ This means that periodic transactions will begin only after the latest+ recorded transaction. And a recorded transaction dated in the future+ can prevent generation of periodic transactions. (You can avoid that+ by writing the future transaction as a one-time periodic rule instead -+ put tilde before the date, eg ~ YYYY-MM-DD ...).++ Or, you can set your own arbitrary "forecast period", which can overlap+ recorded transactions, and need not be in the future, by providing an+ option argument, like --forecast=PERIODEXPR. Note the equals sign is+ required, a space won't work. PERIODEXPR is a period expression, which+ can specify the start date, end date, or both, like in a date: query.+ (See also hledger.1 -> Report start & end date). Some examples:+ --forecast=202001-202004, --forecast=jan-, --forecast=2020.++ Budgeting with periodic transactions+ With the --budget flag, currently supported by the balance command,+ each periodic transaction rule declares recurring budget goals for the+ specified accounts. Eg the first example above declares a goal of+ spending $2000 on rent (and also, a goal of depositing $2000 into+ checking) every month. Goals and actual performance can then be com-+ pared in budget reports.++ See also: Budgeting and Forecasting.+++ Auto postings+ "Automated postings" or "auto postings" are extra postings which get+ added automatically to transactions which match certain queries,+ defined by "auto posting rules", when you use the --auto flag.++ An auto posting rule looks a bit like a transaction:++ = QUERY+ ACCOUNT AMOUNT+ ...+ ACCOUNT [AMOUNT]++ except the first line is an equals sign (mnemonic: = suggests match-+ ing), followed by a query (which matches existing postings), and each+ "posting" line describes a posting to be generated, and the posting+ amounts can be:++ o a normal amount with a commodity symbol, eg $2. This will be used+ as-is.++ o a number, eg 2. The commodity symbol (if any) from the matched post-+ ing will be added to this.++ o a numeric multiplier, eg *2 (a star followed by a number N). The+ matched posting's amount (and total price, if any) will be multiplied+ by N.++ o a multiplier with a commodity symbol, eg *$2 (a star, number N, and+ symbol S). The matched posting's amount will be multiplied by N, and+ its commodity symbol will be replaced with S.++ Any query term containing spaces must be enclosed in single or double+ quotes, as on the command line. Eg, note the quotes around the second+ query term below:++ = expenses:groceries 'expenses:dining out'+ (budget:funds:dining out) *-1++ Some examples:++ ; every time I buy food, schedule a dollar donation+ = expenses:food+ (liabilities:charity) $-1++ ; when I buy a gift, also deduct that amount from a budget envelope subaccount+ = expenses:gifts+ assets:checking:gifts *-1+ assets:checking *1++ 2017/12/1+ expenses:food $10+ assets:checking++ 2017/12/14+ expenses:gifts $20+ assets:checking++ $ hledger print --auto+ 2017-12-01+ expenses:food $10+ assets:checking+ (liabilities:charity) $-1++ 2017-12-14+ expenses:gifts $20+ assets:checking+ assets:checking:gifts -$20+ assets:checking $20++ Auto postings and multiple files+ An auto posting rule can affect any transaction in the current file, or+ in any parent file or child file. Note, currently it will not affect+ sibling files (when multiple -f/--file are used - see #1212).++ Auto postings and dates+ A posting date (or secondary date) in the matched posting, or (taking+ precedence) a posting date in the auto posting rule itself, will also+ be used in the generated posting.++ Auto postings and transaction balancing / inferred amounts / balance asser-+ tions+ Currently, auto postings are added:++ o after missing amounts are inferred, and transactions are checked for+ balancedness,++ o but before balance assertions are checked.++ Note this means that journal entries must be balanced both before and+ after auto postings are added. This changed in hledger 1.12+; see #893+ for background.++ Auto posting tags+ Automated postings will have some extra tags:++ o generated-posting:= QUERY - shows this was generated by an auto post-+ ing rule, and the query++ o _generated-posting:= QUERY - a hidden tag, which does not appear in+ hledger's output. This can be used to match postings generated "just+ now", rather than generated in the past and saved to the journal.++ Also, any transaction that has been changed by auto posting rules will+ have these tags added:++ o modified: - this transaction was modified++ o _modified: - a hidden tag not appearing in the comment; this transac-+ tion was modified "just now".++CSV FORMAT+ How hledger reads CSV data, and the CSV rules file format.++ hledger can read CSV files (Character Separated Value - usually comma,+ semicolon, or tab) containing dated records as if they were journal+ files, automatically converting each CSV record into a transaction.++ (To learn about writing CSV, see CSV output.)++ We describe each CSV file's format with a corresponding rules file. By+ default this is named like the CSV file with a .rules extension added.+ Eg when reading FILE.csv, hledger also looks for FILE.csv.rules in the+ same directory as FILE.csv. You can specify a different rules file+ with the --rules-file option. If a rules file is not found, hledger+ will create a sample rules file, which you'll need to adjust.++ This file contains rules describing the CSV data (header line, fields+ layout, date format etc.), and how to construct hledger journal entries+ (transactions) from it. Often there will also be a list of conditional+ rules for categorising transactions based on their descriptions.+ Here's an overview of the CSV rules; these are described more fully+ below, after the examples:+++ skip skip one or more header lines or matched CSV+ records+ fields list name CSV fields, assign them to hledger+ fields+ field assignment assign a value to one hledger field, with+ interpolation+ Field names hledger field names, used in the fields list+ and field assignments+ separator a custom field separator++ if block apply some rules to CSV records matched by+ patterns+ if table apply some rules to CSV records matched by+ patterns, alternate syntax+ end skip the remaining CSV records+ date-format how to parse dates in CSV records+ decimal-mark the decimal mark used in CSV amounts, if+ ambiguous+ newest-first disambiguate record order when there's only+ one date+ include inline another CSV rules file+ balance-type choose which type of balance assignments to+ use++ Note, for best error messages when reading CSV files, use a .csv, .tsv+ or .ssv file extension or file prefix - see File Extension below.++ There's an introductory Convert CSV files tutorial on hledger.org.++ Examples+ Here are some sample hledger CSV rules files. See also the full col-+ lection at:+ https://github.com/simonmichael/hledger/tree/master/examples/csv++ Basic+ At minimum, the rules file must identify the date and amount fields,+ and often it also specifies the date format and how many header lines+ there are. Here's a simple CSV file and a rules file for it:++ Date, Description, Id, Amount+ 12/11/2019, Foo, 123, 10.23++ # basic.csv.rules+ skip 1+ fields date, description, _, amount+ date-format %d/%m/%Y++ $ hledger print -f basic.csv+ 2019-11-12 Foo+ expenses:unknown 10.23+ income:unknown -10.23++ Default account names are chosen, since we didn't set them.++ Bank of Ireland+ Here's a CSV with two amount fields (Debit and Credit), and a balance+ field, which we can use to add balance assertions, which is not neces-+ sary but provides extra error checking:++ Date,Details,Debit,Credit,Balance+ 07/12/2012,LODGMENT 529898,,10.0,131.21+ 07/12/2012,PAYMENT,5,,126++ # bankofireland-checking.csv.rules++ # skip the header line+ skip++ # name the csv fields, and assign some of them as journal entry fields+ fields date, description, amount-out, amount-in, balance++ # We generate balance assertions by assigning to "balance"+ # above, but you may sometimes need to remove these because:+ #+ # - the CSV balance differs from the true balance,+ # by up to 0.0000000000005 in my experience+ #+ # - it is sometimes calculated based on non-chronological ordering,+ # eg when multiple transactions clear on the same day++ # date is in UK/Ireland format+ date-format %d/%m/%Y++ # set the currency+ currency EUR++ # set the base account for all txns+ account1 assets:bank:boi:checking++ $ hledger -f bankofireland-checking.csv print+ 2012-12-07 LODGMENT 529898+ assets:bank:boi:checking EUR10.0 = EUR131.2+ income:unknown EUR-10.0++ 2012-12-07 PAYMENT+ assets:bank:boi:checking EUR-5.0 = EUR126.0+ expenses:unknown EUR5.0++ The balance assertions don't raise an error above, because we're read-+ ing directly from CSV, but they will be checked if these entries are+ imported into a journal file.++ Amazon+ Here we convert amazon.com order history, and use an if block to gener-+ ate a third posting if there's a fee. (In practice you'd probably get+ this data from your bank instead, but it's an example.)++ "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"+ "Jul 29, 2012","Payment","To","Foo.","Completed","$20.00","$0.00","16000000000000DGLNJPI1P9B8DKPVHL"+ "Jul 30, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$1.00","17LA58JSKRD4HDGLNJPI1P9B8DKPVHL"++ # amazon-orders.csv.rules++ # skip one header line+ skip 1++ # name the csv fields, and assign the transaction's date, amount and code.+ # Avoided the "status" and "amount" hledger field names to prevent confusion.+ fields date, _, toorfrom, name, amzstatus, amzamount, fees, code++ # how to parse the date+ date-format %b %-d, %Y++ # combine two fields to make the description+ description %toorfrom %name++ # save the status as a tag+ comment status:%amzstatus++ # set the base account for all transactions+ account1 assets:amazon+ # leave amount1 blank so it can balance the other(s).+ # I'm assuming amzamount excludes the fees, don't remember++ # set a generic account2+ account2 expenses:misc+ amount2 %amzamount+ # and maybe refine it further:+ #include categorisation.rules++ # add a third posting for fees, but only if they are non-zero.+ if %fees [1-9]+ account3 expenses:fees+ amount3 %fees++ $ hledger -f amazon-orders.csv print+ 2012-07-29 (16000000000000DGLNJPI1P9B8DKPVHL) To Foo. ; status:Completed+ assets:amazon+ expenses:misc $20.00++ 2012-07-30 (17LA58JSKRD4HDGLNJPI1P9B8DKPVHL) To Adapteva, Inc. ; status:Completed+ assets:amazon+ expenses:misc $25.00+ expenses:fees $1.00++ Paypal+ Here's a real-world rules file for (customised) Paypal CSV, with some+ Paypal-specific rules, and a second rules file included:++ "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"+ "10/01/2019","03:46:20","PDT","Calm Radio","Subscription Payment","Completed","USD","-6.99","0.00","-6.99","simon@joyful.com","memberships@calmradio.com","60P57143A8206782E","MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month","","I-R8YLY094FJYR","","-6.99",""+ "10/01/2019","03:46:20","PDT","","Bank Deposit to PP Account ","Pending","USD","6.99","0.00","6.99","","simon@joyful.com","0TU1544T080463733","","","60P57143A8206782E","","0.00",""+ "10/01/2019","08:57:01","PDT","Patreon","PreApproved Payment Bill User Payment","Completed","USD","-7.00","0.00","-7.00","simon@joyful.com","support@patreon.com","2722394R5F586712G","Patreon* Membership","","B-0PG93074E7M86381M","","-7.00",""+ "10/01/2019","08:57:01","PDT","","Bank Deposit to PP Account ","Pending","USD","7.00","0.00","7.00","","simon@joyful.com","71854087RG994194F","Patreon* Membership","","2722394R5F586712G","","0.00",""+ "10/19/2019","03:02:12","PDT","Wikimedia Foundation, Inc.","Subscription Payment","Completed","USD","-2.00","0.00","-2.00","simon@joyful.com","tle@wikimedia.org","K9U43044RY432050M","Monthly donation to the Wikimedia Foundation","","I-R5C3YUS3285L","","-2.00",""+ "10/19/2019","03:02:12","PDT","","Bank Deposit to PP Account ","Pending","USD","2.00","0.00","2.00","","simon@joyful.com","3XJ107139A851061F","","","K9U43044RY432050M","","0.00",""+ "10/22/2019","05:07:06","PDT","Noble Benefactor","Subscription Payment","Completed","USD","10.00","-0.59","9.41","noble@bene.fac.tor","simon@joyful.com","6L8L1662YP1334033","Joyful Systems","","I-KC9VBGY2GWDB","","9.41",""++ # paypal-custom.csv.rules++ # Tips:+ # Export from Activity -> Statements -> Custom -> Activity download+ # Suggested transaction type: "Balance affecting"+ # Paypal's default fields in 2018 were:+ # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Shipping Address","Address Status","Item Title","Item ID","Shipping and Handling Amount","Insurance Amount","Sales Tax","Option 1 Name","Option 1 Value","Option 2 Name","Option 2 Value","Reference Txn ID","Invoice Number","Custom Number","Quantity","Receipt ID","Balance","Address Line 1","Address Line 2/District/Neighborhood","Town/City","State/Province/Region/County/Territory/Prefecture/Republic","Zip/Postal Code","Country","Contact Phone Number","Subject","Note","Country Code","Balance Impact"+ # This rules file assumes the following more detailed fields, configured in "Customize report fields":+ # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"++ fields date, time, timezone, description_, type, status_, currency, grossamount, feeamount, netamount, fromemail, toemail, code, itemtitle, itemid, referencetxnid, receiptid, balance, note++ skip 1++ date-format %-m/%-d/%Y++ # ignore some paypal events+ if+ In Progress+ Temporary Hold+ Update to+ skip++ # add more fields to the description+ description %description_ %itemtitle++ # save some other fields as tags+ comment itemid:%itemid, fromemail:%fromemail, toemail:%toemail, time:%time, type:%type, status:%status_++ # convert to short currency symbols+ if %currency USD+ currency $+ if %currency EUR+ currency E+ if %currency GBP+ currency P++ # generate postings++ # the first posting will be the money leaving/entering my paypal account+ # (negative means leaving my account, in all amount fields)+ account1 assets:online:paypal+ amount1 %netamount++ # the second posting will be money sent to/received from other party+ # (account2 is set below)+ amount2 -%grossamount++ # if there's a fee, add a third posting for the money taken by paypal.+ if %feeamount [1-9]+ account3 expenses:banking:paypal+ amount3 -%feeamount+ comment3 business:++ # choose an account for the second posting++ # override the default account names:+ # if the amount is positive, it's income (a debit)+ if %grossamount ^[^-]+ account2 income:unknown+ # if negative, it's an expense (a credit)+ if %grossamount ^-+ account2 expenses:unknown++ # apply common rules for setting account2 & other tweaks+ include common.rules++ # apply some overrides specific to this csv++ # Transfers from/to bank. These are usually marked Pending,+ # which can be disregarded in this case.+ if+ Bank Account+ Bank Deposit to PP Account+ description %type for %referencetxnid %itemtitle+ account2 assets:bank:wf:pchecking+ account1 assets:online:paypal++ # Currency conversions+ if Currency Conversion+ account2 equity:currency conversion++ # common.rules++ if+ darcs+ noble benefactor+ account2 revenues:foss donations:darcshub+ comment2 business:++ if+ Calm Radio+ account2 expenses:online:apps++ if+ electronic frontier foundation+ Patreon+ wikimedia+ Advent of Code+ account2 expenses:dues++ if Google+ account2 expenses:online:apps+ description google | music++ $ hledger -f paypal-custom.csv print+ 2019-10-01 (60P57143A8206782E) Calm Radio MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month ; itemid:, fromemail:simon@joyful.com, toemail:memberships@calmradio.com, time:03:46:20, type:Subscription Payment, status:Completed+ assets:online:paypal $-6.99 = $-6.99+ expenses:online:apps $6.99++ 2019-10-01 (0TU1544T080463733) Bank Deposit to PP Account for 60P57143A8206782E ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:46:20, type:Bank Deposit to PP Account, status:Pending+ assets:online:paypal $6.99 = $0.00+ assets:bank:wf:pchecking $-6.99++ 2019-10-01 (2722394R5F586712G) Patreon Patreon* Membership ; itemid:, fromemail:simon@joyful.com, toemail:support@patreon.com, time:08:57:01, type:PreApproved Payment Bill User Payment, status:Completed+ assets:online:paypal $-7.00 = $-7.00+ expenses:dues $7.00++ 2019-10-01 (71854087RG994194F) Bank Deposit to PP Account for 2722394R5F586712G Patreon* Membership ; itemid:, fromemail:, toemail:simon@joyful.com, time:08:57:01, type:Bank Deposit to PP Account, status:Pending+ assets:online:paypal $7.00 = $0.00+ assets:bank:wf:pchecking $-7.00++ 2019-10-19 (K9U43044RY432050M) Wikimedia Foundation, Inc. Monthly donation to the Wikimedia Foundation ; itemid:, fromemail:simon@joyful.com, toemail:tle@wikimedia.org, time:03:02:12, type:Subscription Payment, status:Completed+ assets:online:paypal $-2.00 = $-2.00+ expenses:dues $2.00+ expenses:banking:paypal ; business:++ 2019-10-19 (3XJ107139A851061F) Bank Deposit to PP Account for K9U43044RY432050M ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:02:12, type:Bank Deposit to PP Account, status:Pending+ assets:online:paypal $2.00 = $0.00+ assets:bank:wf:pchecking $-2.00++ 2019-10-22 (6L8L1662YP1334033) Noble Benefactor Joyful Systems ; itemid:, fromemail:noble@bene.fac.tor, toemail:simon@joyful.com, time:05:07:06, type:Subscription Payment, status:Completed+ assets:online:paypal $9.41 = $9.41+ revenues:foss donations:darcshub $-10.00 ; business:+ expenses:banking:paypal $0.59 ; business:++ CSV rules+ The following kinds of rule can appear in the rules file, in any order.+ Blank lines and lines beginning with # or ; are ignored.++ skip+ skip N++ The word "skip" followed by a number (or no number, meaning 1) tells+ hledger to ignore this many non-empty lines preceding the CSV data.+ (Empty/blank lines are skipped automatically.) You'll need this when-+ ever your CSV data contains header lines.++ It also has a second purpose: it can be used inside if blocks to ignore+ certain CSV records (described below).++ fields list+ fields FIELDNAME1, FIELDNAME2, ...++ A fields list (the word "fields" followed by comma-separated field+ names) is the quick way to assign CSV field values to hledger fields.+ (The other way is field assignments, see below.) A fields list does+ does two things:++ 1. It names the CSV fields. This is optional, but can be convenient+ later for interpolating them.++ 2. Whenever you use a standard hledger field name (defined below), the+ CSV value is assigned to that part of the hledger transaction.++ Here's an example that says "use the 1st, 2nd and 4th fields as the+ transaction's date, description and amount; name the last two fields+ for later reference; and ignore the others":++ fields date, description, , amount, , , somefield, anotherfield++ Tips:++ o The fields list always use commas, even if your CSV data uses another+ separator character.++ o Currently there must be least two items in the list (at least one+ comma).++ o Field names may not contain spaces. Spaces before/after field names+ are optional.++ o If the CSV contains column headings, it's a good idea to use these,+ suitably modified, as the basis for your field names (eg lower-cased,+ with underscores instead of spaces).++ o If some heading names match standard hledger fields, but you don't+ want to set the hledger fields directly, alter those names, eg by+ appending an underscore.++ o Fields you don't care about can be given a dummy name (eg: _ ), or no+ name.++ field assignment+ HLEDGERFIELDNAME FIELDVALUE++ Field assignments are the more flexible way to assign CSV values to+ hledger fields. They can be used instead of or in addition to a fields+ list (see above).++ 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-+ FIELDNAME).++ Some examples:++ # set the amount to the 4th CSV field, with " USD" appended+ amount %4 USD++ # combine three fields to make a comment, containing note: and date: tags+ comment note: %somefield - %anotherfield, date: %1++ Tips:++ o Interpolation strips outer whitespace (so a CSV value like " 1 "+ becomes 1 when interpolated) (#1051).++ o See also Tips below.++ Field names+ Here are the standard hledger field (and pseudo-field) names, which you+ can use in a fields list and in field assignments. For more about the+ transaction parts they refer to, see Transactions.++ date field+ Assigning to date sets the transaction date.++ date2 field+ date2 sets the transaction's secondary date, if any.++ status field+ status sets the transaction's status, if any.++ code field+ code sets the transaction's code, if any.++ description field+ description sets the transaction's description, if any.++ comment field+ comment sets the transaction's comment, if any.++ commentN, where N is a number, sets the Nth posting's comment.++ Tips: - Only single-line comments can be assigned. - Comments can con-+ tain tags, as usual.++ account field+ 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+ each transaction's description, and in conditional blocks.++ If a posting's account name is left unset but its amount is set (see+ below), a default account name will be chosen (like "expenses:unknown"+ or "income:unknown").++ amount field+ amountN sets the amount of the Nth posting, and causes that posting to+ be generated. By assigning to amount1, amount2, ... etc. you can+ generate up to 99 postings.++ amountN-in and amountN-out can be used instead, if the CSV uses sepa-+ rate fields for debits and credits (inflows and outflows). hledger+ assumes both of these CSV fields are unsigned, and will automatically+ negate the "-out" value. If they are signed, see "Setting amounts"+ below.++ amount, or amount-in and amount-out are a legacy mode, to keep pre-+ hledger-1.17 CSV rules files working (and for occasional convenience).+ They are suitable only for two-posting transactions; they set both+ posting 1's and posting 2's amount. Posting 2's amount will be+ negated, and also converted to cost if there's a transaction price.++ If you have an existing rules file using the unnumbered form, you might+ want to use the numbered form in certain conditional blocks, without+ having to update and retest all the old rules. To facilitate this,+ posting 1 ignores amount/amount-in/amount-out if any of+ amount1/amount1-in/amount1-out are assigned, and posting 2 ignores them+ if any of amount2/amount2-in/amount2-out are assigned, avoiding con-+ flicts.++ currency field+ currency sets a currency symbol, to be prepended to all postings'+ amounts. You can use this if the CSV amounts do not have a currency+ symbol, eg if it is in a separate column.++ currencyN prepends a currency symbol to just the Nth posting's amount.++ balance field+ balanceN sets a balance assertion amount (or if the posting amount is+ left empty, a balance assignment) on posting N.++ 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+ rule (see below).++ See Tips below for more about setting amounts and currency.++ separator+ You can use the separator rule to read other kinds of character-sepa-+ rated data. The argument is any single separator character, or the+ words tab or space (case insensitive). Eg, for comma-separated values+ (CSV):++ separator ,++ or for semicolon-separated values (SSV):++ separator ;++ or for tab-separated values (TSV):++ separator TAB++ If the input file has a .csv, .ssv or .tsv file extension (or a csv:,+ ssv:, tsv: prefix), the appropriate separator will be inferred automat-+ ically, and you won't need this rule.++ if block+ if MATCHER+ RULE++ if+ MATCHER+ MATCHER+ MATCHER+ RULE+ RULE++ Conditional blocks ("if blocks") are a block of rules that are applied+ only to CSV records which match certain patterns. They are often used+ for customising account names based on transaction descriptions.++ Matching the whole record+ Each MATCHER can be a record matcher, which looks like this:++ REGEX++ REGEX is a case-insensitive regular expression that tries to match any-+ where within the CSV record. It is a POSIX ERE (extended regular+ expression) that also supports GNU word boundaries (\b, \B, \<, \>),+ and nothing else. If you have trouble, be sure to check our doc:+ https://hledger.org/hledger.html#regular-expressions++ Important note: the record that is matched is not the original record,+ but a synthetic one, with any enclosing double quotes (but not enclos-+ ing whitespace) removed, and always comma-separated (which means that a+ field containing a comma will appear like two fields). Eg, if the+ original record is 2020-01-01; "Acme, Inc."; 1,000, the REGEX will+ actually see 2020-01-01,Acme, Inc., 1,000).++ Matching individual fields+ Or, MATCHER can be a field matcher, like this:++ %CSVFIELD REGEX++ which matches just the content of a particular CSV field. CSVFIELD is+ a percent sign followed by the field's name or column number, like+ %date or %1.++ Combining matchers+ A single matcher can be written on the same line as the "if"; or multi-+ ple matchers can be written on the following lines, non-indented. Mul-+ tiple matchers are OR'd (any one of them can match), unless one begins+ with an & symbol, in which case it is AND'ed with the previous matcher.++ if+ MATCHER+ & MATCHER+ RULE++ Rules applied on successful match+ After the patterns there should be one or more rules to apply, all+ indented by at least one space. Three kinds of rule are allowed in+ conditional blocks:++ o field assignments (to set a hledger field)++ o skip (to skip the matched CSV record)++ o end (to skip all remaining CSV records).++ Examples:++ # if the CSV record contains "groceries", set account2 to "expenses:groceries"+ if groceries+ account2 expenses:groceries++ # if the CSV record contains any of these patterns, set account2 and comment as shown+ if+ monthly service fee+ atm transaction fee+ banking thru software+ account2 expenses:business:banking+ comment XXX deductible ? check it++ if table+ if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn+ MATCHER1,VALUE11,VALUE12,...,VALUE1n+ MATCHER2,VALUE21,VALUE22,...,VALUE2n+ MATCHER3,VALUE31,VALUE32,...,VALUE3n+ <empty line>++ Conditional tables ("if tables") are a different syntax to specify+ field assignments that will be applied only to CSV records which match+ certain patterns.++ MATCHER could be either field or record matcher, as described above.+ When MATCHER matches, values from that row would be assigned to the CSV+ fields named on the if line, in the same order.++ Therefore if table is exactly equivalent to a sequence of of if blocks:++ if MATCHER1+ CSVFIELDNAME1 VALUE11+ CSVFIELDNAME2 VALUE12+ ...+ CSVFIELDNAMEn VALUE1n++ if MATCHER2+ CSVFIELDNAME1 VALUE21+ CSVFIELDNAME2 VALUE22+ ...+ CSVFIELDNAMEn VALUE2n++ if MATCHER3+ CSVFIELDNAME1 VALUE31+ CSVFIELDNAME2 VALUE32+ ...+ CSVFIELDNAMEn VALUE3n++ Each line starting with MATCHER should contain enough (possibly empty)+ values for all the listed fields.++ Rules would be checked and applied in the order they are listed in the+ table and, like with if blocks, later rules (in the same or another ta-+ ble) or if blocks could override the effect of any rule.++ Instead of ',' you can use a variety of other non-alphanumeric charac-+ ters as a separator. First character after if is taken to be the sepa-+ rator for the rest of the table. It is the responsibility of the user+ to ensure that separator does not occur inside MATCHERs and values -+ there is no way to escape separator.++ Example:++ if,account2,comment+ atm transaction fee,expenses:business:banking,deductible? check it+ %description groceries,expenses:groceries,+ 2020/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out++ end+ This rule can be used inside if blocks (only), to make hledger stop+ reading this CSV file and move on to the next input file, or to command+ execution. Eg:++ # ignore everything following the first empty record+ if ,,,,+ end++ date-format+ date-format DATEFMT++ This is a helper for the date (and date2) fields. If your CSV dates+ are not formatted like YYYY-MM-DD, YYYY/MM/DD or YYYY.MM.DD, you'll+ need to add a date-format rule describing them with a strptime date+ parsing pattern, which must parse the CSV date value completely. Some+ examples:++ # MM/DD/YY+ date-format %m/%d/%y++ # D/M/YYYY+ # The - makes leading zeros optional.+ date-format %-d/%-m/%Y++ # YYYY-Mmm-DD+ date-format %Y-%h-%d++ # M/D/YYYY HH:MM AM some other junk+ # Note the time and junk must be fully parsed, though only the date is used.+ date-format %-m/%-d/%Y %l:%M %p some other junk++ For the supported strptime syntax, see:+ https://hackage.haskell.org/package/time/docs/Data-Time-For-+ mat.html#v:formatTime++ Note that although you can parse date-times which include a time zone,+ that time zone is ignored; it will not change the date that is parsed.+ This means when reading CSV data with times not in your local time+ zone, dates can be "off by one".++ decimal-mark+ decimal-mark .++ or:++ decimal-mark ,++ hledger automatically accepts either period or comma as a decimal mark+ when parsing numbers (cf Amounts). However if any numbers in the CSV+ contain digit group marks, such as thousand-separating commas, you+ should declare the decimal mark explicitly with this rule, to avoid+ misparsed numbers.++ newest-first+ hledger always sorts the generated transactions by date. Transactions+ on the same date should appear in the same order as their CSV records,+ as hledger can usually auto-detect whether the CSV's normal order is+ oldest first or newest first. But if all of the following are true:++ o the CSV might sometimes contain just one day of data (all records+ having the same date)++ o the CSV records are normally in reverse chronological order (newest+ at the top)++ o and you care about preserving the order of same-day transactions++ then, you should add the newest-first rule as a hint. Eg:++ # tell hledger explicitly that the CSV is normally newest first+ newest-first++ include+ include RULESFILE++ This includes the contents of another CSV rules file at this point.+ RULESFILE is an absolute file path or a path relative to the current+ file's directory. This can be useful for sharing common rules between+ several rules files, eg:++ # someaccount.csv.rules++ ## someaccount-specific rules+ fields date,description,amount+ account1 assets:someaccount+ account2 expenses:misc++ ## common rules+ include categorisation.rules++ balance-type+ Balance assertions generated by assigning to balanceN are of the simple+ = type by default, which is a single-commodity, subaccount-excluding+ assertion. You may find the subaccount-including variants more useful,+ eg if you have created some virtual subaccounts of checking to help+ with budgeting. You can select a different type of assertion with the+ balance-type rule:++ # balance assertions will consider all commodities and all subaccounts+ balance-type ==*++ Here are the balance assertion types for quick reference:++ = single commodity, exclude subaccounts+ =* single commodity, include subaccounts+ == multi commodity, exclude subaccounts+ ==* multi commodity, include subaccounts++ Tips+ Rapid feedback+ It's a good idea to get rapid feedback while creating/troubleshooting+ CSV rules. Here's a good way, using entr from http://eradman.com/entr-+ project :++ $ ls foo.csv* | entr bash -c 'echo ----; hledger -f foo.csv print desc:SOMEDESC'++ A desc: query (eg) is used to select just one, or a few, transactions+ of interest. "bash -c" is used to run multiple commands, so we can+ echo a separator each time the command re-runs, making it easier to+ read the output.++ Valid CSV+ hledger accepts CSV conforming to RFC 4180. When CSV values are+ enclosed in quotes, note:++ o they must be double quotes (not single quotes)++ o spaces outside the quotes are not allowed++ File Extension+ To help hledger identify the format and show the right error messages,+ CSV/SSV/TSV files should normally be named with a .csv, .ssv or .tsv+ filename extension. Or, the file path should be prefixed with csv:,+ ssv: or tsv:. Eg:++ $ hledger -f foo.ssv print++ or:++ $ cat foo | hledger -f ssv:- foo++ You can override the file extension with a separator rule if needed.+ See also: Input files in the hledger manual.++ Reading multiple CSV files+ If you use multiple -f options to read multiple CSV files at once,+ hledger will look for a correspondingly-named rules file for each CSV+ file. But if you use the --rules-file option, that rules file will be+ used for all the CSV files.++ Valid transactions+ After reading a CSV file, hledger post-processes and validates the gen-+ erated journal entries as it would for a journal file - balancing them,+ applying balance assignments, and canonicalising amount styles. Any+ errors at this stage will be reported in the usual way, displaying the+ problem entry.++ There is one exception: balance assertions, if you have generated them,+ will not be checked, since normally these will work only when the CSV+ data is part of the main journal. If you do need to check balance+ assertions generated from CSV right away, pipe into another hledger:++ $ hledger -f file.csv print | hledger -f- print++ Deduplicating, importing+ When you download a CSV file periodically, eg to get your latest bank+ transactions, the new file may overlap with the old one, containing+ some of the same records.++ The import command will (a) detect the new transactions, and (b) append+ just those transactions to your main journal. It is idempotent, so you+ don't have to remember how many times you ran it or with which version+ of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This+ is the easiest way to import CSV data. Eg:++ # download the latest CSV files, then run this command.+ # Note, no -f flags needed here.+ $ hledger import *.csv [--dry]++ This method works for most CSV files. (Where records have a stable+ chronological order, and new records appear only at the new end.)++ A number of other tools and workflows, hledger-specific and otherwise,+ exist for converting, deduplicating, classifying and managing CSV data.+ See:++ o https://hledger.org -> sidebar -> real world setups++ o https://plaintextaccounting.org -> data import/conversion++ Setting amounts+ Some tips on using the amount-setting rules discussed above.++ Here are the ways to set a posting's amount:++ 1. If the CSV has a single amount field:+ Assign (via a fields list or a field assignment) to amountN. This sets+ the Nth posting's amount. N is usually 1 or 2 but can go up to 99.++ 2. If the CSV has separate amount fields for debit & credit (in & out):++ a. If both fields are unsigned:+ Assign to amountN-in and amountN-out. This sets posting N's amount+ to whichever of these has a non-zero value, and negates the "-out"+ value.++ b. If either field is signed (can contain a minus sign):+ Use a conditional rule to flip the sign (of non-empty values).+ Since hledger always negates amountN-out, if it was already nega-+ tive, we must undo that by negating once more (but only if the+ field is non-empty):++ fields date, description, amount1-in, amount1-out+ if %amount1-out [1-9]+ amount1-out -%amount1-out++ c. If both fields, or neither field, can contain a non-zero value:+ hledger normally expects exactly one of the fields to have a non-+ zero value. Eg, the amountN-in/amountN-out rules would reject+ value pairs like these:++ "", ""+ "0", "0"+ "1", "none"++ So, use smarter conditional rules to set the amount from the appro-+ priate field. Eg, these rules would make it use only the value+ containing non-zero digits, handling the above:++ fields date, description, in, out+ if %in [1-9]+ amount1 %in+ if %out [1-9]+ amount1 %out++ 3. If you are stuck with hledger <1.17, or you want posting 2's amount+ converted to cost:+ Assign to amount (or to amount-in and amount-out). (The old numberless+ syntax, which sets amount1 and amount2.)++ 4. If the CSV has the balance instead of the transaction amount:+ Assign to balanceN, which sets posting N's amount indirectly via a bal-+ ance assignment. (Old syntax: balance, equivalent to balance1.)++ o If hledger guesses the wrong default account name:+ When setting the amount via balance assertion, hledger may guess+ the wrong default account name. So, set the account name explic-+ itly, eg:++ fields date, description, balance1+ account1 assets:checking++ Amount signs+ There is some special handling for amount signs, to simplify parsing+ and sign-flipping:++ o If an amount value begins with a plus sign:+ that will be removed: +AMT becomes AMT++ o If an amount value is parenthesised:+ it will be de-parenthesised and sign-flipped: (AMT) becomes -AMT++ o If an amount value has two minus signs (or two sets of parentheses,+ or a minus sign and parentheses):+ they cancel out and will be removed: --AMT or -(AMT) becomes AMT++ o If an amount value contains just a sign (or just a set of parenthe-+ ses):+ that is removed, making it an empty value. "+" or "-" or "()" becomes+ "".++ Setting currency/commodity+ If the currency/commodity symbol is included in the CSV's amount+ field(s):++ 2020-01-01,foo,$123.00++ you don't have to do anything special for the commodity symbol, it will+ be assigned as part of the amount. Eg:++ fields date,description,amount++ 2020-01-01 foo+ expenses:unknown $123.00+ income:unknown $-123.00++ If the currency is provided as a separate CSV field:++ 2020-01-01,foo,USD,123.00++ You can assign that to the currency pseudo-field, which has the special+ effect of prepending itself to every amount in the transaction (on the+ left, with no separating space):++ fields date,description,currency,amount++ 2020-01-01 foo+ expenses:unknown USD123.00+ income:unknown USD-123.00++ Or, you can use a field assignment to construct the amount yourself,+ with more control. Eg to put the symbol on the right, and separated by+ a space:++ fields date,description,cur,amt+ amount %amt %cur++ 2020-01-01 foo+ expenses:unknown 123.00 USD+ income:unknown -123.00 USD++ Note we used a temporary field name (cur) that is not currency - that+ would trigger the prepending effect, which we don't want here.++ Amount decimal places+ Like amounts in a journal file, the amounts generated by CSV rules like+ 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+ 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+ hledger field:++ # Name the third CSV field "amount1"+ fields date,description,amount1++ # Set hledger's amount1 to the CSV amount1 field followed by USD+ amount1 %amount1 USD++ # Set comment to the CSV amount1 (not the amount1 assigned above)+ comment %amount1++ Here, since there's no CSV amount1 field, %amount1 will produce a lit-+ eral "amount1":++ fields date,description,csvamount+ amount1 %csvamount USD+ # Can't interpolate amount1 here+ comment %amount1++ When there are multiple field assignments to the same hledger field,+ only the last one takes effect. Here, comment's value will be be B, or+ C if "something" is matched, but never A:++ comment A+ comment B+ if something+ comment C++ How CSV rules are evaluated+ Here's how to think of CSV rules being evaluated (if you really need+ to). First,++ o include - all includes are inlined, from top to bottom, depth first.+ (At each include point the file is inlined and scanned for further+ includes, recursively, before proceeding.)++ Then "global" rules are evaluated, top to bottom. If a rule is+ repeated, the last one wins:++ o skip (at top level)++ o date-format++ o newest-first++ o fields - names the CSV fields, optionally sets up initial assignments+ to hledger fields++ Then for each CSV record in turn:++ o test all if blocks. If any of them contain a end rule, skip all+ remaining CSV records. Otherwise if any of them contain a skip rule,+ skip that many CSV records. If there are multiple matched skip+ rules, the first one wins.++ o collect all field assignments at top level and in matched if blocks.+ When there are multiple assignments for a field, keep only the last+ one.++ o compute a value for each hledger field - either the one that was+ assigned to it (and interpolate the %CSVFIELDNAME references), or a+ default++ o generate a synthetic hledger transaction from these values.++ This is all part of the CSV reader, one of several readers hledger can+ use to parse input files. When all files have been read successfully,+ the transactions are passed as input to whichever hledger command the+ user specified.++TIMECLOCK FORMAT+ The time logging format of timeclock.el, as read by hledger.++ hledger can read time logs in timeclock format. As with Ledger, these+ are (a subset of) timeclock.el's format, containing clock-in and clock-+ out entries as in the example below. The date is a simple date. The+ time format is HH:MM[:SS][+-ZZZZ]. Seconds and timezone are optional.+ The timezone, if present, must be four digits and is ignored (currently+ the time is always interpreted as a local time).++ i 2015/03/30 09:00:00 some:account name optional description after two spaces+ o 2015/03/30 09:20:00+ i 2015/03/31 22:21:45 another account+ o 2015/04/01 02:00:34++ hledger treats each clock-in/clock-out pair as a transaction posting+ some number of hours to an account. Or if the session spans more than+ one day, it is split into several transactions, one for each day. For+ the above time log, hledger print generates these journal entries:++ $ hledger -f t.timeclock print+ 2015-03-30 * optional description after two spaces+ (some:account name) 0.33h++ 2015-03-31 * 22:21-23:59+ (another account) 1.64h++ 2015-04-01 * 00:00-02:00+ (another account) 2.01h++ Here is a sample.timeclock to download and some queries to try:++ $ hledger -f sample.timeclock balance # current time balances+ $ hledger -f sample.timeclock register -p 2009/3 # sessions in march 2009+ $ hledger -f sample.timeclock register -p weekly --depth 1 --empty # time summary by week++ To generate time logs, ie to clock in and clock out, you could:++ o use emacs and the built-in timeclock.el, or the extended timeclock-+ x.el and perhaps the extras in ledgerutils.el++ o at the command line, use these bash aliases: shell alias ti="echo+ i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o+ `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"++ o or use the old ti and to scripts in the ledger 2.x repository. These+ rely on a "timeclock" executable which I think is just the ledger 2+ executable renamed.++TIMEDOT FORMAT+ 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+ this:++ 2021-08-04+ hom:errands .... ....+ fos:hledger:timedot .. ; docs+ per:admin:finance++ hledger reads this as three time transactions on this day, with each+ dot representing a quarter-hour spent:++ $ hledger -f a.timedot print # .timedot file extension activates the timedot reader+ 2021-08-04 *+ (hom:errands) 2.00++ 2021-08-04 *+ (fos:hledger:timedot) 0.50++ 2021-08-04 *+ (per:admin:finance) 0++ A day entry begins with a date line:++ o a non-indented simple date (Y-M-D, Y/M/D, or Y.M.D).++ Optionally this can be followed on the same line by++ o a common transaction description for this day++ o a common transaction comment for this day, after a semicolon (;).++ After the date line are zero or more optionally-indented time transac-+ tion lines, consisting of:++ o an account name - any word or phrase, usually a hledger-style account+ name.++ o two or more spaces - a field separator, required if there is an+ amount (as in journal format).++ o a timedot amount - dots representing quarter hours, or a number rep-+ resenting hours.++ o an optional comment beginning with semicolon. This is ignored.++ In more detail, timedot amounts can be:++ o dots: zero or more period characters, each representing one quarter-+ hour. Spaces are ignored and can be used for grouping. Eg: .... ..++ o a number, representing hours. Eg: 1.5++ o a number immediately followed by a unit symbol s, m, h, d, w, mo, or+ y, representing seconds, minutes, hours, days weeks, months or years.+ Eg 1.5h or 90m. The following equivalencies are assumed:+ 60s = 1m, 60m = 1h, 24h = 1d, 7d = 1w, 30d = 1mo, 365d = 1y. (This+ unit will not be visible in the generated transaction amount, which is+ always in hours.)++ There is some added flexibility to help with keeping time log data in+ the same file as your notes, todo lists, etc.:++ o Lines beginning with # or ;, and blank lines, are ignored.++ o Lines not ending with a double-space and amount are parsed as trans-+ actions with zero amount. (Most hledger reports hide these by+ default; add -E to see them.)++ o One or more stars (*) followed by a space, at the start of a line, is+ ignored. So date lines or time transaction lines can also be Org-+ mode headlines.++ o All Org-mode headlines before the first date line are ignored.++ More examples:++ # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.+ 2016/2/1+ inc:client1 .... .... .... .... .... ....+ fos:haskell .... ..+ biz:research .++ 2016/2/2+ inc:client1 .... ....+ biz:research .++ 2016/2/3+ inc:client1 4+ fos:hledger 3+ biz:research 1++ * Time log+ ** 2020-01-01+ *** adm:time .+ *** adm:finance .++ * 2020 Work Diary+ ** Q1+ *** 2020-02-29+ **** DONE+ 0700 yoga+ **** UNPLANNED+ **** BEGUN+ hom:chores+ cleaning ...+ water plants+ outdoor - one full watering can+ indoor - light watering+ **** TODO+ adm:planning: trip+ *** LATER++ Reporting:++ $ hledger -f a.timedot print date:2016/2/2+ 2016-02-02 *+ (inc:client1) 2.00++ 2016-02-02 *+ (biz:research) 0.25++ $ hledger -f a.timedot bal --daily --tree+ Balance changes in 2016-02-01-2016-02-03:++ || 2016-02-01d 2016-02-02d 2016-02-03d+ ============++========================================+ biz || 0.25 0.25 1.00+ research || 0.25 0.25 1.00+ fos || 1.50 0 3.00+ haskell || 1.50 0 0+ hledger || 0 0 3.00+ inc || 6.00 2.00 4.00+ client1 || 6.00 2.00 4.00+ ------------++----------------------------------------+ || 7.75 2.25 8.00++ Using period instead of colon as account name separator:++ 2016/2/4+ fos.hledger.timedot 4+ fos.ledger ..++ $ hledger -f a.timedot --alias /\\./=: bal --tree+ 4.50 fos+ 4.00 hledger:timedot+ 0.50 ledger+ --------------------+ 4.50++ A sample.timedot file.++COMMON TASKS+ Here are some quick examples of how to do some basic tasks with+ hledger. For more details, see the reference section below, the+ hledger_journal(5) manual, or the more extensive docs at+ https://hledger.org.++ Getting help+ $ hledger # show available commands+ $ hledger --help # show common options+ $ hledger CMD --help # show common and command options, and command help+ $ hledger help # show available manuals/topics+ $ hledger help hledger # show hledger manual as info/man/text (auto-chosen)+ $ hledger help journal --man # show the journal manual as a man page+ $ hledger help --help # show more detailed help for the help command++ Find more docs, chat, mail list, reddit, issue tracker:+ https://hledger.org#help-feedback++ Constructing command lines+ hledger has an extensive and powerful command line interface. We+ strive to keep it simple and ergonomic, but you may run into one of the+ confusing real world details described in OPTIONS, below. If that hap-+ pens, here are some tips that may help:++ o command-specific options must go after the command (it's fine to put+ all options there) (hledger CMD OPTS ARGS)++ o running add-on executables directly simplifies command line parsing+ (hledger-ui OPTS ARGS)++ o enclose "problematic" args in single quotes++ o if needed, also add a backslash to hide regular expression metachar-+ acters from the shell++ o to see how a misbehaving command is being parsed, add --debug=2.++ Starting a journal file+ hledger looks for your accounting data in a journal file,+ $HOME/.hledger.journal by default:++ $ hledger stats+ The hledger journal file "/Users/simon/.hledger.journal" was not found.+ Please create it first, eg with "hledger add" or a text editor.+ Or, specify an existing journal file with -f or LEDGER_FILE.++ You can override this by setting the LEDGER_FILE environment variable.+ It's a good practice to keep this important file under version control,+ and to start a new file each year. So you could do something like+ this:++ $ mkdir ~/finance+ $ cd ~/finance+ $ git init+ Initialized empty Git repository in /Users/simon/finance/.git/+ $ touch 2020.journal+ $ echo "export LEDGER_FILE=$HOME/finance/2020.journal" >> ~/.bashrc+ $ source ~/.bashrc+ $ hledger stats+ Main file : /Users/simon/finance/2020.journal+ Included files :+ Transactions span : to (0 days)+ Last transaction : none+ Transactions : 0 (0.0 per day)+ Transactions last 30 days: 0 (0.0 per day)+ Transactions last 7 days : 0 (0.0 per day)+ Payees/descriptions : 0+ Accounts : 0 (depth 0)+ Commodities : 0 ()+ Market prices : 0 ()++ Setting opening balances+ Pick a starting date for which you can look up the balances of some+ real-world assets (bank accounts, wallet..) and liabilities (credit+ cards..).++ To avoid a lot of data entry, you may want to start with just one or+ two accounts, like your checking account or cash wallet; and pick a+ recent starting date, like today or the start of the week. You can+ always come back later and add more accounts and older transactions, eg+ going back to january 1st.++ Add an opening balances transaction to the journal, declaring the bal-+ ances on this date. Here are two ways to do it:++ o The first way: open the journal in any text editor and save an entry+ like this:++ 2020-01-01 * opening balances+ assets:bank:checking $1000 = $1000+ assets:bank:savings $2000 = $2000+ assets:cash $100 = $100+ liabilities:creditcard $-50 = $-50+ equity:opening/closing balances++ These are start-of-day balances, ie whatever was in the account at+ the end of the previous day.++ The * after the date is an optional status flag. Here it means+ "cleared & confirmed".++ The currency symbols are optional, but usually a good idea as you'll+ be dealing with multiple currencies sooner or later.++ The = amounts are optional balance assertions, providing extra error+ checking.++ o The second way: run hledger add and follow the prompts to record a+ similar transaction:++ $ hledger add+ Adding transactions to journal file /Users/simon/finance/2020.journal+ Any command line arguments will be used as defaults.+ Use tab key to complete, readline keys to edit, enter to accept defaults.+ An optional (CODE) may follow transaction dates.+ An optional ; COMMENT may follow descriptions or amounts.+ If you make a mistake, enter < at any prompt to go one step backward.+ To end a transaction, enter . when prompted.+ To quit, enter . at a date prompt or press control-d or control-c.+ Date [2020-02-07]: 2020-01-01+ Description: * opening balances+ Account 1: assets:bank:checking+ Amount 1: $1000+ Account 2: assets:bank:savings+ Amount 2 [$-1000]: $2000+ Account 3: assets:cash+ Amount 3 [$-3000]: $100+ Account 4: liabilities:creditcard+ Amount 4 [$-3100]: $-50+ Account 5: equity:opening/closing balances+ Amount 5 [$-3050]:+ Account 6 (or . or enter to finish this transaction): .+ 2020-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++ Save this transaction to the journal ? [y]:+ Saved.+ Starting the next transaction (. or ctrl-D/ctrl-C to quit)+ Date [2020-01-01]: .++ If you're using version control, this could be a good time to commit+ the journal. Eg:++ $ git commit -m 'initial balances' 2020.journal++ Recording transactions+ As you spend or receive money, you can record these transactions using+ one of the methods above (text editor, hledger add) or by using the+ hledger-iadd or hledger-web add-ons, or by using the import command to+ convert CSV data downloaded from your bank.++ Here are some simple transactions, see the hledger_journal(5) manual+ and hledger.org for more ideas:++ 2020/1/10 * gift received+ assets:cash $20+ income:gifts++ 2020.1.12 * farmers market+ expenses:food $13+ assets:cash++ 2020-01-15 paycheck+ income:salary+ assets:bank:checking $1000++ Reconciling+ Periodically you should reconcile - compare your hledger-reported bal-+ ances against external sources of truth, like bank statements or your+ bank's website - to be sure that your ledger accurately represents the+ real-world balances (and, that the real-world institutions have not+ made a mistake!). This gets easy and fast with (1) practice and (2)+ frequency. If you do it daily, it can take 2-10 minutes. If you let+ it pile up, expect it to take longer as you hunt down errors and dis-+ crepancies.++ A typical workflow:++ 1. Reconcile cash. Count what's in your wallet. Compare with what+ hledger reports (hledger bal cash). If they are different, try to+ remember the missing transaction, or look for the error in the+ already-recorded transactions. A register report can be helpful+ (hledger reg cash). If you can't find the error, add an adjustment+ transaction. Eg if you have $105 after the above, and can't explain+ the missing $2, it could be:++ 2020-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ 2. Reconcile checking. Log in to your bank's website. Compare today's+ (cleared) balance with hledger's cleared balance (hledger bal check-+ ing -C). If they are different, track down the error or record the+ missing transaction(s) or add an adjustment transaction, similar to+ the above. Unlike the cash case, you can usually compare the trans-+ action history and running balance from your bank with the one+ reported by hledger reg checking -C. This will be easier if you+ generally record transaction dates quite similar to your bank's+ clearing dates.++ 3. Repeat for other asset/liability accounts.++ Tip: instead of the register command, use hledger-ui to see a live-+ updating register while you edit the journal: hledger-ui --watch --reg-+ ister checking -C++ After reconciling, it could be a good time to mark the reconciled+ transactions' status as "cleared and confirmed", if you want to track+ that, by adding the * marker. Eg in the paycheck transaction above,+ insert * between 2020-01-15 and paycheck++ If you're using version control, this can be another good time to com-+ mit:++ $ git commit -m 'txns' 2020.journal++ Reporting+ Here are some basic reports.++ Show all transactions:++ $ hledger print+ 2020-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++ 2020-01-10 * gift received+ assets:cash $20+ income:gifts++ 2020-01-12 * farmers market+ expenses:food $13+ assets:cash++ 2020-01-15 * paycheck+ income:salary+ assets:bank:checking $1000++ 2020-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ Show account names, and their hierarchy:++ $ hledger accounts --tree+ assets+ bank+ checking+ savings+ cash+ equity+ opening/closing balances+ expenses+ food+ misc+ income+ gifts+ salary+ liabilities+ creditcard++ Show all account totals:++ $ hledger balance+ $4105 assets+ $4000 bank+ $2000 checking+ $2000 savings+ $105 cash+ $-3050 equity:opening/closing balances+ $15 expenses+ $13 food+ $2 misc+ $-1020 income+ $-20 gifts+ $-1000 salary+ $-50 liabilities:creditcard+ --------------------+ 0++ Show only asset and liability balances, as a flat list, limited to+ depth 2:++ $ hledger bal assets liabilities --flat -2+ $4000 assets:bank+ $105 assets:cash+ $-50 liabilities:creditcard+ --------------------+ $4055++ Show the same thing without negative numbers, formatted as a simple+ balance sheet:++ $ hledger bs --flat -2+ Balance Sheet 2020-01-16++ || 2020-01-16+ ========================++============+ Assets ||+ ------------------------++------------+ assets:bank || $4000+ assets:cash || $105+ ------------------------++------------+ || $4105+ ========================++============+ Liabilities ||+ ------------------------++------------+ liabilities:creditcard || $50+ ------------------------++------------+ || $50+ ========================++============+ Net: || $4055++ The final total is your "net worth" on the end date. (Or use bse for a+ full balance sheet with equity.)++ Show income and expense totals, formatted as an income statement:++ hledger is+ Income Statement 2020-01-01-2020-01-16++ || 2020-01-01-2020-01-16+ ===============++=======================+ Revenues ||+ ---------------++-----------------------+ income:gifts || $20+ income:salary || $1000+ ---------------++-----------------------+ || $1020+ ===============++=======================+ Expenses ||+ ---------------++-----------------------+ expenses:food || $13+ expenses:misc || $2+ ---------------++-----------------------+ || $15+ ===============++=======================+ Net: || $1005++ The final total is your net income during this period.++ Show transactions affecting your wallet, with running total:++ $ hledger register cash+ 2020-01-01 opening balances assets:cash $100 $100+ 2020-01-10 gift received assets:cash $20 $120+ 2020-01-12 farmers market assets:cash $-13 $107+ 2020-01-16 adjust cash assets:cash $-2 $105++ Show weekly posting counts as a bar chart:++ $ hledger activity -W+ 2019-12-30 *****+ 2020-01-06 ****+ 2020-01-13 ****++ Migrating to a new file+ At the end of the year, you may want to continue your journal in a new+ file, so that old transactions don't slow down or clutter your reports,+ and to help ensure the integrity of your accounting history. See the+ close command.++ If using version control, don't forget to git add the new file.++LIMITATIONS+ The need to precede add-on command options with -- when invoked from+ hledger is awkward.++ When input data contains non-ascii characters, a suitable system locale+ must be configured (or there will be an unhelpful error). Eg on POSIX,+ set LANG to something other than C.++ In a Microsoft Windows CMD window, non-ascii characters and colours are+ not supported.++ On Windows, non-ascii characters may not display correctly when running+ a hledger built in CMD in MSYS/CYGWIN, or vice-versa.++ In a Cygwin/MSYS/Mintty window, the tab key is not supported in hledger+ add.++ Not all of Ledger's journal file syntax is supported. See file format+ differences.++ On large data files, hledger is slower and uses more memory than+ Ledger.++TROUBLESHOOTING+ Here are some issues you might encounter when you run hledger (and+ remember you can also seek help from the IRC channel, mail list or bug+ tracker):++ Successfully installed, but "No command 'hledger' found"+ stack and cabal install binaries into a special directory, which should+ be added to your PATH environment variable. Eg on unix-like systems,+ that is ~/.local/bin and ~/.cabal/bin respectively.++ I set a custom LEDGER_FILE, but hledger is still using the default file+ LEDGER_FILE should be a real environment variable, not just a shell+ variable. The command env | grep LEDGER_FILE should show it. You may+ need to use export. Here's an explanation.++ Getting errors like "Illegal byte sequence" or "Invalid or incomplete+ multibyte or wide character" or "commitAndReleaseBuffer: invalid argu-+ ment (invalid character)"+ Programs compiled with GHC (hledger, haskell build tools, etc.) need to+ have a UTF-8-aware locale configured in the environment, otherwise they+ will fail with these kinds of errors when they encounter non-ascii+ characters.++ To fix it, set the LANG environment variable to some locale which sup-+ ports UTF-8. The locale you choose must be installed on your system.++ Here's an example of setting LANG temporarily, on Ubuntu GNU/Linux:++ $ file my.journal+ my.journal: UTF-8 Unicode text # the file is UTF8-encoded+ $ echo $LANG+ C # LANG is set to the default locale, which does not support UTF8+ $ locale -a # which locales are installed ?+ C+ en_US.utf8 # here's a UTF8-aware one we can use+ POSIX+ $ LANG=en_US.utf8 hledger -f my.journal print # ensure it is used for this command++ If available, C.UTF-8 will also work. If your preferred locale isn't+ listed by locale -a, you might need to install it. Eg on+ Ubuntu/Debian:++ $ apt-get install language-pack-fr+ $ locale -a+ C+ en_US.utf8+ fr_BE.utf8+ fr_CA.utf8+ fr_CH.utf8+ fr_FR.utf8+ fr_LU.utf8+ POSIX+ $ LANG=fr_FR.utf8 hledger -f my.journal print++ Here's how you could set it permanently, if you use a bash shell:++ $ echo "export LANG=en_US.utf8" >>~/.bash_profile+ $ bash --login++ Exact spelling and capitalisation may be important. Note the differ-+ ence on MacOS (UTF-8, not utf8). Some platforms (eg ubuntu) allow+ variant spellings, but others (eg macos) require it to be exact:++ $ locale -a | grep -iE en_us.*utf+ en_US.UTF-8+ $ LANG=en_US.UTF-8 hledger -f my.journal print++++REPORTING BUGS+ Report bugs at http://bugs.hledger.org (or on the #hledger IRC channel+ or hledger mail list)+++AUTHORS+ Simon Michael <simon@joyful.com> and contributors+++COPYRIGHT+ Copyright (C) 2007-2020 Simon Michael.+ Released under GNU GPL v3 or later.+++SEE ALSO+ hledger(1), hledger-ui(1), hledger-web(1), ledger(1)++++hledger-1.22.2 August 2021 HLEDGER(1)
hledger.1 view
@@ -1,6 +1,6 @@ .\"t -.TH "HLEDGER" "1" "August 2021" "hledger-1.22.1 " "hledger User Manuals"+.TH "HLEDGER" "1" "August 2021" "hledger-1.22.2 " "hledger User Manuals" @@ -9,7 +9,7 @@ This is the command-line interface (CLI) for the hledger accounting tool. Here we also describe hledger\[aq]s concepts and file formats.-This manual is for hledger 1.22.1.+This manual is for hledger 1.22.2. .SH SYNOPSIS .PP \f[C]hledger\f[R]@@ -2511,30 +2511,23 @@ .P .PD .PP-Show the transactions and running historical balance in an account, with-each line item representing one transaction.-.PP-\f[C]aregister\f[R] shows the transactions affecting a particular-account and its subaccounts, with each line item representing a whole-transaction - as in bank statements, hledger-ui, hledger-web and other-accounting apps.-.PP-Note this is unlike the \f[C]register\f[R] command, which shows-individual postings and does not always show a single account or a-historical balance.+Show the transactions and running historical balance of a single+account, with each transaction displayed as one line. .PP-A reminder, \[dq]historical\[dq] balances include any balance from-transactions before the report start date, so (if opening balances are-recorded correctly) \f[C]aregister\f[R] will show the real-world-balances of an account, as you would see in a bank statement.+\f[C]aregister\f[R] shows the overall transactions affecting a+particular account (and any subaccounts).+Each report line represents one transaction in this account.+Transactions before the report start date are always included in the+running balance (\f[C]--historical\f[R] mode is always on). .PP-As a quick rule of thumb, use \f[C]aregister\f[R] for reconciling-real-world asset/liability accounts and \f[C]register\f[R] for reviewing-detailed revenues/expenses.+This is a more \[dq]real world\[dq], bank-like view than the+\f[C]register\f[R] command (which shows individual postings, possibly+from multiple accounts, not necessarily in historical mode).+As a quick rule of thumb: - use \f[C]aregister\f[R] for reviewing and+reconciling real-world asset/liability accounts - use \f[C]register\f[R]+for reviewing detailed revenues/expenses. .PP-\f[C]aregister\f[R] shows the register for just one account (and its-subaccounts).-This account must be specified as the first argument.+\f[C]aregister\f[R] requires one argument: the account to report on. You can write either the full account name, or a case-insensitive regular expression which will select the alphabetically first matched account.@@ -2542,9 +2535,25 @@ \f[C]assets:bbb:checking\f[R] accounts, \f[C]hledger areg checking\f[R] would select \f[C]assets:aaa:checking\f[R].) .PP+Transactions involving subaccounts of this account will also be shown.+\f[C]aregister\f[R] ignores depth limits, so its final total will always+match a balance report with similar arguments.+.PP Any additional arguments form a query which will filter the transactions shown.+Note some queries will disturb the running balance, causing it to be+different from the account\[aq]s real-world running balance. .PP+An example: this shows the transactions and historical running balance+during july, in the first account whose name contains+\[dq]checking\[dq]:+.IP+.nf+\f[C]+$ hledger areg checking date:jul+\f[R]+.fi+.PP Each \f[C]aregister\f[R] line item shows: .IP \[bu] 2 the transaction\[aq]s date (or the relevant posting\[aq]s date if@@ -2560,12 +2569,10 @@ Transactions making a net change of zero are not shown by default; add the \f[C]-E/--empty\f[R] flag to show them. .PP-\f[C]aregister\f[R] ignores a depth limit, so its final total will-always match a balance report with similar arguments.-.PP This command also supports the output destination and output format-options The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R],-and \f[C]json\f[R].+options.+The output formats supported are \f[C]txt\f[R], \f[C]csv\f[R], and+\f[C]json\f[R]. .SS aregister and custom posting dates .PP Transactions whose date is outside the report period can still be shown,@@ -2579,26 +2586,6 @@ \f[C]--txn-dates\f[R] flag. If you use this flag and some of your postings have custom dates, it\[aq]s probably best to assume the running balance is wrong.-.PP-Examples:-.PP-Show all transactions and historical running balance in the first-account whose name contains \[dq]checking\[dq]:-.IP-.nf-\f[C]-$ hledger areg checking-\f[R]-.fi-.PP-Show transactions and historical running balance in all asset accounts-during july:-.IP-.nf-\f[C]-$ hledger areg assets date:jul-\f[R]-.fi .SS balance .PP balance, bal@@ -8851,70 +8838,111 @@ ledger 2 executable renamed. .SH TIMEDOT FORMAT .PP-hledger\[aq]s human-friendly time logging format.+\f[C]timedot\f[R] format is hledger\[aq]s human-friendly time logging+format.+Compared to \f[C]timeclock\f[R] format, it is+.IP \[bu] 2+convenient for quick, approximate, and retroactive time logging+.IP \[bu] 2+readable: you can see at a glance where time was spent. .PP-Timedot is a plain text format for logging dated, categorised quantities-(of time, usually), supported by hledger.-It is convenient for approximate and retroactive time logging, eg when-the real-time clock-in/out required with a timeclock file is too precise-or too interruptive.-It can be formatted like a bar chart, making clear at a glance where-time was spent.+A timedot file contains a series of day entries, which might look like+this:+.IP+.nf+\f[C]+2021-08-04+hom:errands .... ....+fos:hledger:timedot .. ; docs+per:admin:finance +\f[R]+.fi .PP-Though called \[dq]timedot\[dq], this format is read by hledger as-commodityless quantities, so it could be used to represent dated-quantities other than time.-In the docs below we\[aq]ll assume it\[aq]s time.+hledger reads this as three time transactions on this day, with each dot+representing a quarter-hour spent:+.IP+.nf+\f[C]+$ hledger -f a.timedot print # .timedot file extension activates the timedot reader+2021-08-04 *+ (hom:errands) 2.00++2021-08-04 *+ (fos:hledger:timedot) 0.50++2021-08-04 *+ (per:admin:finance) 0+\f[R]+.fi .PP-A timedot file contains a series of day entries.-A day entry begins with a non-indented hledger-style simple date (Y-M-D,-Y/M/D, Y.M.D..) Any additional text on the same line is used as a-transaction description for this day.+A day entry begins with a date line:+.IP \[bu] 2+a non-indented \f[B]simple date\f[R] (Y-M-D, Y/M/D, or Y.M.D). .PP-This is followed by optionally-indented timelog items for that day, one-per line.-Each timelog item is a note, usually a hledger:style:account:name-representing a time category, followed by two or more spaces, and a-quantity.-Each timelog item generates a hledger transaction.+Optionally this can be followed on the same line by+.IP \[bu] 2+a common \f[B]transaction description\f[R] for this day+.IP \[bu] 2+a common \f[B]transaction comment\f[R] for this day, after a semicolon+(\f[C];\f[R]). .PP-Quantities can be written as:+After the date line are zero or more optionally-indented time+transaction lines, consisting of: .IP \[bu] 2-dots: a sequence of dots (.) representing quarter hours.-Spaces may optionally be used for grouping.-Eg: ....-\&..+an \f[B]account name\f[R] - any word or phrase, usually a hledger-style+account name. .IP \[bu] 2-an integral or decimal number, representing hours.-Eg: 1.5+\f[B]two or more spaces\f[R] - a field separator, required if there is+an amount (as in journal format). .IP \[bu] 2-an integral or decimal number immediately followed by a unit symbol-\f[C]s\f[R], \f[C]m\f[R], \f[C]h\f[R], \f[C]d\f[R], \f[C]w\f[R],-\f[C]mo\f[R], or \f[C]y\f[R], representing seconds, minutes, hours, days-weeks, months or years respectively.-Eg: 90m.-The following equivalencies are assumed, currently: 1m = 60s, 1h = 60m,-1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.+a \f[B]timedot amount\f[R] - dots representing quarter hours, or a+number representing hours.+.IP \[bu] 2+an optional \f[B]comment\f[R] beginning with semicolon.+This is ignored. .PP-There is some flexibility allowing notes and todo lists to be kept right-in the time log, if needed:+In more detail, timedot amounts can be: .IP \[bu] 2-Blank lines and lines beginning with \f[C]#\f[R] or \f[C];\f[R] are+\f[B]dots\f[R]: zero or more period characters, each representing one+quarter-hour.+Spaces are ignored and can be used for grouping.+Eg: \f[C].... ..\f[R]+.IP \[bu] 2+a \f[B]number\f[R], representing hours.+Eg: \f[C]1.5\f[R]+.IP \[bu] 2+a \f[B]number immediately followed by a unit symbol\f[R] \f[C]s\f[R],+\f[C]m\f[R], \f[C]h\f[R], \f[C]d\f[R], \f[C]w\f[R], \f[C]mo\f[R], or+\f[C]y\f[R], representing seconds, minutes, hours, days weeks, months or+years.+Eg \f[C]1.5h\f[R] or \f[C]90m\f[R].+The following equivalencies are assumed:+.PD 0+.P+.PD+\f[C]60s\f[R] = \f[C]1m\f[R], \f[C]60m\f[R] = \f[C]1h\f[R],+\f[C]24h\f[R] = \f[C]1d\f[R], \f[C]7d\f[R] = \f[C]1w\f[R], \f[C]30d\f[R]+= \f[C]1mo\f[R], \f[C]365d\f[R] = \f[C]1y\f[R].+(This unit will not be visible in the generated transaction amount,+which is always in hours.)+.PP+There is some added flexibility to help with keeping time log data in+the same file as your notes, todo lists, etc.:+.IP \[bu] 2+Lines beginning with \f[C]#\f[R] or \f[C];\f[R], and blank lines, are ignored. .IP \[bu] 2-Lines not ending with a double-space and quantity are parsed as items-taking no time, which will not appear in balance reports by default.-(Add -E to see them.)+Lines not ending with a double-space and amount are parsed as+transactions with zero amount.+(Most hledger reports hide these by default; add -E to see them.) .IP \[bu] 2-Org mode headlines (lines beginning with one or more \f[C]*\f[R]-followed by a space) can be used as date lines or timelog items (the-stars are ignored).-Also all org headlines before the first date line are ignored.-This means org users can manage their timelog as an org outline (eg-using org-mode/orgstruct-mode in Emacs), for organisation, faster-navigation, controlling visibility etc.+One or more stars (\f[C]*\f[R]) followed by a space, at the start of a+line, is ignored.+So date lines or time transaction lines can also be Org-mode headlines.+.IP \[bu] 2+All Org-mode headlines before the first date line are ignored. .PP-Examples:+More examples: .IP .nf \f[C]@@ -8972,7 +9000,7 @@ .IP .nf \f[C]-$ hledger -f t.timedot print date:2016/2/2+$ hledger -f a.timedot print date:2016/2/2 2016-02-02 * (inc:client1) 2.00 @@ -8983,7 +9011,7 @@ .IP .nf \f[C]-$ hledger -f t.timedot bal --daily --tree+$ hledger -f a.timedot bal --daily --tree Balance changes in 2016-02-01-2016-02-03: || 2016-02-01d 2016-02-02d 2016-02-03d @@ -9000,8 +9028,7 @@ \f[R] .fi .PP-I prefer to use period for separating account components.-We can make this work with an account alias:+Using period instead of colon as account name separator: .IP .nf \f[C]@@ -9013,7 +9040,7 @@ .IP .nf \f[C]-$ hledger -f t.timedot --alias /\[rs]\[rs]./=: bal date:2016/2/4 --tree+$ hledger -f a.timedot --alias /\[rs]\[rs]./=: bal --tree 4.50 fos 4.00 hledger:timedot 0.50 ledger@@ -9022,7 +9049,7 @@ \f[R] .fi .PP-Here is a sample.timedot.+A sample.timedot file. .SH COMMON TASKS .PP Here are some quick examples of how to do some basic tasks with hledger.
hledger.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: hledger-version: 1.22.1+version: 1.22.2 synopsis: Command-line interface for the hledger accounting system description: The command-line interface for the hledger accounting system. Its basic function is to read a plain text file describing@@ -136,7 +136,7 @@ other-modules: Paths_hledger ghc-options: -Wall -fno-warn-unused-do-bind -fno-warn-name-shadowing -fno-warn-missing-signatures -fno-warn-type-defaults -fno-warn-orphans -optP-Wno-nonportable-include-path- cpp-options: -DVERSION="1.22.1"+ cpp-options: -DVERSION="1.22.2" build-depends: Decimal >=0.5.1 , Diff@@ -154,7 +154,7 @@ , githash >=0.1.2 , hashable >=1.2.4 , haskeline >=0.6- , hledger-lib >=1.22.1 && <1.23+ , hledger-lib >=1.22.2 && <1.23 , lucid , math-functions >=0.3.3.0 , megaparsec >=7.0.0 && <9.2@@ -188,7 +188,7 @@ hs-source-dirs: app ghc-options: -Wall -fno-warn-unused-do-bind -fno-warn-name-shadowing -fno-warn-missing-signatures -fno-warn-type-defaults -fno-warn-orphans -optP-Wno-nonportable-include-path- cpp-options: -DVERSION="1.22.1"+ cpp-options: -DVERSION="1.22.2" build-depends: Decimal >=0.5.1 , aeson >=1@@ -205,7 +205,7 @@ , githash >=0.1.2 , haskeline >=0.6 , hledger- , hledger-lib >=1.22.1 && <1.23+ , hledger-lib >=1.22.2 && <1.23 , math-functions >=0.3.3.0 , megaparsec >=7.0.0 && <9.2 , mtl >=2.2.1@@ -239,7 +239,7 @@ hs-source-dirs: test ghc-options: -Wall -fno-warn-unused-do-bind -fno-warn-name-shadowing -fno-warn-missing-signatures -fno-warn-type-defaults -fno-warn-orphans -optP-Wno-nonportable-include-path- cpp-options: -DVERSION="1.22.1"+ cpp-options: -DVERSION="1.22.2" build-depends: Decimal >=0.5.1 , aeson >=1@@ -256,7 +256,7 @@ , githash >=0.1.2 , haskeline >=0.6 , hledger- , hledger-lib >=1.22.1 && <1.23+ , hledger-lib >=1.22.2 && <1.23 , math-functions >=0.3.3.0 , megaparsec >=7.0.0 && <9.2 , mtl >=2.2.1@@ -305,7 +305,7 @@ , githash >=0.1.2 , haskeline >=0.6 , hledger- , hledger-lib >=1.22.1 && <1.23+ , hledger-lib >=1.22.2 && <1.23 , html , math-functions >=0.3.3.0 , megaparsec >=7.0.0 && <9.2
hledger.info view
@@ -13,7 +13,7 @@ This is the command-line interface (CLI) for the hledger accounting tool. Here we also describe hledger's concepts and file formats. This-manual is for hledger 1.22.1.+manual is for hledger 1.22.2. 'hledger' @@ -2000,38 +2000,43 @@ aregister, areg - Show the transactions and running historical balance in an account,-with each line item representing one transaction.-- 'aregister' shows the transactions affecting a particular account and-its subaccounts, with each line item representing a whole transaction --as in bank statements, hledger-ui, hledger-web and other accounting-apps.-- Note this is unlike the 'register' command, which shows individual-postings and does not always show a single account or a historical-balance.+ Show the transactions and running historical balance of a single+account, with each transaction displayed as one line. - A reminder, "historical" balances include any balance from-transactions before the report start date, so (if opening balances are-recorded correctly) 'aregister' will show the real-world balances of an-account, as you would see in a bank statement.+ 'aregister' shows the overall transactions affecting a particular+account (and any subaccounts). Each report line represents one+transaction in this account. Transactions before the report start date+are always included in the running balance ('--historical' mode is+always on). - As a quick rule of thumb, use 'aregister' for reconciling real-world-asset/liability accounts and 'register' for reviewing detailed+ 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 'aregister' for reviewing and reconciling real-world+asset/liability accounts - use 'register' for reviewing detailed revenues/expenses. - 'aregister' shows the register for just one account (and its-subaccounts). This account must be specified as the first argument.-You can write either the full account name, or a case-insensitive-regular expression which will select the alphabetically first matched-account. (Eg if you have 'assets:aaa:checking' and-'assets:bbb:checking' accounts, 'hledger areg checking' would select-'assets:aaa:checking'.)+ 'aregister' requires one argument: the account to report on. You can+write either the full account name, or a case-insensitive regular+expression which will select the alphabetically first matched account.+(Eg if you have 'assets:aaa:checking' and 'assets:bbb:checking'+accounts, 'hledger areg checking' would select 'assets:aaa:checking'.) + Transactions involving subaccounts of this account will also be+shown. 'aregister' ignores depth limits, so its final total will always+match a balance report with similar arguments.+ Any additional arguments form a query which will filter the-transactions shown.+transactions shown. Note some queries will disturb the running balance,+causing it to be different from the account's real-world 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: * the transaction's date (or the relevant posting's date if@@ -2044,11 +2049,8 @@ Transactions making a net change of zero are not shown by default; add the '-E/--empty' flag to show them. - 'aregister' ignores a depth limit, so its final total will always-match a balance report with similar arguments.- This command also supports the output destination and output format-options The output formats supported are 'txt', 'csv', and 'json'.+options. The output formats supported are 'txt', 'csv', and 'json'. * Menu: @@ -2070,18 +2072,6 @@ flag. If you use this flag and some of your postings have custom dates, it's probably best to assume the running balance is wrong. - Examples:-- Show all transactions and historical running balance in the first-account whose name contains "checking":--$ hledger areg checking-- Show transactions and historical running balance in all asset-accounts during july:--$ hledger areg assets date:jul- File: hledger.info, Node: balance, Next: balancesheet, Prev: aregister, Up: COMMANDS @@ -7807,61 +7797,87 @@ 15 TIMEDOT FORMAT ***************** -hledger's human-friendly time logging format.+'timedot' format is hledger's human-friendly time logging format.+Compared to 'timeclock' format, it is - Timedot is a plain text format for logging dated, categorised-quantities (of time, usually), supported by hledger. It is convenient-for approximate and retroactive time logging, eg when the real-time-clock-in/out required with a timeclock file is too precise or too-interruptive. It can be formatted like a bar chart, making clear at a-glance where time was spent.+ * convenient for quick, approximate, and retroactive time logging+ * readable: you can see at a glance where time was spent. - Though called "timedot", this format is read by hledger as-commodityless quantities, so it could be used to represent dated-quantities other than time. In the docs below we'll assume it's time.+ A timedot file contains a series of day entries, which might look+like this: - A timedot file contains a series of day entries. A day entry begins-with a non-indented hledger-style simple date (Y-M-D, Y/M/D, Y.M.D..)-Any additional text on the same line is used as a transaction-description for this day.+2021-08-04+hom:errands .... ....+fos:hledger:timedot .. ; docs+per:admin:finance - This is followed by optionally-indented timelog items for that day,-one per line. Each timelog item is a note, usually a-hledger:style:account:name representing a time category, followed by two-or more spaces, and a quantity. Each timelog item generates a hledger-transaction.+ hledger reads this as three time transactions on this day, with each+dot representing a quarter-hour spent: - Quantities can be written as:+$ hledger -f a.timedot print # .timedot file extension activates the timedot reader+2021-08-04 *+ (hom:errands) 2.00 - * dots: a sequence of dots (.) representing quarter hours. Spaces- may optionally be used for grouping. Eg: .... ..+2021-08-04 *+ (fos:hledger:timedot) 0.50 - * an integral or decimal number, representing hours. Eg: 1.5+2021-08-04 *+ (per:admin:finance) 0 - * an integral or decimal number immediately followed by a unit symbol- 's', 'm', 'h', 'd', 'w', 'mo', or 'y', representing seconds,- minutes, hours, days weeks, months or years respectively. Eg: 90m.- The following equivalencies are assumed, currently: 1m = 60s, 1h =- 60m, 1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.+ A day entry begins with a date line: - There is some flexibility allowing notes and todo lists to be kept-right in the time log, if needed:+ * a non-indented *simple date* (Y-M-D, Y/M/D, or Y.M.D). - * Blank lines and lines beginning with '#' or ';' are ignored.+ Optionally this can be followed on the same line by - * Lines not ending with a double-space and quantity are parsed as- items taking no time, which will not appear in balance reports by- default. (Add -E to see them.)+ * a common *transaction description* for this day+ * a common *transaction comment* for this day, after a semicolon+ (';'). - * Org mode headlines (lines beginning with one or more '*' followed- by a space) can be used as date lines or timelog items (the stars- are ignored). Also all org headlines before the first date line- are ignored. This means org users can manage their timelog as an- org outline (eg using org-mode/orgstruct-mode in Emacs), for- organisation, faster navigation, controlling visibility etc.+ After the date line are zero or more optionally-indented time+transaction lines, consisting of: - Examples:+ * an *account name* - any word or phrase, usually a hledger-style+ account name.+ * *two or more spaces* - a field separator, required if there is an+ amount (as in journal format).+ * a *timedot amount* - dots representing quarter hours, or a number+ representing hours.+ * an optional *comment* beginning with semicolon. This is ignored. + In more detail, timedot amounts can be:++ * *dots*: zero or more period characters, each representing one+ quarter-hour. Spaces are ignored and can be used for grouping.+ Eg: '.... ..'++ * a *number*, representing hours. Eg: '1.5'++ * a *number immediately followed by a unit symbol* 's', 'm', 'h',+ 'd', 'w', 'mo', or 'y', representing seconds, minutes, hours, days+ weeks, months or years. Eg '1.5h' or '90m'. The following+ equivalencies are assumed:+ '60s' = '1m', '60m' = '1h', '24h' = '1d', '7d' = '1w', '30d' =+ '1mo', '365d' = '1y'. (This unit will not be visible in the+ generated transaction amount, which is always in hours.)++ There is some added flexibility to help with keeping time log data in+the same file as your notes, todo lists, etc.:++ * Lines beginning with '#' or ';', and blank lines, are ignored.++ * Lines not ending with a double-space and amount are parsed as+ transactions with zero amount. (Most hledger reports hide these by+ default; add -E to see them.)++ * One or more stars ('*') followed by a space, at the start of a+ line, is ignored. So date lines or time transaction lines can also+ be Org-mode headlines.++ * All Org-mode headlines before the first date line are ignored.++ More examples:+ # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc. 2016/2/1 inc:client1 .... .... .... .... .... ....@@ -7900,14 +7916,14 @@ Reporting: -$ hledger -f t.timedot print date:2016/2/2+$ hledger -f a.timedot print date:2016/2/2 2016-02-02 * (inc:client1) 2.00 2016-02-02 * (biz:research) 0.25 -$ hledger -f t.timedot bal --daily --tree+$ hledger -f a.timedot bal --daily --tree Balance changes in 2016-02-01-2016-02-03: || 2016-02-01d 2016-02-02d 2016-02-03d @@ -7922,21 +7938,20 @@ ------------++---------------------------------------- || 7.75 2.25 8.00 - I prefer to use period for separating account components. We can-make this work with an account alias:+ Using period instead of colon as account name separator: 2016/2/4 fos.hledger.timedot 4 fos.ledger .. -$ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4 --tree+$ hledger -f a.timedot --alias /\\./=: bal --tree 4.50 fos 4.00 hledger:timedot 0.50 ledger -------------------- 4.50 - Here is a sample.timedot.+ A sample.timedot file. File: hledger.info, Node: COMMON TASKS, Next: LIMITATIONS, Prev: TIMEDOT FORMAT, Up: Top@@ -8567,386 +8582,386 @@ Ref: #add65805 Node: aregister68598 Ref: #aregister68712-Node: aregister and custom posting dates70910-Ref: #aregister-and-custom-posting-dates71076-Node: balance71897-Ref: #balance72016-Node: balance features72931-Ref: #balance-features73071-Node: Simple balance report74728-Ref: #simple-balance-report74910-Node: Filtered balance report76363-Ref: #filtered-balance-report76550-Node: List or tree mode76850-Ref: #list-or-tree-mode77018-Node: Depth limiting78336-Ref: #depth-limiting78502-Node: Multi-period balance report79263-Ref: #multi-period-balance-report79455-Node: Sorting by amount81707-Ref: #sorting-by-amount81876-Node: Percentages82342-Ref: #percentages82498-Node: Balance change end balance83432-Ref: #balance-change-end-balance83623-Node: Balance report types85051-Ref: #balance-report-types85241-Node: Useful balance reports89314-Ref: #useful-balance-reports89495-Node: Budget report90580-Ref: #budget-report90764-Node: Budget report start date96003-Ref: #budget-report-start-date96172-Node: Nested budgets97504-Ref: #nested-budgets97653-Node: Customising single-period balance reports101093-Ref: #customising-single-period-balance-reports101302-Node: balancesheet103450-Ref: #balancesheet103588-Node: balancesheetequity104887-Ref: #balancesheetequity105038-Node: cashflow106418-Ref: #cashflow106542-Node: check107688-Ref: #check107793-Node: Basic checks108427-Ref: #basic-checks108545-Node: Strict checks109096-Ref: #strict-checks109237-Node: Other checks109673-Ref: #other-checks109813-Node: Custom checks110170-Ref: #custom-checks110290-Node: close110707-Ref: #close110811-Node: close usage112333-Ref: #close-usage112428-Node: codes115241-Ref: #codes115351-Node: commodities116063-Ref: #commodities116192-Node: descriptions116274-Ref: #descriptions116404-Node: diff116708-Ref: #diff116816-Node: files117863-Ref: #files117965-Node: help118112-Ref: #help118214-Node: import118941-Ref: #import119057-Node: Deduplication119922-Ref: #deduplication120047-Node: Import testing121941-Ref: #import-testing122106-Node: Importing balance assignments122594-Ref: #importing-balance-assignments122800-Node: Commodity display styles123449-Ref: #commodity-display-styles123622-Node: incomestatement123751-Ref: #incomestatement123886-Node: notes125191-Ref: #notes125306-Node: payees125674-Ref: #payees125782-Node: prices126308-Ref: #prices126416-Node: print126757-Ref: #print126869-Node: print-unique132184-Ref: #print-unique132312-Node: register132597-Ref: #register132726-Node: Custom register output137172-Ref: #custom-register-output137303-Node: register-match138640-Ref: #register-match138776-Node: rewrite139127-Ref: #rewrite139244-Node: Re-write rules in a file141150-Ref: #re-write-rules-in-a-file141313-Node: Diff output format142462-Ref: #diff-output-format142645-Node: rewrite vs print --auto143737-Ref: #rewrite-vs.-print---auto143897-Node: roi144453-Ref: #roi144553-Node: Spaces and special characters in --inv and --pnl146239-Ref: #spaces-and-special-characters-in---inv-and---pnl146479-Node: Semantics of --inv and --pnl146967-Ref: #semantics-of---inv-and---pnl147206-Node: IRR and TWR explained149056-Ref: #irr-and-twr-explained149216-Node: stats152284-Ref: #stats152385-Node: tags153173-Ref: #tags153273-Node: test153792-Ref: #test153908-Node: About add-on commands154655-Ref: #about-add-on-commands154792-Node: JOURNAL FORMAT155923-Ref: #journal-format156051-Node: Transactions158247-Ref: #transactions158362-Node: Dates159376-Ref: #dates159492-Node: Simple dates159557-Ref: #simple-dates159677-Node: Secondary dates160186-Ref: #secondary-dates160334-Node: Posting dates161670-Ref: #posting-dates161793-Node: Status163165-Ref: #status163275-Node: Code164983-Ref: #code165095-Node: Description165327-Ref: #description165455-Node: Payee and note165775-Ref: #payee-and-note165883-Node: Comments166218-Ref: #comments166340-Node: Tags167534-Ref: #tags-1167645-Node: Postings169038-Ref: #postings169162-Node: Virtual postings170188-Ref: #virtual-postings170299-Node: Account names171604-Ref: #account-names171741-Node: Amounts172229-Ref: #amounts172366-Node: Decimal marks digit group marks173322-Ref: #decimal-marks-digit-group-marks173499-Node: Commodity174371-Ref: #commodity174531-Node: Commodity directives175483-Ref: #commodity-directives175657-Node: Commodity display style176144-Ref: #commodity-display-style176323-Node: Rounding178431-Ref: #rounding178551-Node: Transaction prices178963-Ref: #transaction-prices179129-Node: Lot prices lot dates181560-Ref: #lot-prices-lot-dates181743-Node: Balance assertions182231-Ref: #balance-assertions182409-Node: Assertions and ordering183442-Ref: #assertions-and-ordering183624-Node: Assertions and included files184324-Ref: #assertions-and-included-files184561-Node: Assertions and multiple -f options184894-Ref: #assertions-and-multiple--f-options185144-Node: Assertions and commodities185276-Ref: #assertions-and-commodities185502-Node: Assertions and prices186659-Ref: #assertions-and-prices186867-Node: Assertions and subaccounts187307-Ref: #assertions-and-subaccounts187530-Node: Assertions and virtual postings187854-Ref: #assertions-and-virtual-postings188090-Node: Assertions and precision188232-Ref: #assertions-and-precision188419-Node: Balance assignments188686-Ref: #balance-assignments188856-Node: Balance assignments and prices190020-Ref: #balance-assignments-and-prices190186-Node: Directives190410-Ref: #directives190573-Node: Directives and multiple files195927-Ref: #directives-and-multiple-files196123-Node: Comment blocks196787-Ref: #comment-blocks196964-Node: Including other files197140-Ref: #including-other-files197314-Node: Default year198238-Ref: #default-year198396-Node: Declaring payees198803-Ref: #declaring-payees198969-Node: Declaring commodities199215-Ref: #declaring-commodities199396-Node: Commodity error checking201776-Ref: #commodity-error-checking201926-Node: Default commodity202183-Ref: #default-commodity202363-Node: Declaring market prices203239-Ref: #declaring-market-prices203428-Node: Declaring accounts204241-Ref: #declaring-accounts204421-Node: Account error checking205623-Ref: #account-error-checking205789-Node: Account comments206968-Ref: #account-comments207152-Node: Account subdirectives207576-Ref: #account-subdirectives207761-Node: Account types208074-Ref: #account-types208248-Node: Declaring account types208984-Ref: #declaring-account-types209163-Node: Auto-detected account types209813-Ref: #auto-detected-account-types210054-Node: Interference from auto-detected account types211014-Ref: #interference-from-auto-detected-account-types211291-Node: Old account type syntax211774-Ref: #old-account-type-syntax211971-Node: Account display order212271-Ref: #account-display-order212431-Node: Rewriting accounts213582-Ref: #rewriting-accounts213761-Node: Basic aliases214518-Ref: #basic-aliases214654-Node: Regex aliases215398-Ref: #regex-aliases215560-Node: Combining aliases216279-Ref: #combining-aliases216462-Node: Aliases and multiple files217738-Ref: #aliases-and-multiple-files217937-Node: end aliases218516-Ref: #end-aliases218663-Node: Default parent account218764-Ref: #default-parent-account218954-Node: Periodic transactions219838-Ref: #periodic-transactions220021-Node: Periodic rule syntax221938-Ref: #periodic-rule-syntax222138-Node: Two spaces between period expression and description!222842-Ref: #two-spaces-between-period-expression-and-description223155-Node: Forecasting with periodic transactions223839-Ref: #forecasting-with-periodic-transactions224138-Node: Budgeting with periodic transactions226193-Ref: #budgeting-with-periodic-transactions226426-Node: Auto postings226835-Ref: #auto-postings226971-Node: Auto postings and multiple files229150-Ref: #auto-postings-and-multiple-files229348-Node: Auto postings and dates229557-Ref: #auto-postings-and-dates229825-Node: Auto postings and transaction balancing / inferred amounts / balance assertions230000-Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions230345-Node: Auto posting tags230687-Ref: #auto-posting-tags230896-Node: CSV FORMAT231532-Ref: #csv-format231660-Node: Examples234289-Ref: #examples234392-Node: Basic234600-Ref: #basic234702-Node: Bank of Ireland235244-Ref: #bank-of-ireland235381-Node: Amazon236843-Ref: #amazon236963-Node: Paypal238682-Ref: #paypal238778-Node: CSV rules246422-Ref: #csv-rules246540-Node: skip246873-Ref: #skip246973-Node: fields list247348-Ref: #fields-list247487-Node: field assignment248990-Ref: #field-assignment249142-Node: Field names250070-Ref: #field-names250210-Node: date field250590-Ref: #date-field250710-Node: date2 field250758-Ref: #date2-field250901-Node: status field250957-Ref: #status-field251102-Node: code field251151-Ref: #code-field251298-Node: description field251343-Ref: #description-field251505-Node: comment field251564-Ref: #comment-field251721-Node: account field251936-Ref: #account-field252088-Node: amount field252663-Ref: #amount-field252814-Node: currency field254059-Ref: #currency-field254214-Node: balance field254471-Ref: #balance-field254605-Node: separator254977-Ref: #separator255109-Node: if block255649-Ref: #if-block255776-Node: Matching the whole record256177-Ref: #matching-the-whole-record256354-Node: Matching individual fields257157-Ref: #matching-individual-fields257363-Node: Combining matchers257587-Ref: #combining-matchers257785-Node: Rules applied on successful match258098-Ref: #rules-applied-on-successful-match258291-Node: if table258945-Ref: #if-table259066-Node: end260804-Ref: #end260918-Node: date-format261142-Ref: #date-format261276-Node: decimal-mark262272-Ref: #decimal-mark262419-Node: newest-first262758-Ref: #newest-first262901-Node: include263584-Ref: #include263717-Node: balance-type264161-Ref: #balance-type264283-Node: Tips264983-Ref: #tips265074-Node: Rapid feedback265373-Ref: #rapid-feedback265492-Node: Valid CSV265952-Ref: #valid-csv266084-Node: File Extension266276-Ref: #file-extension266430-Node: Reading multiple CSV files266859-Ref: #reading-multiple-csv-files267046-Node: Valid transactions267287-Ref: #valid-transactions267467-Node: Deduplicating importing268095-Ref: #deduplicating-importing268276-Node: Setting amounts269309-Ref: #setting-amounts269466-Node: Amount signs271907-Ref: #amount-signs272061-Node: Setting currency/commodity272748-Ref: #setting-currencycommodity272936-Node: Amount decimal places274110-Ref: #amount-decimal-places274302-Node: Referencing other fields274614-Ref: #referencing-other-fields274813-Node: How CSV rules are evaluated275710-Ref: #how-csv-rules-are-evaluated275885-Node: TIMECLOCK FORMAT277336-Ref: #timeclock-format277476-Node: TIMEDOT FORMAT279537-Ref: #timedot-format279675-Node: COMMON TASKS283951-Ref: #common-tasks284080-Node: Getting help284487-Ref: #getting-help284621-Node: Constructing command lines285174-Ref: #constructing-command-lines285368-Node: Starting a journal file286065-Ref: #starting-a-journal-file286265-Node: Setting opening balances287453-Ref: #setting-opening-balances287651-Node: Recording transactions290792-Ref: #recording-transactions290974-Node: Reconciling291530-Ref: #reconciling291675-Node: Reporting293932-Ref: #reporting294074-Node: Migrating to a new file298073-Ref: #migrating-to-a-new-file298223-Node: LIMITATIONS298522-Ref: #limitations298650-Node: TROUBLESHOOTING299393-Ref: #troubleshooting299508+Node: aregister and custom posting dates71077+Ref: #aregister-and-custom-posting-dates71243+Node: balance71795+Ref: #balance71914+Node: balance features72829+Ref: #balance-features72969+Node: Simple balance report74626+Ref: #simple-balance-report74808+Node: Filtered balance report76261+Ref: #filtered-balance-report76448+Node: List or tree mode76748+Ref: #list-or-tree-mode76916+Node: Depth limiting78234+Ref: #depth-limiting78400+Node: Multi-period balance report79161+Ref: #multi-period-balance-report79353+Node: Sorting by amount81605+Ref: #sorting-by-amount81774+Node: Percentages82240+Ref: #percentages82396+Node: Balance change end balance83330+Ref: #balance-change-end-balance83521+Node: Balance report types84949+Ref: #balance-report-types85139+Node: Useful balance reports89212+Ref: #useful-balance-reports89393+Node: Budget report90478+Ref: #budget-report90662+Node: Budget report start date95901+Ref: #budget-report-start-date96070+Node: Nested budgets97402+Ref: #nested-budgets97551+Node: Customising single-period balance reports100991+Ref: #customising-single-period-balance-reports101200+Node: balancesheet103348+Ref: #balancesheet103486+Node: balancesheetequity104785+Ref: #balancesheetequity104936+Node: cashflow106316+Ref: #cashflow106440+Node: check107586+Ref: #check107691+Node: Basic checks108325+Ref: #basic-checks108443+Node: Strict checks108994+Ref: #strict-checks109135+Node: Other checks109571+Ref: #other-checks109711+Node: Custom checks110068+Ref: #custom-checks110188+Node: close110605+Ref: #close110709+Node: close usage112231+Ref: #close-usage112326+Node: codes115139+Ref: #codes115249+Node: commodities115961+Ref: #commodities116090+Node: descriptions116172+Ref: #descriptions116302+Node: diff116606+Ref: #diff116714+Node: files117761+Ref: #files117863+Node: help118010+Ref: #help118112+Node: import118839+Ref: #import118955+Node: Deduplication119820+Ref: #deduplication119945+Node: Import testing121839+Ref: #import-testing122004+Node: Importing balance assignments122492+Ref: #importing-balance-assignments122698+Node: Commodity display styles123347+Ref: #commodity-display-styles123520+Node: incomestatement123649+Ref: #incomestatement123784+Node: notes125089+Ref: #notes125204+Node: payees125572+Ref: #payees125680+Node: prices126206+Ref: #prices126314+Node: print126655+Ref: #print126767+Node: print-unique132082+Ref: #print-unique132210+Node: register132495+Ref: #register132624+Node: Custom register output137070+Ref: #custom-register-output137201+Node: register-match138538+Ref: #register-match138674+Node: rewrite139025+Ref: #rewrite139142+Node: Re-write rules in a file141048+Ref: #re-write-rules-in-a-file141211+Node: Diff output format142360+Ref: #diff-output-format142543+Node: rewrite vs print --auto143635+Ref: #rewrite-vs.-print---auto143795+Node: roi144351+Ref: #roi144451+Node: Spaces and special characters in --inv and --pnl146137+Ref: #spaces-and-special-characters-in---inv-and---pnl146377+Node: Semantics of --inv and --pnl146865+Ref: #semantics-of---inv-and---pnl147104+Node: IRR and TWR explained148954+Ref: #irr-and-twr-explained149114+Node: stats152182+Ref: #stats152283+Node: tags153071+Ref: #tags153171+Node: test153690+Ref: #test153806+Node: About add-on commands154553+Ref: #about-add-on-commands154690+Node: JOURNAL FORMAT155821+Ref: #journal-format155949+Node: Transactions158145+Ref: #transactions158260+Node: Dates159274+Ref: #dates159390+Node: Simple dates159455+Ref: #simple-dates159575+Node: Secondary dates160084+Ref: #secondary-dates160232+Node: Posting dates161568+Ref: #posting-dates161691+Node: Status163063+Ref: #status163173+Node: Code164881+Ref: #code164993+Node: Description165225+Ref: #description165353+Node: Payee and note165673+Ref: #payee-and-note165781+Node: Comments166116+Ref: #comments166238+Node: Tags167432+Ref: #tags-1167543+Node: Postings168936+Ref: #postings169060+Node: Virtual postings170086+Ref: #virtual-postings170197+Node: Account names171502+Ref: #account-names171639+Node: Amounts172127+Ref: #amounts172264+Node: Decimal marks digit group marks173220+Ref: #decimal-marks-digit-group-marks173397+Node: Commodity174269+Ref: #commodity174429+Node: Commodity directives175381+Ref: #commodity-directives175555+Node: Commodity display style176042+Ref: #commodity-display-style176221+Node: Rounding178329+Ref: #rounding178449+Node: Transaction prices178861+Ref: #transaction-prices179027+Node: Lot prices lot dates181458+Ref: #lot-prices-lot-dates181641+Node: Balance assertions182129+Ref: #balance-assertions182307+Node: Assertions and ordering183340+Ref: #assertions-and-ordering183522+Node: Assertions and included files184222+Ref: #assertions-and-included-files184459+Node: Assertions and multiple -f options184792+Ref: #assertions-and-multiple--f-options185042+Node: Assertions and commodities185174+Ref: #assertions-and-commodities185400+Node: Assertions and prices186557+Ref: #assertions-and-prices186765+Node: Assertions and subaccounts187205+Ref: #assertions-and-subaccounts187428+Node: Assertions and virtual postings187752+Ref: #assertions-and-virtual-postings187988+Node: Assertions and precision188130+Ref: #assertions-and-precision188317+Node: Balance assignments188584+Ref: #balance-assignments188754+Node: Balance assignments and prices189918+Ref: #balance-assignments-and-prices190084+Node: Directives190308+Ref: #directives190471+Node: Directives and multiple files195825+Ref: #directives-and-multiple-files196021+Node: Comment blocks196685+Ref: #comment-blocks196862+Node: Including other files197038+Ref: #including-other-files197212+Node: Default year198136+Ref: #default-year198294+Node: Declaring payees198701+Ref: #declaring-payees198867+Node: Declaring commodities199113+Ref: #declaring-commodities199294+Node: Commodity error checking201674+Ref: #commodity-error-checking201824+Node: Default commodity202081+Ref: #default-commodity202261+Node: Declaring market prices203137+Ref: #declaring-market-prices203326+Node: Declaring accounts204139+Ref: #declaring-accounts204319+Node: Account error checking205521+Ref: #account-error-checking205687+Node: Account comments206866+Ref: #account-comments207050+Node: Account subdirectives207474+Ref: #account-subdirectives207659+Node: Account types207972+Ref: #account-types208146+Node: Declaring account types208882+Ref: #declaring-account-types209061+Node: Auto-detected account types209711+Ref: #auto-detected-account-types209952+Node: Interference from auto-detected account types210912+Ref: #interference-from-auto-detected-account-types211189+Node: Old account type syntax211672+Ref: #old-account-type-syntax211869+Node: Account display order212169+Ref: #account-display-order212329+Node: Rewriting accounts213480+Ref: #rewriting-accounts213659+Node: Basic aliases214416+Ref: #basic-aliases214552+Node: Regex aliases215296+Ref: #regex-aliases215458+Node: Combining aliases216177+Ref: #combining-aliases216360+Node: Aliases and multiple files217636+Ref: #aliases-and-multiple-files217835+Node: end aliases218414+Ref: #end-aliases218561+Node: Default parent account218662+Ref: #default-parent-account218852+Node: Periodic transactions219736+Ref: #periodic-transactions219919+Node: Periodic rule syntax221836+Ref: #periodic-rule-syntax222036+Node: Two spaces between period expression and description!222740+Ref: #two-spaces-between-period-expression-and-description223053+Node: Forecasting with periodic transactions223737+Ref: #forecasting-with-periodic-transactions224036+Node: Budgeting with periodic transactions226091+Ref: #budgeting-with-periodic-transactions226324+Node: Auto postings226733+Ref: #auto-postings226869+Node: Auto postings and multiple files229048+Ref: #auto-postings-and-multiple-files229246+Node: Auto postings and dates229455+Ref: #auto-postings-and-dates229723+Node: Auto postings and transaction balancing / inferred amounts / balance assertions229898+Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions230243+Node: Auto posting tags230585+Ref: #auto-posting-tags230794+Node: CSV FORMAT231430+Ref: #csv-format231558+Node: Examples234187+Ref: #examples234290+Node: Basic234498+Ref: #basic234600+Node: Bank of Ireland235142+Ref: #bank-of-ireland235279+Node: Amazon236741+Ref: #amazon236861+Node: Paypal238580+Ref: #paypal238676+Node: CSV rules246320+Ref: #csv-rules246438+Node: skip246771+Ref: #skip246871+Node: fields list247246+Ref: #fields-list247385+Node: field assignment248888+Ref: #field-assignment249040+Node: Field names249968+Ref: #field-names250108+Node: date field250488+Ref: #date-field250608+Node: date2 field250656+Ref: #date2-field250799+Node: status field250855+Ref: #status-field251000+Node: code field251049+Ref: #code-field251196+Node: description field251241+Ref: #description-field251403+Node: comment field251462+Ref: #comment-field251619+Node: account field251834+Ref: #account-field251986+Node: amount field252561+Ref: #amount-field252712+Node: currency field253957+Ref: #currency-field254112+Node: balance field254369+Ref: #balance-field254503+Node: separator254875+Ref: #separator255007+Node: if block255547+Ref: #if-block255674+Node: Matching the whole record256075+Ref: #matching-the-whole-record256252+Node: Matching individual fields257055+Ref: #matching-individual-fields257261+Node: Combining matchers257485+Ref: #combining-matchers257683+Node: Rules applied on successful match257996+Ref: #rules-applied-on-successful-match258189+Node: if table258843+Ref: #if-table258964+Node: end260702+Ref: #end260816+Node: date-format261040+Ref: #date-format261174+Node: decimal-mark262170+Ref: #decimal-mark262317+Node: newest-first262656+Ref: #newest-first262799+Node: include263482+Ref: #include263615+Node: balance-type264059+Ref: #balance-type264181+Node: Tips264881+Ref: #tips264972+Node: Rapid feedback265271+Ref: #rapid-feedback265390+Node: Valid CSV265850+Ref: #valid-csv265982+Node: File Extension266174+Ref: #file-extension266328+Node: Reading multiple CSV files266757+Ref: #reading-multiple-csv-files266944+Node: Valid transactions267185+Ref: #valid-transactions267365+Node: Deduplicating importing267993+Ref: #deduplicating-importing268174+Node: Setting amounts269207+Ref: #setting-amounts269364+Node: Amount signs271805+Ref: #amount-signs271959+Node: Setting currency/commodity272646+Ref: #setting-currencycommodity272834+Node: Amount decimal places274008+Ref: #amount-decimal-places274200+Node: Referencing other fields274512+Ref: #referencing-other-fields274711+Node: How CSV rules are evaluated275608+Ref: #how-csv-rules-are-evaluated275783+Node: TIMECLOCK FORMAT277234+Ref: #timeclock-format277374+Node: TIMEDOT FORMAT279435+Ref: #timedot-format279573+Node: COMMON TASKS284135+Ref: #common-tasks284264+Node: Getting help284671+Ref: #getting-help284805+Node: Constructing command lines285358+Ref: #constructing-command-lines285552+Node: Starting a journal file286249+Ref: #starting-a-journal-file286449+Node: Setting opening balances287637+Ref: #setting-opening-balances287835+Node: Recording transactions290976+Ref: #recording-transactions291158+Node: Reconciling291714+Ref: #reconciling291859+Node: Reporting294116+Ref: #reporting294258+Node: Migrating to a new file298257+Ref: #migrating-to-a-new-file298407+Node: LIMITATIONS298706+Ref: #limitations298834+Node: TROUBLESHOOTING299577+Ref: #troubleshooting299692 End Tag Table
hledger.txt view
@@ -6,7050 +6,7070 @@ NAME This is the command-line interface (CLI) for the hledger accounting tool. Here we also describe hledger's concepts and file formats. This- manual is for hledger 1.22.1.--SYNOPSIS- hledger-- hledger [-f FILE] COMMAND [OPTIONS] [ARGS]-- hledger [-f FILE] ADDONCMD -- [OPTIONS] [ARGS]--DESCRIPTION- hledger is a reliable, cross-platform set of programs for tracking- money, time, or any other commodity, using double-entry accounting and- a simple, editable file format. hledger is inspired by and largely- compatible with ledger(1).-- The basic function of the hledger CLI is to read a plain text file- describing financial transactions (in accounting terms, a general jour-- nal) and print useful reports on standard output, or export them as- CSV. hledger can also read some other file formats such as CSV files,- translating them to journal format. Additionally, hledger lists other- hledger-* executables found in the user's $PATH and can invoke them as- subcommands.-- hledger reads data from one or more files in hledger journal, time-- clock, timedot, or CSV format specified with -f, or $LEDGER_FILE, or- $HOME/.hledger.journal (on windows, perhaps- C:/Users/USER/.hledger.journal). If using $LEDGER_FILE, note this must- be a real environment variable, not a shell variable. You can specify- standard input with -f-.-- Transactions are dated movements of money between two (or more) named- accounts, and are recorded with journal entries like this:-- 2015/10/16 bought food- expenses:food $10- assets:cash-- Most users use a text editor to edit the journal, usually with an edi-- tor mode such as ledger-mode for added convenience. hledger's interac-- tive add command is another way to record new transactions. hledger- never changes existing transactions.-- To get started, you can either save some entries like the above in- ~/.hledger.journal, or run hledger add and follow the prompts. Then- try some commands like hledger print or hledger balance. Run hledger- with no arguments for a list of commands.--OPTIONS- General options- To see general usage help, including general options which are sup-- ported by most hledger commands, run hledger -h.-- General help options:-- -h --help- show general or COMMAND help-- --man show general or COMMAND user manual with man-- --info show general or COMMAND user manual with info-- --version- show general or ADDONCMD version-- --debug[=N]- show debug output (levels 1-9, default: 1)-- General input options:-- -f FILE --file=FILE- use a different input file. For stdin, use - (default:- $LEDGER_FILE or $HOME/.hledger.journal)-- --rules-file=RULESFILE- Conversion rules file to use when reading CSV (default:- FILE.rules)-- --separator=CHAR- Field separator to expect when reading CSV (default: ',')-- --alias=OLD=NEW- rename accounts named OLD to NEW-- --anon anonymize accounts and payees-- --pivot FIELDNAME- use some other field or tag for the account name-- -I --ignore-assertions- disable balance assertion checks (note: does not disable balance- assignments)-- -s --strict- do extra error checking (check that all posted accounts are- declared)-- General reporting options:-- -b --begin=DATE- include postings/txns on or after this date (will be adjusted to- preceding subperiod start when using a report interval)-- -e --end=DATE- include postings/txns before this date (will be adjusted to fol-- lowing subperiod end when using a report interval)-- -D --daily- multiperiod/multicolumn report by day-- -W --weekly- multiperiod/multicolumn report by week-- -M --monthly- multiperiod/multicolumn report by month-- -Q --quarterly- multiperiod/multicolumn report by quarter-- -Y --yearly- multiperiod/multicolumn report by year-- -p --period=PERIODEXP- set start date, end date, and/or reporting interval all at once- using period expressions syntax-- --date2- match the secondary date instead (see command help for other- effects)-- -U --unmarked- include only unmarked postings/txns (can combine with -P or -C)-- -P --pending- include only pending postings/txns-- -C --cleared- include only cleared postings/txns-- -R --real- include only non-virtual postings-- -NUM --depth=NUM- hide/aggregate accounts or postings more than NUM levels deep-- -E --empty- show items with zero amount, normally hidden (and vice-versa in- hledger-ui/hledger-web)-- -B --cost- convert amounts to their cost/selling amount at transaction time-- -V --market- convert amounts to their market value in default valuation com-- modities-- -X --exchange=COMM- convert amounts to their market value in commodity COMM-- --value- convert amounts to cost or market value, more flexibly than- -B/-V/-X-- --infer-market-prices- use transaction prices (recorded with @ or @@) as additional- market prices, as if they were P directives-- --auto apply automated posting rules to modify transactions.-- --forecast- generate future transactions from periodic transaction rules,- for the next 6 months or till report end date. In hledger-ui,- also make ordinary future transactions visible.-- --color=WHEN (or --colour=WHEN)- Should color-supporting commands use ANSI color codes in text- output. 'auto' (default): whenever stdout seems to be a color-- supporting terminal. 'always' or 'yes': always, useful eg when- piping output into 'less -R'. 'never' or 'no': never. A- NO_COLOR environment variable overrides this.-- When a reporting option appears more than once in the command line, the- last one takes precedence.-- Some reporting options can also be written as query arguments.-- Command options- To see options for a particular command, including command-specific- options, run: hledger COMMAND -h.-- Command-specific options must be written after the command name, eg:- hledger print -x.-- Additionally, if the command is an add-on, you may need to put its- options after a double-hyphen, eg: hledger ui -- --watch. Or, you can- run the add-on executable directly: hledger-ui --watch.-- Command arguments- Most hledger commands accept arguments after the command name, which- are often a query, filtering the data in some way.-- You can save a set of command line options/arguments in a file, and- then reuse them by writing @FILENAME as a command line argument. Eg:- hledger bal @foo.args. (To prevent this, eg if you have an argument- that begins with a literal @, precede it with --, eg: hledger bal --- @ARG).-- Inside the argument file, each line should contain just one option or- argument. Avoid the use of spaces, except inside quotes (or you'll see- a confusing error). Between a flag and its argument, use = (or noth-- ing). Bad:-- assets depth:2- -X USD-- Good:-- assets- depth:2- -X=USD-- For special characters (see below), use one less level of quoting than- you would at the command prompt. Bad:-- -X"$"-- Good:-- -X$-- See also: Save frequently used options.-- Special characters- Single escaping (shell metacharacters)- In shell command lines, characters significant to your shell - such as- spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want- hledger to see them. This is done by enclosing them in single or dou-- ble quotes, or by writing a backslash before them. Eg to match an- account name containing a space:-- $ hledger register 'credit card'-- or:-- $ 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.- 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- using the bash shell:-- $ hledger balance cur:'\$'-- or:-- $ hledger balance cur:\\$-- Triple escaping (for add-on commands)- When you use hledger to run an external add-on command (described- below), one level of shell-escaping is lost from any options or argu-- ments intended for by the add-on command, so those need an extra level- of shell-escaping. Eg to match a literal $ sign while using the bash- shell and running an add-on command (ui):-- $ hledger ui cur:'\\$'-- or:-- $ hledger ui cur:\\\\$-- If you wondered why four backslashes, perhaps this helps:--- unescaped: $- escaped: \$- double-escaped: \\$- triple-escaped: \\\\$-- Or, you can avoid the extra escaping by running the add-on executable- directly:-- $ hledger-ui cur:\\$-- Less escaping- Options and arguments are sometimes used in places other than the shell- command line, where shell-escaping is not needed, so there you should- use one less level of escaping. Those places include:-- o an @argumentfile-- o hledger-ui's filter field-- o hledger-web's search form-- o GHCI's prompt (used by developers).-- Unicode characters- hledger is expected to handle non-ascii characters correctly:-- o they should be parsed correctly in input files and on the command- line, by all hledger tools (add, iadd, hledger-web's search/add/edit- forms, etc.)-- o they should be displayed correctly by all hledger tools, and on-- screen alignment should be preserved.-- This requires a well-configured environment. Here are some tips:-- o A system locale must be configured, and it must be one that can- decode the characters being used. In bash, you can set a locale like- this: export LANG=en_US.UTF-8. There are some more details in Trou-- bleshooting. This step is essential - without it, hledger will quit- on encountering a non-ascii character (as with all GHC-compiled pro-- grams).-- o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)- must support unicode-- o the terminal must be using a font which includes the required unicode- glyphs-- o the terminal should be configured to display wide characters as dou-- ble width (for report alignment)-- o on Windows, for best results you should run hledger in the same kind- of environment in which it was built. Eg hledger built in the stan-- dard CMD.EXE environment (like the binaries on our download page)- might show display problems when run in a cygwin or msys terminal,- and vice versa. (See eg #961).-- Regular expressions- hledger uses regular expressions in a number of places:-- o query terms, on the command line and in the hledger-web search form:- REGEX, desc:REGEX, cur:REGEX, tag:...=REGEX-- o CSV rules conditional blocks: if REGEX ...-- o account alias directives and options: alias /REGEX/ = REPLACEMENT,- --alias /REGEX/=REPLACEMENT-- hledger's regular expressions come from the regex-tdfa library. If- they're not doing what you expect, it's important to know exactly what- they support:-- 1. they are case insensitive-- 2. they are infix matching (they do not need to match the entire thing- being matched)-- 3. they are POSIX ERE (extended regular expressions)-- 4. they also support GNU word boundaries (\b, \B, \<, \>)-- 5. they do not support backreferences; if you write \1, it will match- the digit 1. Except when doing text replacement, eg in account- aliases, where backreferences can be used in the replacement string- to reference capturing groups in the search regexp.-- 6. they do not support mode modifiers ((?s)), character classes (\w,- \d), or anything else not mentioned above.-- Some things to note:-- o In the alias directive and --alias option, regular expressions must- be enclosed in forward slashes (/REGEX/). Elsewhere in hledger,- these are not required.-- o In queries, to match a regular expression metacharacter like $ as a- literal character, prepend a backslash. Eg to search for amounts- with the dollar sign in hledger-web, write cur:\$.-- o On the command line, some metacharacters like $ have a special mean-- ing to the shell and so must be escaped at least once more. See Spe-- cial characters.--ENVIRONMENT- LEDGER_FILE The journal file path when not specified with -f. Default:- ~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour-- nal).-- A typical value is ~/DIR/YYYY.journal, where DIR is a version-con-- trolled finance directory and YYYY is the current year. Or ~/DIR/cur-- rent.journal, where current.journal is a symbolic link to YYYY.journal.-- On Mac computers, you can set this and other environment variables in a- more thorough way that also affects applications started from the GUI- (say, an Emacs dock icon). Eg on MacOS Catalina I have a- ~/.MacOSX/environment.plist file containing-- {- "LEDGER_FILE" : "~/finance/current.journal"- }-- To see the effect you may need to killall Dock, or reboot.-- COLUMNS The screen width used by the register command. Default: the- full terminal width.-- NO_COLOR If this variable exists with any value, hledger will not use- ANSI color codes in terminal output. This overrides the- --color/--colour option.--DATA FILES- hledger reads transactions from one or more data files. The default- data file is $HOME/.hledger.journal (or on Windows, something like- C:/Users/USER/.hledger.journal).-- You can override this with the $LEDGER_FILE environment variable:-- $ setenv LEDGER_FILE ~/finance/2016.journal- $ hledger stats-- or with one or more -f/--file options:-- $ hledger -f /some/file -f another_file stats-- The file name - means standard input:-- $ cat some.journal | hledger -f--- Data formats- Usually the data file is in hledger's journal format, but it can be in- any of the supported file formats, which currently are:--- Reader: Reads: Used for file exten-- sions:- ------------------------------------------------------------------------------ journal hledger journal files and some Ledger .journal .j .hledger- journals, for transactions .ledger- time- timeclock files, for precise time log- .timeclock- clock ging- timedot timedot files, for approximate time .timedot- logging- csv comma/semicolon/tab/other-separated .csv .ssv .tsv- values, for data import-- These formats are described in their own sections, below.-- hledger detects the format automatically based on the file extensions- shown above. If it can't recognise the file extension, it assumes- journal format. So for non-journal files, it's important to use a- recognised file extension, so as to either read successfully or to show- relevant error messages.-- You can also force a specific reader/format by prefixing the file path- with the format and a colon. Eg, to read a .dat file as csv format:-- $ hledger -f csv:/some/csv-file.dat stats-- Or to read stdin (-) as timeclock format:-- $ echo 'i 2009/13/1 08:00:00' | hledger print -ftimeclock:--- Multiple files- You can specify multiple -f options, to read multiple files as one big- journal. There are some limitations with this:-- o most directives do not affect sibling files-- o balance assertions will not see any account balances from previous- files-- If you need either of those things, you can-- o use a single parent file which includes the others-- o or concatenate the files into one before reading, eg: cat a.journal- b.journal | hledger -f- CMD.-- Strict mode- hledger checks input files for valid data. By default, the most impor-- tant errors are detected, while still accepting easy journal files- without a lot of declarations:-- o Are the input files parseable, with valid syntax ?-- o Are all transactions balanced ?-- o Do all balance assertions pass ?-- With the -s/--strict flag, additional checks are performed:-- o Are all accounts posted to, declared with an account directive ?- (Account error checking)-- o Are all commodities declared with a commodity directive ? (Commodity- error checking)-- o Are all commodity conversions declared explicitly ?-- You can also use the check command to run these and some additional- checks.--TIME PERIODS- Smart dates- hledger's user interfaces accept a flexible "smart date" syntax. Smart- dates allow some english words, can be relative to today's date, and- can have less-significant date parts omitted (defaulting to 1).-- Examples:--- 2004/10/1, 2004-01-01, exact date, several separators allowed. Year- 2004.9.1 is 4+ digits, month is 1-12, day is 1-31- 2004 start of year- 2004/10 start of month- 10/1 month and day in current year- 21 day in current month- october, oct start of month in current year- yesterday, today, tomor- -1, 0, 1 days from today- row- last/this/next -1, 0, 1 periods from the current period- day/week/month/quar-- ter/year- 20181201 8 digit YYYYMMDD with valid year month and day- 201812 6 digit YYYYMM with valid year and month-- Counterexamples - malformed digit sequences might give surprising- results:--- 201813 6 digits with an invalid month is parsed as start of- 6-digit year- 20181301 8 digits with an invalid month is parsed as start of- 8-digit year- 20181232 8 digits with an invalid day gives an error- 201801012 9+ digits beginning with a valid YYYYMMDD gives an error--- Report start & end date- By default, most hledger reports will show the full span of time repre-- sented by the journal data. The report start date will be the earliest- transaction or posting date, and the report end date will be the latest- transaction, posting, or market price date.-- Often you will want to see a shorter time span, such as the current- month. You can specify a start and/or end date using -b/--begin,- -e/--end, -p/--period or a date: query (described below). All of these- accept the smart date syntax.-- Some notes:-- o As in Ledger, end dates are exclusive, so you need to write the date- after the last day you want to include.-- o As noted in reporting options: among start/end dates specified with- options, the last (i.e. right-most) option takes precedence.-- o The effective report start and end dates are the intersection of the- start/end dates from options and that from date: queries. That is,- date:2019-01 date:2019 -p'2000 to 2030' yields January 2019, the- smallest common time span.-- o A report interval (see below) will adjust start/end dates, when- needed, so that they fall on subperiod boundaries.-- Examples:--- -b 2016/3/17 begin on St. Patrick's day 2016- -e 12/1 end at the start of december 1st of the current year- (11/30 will be the last date included)- -b thismonth all transactions on or after the 1st of the current month- -p thismonth all transactions in the current month- date:2016/3/17.. the above written as queries instead (.. can also be- replaced with -)- date:..12/1- date:thismonth..- date:thismonth-- Report intervals- A report interval can be specified so that commands like register, bal-- ance and activity become multi-period, showing each subperiod as a sep-- arate row or column.-- The following "standard" report intervals can be enabled by using their- corresponding flag:-- -D/--daily, -W/--weekly, -M/--monthly, -Q/--quarterly, -Y/--yearly.-- These standard intervals always start on natural interval boundaries:- eg --weekly starts on mondays, --monthly starts on the first of the- month, --yearly always starts on January 1st, etc.-- Certain more complex intervals, and more flexible boundary dates, can- be specified by -p/--period. These are described in period expres-- sions, below.-- Report intervals can only be specified by the flags above, and not by- query arguments, currently.-- Report intervals have another effect: multi-period reports are always- expanded to fill a whole number of subperiods. So if you use a report- interval (other than --daily), and you have specified a start or end- date, you may notice those dates being overridden (ie, the report- starts earlier than your requested start date, or ends later than your- requested end date). This is done to ensure "full" first and last sub-- periods, so that all subperiods' numbers are comparable.-- Period expressions- The -p/--period option accepts period expressions, a shorthand way of- expressing a start date, end date, and/or report interval all at once.-- Here's a basic period expression specifying the first quarter of 2009.- Note, hledger always treats start dates as inclusive and end dates as- exclusive:-- -p "from 2009/1/1 to 2009/4/1"-- Keywords like "from" and "to" are optional, and so are the spaces, as- long as you don't run two dates together. "to" can also be written as- ".." or "-". These are equivalent to the above:--- -p "2009/1/1 2009/4/1"- -p2009/1/1to2009/4/1- -p2009/1/1..2009/4/1-- Dates are smart dates, so if the current year is 2009, the above can- also be written as:--- -p "1/1 4/1"-- -p "january-apr"- -p "this year to 4/1"-- If you specify only one date, the missing start or end date will be the- earliest or latest transaction in your journal:--- -p "from 2009/1/1" everything after january- 1, 2009- -p "from 2009/1" the same- -p "from 2009" the same- -p "to 2009" everything before january- 1, 2009-- A single date with no "from" or "to" defines both the start and end- date like so:--- -p "2009" the year 2009; equivalent- to "2009/1/1 to 2010/1/1"- -p "2009/1" the month of jan; equiva-- lent to "2009/1/1 to- 2009/2/1"- -p "2009/1/1" just that day; equivalent- to "2009/1/1 to 2009/1/2"-- Or you can specify a single quarter like so:--- -p "2009Q1" first quarter of 2009,- equivalent to "2009/1/1 to- 2009/4/1"- -p "q4" fourth quarter of the cur-- rent year-- The argument of -p can also begin with, or be, a report interval- expression. The basic report intervals are daily, weekly, monthly,- quarterly, or yearly, which have the same effect as the -D,-W,-M,-Q, or- -Y flags. Between report interval and start/end dates (if any), the- word in is optional. Examples:--- -p "weekly from 2009/1/1 to 2009/4/1"- -p "monthly in 2008"- -p "quarterly"-- Note that weekly, monthly, quarterly and yearly intervals will always- start on the first day on week, month, quarter or year accordingly, and- will end on the last day of same period, even if associated period- expression specifies different explicit start and end date.-- For example:--- -p "weekly from 2009/1/1 starts on 2008/12/29, closest preceding Mon-- to 2009/4/1" day- -p "monthly in starts on 2018/11/01- 2008/11/25"- -p "quarterly from starts on 2009/04/01, ends on 2009/06/30,- 2009-05-05 to 2009-06-01" which are first and last days of Q2 2009- -p "yearly from starts on 2009/01/01, first day of 2009- 2009-12-29"-- The following more complex report intervals are also supported:- biweekly, fortnightly, bimonthly, every day|week|month|quarter|year,- every N days|weeks|months|quarters|years.-- All of these will start on the first day of the requested period and- end on the last one, as described above.-- Examples:--- -p "bimonthly from 2008" periods will have boundaries on 2008/01/01,- 2008/03/01, ...- -p "every 2 weeks" starts on closest preceding Monday- -p "every 5 month from periods will have boundaries on 2009/03/01,- 2009/03" 2009/08/01, ...-- If you want intervals that start on arbitrary day of your choosing and- span a week, month or year, you need to use any of the following:-- every Nth day of week, every WEEKDAYNAME (eg- mon|tue|wed|thu|fri|sat|sun), every Nth day [of month], every Nth WEEK-- DAYNAME [of month], every MM/DD [of year], every Nth MMM [of year],- every MMM Nth [of year].-- Examples:--- -p "every 2nd day of periods will go from Tue to Tue- week"- -p "every Tue" same- -p "every 15th day" period boundaries will be on 15th of each- month- -p "every 2nd Monday" period boundaries will be on second Monday of- each month- -p "every 11/05" yearly periods with boundaries on 5th of Nov- -p "every 5th Nov" same- -p "every Nov 5th" same-- Show historical balances at end of 15th each month (N is exclusive end- date):-- hledger balance -H -p "every 16th day"-- Group postings from start of wednesday to end of next tuesday (N is- start date and exclusive end date):-- hledger register checking -p "every 3rd day of week"--DEPTH- With the --depth N option (short form: -N), commands like account, bal-- ance and register will show only the uppermost accounts in the account- tree, down to level N. Use this when you want a summary with less- detail. This flag has the same effect as a depth: query argument (so- -2, --depth=2 or depth:2 are equivalent).--QUERIES- One of hledger's strengths is being able to quickly report on a precise- subset of your data. Most hledger commands accept optional query argu-- ments to restrict their scope. The syntax is as follows:-- o Zero or more space-separated query terms. These are most often- account name substrings:-- utilities food:groceries-- o Terms with spaces or other special characters should be enclosed in- quotes:-- "personal care"-- o Regular expressions are also supported:-- "^expenses\b" "accounts (payable|receivable)"-- o Add a query type prefix to match other parts of the data:-- date:202012- desc:amazon cur:USD amt:">100" status:-- o Add a not: prefix to negate a term:-- not:cur:USD-- Query types- Here are the types of query term available. Remember these can also be- prefixed with not: to convert them into a negative match.-- acct:REGEX, REGEX- 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.-- amt:N, amt:<N, amt:<=N, amt:>N, amt:>=N- 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-- erwise, the absolute magnitudes are compared, ignoring sign.-- code:REGEX- Match by transaction code (eg check number).-- cur:REGEX- Match postings or transactions including any amounts whose cur-- rency/commodity symbol is fully matched by REGEX. (For a 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- escaping. So eg to match the dollar sign:- hledger print cur:\\$.-- desc:REGEX- Match transaction descriptions.-- date:PERIODEXPR- Match dates (or with the --date2 flag, secondary dates) within the- specified period. PERIODEXPR is a period expression with no report- interval. Examples:- date:2016, date:thismonth, date:2/1-2/15, date:2021-07-27..nextquarter.-- date2:PERIODEXPR- Match secondary dates within the specified period (independent of the- --date2 flag).-- depth:N- Match (or display, depending on command) accounts at or above this- depth.-- note:REGEX- Match transaction notes (the part of the description right of |, or the- whole description if there's no |).-- payee:REGEX- Match transaction payee/payer names (the part of the description left- of |, or the whole description if there's no |).-- real:, real:0- Match real or virtual postings respectively.-- status:, status:!, status:*- Match unmarked, pending, or cleared transactions respectively.-- tag:REGEX[=REGEX]- Match by tag name, and optionally also by tag value. (To match only by- value, use tag:.=REGEX.) Note that postings also inherit tags from- their transaction, and transactions also acquire tags from their post-- ings, when querying.-- (inacct:ACCTNAME- A special query term used automatically in hledger-web only: tells- hledger-web to show the transaction register for an account.)-- Combining query terms- Most commands select things which match:-- o any of the description terms AND-- o any of the account terms AND-- o any of the status terms AND-- o all the other terms.-- while the print command shows transactions which:-- o match any of the description terms AND-- o have any postings matching any of the positive account terms AND-- o have no postings matching any of the negative account terms AND-- o match all the other terms.-- You can do more powerful queries (such as AND-ing two like terms) by- running a first query with print, and piping the result into a second- hledger command. Eg: how much of food expenses was paid with cash ?-- $ hledger print assets:cash | hledger f- -I balance expenses:food-- If you are interested in full boolean expressions for queries, see- #203.-- Queries and command options- Some queries can also be expressed as command-line options: depth:2 is- equivalent to --depth 2, date:2020 is equivalent to -p 2020, etc. When- you mix command options and query arguments, generally the resulting- query is their intersection.-- Queries and account aliases- When account names are rewritten with --alias or alias, acct: will- match either the old or the new account name.-- Queries and valuation- When amounts are converted to other commodities in cost or value- reports, 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- reversed, see #1625).-- Querying with account aliases- When account names are rewritten with --alias or alias, note that acct:- will match either the old or the new account name.-- Querying with cost or value- When amounts are converted to other commodities in cost or value- reports, 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- discussion at #1625.--COSTING- The -B/--cost flag converts amounts to their cost or sale amount at- transaction time, if they have a transaction price specified. If this- flag is supplied, hledger will perform cost conversion first, and will- apply any market price valuations (if requested) afterwards.--VALUATION- Instead of reporting amounts in their original commodity, hledger can- convert them to cost/sale amount (using the conversion rate recorded in- the transaction), and/or to market value (using some market price on a- certain date). This is controlled by the --value=TYPE[,COMMODITY]- option, 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- valuation commodity, using the market prices in effect on the valuation- date(s), if any. More on these in a minute.-- -X: Value in specified commodity- The -X/--exchange=COMM option is like -V, except you tell it which cur-- rency you want to convert to, and it tries to convert everything to- that.-- Valuation date- Since market prices can change from day to day, market value reports- have a valuation date (or more than one), which determines which market- prices will be used.-- For single period reports, if an explicit report end date is specified,- that will be used as the valuation date; otherwise the valuation date- is the journal's end date.-- For multiperiod reports, each column/period is valued on the last day- of the period, by default.-- Market prices- To convert a commodity A to its market value in another commodity B,- hledger looks for a suitable market price (exchange rate) as follows,- in this order of preference :-- 1. A declared market price or inferred market price: A's latest market- price in B on or before the valuation date as declared by a P direc-- tive, or (with the --infer-market-price flag) inferred from transac-- tion prices.-- 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-- bining the shortest chain of "forward" (only 1 above) market prices,- leading from A to B.-- 4. Any chain of market prices: a chain of any market prices, including- both forward and reverse prices (1 and 2 above), leading from A to- B.-- There is a limit to the length of these price chains; if hledger- reaches that length without finding a complete chain or exhausting all- possibilities, it will give up (with a "gave up" message visible in- --debug=2 output). That limit is currently 1000.-- Amounts for which no suitable market price can be found, are not con-- verted.-- --infer-market-price: market prices from transactions- Normally, market value in hledger is fully controlled by, and requires,- P directives in your journal. Since adding and updating those can be a- chore, and since transactions usually take place at close to market- value, why not use the recorded transaction prices as additional market- prices (as Ledger does) ? We could produce value reports without need-- ing P directives at all.-- Adding the --infer-market-price flag to -V, -X or --value enables this.- So for example, hledger bs -V --infer-market-price will get market- prices both from P directives and from transactions. (And if both- occur on 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.-- --infer-market-price can infer market prices from:-- o multicommodity transactions with explicit prices (@/@@)-- o multicommodity transactions with implicit prices (no @, two commodi-- ties, unbalanced). (With these, the order of postings matters.- hledger print -x can be useful for troubleshooting.)-- o but not, currently, from "more correct" multicommodity transactions- (no @, multiple commodities, balanced).-- Valuation commodity- When you specify a valuation commodity (-X COMM or --value TYPE,COMM):- hledger will convert all amounts to COMM, wherever it can find a suit-- able market price (including by reversing or chaining prices).-- When you leave the valuation commodity unspecified (-V or --value- TYPE):- For each commodity A, hledger picks a default valuation commodity as- follows, in this order of preference:-- 1. The price commodity from the latest P-declared market price for A on- or before valuation date.-- 2. The price commodity from the latest P-declared market price for A on- any date. (Allows conversion to proceed when there are inferred- prices before the valuation date.)-- 3. If there are no P directives at all (any commodity or date) and the- --infer-market-price flag is used: the price commodity from the lat-- est transaction-inferred price for A on or before valuation date.-- This means:-- o If you have P directives, they determine which commodities -V will- convert, and to what.-- o If you have no P directives, and use the --infer-market-price flag,- transaction prices determine it.-- Amounts for which no valuation commodity can be found are not con-- verted.-- Simple valuation examples- Here are some quick examples of -V:-- ; one euro is worth this many dollars from nov 1- P 2016/11/01 EUR $1.10-- ; purchase some euros on nov 3- 2016/11/3- assets:euros EUR100- assets:checking-- ; the euro is worth fewer dollars by dec 21- P 2016/12/21 EUR $1.03-- How many euros do I have ?-- $ hledger -f t.j bal -N euros- EUR100 assets:euros-- What are they worth at end of nov 3 ?-- $ hledger -f t.j bal -N euros -V -e 2016/11/4- $110.00 assets:euros-- What are they worth after 2016/12/21 ? (no report end date specified,- defaults to today)-- $ hledger -f t.j bal -N euros -V- $103.00 assets:euros-- --value: Flexible valuation- -V and -X are special cases of the more general --value option:-- --value=TYPE[,COMM] TYPE is then, end, now or YYYY-MM-DD.- COMM is an optional commodity symbol.- Shows amounts converted to:- - default valuation commodity (or COMM) using market prices at posting dates- - default valuation commodity (or COMM) using market prices at period end(s)- - default valuation commodity (or COMM) using current market prices- - default valuation commodity (or COMM) using market prices at some date-- The TYPE part selects cost or value and valuation date:-- --value=then- Convert amounts to their value in the default valuation commod-- ity, using market prices on each posting's date.-- --value=end- Convert amounts to their value in the default valuation commod-- ity, using market prices on the last day of the report period- (or if unspecified, the journal's end date); or in multiperiod- reports, market prices on the last day of each subperiod.-- --value=now- Convert amounts to their value in the default valuation commod-- ity using current market prices (as of when report is gener-- ated).-- --value=YYYY-MM-DD- Convert amounts to their value in the default valuation commod-- ity using market prices on this date.-- To select a different valuation commodity, add the optional ,COMM part:- a comma, then the target commodity's symbol. Eg: --value=now,EUR.- hledger will do its best to convert amounts to this commodity, deducing- market prices as described above.-- More valuation examples- Here are some examples showing the effect of --value, as seen with- print:-- P 2000-01-01 A 1 B- P 2000-02-01 A 2 B- P 2000-03-01 A 3 B- P 2000-04-01 A 4 B-- 2000-01-01- (a) 1 A @ 5 B-- 2000-02-01- (a) 1 A @ 6 B-- 2000-03-01- (a) 1 A @ 7 B-- Show the cost of each posting:-- $ hledger -f- print --cost- 2000-01-01- (a) 5 B-- 2000-02-01- (a) 6 B-- 2000-03-01- (a) 7 B-- Show the value as of the last day of the report period (2000-02-29):-- $ hledger -f- print --value=end date:2000/01-2000/03- 2000-01-01- (a) 2 B-- 2000-02-01- (a) 2 B-- With no report period specified, that shows the value as of the last- day of the journal (2000-03-01):-- $ hledger -f- print --value=end- 2000-01-01- (a) 3 B-- 2000-02-01- (a) 3 B-- 2000-03-01- (a) 3 B-- Show the current value (the 2000-04-01 price is still in effect today):-- $ hledger -f- print --value=now- 2000-01-01- (a) 4 B-- 2000-02-01- (a) 4 B-- 2000-03-01- (a) 4 B-- Show the value on 2000/01/15:-- $ hledger -f- print --value=2000-01-15- 2000-01-01- (a) 1 B-- 2000-02-01- (a) 1 B-- 2000-03-01- (a) 1 B-- You may need to explicitly set a commodity's display style, when- reverse prices are used. Eg this output might be surprising:-- P 2000-01-01 A 2B-- 2000-01-01- a 1B- b-- $ hledger print -x -X A- 2000-01-01- a 0- b 0-- Explanation: because there's no amount or commodity directive specify-- ing a display style for A, 0.5A gets the default style, which shows no- decimal digits. Because the displayed amount looks like zero, the com-- modity symbol and minus sign are not displayed either. Adding a com-- modity directive sets a more useful display style for A:-- P 2000-01-01 A 2B- commodity 0.00A-- 2000-01-01- a 1B- b-- $ hledger print -X A- 2000-01-01- a 0.50A- b -0.50A-- Effect of valuation on reports- Here is a reference for how valuation is supposed to affect each part- of hledger's reports (and a glossary). (It's wide, you'll have to- scroll sideways.) It may be useful when troubleshooting. If you find- problems, please report them, ideally with a reproducible example.- Related: #329, #1083.--- Report -B, --cost -V, -X --value=then --value=end --value=DATE,- type --value=now- ------------------------------------------------------------------------------------------------ print- posting cost value at value at posting value at value at- amounts report end date report or DATE/today- or today journal end- balance unchanged unchanged unchanged unchanged unchanged- asser-- tions/assign-- ments-- register- starting bal- cost value at day valued at day value at day value at- ance (-H) before each historical before DATE/today- report or posting was made report or- journal journal- start start- posting cost value at value at posting value at value at- amounts report end date report or DATE/today- or today journal end- summary post- summarised value at sum of postings value at value at- ing amounts cost period ends in interval, val- period ends DATE/today- with report ued at interval- interval start- running sum/average sum/average sum/average of sum/average sum/average- total/average of displayed of displayed displayed values of displayed of displayed- values values values values---- balance (bs,- bse, cf, is)- balance sums of value at value at posting value at value at- changes costs report end date report or DATE/today of- or today of journal end sums of post-- sums of of sums of ings- postings postings- budget like balance like balance like balance like bal- like balance- amounts changes changes changes ances changes- (--budget)- grand total sum of dis- sum of dis- sum of displayed sum of dis- sum of dis-- played val- played val- valued played val- played values- ues ues ues-- balance (bs,- bse, cf, is)- with report- interval- starting bal- sums of value at sums of values of value at sums of post-- ances (-H) costs of report start postings before report start ings before- postings of sums of report start at of sums of report start- before all postings respective post- all postings- report start before ing dates before- report start report start- balance sums of same as sums of values of balance value at- changes (bal, costs of --value=end postings in change in DATE/today of- is, bs postings in period at respec- each period, sums of post-- --change, cf period tive posting valued at ings- --change) dates period ends- end balances sums of same as sums of values of period end value at- (bal -H, is costs of --value=end postings from balances, DATE/today of- --H, bs, cf) postings before period valued at sums of post-- from before start to period period ends ings- report start end at respective- to period posting dates- end- budget like balance like balance like balance like bal- like balance- amounts changes/end changes/end changes/end bal- ances changes/end- (--budget) balances balances ances balances- row totals, sums, aver- sums, aver- sums, averages of sums, aver- sums, aver-- row averages ages of dis- ages of dis- displayed values ages of dis- ages of dis-- (-T, -A) played val- played val- played val- played values- ues ues ues- column totals sums of dis- sums of dis- sums of displayed sums of dis- sums of dis-- played val- played val- values played val- played values- ues ues ues- grand total, sum, average sum, average sum, average of sum, average sum, average- grand average of column of column column totals of column of column- totals totals totals totals--- --cumulative is omitted to save space, it works like -H but with a zero- starting balance.-- Glossary:-- cost calculated using price(s) recorded in the transaction(s).-- value market value using available market price declarations, or the- unchanged amount if no conversion rate can be found.-- report start- the first day of the report period specified with -b or -p or- date:, otherwise today.-- report or journal start- the first day of the report period specified with -b or -p or- date:, otherwise the earliest transaction date in the journal,- otherwise today.-- report end- the last day of the report period specified with -e or -p or- date:, otherwise today.-- report or journal end- the last day of the report period specified with -e or -p or- date:, otherwise the latest transaction date in the journal,- otherwise today.-- report interval- a flag (-D/-W/-M/-Q/-Y) or period expression that activates the- report's multi-period mode (whether showing one or many subperi-- ods).--PIVOTING- Normally hledger sums amounts, and organizes them in a hierarchy, based- on account name. The --pivot FIELD option causes it to sum and orga-- nize hierarchy based on the value of some other field instead. FIELD- can be: code, description, payee, note, or the full name (case insensi-- tive) of any tag. As with account names, values containing colon:sepa-- rated:parts will be displayed hierarchically in reports.-- --pivot is a general option affecting all reports; you can think of- hledger transforming the journal before any other processing, replacing- every posting's account name with the value of the specified field on- that posting, inheriting it from the transaction or using a blank value- if it's not present.-- An example:-- 2016/02/16 Member Fee Payment- assets:bank account 2 EUR- income:member fees -2 EUR ; member: John Doe-- Normal balance report showing account names:-- $ hledger balance- 2 EUR assets:bank account- -2 EUR income:member fees- --------------------- 0-- Pivoted balance report, using member: tag values instead:-- $ hledger balance --pivot member- 2 EUR- -2 EUR John Doe- --------------------- 0-- One way to show only amounts with a member: value (using a query,- described below):-- $ hledger balance --pivot member tag:member=.- -2 EUR John Doe- --------------------- -2 EUR-- Another way (the acct: query matches against the pivoted "account- name"):-- $ hledger balance --pivot member acct:.- -2 EUR John Doe- --------------------- -2 EUR--OUTPUT- Output destination- hledger commands send their output to the terminal by default. You can- of course redirect this, eg into a file, using standard shell syntax:-- $ hledger print > foo.txt-- Some commands (print, register, stats, the balance commands) also pro-- vide the -o/--output-file option, which does the same thing without- needing the shell. Eg:-- $ hledger print -o foo.txt- $ hledger print -o - # write to stdout (the default)-- hledger can optionally produce debug output (if enabled with- --debug=N); this goes to stderr, and is not affected by -o/--output-- file. If you need to capture it, use shell redirects, eg: hledger bal- --debug=3 >file 2>&1.-- Output format- Some commands (print, register, the balance commands) offer a choice of- output format. In addition to the usual plain text format (txt), there- are CSV (csv), HTML (html), JSON (json) and SQL (sql). This is con-- trolled by the -O/--output-format option:-- $ hledger print -O csv-- or, by a file extension specified with -o/--output-file:-- $ hledger balancesheet -o foo.html # write HTML to foo.html-- The -O option can be used to override the file extension if needed:-- $ hledger balancesheet -o foo.txt -O html # write HTML to foo.txt-- Some notes about JSON output:-- o This feature is marked experimental, and not yet much used; you- should expect our JSON to evolve. Real-world feedback is welcome.-- o Our JSON is rather large and verbose, as it is quite a faithful rep-- resentation of hledger's internal data types. To understand the- JSON, read the Haskell type definitions, which are mostly in- https://github.com/simonmichael/hledger/blob/master/hledger-- lib/Hledger/Data/Types.hs.-- o hledger represents quantities as Decimal values storing up to 255- significant digits, eg for repeating decimals. Such numbers can- arise in practice (from automatically-calculated transaction prices),- and would break most JSON consumers. So in JSON, we show quantities- as simple Numbers with at most 10 decimal places. We don't limit the- number of integer digits, but that part is under your control. We- hope this approach will not cause problems in practice; if you find- otherwise, please let us know. (Cf #1195)-- Notes about SQL output:-- o SQL output is also marked experimental, and much like JSON could use- real-world feedback.-- o SQL output is expected to work with sqlite, MySQL and PostgreSQL-- o SQL output is structured with the expectations that statements will- be executed in the empty database. If you already have tables cre-- ated via SQL output of hledger, you would probably want to either- clear tables of existing data (via delete or truncate SQL statements)- or drop tables completely as otherwise your postings will be duped.--COMMANDS- hledger provides a number of commands for producing reports and manag-- ing your data. Run hledger with no arguments to list the commands- available, and hledger CMD to run a command. CMD can be the full com-- mand name, or its standard abbreviation shown in the commands list, or- any unambiguous prefix of the name. Eg: hledger bal.-- Here are the built-in commands, with the most often-used in bold:-- Data entry:-- These data entry commands are the only ones which can modify your jour-- nal file.-- o add - add transactions using guided prompts-- o import - add any new transactions from other files (eg csv)-- Data management:-- o check - check for various kinds of issue in the data-- o close (equity) - generate balance-resetting transactions-- o diff - compare account transactions in two journal files-- o rewrite - generate extra postings, similar to print --auto-- Financial statements:-- o aregister (areg) - show transactions in a particular account-- o balancesheet (bs) - show assets, liabilities and net worth-- o balancesheetequity (bse) - show assets, liabilities and equity-- o cashflow (cf) - show changes in liquid assets-- o incomestatement (is) - show revenues and expenses-- o roi - show return on investments-- Miscellaneous reports:-- o accounts - show account names-- o activity - show postings-per-interval bar charts-- o balance (bal) - show balance changes/end balances/budgets in any- accounts-- o codes - show transaction codes-- o commodities - show commodity/currency symbols-- o descriptions - show unique transaction descriptions-- o files - show input file paths-- o help - show hledger user manuals in several formats-- o notes - show unique note segments of transaction descriptions-- o payees - show unique payee segments of transaction descriptions-- o prices - show market price records-- o print - show transactions (journal entries)-- o print-unique - show only transactions with unique descriptions-- o register (reg) - show postings in one or more accounts & running- total-- o register-match - show a recent posting that best matches a descrip-- tion-- o stats - show journal statistics-- o tags - show tag names-- o test - run self tests-- Add-on commands:-- Programs or scripts named hledger-SOMETHING in your PATH are add-on- commands; these appear in the commands list with a + mark. Two of- these are maintained and released with hledger:-- o ui - an efficient terminal interface (TUI) for hledger-- o web - a simple web interface (WUI) for hledger-- And these add-ons are maintained separately:-- o iadd - a more interactive alternative for the add command-- o interest - generates interest transactions according to various- schemes-- o stockquotes - downloads market prices for your commodities from- AlphaVantage (experimental)-- Next, the detailed command docs, in alphabetical order.-- accounts- accounts- Show account names.-- This command lists account names, either declared with account direc-- tives (--declared), posted to (--used), or both (the default). With- query arguments, only matched account names and account names refer-- enced by matched postings are shown. It shows a flat list by default.- With --tree, it uses indentation to show the account hierarchy. In- flat mode you can add --drop N to omit the first few account name com-- ponents. Account names can be depth-clipped with depth:N or --depth N- or -N.-- Examples:-- $ hledger accounts- assets:bank:checking- assets:bank:saving- assets:cash- expenses:food- expenses:supplies- income:gifts- income:salary- liabilities:debts-- activity- activity- Show an ascii barchart of posting counts per interval.-- The activity command displays an ascii histogram showing transaction- counts by day, week, month or other reporting interval (by day is the- default). With query arguments, it counts only matched transactions.-- Examples:-- $ hledger activity --quarterly- 2008-01-01 **- 2008-04-01 *******- 2008-07-01- 2008-10-01 **-- add- add- Prompt for transactions and add them to the journal. Any arguments- will be used as default inputs for the first N prompts.-- Many hledger users edit their journals directly with a text editor, or- generate them from CSV. For more interactive data entry, there is the- add command, which prompts interactively on the console for new trans-- actions, and appends them to the journal file (if there are multiple -f- FILE options, the first file is used.) Existing transactions are not- changed. This is the only hledger command that writes to the journal- file.-- To use it, just run hledger add and follow the prompts. You can add as- many transactions as you like; when you are finished, enter . or press- control-d or control-c to exit.-- Features:-- o add tries to provide useful defaults, using the most similar (by- description) recent transaction (filtered by the query, if any) as a- template.-- o You can also set the initial defaults with command line arguments.-- o Readline-style edit keys can be used during data entry.-- o The tab key will auto-complete whenever possible - accounts, descrip-- tions, dates (yesterday, today, tomorrow). If the input area is- empty, it will insert the default value.-- o If the journal defines a default commodity, it will be added to any- bare numbers entered.-- o A parenthesised transaction code may be entered following a date.-- o Comments and tags may be entered following a description or amount.-- o If you make a mistake, enter < at any prompt to go one step backward.-- o Input prompts are displayed in a different colour when the terminal- supports it.-- Example (see the tutorial for a detailed explanation):-- $ hledger add- Adding transactions to journal file /src/hledger/examples/sample.journal- Any command line arguments will be used as defaults.- Use tab key to complete, readline keys to edit, enter to accept defaults.- An optional (CODE) may follow transaction dates.- An optional ; COMMENT may follow descriptions or amounts.- If you make a mistake, enter < at any prompt to go one step backward.- To end a transaction, enter . when prompted.- To quit, enter . at a date prompt or press control-d or control-c.- Date [2015/05/22]:- Description: supermarket- Account 1: expenses:food- Amount 1: $10- Account 2: assets:checking- Amount 2 [$-10.0]:- Account 3 (or . or enter to finish this transaction): .- 2015/05/22 supermarket- expenses:food $10- assets:checking $-10.0-- Save this transaction to the journal ? [y]:- Saved.- Starting the next transaction (. or ctrl-D/ctrl-C to quit)- Date [2015/05/22]: <CTRL-D> $-- On Microsoft Windows, the add command makes sure that no part of the- file path ends with a period, as that would cause problems (#1056).-- aregister- aregister, areg-- Show the transactions and running historical balance in an account,- with each line item representing one transaction.-- aregister shows the transactions affecting a particular account and its- subaccounts, with each line item representing a whole transaction - as- in bank statements, hledger-ui, hledger-web and other accounting apps.-- Note this is unlike the register command, which shows individual post-- ings and does not always show a single account or a historical balance.-- A reminder, "historical" balances include any balance from transactions- before the report start date, so (if opening balances are recorded cor-- rectly) aregister will show the real-world balances of an account, as- you would see in a bank statement.-- As a quick rule of thumb, use aregister for reconciling real-world- asset/liability accounts and register for reviewing detailed rev-- enues/expenses.-- aregister shows the register for just one account (and its subac-- counts). This account must be specified as the first argument. You- can write either the full account name, or a case-insensitive regular- expression which will select the alphabetically first matched account.- (Eg if you have assets:aaa:checking and assets:bbb:checking accounts,- hledger areg checking would select assets:aaa:checking.)-- Any additional arguments form a query which will filter the transac-- tions shown.-- Each aregister line item shows:-- 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- (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- the -E/--empty flag to show them.-- aregister ignores a depth limit, so its final total will always match a- balance report with similar arguments.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, and json.-- aregister and custom posting dates- Transactions whose date is outside the report period can still be- shown, if they have a posting to this account dated inside the report- period. (And in this case it's the posting date that is shown.) This- ensures that aregister can show an accurate historical running balance,- matching the one shown by register -H with the same arguments.-- To filter strictly by transaction date instead, add the --txn-dates- flag. If you use this flag and some of your postings have custom- dates, it's probably best to assume the running balance is wrong.-- Examples:-- Show all transactions and historical running balance in the first- account whose name contains "checking":-- $ hledger areg checking-- Show transactions and historical running balance in all asset accounts- during july:-- $ hledger areg assets date:jul-- balance- balance, bal- Show accounts and their balances.-- 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.-- Note there are some higher-level variants of the balance command with- convenient defaults, which can be simpler to use: balancesheet, bal-- ancesheetequity, cashflow and incomestatement. When you need more con-- 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- higher-level commands as well.-- balance can show..-- o accounts as a list (-l) or a tree (-t)-- o optionally depth-limited (-[1-9])-- o sorted by declaration order and name, or by amount-- ..and their..-- o balance changes (the default)-- o or actual and planned balance changes (--budget)-- o or value of balance changes (-V)-- o or change of balance values (--valuechange)-- ..in..-- o one time period (the whole journal period by default)-- o or multiple periods (-D, -W, -M, -Q, -Y, -p INTERVAL)-- ..either..-- o per period (the default)-- o or accumulated since report start date (--cumulative)-- o or accumulated since account creation (--historical/-H)-- ..possibly converted to..-- o cost (--value=cost[,COMM]/--cost/-B)-- o or market value, as of transaction dates (--value=then[,COMM])-- o or at period ends (--value=end[,COMM])-- o or now (--value=now)-- o or at some other date (--value=YYYY-MM-DD)-- ..with..-- o totals (-T), averages (-A), percentages (-%), inverted sign- (--invert)-- o rows and columns swapped (--transpose)-- o another field used as account name (--pivot)-- o custom-formatted line items (single-period reports only) (--format)-- This command supports the output destination and output format options,- with output formats txt, csv, json, and (multi-period reports only:)- html. In txt output in a colour-supporting terminal, negative amounts- are shown in red.-- Simple balance report- With no arguments, balance shows a list of all accounts and their- change of balance - ie, the sum of posting amounts, both inflows and- outflows - during the entire period of the journal. For real-world- accounts, this should also match their end balance at the end of the- journal period (more on this below).-- Accounts are sorted by declaration order if any, and then alphabeti-- cally by account name. For instance, using examples/sample.journal:-- $ hledger bal- $1 assets:bank:saving- $-2 assets:cash- $1 expenses:food- $1 expenses:supplies- $-1 income:gifts- $-1 income:salary- $1 liabilities:debts- --------------------- 0-- 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- (revealing assets:bank:checking here):-- $ hledger -f examples/sample.journal bal -E- 0 assets:bank:checking- $1 assets:bank:saving- $-2 assets:cash- $1 expenses:food- $1 expenses:supplies- $-1 income:gifts- $-1 income:salary- $1 liabilities:debts- --------------------- 0-- The total of the amounts displayed is shown as the last line, unless- -N/--no-total is used.-- Filtered balance report- 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:-- $ hledger bal --cleared assets date:200806- $-2 assets:cash- --------------------- $-2-- List or tree mode- By default, or with -l/--flat, accounts are shown as a flat list with- their full names visible, as in the examples above.-- With -t/--tree, the account hierarchy is shown, with subaccounts'- "leaf" names indented below their parent:-- $ hledger balance- $-1 assets- $1 bank:saving- $-2 cash- $2 expenses- $1 food- $1 supplies- $-2 income- $-1 gifts- $-1 salary- $1 liabilities:debts- --------------------- 0-- 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- above).-- 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.-- o Each group of sibling accounts (ie, under a common parent) is sorted- separately.-- Depth limiting- With a depth:N query, or --depth N option, or just -N, balance reports- will show accounts only to the specified depth, hiding the deeper sub-- accounts. Account balances at the depth limit always include the bal-- ances from any hidden subaccounts (even in list mode). This can be- useful for getting an overview. Eg, limiting to depth 1:-- $ hledger balance -N -1- $-1 assets- $2 expenses- $-2 income- $1 liabilities-- You can also hide top-level account name parts, using --drop N. This- can be useful for hiding repetitive top-level account names:-- $ hledger bal expenses --drop 1- $1 food- $1 supplies- --------------------- $2--- Multi-period balance report- With a report interval (set by the -D/--daily, -W/--weekly,- -M/--monthly, -Q/--quarterly, -Y/--yearly, or -p/--period flag), bal-- ance shows a tabular report, with columns representing successive time- periods (and a title):-- $ hledger balance --quarterly income expenses -E- Balance changes in 2008:-- || 2008q1 2008q2 2008q3 2008q4- ===================++=================================- expenses:food || 0 $1 0 0- expenses:supplies || 0 $1 0 0- income:gifts || 0 $-1 0 0- income:salary || $-1 0 0 0- -------------------++---------------------------------- || $-1 $1 0 0-- Notes:-- o The report's start/end dates will be expanded, if necessary, to fully- encompass the displayed subperiods (so that the first and last subpe-- riods have the same duration as the others).-- o Leading and trailing periods (columns) containing all zeroes are not- shown, unless -E/--empty is used.-- o Accounts (rows) containing all zeroes are not shown, unless- -E/--empty is used.-- o Amounts with many commodities are shown in abbreviated form, unless- --no-elide is used. (experimental)-- o Average and/or total columns can be added with the -A/--average and- -T/--row-total flags.-- o The --transpose flag can be used to exchange rows and columns.-- o The --pivot FIELD option causes a different transaction field to be- used as "account name". See PIVOTING.-- Multi-period reports with many periods can be too wide for easy viewing- in the terminal. Here are some ways to handle that:-- o Hide the totals row with -N/--no-total-- o Convert to a single currency with -V-- o Maximize the terminal window-- o Reduce the terminal's font size-- 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- 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 &&- open a.html-- 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.-- Revenues and liability balances are typically negative, however, so -S- shows these in reverse order. To work around this, you can add- --invert to flip the signs. (Or, use one of the higher-level reports,- which flip the sign automatically. Eg: hledger incomestatement -MAS).--- Percentages- With -%/--percent, balance reports show each account's value expressed- as a percentage of the (column) total:-- $ hledger bal expenses -Q -%- Balance changes in 2008:-- || 2008Q1 2008Q2 2008Q3 2008Q4- ===================++=================================- expenses:food || 0 50.0 % 0 0- expenses:supplies || 0 50.0 % 0 0- -------------------++---------------------------------- || 0 100.0 % 0 0-- Note it is not useful to calculate percentages if the amounts in a col-- umn have mixed signs. In this case, make a separate report for each- sign, eg:-- $ hledger bal -% amt:`>0`- $ hledger bal -% amt:`<0`-- Similarly, if the amounts in a column have mixed commodities, convert- them to one commodity with -B, -V, -X or --value, or make a separate- report for each commodity:-- $ hledger bal -% cur:\\$- $ hledger bal -% cur:EUR-- Balance change, end balance- 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- account 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- your timezone). It is the sum of previous 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!)-- In general, balance changes are what you want to see when reviewing- revenues and expenses, and historical end balances are what you want to- see when reviewing or reconciling asset, liability and equity accounts.-- 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- journal covers the account's full lifetime.-- 2. Include all of of the account's prior postings in the report, by not- specifying a report start date, or by using the -H/--historical- flag. (-H causes report start date to be ignored when summing post-- ings.)-- Balance report types- For more flexible reporting, there are three important option groups:-- hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]- ...-- The first two are the most important: calculation type selects the- basic calculation to perform for each table cell, while accumulation- type says which postings should be included in each cell's calculation.- Typically one or both of these are selected by default, so you don't- need to write them explicitly. A valuation type can be added if you- want to convert the basic report to value or cost.-- Calculation type:- The basic calculation to perform for each table cell. It is one of:-- o --sum : sum the posting amounts (default)-- o --budget : like --sum but also show a goal amount-- o --valuechange : show the change in period-end historical balance val-- ues-- Accumulation type:- Which postings should be included in each cell's calculation. It is- one of:-- o --change : postings from column start to column end, ie within the- cell's period. Typically used to see revenues/expenses. (default- for balance, incomestatement)-- o --cumulative : postings from report start to column end, eg to show- changes accumulated since the report's start date. Rarely used.-- o --historical/-H : postings from journal start to column end, ie all- postings from account creation to the end of the cell's period. Typ-- ically used to see historical end balances of assets/liabili-- ties/equity. (default for balancesheet, balancesheetequity, cash-- flow)-- Valuation type:- Which kind of valuation, valuation date(s) and optionally a target val-- uation commodity to use. It is one of:-- o no valuation, show amounts in their original commodities (default)-- o --value=cost[,COMM] : no valuation, show amounts converted to cost-- o --value=then[,COMM] : show value at transaction dates-- o --value=end[,COMM] : show value at period end date(s) (default with- --valuechange)-- o --value=now[,COMM] : show value at today's date-- o --value=YYYY-MM-DD[,COMM] : show value at another date-- or one of their aliases: --cost/-B, --market/-V or --exchange/-X.-- 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-- ancesheet/balancesheetequity commands-- o --cumulative or --historical disables --row-total/-T-- For reference, here is what the combinations of accumulation and valua-- tion show:--- Valua- no valuation --value= then --value= end --value= YYYY-- tion: MM-DD /now- >Accumu-- lation:- v- ------------------------------------------------------------------------------------- --change change in period sum of posting- period-end DATE-value of- date market val- value of change change in- ues in period in period period- --cumu- change from sum of posting- period-end DATE-value of- lative report 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 end bal- start to period start to period to period end- ance) end end-- Useful balance reports- Some frequently used balance options/reports are:-- o bal -M revenues expenses- 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- available as the balancesheet command.-- o bal -M -H assets liabilities equity- 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- cashflow command.-- Also:-- o bal -M expenses -2 -SA- Show monthly expenses summarised to depth 2 and sorted by average- amount.-- o bal -M --budget expenses- Show monthly expenses and budget goals.-- o bal -M --valuechange investments- Show monthly change in market value of investment assets.-- o bal investments --valuechange -D date:lastweek amt:'>1000' -STA- [--invert]- Show top gainers [or losers] last week-- Budget report- The --budget report type activates extra columns showing any budget- goals for each account and period. The budget goals are defined by- periodic transactions. This is very useful for comparing planned and- actual income, expenses, time usage, etc.-- For example, you can take average monthly expenses in the common- expense categories to construct a minimal monthly budget:-- ;; Budget- ~ monthly- income $2000- expenses:food $400- expenses:bus $50- expenses:movies $30- assets:bank:checking-- ;; Two months worth of expenses- 2017-11-01- income $1950- expenses:food $396- expenses:bus $49- expenses:movies $30- expenses:supplies $20- assets:bank:checking-- 2017-12-01- income $2100- expenses:food $412- expenses:bus $53- expenses:gifts $100- assets:bank:checking-- You can now see a monthly budget report:-- $ hledger balance -M --budget- Budget performance in 2017/11/01-2017/12/31:-- || Nov Dec- ======================++====================================================- assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- expenses || $495 [ 103% of $480] $565 [ 118% of $480]- expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]- expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]- expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]- income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]- ----------------------++----------------------------------------------------- || 0 [ 0] 0 [ 0]-- This is different from a normal balance report in several ways:-- o Only accounts with budget goals during the report period are shown,- by default.-- o In each column, in square brackets after the actual amount, budget- goal amounts are shown, and the actual/goal percentage. (Note: bud-- get goals should be in the same commodity as the actual amount.)-- o All parent accounts are always shown, even in list mode. Eg assets,- assets:bank, and expenses above.-- o Amounts always include all subaccounts, budgeted or unbudgeted, even- in list mode.-- This means that the numbers displayed will not always add up! Eg above,- the expenses actual amount includes the gifts and supplies transac-- tions, but the expenses:gifts and expenses:supplies accounts are not- shown, as they have no budget amounts declared.-- This can be confusing. When you need to make things clearer, use the- -E/--empty flag, which will reveal all accounts including unbudgeted- ones, giving the full picture. Eg:-- $ hledger balance -M --budget --empty- Budget performance in 2017/11/01-2017/12/31:-- || Nov Dec- ======================++====================================================- assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]- expenses || $495 [ 103% of $480] $565 [ 118% of $480]- expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]- expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]- expenses:gifts || 0 $100- expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]- expenses:supplies || $20 0- income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]- ----------------------++----------------------------------------------------- || 0 [ 0] 0 [ 0]-- You can roll over unspent budgets to next period with --cumulative:-- $ hledger balance -M --budget --cumulative- Budget performance in 2017/11/01-2017/12/31:-- || Nov Dec- ======================++====================================================- assets || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]- assets:bank || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]- assets:bank:checking || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]- expenses || $495 [ 103% of $480] $1060 [ 110% of $960]- expenses:bus || $49 [ 98% of $50] $102 [ 102% of $100]- expenses:food || $396 [ 99% of $400] $808 [ 101% of $800]- expenses:movies || $30 [ 100% of $30] $30 [ 50% of $60]- income || $1950 [ 98% of $2000] $4050 [ 101% of $4000]- ----------------------++----------------------------------------------------- || 0 [ 0] 0 [ 0]-- For more examples and notes, see Budgeting.-- Budget report start date- This might be a bug, but for now: when making budget reports, it's a- good idea to explicitly set the report's start date to the first day of- a reporting period, because a periodic rule like ~ monthly generates- its transactions on the 1st of each month, and if your journal has no- regular transactions on the 1st, the default report start date could- exclude that budget goal, which can be a little surprising. Eg here- the default report period is just the day of 2020-01-15:-- ~ monthly in 2020- (expenses:food) $500-- 2020-01-15- expenses:food $400- assets:checking-- $ hledger bal expenses --budget- Budget performance in 2020-01-15:-- || 2020-01-15- ==============++============- <unbudgeted> || $400- --------------++------------- || $400-- To avoid this, specify the budget report's period, or at least the- start date, with -b/-e/-p/date:, to ensure it includes the budget goal- transactions (periodic transactions) that you want. Eg, adding -b- 2020/1/1 to the above:-- $ hledger bal expenses --budget -b 2020/1/1- Budget performance in 2020-01-01..2020-01-15:-- || 2020-01-01..2020-01-15- ===============++========================- expenses:food || $400 [80% of $500]- ---------------++------------------------- || $400 [80% of $500]-- Nested budgets- You can add budgets to any account in your account hierarchy. If you- have budgets on both parent account and some of its children, then bud-- get(s) of the child account(s) would be added to the budget of their- parent, much like account balances behave.-- In the most simple case this means that once you add a budget to any- account, all its parents would have budget as well.-- To illustrate this, consider the following budget:-- ~ monthly from 2019/01- expenses:personal $1,000.00- expenses:personal:electronics $100.00- liabilities-- With this, monthly budget for electronics is defined to be $100 and- budget for personal expenses is an additional $1000, which implicitly- means that budget for both expenses:personal and expenses is $1100.-- Transactions in expenses:personal:electronics will be counted both- towards its $100 budget and $1100 of expenses:personal , and transac-- tions in any other subaccount of expenses:personal would be counted- towards only towards the budget of expenses:personal.-- For example, let's consider these transactions:-- ~ monthly from 2019/01- expenses:personal $1,000.00- expenses:personal:electronics $100.00- liabilities-- 2019/01/01 Google home hub- expenses:personal:electronics $90.00- liabilities $-90.00-- 2019/01/02 Phone screen protector- expenses:personal:electronics:upgrades $10.00- liabilities-- 2019/01/02 Weekly train ticket- expenses:personal:train tickets $153.00- liabilities-- 2019/01/03 Flowers- expenses:personal $30.00- liabilities-- As you can see, we have transactions in expenses:personal:electron-- ics:upgrades and expenses:personal:train tickets, and since both of- these accounts are without explicitly defined budget, these transac-- tions would be counted towards budgets of expenses:personal:electronics- and expenses:personal accordingly:-- $ hledger balance --budget -M- Budget performance in 2019/01:-- || Jan- ===============================++===============================- expenses || $283.00 [ 26% of $1100.00]- expenses:personal || $283.00 [ 26% of $1100.00]- expenses:personal:electronics || $100.00 [ 100% of $100.00]- liabilities || $-283.00 [ 26% of $-1100.00]- -------------------------------++-------------------------------- || 0 [ 0]-- And with --empty, we can get a better picture of budget allocation and- consumption:-- $ hledger balance --budget -M --empty- Budget performance in 2019/01:-- || Jan- ========================================++===============================- expenses || $283.00 [ 26% of $1100.00]- expenses:personal || $283.00 [ 26% of $1100.00]- expenses:personal:electronics || $100.00 [ 100% of $100.00]- expenses:personal:electronics:upgrades || $10.00- expenses:personal:train tickets || $153.00- liabilities || $-283.00 [ 26% of $-1100.00]- ----------------------------------------++-------------------------------- || 0 [ 0]-- Customising single-period balance reports- For single-period balance reports displayed in the terminal (only), you- can use --format FMT to customise the format and content of each line.- Eg:-- $ hledger balance --format "%20(account) %12(total)"- assets $-1- bank:saving $1- cash $-2- expenses $2- food $1- supplies $1- income $-2- gifts $-1- salary $-1- liabilities:debts $1- ---------------------------------- 0-- The FMT format string (plus a newline) specifies the formatting applied- to each account/balance pair. It may contain any suitable text, with- data fields interpolated like so:-- %[MIN][.MAX](FIELDNAME)-- o MIN pads with spaces to at least this width (optional)-- o MAX truncates at this width (optional)-- o FIELDNAME must be enclosed in parentheses, and can be one of:-- o depth_spacer - a number of spaces equal to the account's depth, or- if MIN is specified, MIN * depth spaces.-- o account - the account's name-- o total - the account's balance/posted total, right justified-- Also, FMT can begin with an optional prefix to control how multi-com-- modity amounts are rendered:-- o %_ - render on multiple lines, bottom-aligned (the default)-- o %^ - render on multiple lines, top-aligned-- o %, - render on one line, comma-separated-- There are some quirks. Eg in one-line mode, %(depth_spacer) has no- effect, instead %(account) has indentation built in. Experimentation- may be needed to get pleasing results.-- Some example formats:-- o %(total) - the account's total-- o %-20.20(account) - the account's name, left justified, padded to 20- characters and clipped at 20 characters-- o %,%-50(account) %25(total) - account name padded to 50 characters,- total padded to 20 characters, with multiple commodities rendered on- one line-- o %20(total) %2(depth_spacer)%-(account) - the default format for the- single-column balance report-- balancesheet- balancesheet, bs- This command displays a balance sheet, showing historical ending bal-- ances of asset and liability accounts. (To see equity as well, use the- balancesheetequity command.) Amounts are shown with normal positive- sign, as in conventional financial statements.-- The asset and liability accounts shown are those accounts declared with- the Asset or Cash or Liability type, or otherwise all accounts under a- top-level asset or liability account (case insensitive, plurals- allowed).-- Example:-- $ hledger balancesheet- Balance Sheet-- Assets:- $-1 assets- $1 bank:saving- $-2 cash- --------------------- $-1-- Liabilities:- $1 liabilities:debts- --------------------- $1-- Total:- --------------------- 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- flipped.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, html, and (experi-- mental) json.-- balancesheetequity- balancesheetequity, bse- This command displays a balance sheet, showing historical ending bal-- ances of asset, liability and equity accounts. Amounts are shown with- normal positive sign, as in conventional financial statements.-- The asset, liability and equity accounts shown are those accounts- declared with the Asset, Cash, Liability or Equity type, or otherwise- all accounts under a top-level asset, liability or equity account (case- insensitive, plurals allowed).-- Example:-- $ hledger balancesheetequity- Balance Sheet With Equity-- Assets:- $-2 assets- $1 bank:saving- $-3 cash- --------------------- $-2-- Liabilities:- $1 liabilities:debts- --------------------- $1-- Equity:- $1 equity:owner- --------------------- $1-- Total:- --------------------- 0-- This command 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 equity, but with- smarter account detection, and liabilities/equity displayed with their- sign flipped.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, html, and (experi-- mental) json.-- cashflow- cashflow, cf- This command displays a cashflow statement, showing the inflows and- outflows affecting "cash" (ie, liquid) assets. Amounts are shown with- normal positive sign, as in conventional financial statements.-- The "cash" accounts shown are those accounts declared with the Cash- type, or otherwise all accounts under a top-level asset account (case- insensitive, plural allowed) which do not have fixed, investment,- receivable or A/R in their name.-- Example:-- $ hledger cashflow- Cashflow Statement-- Cash flows:- $-1 assets- $1 bank:saving- $-2 cash- --------------------- $-1-- Total:- --------------------- $-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- not:receivable, but with smarter account detection.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, html, and (experi-- mental) json.-- check- check- Check for various kinds of errors in your data.-- hledger provides a number of built-in error checks to help prevent- problems in your data. Some of these are run automatically; or, you- can use this check command to run them on demand, with no output and a- zero exit code if all is well. Specify their names (or a prefix) as- argument(s).-- Some examples:-- hledger check # basic checks- hledger check -s # basic + strict checks- hledger check ordereddates payees # basic + two other checks-- Here are the checks currently available:-- Basic checks- These checks are always run automatically, by (almost) all hledger com-- mands, including check:-- 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 transaction prices or automatically-inferred transaction prices-- o assertions - all balance assertions in the journal are passing.- (This check can be disabled with -I/--ignore-assertions.)-- Strict checks- These additional checks are run when the -s/--strict (strict mode) flag- is used. Or, they can be run by giving their names as arguments to- check:-- o accounts - all account names used by transactions have been declared-- o commodities - all commodity symbols used have been declared-- o balancednoautoconversion - transactions are balanced, possibly using- explicit transaction prices but not inferred ones-- 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,- therefore optional:-- o ordereddates - transactions are ordered by date within each file-- o payees - all payees 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- https://github.com/simonmichael/hledger/tree/master/bin:-- o hledger-check-tagfiles - all tag values containing / (a forward- slash) exist as file paths-- o hledger-check-fancyassertions - more complex balance assertions are- passing-- You could make similar scripts to perform your own custom checks. See:- Cookbook -> Scripting.-- close- close, equity- Prints a "closing balances" transaction and an "opening balances"- transaction that bring account balances to and from zero, respectively.- These can be added to your journal file(s), eg to bring asset/liability- balances forward into a new journal file, or to close out rev-- enues/expenses to retained earnings at the end of a period.-- You can print just one of these transactions by using the --close or- --open flag. You can customise their descriptions with the --close-- desc and --open-desc options.-- One amountless posting to "equity:opening/closing balances" is added to- balance the transactions, by default. You can customise this account- name with --close-acct and --open-acct; if you specify only one of- these, it will be used for both.-- With --x/--explicit, the equity posting's amount will be shown. And if- it involves multiple commodities, a posting for each commodity will be- shown, as with the print command.-- With --interleaved, the equity postings are shown next to the postings- they balance, which makes troubleshooting easier.-- By default, transaction prices in the journal are ignored when generat-- ing the closing/opening transactions. With --show-costs, this cost- information is preserved (balance -B reports will be unchanged after- the transition). Separate postings are generated for each cost in each- commodity. Note this can generate very large journal entries, if you- have many foreign currency or investment transactions.-- close usage- If you split your journal files by time (eg yearly), you will typically- run this command at the end of the year, and save the closing transac-- tion as last entry of the old file, and the opening transaction as the- first entry of the new file. This makes the files self contained, so- that correct balances are reported no matter which of them are loaded.- Ie, if you load just one file, the balances are initialised correctly;- or if you load several files, the redundant closing/opening transac-- tions cancel each other out. (They will show up in print or register- reports; you can exclude them with a query like not:desc:'(open-- ing|closing) balances'.)-- If you're running a business, you might also use this command to "close- the books" at the end of an accounting period, transferring income- statement account balances to retained earnings. (You may want to- change the equity account name to something like "equity:retained earn-- ings".)-- By default, the closing transaction is dated yesterday, the balances- are calculated as of end of yesterday, and the opening transaction is- dated today. To close on some other date, use: hledger close -e OPEN-- INGDATE. Eg, to close/open on the 2018/2019 boundary, use -e 2019.- You can also use -p or date:PERIOD (any starting date is ignored).-- Both transactions will include balance assertions for the- closed/reopened accounts. You probably shouldn't use status or real-- ness filters (like -C or -R or status:) with this command, or the gen-- erated balance assertions will depend on these flags. Likewise, if you- run this command with --auto, the balance assertions will probably- always require --auto.-- Examples:-- Carrying asset/liability balances into a new file for 2019:-- $ hledger close -f 2018.journal -e 2019 assets liabilities --open- # (copy/paste the output to the start of your 2019 journal file)- $ hledger close -f 2018.journal -e 2019 assets liabilities --close- # (copy/paste the output to the end of your 2018 journal file)-- Now:-- $ hledger bs -f 2019.journal # one file - balances are correct- $ hledger bs -f 2018.journal -f 2019.journal # two files - balances still correct- $ hledger bs -f 2018.journal not:desc:closing # to see year-end balances, must exclude closing txn-- Transactions spanning the closing date can complicate matters, breaking- balance assertions:-- 2018/12/30 a purchase made in 2018, clearing the following year- expenses:food 5- assets:bank:checking -5 ; [2019/1/2]-- Here's one way to resolve that:-- ; in 2018.journal:- 2018/12/30 a purchase made in 2018, clearing the following year- expenses:food 5- liabilities:pending-- ; in 2019.journal:- 2019/1/2 clearance of last year's pending transactions- liabilities:pending 5 = 0- assets:checking-- codes- codes- List the codes seen in transactions, in the order parsed.-- This command prints the value of each transaction's code field, in the- order transactions were parsed. The transaction code is an optional- value written in parentheses between the date and description, often- used to store a cheque number, order number or similar.-- Transactions aren't required to have a code, and missing or empty codes- will not be shown by default. With the -E/--empty flag, they will be- printed as blank lines.-- You can add a query to select a subset of transactions.-- Examples:-- 1/1 (123)- (a) 1-- 1/1 ()- (a) 1-- 1/1- (a) 1-- 1/1 (126)- (a) 1-- $ hledger codes- 123- 124- 126-- $ hledger codes -E- 123- 124--- 126-- commodities- commodities- List all commodity/currency symbols used or declared in the journal.-- descriptions- descriptions- List the unique descriptions that appear in transactions.-- This command lists the unique descriptions that appear in transactions,- in alphabetic order. You can add a query to select a subset of trans-- actions.-- Example:-- $ hledger descriptions- Store Name- Gas Station | Petrol- Person A-- diff- diff- Compares a particular account's transactions in two input files. It- shows any transactions to this account which are in one file but not in- the other.-- More precisely, for each posting affecting this account in either file,- it looks for a corresponding posting in the other file which posts the- same amount to the same account (ignoring date, description, etc.)- Since postings not transactions are compared, this also works when mul-- tiple bank transactions have been combined into a single journal entry.-- This is useful eg if you have downloaded an account's transactions from- your bank (eg as CSV data). When hledger and your bank disagree about- the account balance, you can compare the bank data with your journal to- find out the cause.-- Examples:-- $ hledger diff -f $LEDGER_FILE -f bank.csv assets:bank:giro- These transactions are in the first file only:-- 2014/01/01 Opening Balances- assets:bank:giro EUR ...- ...- equity:opening balances EUR -...-- These transactions are in the second file only:-- files- files- List all files included in the journal. With a REGEX argument, only- file names matching the regular expression (case sensitive) are shown.-- help- help- Show the hledger user manual in one of several formats, optionally- positioned at a given TOPIC (if possible). TOPIC is any heading, or- heading prefix, in the manual. Some examples: commands, print, 'auto- postings', periodic.-- This command shows the user manual built in to this hledger version.- It can be useful if the correct version of the hledger manual, or the- usual viewing tools, are not installed on your system.-- By default it uses the best viewer it can find in $PATH, in this order:- info, man, $PAGER (unless a topic is specified), less, or stdout. When- run non-interactively, it always uses stdout. Or you can select a par-- ticular viewer with the -i (info), -m (man), or -p (pager) flags.-- import- import- Read new transactions added to each FILE since last run, and add them- to the main journal file. Or with --dry-run, just print the transac-- tions that would be added. Or with --catchup, just mark all of the- FILEs' transactions as imported, without actually importing any.-- 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- hledger import bank.csv or perhaps hledger import *.csv.-- Note you can import from any file format, though CSV files are the most- common import source, and these docs focus on that case.-- Deduplication- 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- already-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-- potent.)-- Since the items being read (CSV records, eg) often do not come with- unique identifiers, hledger detects new transactions by date, assuming- that:-- 1. new items always have the newest dates-- 2. item dates do not change across reads-- 3. and items with the same date remain in the same relative order- across reads.-- 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- be the ones affected).-- 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- 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-- tain date.-- Note deduplication (and updating of state files) can also be done by- print --new, but this is less often used.-- Import testing- 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- categorised:-- $ hledger import --dry bank.csv | hledger -f- -I print unknown-- or (live updating):-- $ ls bank.csv* | entr bash -c 'echo ====; hledger import --dry bank.csv | hledger -f- -I print unknown'-- Importing balance assignments- Entries added by import will have their posting amounts made explicit- (like hledger print -x). This means that any balance assignments in- imported files must be evaluated; but, imported files don't get to see- the main file's account balances. As a result, importing entries with- balance assignments (eg from an institution that provides only balances- and not posting amounts) will probably generate incorrect posting- amounts. To avoid this problem, use print instead of import:-- $ hledger print IMPORTFILE [--new] >> $LEDGER_FILE-- (If you think import should leave amounts implicit like print does,- please test it and send a pull request.)-- Commodity display styles- Imported amounts will be formatted according to the canonical commodity- styles (declared or inferred) in the main journal file.-- incomestatement- incomestatement, is-- This command displays an income statement, showing revenues and- expenses during one or more periods. Amounts are shown with normal- positive sign, as in conventional financial statements.-- The revenue and expense accounts shown are those accounts declared with- the Revenue or Expense type, or otherwise all accounts under a top-- level revenue or income or expense account (case insensitive, plurals- allowed).-- Example:-- $ hledger incomestatement- Income Statement-- Revenues:- $-2 income- $-1 gifts- $-1 salary- --------------------- $-2-- Expenses:- $2 expenses- $1 food- $1 supplies- --------------------- $2-- Total:- --------------------- 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 '(revenues|income)' expenses, but with- smarter account detection, and revenues/income displayed with their- sign flipped.-- This command also supports the output destination and output format- options The output formats supported are txt, csv, html, and (experi-- mental) json.-- notes- notes- List the unique notes that appear in transactions.-- This command lists the unique notes that appear in transactions, in- alphabetic order. You can add a query to select a subset of transac-- tions. The note is the part of the transaction description after a |- character (or if there is no |, the whole description).-- Example:-- $ hledger notes- Petrol- Snacks-- payees- payees- List the unique payee/payer names that appear in transactions.-- This command lists 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 |- character (or if there is no |, the whole description).-- You can add query arguments to select a subset of transactions. This- implies --used.-- Example:-- $ hledger payees- Store Name- Gas Station- Person A-- prices- prices- Print market price directives from the journal. With --costs, also- print synthetic market prices based on transaction prices. With- --inverted-costs, also print inverse prices based on transaction- prices. Prices (and postings providing prices) can be filtered by a- query. Price amounts are always displayed with their full precision.-- print- print- Show transaction journal entries, sorted by date.-- The print command displays full journal entries (transactions) from the- journal file, sorted by date (or with --date2, by secondary date).-- Amounts are shown 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.- This means the print command is somewhat lossy, and if you are using it- to reformat your journal you should take care to also copy over the- directives and file-level comments.-- Eg:-- $ hledger print- 2008/01/01 income- assets:bank:checking $1- income:salary $-1-- 2008/06/01 gift- assets:bank:checking $1- income:gifts $-1-- 2008/06/02 save- assets:bank:saving $1- assets:bank:checking $-1-- 2008/06/03 * eat & shop- expenses:food $1- expenses:supplies $1- assets:cash $-2-- 2008/12/31 * pay off- liabilities:debts $1- assets:bank:checking $-1-- print's output is usually a valid hledger journal, and you can process- it again with a second hledger command. This can be useful for certain- kinds of search, eg:-- # Show running total of food expenses paid from cash.- # -f- reads from stdin. -I/--ignore-assertions is sometimes needed.- $ hledger print assets:cash | hledger -f- -I reg expenses:food-- There are some situations where print's output can become unparseable:-- o Valuation affects posting amounts but not balance assertion or bal-- ance assignment amounts, potentially causing those to fail.-- o Auto postings can generate postings with too many missing amounts.-- Normally, the journal entry's explicit or implicit amount style is pre-- served. For example, when an amount is omitted in the journal, it will- not appear in the output. Similarly, when a transaction price is- implied but not written, it will not appear in the output. You can use- the -x/--explicit flag to make all amounts and transaction prices- explicit, which can be useful for troubleshooting or for making your- journal more readable and robust against data entry errors. -x is also- implied by using any of -B,-V,-X,--value.-- Note, -x/--explicit will cause postings with a multi-commodity amount- (these can arise when a multi-commodity transaction has an implicit- amount) to be split into multiple single-commodity postings, keeping- the output parseable.-- With -B/--cost, amounts with transaction prices are converted to cost- using that price. This can be used for troubleshooting.-- With -m/--match and a STR argument, print will show at most one trans-- action: the one one whose description is most similar to STR, and is- most recent. STR should contain at least two characters. If there is- no similar-enough match, no transaction will be shown.-- With --new, hledger prints only transactions it has not seen on a pre-- vious run. This uses the same deduplication system as the import com-- mand. (See import's docs for details.)-- This command also supports the output destination and output format- options The output formats supported are txt, csv, and (experimental)- json and sql.-- Here's an example of print's CSV output:-- $ hledger print -Ocsv- "txnidx","date","date2","status","code","description","comment","account","amount","commodity","credit","debit","posting-status","posting-comment"- "1","2008/01/01","","","","income","","assets:bank:checking","1","$","","1","",""- "1","2008/01/01","","","","income","","income:salary","-1","$","1","","",""- "2","2008/06/01","","","","gift","","assets:bank:checking","1","$","","1","",""- "2","2008/06/01","","","","gift","","income:gifts","-1","$","1","","",""- "3","2008/06/02","","","","save","","assets:bank:saving","1","$","","1","",""- "3","2008/06/02","","","","save","","assets:bank:checking","-1","$","1","","",""- "4","2008/06/03","","*","","eat & shop","","expenses:food","1","$","","1","",""- "4","2008/06/03","","*","","eat & shop","","expenses:supplies","1","$","","1","",""- "4","2008/06/03","","*","","eat & shop","","assets:cash","-2","$","2","","",""- "5","2008/12/31","","*","","pay off","","liabilities:debts","1","$","","1","",""- "5","2008/12/31","","*","","pay off","","assets:bank:checking","-1","$","1","","",""-- o There is one CSV record per posting, with the parent transaction's- fields repeated.-- o The "txnidx" (transaction index) field shows which postings belong to- the same transaction. (This number might change if transactions are- reordered within the file, files are parsed/included in a different- order, etc.)-- o The amount is separated into "commodity" (the symbol) and "amount"- (numeric quantity) fields.-- o The numeric amount is repeated in either the "credit" or "debit" col-- umn, for convenience. (Those names are not accurate in the account-- ing sense; it just puts negative amounts under credit and zero or- greater amounts under debit.)-- print-unique- print-unique- Print transactions which do not reuse an already-seen description.-- Example:-- $ cat unique.journal- 1/1 test- (acct:one) 1- 2/2 test- (acct:two) 2- $ LEDGER_FILE=unique.journal hledger print-unique- (-f option not supported)- 2015/01/01 test- (acct:one) 1-- register- register, reg- Show postings and their running total.-- The register command displays matched postings, across all accounts, in- date order, with their running total or running historical balance.- (See also the aregister command, which shows matched transactions in a- specific account.)-- register normally shows line per posting, but note that multi-commodity- amounts will occupy multiple lines (one line per commodity).-- It is typically used with a query selecting a particular account, to- see that account's activity:-- $ hledger register checking- 2008/01/01 income assets:bank:checking $1 $1- 2008/06/01 gift assets:bank:checking $1 $2- 2008/06/02 save assets:bank:checking $-1 $1- 2008/12/31 pay off assets:bank:checking $-1 0-- With --date2, it shows and sorts by secondary date instead.-- The --historical/-H flag adds the balance from any undisplayed prior- postings to the running total. This is useful when you want to see- only recent activity, with a historically accurate running balance:-- $ hledger register checking -b 2008/6 --historical- 2008/06/01 gift assets:bank:checking $1 $2- 2008/06/02 save assets:bank:checking $-1 $1- 2008/12/31 pay off assets:bank:checking $-1 0-- The --depth option limits the amount of sub-account detail displayed.-- The --average/-A flag shows the running average posting amount instead- of the running total (so, the final number displayed is the average for- the whole report period). This flag implies --empty (see below). It- is affected by --historical. It works best when showing just one- account and one commodity.-- The --related/-r flag shows the other postings in the transactions of- the postings which would normally be shown.-- The --invert flag negates all amounts. For example, it can be used on- an income account where amounts are normally displayed as negative num-- bers. It's also useful to show postings on the checking account- together with the related account:-- $ hledger register --related --invert assets:checking-- With a reporting interval, register shows summary postings, one per- interval, aggregating the postings to each account:-- $ hledger register --monthly income- 2008/01 income:salary $-1 $-1- 2008/06 income:gifts $-1 $-2-- Periods with no activity, and summary postings with a zero amount, are- not shown by default; use the --empty/-E flag to see them:-- $ hledger register --monthly income -E- 2008/01 income:salary $-1 $-1- 2008/02 0 $-1- 2008/03 0 $-1- 2008/04 0 $-1- 2008/05 0 $-1- 2008/06 income:gifts $-1 $-2- 2008/07 0 $-2- 2008/08 0 $-2- 2008/09 0 $-2- 2008/10 0 $-2- 2008/11 0 $-2- 2008/12 0 $-2-- Often, you'll want to see just one line per interval. The --depth- option helps with this, causing subaccounts to be aggregated:-- $ hledger register --monthly assets --depth 1h- 2008/01 assets $1 $1- 2008/06 assets $-1 0- 2008/12 assets $-1 $-1-- Note when using report intervals, if you specify start/end dates these- will be adjusted outward if necessary to contain a whole number of- intervals. This ensures that the first and last intervals are full- length and comparable to the others in the report.-- Custom register output- register uses the full terminal width by default, except on windows.- You can override this by setting the COLUMNS environment variable (not- a bash shell variable) or by using the --width/-w option.-- The description and account columns normally share the space equally- (about half of (width - 40) each). You can adjust this by adding a- description width as part of --width's argument, comma-separated:- --width W,D . Here's a diagram (won't display correctly in --help):-- <--------------------------------- width (W) ---------------------------------->- date (10) description (D) account (W-41-D) amount (12) balance (12)- DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA-- and some examples:-- $ hledger reg # use terminal width (or 80 on windows)- $ hledger reg -w 100 # use width 100- $ COLUMNS=100 hledger reg # set with one-time environment variable- $ export COLUMNS=100; hledger reg # set till session end (or window resize)- $ hledger reg -w 100,40 # set overall width 100, description width 40- $ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40-- This command also supports the output destination and output format- options The output formats supported are txt, csv, and (experimental)- json.-- register-match- register-match- Print the one posting whose transaction description is closest to DESC,- in the style of the register command. If there are multiple equally- good matches, it shows the most recent. Query options (options, not- arguments) can be used to restrict the search space. Helps ledger-- autosync detect already-seen transactions when importing.-- rewrite- rewrite- Print all transactions, rewriting the postings of matched transactions.- For now the only rewrite available is adding new postings, like print- --auto.-- This is a start at a generic rewriter of transaction entries. It reads- the default journal and prints the transactions, like print, but adds- one or more specified postings to any transactions matching QUERY. The- posting amounts can be fixed, or a multiplier of the existing transac-- tion's first posting amount.-- Examples:-- $ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'- $ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'- $ hledger-rewrite.hs -f rewrites.hledger-- rewrites.hledger may consist of entries like:-- = ^income amt:<0 date:2017- (liabilities:tax) *0.33 ; tax on income- (reserve:grocery) *0.25 ; reserve 25% for grocery- (reserve:) *0.25 ; reserve 25% for grocery-- Note the single quotes to protect the dollar sign from bash, and the- two spaces between account and amount.-- More:-- $ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...- $ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'- $ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'- $ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'-- Argument for --add-posting option is a usual posting of transaction- with an exception for amount specification. More precisely, you can- use '*' (star symbol) before the amount to indicate that that this is a- factor for an amount of original matched posting. If the amount- includes a commodity name, the new posting amount will be in the new- commodity; otherwise, it will be in the matched posting amount's com-- modity.-- Re-write rules in a file- During the run this tool will execute so called "Automated Transac-- tions" found in any journal it process. I.e instead of specifying this- operations in command line you can put them in a journal file.-- $ rewrite-rules.journal-- Make contents look like this:-- = ^income- (liabilities:tax) *.33-- = expenses:gifts- budget:gifts *-1- assets:budget *1-- Note that '=' (equality symbol) that is used instead of date in trans-- actions you usually write. It indicates the query by which you want to- match the posting to add new ones.-- $ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal-- This is something similar to the commands pipeline:-- $ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \- | hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \- --add-posting 'assets:budget *1' \- > rewritten-tidy-output.journal-- It is important to understand that relative order of such entries in- journal is important. You can re-use result of previously added post-- ings.-- Diff output format- To use this tool for batch modification of your journal files you may- find useful output in form of unified diff.-- $ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'-- Output might look like:-- --- /tmp/examples/sample.journal- +++ /tmp/examples/sample.journal- @@ -18,3 +18,4 @@- 2008/01/01 income- - assets:bank:checking $1- + assets:bank:checking $1- income:salary- + (liabilities:tax) 0- @@ -22,3 +23,4 @@- 2008/06/01 gift- - assets:bank:checking $1- + assets:bank:checking $1- income:gifts- + (liabilities:tax) 0-- If you'll pass this through patch tool you'll get transactions contain-- ing the posting that matches your query be updated. Note that multiple- files might be update according to list of input files specified via- --file options and include directives inside of these files.-- Be careful. Whole transaction being re-formatted in a style of output- from hledger print.-- See also:-- https://github.com/simonmichael/hledger/issues/99-- rewrite vs. print --auto- This command predates print --auto, and currently does much the same- thing, but with these differences:-- o with multiple files, rewrite lets rules in any file affect all other- files. print --auto uses standard directive scoping; rules affect- only child files.-- o rewrite's query limits which transactions can be rewritten; all are- printed. print --auto's query limits which transactions are printed.-- o rewrite applies rules specified on command line or in the journal.- print --auto applies rules specified in the journal.-- roi- roi- Shows the time-weighted (TWR) and money-weighted (IRR) rate of return- on your investments.-- At a minimum, you need to supply a query (which could be just an- account name) to select your investment(s) with --inv, and another- query to identify your profit and loss transactions with --pnl.-- If you do not record changes in the value of your investment manually,- or do not require computation of time-weighted return (TWR), --pnl- 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- display, regardless of the length of reporting interval.-- 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- becomes negative at some point in time.-- o Error (SearchFailed): Failed to find solution for Internal Rate of- Return (IRR). Either search does not converge to a solution, or con-- verges too slowly.-- Examples:-- o Using roi to compute total return of investment in stocks:- https://github.com/simonmichael/hledger/blob/master/examples/roi-- unrealised.ledger-- o Cookbook -> Return on Investment-- Spaces and special characters in --inv and --pnl- Note that --inv and --pnl's argument is a query, and queries could have- several space-separated terms (see QUERIES).-- To indicate that all search terms form single command-line argument,- you will need to put them in quotes (see Special characters):-- $ hledger roi --inv 'term1 term2 term3 ...'-- If any query terms contain spaces themselves, you will need an extra- level of nested quoting, eg:-- $ hledger roi --inv="'Assets:Test 1'" --pnl="'Equity:Unrealized Profit and Loss'"-- Semantics of --inv and --pnl- Query supplied to --inv has to match all transactions that are related- 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- and which is due to the return on investment.-- o "Cash flow" is depositing or withdrawing money, buying or selling- assets, or otherwise converting between your investment commodity and- any other commodity. Example:-- 2019-01-01 Investing in Snake Oil- assets:cash -$100- investment:snake oil-- 2020-01-01 Selling my Snake Oil- assets:cash $10- investment:snake oil = 0-- o "Profit and loss" is change in the value of your investment:-- 2019-06-01 Snake Oil falls in value- investment:snake oil = $57- equity:unrealized profit or loss-- All non-investment postings are assumed to be "cash flow", unless they- match --pnl query. Changes in value of your investment due to "profit- and loss" postings will be considered as part of your investment- return.-- Example: if you use --inv snake --pnl equity:unrealized, then postings- in the example below would be classifed as:-- 2019-01-01 Snake Oil #1- assets:cash -$100 ; cash flow posting- investment:snake oil ; investment posting-- 2019-03-01 Snake Oil #2- equity:unrealized pnl -$100 ; profit and loss posting- snake oil ; investment posting-- 2019-07-01 Snake Oil #3- equity:unrealized pnl ; profit and loss posting- cash -$100 ; cash flow posting- snake oil $50 ; investment posting-- IRR and TWR explained- "ROI" stands for "return on investment". Traditionally this was com-- puted as a difference between current value of investment and its ini-- tial value, expressed in percentage of the initial value.-- However, this approach is only practical in simple cases, where invest-- ments receives no in-flows or out-flows of money, and where rate of- growth is fixed over time. For more complex scenarios you need differ-- ent ways to compute rate of return, and this command implements two of- them: IRR and TWR.-- Internal rate of return, or "IRR" (also called "money-weighted rate of- return") takes into account effects of in-flows and out-flows.- Naively, if you are withdrawing from your investment, your future gains- would be smaller (in absolute numbers), and will be a smaller percent-- age of your initial investment, and if you are adding to your invest-- ment, you will receive bigger absolute gains (but probably at the same- rate of return). IRR is a way to compute rate of return for each- period between in-flow or out-flow of money, and then combine them in a- way that gives you a compound annual rate of return that investment is- expected to generate.-- 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.-- If you manually record changes in the value of your investment as- transactions that balance them against "profit and loss" (or "unreal-- ized gains") account or use price directives, then in order for IRR to- compute the precise effect of your in-flows and out-flows on the rate- of return, you will need to record the value of your investement on or- close to the days when in- or out-flows occur.-- In technical terms, IRR uses the same approach as computation of net- present value, and tries to find a discount rate that makes net present- value of all the cash flows of your investment to add up to zero. This- could be hard to wrap your head around, especially if you haven't done- discounted cash flow analysis before. 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- 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- and then a compound rate of return. However, internal workings of TWR- are quite different.-- TWR represents your investment as an imaginary "unit fund" where in-- flows/ out-flows lead to buying or selling "units" of your investment- and changes in its value change the value of "investment unit". Change- in "unit price" over the reporting period gives you rate of return of- your investment.-- References: * Explanation of rate of return * Explanation of IRR *- Explanation of TWR * Examples of computing IRR and TWR and discussion- of the limitations of both metrics-- stats- stats- Show some journal statistics.-- The stats command displays summary information for the whole journal,- or a matched part of it. With a reporting interval, it shows a report- for each report period.-- Example:-- $ hledger stats- Main journal file : /src/hledger/examples/sample.journal- Included journal files :- Transactions span : 2008-01-01 to 2009-01-01 (366 days)- Last transaction : 2008-12-31 (2333 days ago)- Transactions : 5 (0.0 per day)- Transactions last 30 days: 0 (0.0 per day)- Transactions last 7 days : 0 (0.0 per day)- Payees/descriptions : 5- Accounts : 8 (depth 3)- Commodities : 1 ($)- Market prices : 12 ($)-- This command also supports output destination and output format selec-- tion.-- tags- tags- List the unique tag names used in the journal. With a TAGREGEX argu-- ment, only tag names matching the regular expression (case insensitive)- are shown. With QUERY arguments, only transactions matching the query- are considered.-- With the --values flag, the tags' unique values are listed instead.-- With --parsed flag, all tags or values are shown in the order they are- parsed from the input data, including duplicates.-- With -E/--empty, any blank/empty values will also be shown, otherwise- they are omitted.-- test- test- Run built-in unit tests.-- This command runs the unit tests built in to hledger and hledger-lib,- printing the results on stdout. If any test fails, the exit code will- be non-zero.-- This is mainly used by hledger developers, but you can also use it to- sanity-check the installed hledger executable on your platform. All- tests are expected to pass - if you ever see a failure, please report- as a bug!-- This command also accepts tasty test runner options, written after a --- (double hyphen). Eg to run only the tests in Hledger.Data.Amount, with- ANSI colour codes disabled:-- $ hledger test -- -pData.Amount --color=never-- For help on these, see https://github.com/feuerbach/tasty#options (--- --help currently doesn't show them).-- About add-on commands- Add-on commands are programs or scripts in your PATH-- o whose name starts with hledger--- o whose name ends with a recognised file extension: .bat,.com,.exe,- .hs,.lhs,.pl,.py,.rb,.rkt,.sh or none-- o and (on unix, mac) which are executable by the current user.-- Add-ons are a relatively easy way to add local features or experiment- with new ideas. They can be written in any language, but haskell- scripts have a big advantage: they can use the same hledger library- functions that built-in commands use for command-line options, parsing- and reporting. Some experimental/example add-on scripts can be found- in the hledger repo's bin/ directory.-- Note in a hledger command line, add-on command flags must have a double- dash (--) preceding them. Eg you must write:-- $ hledger web -- --serve-- and not:-- $ hledger web --serve-- (because the --serve flag belongs to hledger-web, not hledger).-- The -h/--help and --version flags don't require --.-- If you have any trouble with this, remember you can always run the add-- on program directly, eg:-- $ hledger-web --serve--JOURNAL FORMAT- hledger's default file format, representing a General Journal.-- hledger's usual data source is a plain text file containing journal- entries in hledger journal format. This file represents a standard- accounting general journal. I use file names ending in .journal, but- that's not required. The journal file contains a number of transaction- entries, each describing a transfer of money (or any commodity) between- two or more named accounts, in a simple format readable by both hledger- and humans.-- hledger's journal format is a compatible subset, mostly, of ledger's- journal format, so hledger can work with compatible ledger journal- files as well. It's safe, and encouraged, to run both hledger and- ledger on the same journal file, eg to validate the results you're get-- ting.-- You can use hledger without learning any more about this file; just use- the add or web or import commands to create and update it.-- Many users, though, edit the journal file with a text editor, and track- changes with a version control system such as git. Editor addons such- as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and- hledger-vscode for Visual Studio Code, make this easier, adding colour,- formatting, tab completion, and useful commands. See Editor configura-- tion at hledger.org for the full list.-- Here's a description of each part of the file format (and hledger's- data model). These are mostly in the order you'll use them, but in- some cases related concepts have been grouped together for easy refer-- ence, or linked before they are introduced, so feel free to skip over- anything that looks unnecessary right now.-- Transactions- Transactions are the main unit of information in a journal file. They- represent events, typically a movement of some quantity of commodities- between two or more named accounts.-- Each transaction is recorded as a journal entry, beginning with a sim-- ple date in column 0. This can be followed by any of the following- optional fields, separated by spaces:-- o a status character (empty, !, or *)-- o a code (any short number or text, enclosed in parentheses)-- o a description (any remaining text until end of line or a semicolon)-- o a comment (any remaining text following a semicolon until end of- line, and any following indented lines beginning with a semicolon)-- o 0 or more indented posting lines, describing what was transferred and- the accounts involved (indented comment lines are also allowed, but- not blank lines or non-indented lines).-- Here's a simple journal file containing one transaction:-- 2008/01/01 income- assets:bank:checking $1- income:salary $-1-- Dates- Simple dates- Dates in the journal file use simple dates format: YYYY-MM-DD or- YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be- omitted, in which case it will be inferred from the context: the cur-- rent transaction, the default year set with a default year directive,- or the current date when the command is run. Some examples:- 2010-01-31, 2010/01/31, 2010.1.31, 1/31.-- (The UI also accepts simple dates, as well as the more flexible smart- dates documented in the hledger manual.)-- Secondary dates- Real-life transactions sometimes involve more than one date - eg the- date you write a cheque, and the date it clears in your bank. When you- want to model this, for more accurate daily balances, you can specify- individual posting dates.-- Or, you can use the older secondary date feature (Ledger calls it aux-- iliary date or effective date). Note: we support this for compatibil-- ity, but I usually recommend avoiding this feature; posting dates are- almost always clearer and simpler.-- A secondary date is written after the primary date, following an equals- sign. If the year is omitted, the primary date's year is assumed.- When running reports, the primary (left) date is used by default, but- with the --date2 flag (or --aux-date or --effective), the secondary- (right) date will be used instead.-- The meaning of secondary dates is up to you, but it's best to follow a- consistent rule. Eg "primary = the bank's clearing date, secondary =- date the transaction was initiated, if different", as shown here:-- 2010/2/23=2/19 movie ticket- expenses:cinema $10- assets:checking-- $ hledger register checking- 2010-02-23 movie ticket assets:checking $-10 $-10-- $ hledger register checking --date2- 2010-02-19 movie ticket assets:checking $-10 $-10-- Posting dates- You can give individual postings a different date from their parent- transaction, by adding a posting comment containing a tag (see below)- like date:DATE. This is probably the best way to control posting dates- precisely. Eg in this example the expense should appear in May- reports, and the deduction from checking should be reported on 6/1 for- easy bank reconciliation:-- 2015/5/30- expenses:food $10 ; food purchased on saturday 5/30- assets:checking ; bank cleared it on monday, date:6/1-- $ hledger -f t.j register food- 2015-05-30 expenses:food $10 $10-- $ hledger -f t.j register checking- 2015-06-01 assets:checking $-10 $-10-- DATE should be a simple date; if the year is not specified it will use- the year of the transaction's date. You can set the secondary date- similarly, with date2:DATE2. The date: or date2: tags must have a- valid simple date value if they are present, eg a date: tag with no- value is not allowed.-- Ledger's earlier, more compact bracketed date syntax is also supported:- [DATE], [DATE=DATE2] or [=DATE2]. hledger will attempt to parse any- square-bracketed sequence of the 0123456789/-.= characters in this way.- With this syntax, DATE infers its year from the transaction and DATE2- infers its year from DATE.-- Status- Transactions, or individual postings within a transaction, can have a- status mark, which is a single character before the transaction- description or posting account name, separated from it by a space,- indicating one of three statuses:--- mark status- ------------------- unmarked- ! pending- * cleared-- When reporting, you can filter by status with the -U/--unmarked,- -P/--pending, and -C/--cleared flags; or the status:, status:!, and- status:* queries; or the U, P, C keys in hledger-ui.-- Note, in Ledger and in older versions of hledger, the "unmarked" state- is called "uncleared". As of hledger 1.3 we have renamed it to- unmarked for clarity.-- To replicate Ledger and old hledger's behaviour of also matching pend-- ing, combine -U and -P.-- Status marks are optional, but can be helpful eg for reconciling with- real-world accounts. Some editor modes provide highlighting and short-- cuts for working with status. Eg in Emacs ledger-mode, you can toggle- transaction status with C-c C-e, or posting status with C-c C-c.-- What "uncleared", "pending", and "cleared" actually mean is up to you.- Here's one suggestion:--- status meaning- --------------------------------------------------------------------------- uncleared recorded but not yet reconciled; needs review- pending tentatively reconciled (if needed, eg during a big reconcil-- iation)- cleared complete, reconciled as far as possible, and considered cor-- rect-- With this scheme, you would use -PC to see the current balance at your- bank, -U to see things which will probably hit your bank soon (like- uncashed checks), and no flags to see the most up-to-date state of your- finances.-- Code- After the status mark, but before the description, you can optionally- write a transaction "code", enclosed in parentheses. This is a good- place to record a check number, or some other important transaction id- or reference number.-- Description- A transaction's description is the rest of the line following the date- and status mark (or until a comment begins). Sometimes called the- "narration" in traditional bookkeeping, it can be used for whatever you- wish, or left blank. Transaction descriptions can be queried, unlike- comments.-- Payee and note- You can optionally include a | (pipe) character in descriptions to sub-- divide the description into separate fields for payee/payer name on the- left (up to the first |) and an additional note field on the right- (after the first |). This may be worthwhile if you need to do more- precise querying and pivoting by payee or by note.-- Comments- Lines in the journal beginning with a semicolon (;) or hash (#) or star- (*) are comments, and will be ignored. (Star comments cause org-mode- nodes to be ignored, allowing emacs users to fold and navigate their- journals with org-mode or orgstruct-mode.)-- You can attach comments to a transaction by writing them after the- description and/or indented on the following lines (before the post-- ings). Similarly, you can attach comments to an individual posting by- writing them after the amount and/or indented on the following lines.- Transaction and posting comments must begin with a semicolon (;).-- Some examples:-- # a file comment- ; another file comment- * also a file comment, useful in org/orgstruct mode-- comment- A multiline file comment, which continues- until a line containing just "end comment"- (or end of file).- end comment-- 2012/5/14 something ; a transaction comment- ; the transaction comment, continued- posting1 1 ; a comment for posting 1- posting2- ; a comment for posting 2- ; another comment line for posting 2- ; a file comment (because not indented)-- You can also comment larger regions of a file using comment and end- comment directives.-- Tags- Tags are a way to add extra labels or labelled data to postings and- transactions, which you can then search or pivot on.-- A simple tag is a word (which may contain hyphens) followed by a full- colon, written inside a transaction or posting comment line:-- 2017/1/16 bought groceries ; sometag:-- Tags can have a value, which is the text after the colon, up to the- next comma or end of line, with leading/trailing whitespace removed:-- expenses:food $10 ; a-posting-tag: the tag value-- Note this means hledger's tag values can not contain commas or new-- lines. Ending at commas means you can write multiple short tags on one- line, comma separated:-- assets:checking ; a comment containing tag1:, tag2: some value ...-- Here,-- o "a comment containing" is just comment text, not a tag-- o "tag1" is a tag with no value-- o "tag2" is another tag, whose value is "some value ..."-- Tags in a transaction comment affect the transaction and all of its- postings, while tags in a posting comment affect only that posting.- For example, the following transaction has three tags (A, TAG2, third-- tag) and the posting has four (those plus posting-tag):-- 1/1 a transaction ; A:, TAG2:- ; third-tag: a third transaction tag, <- with a value- (a) $1 ; posting-tag:-- Tags are like Ledger's metadata feature, except hledger's tag values- are simple strings.-- Postings- A posting is an addition of some amount to, or removal of some amount- from, an account. Each posting line begins with at least one space or- tab (2 or 4 spaces is common), followed by:-- o (optional) a status character (empty, !, or *), followed by a space-- o (required) an account name (any text, optionally containing single- spaces, until end of line or a double space)-- o (optional) two or more spaces or tabs followed by an amount.-- Positive amounts are being added to the account, negative amounts are- being removed.-- The amounts within a transaction must always sum up to zero. As a con-- venience, one amount may be left blank; it will be inferred so as to- balance the transaction.-- Be sure to note the unusual two-space delimiter between account name- and amount. This makes it easy to write account names containing spa-- ces. But if you accidentally leave only one space (or tab) before the- amount, the amount will be considered part of the account name.-- Virtual postings- A posting with a parenthesised account name is called a virtual posting- or unbalanced posting, which means it is exempt from the usual rule- that a transaction's postings must balance add up to zero.-- This is not part of double entry accounting, so you might choose to- avoid this feature. Or you can use it sparingly for certain special- cases where it can be convenient. Eg, you could set opening balances- without using a balancing equity account:-- 1/1 opening balances- (assets:checking) $1000- (assets:savings) $2000-- A posting with a bracketed account name is called a balanced virtual- posting. The balanced virtual postings in a transaction must add up to- zero (separately from other postings). Eg:-- 1/1 buy food with cash, update budget envelope subaccounts, & something else- assets:cash $-10 ; <- these balance- expenses:food $7 ; <-- expenses:food $3 ; <-- [assets:checking:budget:food] $-10 ; <- and these balance- [assets:checking:available] $10 ; <-- (something:else) $5 ; <- not required to balance-- Ordinary non-parenthesised, non-bracketed postings are called real- postings. You can exclude virtual postings from reports with the- -R/--real flag or real:1 query.-- Account names- Account names typically have several parts separated by a full colon,- from which hledger derives a hierarchical chart of accounts. They can- be anything you like, but in finance there are traditionally five top-- level accounts: assets, liabilities, revenue, expenses, and equity.-- Account names may contain single spaces, eg: assets:accounts receiv-- able. Because of this, they must always be followed by two or more- spaces (or newline).-- Account names can be aliased.-- Amounts- After the account name, there is usually an amount. (Important:- between account name and amount, there must be two or more spaces.)-- hledger's amount format is flexible, supporting several international- formats. Here are some examples. Amounts have a number (the "quan-- tity"):-- 1-- ..and usually a currency symbol or commodity name (more on this below),- to the left or right of the quantity, with or without a separating- space:-- $1- 4000 AAPL- 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-- modity symbol:-- -$1- $-1-- One or more spaces between the sign and the number are acceptable when- parsing (but they won't be displayed in output):-- + $1- $- 1-- Scientific E notation is allowed:-- 1E-6- EUR 1E3-- Decimal marks, digit group marks- A decimal mark can be written as a period or a comma:-- 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, comma, or period (different from the decimal mark):-- $1,000,000.00- EUR 2.000.000,00- INR 9,99,99,999.00- 1 000 000.9455-- Note, a number containing a single digit group mark and no decimal mark- is ambiguous. Are these digit group marks or decimal marks ?-- 1,000- 1.000-- If you don't tell it otherwise, hledger will assume both of the above- are decimal marks, parsing both numbers as 1. To prevent confusion and- undetected typos, we recommend adding commodity directives at the top- of your journal file to explicitly declare the decimal mark (and- optionally a digit group mark) for each commodity. Read on for more- about this.-- Commodity- 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",- "ABC123").-- 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- 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- are the Amount and MixedAmount types.)-- Commodity directives- You can add commodity directives to the journal, preferably at the top,- to declare your commodities and help with number parsing (see above)- and display (see below). These are optional, but recommended. They- are described in more detail in JOURNAL FORMAT -> Declaring commodi-- ties. Here's a quick example:-- # number format and display style for $, EUR, INR and the no-symbol commodity:- commodity $1,000.00- commodity EUR 1.000,00- commodity INR 9,99,99,999.00- commodity 1 000 000.9455--- Commodity display style- For the amounts in each commodity, hledger chooses a consistent display- style to use in most reports. (Exceptions: price amounts, and all- amounts displayed by the print command, are displayed with all of their- decimal digits visible.)-- A commodity's display style is inferred as follows.-- 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- order of preference:-- 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.- (Posting amounts only; prices and periodic or auto rules are ignored,- currently.)-- o The built-in fallback style, which looks like this: $1000.00. (Sym-- bol on the left, period decimal mark, two decimal places.)-- A style is inferred from journal amounts as follows:-- o Use the general style (decimal mark, symbol placement) of the first- amount-- o Use the first-seen digit group style (digit group mark, digit group- sizes), if any-- o Use the maximum number of decimal places of all.-- Transaction price amounts don't affect the commodity display style- directly, but occasionally they can do so indirectly (eg when a post-- ing's amount is inferred using a transaction price). If you find this- causing problems, use a commodity 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- places, use a commodity directive. Some examples:-- # declare euro, dollar, bitcoin and no-symbol commodities and set their- # input number formats and output display styles:- commodity EUR 1.000,- commodity $1000.00- commodity 1000.00000000 BTC- commodity 1 000.-- Rounding- Amounts are stored internally as decimal numbers with up to 255 decimal- places, and displayed with the number of decimal places specified by- the commodity display style. Note, hledger uses banker's rounding: it- rounds to the nearest even number, eg 0.5 displayed with zero decimal- places is "0"). (Guaranteed since hledger 1.17.1; in older versions- this could vary if hledger was built with Decimal < 0.5.1.)-- Transaction prices- Within a transaction, you can note an amount's price in another commod-- ity. This can be used to document the cost (in a purchase) or selling- price (in a sale). For example, transaction prices are useful to- record purchases of a foreign currency. Note transaction prices are- fixed at the time of the transaction, and do not change over time. See- also market prices, which represent prevailing exchange rates on a cer-- tain date.-- There are several ways to record a transaction price:-- 1. Write the price per unit, as @ UNITPRICE after the amount:-- 2009/1/1- assets:euros EUR100 @ $1.35 ; one hundred euros purchased at $1.35 each- assets:dollars ; balancing amount is -$135.00-- 2. Write the total price, as @@ TOTALPRICE after the amount:-- 2009/1/1- assets:euros EUR100 @@ $135 ; one hundred euros purchased at $135 for the lot- assets:dollars-- 3. Specify amounts for all postings, using exactly two commodities, and- let hledger infer the price that balances the transaction:-- 2009/1/1- assets:euros EUR100 ; one hundred euros purchased- assets:dollars $-135 ; for $135-- 4. Like 1, but the @ is parenthesised, i.e. (@); this is for compati-- bility with Ledger journals (Virtual posting costs), and is equiva-- lent to 1 in hledger.-- 5. Like 2, but as in 4 the @@ is parenthesised, i.e. (@@); in hledger,- this is equivalent to 2.-- Use the -B/--cost flag to convert amounts to their transaction price's- commodity, if any. (mnemonic: "B" is from "cost Basis", as in Ledger).- Eg here is how -B affects the balance report for the example above:-- $ hledger bal -N --flat- $-135 assets:dollars- EUR100 assets:euros- $ hledger bal -N --flat -B- $-135 assets:dollars- $135 assets:euros # <- the euros' cost-- Note -B is sensitive to the order of postings when a transaction price- is inferred: the inferred price will be in the commodity of the last- amount. So if example 3's postings are reversed, while the transaction- is equivalent, -B shows something different:-- 2009/1/1- assets:dollars $-135 ; 135 dollars sold- assets:euros EUR100 ; for 100 euros-- $ hledger bal -N --flat -B- EUR-100 assets:dollars # <- the dollars' selling price- EUR100 assets:euros-- Lot prices, lot dates- Ledger allows another kind of price, lot price (four variants: {UNIT-- PRICE}, {{TOTALPRICE}}, {=FIXEDUNITPRICE}, {{=FIXEDTOTALPRICE}}),- and/or a lot date ([DATE]) to be specified. These are normally used to- select a lot when selling investments. hledger will parse these, for- compatibility with Ledger journals, but currently ignores them. A- transaction price, lot price and/or lot date may appear in any order,- after the posting amount and before the balance assertion if any.-- Balance assertions- hledger supports Ledger-style balance assertions in journal files.- These look like, for example, = EXPECTEDBALANCE following a posting's- amount. Eg here we assert the expected dollar balance in accounts a- and b after each posting:-- 2013/1/1- a $1 =$1- b =$-1-- 2013/1/2- a $1 =$2- b $-1 =$-2-- After reading a journal file, hledger will check all balance assertions- and report an error if any of them fail. Balance assertions can pro-- tect you from, eg, inadvertently disrupting reconciled balances while- cleaning up old entries. You can disable them temporarily with the- -I/--ignore-assertions flag, which can be useful for troubleshooting or- for reading Ledger files. (Note: this flag currently does not disable- balance assignments, below).-- Assertions and ordering- hledger sorts an account's postings and assertions first by date and- then (for postings on the same day) by parse order. Note this is dif-- ferent from Ledger, which sorts assertions only by parse order. (Also,- Ledger assertions do not see the accumulated effect of repeated post-- ings to the same account within a transaction.)-- So, hledger balance assertions keep working if you reorder differently-- dated transactions within the journal. But if you reorder same-dated- transactions or postings, assertions might break and require updating.- This order dependence does bring an advantage: precise control over the- order of postings and assertions within a day, so you can assert intra-- day balances.-- Assertions and included files- With included files, things are a little more complicated. Including- preserves the ordering of postings and assertions. If you have multi-- ple postings to an account on the same day, split across different- files, and you also want to assert the account's balance on the same- day, you'll have to put the assertion in the right file.-- Assertions and multiple -f options- Balance assertions don't work well across files specified with multiple- -f options. Use include or concatenate the files instead.-- Assertions and commodities- The asserted balance must be a simple single-commodity amount, and in- fact the assertion checks only this commodity's balance within the- (possibly multi-commodity) account balance. This is how assertions- work in Ledger also. We could call this a "partial" balance assertion.-- To assert the balance of more than one commodity in an account, you can- write multiple postings, each asserting one commodity's balance.-- You can make a stronger "total" balance assertion by writing a double- equals sign (== EXPECTEDBALANCE). This asserts that there are no other- unasserted commodities in the account (or, that their balance is 0).-- 2013/1/1- a $1- a 1EUR- b $-1- c -1EUR-- 2013/1/2 ; These assertions succeed- a 0 = $1- a 0 = 1EUR- b 0 == $-1- c 0 == -1EUR-- 2013/1/3 ; This assertion fails as 'a' also contains 1EUR- a 0 == $1-- It's not yet possible to make a complete assertion about a balance that- has multiple commodities. One workaround is to isolate each commodity- into its own subaccount:-- 2013/1/1- a:usd $1- a:euro 1EUR- b-- 2013/1/2- a 0 == 0- a:usd 0 == $1- a:euro 0 == 1EUR-- Assertions and prices- Balance assertions ignore transaction prices, and should normally be- written without one:-- 2019/1/1- (a) $1 @ EUR1 = $1-- We do allow prices to be written there, however, and print shows them,- even though they don't affect whether the assertion passes or fails.- This is for backward compatibility (hledger's close command used to- generate balance assertions with prices), and because balance assign-- ments do use them (see below).-- Assertions and subaccounts- The balance assertions above (= and ==) do not count the balance from- subaccounts; they check the account's exclusive balance only. You can- assert the balance including subaccounts by writing =* or ==*, eg:-- 2019/1/1- equity:opening balances- checking:a 5- checking:b 5- checking 1 ==* 11-- Assertions and virtual postings- Balance assertions are checked against all postings, both real and vir-- tual. They are not affected by the --real/-R flag or real: query.-- Assertions and precision- Balance assertions compare the exactly calculated amounts, which are- not always what is shown by reports. Eg a commodity directive may- limit the display precision, but this will not affect balance asser-- tions. Balance assertion failure messages show exact amounts.-- Balance assignments- Ledger-style balance assignments are also supported. These are like- balance assertions, but with no posting amount on the left side of the- equals sign; instead it is calculated automatically so as to satisfy- the assertion. This can be a convenience during data entry, eg when- setting opening balances:-- ; starting a new journal, set asset account balances- 2016/1/1 opening balances- assets:checking = $409.32- assets:savings = $735.24- assets:cash = $42- equity:opening balances-- or when adjusting a balance to reality:-- ; no cash left; update balance, record any untracked spending as a generic expense- 2016/1/15- assets:cash = $0- expenses:misc-- The calculated amount depends on the account's balance in the commodity- at that point (which depends on the previously-dated postings of the- commodity to that account since the last balance assertion or assign-- ment). Note that using balance assignments makes your journal a little- less explicit; to know the exact amount posted, you have to run hledger- or do the calculations yourself, instead of just reading it.-- Balance assignments and prices- A transaction price in a balance assignment will cause the calculated- amount to have that price attached:-- 2019/1/1- (a) = $1 @ EUR2-- $ hledger print --explicit- 2019-01-01- (a) $1 @ EUR2 = $1 @ EUR2-- Directives- A directive is a line in the journal beginning with a special keyword,- that influences how the journal is processed. hledger's directives are- based on a subset of Ledger's, but there are many differences (and also- some differences between hledger versions).-- Directives' behaviour and interactions can get a little bit complex, so- here is a table summarising the directives and their effects, with- links to more detailed docs.--- direc- end subdi- purpose can affect (as of- tive directive rec- 2018/06)- tives- ------------------------------------------------------------------------------------- account any document account names, all entries in all- text declare account types & dis- files, before or- play order after- alias end rewrite account names following entries- aliases until end of cur-- rent file or end- directive- apply end apply prepend a common parent to following entries- account account account names until end of cur-- rent file or end- directive- comment end com- ignore part of journal following entries- ment until end of cur-- rent file or end- directive- commod- format declare a commodity and its number notation:- ity number notation & display following entries- style until end of cur-- rent file; display- style: amounts of- that commodity in- reports- D declare a commodity to be default commodity:- used for commodityless following commod-- amounts, and its number ityless entries- notation & display style until end of cur-- rent file; number- notation: following- entries in that- commodity until end- of current file;- display style:- amounts of that- commodity in- reports- include include entries/directives what the included- from another file directives affect- payee declare a payee name following entries- until end of cur-- rent file- P declare a market price for a amounts of that- commodity commodity in- reports, when -V is- used- Y declare a year for yearless following entries- dates until end of cur-- rent file- = declare an auto posting all entries in par-- rule, adding postings to ent/current/child- other transactions files (but not sib-- ling files, see- #1212)-- And some definitions:--- subdi- optional indented directive line immediately following a parent- rec- directive- tive- number how to interpret numbers when parsing journal entries (the iden-- nota- tity of the decimal separator character). (Currently each com-- tion modity can have its own notation, even in the same file.)--- dis- how to display amounts of a commodity in reports (symbol side- play and spacing, digit groups, decimal separator, decimal places)- style- direc- which entries and (when there are multiple files) which files- tive are affected by a directive- scope-- As you can see, directives vary in which journal entries and files they- affect, and whether they are focussed on input (parsing) or output- (reports). Some directives have multiple effects.-- Directives and multiple files- If you use multiple -f/--file options, or the include directive,- hledger will process multiple input files. But note that directives- which affect input (see above) typically last only until the end of the- file in which they occur.-- This may seem inconvenient, but it's intentional; it makes reports sta-- ble and deterministic, independent of the order of input. Otherwise- you could see different numbers if you happened to write -f options in- a different order, or if you moved includes around while cleaning up- your files.-- It can be surprising though; for example, it means that alias direc-- tives do not affect parent or sibling files (see below).-- Comment blocks- A line containing just comment starts a commented region of the file,- and a line containing just end comment (or the end of the current file)- ends it. See also comments.-- Including other files- You can pull in the content of additional files by writing an include- directive, like this:-- include FILEPATH-- Only journal files can include, and only journal, timeclock or timedot- files can be included (not CSV files, currently).-- If the file path does not begin with a slash, it is relative to the- current file's folder.-- A tilde means home directory, eg: include ~/main.journal.-- The path may contain glob patterns to match multiple files, eg: include- *.journal.-- There is limited support for recursive wildcards: **/ (the slash is- required) matches 0 or more subdirectories. It's not super convenient- since you have to avoid include cycles and including directories, but- this can be done, eg: include */**/*.journal.-- The path may also be prefixed to force a specific file format, overrid-- ing the file extension (as described in hledger.1 -> Input files):- include timedot:~/notes/2020*.md.-- Default year- You can set a default year to be used for subsequent dates which don't- specify a year. This is a line beginning with Y followed by the year.- Eg:-- Y2009 ; set default year to 2009-- 12/15 ; equivalent to 2009/12/15- expenses 1- assets-- Y2010 ; change default year to 2010-- 2009/1/30 ; specifies the year, not affected- expenses 1- assets-- 1/31 ; equivalent to 2010/1/31- expenses 1- assets-- Declaring payees- The payee directive can be used to declare a limited set of payees- which may appear in transaction descriptions. The "payees" check will- report an error if any transaction refers to a payee that has not been- declared. Eg:-- payee Whole Foods-- Declaring commodities- You can use commodity directives to declare your commodities. In fact- the commodity directive performs several functions at once:-- 1. It declares commodities which may be used in the journal. This can- optionally be enforced, providing useful error checking. (Cf Com-- modity error checking)-- 2. It declares which decimal mark character (period or comma), to- expect when parsing input - useful to disambiguate international- number formats in your data. Without this, hledger will parse both- 1,000 and 1.000 as 1. (Cf Amounts)-- 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- style)-- 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.-- Generally you should put them at the top of your journal file (since- for function 2, they affect only following amounts, cf #793).-- A commodity directive is just the word commodity followed by a sample- amount, like this:-- ;commodity SAMPLEAMOUNT-- commodity $1000.00- commodity 1,000.0000 AAAA ; optional same-line comment-- It may also be written on multiple lines, and use the format subdirec-- tive, as in Ledger. Note in this case the commodity symbol appears- twice; it must be the same in both places:-- ;commodity SYMBOL- ; format SAMPLEAMOUNT-- ; display indian rupees with currency name on the left,- ; thousands, lakhs and crores comma-separated,- ; period as decimal point, and two decimal places.- commodity INR- format INR 1,00,00,000.00-- Remember that if the commodity symbol contains spaces, numbers, or- punctuation, it must be enclosed in double quotes (cf Commodity).-- The amount's quantity does not matter; only the format is significant.- It must include a decimal mark - either a period or a comma - followed- by 0 or more decimal digits.-- A few more examples:-- # number formats for $, EUR, INR and the no-symbol commodity:- commodity $1,000.00- commodity EUR 1.000,00- commodity INR 9,99,99,999.0- commodity 1 000 000.-- Note hledger normally uses banker's rounding, so 0.5 displayed with- zero decimal digits is "0". (More at Commodity display style.)-- Commodity error checking- In strict mode, enabled with the -s/--strict flag, hledger will report- an error if a commodity symbol is used that has not been declared by a- commodity directive. This works similarly to account error checking,- see the notes there for more details.-- Default commodity- The D directive sets a default commodity, to be used for any subsequent- commodityless amounts (ie, plain numbers) seen while parsing the jour-- nal. This effect lasts until the next D directive, or the end of the- journal.-- For compatibility/historical reasons, D also acts like a commodity- directive (setting the commodity's decimal mark for parsing and display- style for output).-- As with commodity, the amount must include a decimal mark (either- period or comma). If both commodity and D directives are used for the- same commodity, the commodity style takes precedence.-- The syntax is D AMOUNT. Eg:-- ; commodity-less amounts should be treated as dollars- ; (and displayed with the dollar sign on the left, thousands separators and two decimal places)- D $1,000.00-- 1/1- a 5 ; <- commodity-less amount, parsed as $5 and displayed as $5.00- b-- Declaring market prices- The P directive declares a market price, which is an exchange rate- between two commodities on a certain date. (In Ledger, they are called- "historical prices".) These are often obtained from a stock exchange,- cryptocurrency exchange, or the foreign exchange market.-- The format is:-- P DATE COMMODITY1SYMBOL COMMODITY2AMOUNT-- DATE is a simple date, COMMODITY1SYMBOL is the symbol of the commodity- being priced, and COMMODITY2AMOUNT is the amount (symbol and quantity)- of commodity 2 that one unit of commodity 1 is worth on this date.- Examples:-- # one euro was worth $1.35 from 2009-01-01 onward:- P 2009-01-01 EUR $1.35-- # and $1.40 from 2010-01-01 onward:- P 2010-01-01 EUR $1.40-- The -V, -X and --value flags use these market prices to show amount- values in another commodity. See Valuation.-- Declaring accounts- account directives can be used to declare accounts (ie, the places that- amounts are transferred from and to). Though not required, these dec-- larations can provide several benefits:-- o They can document your intended chart of accounts, providing a refer-- ence.-- o They can help hledger know your accounts' types (asset, liability,- equity, revenue, expense), useful for reports like balancesheet and- incomestatement.-- o They control account display order in reports, allowing non-alpha-- betic sorting (eg Revenues to appear above Expenses).-- o They can store extra information about accounts (account numbers,- notes, etc.)-- o They help with account name completion in the add command, hledger-- iadd, hledger-web, ledger-mode etc.-- o In strict mode, they restrict which accounts may be posted to by- transactions, which helps detect typos.-- The simplest form is just the word account followed by a hledger-style- account name, eg this account directive declares the assets:bank:check-- ing account:-- account assets:bank:checking-- Account error checking- By default, accounts come into existence when a transaction references- them by name. This is convenient, but it means hledger can't warn you- when you mis-spell an account name in the journal. Usually you'll find- the error later, as an extra account in balance reports, or an incor-- rect balance when reconciling.-- In strict mode, enabled with the -s/--strict flag, hledger will report- an error if any transaction uses an account name that has not been- declared by an account directive. Some notes:-- o The declaration is case-sensitive; transactions must use the correct- account name capitalisation.-- o The account directive's scope is "whole file and below" (see direc-- tives). This means it affects all of the current file, and any files- it includes, but not parent or sibling files. The position of- account 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- included files in other formats).-- o It's currently not possible to declare "all possible subaccounts"- with a wildcard; every account posted to must be declared.-- Account comments- Comments, beginning with a semicolon, can be added:-- o on the same line, after two or more spaces (because ; is allowed in- account names)-- o on the next lines, indented-- An example of both:-- account assets:bank:checking ; same-line comment, note 2+ spaces before ;- ; next-line comment- ; another with tag, acctno:12345 (not used yet)-- Same-line comments are not supported by Ledger, or hledger <1.13.-- Account subdirectives- We also allow (and ignore) Ledger-style indented subdirectives, just- for compatibility.:-- account assets:bank:checking- format blah blah ; <- subdirective, ignored-- Here is the full syntax of account directives:-- account ACCTNAME [ACCTTYPE] [;COMMENT]- [;COMMENTS]- [LEDGER-STYLE SUBDIRECTIVES, IGNORED]-- Account types- hledger recognises five main types of account, corresponding to the- account classes in the accounting equation:-- Asset, Liability, Equity, Revenue, Expense.-- These account types are important for controlling which accounts appear- in the balancesheet, balancesheetequity, incomestatement reports (and- probably for other things in future).-- Additionally, we recognise the Cash type, which is also an Asset, and- which causes accounts to appear in the cashflow report. ("Cash" here- means liquid assets, eg bank balances but typically not investments or- receivables.)-- Declaring account types- Generally, to make these reports work you should declare your top-level- accounts and their types, using account directives with type: tags.-- The tag's value should be one of: Asset, Liability, Equity, Revenue,- Expense, Cash, A, L, E, R, X, C (all case insensitive). The type is- inherited by all subaccounts except where they override it. Here's a- complete example:-- account assets ; type: Asset- account assets:bank ; type: Cash- account assets:cash ; type: Cash- account liabilities ; type: Liability- account equity ; type: Equity- account revenues ; type: Revenue- account expenses ; type: Expense-- Auto-detected account types- If you happen to use common english top-level account names, you may- not need to declare account types, as they will be detected automati-- cally using the following rules:-- If account's name matches this regular expression: | its type is:- ------------------------------------------------------------------- | ------------- ^assets?(:|$) |- and does not contain regexp (investment|receivable|:A/R|:fixed) | Cash- otherwise | Asset- ^(debts?|liabilit(y|ies))(:|$) | Liability- ^equity(:|$) | Equity- ^(income|revenue)s?(:|$) | Revenue- ^expenses?(:|$) | Expense-- Even so, explicit declarations may be a good idea, for clarity and pre-- dictability.-- Interference from auto-detected account types- If you assign any account type, it's a good idea to assign all of them,- to prevent any confusion from mixing declared and auto-detected types.- Although it's unlikely to happen in real life, here's an example: with- the following journal, balancesheetequity shows "liabilities" in both- Liabilities and Equity sections. Declaring another account as- type:Liability would fix it:-- account liabilities ; type:Equity-- 2020-01-01- assets 1- liabilities 1- equity -2-- Old account type syntax- In some hledger journals you might instead see this old syntax (the- letters ALERX, separated from the account name by two or more spaces);- this is deprecated and may be removed soon:-- account assets A- account liabilities L- account equity E- account revenues R- account expenses X-- Account display order- Account directives also set the order in which accounts are displayed,- eg in reports, the hledger-ui accounts screen, and the hledger-web- sidebar. By default accounts are listed in alphabetical order. But if- you have these account directives in the journal:-- account assets- account liabilities- account equity- account revenues- account expenses-- you'll see those accounts displayed in declaration order, not alphabet-- ically:-- $ hledger accounts -1- assets- liabilities- equity- revenues- expenses-- Undeclared accounts, if any, are displayed last, in alphabetical order.-- Note that sorting is done at each level of the account tree (within- each group of sibling accounts under the same parent). And currently,- this directive:-- account other:zoo-- would influence the position of zoo among other's subaccounts, but not- the position of other among the top-level accounts. This means:-- o you will sometimes declare parent accounts (eg account other above)- that you don't intend to post to, just to customize their display- order-- o sibling accounts stay together (you couldn't display x:y in between- a:b and a:c).-- Rewriting accounts- You can define account alias rules which rewrite your account names, or- parts of them, before generating reports. This can be useful for:-- o expanding shorthand account names to their full form, allowing easier- data entry and a less verbose journal-- o adapting old journals to your current chart of accounts-- o experimenting with new account organisations, like a new hierarchy or- combining two accounts into one-- o customising reports-- Account aliases also rewrite account names in account directives. They- do not affect account names being entered via hledger add or hledger-- web.-- See also Rewrite account names.-- Basic aliases- To set an account alias, use the alias directive in your journal file.- This affects all subsequent journal entries in the current file or its- included files (but note: not sibling or parent files). The spaces- around the = are optional:-- alias OLD = NEW-- Or, you can use the --alias 'OLD=NEW' option on the command line. This- affects all entries. It's useful for trying out aliases interactively.-- OLD and NEW are case sensitive full account names. hledger will- replace any occurrence of the old account name with the new one. Sub-- accounts are also affected. Eg:-- alias checking = assets:bank:wells fargo:checking- ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"-- Regex aliases- There is also a more powerful variant that uses a regular expression,- indicated by the forward slashes:-- alias /REGEX/ = REPLACEMENT-- or --alias '/REGEX/=REPLACEMENT'.-- REGEX is a case-insensitive regular expression. Anywhere it matches- inside an account name, the matched part will be replaced by REPLACE-- MENT. If REGEX contains parenthesised match groups, these can be ref-- erenced by the usual numeric backreferences in REPLACEMENT. Eg:-- alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3- ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"-- Also note that REPLACEMENT continues to the end of line (or on command- line, to end of option argument), so it can contain trailing white-- space.-- Combining aliases- You can define as many aliases as you like, using journal directives- and/or command line options.-- Recursive aliases - where an account name is rewritten by one alias,- then by another alias, and so on - are allowed. Each alias sees the- effect of previously applied aliases.-- In such cases it can be important to understand which aliases will be- applied and in which order. For (each account name in) each journal- entry, we apply:-- 1. alias directives preceding the journal entry, most recently parsed- first (ie, reading upward from the journal entry, bottom to top)-- 2. --alias options, in the order they appeared on the command line- (left to right).-- In other words, for (an account name in) a given journal entry:-- o the nearest alias declaration before/above the entry is applied first-- o the next alias before/above that will be be applied next, and so on-- o aliases defined after/below the entry do not affect it.-- This gives nearby aliases precedence over distant ones, and helps pro-- vide semantic stability - aliases will keep working the same way inde-- pendent of which files are being read and in which order.-- In case of trouble, adding --debug=6 to the command line will show- which aliases are being applied when.-- Aliases and multiple files- As explained at Directives and multiple files, alias directives do not- affect parent or sibling files. Eg in this command,-- hledger -f a.aliases -f b.journal-- account aliases defined in a.aliases will not affect b.journal.- Including the aliases doesn't work either:-- include a.aliases-- 2020-01-01 ; not affected by a.aliases- foo 1- bar-- This means that account aliases should usually be declared at the start- of your top-most file, like this:-- alias foo=Foo- alias bar=Bar-- 2020-01-01 ; affected by aliases above- foo 1- bar-- include c.journal ; also affected-- end aliases- You can clear (forget) all currently defined aliases with the end- aliases directive:-- end aliases-- Default parent account- You can specify a parent account which will be prepended to all- accounts within a section of the journal. Use the apply account and- end apply account directives like so:-- apply account home-- 2010/1/1- food $10- cash-- end apply account-- which is equivalent to:-- 2010/01/01- home:food $10- home:cash $-10-- If end apply account is omitted, the effect lasts to the end of the- file. Included files are also affected, eg:-- apply account business- include biz.journal- end apply account- apply account personal- include personal.journal-- Prior to hledger 1.0, legacy account and end spellings were also sup-- ported.-- A default parent account also affects account directives. It does not- affect account names being entered via hledger add or hledger-web. If- account aliases are present, they are applied after the default parent- account.-- Periodic transactions- Periodic transaction rules describe transactions that recur. They- allow hledger to generate temporary future transactions to help with- forecasting, so you don't have to write out each one in the journal,- and it's easy to try out different forecasts.-- Periodic transactions can be a little tricky, so before you use them,- read this whole section - or at least these tips:-- 1. Two spaces accidentally added or omitted will cause you trouble -- read about this below.-- 2. For troubleshooting, show the generated transactions with hledger- print --forecast tag:generated or hledger register --forecast- tag:generated.-- 3. Forecasted transactions will begin only after the last non-fore-- casted transaction's date.-- 4. Forecasted transactions will end 6 months from today, by default.- See below for the exact start/end rules.-- 5. period expressions can be tricky. Their documentation needs- improvement, but is worth studying.-- 6. Some period expressions with a repeating interval must begin on a- natural boundary of that interval. Eg in weekly from DATE, DATE- must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an- error.-- 7. Other period expressions with an interval are automatically expanded- to cover a whole number of that interval. (This is done to improve- reports, but it also affects periodic transactions. Yes, it's a bit- inconsistent with the above.) Eg: ~ every 10th day of month from- 2020/01, which is equivalent to ~ every 10th day of month from- 2020/01/01, will be adjusted to start on 2019/12/10.-- Periodic transaction rules also have a second meaning: they are used to- define budget goals, shown in budget reports.-- Periodic rule syntax- A periodic transaction rule looks like a normal journal entry, with the- date replaced by a tilde (~) followed by a period expression (mnemonic:- ~ looks like a recurring sine wave.):-- ~ monthly- expenses:rent $2000- assets:bank:checking-- There is an additional constraint on the period expression: the start- date must fall on a natural boundary of the interval. Eg monthly from- 2018/1/1 is valid, but monthly from 2018/1/15 is not.-- Partial or relative dates (M/D, D, tomorrow, last week) in the period- expression can work (useful or not). They will be relative to today's- date, unless a Y default year directive is in effect, in which case- they will be relative to Y/1/1.-- Two spaces between period expression and description!- If the period expression is followed by a transaction description,- these must be separated by two or more spaces. This helps hledger know- where the period expression ends, so that descriptions can not acciden-- tally alter their meaning, as in this example:-- ; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020"- ; ||- ; vv- ~ every 2 months in 2020, we will review- assets:bank:checking $1500- income:acme inc-- So,-- o Do write two spaces between your period expression and your transac-- tion description, if any.-- o Don't accidentally write two spaces in the middle of your period- expression.-- Forecasting with periodic transactions- The --forecast flag activates any periodic transaction rules in the- journal. They will generate temporary recurring transactions, which- are not saved in the journal, but will appear in all reports (eg- print). This can be useful for estimating balances into the future, or- experimenting with different scenarios. Or, it can be used as a data- entry aid: describe recurring transactions, and every so often copy the- output of print --forecast into the journal.-- These transactions will have an extra tag indicating which periodic- rule generated them: generated-transaction:~ PERIODICEXPR. And a simi-- lar, hidden tag (beginning with an underscore) which, because it's- never displayed by print, can be used to match transactions generated- "just now": _generated-transaction:~ PERIODICEXPR.-- Periodic transactions are generated within some forecast period. By- default, this-- o begins on the later of-- o the report start date if specified with -b/-p/date:-- o the day after the latest normal (non-periodic) transaction in the- journal, or today if there are no normal transactions.-- o ends on the report end date if specified with -e/-p/date:, or 6- months (180 days) from today.-- This means that periodic transactions will begin only after the latest- recorded transaction. And a recorded transaction dated in the future- can prevent generation of periodic transactions. (You can avoid that- by writing the future transaction as a one-time periodic rule instead -- put tilde before the date, eg ~ YYYY-MM-DD ...).-- Or, you can set your own arbitrary "forecast period", which can overlap- recorded transactions, and need not be in the future, by providing an- option argument, like --forecast=PERIODEXPR. Note the equals sign is- required, a space won't work. PERIODEXPR is a period expression, which- can specify the start date, end date, or both, like in a date: query.- (See also hledger.1 -> Report start & end date). Some examples:- --forecast=202001-202004, --forecast=jan-, --forecast=2020.-- Budgeting with periodic transactions- With the --budget flag, currently supported by the balance command,- each periodic transaction rule declares recurring budget goals for the- specified accounts. Eg the first example above declares a goal of- spending $2000 on rent (and also, a goal of depositing $2000 into- checking) every month. Goals and actual performance can then be com-- pared in budget reports.-- See also: Budgeting and Forecasting.--- Auto postings- "Automated postings" or "auto postings" are extra postings which get- added automatically to transactions which match certain queries,- defined by "auto posting rules", when you use the --auto flag.-- An auto posting rule looks a bit like a transaction:-- = QUERY- ACCOUNT AMOUNT- ...- ACCOUNT [AMOUNT]-- except the first line is an equals sign (mnemonic: = suggests match-- ing), followed by a query (which matches existing postings), and each- "posting" line describes a posting to be generated, and the posting- amounts can be:-- o a normal amount with a commodity symbol, eg $2. This will be used- as-is.-- o a number, eg 2. The commodity symbol (if any) from the matched post-- ing will be added to this.-- o a numeric multiplier, eg *2 (a star followed by a number N). The- matched posting's amount (and total price, if any) will be multiplied- by N.-- o a multiplier with a commodity symbol, eg *$2 (a star, number N, and- symbol S). The matched posting's amount will be multiplied by N, and- its commodity symbol will be replaced with S.-- Any query term containing spaces must be enclosed in single or double- quotes, as on the command line. Eg, note the quotes around the second- query term below:-- = expenses:groceries 'expenses:dining out'- (budget:funds:dining out) *-1-- Some examples:-- ; every time I buy food, schedule a dollar donation- = expenses:food- (liabilities:charity) $-1-- ; when I buy a gift, also deduct that amount from a budget envelope subaccount- = expenses:gifts- assets:checking:gifts *-1- assets:checking *1-- 2017/12/1- expenses:food $10- assets:checking-- 2017/12/14- expenses:gifts $20- assets:checking-- $ hledger print --auto- 2017-12-01- expenses:food $10- assets:checking- (liabilities:charity) $-1-- 2017-12-14- expenses:gifts $20- assets:checking- assets:checking:gifts -$20- assets:checking $20-- Auto postings and multiple files- An auto posting rule can affect any transaction in the current file, or- in any parent file or child file. Note, currently it will not affect- sibling files (when multiple -f/--file are used - see #1212).-- Auto postings and dates- A posting date (or secondary date) in the matched posting, or (taking- precedence) a posting date in the auto posting rule itself, will also- be used in the generated posting.-- Auto postings and transaction balancing / inferred amounts / balance asser-- tions- Currently, auto postings are added:-- o after missing amounts are inferred, and transactions are checked for- balancedness,-- o but before balance assertions are checked.-- Note this means that journal entries must be balanced both before and- after auto postings are added. This changed in hledger 1.12+; see #893- for background.-- Auto posting tags- Automated postings will have some extra tags:-- o generated-posting:= QUERY - shows this was generated by an auto post-- ing rule, and the query-- o _generated-posting:= QUERY - a hidden tag, which does not appear in- hledger's output. This can be used to match postings generated "just- now", rather than generated in the past and saved to the journal.-- Also, any transaction that has been changed by auto posting rules will- have these tags added:-- o modified: - this transaction was modified-- o _modified: - a hidden tag not appearing in the comment; this transac-- tion was modified "just now".--CSV FORMAT- How hledger reads CSV data, and the CSV rules file format.-- hledger can read CSV files (Character Separated Value - usually comma,- semicolon, or tab) containing dated records as if they were journal- files, automatically converting each CSV record into a transaction.-- (To learn about writing CSV, see CSV output.)-- We describe each CSV file's format with a corresponding rules file. By- default this is named like the CSV file with a .rules extension added.- Eg when reading FILE.csv, hledger also looks for FILE.csv.rules in the- same directory as FILE.csv. You can specify a different rules file- with the --rules-file option. If a rules file is not found, hledger- will create a sample rules file, which you'll need to adjust.-- This file contains rules describing the CSV data (header line, fields- layout, date format etc.), and how to construct hledger journal entries- (transactions) from it. Often there will also be a list of conditional- rules for categorising transactions based on their descriptions.- Here's an overview of the CSV rules; these are described more fully- below, after the examples:--- skip skip one or more header lines or matched CSV- records--- fields list name CSV fields, assign them to hledger- fields- field assignment assign a value to one hledger field, with- interpolation- Field names hledger field names, used in the fields list- and field assignments- separator a custom field separator- if block apply some rules to CSV records matched by- patterns- if table apply some rules to CSV records matched by- patterns, alternate syntax- end skip the remaining CSV records- date-format how to parse dates in CSV records- decimal-mark the decimal mark used in CSV amounts, if- ambiguous- newest-first disambiguate record order when there's only- one date- include inline another CSV rules file- balance-type choose which type of balance assignments to- use-- Note, for best error messages when reading CSV files, use a .csv, .tsv- or .ssv file extension or file prefix - see File Extension below.-- There's an introductory Convert CSV files tutorial on hledger.org.-- Examples- Here are some sample hledger CSV rules files. See also the full col-- lection at:- https://github.com/simonmichael/hledger/tree/master/examples/csv-- Basic- At minimum, the rules file must identify the date and amount fields,- and often it also specifies the date format and how many header lines- there are. Here's a simple CSV file and a rules file for it:-- Date, Description, Id, Amount- 12/11/2019, Foo, 123, 10.23-- # basic.csv.rules- skip 1- fields date, description, _, amount- date-format %d/%m/%Y-- $ hledger print -f basic.csv- 2019-11-12 Foo- expenses:unknown 10.23- income:unknown -10.23-- Default account names are chosen, since we didn't set them.-- Bank of Ireland- Here's a CSV with two amount fields (Debit and Credit), and a balance- field, which we can use to add balance assertions, which is not neces-- sary but provides extra error checking:-- Date,Details,Debit,Credit,Balance- 07/12/2012,LODGMENT 529898,,10.0,131.21- 07/12/2012,PAYMENT,5,,126-- # bankofireland-checking.csv.rules-- # skip the header line- skip-- # name the csv fields, and assign some of them as journal entry fields- fields date, description, amount-out, amount-in, balance-- # We generate balance assertions by assigning to "balance"- # above, but you may sometimes need to remove these because:- #- # - the CSV balance differs from the true balance,- # by up to 0.0000000000005 in my experience- #- # - it is sometimes calculated based on non-chronological ordering,- # eg when multiple transactions clear on the same day-- # date is in UK/Ireland format- date-format %d/%m/%Y-- # set the currency- currency EUR-- # set the base account for all txns- account1 assets:bank:boi:checking-- $ hledger -f bankofireland-checking.csv print- 2012-12-07 LODGMENT 529898- assets:bank:boi:checking EUR10.0 = EUR131.2- income:unknown EUR-10.0-- 2012-12-07 PAYMENT- assets:bank:boi:checking EUR-5.0 = EUR126.0- expenses:unknown EUR5.0-- The balance assertions don't raise an error above, because we're read-- ing directly from CSV, but they will be checked if these entries are- imported into a journal file.-- Amazon- Here we convert amazon.com order history, and use an if block to gener-- ate a third posting if there's a fee. (In practice you'd probably get- this data from your bank instead, but it's an example.)-- "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"- "Jul 29, 2012","Payment","To","Foo.","Completed","$20.00","$0.00","16000000000000DGLNJPI1P9B8DKPVHL"- "Jul 30, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$1.00","17LA58JSKRD4HDGLNJPI1P9B8DKPVHL"-- # amazon-orders.csv.rules-- # skip one header line- skip 1-- # name the csv fields, and assign the transaction's date, amount and code.- # Avoided the "status" and "amount" hledger field names to prevent confusion.- fields date, _, toorfrom, name, amzstatus, amzamount, fees, code-- # how to parse the date- date-format %b %-d, %Y-- # combine two fields to make the description- description %toorfrom %name-- # save the status as a tag- comment status:%amzstatus-- # set the base account for all transactions- account1 assets:amazon- # leave amount1 blank so it can balance the other(s).- # I'm assuming amzamount excludes the fees, don't remember-- # set a generic account2- account2 expenses:misc- amount2 %amzamount- # and maybe refine it further:- #include categorisation.rules-- # add a third posting for fees, but only if they are non-zero.- if %fees [1-9]- account3 expenses:fees- amount3 %fees-- $ hledger -f amazon-orders.csv print- 2012-07-29 (16000000000000DGLNJPI1P9B8DKPVHL) To Foo. ; status:Completed- assets:amazon- expenses:misc $20.00-- 2012-07-30 (17LA58JSKRD4HDGLNJPI1P9B8DKPVHL) To Adapteva, Inc. ; status:Completed- assets:amazon- expenses:misc $25.00- expenses:fees $1.00-- Paypal- Here's a real-world rules file for (customised) Paypal CSV, with some- Paypal-specific rules, and a second rules file included:-- "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"- "10/01/2019","03:46:20","PDT","Calm Radio","Subscription Payment","Completed","USD","-6.99","0.00","-6.99","simon@joyful.com","memberships@calmradio.com","60P57143A8206782E","MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month","","I-R8YLY094FJYR","","-6.99",""- "10/01/2019","03:46:20","PDT","","Bank Deposit to PP Account ","Pending","USD","6.99","0.00","6.99","","simon@joyful.com","0TU1544T080463733","","","60P57143A8206782E","","0.00",""- "10/01/2019","08:57:01","PDT","Patreon","PreApproved Payment Bill User Payment","Completed","USD","-7.00","0.00","-7.00","simon@joyful.com","support@patreon.com","2722394R5F586712G","Patreon* Membership","","B-0PG93074E7M86381M","","-7.00",""- "10/01/2019","08:57:01","PDT","","Bank Deposit to PP Account ","Pending","USD","7.00","0.00","7.00","","simon@joyful.com","71854087RG994194F","Patreon* Membership","","2722394R5F586712G","","0.00",""- "10/19/2019","03:02:12","PDT","Wikimedia Foundation, Inc.","Subscription Payment","Completed","USD","-2.00","0.00","-2.00","simon@joyful.com","tle@wikimedia.org","K9U43044RY432050M","Monthly donation to the Wikimedia Foundation","","I-R5C3YUS3285L","","-2.00",""- "10/19/2019","03:02:12","PDT","","Bank Deposit to PP Account ","Pending","USD","2.00","0.00","2.00","","simon@joyful.com","3XJ107139A851061F","","","K9U43044RY432050M","","0.00",""- "10/22/2019","05:07:06","PDT","Noble Benefactor","Subscription Payment","Completed","USD","10.00","-0.59","9.41","noble@bene.fac.tor","simon@joyful.com","6L8L1662YP1334033","Joyful Systems","","I-KC9VBGY2GWDB","","9.41",""-- # paypal-custom.csv.rules-- # Tips:- # Export from Activity -> Statements -> Custom -> Activity download- # Suggested transaction type: "Balance affecting"- # Paypal's default fields in 2018 were:- # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Shipping Address","Address Status","Item Title","Item ID","Shipping and Handling Amount","Insurance Amount","Sales Tax","Option 1 Name","Option 1 Value","Option 2 Name","Option 2 Value","Reference Txn ID","Invoice Number","Custom Number","Quantity","Receipt ID","Balance","Address Line 1","Address Line 2/District/Neighborhood","Town/City","State/Province/Region/County/Territory/Prefecture/Republic","Zip/Postal Code","Country","Contact Phone Number","Subject","Note","Country Code","Balance Impact"- # This rules file assumes the following more detailed fields, configured in "Customize report fields":- # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"-- fields date, time, timezone, description_, type, status_, currency, grossamount, feeamount, netamount, fromemail, toemail, code, itemtitle, itemid, referencetxnid, receiptid, balance, note-- skip 1-- date-format %-m/%-d/%Y-- # ignore some paypal events- if- In Progress- Temporary Hold- Update to- skip-- # add more fields to the description- description %description_ %itemtitle-- # save some other fields as tags- comment itemid:%itemid, fromemail:%fromemail, toemail:%toemail, time:%time, type:%type, status:%status_-- # convert to short currency symbols- if %currency USD- currency $- if %currency EUR- currency E- if %currency GBP- currency P-- # generate postings-- # the first posting will be the money leaving/entering my paypal account- # (negative means leaving my account, in all amount fields)- account1 assets:online:paypal- amount1 %netamount-- # the second posting will be money sent to/received from other party- # (account2 is set below)- amount2 -%grossamount-- # if there's a fee, add a third posting for the money taken by paypal.- if %feeamount [1-9]- account3 expenses:banking:paypal- amount3 -%feeamount- comment3 business:-- # choose an account for the second posting-- # override the default account names:- # if the amount is positive, it's income (a debit)- if %grossamount ^[^-]- account2 income:unknown- # if negative, it's an expense (a credit)- if %grossamount ^-- account2 expenses:unknown-- # apply common rules for setting account2 & other tweaks- include common.rules-- # apply some overrides specific to this csv-- # Transfers from/to bank. These are usually marked Pending,- # which can be disregarded in this case.- if- Bank Account- Bank Deposit to PP Account- description %type for %referencetxnid %itemtitle- account2 assets:bank:wf:pchecking- account1 assets:online:paypal-- # Currency conversions- if Currency Conversion- account2 equity:currency conversion-- # common.rules-- if- darcs- noble benefactor- account2 revenues:foss donations:darcshub- comment2 business:-- if- Calm Radio- account2 expenses:online:apps-- if- electronic frontier foundation- Patreon- wikimedia- Advent of Code- account2 expenses:dues-- if Google- account2 expenses:online:apps- description google | music-- $ hledger -f paypal-custom.csv print- 2019-10-01 (60P57143A8206782E) Calm Radio MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month ; itemid:, fromemail:simon@joyful.com, toemail:memberships@calmradio.com, time:03:46:20, type:Subscription Payment, status:Completed- assets:online:paypal $-6.99 = $-6.99- expenses:online:apps $6.99-- 2019-10-01 (0TU1544T080463733) Bank Deposit to PP Account for 60P57143A8206782E ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:46:20, type:Bank Deposit to PP Account, status:Pending- assets:online:paypal $6.99 = $0.00- assets:bank:wf:pchecking $-6.99-- 2019-10-01 (2722394R5F586712G) Patreon Patreon* Membership ; itemid:, fromemail:simon@joyful.com, toemail:support@patreon.com, time:08:57:01, type:PreApproved Payment Bill User Payment, status:Completed- assets:online:paypal $-7.00 = $-7.00- expenses:dues $7.00-- 2019-10-01 (71854087RG994194F) Bank Deposit to PP Account for 2722394R5F586712G Patreon* Membership ; itemid:, fromemail:, toemail:simon@joyful.com, time:08:57:01, type:Bank Deposit to PP Account, status:Pending- assets:online:paypal $7.00 = $0.00- assets:bank:wf:pchecking $-7.00-- 2019-10-19 (K9U43044RY432050M) Wikimedia Foundation, Inc. Monthly donation to the Wikimedia Foundation ; itemid:, fromemail:simon@joyful.com, toemail:tle@wikimedia.org, time:03:02:12, type:Subscription Payment, status:Completed- assets:online:paypal $-2.00 = $-2.00- expenses:dues $2.00- expenses:banking:paypal ; business:-- 2019-10-19 (3XJ107139A851061F) Bank Deposit to PP Account for K9U43044RY432050M ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:02:12, type:Bank Deposit to PP Account, status:Pending- assets:online:paypal $2.00 = $0.00- assets:bank:wf:pchecking $-2.00-- 2019-10-22 (6L8L1662YP1334033) Noble Benefactor Joyful Systems ; itemid:, fromemail:noble@bene.fac.tor, toemail:simon@joyful.com, time:05:07:06, type:Subscription Payment, status:Completed- assets:online:paypal $9.41 = $9.41- revenues:foss donations:darcshub $-10.00 ; business:- expenses:banking:paypal $0.59 ; business:-- CSV rules- The following kinds of rule can appear in the rules file, in any order.- Blank lines and lines beginning with # or ; are ignored.-- skip- skip N-- The word "skip" followed by a number (or no number, meaning 1) tells- hledger to ignore this many non-empty lines preceding the CSV data.- (Empty/blank lines are skipped automatically.) You'll need this when-- ever your CSV data contains header lines.-- It also has a second purpose: it can be used inside if blocks to ignore- certain CSV records (described below).-- fields list- fields FIELDNAME1, FIELDNAME2, ...-- A fields list (the word "fields" followed by comma-separated field- names) is the quick way to assign CSV field values to hledger fields.- (The other way is field assignments, see below.) A fields list does- does two things:-- 1. It names the CSV fields. This is optional, but can be convenient- later for interpolating them.-- 2. Whenever you use a standard hledger field name (defined below), the- CSV value is assigned to that part of the hledger transaction.-- Here's an example that says "use the 1st, 2nd and 4th fields as the- transaction's date, description and amount; name the last two fields- for later reference; and ignore the others":-- fields date, description, , amount, , , somefield, anotherfield-- Tips:-- o The fields list always use commas, even if your CSV data uses another- separator character.-- o Currently there must be least two items in the list (at least one- comma).-- o Field names may not contain spaces. Spaces before/after field names- are optional.-- o If the CSV contains column headings, it's a good idea to use these,- suitably modified, as the basis for your field names (eg lower-cased,- with underscores instead of spaces).-- o If some heading names match standard hledger fields, but you don't- want to set the hledger fields directly, alter those names, eg by- appending an underscore.-- o Fields you don't care about can be given a dummy name (eg: _ ), or no- name.-- field assignment- HLEDGERFIELDNAME FIELDVALUE-- Field assignments are the more flexible way to assign CSV values to- hledger fields. They can be used instead of or in addition to a fields- list (see above).-- 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-- FIELDNAME).-- Some examples:-- # set the amount to the 4th CSV field, with " USD" appended- amount %4 USD-- # combine three fields to make a comment, containing note: and date: tags- comment note: %somefield - %anotherfield, date: %1-- Tips:-- o Interpolation strips outer whitespace (so a CSV value like " 1 "- becomes 1 when interpolated) (#1051).-- o See also Tips below.-- Field names- Here are the standard hledger field (and pseudo-field) names, which you- can use in a fields list and in field assignments. For more about the- transaction parts they refer to, see Transactions.-- date field- Assigning to date sets the transaction date.-- date2 field- date2 sets the transaction's secondary date, if any.-- status field- status sets the transaction's status, if any.-- code field- code sets the transaction's code, if any.-- description field- description sets the transaction's description, if any.-- comment field- comment sets the transaction's comment, if any.-- commentN, where N is a number, sets the Nth posting's comment.-- Tips: - Only single-line comments can be assigned. - Comments can con-- tain tags, as usual.-- account field- 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- each transaction's description, and in conditional blocks.-- If a posting's account name is left unset but its amount is set (see- below), a default account name will be chosen (like "expenses:unknown"- or "income:unknown").-- amount field- amountN sets the amount of the Nth posting, and causes that posting to- be generated. By assigning to amount1, amount2, ... etc. you can- generate up to 99 postings.-- amountN-in and amountN-out can be used instead, if the CSV uses sepa-- rate fields for debits and credits (inflows and outflows). hledger- assumes both of these CSV fields are unsigned, and will automatically- negate the "-out" value. If they are signed, see "Setting amounts"- below.-- amount, or amount-in and amount-out are a legacy mode, to keep pre-- hledger-1.17 CSV rules files working (and for occasional convenience).- They are suitable only for two-posting transactions; they set both- posting 1's and posting 2's amount. Posting 2's amount will be- negated, and also converted to cost if there's a transaction price.-- If you have an existing rules file using the unnumbered form, you might- want to use the numbered form in certain conditional blocks, without- having to update and retest all the old rules. To facilitate this,- posting 1 ignores amount/amount-in/amount-out if any of- amount1/amount1-in/amount1-out are assigned, and posting 2 ignores them- if any of amount2/amount2-in/amount2-out are assigned, avoiding con-- flicts.-- currency field- currency sets a currency symbol, to be prepended to all postings'- amounts. You can use this if the CSV amounts do not have a currency- symbol, eg if it is in a separate column.-- currencyN prepends a currency symbol to just the Nth posting's amount.-- balance field- balanceN sets a balance assertion amount (or if the posting amount is- left empty, a balance assignment) on posting N.-- 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- rule (see below).-- See Tips below for more about setting amounts and currency.-- separator- You can use the separator rule to read other kinds of character-sepa-- rated data. The argument is any single separator character, or the- words tab or space (case insensitive). Eg, for comma-separated values- (CSV):-- separator ,-- or for semicolon-separated values (SSV):-- separator ;-- or for tab-separated values (TSV):-- separator TAB-- If the input file has a .csv, .ssv or .tsv file extension (or a csv:,- ssv:, tsv: prefix), the appropriate separator will be inferred automat-- ically, and you won't need this rule.-- if block- if MATCHER- RULE-- if- MATCHER- MATCHER- MATCHER- RULE- RULE-- Conditional blocks ("if blocks") are a block of rules that are applied- only to CSV records which match certain patterns. They are often used- for customising account names based on transaction descriptions.-- Matching the whole record- Each MATCHER can be a record matcher, which looks like this:-- REGEX-- REGEX is a case-insensitive regular expression that tries to match any-- where within the CSV record. It is a POSIX ERE (extended regular- expression) that also supports GNU word boundaries (\b, \B, \<, \>),- and nothing else. If you have trouble, be sure to check our doc:- https://hledger.org/hledger.html#regular-expressions-- Important note: the record that is matched is not the original record,- but a synthetic one, with any enclosing double quotes (but not enclos-- ing whitespace) removed, and always comma-separated (which means that a- field containing a comma will appear like two fields). Eg, if the- original record is 2020-01-01; "Acme, Inc."; 1,000, the REGEX will- actually see 2020-01-01,Acme, Inc., 1,000).-- Matching individual fields- Or, MATCHER can be a field matcher, like this:-- %CSVFIELD REGEX-- which matches just the content of a particular CSV field. CSVFIELD is- a percent sign followed by the field's name or column number, like- %date or %1.-- Combining matchers- A single matcher can be written on the same line as the "if"; or multi-- ple matchers can be written on the following lines, non-indented. Mul-- tiple matchers are OR'd (any one of them can match), unless one begins- with an & symbol, in which case it is AND'ed with the previous matcher.-- if- MATCHER- & MATCHER- RULE-- Rules applied on successful match- After the patterns there should be one or more rules to apply, all- indented by at least one space. Three kinds of rule are allowed in- conditional blocks:-- o field assignments (to set a hledger field)-- o skip (to skip the matched CSV record)-- o end (to skip all remaining CSV records).-- Examples:-- # if the CSV record contains "groceries", set account2 to "expenses:groceries"- if groceries- account2 expenses:groceries-- # if the CSV record contains any of these patterns, set account2 and comment as shown- if- monthly service fee- atm transaction fee- banking thru software- account2 expenses:business:banking- comment XXX deductible ? check it-- if table- if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn- MATCHER1,VALUE11,VALUE12,...,VALUE1n- MATCHER2,VALUE21,VALUE22,...,VALUE2n- MATCHER3,VALUE31,VALUE32,...,VALUE3n- <empty line>-- Conditional tables ("if tables") are a different syntax to specify- field assignments that will be applied only to CSV records which match- certain patterns.-- MATCHER could be either field or record matcher, as described above.- When MATCHER matches, values from that row would be assigned to the CSV- fields named on the if line, in the same order.-- Therefore if table is exactly equivalent to a sequence of of if blocks:-- if MATCHER1- CSVFIELDNAME1 VALUE11- CSVFIELDNAME2 VALUE12- ...- CSVFIELDNAMEn VALUE1n-- if MATCHER2- CSVFIELDNAME1 VALUE21- CSVFIELDNAME2 VALUE22- ...- CSVFIELDNAMEn VALUE2n-- if MATCHER3- CSVFIELDNAME1 VALUE31- CSVFIELDNAME2 VALUE32- ...- CSVFIELDNAMEn VALUE3n-- Each line starting with MATCHER should contain enough (possibly empty)- values for all the listed fields.-- Rules would be checked and applied in the order they are listed in the- table and, like with if blocks, later rules (in the same or another ta-- ble) or if blocks could override the effect of any rule.-- Instead of ',' you can use a variety of other non-alphanumeric charac-- ters as a separator. First character after if is taken to be the sepa-- rator for the rest of the table. It is the responsibility of the user- to ensure that separator does not occur inside MATCHERs and values -- there is no way to escape separator.-- Example:-- if,account2,comment- atm transaction fee,expenses:business:banking,deductible? check it- %description groceries,expenses:groceries,- 2020/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out-- end- This rule can be used inside if blocks (only), to make hledger stop- reading this CSV file and move on to the next input file, or to command- execution. Eg:-- # ignore everything following the first empty record- if ,,,,- end-- date-format- date-format DATEFMT-- This is a helper for the date (and date2) fields. If your CSV dates- are not formatted like YYYY-MM-DD, YYYY/MM/DD or YYYY.MM.DD, you'll- need to add a date-format rule describing them with a strptime date- parsing pattern, which must parse the CSV date value completely. Some- examples:-- # MM/DD/YY- date-format %m/%d/%y-- # D/M/YYYY- # The - makes leading zeros optional.- date-format %-d/%-m/%Y-- # YYYY-Mmm-DD- date-format %Y-%h-%d-- # M/D/YYYY HH:MM AM some other junk- # Note the time and junk must be fully parsed, though only the date is used.- date-format %-m/%-d/%Y %l:%M %p some other junk-- For the supported strptime syntax, see:- https://hackage.haskell.org/package/time/docs/Data-Time-For-- mat.html#v:formatTime-- Note that although you can parse date-times which include a time zone,- that time zone is ignored; it will not change the date that is parsed.- This means when reading CSV data with times not in your local time- zone, dates can be "off by one".-- decimal-mark- decimal-mark .-- or:-- decimal-mark ,-- hledger automatically accepts either period or comma as a decimal mark- when parsing numbers (cf Amounts). However if any numbers in the CSV- contain digit group marks, such as thousand-separating commas, you- should declare the decimal mark explicitly with this rule, to avoid- misparsed numbers.-- newest-first- hledger always sorts the generated transactions by date. Transactions- on the same date should appear in the same order as their CSV records,- as hledger can usually auto-detect whether the CSV's normal order is- oldest first or newest first. But if all of the following are true:-- o the CSV might sometimes contain just one day of data (all records- having the same date)-- o the CSV records are normally in reverse chronological order (newest- at the top)-- o and you care about preserving the order of same-day transactions-- then, you should add the newest-first rule as a hint. Eg:-- # tell hledger explicitly that the CSV is normally newest first- newest-first-- include- include RULESFILE-- This includes the contents of another CSV rules file at this point.- RULESFILE is an absolute file path or a path relative to the current- file's directory. This can be useful for sharing common rules between- several rules files, eg:-- # someaccount.csv.rules-- ## someaccount-specific rules- fields date,description,amount- account1 assets:someaccount- account2 expenses:misc-- ## common rules- include categorisation.rules-- balance-type- Balance assertions generated by assigning to balanceN are of the simple- = type by default, which is a single-commodity, subaccount-excluding- assertion. You may find the subaccount-including variants more useful,- eg if you have created some virtual subaccounts of checking to help- with budgeting. You can select a different type of assertion with the- balance-type rule:-- # balance assertions will consider all commodities and all subaccounts- balance-type ==*-- Here are the balance assertion types for quick reference:-- = single commodity, exclude subaccounts- =* single commodity, include subaccounts- == multi commodity, exclude subaccounts- ==* multi commodity, include subaccounts-- Tips- Rapid feedback- It's a good idea to get rapid feedback while creating/troubleshooting- CSV rules. Here's a good way, using entr from http://eradman.com/entr-- project :-- $ ls foo.csv* | entr bash -c 'echo ----; hledger -f foo.csv print desc:SOMEDESC'-- A desc: query (eg) is used to select just one, or a few, transactions- of interest. "bash -c" is used to run multiple commands, so we can- echo a separator each time the command re-runs, making it easier to- read the output.-- Valid CSV- hledger accepts CSV conforming to RFC 4180. When CSV values are- enclosed in quotes, note:-- o they must be double quotes (not single quotes)-- o spaces outside the quotes are not allowed-- File Extension- To help hledger identify the format and show the right error messages,- CSV/SSV/TSV files should normally be named with a .csv, .ssv or .tsv- filename extension. Or, the file path should be prefixed with csv:,- ssv: or tsv:. Eg:-- $ hledger -f foo.ssv print-- or:-- $ cat foo | hledger -f ssv:- foo-- You can override the file extension with a separator rule if needed.- See also: Input files in the hledger manual.-- Reading multiple CSV files- If you use multiple -f options to read multiple CSV files at once,- hledger will look for a correspondingly-named rules file for each CSV- file. But if you use the --rules-file option, that rules file will be- used for all the CSV files.-- Valid transactions- After reading a CSV file, hledger post-processes and validates the gen-- erated journal entries as it would for a journal file - balancing them,- applying balance assignments, and canonicalising amount styles. Any- errors at this stage will be reported in the usual way, displaying the- problem entry.-- There is one exception: balance assertions, if you have generated them,- will not be checked, since normally these will work only when the CSV- data is part of the main journal. If you do need to check balance- assertions generated from CSV right away, pipe into another hledger:-- $ hledger -f file.csv print | hledger -f- print-- Deduplicating, importing- When you download a CSV file periodically, eg to get your latest bank- transactions, the new file may overlap with the old one, containing- some of the same records.-- The import command will (a) detect the new transactions, and (b) append- just those transactions to your main journal. It is idempotent, so you- don't have to remember how many times you ran it or with which version- of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This- is the easiest way to import CSV data. Eg:-- # download the latest CSV files, then run this command.- # Note, no -f flags needed here.- $ hledger import *.csv [--dry]-- This method works for most CSV files. (Where records have a stable- chronological order, and new records appear only at the new end.)-- A number of other tools and workflows, hledger-specific and otherwise,- exist for converting, deduplicating, classifying and managing CSV data.- See:-- o https://hledger.org -> sidebar -> real world setups-- o https://plaintextaccounting.org -> data import/conversion-- Setting amounts- Some tips on using the amount-setting rules discussed above.-- Here are the ways to set a posting's amount:-- 1. If the CSV has a single amount field:- Assign (via a fields list or a field assignment) to amountN. This sets- the Nth posting's amount. N is usually 1 or 2 but can go up to 99.-- 2. If the CSV has separate amount fields for debit & credit (in & out):-- a. If both fields are unsigned:- Assign to amountN-in and amountN-out. This sets posting N's amount- to whichever of these has a non-zero value, and negates the "-out"- value.-- b. If either field is signed (can contain a minus sign):- Use a conditional rule to flip the sign (of non-empty values).- Since hledger always negates amountN-out, if it was already nega-- tive, we must undo that by negating once more (but only if the- field is non-empty):-- fields date, description, amount1-in, amount1-out- if %amount1-out [1-9]- amount1-out -%amount1-out-- c. If both fields, or neither field, can contain a non-zero value:- hledger normally expects exactly one of the fields to have a non-- zero value. Eg, the amountN-in/amountN-out rules would reject- value pairs like these:-- "", ""- "0", "0"- "1", "none"-- So, use smarter conditional rules to set the amount from the appro-- priate field. Eg, these rules would make it use only the value- containing non-zero digits, handling the above:-- fields date, description, in, out- if %in [1-9]- amount1 %in- if %out [1-9]- amount1 %out-- 3. If you are stuck with hledger <1.17, or you want posting 2's amount- converted to cost:- Assign to amount (or to amount-in and amount-out). (The old numberless- syntax, which sets amount1 and amount2.)-- 4. If the CSV has the balance instead of the transaction amount:- Assign to balanceN, which sets posting N's amount indirectly via a bal-- ance assignment. (Old syntax: balance, equivalent to balance1.)-- o If hledger guesses the wrong default account name:- When setting the amount via balance assertion, hledger may guess- the wrong default account name. So, set the account name explic-- itly, eg:-- fields date, description, balance1- account1 assets:checking-- Amount signs- There is some special handling for amount signs, to simplify parsing- and sign-flipping:-- o If an amount value begins with a plus sign:- that will be removed: +AMT becomes AMT-- o If an amount value is parenthesised:- it will be de-parenthesised and sign-flipped: (AMT) becomes -AMT-- o If an amount value has two minus signs (or two sets of parentheses,- or a minus sign and parentheses):- they cancel out and will be removed: --AMT or -(AMT) becomes AMT-- o If an amount value contains just a sign (or just a set of parenthe-- ses):- that is removed, making it an empty value. "+" or "-" or "()" becomes- "".-- Setting currency/commodity- If the currency/commodity symbol is included in the CSV's amount- field(s):-- 2020-01-01,foo,$123.00-- you don't have to do anything special for the commodity symbol, it will- be assigned as part of the amount. Eg:-- fields date,description,amount-- 2020-01-01 foo- expenses:unknown $123.00- income:unknown $-123.00-- If the currency is provided as a separate CSV field:-- 2020-01-01,foo,USD,123.00-- You can assign that to the currency pseudo-field, which has the special- effect of prepending itself to every amount in the transaction (on the- left, with no separating space):-- fields date,description,currency,amount-- 2020-01-01 foo- expenses:unknown USD123.00- income:unknown USD-123.00-- Or, you can use a field assignment to construct the amount yourself,- with more control. Eg to put the symbol on the right, and separated by- a space:-- fields date,description,cur,amt- amount %amt %cur-- 2020-01-01 foo- expenses:unknown 123.00 USD- income:unknown -123.00 USD-- Note we used a temporary field name (cur) that is not currency - that- would trigger the prepending effect, which we don't want here.-- Amount decimal places- Like amounts in a journal file, the amounts generated by CSV rules like- 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- 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- hledger field:-- # Name the third CSV field "amount1"- fields date,description,amount1-- # Set hledger's amount1 to the CSV amount1 field followed by USD- amount1 %amount1 USD-- # Set comment to the CSV amount1 (not the amount1 assigned above)- comment %amount1-- Here, since there's no CSV amount1 field, %amount1 will produce a lit-- eral "amount1":-- fields date,description,csvamount- amount1 %csvamount USD- # Can't interpolate amount1 here- comment %amount1-- When there are multiple field assignments to the same hledger field,- only the last one takes effect. Here, comment's value will be be B, or- C if "something" is matched, but never A:-- comment A- comment B- if something- comment C-- How CSV rules are evaluated- Here's how to think of CSV rules being evaluated (if you really need- to). First,-- o include - all includes are inlined, from top to bottom, depth first.- (At each include point the file is inlined and scanned for further- includes, recursively, before proceeding.)-- Then "global" rules are evaluated, top to bottom. If a rule is- repeated, the last one wins:-- o skip (at top level)-- o date-format-- o newest-first-- o fields - names the CSV fields, optionally sets up initial assignments- to hledger fields-- Then for each CSV record in turn:-- o test all if blocks. If any of them contain a end rule, skip all- remaining CSV records. Otherwise if any of them contain a skip rule,- skip that many CSV records. If there are multiple matched skip- rules, the first one wins.-- o collect all field assignments at top level and in matched if blocks.- When there are multiple assignments for a field, keep only the last- one.-- o compute a value for each hledger field - either the one that was- assigned to it (and interpolate the %CSVFIELDNAME references), or a- default-- o generate a synthetic hledger transaction from these values.-- This is all part of the CSV reader, one of several readers hledger can- use to parse input files. When all files have been read successfully,- the transactions are passed as input to whichever hledger command the- user specified.--TIMECLOCK FORMAT- The time logging format of timeclock.el, as read by hledger.-- hledger can read time logs in timeclock format. As with Ledger, these- are (a subset of) timeclock.el's format, containing clock-in and clock-- out entries as in the example below. The date is a simple date. The- time format is HH:MM[:SS][+-ZZZZ]. Seconds and timezone are optional.- The timezone, if present, must be four digits and is ignored (currently- the time is always interpreted as a local time).-- i 2015/03/30 09:00:00 some:account name optional description after two spaces- o 2015/03/30 09:20:00- i 2015/03/31 22:21:45 another account- o 2015/04/01 02:00:34-- hledger treats each clock-in/clock-out pair as a transaction posting- some number of hours to an account. Or if the session spans more than- one day, it is split into several transactions, one for each day. For- the above time log, hledger print generates these journal entries:-- $ hledger -f t.timeclock print- 2015-03-30 * optional description after two spaces- (some:account name) 0.33h-- 2015-03-31 * 22:21-23:59- (another account) 1.64h-- 2015-04-01 * 00:00-02:00- (another account) 2.01h-- Here is a sample.timeclock to download and some queries to try:-- $ hledger -f sample.timeclock balance # current time balances- $ hledger -f sample.timeclock register -p 2009/3 # sessions in march 2009- $ hledger -f sample.timeclock register -p weekly --depth 1 --empty # time summary by week-- To generate time logs, ie to clock in and clock out, you could:-- o use emacs and the built-in timeclock.el, or the extended timeclock-- x.el and perhaps the extras in ledgerutils.el-- o at the command line, use these bash aliases: shell alias ti="echo- i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o- `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"-- o or use the old ti and to scripts in the ledger 2.x repository. These- rely on a "timeclock" executable which I think is just the ledger 2- executable renamed.--TIMEDOT FORMAT- hledger's human-friendly time logging format.-- Timedot is a plain text format for logging dated, categorised quanti-- ties (of time, usually), supported by hledger. It is convenient for- approximate and retroactive time logging, eg when the real-time clock-- in/out required with a timeclock file is too precise or too interrup-- tive. It can be formatted like a bar chart, making clear at a glance- where time was spent.-- Though called "timedot", this format is read by hledger as commodity-- less quantities, so it could be used to represent dated quantities- other than time. In the docs below we'll assume it's time.-- A timedot file contains a series of day entries. A day entry begins- with a non-indented hledger-style simple date (Y-M-D, Y/M/D, Y.M.D..)- Any additional text on the same line is used as a transaction descrip-- tion for this day.-- This is followed by optionally-indented timelog items for that day, one- per line. Each timelog item is a note, usually a- hledger:style:account:name representing a time category, followed by- two or more spaces, and a quantity. Each timelog item generates a- hledger transaction.-- Quantities can be written as:-- o dots: a sequence of dots (.) representing quarter hours. Spaces may- optionally be used for grouping. Eg: .... ..-- o an integral or decimal number, representing hours. Eg: 1.5-- o an integral or decimal number immediately followed by a unit symbol- s, m, h, d, w, mo, or y, representing seconds, minutes, hours, days- weeks, months or years respectively. Eg: 90m. The following equiva-- lencies are assumed, currently: 1m = 60s, 1h = 60m, 1d = 24h, 1w =- 7d, 1mo = 30d, 1y=365d.-- There is some flexibility allowing notes and todo lists to be kept- right in the time log, if needed:-- o Blank lines and lines beginning with # or ; are ignored.-- o Lines not ending with a double-space and quantity are parsed as items- taking no time, which will not appear in balance reports by default.- (Add -E to see them.)-- o Org mode headlines (lines beginning with one or more * followed by a- space) can be used as date lines or timelog items (the stars are- ignored). Also all org headlines before the first date line are- ignored. This means org users can manage their timelog as an org- outline (eg using org-mode/orgstruct-mode in Emacs), for organisa-- tion, faster navigation, controlling visibility etc.-- Examples:-- # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.- 2016/2/1- inc:client1 .... .... .... .... .... ....- fos:haskell .... ..- biz:research .-- 2016/2/2- inc:client1 .... ....- biz:research .-- 2016/2/3- inc:client1 4- fos:hledger 3- biz:research 1-- * Time log- ** 2020-01-01- *** adm:time .- *** adm:finance .-- * 2020 Work Diary- ** Q1- *** 2020-02-29- **** DONE- 0700 yoga- **** UNPLANNED- **** BEGUN- hom:chores- cleaning ...- water plants- outdoor - one full watering can- indoor - light watering- **** TODO- adm:planning: trip- *** LATER-- Reporting:-- $ hledger -f t.timedot print date:2016/2/2- 2016-02-02 *- (inc:client1) 2.00-- 2016-02-02 *- (biz:research) 0.25-- $ hledger -f t.timedot bal --daily --tree- Balance changes in 2016-02-01-2016-02-03:-- || 2016-02-01d 2016-02-02d 2016-02-03d- ============++========================================- biz || 0.25 0.25 1.00- research || 0.25 0.25 1.00- fos || 1.50 0 3.00- haskell || 1.50 0 0- hledger || 0 0 3.00- inc || 6.00 2.00 4.00- client1 || 6.00 2.00 4.00- ------------++----------------------------------------- || 7.75 2.25 8.00-- I prefer to use period for separating account components. We can make- this work with an account alias:-- 2016/2/4- fos.hledger.timedot 4- fos.ledger ..-- $ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4 --tree- 4.50 fos- 4.00 hledger:timedot- 0.50 ledger- --------------------- 4.50-- Here is a sample.timedot.--COMMON TASKS- Here are some quick examples of how to do some basic tasks with- hledger. For more details, see the reference section below, the- hledger_journal(5) manual, or the more extensive docs at- https://hledger.org.-- Getting help- $ hledger # show available commands- $ hledger --help # show common options- $ hledger CMD --help # show common and command options, and command help- $ hledger help # show available manuals/topics- $ hledger help hledger # show hledger manual as info/man/text (auto-chosen)- $ hledger help journal --man # show the journal manual as a man page- $ hledger help --help # show more detailed help for the help command-- Find more docs, chat, mail list, reddit, issue tracker:- https://hledger.org#help-feedback-- Constructing command lines- hledger has an extensive and powerful command line interface. We- strive to keep it simple and ergonomic, but you may run into one of the- confusing real world details described in OPTIONS, below. If that hap-- pens, here are some tips that may help:-- o command-specific options must go after the command (it's fine to put- all options there) (hledger CMD OPTS ARGS)-- o running add-on executables directly simplifies command line parsing- (hledger-ui OPTS ARGS)-- o enclose "problematic" args in single quotes-- o if needed, also add a backslash to hide regular expression metachar-- acters from the shell-- o to see how a misbehaving command is being parsed, add --debug=2.-- Starting a journal file- hledger looks for your accounting data in a journal file,- $HOME/.hledger.journal by default:-- $ hledger stats- The hledger journal file "/Users/simon/.hledger.journal" was not found.- Please create it first, eg with "hledger add" or a text editor.- Or, specify an existing journal file with -f or LEDGER_FILE.-- You can override this by setting the LEDGER_FILE environment variable.- It's a good practice to keep this important file under version control,- and to start a new file each year. So you could do something like- this:-- $ mkdir ~/finance- $ cd ~/finance- $ git init- Initialized empty Git repository in /Users/simon/finance/.git/- $ touch 2020.journal- $ echo "export LEDGER_FILE=$HOME/finance/2020.journal" >> ~/.bashrc- $ source ~/.bashrc- $ hledger stats- Main file : /Users/simon/finance/2020.journal- Included files :- Transactions span : to (0 days)- Last transaction : none- Transactions : 0 (0.0 per day)- Transactions last 30 days: 0 (0.0 per day)- Transactions last 7 days : 0 (0.0 per day)- Payees/descriptions : 0- Accounts : 0 (depth 0)- Commodities : 0 ()- Market prices : 0 ()-- Setting opening balances- Pick a starting date for which you can look up the balances of some- real-world assets (bank accounts, wallet..) and liabilities (credit- cards..).-- To avoid a lot of data entry, you may want to start with just one or- two accounts, like your checking account or cash wallet; and pick a- recent starting date, like today or the start of the week. You can- always come back later and add more accounts and older transactions, eg- going back to january 1st.-- Add an opening balances transaction to the journal, declaring the bal-- ances on this date. Here are two ways to do it:-- o The first way: open the journal in any text editor and save an entry- like this:-- 2020-01-01 * opening balances- assets:bank:checking $1000 = $1000- assets:bank:savings $2000 = $2000- assets:cash $100 = $100- liabilities:creditcard $-50 = $-50- equity:opening/closing balances-- These are start-of-day balances, ie whatever was in the account at- the end of the previous day.-- The * after the date is an optional status flag. Here it means- "cleared & confirmed".-- The currency symbols are optional, but usually a good idea as you'll- be dealing with multiple currencies sooner or later.-- The = amounts are optional balance assertions, providing extra error- checking.-- o The second way: run hledger add and follow the prompts to record a- similar transaction:-- $ hledger add- Adding transactions to journal file /Users/simon/finance/2020.journal- Any command line arguments will be used as defaults.- Use tab key to complete, readline keys to edit, enter to accept defaults.- An optional (CODE) may follow transaction dates.- An optional ; COMMENT may follow descriptions or amounts.- If you make a mistake, enter < at any prompt to go one step backward.- To end a transaction, enter . when prompted.- To quit, enter . at a date prompt or press control-d or control-c.- Date [2020-02-07]: 2020-01-01- Description: * opening balances- Account 1: assets:bank:checking- Amount 1: $1000- Account 2: assets:bank:savings- Amount 2 [$-1000]: $2000- Account 3: assets:cash- Amount 3 [$-3000]: $100- Account 4: liabilities:creditcard- Amount 4 [$-3100]: $-50- Account 5: equity:opening/closing balances- Amount 5 [$-3050]:- Account 6 (or . or enter to finish this transaction): .- 2020-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050-- Save this transaction to the journal ? [y]:- Saved.- Starting the next transaction (. or ctrl-D/ctrl-C to quit)- Date [2020-01-01]: .-- If you're using version control, this could be a good time to commit- the journal. Eg:-- $ git commit -m 'initial balances' 2020.journal-- Recording transactions- As you spend or receive money, you can record these transactions using- one of the methods above (text editor, hledger add) or by using the- hledger-iadd or hledger-web add-ons, or by using the import command to- convert CSV data downloaded from your bank.-- Here are some simple transactions, see the hledger_journal(5) manual- and hledger.org for more ideas:-- 2020/1/10 * gift received- assets:cash $20- income:gifts-- 2020.1.12 * farmers market- expenses:food $13- assets:cash-- 2020-01-15 paycheck- income:salary- assets:bank:checking $1000-- Reconciling- Periodically you should reconcile - compare your hledger-reported bal-- ances against external sources of truth, like bank statements or your- bank's website - to be sure that your ledger accurately represents the- real-world balances (and, that the real-world institutions have not- made a mistake!). This gets easy and fast with (1) practice and (2)- frequency. If you do it daily, it can take 2-10 minutes. If you let- it pile up, expect it to take longer as you hunt down errors and dis-- crepancies.-- A typical workflow:-- 1. Reconcile cash. Count what's in your wallet. Compare with what- hledger reports (hledger bal cash). If they are different, try to- remember the missing transaction, or look for the error in the- already-recorded transactions. A register report can be helpful- (hledger reg cash). If you can't find the error, add an adjustment- transaction. Eg if you have $105 after the above, and can't explain- the missing $2, it could be:-- 2020-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- 2. Reconcile checking. Log in to your bank's website. Compare today's- (cleared) balance with hledger's cleared balance (hledger bal check-- ing -C). If they are different, track down the error or record the- missing transaction(s) or add an adjustment transaction, similar to- the above. Unlike the cash case, you can usually compare the trans-- action history and running balance from your bank with the one- reported by hledger reg checking -C. This will be easier if you- generally record transaction dates quite similar to your bank's- clearing dates.-- 3. Repeat for other asset/liability accounts.-- Tip: instead of the register command, use hledger-ui to see a live-- updating register while you edit the journal: hledger-ui --watch --reg-- ister checking -C-- After reconciling, it could be a good time to mark the reconciled- transactions' status as "cleared and confirmed", if you want to track- that, by adding the * marker. Eg in the paycheck transaction above,- insert * between 2020-01-15 and paycheck-- If you're using version control, this can be another good time to com-- mit:-- $ git commit -m 'txns' 2020.journal-- Reporting- Here are some basic reports.-- Show all transactions:-- $ hledger print- 2020-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050-- 2020-01-10 * gift received- assets:cash $20- income:gifts-- 2020-01-12 * farmers market- expenses:food $13- assets:cash-- 2020-01-15 * paycheck- income:salary- assets:bank:checking $1000-- 2020-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- Show account names, and their hierarchy:-- $ hledger accounts --tree- assets- bank- checking- savings- cash- equity- opening/closing balances- expenses- food- misc- income- gifts- salary- liabilities- creditcard-- Show all account totals:-- $ hledger balance- $4105 assets- $4000 bank- $2000 checking- $2000 savings- $105 cash- $-3050 equity:opening/closing balances- $15 expenses- $13 food- $2 misc- $-1020 income- $-20 gifts- $-1000 salary- $-50 liabilities:creditcard- --------------------- 0-- Show only asset and liability balances, as a flat list, limited to- depth 2:-- $ hledger bal assets liabilities --flat -2- $4000 assets:bank- $105 assets:cash- $-50 liabilities:creditcard- --------------------- $4055-- Show the same thing without negative numbers, formatted as a simple- balance sheet:-- $ hledger bs --flat -2- Balance Sheet 2020-01-16-- || 2020-01-16- ========================++============- Assets ||- ------------------------++------------- assets:bank || $4000- assets:cash || $105- ------------------------++------------- || $4105- ========================++============- Liabilities ||- ------------------------++------------- liabilities:creditcard || $50- ------------------------++------------- || $50- ========================++============- Net: || $4055-- The final total is your "net worth" on the end date. (Or use bse for a- full balance sheet with equity.)-- Show income and expense totals, formatted as an income statement:-- hledger is- Income Statement 2020-01-01-2020-01-16-- || 2020-01-01-2020-01-16- ===============++=======================- Revenues ||- ---------------++------------------------ income:gifts || $20- income:salary || $1000- ---------------++------------------------ || $1020- ===============++=======================- Expenses ||- ---------------++------------------------ expenses:food || $13- expenses:misc || $2- ---------------++------------------------ || $15- ===============++=======================- Net: || $1005-- The final total is your net income during this period.-- Show transactions affecting your wallet, with running total:-- $ hledger register cash- 2020-01-01 opening balances assets:cash $100 $100- 2020-01-10 gift received assets:cash $20 $120- 2020-01-12 farmers market assets:cash $-13 $107- 2020-01-16 adjust cash assets:cash $-2 $105-- Show weekly posting counts as a bar chart:-- $ hledger activity -W- 2019-12-30 *****- 2020-01-06 ****- 2020-01-13 ****-- Migrating to a new file- At the end of the year, you may want to continue your journal in a new- file, so that old transactions don't slow down or clutter your reports,- and to help ensure the integrity of your accounting history. See the- close command.-- If using version control, don't forget to git add the new file.--LIMITATIONS- The need to precede add-on command options with -- when invoked from- hledger is awkward.-- When input data contains non-ascii characters, a suitable system locale- must be configured (or there will be an unhelpful error). Eg on POSIX,- set LANG to something other than C.-- In a Microsoft Windows CMD window, non-ascii characters and colours are- not supported.-- On Windows, non-ascii characters may not display correctly when running- a hledger built in CMD in MSYS/CYGWIN, or vice-versa.-- In a Cygwin/MSYS/Mintty window, the tab key is not supported in hledger- add.-- Not all of Ledger's journal file syntax is supported. See file format- differences.-- On large data files, hledger is slower and uses more memory than- Ledger.--TROUBLESHOOTING- Here are some issues you might encounter when you run hledger (and- remember you can also seek help from the IRC channel, mail list or bug- tracker):-- Successfully installed, but "No command 'hledger' found"- stack and cabal install binaries into a special directory, which should- be added to your PATH environment variable. Eg on unix-like systems,- that is ~/.local/bin and ~/.cabal/bin respectively.-- I set a custom LEDGER_FILE, but hledger is still using the default file- LEDGER_FILE should be a real environment variable, not just a shell- variable. The command env | grep LEDGER_FILE should show it. You may- need to use export. Here's an explanation.-- Getting errors like "Illegal byte sequence" or "Invalid or incomplete- multibyte or wide character" or "commitAndReleaseBuffer: invalid argu-- ment (invalid character)"- Programs compiled with GHC (hledger, haskell build tools, etc.) need to- have a UTF-8-aware locale configured in the environment, otherwise they- will fail with these kinds of errors when they encounter non-ascii- characters.-- To fix it, set the LANG environment variable to some locale which sup-- ports UTF-8. The locale you choose must be installed on your system.-- Here's an example of setting LANG temporarily, on Ubuntu GNU/Linux:-- $ file my.journal- my.journal: UTF-8 Unicode text # the file is UTF8-encoded- $ echo $LANG- C # LANG is set to the default locale, which does not support UTF8- $ locale -a # which locales are installed ?- C- en_US.utf8 # here's a UTF8-aware one we can use- POSIX- $ LANG=en_US.utf8 hledger -f my.journal print # ensure it is used for this command-- If available, C.UTF-8 will also work. If your preferred locale isn't- listed by locale -a, you might need to install it. Eg on- Ubuntu/Debian:-- $ apt-get install language-pack-fr- $ locale -a- C- en_US.utf8- fr_BE.utf8- fr_CA.utf8- fr_CH.utf8- fr_FR.utf8- fr_LU.utf8- POSIX- $ LANG=fr_FR.utf8 hledger -f my.journal print-- Here's how you could set it permanently, if you use a bash shell:-- $ echo "export LANG=en_US.utf8" >>~/.bash_profile- $ bash --login-- Exact spelling and capitalisation may be important. Note the differ-- ence on MacOS (UTF-8, not utf8). Some platforms (eg ubuntu) allow- variant spellings, but others (eg macos) require it to be exact:-- $ locale -a | grep -iE en_us.*utf- en_US.UTF-8- $ LANG=en_US.UTF-8 hledger -f my.journal print----REPORTING BUGS- Report bugs at http://bugs.hledger.org (or on the #hledger IRC channel- or hledger mail list)---AUTHORS- Simon Michael <simon@joyful.com> and contributors---COPYRIGHT- Copyright (C) 2007-2020 Simon Michael.- Released under GNU GPL v3 or later.---SEE ALSO- hledger(1), hledger-ui(1), hledger-web(1), ledger(1)----hledger-1.22.1 August 2021 HLEDGER(1)+ manual is for hledger 1.22.2.++SYNOPSIS+ hledger++ hledger [-f FILE] COMMAND [OPTIONS] [ARGS]++ hledger [-f FILE] ADDONCMD -- [OPTIONS] [ARGS]++DESCRIPTION+ hledger is a reliable, cross-platform set of programs for tracking+ money, time, or any other commodity, using double-entry accounting and+ a simple, editable file format. hledger is inspired by and largely+ compatible with ledger(1).++ The basic function of the hledger CLI is to read a plain text file+ describing financial transactions (in accounting terms, a general jour-+ nal) and print useful reports on standard output, or export them as+ CSV. hledger can also read some other file formats such as CSV files,+ translating them to journal format. Additionally, hledger lists other+ hledger-* executables found in the user's $PATH and can invoke them as+ subcommands.++ hledger reads data from one or more files in hledger journal, time-+ clock, timedot, or CSV format specified with -f, or $LEDGER_FILE, or+ $HOME/.hledger.journal (on windows, perhaps+ C:/Users/USER/.hledger.journal). If using $LEDGER_FILE, note this must+ be a real environment variable, not a shell variable. You can specify+ standard input with -f-.++ Transactions are dated movements of money between two (or more) named+ accounts, and are recorded with journal entries like this:++ 2015/10/16 bought food+ expenses:food $10+ assets:cash++ Most users use a text editor to edit the journal, usually with an edi-+ tor mode such as ledger-mode for added convenience. hledger's interac-+ tive add command is another way to record new transactions. hledger+ never changes existing transactions.++ To get started, you can either save some entries like the above in+ ~/.hledger.journal, or run hledger add and follow the prompts. Then+ try some commands like hledger print or hledger balance. Run hledger+ with no arguments for a list of commands.++OPTIONS+ General options+ To see general usage help, including general options which are sup-+ ported by most hledger commands, run hledger -h.++ General help options:++ -h --help+ show general or COMMAND help++ --man show general or COMMAND user manual with man++ --info show general or COMMAND user manual with info++ --version+ show general or ADDONCMD version++ --debug[=N]+ show debug output (levels 1-9, default: 1)++ General input options:++ -f FILE --file=FILE+ use a different input file. For stdin, use - (default:+ $LEDGER_FILE or $HOME/.hledger.journal)++ --rules-file=RULESFILE+ Conversion rules file to use when reading CSV (default:+ FILE.rules)++ --separator=CHAR+ Field separator to expect when reading CSV (default: ',')++ --alias=OLD=NEW+ rename accounts named OLD to NEW++ --anon anonymize accounts and payees++ --pivot FIELDNAME+ use some other field or tag for the account name++ -I --ignore-assertions+ disable balance assertion checks (note: does not disable balance+ assignments)++ -s --strict+ do extra error checking (check that all posted accounts are+ declared)++ General reporting options:++ -b --begin=DATE+ include postings/txns on or after this date (will be adjusted to+ preceding subperiod start when using a report interval)++ -e --end=DATE+ include postings/txns before this date (will be adjusted to fol-+ lowing subperiod end when using a report interval)++ -D --daily+ multiperiod/multicolumn report by day++ -W --weekly+ multiperiod/multicolumn report by week++ -M --monthly+ multiperiod/multicolumn report by month++ -Q --quarterly+ multiperiod/multicolumn report by quarter++ -Y --yearly+ multiperiod/multicolumn report by year++ -p --period=PERIODEXP+ set start date, end date, and/or reporting interval all at once+ using period expressions syntax++ --date2+ match the secondary date instead (see command help for other+ effects)++ -U --unmarked+ include only unmarked postings/txns (can combine with -P or -C)++ -P --pending+ include only pending postings/txns++ -C --cleared+ include only cleared postings/txns++ -R --real+ include only non-virtual postings++ -NUM --depth=NUM+ hide/aggregate accounts or postings more than NUM levels deep++ -E --empty+ show items with zero amount, normally hidden (and vice-versa in+ hledger-ui/hledger-web)++ -B --cost+ convert amounts to their cost/selling amount at transaction time++ -V --market+ convert amounts to their market value in default valuation com-+ modities++ -X --exchange=COMM+ convert amounts to their market value in commodity COMM++ --value+ convert amounts to cost or market value, more flexibly than+ -B/-V/-X++ --infer-market-prices+ use transaction prices (recorded with @ or @@) as additional+ market prices, as if they were P directives++ --auto apply automated posting rules to modify transactions.++ --forecast+ generate future transactions from periodic transaction rules,+ for the next 6 months or till report end date. In hledger-ui,+ also make ordinary future transactions visible.++ --color=WHEN (or --colour=WHEN)+ Should color-supporting commands use ANSI color codes in text+ output. 'auto' (default): whenever stdout seems to be a color-+ supporting terminal. 'always' or 'yes': always, useful eg when+ piping output into 'less -R'. 'never' or 'no': never. A+ NO_COLOR environment variable overrides this.++ When a reporting option appears more than once in the command line, the+ last one takes precedence.++ Some reporting options can also be written as query arguments.++ Command options+ To see options for a particular command, including command-specific+ options, run: hledger COMMAND -h.++ Command-specific options must be written after the command name, eg:+ hledger print -x.++ Additionally, if the command is an add-on, you may need to put its+ options after a double-hyphen, eg: hledger ui -- --watch. Or, you can+ run the add-on executable directly: hledger-ui --watch.++ Command arguments+ Most hledger commands accept arguments after the command name, which+ are often a query, filtering the data in some way.++ You can save a set of command line options/arguments in a file, and+ then reuse them by writing @FILENAME as a command line argument. Eg:+ hledger bal @foo.args. (To prevent this, eg if you have an argument+ that begins with a literal @, precede it with --, eg: hledger bal --+ @ARG).++ Inside the argument file, each line should contain just one option or+ argument. Avoid the use of spaces, except inside quotes (or you'll see+ a confusing error). Between a flag and its argument, use = (or noth-+ ing). Bad:++ assets depth:2+ -X USD++ Good:++ assets+ depth:2+ -X=USD++ For special characters (see below), use one less level of quoting than+ you would at the command prompt. Bad:++ -X"$"++ Good:++ -X$++ See also: Save frequently used options.++ Special characters+ Single escaping (shell metacharacters)+ In shell command lines, characters significant to your shell - such as+ spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want+ hledger to see them. This is done by enclosing them in single or dou-+ ble quotes, or by writing a backslash before them. Eg to match an+ account name containing a space:++ $ hledger register 'credit card'++ or:++ $ 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.+ 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+ using the bash shell:++ $ hledger balance cur:'\$'++ or:++ $ hledger balance cur:\\$++ Triple escaping (for add-on commands)+ When you use hledger to run an external add-on command (described+ below), one level of shell-escaping is lost from any options or argu-+ ments intended for by the add-on command, so those need an extra level+ of shell-escaping. Eg to match a literal $ sign while using the bash+ shell and running an add-on command (ui):++ $ hledger ui cur:'\\$'++ or:++ $ hledger ui cur:\\\\$++ If you wondered why four backslashes, perhaps this helps:+++ unescaped: $+ escaped: \$+ double-escaped: \\$+ triple-escaped: \\\\$++ Or, you can avoid the extra escaping by running the add-on executable+ directly:++ $ hledger-ui cur:\\$++ Less escaping+ Options and arguments are sometimes used in places other than the shell+ command line, where shell-escaping is not needed, so there you should+ use one less level of escaping. Those places include:++ o an @argumentfile++ o hledger-ui's filter field++ o hledger-web's search form++ o GHCI's prompt (used by developers).++ Unicode characters+ hledger is expected to handle non-ascii characters correctly:++ o they should be parsed correctly in input files and on the command+ line, by all hledger tools (add, iadd, hledger-web's search/add/edit+ forms, etc.)++ o they should be displayed correctly by all hledger tools, and on-+ screen alignment should be preserved.++ This requires a well-configured environment. Here are some tips:++ o A system locale must be configured, and it must be one that can+ decode the characters being used. In bash, you can set a locale like+ this: export LANG=en_US.UTF-8. There are some more details in Trou-+ bleshooting. This step is essential - without it, hledger will quit+ on encountering a non-ascii character (as with all GHC-compiled pro-+ grams).++ o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)+ must support unicode++ o the terminal must be using a font which includes the required unicode+ glyphs++ o the terminal should be configured to display wide characters as dou-+ ble width (for report alignment)++ o on Windows, for best results you should run hledger in the same kind+ of environment in which it was built. Eg hledger built in the stan-+ dard CMD.EXE environment (like the binaries on our download page)+ might show display problems when run in a cygwin or msys terminal,+ and vice versa. (See eg #961).++ Regular expressions+ hledger uses regular expressions in a number of places:++ o query terms, on the command line and in the hledger-web search form:+ REGEX, desc:REGEX, cur:REGEX, tag:...=REGEX++ o CSV rules conditional blocks: if REGEX ...++ o account alias directives and options: alias /REGEX/ = REPLACEMENT,+ --alias /REGEX/=REPLACEMENT++ hledger's regular expressions come from the regex-tdfa library. If+ they're not doing what you expect, it's important to know exactly what+ they support:++ 1. they are case insensitive++ 2. they are infix matching (they do not need to match the entire thing+ being matched)++ 3. they are POSIX ERE (extended regular expressions)++ 4. they also support GNU word boundaries (\b, \B, \<, \>)++ 5. they do not support backreferences; if you write \1, it will match+ the digit 1. Except when doing text replacement, eg in account+ aliases, where backreferences can be used in the replacement string+ to reference capturing groups in the search regexp.++ 6. they do not support mode modifiers ((?s)), character classes (\w,+ \d), or anything else not mentioned above.++ Some things to note:++ o In the alias directive and --alias option, regular expressions must+ be enclosed in forward slashes (/REGEX/). Elsewhere in hledger,+ these are not required.++ o In queries, to match a regular expression metacharacter like $ as a+ literal character, prepend a backslash. Eg to search for amounts+ with the dollar sign in hledger-web, write cur:\$.++ o On the command line, some metacharacters like $ have a special mean-+ ing to the shell and so must be escaped at least once more. See Spe-+ cial characters.++ENVIRONMENT+ LEDGER_FILE The journal file path when not specified with -f. Default:+ ~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour-+ nal).++ A typical value is ~/DIR/YYYY.journal, where DIR is a version-con-+ trolled finance directory and YYYY is the current year. Or ~/DIR/cur-+ rent.journal, where current.journal is a symbolic link to YYYY.journal.++ On Mac computers, you can set this and other environment variables in a+ more thorough way that also affects applications started from the GUI+ (say, an Emacs dock icon). Eg on MacOS Catalina I have a+ ~/.MacOSX/environment.plist file containing++ {+ "LEDGER_FILE" : "~/finance/current.journal"+ }++ To see the effect you may need to killall Dock, or reboot.++ COLUMNS The screen width used by the register command. Default: the+ full terminal width.++ NO_COLOR If this variable exists with any value, hledger will not use+ ANSI color codes in terminal output. This overrides the+ --color/--colour option.++DATA FILES+ hledger reads transactions from one or more data files. The default+ data file is $HOME/.hledger.journal (or on Windows, something like+ C:/Users/USER/.hledger.journal).++ You can override this with the $LEDGER_FILE environment variable:++ $ setenv LEDGER_FILE ~/finance/2016.journal+ $ hledger stats++ or with one or more -f/--file options:++ $ hledger -f /some/file -f another_file stats++ The file name - means standard input:++ $ cat some.journal | hledger -f-++ Data formats+ Usually the data file is in hledger's journal format, but it can be in+ any of the supported file formats, which currently are:+++ Reader: Reads: Used for file exten-+ sions:+ -----------------------------------------------------------------------------+ journal hledger journal files and some Ledger .journal .j .hledger+ journals, for transactions .ledger+ time- timeclock files, for precise time log- .timeclock+ clock ging+ timedot timedot files, for approximate time .timedot+ logging+ csv comma/semicolon/tab/other-separated .csv .ssv .tsv+ values, for data import++ These formats are described in their own sections, below.++ hledger detects the format automatically based on the file extensions+ shown above. If it can't recognise the file extension, it assumes+ journal format. So for non-journal files, it's important to use a+ recognised file extension, so as to either read successfully or to show+ relevant error messages.++ You can also force a specific reader/format by prefixing the file path+ with the format and a colon. Eg, to read a .dat file as csv format:++ $ hledger -f csv:/some/csv-file.dat stats++ Or to read stdin (-) as timeclock format:++ $ echo 'i 2009/13/1 08:00:00' | hledger print -ftimeclock:-++ Multiple files+ You can specify multiple -f options, to read multiple files as one big+ journal. There are some limitations with this:++ o most directives do not affect sibling files++ o balance assertions will not see any account balances from previous+ files++ If you need either of those things, you can++ o use a single parent file which includes the others++ o or concatenate the files into one before reading, eg: cat a.journal+ b.journal | hledger -f- CMD.++ Strict mode+ hledger checks input files for valid data. By default, the most impor-+ tant errors are detected, while still accepting easy journal files+ without a lot of declarations:++ o Are the input files parseable, with valid syntax ?++ o Are all transactions balanced ?++ o Do all balance assertions pass ?++ With the -s/--strict flag, additional checks are performed:++ o Are all accounts posted to, declared with an account directive ?+ (Account error checking)++ o Are all commodities declared with a commodity directive ? (Commodity+ error checking)++ o Are all commodity conversions declared explicitly ?++ You can also use the check command to run these and some additional+ checks.++TIME PERIODS+ Smart dates+ hledger's user interfaces accept a flexible "smart date" syntax. Smart+ dates allow some english words, can be relative to today's date, and+ can have less-significant date parts omitted (defaulting to 1).++ Examples:+++ 2004/10/1, 2004-01-01, exact date, several separators allowed. Year+ 2004.9.1 is 4+ digits, month is 1-12, day is 1-31+ 2004 start of year+ 2004/10 start of month+ 10/1 month and day in current year+ 21 day in current month+ october, oct start of month in current year+ yesterday, today, tomor- -1, 0, 1 days from today+ row+ last/this/next -1, 0, 1 periods from the current period+ day/week/month/quar-+ ter/year+ 20181201 8 digit YYYYMMDD with valid year month and day+ 201812 6 digit YYYYMM with valid year and month++ Counterexamples - malformed digit sequences might give surprising+ results:+++ 201813 6 digits with an invalid month is parsed as start of+ 6-digit year+ 20181301 8 digits with an invalid month is parsed as start of+ 8-digit year+ 20181232 8 digits with an invalid day gives an error+ 201801012 9+ digits beginning with a valid YYYYMMDD gives an error+++ Report start & end date+ By default, most hledger reports will show the full span of time repre-+ sented by the journal data. The report start date will be the earliest+ transaction or posting date, and the report end date will be the latest+ transaction, posting, or market price date.++ Often you will want to see a shorter time span, such as the current+ month. You can specify a start and/or end date using -b/--begin,+ -e/--end, -p/--period or a date: query (described below). All of these+ accept the smart date syntax.++ Some notes:++ o As in Ledger, end dates are exclusive, so you need to write the date+ after the last day you want to include.++ o As noted in reporting options: among start/end dates specified with+ options, the last (i.e. right-most) option takes precedence.++ o The effective report start and end dates are the intersection of the+ start/end dates from options and that from date: queries. That is,+ date:2019-01 date:2019 -p'2000 to 2030' yields January 2019, the+ smallest common time span.++ o A report interval (see below) will adjust start/end dates, when+ needed, so that they fall on subperiod boundaries.++ Examples:+++ -b 2016/3/17 begin on St. Patrick's day 2016+ -e 12/1 end at the start of december 1st of the current year+ (11/30 will be the last date included)+ -b thismonth all transactions on or after the 1st of the current month+ -p thismonth all transactions in the current month+ date:2016/3/17.. the above written as queries instead (.. can also be+ replaced with -)+ date:..12/1+ date:thismonth..+ date:thismonth++ Report intervals+ A report interval can be specified so that commands like register, bal-+ ance and activity become multi-period, showing each subperiod as a sep-+ arate row or column.++ The following "standard" report intervals can be enabled by using their+ corresponding flag:++ -D/--daily, -W/--weekly, -M/--monthly, -Q/--quarterly, -Y/--yearly.++ These standard intervals always start on natural interval boundaries:+ eg --weekly starts on mondays, --monthly starts on the first of the+ month, --yearly always starts on January 1st, etc.++ Certain more complex intervals, and more flexible boundary dates, can+ be specified by -p/--period. These are described in period expres-+ sions, below.++ Report intervals can only be specified by the flags above, and not by+ query arguments, currently.++ Report intervals have another effect: multi-period reports are always+ expanded to fill a whole number of subperiods. So if you use a report+ interval (other than --daily), and you have specified a start or end+ date, you may notice those dates being overridden (ie, the report+ starts earlier than your requested start date, or ends later than your+ requested end date). This is done to ensure "full" first and last sub-+ periods, so that all subperiods' numbers are comparable.++ Period expressions+ The -p/--period option accepts period expressions, a shorthand way of+ expressing a start date, end date, and/or report interval all at once.++ Here's a basic period expression specifying the first quarter of 2009.+ Note, hledger always treats start dates as inclusive and end dates as+ exclusive:++ -p "from 2009/1/1 to 2009/4/1"++ Keywords like "from" and "to" are optional, and so are the spaces, as+ long as you don't run two dates together. "to" can also be written as+ ".." or "-". These are equivalent to the above:+++ -p "2009/1/1 2009/4/1"+ -p2009/1/1to2009/4/1+ -p2009/1/1..2009/4/1++ Dates are smart dates, so if the current year is 2009, the above can+ also be written as:+++ -p "1/1 4/1"++ -p "january-apr"+ -p "this year to 4/1"++ If you specify only one date, the missing start or end date will be the+ earliest or latest transaction in your journal:+++ -p "from 2009/1/1" everything after january+ 1, 2009+ -p "from 2009/1" the same+ -p "from 2009" the same+ -p "to 2009" everything before january+ 1, 2009++ A single date with no "from" or "to" defines both the start and end+ date like so:+++ -p "2009" the year 2009; equivalent+ to "2009/1/1 to 2010/1/1"+ -p "2009/1" the month of jan; equiva-+ lent to "2009/1/1 to+ 2009/2/1"+ -p "2009/1/1" just that day; equivalent+ to "2009/1/1 to 2009/1/2"++ Or you can specify a single quarter like so:+++ -p "2009Q1" first quarter of 2009,+ equivalent to "2009/1/1 to+ 2009/4/1"+ -p "q4" fourth quarter of the cur-+ rent year++ The argument of -p can also begin with, or be, a report interval+ expression. The basic report intervals are daily, weekly, monthly,+ quarterly, or yearly, which have the same effect as the -D,-W,-M,-Q, or+ -Y flags. Between report interval and start/end dates (if any), the+ word in is optional. Examples:+++ -p "weekly from 2009/1/1 to 2009/4/1"+ -p "monthly in 2008"+ -p "quarterly"++ Note that weekly, monthly, quarterly and yearly intervals will always+ start on the first day on week, month, quarter or year accordingly, and+ will end on the last day of same period, even if associated period+ expression specifies different explicit start and end date.++ For example:+++ -p "weekly from 2009/1/1 starts on 2008/12/29, closest preceding Mon-+ to 2009/4/1" day+ -p "monthly in starts on 2018/11/01+ 2008/11/25"+ -p "quarterly from starts on 2009/04/01, ends on 2009/06/30,+ 2009-05-05 to 2009-06-01" which are first and last days of Q2 2009+ -p "yearly from starts on 2009/01/01, first day of 2009+ 2009-12-29"++ The following more complex report intervals are also supported:+ biweekly, fortnightly, bimonthly, every day|week|month|quarter|year,+ every N days|weeks|months|quarters|years.++ All of these will start on the first day of the requested period and+ end on the last one, as described above.++ Examples:+++ -p "bimonthly from 2008" periods will have boundaries on 2008/01/01,+ 2008/03/01, ...+ -p "every 2 weeks" starts on closest preceding Monday+ -p "every 5 month from periods will have boundaries on 2009/03/01,+ 2009/03" 2009/08/01, ...++ If you want intervals that start on arbitrary day of your choosing and+ span a week, month or year, you need to use any of the following:++ every Nth day of week, every WEEKDAYNAME (eg+ mon|tue|wed|thu|fri|sat|sun), every Nth day [of month], every Nth WEEK-+ DAYNAME [of month], every MM/DD [of year], every Nth MMM [of year],+ every MMM Nth [of year].++ Examples:+++ -p "every 2nd day of periods will go from Tue to Tue+ week"+ -p "every Tue" same+ -p "every 15th day" period boundaries will be on 15th of each+ month+ -p "every 2nd Monday" period boundaries will be on second Monday of+ each month+ -p "every 11/05" yearly periods with boundaries on 5th of Nov+ -p "every 5th Nov" same+ -p "every Nov 5th" same++ Show historical balances at end of 15th each month (N is exclusive end+ date):++ hledger balance -H -p "every 16th day"++ Group postings from start of wednesday to end of next tuesday (N is+ start date and exclusive end date):++ hledger register checking -p "every 3rd day of week"++DEPTH+ With the --depth N option (short form: -N), commands like account, bal-+ ance and register will show only the uppermost accounts in the account+ tree, down to level N. Use this when you want a summary with less+ detail. This flag has the same effect as a depth: query argument (so+ -2, --depth=2 or depth:2 are equivalent).++QUERIES+ One of hledger's strengths is being able to quickly report on a precise+ subset of your data. Most hledger commands accept optional query argu-+ ments to restrict their scope. The syntax is as follows:++ o Zero or more space-separated query terms. These are most often+ account name substrings:++ utilities food:groceries++ o Terms with spaces or other special characters should be enclosed in+ quotes:++ "personal care"++ o Regular expressions are also supported:++ "^expenses\b" "accounts (payable|receivable)"++ o Add a query type prefix to match other parts of the data:++ date:202012- desc:amazon cur:USD amt:">100" status:++ o Add a not: prefix to negate a term:++ not:cur:USD++ Query types+ Here are the types of query term available. Remember these can also be+ prefixed with not: to convert them into a negative match.++ acct:REGEX, REGEX+ 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.++ amt:N, amt:<N, amt:<=N, amt:>N, amt:>=N+ 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-+ erwise, the absolute magnitudes are compared, ignoring sign.++ code:REGEX+ Match by transaction code (eg check number).++ cur:REGEX+ Match postings or transactions including any amounts whose cur-+ rency/commodity symbol is fully matched by REGEX. (For a 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+ escaping. So eg to match the dollar sign:+ hledger print cur:\\$.++ desc:REGEX+ Match transaction descriptions.++ date:PERIODEXPR+ Match dates (or with the --date2 flag, secondary dates) within the+ specified period. PERIODEXPR is a period expression with no report+ interval. Examples:+ date:2016, date:thismonth, date:2/1-2/15, date:2021-07-27..nextquarter.++ date2:PERIODEXPR+ Match secondary dates within the specified period (independent of the+ --date2 flag).++ depth:N+ Match (or display, depending on command) accounts at or above this+ depth.++ note:REGEX+ Match transaction notes (the part of the description right of |, or the+ whole description if there's no |).++ payee:REGEX+ Match transaction payee/payer names (the part of the description left+ of |, or the whole description if there's no |).++ real:, real:0+ Match real or virtual postings respectively.++ status:, status:!, status:*+ Match unmarked, pending, or cleared transactions respectively.++ tag:REGEX[=REGEX]+ Match by tag name, and optionally also by tag value. (To match only by+ value, use tag:.=REGEX.) Note that postings also inherit tags from+ their transaction, and transactions also acquire tags from their post-+ ings, when querying.++ (inacct:ACCTNAME+ A special query term used automatically in hledger-web only: tells+ hledger-web to show the transaction register for an account.)++ Combining query terms+ Most commands select things which match:++ o any of the description terms AND++ o any of the account terms AND++ o any of the status terms AND++ o all the other terms.++ while the print command shows transactions which:++ o match any of the description terms AND++ o have any postings matching any of the positive account terms AND++ o have no postings matching any of the negative account terms AND++ o match all the other terms.++ You can do more powerful queries (such as AND-ing two like terms) by+ running a first query with print, and piping the result into a second+ hledger command. Eg: how much of food expenses was paid with cash ?++ $ hledger print assets:cash | hledger f- -I balance expenses:food++ If you are interested in full boolean expressions for queries, see+ #203.++ Queries and command options+ Some queries can also be expressed as command-line options: depth:2 is+ equivalent to --depth 2, date:2020 is equivalent to -p 2020, etc. When+ you mix command options and query arguments, generally the resulting+ query is their intersection.++ Queries and account aliases+ When account names are rewritten with --alias or alias, acct: will+ match either the old or the new account name.++ Queries and valuation+ When amounts are converted to other commodities in cost or value+ reports, 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+ reversed, see #1625).++ Querying with account aliases+ When account names are rewritten with --alias or alias, note that acct:+ will match either the old or the new account name.++ Querying with cost or value+ When amounts are converted to other commodities in cost or value+ reports, 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+ discussion at #1625.++COSTING+ The -B/--cost flag converts amounts to their cost or sale amount at+ transaction time, if they have a transaction price specified. If this+ flag is supplied, hledger will perform cost conversion first, and will+ apply any market price valuations (if requested) afterwards.++VALUATION+ Instead of reporting amounts in their original commodity, hledger can+ convert them to cost/sale amount (using the conversion rate recorded in+ the transaction), and/or to market value (using some market price on a+ certain date). This is controlled by the --value=TYPE[,COMMODITY]+ option, 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+ valuation commodity, using the market prices in effect on the valuation+ date(s), if any. More on these in a minute.++ -X: Value in specified commodity+ The -X/--exchange=COMM option is like -V, except you tell it which cur-+ rency you want to convert to, and it tries to convert everything to+ that.++ Valuation date+ Since market prices can change from day to day, market value reports+ have a valuation date (or more than one), which determines which market+ prices will be used.++ For single period reports, if an explicit report end date is specified,+ that will be used as the valuation date; otherwise the valuation date+ is the journal's end date.++ For multiperiod reports, each column/period is valued on the last day+ of the period, by default.++ Market prices+ To convert a commodity A to its market value in another commodity B,+ hledger looks for a suitable market price (exchange rate) as follows,+ in this order of preference :++ 1. A declared market price or inferred market price: A's latest market+ price in B on or before the valuation date as declared by a P direc-+ tive, or (with the --infer-market-price flag) inferred from transac-+ tion prices.++ 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-+ bining the shortest chain of "forward" (only 1 above) market prices,+ leading from A to B.++ 4. Any chain of market prices: a chain of any market prices, including+ both forward and reverse prices (1 and 2 above), leading from A to+ B.++ There is a limit to the length of these price chains; if hledger+ reaches that length without finding a complete chain or exhausting all+ possibilities, it will give up (with a "gave up" message visible in+ --debug=2 output). That limit is currently 1000.++ Amounts for which no suitable market price can be found, are not con-+ verted.++ --infer-market-price: market prices from transactions+ Normally, market value in hledger is fully controlled by, and requires,+ P directives in your journal. Since adding and updating those can be a+ chore, and since transactions usually take place at close to market+ value, why not use the recorded transaction prices as additional market+ prices (as Ledger does) ? We could produce value reports without need-+ ing P directives at all.++ Adding the --infer-market-price flag to -V, -X or --value enables this.+ So for example, hledger bs -V --infer-market-price will get market+ prices both from P directives and from transactions. (And if both+ occur on 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.++ --infer-market-price can infer market prices from:++ o multicommodity transactions with explicit prices (@/@@)++ o multicommodity transactions with implicit prices (no @, two commodi-+ ties, unbalanced). (With these, the order of postings matters.+ hledger print -x can be useful for troubleshooting.)++ o but not, currently, from "more correct" multicommodity transactions+ (no @, multiple commodities, balanced).++ Valuation commodity+ When you specify a valuation commodity (-X COMM or --value TYPE,COMM):+ hledger will convert all amounts to COMM, wherever it can find a suit-+ able market price (including by reversing or chaining prices).++ When you leave the valuation commodity unspecified (-V or --value+ TYPE):+ For each commodity A, hledger picks a default valuation commodity as+ follows, in this order of preference:++ 1. The price commodity from the latest P-declared market price for A on+ or before valuation date.++ 2. The price commodity from the latest P-declared market price for A on+ any date. (Allows conversion to proceed when there are inferred+ prices before the valuation date.)++ 3. If there are no P directives at all (any commodity or date) and the+ --infer-market-price flag is used: the price commodity from the lat-+ est transaction-inferred price for A on or before valuation date.++ This means:++ o If you have P directives, they determine which commodities -V will+ convert, and to what.++ o If you have no P directives, and use the --infer-market-price flag,+ transaction prices determine it.++ Amounts for which no valuation commodity can be found are not con-+ verted.++ Simple valuation examples+ Here are some quick examples of -V:++ ; one euro is worth this many dollars from nov 1+ P 2016/11/01 EUR $1.10++ ; purchase some euros on nov 3+ 2016/11/3+ assets:euros EUR100+ assets:checking++ ; the euro is worth fewer dollars by dec 21+ P 2016/12/21 EUR $1.03++ How many euros do I have ?++ $ hledger -f t.j bal -N euros+ EUR100 assets:euros++ What are they worth at end of nov 3 ?++ $ hledger -f t.j bal -N euros -V -e 2016/11/4+ $110.00 assets:euros++ What are they worth after 2016/12/21 ? (no report end date specified,+ defaults to today)++ $ hledger -f t.j bal -N euros -V+ $103.00 assets:euros++ --value: Flexible valuation+ -V and -X are special cases of the more general --value option:++ --value=TYPE[,COMM] TYPE is then, end, now or YYYY-MM-DD.+ COMM is an optional commodity symbol.+ Shows amounts converted to:+ - default valuation commodity (or COMM) using market prices at posting dates+ - default valuation commodity (or COMM) using market prices at period end(s)+ - default valuation commodity (or COMM) using current market prices+ - default valuation commodity (or COMM) using market prices at some date++ The TYPE part selects cost or value and valuation date:++ --value=then+ Convert amounts to their value in the default valuation commod-+ ity, using market prices on each posting's date.++ --value=end+ Convert amounts to their value in the default valuation commod-+ ity, using market prices on the last day of the report period+ (or if unspecified, the journal's end date); or in multiperiod+ reports, market prices on the last day of each subperiod.++ --value=now+ Convert amounts to their value in the default valuation commod-+ ity using current market prices (as of when report is gener-+ ated).++ --value=YYYY-MM-DD+ Convert amounts to their value in the default valuation commod-+ ity using market prices on this date.++ To select a different valuation commodity, add the optional ,COMM part:+ a comma, then the target commodity's symbol. Eg: --value=now,EUR.+ hledger will do its best to convert amounts to this commodity, deducing+ market prices as described above.++ More valuation examples+ Here are some examples showing the effect of --value, as seen with+ print:++ P 2000-01-01 A 1 B+ P 2000-02-01 A 2 B+ P 2000-03-01 A 3 B+ P 2000-04-01 A 4 B++ 2000-01-01+ (a) 1 A @ 5 B++ 2000-02-01+ (a) 1 A @ 6 B++ 2000-03-01+ (a) 1 A @ 7 B++ Show the cost of each posting:++ $ hledger -f- print --cost+ 2000-01-01+ (a) 5 B++ 2000-02-01+ (a) 6 B++ 2000-03-01+ (a) 7 B++ Show the value as of the last day of the report period (2000-02-29):++ $ hledger -f- print --value=end date:2000/01-2000/03+ 2000-01-01+ (a) 2 B++ 2000-02-01+ (a) 2 B++ With no report period specified, that shows the value as of the last+ day of the journal (2000-03-01):++ $ hledger -f- print --value=end+ 2000-01-01+ (a) 3 B++ 2000-02-01+ (a) 3 B++ 2000-03-01+ (a) 3 B++ Show the current value (the 2000-04-01 price is still in effect today):++ $ hledger -f- print --value=now+ 2000-01-01+ (a) 4 B++ 2000-02-01+ (a) 4 B++ 2000-03-01+ (a) 4 B++ Show the value on 2000/01/15:++ $ hledger -f- print --value=2000-01-15+ 2000-01-01+ (a) 1 B++ 2000-02-01+ (a) 1 B++ 2000-03-01+ (a) 1 B++ You may need to explicitly set a commodity's display style, when+ reverse prices are used. Eg this output might be surprising:++ P 2000-01-01 A 2B++ 2000-01-01+ a 1B+ b++ $ hledger print -x -X A+ 2000-01-01+ a 0+ b 0++ Explanation: because there's no amount or commodity directive specify-+ ing a display style for A, 0.5A gets the default style, which shows no+ decimal digits. Because the displayed amount looks like zero, the com-+ modity symbol and minus sign are not displayed either. Adding a com-+ modity directive sets a more useful display style for A:++ P 2000-01-01 A 2B+ commodity 0.00A++ 2000-01-01+ a 1B+ b++ $ hledger print -X A+ 2000-01-01+ a 0.50A+ b -0.50A++ Effect of valuation on reports+ Here is a reference for how valuation is supposed to affect each part+ of hledger's reports (and a glossary). (It's wide, you'll have to+ scroll sideways.) It may be useful when troubleshooting. If you find+ problems, please report them, ideally with a reproducible example.+ Related: #329, #1083.+++ Report -B, --cost -V, -X --value=then --value=end --value=DATE,+ type --value=now+ -----------------------------------------------------------------------------------------------+ print+ posting cost value at value at posting value at value at+ amounts report end date report or DATE/today+ or today journal end+ balance unchanged unchanged unchanged unchanged unchanged+ asser-+ tions/assign-+ ments++ register+ starting bal- cost value at day valued at day value at day value at+ ance (-H) before each historical before DATE/today+ report or posting was made report or+ journal journal+ start start+ posting cost value at value at posting value at value at+ amounts report end date report or DATE/today+ or today journal end+ summary post- summarised value at sum of postings value at value at+ ing amounts cost period ends in interval, val- period ends DATE/today+ with report ued at interval+ interval start+ running sum/average sum/average sum/average of sum/average sum/average+ total/average of displayed of displayed displayed values of displayed of displayed+ values values values values++++ balance (bs,+ bse, cf, is)+ balance sums of value at value at posting value at value at+ changes costs report end date report or DATE/today of+ or today of journal end sums of post-+ sums of of sums of ings+ postings postings+ budget like balance like balance like balance like bal- like balance+ amounts changes changes changes ances changes+ (--budget)+ grand total sum of dis- sum of dis- sum of displayed sum of dis- sum of dis-+ played val- played val- valued played val- played values+ ues ues ues++ balance (bs,+ bse, cf, is)+ with report+ interval+ starting bal- sums of value at sums of values of value at sums of post-+ ances (-H) costs of report start postings before report start ings before+ postings of sums of report start at of sums of report start+ before all postings respective post- all postings+ report start before ing dates before+ report start report start+ balance sums of same as sums of values of balance value at+ changes (bal, costs of --value=end postings in change in DATE/today of+ is, bs postings in period at respec- each period, sums of post-+ --change, cf period tive posting valued at ings+ --change) dates period ends+ end balances sums of same as sums of values of period end value at+ (bal -H, is costs of --value=end postings from balances, DATE/today of+ --H, bs, cf) postings before period valued at sums of post-+ from before start to period period ends ings+ report start end at respective+ to period posting dates+ end+ budget like balance like balance like balance like bal- like balance+ amounts changes/end changes/end changes/end bal- ances changes/end+ (--budget) balances balances ances balances+ row totals, sums, aver- sums, aver- sums, averages of sums, aver- sums, aver-+ row averages ages of dis- ages of dis- displayed values ages of dis- ages of dis-+ (-T, -A) played val- played val- played val- played values+ ues ues ues+ column totals sums of dis- sums of dis- sums of displayed sums of dis- sums of dis-+ played val- played val- values played val- played values+ ues ues ues+ grand total, sum, average sum, average sum, average of sum, average sum, average+ grand average of column of column column totals of column of column+ totals totals totals totals+++ --cumulative is omitted to save space, it works like -H but with a zero+ starting balance.++ Glossary:++ cost calculated using price(s) recorded in the transaction(s).++ value market value using available market price declarations, or the+ unchanged amount if no conversion rate can be found.++ report start+ the first day of the report period specified with -b or -p or+ date:, otherwise today.++ report or journal start+ the first day of the report period specified with -b or -p or+ date:, otherwise the earliest transaction date in the journal,+ otherwise today.++ report end+ the last day of the report period specified with -e or -p or+ date:, otherwise today.++ report or journal end+ the last day of the report period specified with -e or -p or+ date:, otherwise the latest transaction date in the journal,+ otherwise today.++ report interval+ a flag (-D/-W/-M/-Q/-Y) or period expression that activates the+ report's multi-period mode (whether showing one or many subperi-+ ods).++PIVOTING+ Normally hledger sums amounts, and organizes them in a hierarchy, based+ on account name. The --pivot FIELD option causes it to sum and orga-+ nize hierarchy based on the value of some other field instead. FIELD+ can be: code, description, payee, note, or the full name (case insensi-+ tive) of any tag. As with account names, values containing colon:sepa-+ rated:parts will be displayed hierarchically in reports.++ --pivot is a general option affecting all reports; you can think of+ hledger transforming the journal before any other processing, replacing+ every posting's account name with the value of the specified field on+ that posting, inheriting it from the transaction or using a blank value+ if it's not present.++ An example:++ 2016/02/16 Member Fee Payment+ assets:bank account 2 EUR+ income:member fees -2 EUR ; member: John Doe++ Normal balance report showing account names:++ $ hledger balance+ 2 EUR assets:bank account+ -2 EUR income:member fees+ --------------------+ 0++ Pivoted balance report, using member: tag values instead:++ $ hledger balance --pivot member+ 2 EUR+ -2 EUR John Doe+ --------------------+ 0++ One way to show only amounts with a member: value (using a query,+ described below):++ $ hledger balance --pivot member tag:member=.+ -2 EUR John Doe+ --------------------+ -2 EUR++ Another way (the acct: query matches against the pivoted "account+ name"):++ $ hledger balance --pivot member acct:.+ -2 EUR John Doe+ --------------------+ -2 EUR++OUTPUT+ Output destination+ hledger commands send their output to the terminal by default. You can+ of course redirect this, eg into a file, using standard shell syntax:++ $ hledger print > foo.txt++ Some commands (print, register, stats, the balance commands) also pro-+ vide the -o/--output-file option, which does the same thing without+ needing the shell. Eg:++ $ hledger print -o foo.txt+ $ hledger print -o - # write to stdout (the default)++ hledger can optionally produce debug output (if enabled with+ --debug=N); this goes to stderr, and is not affected by -o/--output-+ file. If you need to capture it, use shell redirects, eg: hledger bal+ --debug=3 >file 2>&1.++ Output format+ Some commands (print, register, the balance commands) offer a choice of+ output format. In addition to the usual plain text format (txt), there+ are CSV (csv), HTML (html), JSON (json) and SQL (sql). This is con-+ trolled by the -O/--output-format option:++ $ hledger print -O csv++ or, by a file extension specified with -o/--output-file:++ $ hledger balancesheet -o foo.html # write HTML to foo.html++ The -O option can be used to override the file extension if needed:++ $ hledger balancesheet -o foo.txt -O html # write HTML to foo.txt++ Some notes about JSON output:++ o This feature is marked experimental, and not yet much used; you+ should expect our JSON to evolve. Real-world feedback is welcome.++ o Our JSON is rather large and verbose, as it is quite a faithful rep-+ resentation of hledger's internal data types. To understand the+ JSON, read the Haskell type definitions, which are mostly in+ https://github.com/simonmichael/hledger/blob/master/hledger-+ lib/Hledger/Data/Types.hs.++ o hledger represents quantities as Decimal values storing up to 255+ significant digits, eg for repeating decimals. Such numbers can+ arise in practice (from automatically-calculated transaction prices),+ and would break most JSON consumers. So in JSON, we show quantities+ as simple Numbers with at most 10 decimal places. We don't limit the+ number of integer digits, but that part is under your control. We+ hope this approach will not cause problems in practice; if you find+ otherwise, please let us know. (Cf #1195)++ Notes about SQL output:++ o SQL output is also marked experimental, and much like JSON could use+ real-world feedback.++ o SQL output is expected to work with sqlite, MySQL and PostgreSQL++ o SQL output is structured with the expectations that statements will+ be executed in the empty database. If you already have tables cre-+ ated via SQL output of hledger, you would probably want to either+ clear tables of existing data (via delete or truncate SQL statements)+ or drop tables completely as otherwise your postings will be duped.++COMMANDS+ hledger provides a number of commands for producing reports and manag-+ ing your data. Run hledger with no arguments to list the commands+ available, and hledger CMD to run a command. CMD can be the full com-+ mand name, or its standard abbreviation shown in the commands list, or+ any unambiguous prefix of the name. Eg: hledger bal.++ Here are the built-in commands, with the most often-used in bold:++ Data entry:++ These data entry commands are the only ones which can modify your jour-+ nal file.++ o add - add transactions using guided prompts++ o import - add any new transactions from other files (eg csv)++ Data management:++ o check - check for various kinds of issue in the data++ o close (equity) - generate balance-resetting transactions++ o diff - compare account transactions in two journal files++ o rewrite - generate extra postings, similar to print --auto++ Financial statements:++ o aregister (areg) - show transactions in a particular account++ o balancesheet (bs) - show assets, liabilities and net worth++ o balancesheetequity (bse) - show assets, liabilities and equity++ o cashflow (cf) - show changes in liquid assets++ o incomestatement (is) - show revenues and expenses++ o roi - show return on investments++ Miscellaneous reports:++ o accounts - show account names++ o activity - show postings-per-interval bar charts++ o balance (bal) - show balance changes/end balances/budgets in any+ accounts++ o codes - show transaction codes++ o commodities - show commodity/currency symbols++ o descriptions - show unique transaction descriptions++ o files - show input file paths++ o help - show hledger user manuals in several formats++ o notes - show unique note segments of transaction descriptions++ o payees - show unique payee segments of transaction descriptions++ o prices - show market price records++ o print - show transactions (journal entries)++ o print-unique - show only transactions with unique descriptions++ o register (reg) - show postings in one or more accounts & running+ total++ o register-match - show a recent posting that best matches a descrip-+ tion++ o stats - show journal statistics++ o tags - show tag names++ o test - run self tests++ Add-on commands:++ Programs or scripts named hledger-SOMETHING in your PATH are add-on+ commands; these appear in the commands list with a + mark. Two of+ these are maintained and released with hledger:++ o ui - an efficient terminal interface (TUI) for hledger++ o web - a simple web interface (WUI) for hledger++ And these add-ons are maintained separately:++ o iadd - a more interactive alternative for the add command++ o interest - generates interest transactions according to various+ schemes++ o stockquotes - downloads market prices for your commodities from+ AlphaVantage (experimental)++ Next, the detailed command docs, in alphabetical order.++ accounts+ accounts+ Show account names.++ This command lists account names, either declared with account direc-+ tives (--declared), posted to (--used), or both (the default). With+ query arguments, only matched account names and account names refer-+ enced by matched postings are shown. It shows a flat list by default.+ With --tree, it uses indentation to show the account hierarchy. In+ flat mode you can add --drop N to omit the first few account name com-+ ponents. Account names can be depth-clipped with depth:N or --depth N+ or -N.++ Examples:++ $ hledger accounts+ assets:bank:checking+ assets:bank:saving+ assets:cash+ expenses:food+ expenses:supplies+ income:gifts+ income:salary+ liabilities:debts++ activity+ activity+ Show an ascii barchart of posting counts per interval.++ The activity command displays an ascii histogram showing transaction+ counts by day, week, month or other reporting interval (by day is the+ default). With query arguments, it counts only matched transactions.++ Examples:++ $ hledger activity --quarterly+ 2008-01-01 **+ 2008-04-01 *******+ 2008-07-01+ 2008-10-01 **++ add+ add+ Prompt for transactions and add them to the journal. Any arguments+ will be used as default inputs for the first N prompts.++ Many hledger users edit their journals directly with a text editor, or+ generate them from CSV. For more interactive data entry, there is the+ add command, which prompts interactively on the console for new trans-+ actions, and appends them to the journal file (if there are multiple -f+ FILE options, the first file is used.) Existing transactions are not+ changed. This is the only hledger command that writes to the journal+ file.++ To use it, just run hledger add and follow the prompts. You can add as+ many transactions as you like; when you are finished, enter . or press+ control-d or control-c to exit.++ Features:++ o add tries to provide useful defaults, using the most similar (by+ description) recent transaction (filtered by the query, if any) as a+ template.++ o You can also set the initial defaults with command line arguments.++ o Readline-style edit keys can be used during data entry.++ o The tab key will auto-complete whenever possible - accounts, descrip-+ tions, dates (yesterday, today, tomorrow). If the input area is+ empty, it will insert the default value.++ o If the journal defines a default commodity, it will be added to any+ bare numbers entered.++ o A parenthesised transaction code may be entered following a date.++ o Comments and tags may be entered following a description or amount.++ o If you make a mistake, enter < at any prompt to go one step backward.++ o Input prompts are displayed in a different colour when the terminal+ supports it.++ Example (see the tutorial for a detailed explanation):++ $ hledger add+ Adding transactions to journal file /src/hledger/examples/sample.journal+ Any command line arguments will be used as defaults.+ Use tab key to complete, readline keys to edit, enter to accept defaults.+ An optional (CODE) may follow transaction dates.+ An optional ; COMMENT may follow descriptions or amounts.+ If you make a mistake, enter < at any prompt to go one step backward.+ To end a transaction, enter . when prompted.+ To quit, enter . at a date prompt or press control-d or control-c.+ Date [2015/05/22]:+ Description: supermarket+ Account 1: expenses:food+ Amount 1: $10+ Account 2: assets:checking+ Amount 2 [$-10.0]:+ Account 3 (or . or enter to finish this transaction): .+ 2015/05/22 supermarket+ expenses:food $10+ assets:checking $-10.0++ Save this transaction to the journal ? [y]:+ Saved.+ Starting the next transaction (. or ctrl-D/ctrl-C to quit)+ Date [2015/05/22]: <CTRL-D> $++ On Microsoft Windows, the add command makes sure that no part of the+ file path ends with a period, as that would cause problems (#1056).++ aregister+ aregister, areg++ Show the transactions and running historical balance of a single+ account, with each transaction displayed as one line.++ aregister shows the overall transactions affecting a particular account+ (and any subaccounts). Each report line represents one transaction in+ this account. Transactions before the report start date are always+ included in the running balance (--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+ 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+ expression which will select the alphabetically first matched account.+ (Eg if you have assets:aaa:checking and assets:bbb:checking accounts,+ hledger areg checking would select assets:aaa:checking.)++ Transactions involving subaccounts of this account will also be shown.+ aregister ignores depth limits, so its final total will always match a+ balance report with similar arguments.++ Any additional arguments form a query which will filter the transac-+ 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+ 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,+ see below)++ 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+ the -E/--empty flag to show them.++ This command also supports the output destination and output format+ options. The output formats supported are txt, csv, and json.++ aregister and custom posting dates+ Transactions whose date is outside the report period can still be+ shown, if they have a posting to this account dated inside the report+ period. (And in this case it's the posting date that is shown.) This+ ensures that aregister can show an accurate historical running balance,+ matching the one shown by register -H with the same arguments.++ To filter strictly by transaction date instead, add the --txn-dates+ flag. If you use this flag and some of your postings have custom+ dates, it's probably best to assume the running balance is wrong.++ balance+ balance, bal+ 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+ more, during one time period or many. Generally it shows a table, with+ rows representing accounts, and columns representing periods.++ Note there are some higher-level variants of the balance command with+ convenient defaults, which can be simpler to use: balancesheet, bal-+ ancesheetequity, cashflow and incomestatement. When you need more con-+ 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+ higher-level commands as well.++ balance can show..++ o accounts as a list (-l) or a tree (-t)++ o optionally depth-limited (-[1-9])++ o sorted by declaration order and name, or by amount++ ..and their..++ o balance changes (the default)++ o or actual and planned balance changes (--budget)++ o or value of balance changes (-V)++ o or change of balance values (--valuechange)++ ..in..++ o one time period (the whole journal period by default)++ o or multiple periods (-D, -W, -M, -Q, -Y, -p INTERVAL)++ ..either..++ o per period (the default)++ o or accumulated since report start date (--cumulative)++ o or accumulated since account creation (--historical/-H)++ ..possibly converted to..++ o cost (--value=cost[,COMM]/--cost/-B)++ o or market value, as of transaction dates (--value=then[,COMM])++ o or at period ends (--value=end[,COMM])++ o or now (--value=now)++ o or at some other date (--value=YYYY-MM-DD)++ ..with..++ o totals (-T), averages (-A), percentages (-%), inverted sign+ (--invert)++ o rows and columns swapped (--transpose)++ o another field used as account name (--pivot)++ o custom-formatted line items (single-period reports only) (--format)++ This command supports the output destination and output format options,+ with output formats txt, csv, json, and (multi-period reports only:)+ html. In txt output in a colour-supporting terminal, negative amounts+ are shown in red.++ Simple balance report+ With no arguments, balance shows a list of all accounts and their+ change of balance - ie, the sum of posting amounts, both inflows and+ outflows - during the entire period of the journal. For real-world+ accounts, this should also match their end balance at the end of the+ journal period (more on this below).++ Accounts are sorted by declaration order if any, and then alphabeti-+ cally by account name. For instance, using examples/sample.journal:++ $ hledger bal+ $1 assets:bank:saving+ $-2 assets:cash+ $1 expenses:food+ $1 expenses:supplies+ $-1 income:gifts+ $-1 income:salary+ $1 liabilities:debts+ --------------------+ 0++ 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+ (revealing assets:bank:checking here):++ $ hledger -f examples/sample.journal bal -E+ 0 assets:bank:checking+ $1 assets:bank:saving+ $-2 assets:cash+ $1 expenses:food+ $1 expenses:supplies+ $-1 income:gifts+ $-1 income:salary+ $1 liabilities:debts+ --------------------+ 0++ The total of the amounts displayed is shown as the last line, unless+ -N/--no-total is used.++ Filtered balance report+ 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:++ $ hledger bal --cleared assets date:200806+ $-2 assets:cash+ --------------------+ $-2++ List or tree mode+ By default, or with -l/--flat, accounts are shown as a flat list with+ their full names visible, as in the examples above.++ With -t/--tree, the account hierarchy is shown, with subaccounts'+ "leaf" names indented below their parent:++ $ hledger balance+ $-1 assets+ $1 bank:saving+ $-2 cash+ $2 expenses+ $1 food+ $1 supplies+ $-2 income+ $-1 gifts+ $-1 salary+ $1 liabilities:debts+ --------------------+ 0++ 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+ above).++ 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.++ o Each group of sibling accounts (ie, under a common parent) is sorted+ separately.++ Depth limiting+ With a depth:N query, or --depth N option, or just -N, balance reports+ will show accounts only to the specified depth, hiding the deeper sub-+ accounts. Account balances at the depth limit always include the bal-+ ances from any hidden subaccounts (even in list mode). This can be+ useful for getting an overview. Eg, limiting to depth 1:++ $ hledger balance -N -1+ $-1 assets+ $2 expenses+ $-2 income+ $1 liabilities++ You can also hide top-level account name parts, using --drop N. This+ can be useful for hiding repetitive top-level account names:++ $ hledger bal expenses --drop 1+ $1 food+ $1 supplies+ --------------------+ $2+++ Multi-period balance report+ With a report interval (set by the -D/--daily, -W/--weekly,+ -M/--monthly, -Q/--quarterly, -Y/--yearly, or -p/--period flag), bal-+ ance shows a tabular report, with columns representing successive time+ periods (and a title):++ $ hledger balance --quarterly income expenses -E+ Balance changes in 2008:++ || 2008q1 2008q2 2008q3 2008q4+ ===================++=================================+ expenses:food || 0 $1 0 0+ expenses:supplies || 0 $1 0 0+ income:gifts || 0 $-1 0 0+ income:salary || $-1 0 0 0+ -------------------++---------------------------------+ || $-1 $1 0 0++ Notes:++ o The report's start/end dates will be expanded, if necessary, to fully+ encompass the displayed subperiods (so that the first and last subpe-+ riods have the same duration as the others).++ o Leading and trailing periods (columns) containing all zeroes are not+ shown, unless -E/--empty is used.++ o Accounts (rows) containing all zeroes are not shown, unless+ -E/--empty is used.++ o Amounts with many commodities are shown in abbreviated form, unless+ --no-elide is used. (experimental)++ o Average and/or total columns can be added with the -A/--average and+ -T/--row-total flags.++ o The --transpose flag can be used to exchange rows and columns.++ o The --pivot FIELD option causes a different transaction field to be+ used as "account name". See PIVOTING.++ Multi-period reports with many periods can be too wide for easy viewing+ in the terminal. Here are some ways to handle that:++ o Hide the totals row with -N/--no-total++ o Convert to a single currency with -V++ o Maximize the terminal window++ o Reduce the terminal's font size++ 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+ 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 &&+ open a.html++ 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.++ Revenues and liability balances are typically negative, however, so -S+ shows these in reverse order. To work around this, you can add+ --invert to flip the signs. (Or, use one of the higher-level reports,+ which flip the sign automatically. Eg: hledger incomestatement -MAS).+++ Percentages+ With -%/--percent, balance reports show each account's value expressed+ as a percentage of the (column) total:++ $ hledger bal expenses -Q -%+ Balance changes in 2008:++ || 2008Q1 2008Q2 2008Q3 2008Q4+ ===================++=================================+ expenses:food || 0 50.0 % 0 0+ expenses:supplies || 0 50.0 % 0 0+ -------------------++---------------------------------+ || 0 100.0 % 0 0++ Note it is not useful to calculate percentages if the amounts in a col-+ umn have mixed signs. In this case, make a separate report for each+ sign, eg:++ $ hledger bal -% amt:`>0`+ $ hledger bal -% amt:`<0`++ Similarly, if the amounts in a column have mixed commodities, convert+ them to one commodity with -B, -V, -X or --value, or make a separate+ report for each commodity:++ $ hledger bal -% cur:\\$+ $ hledger bal -% cur:EUR++ Balance change, end balance+ 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+ account 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+ your timezone). It is the sum of previous 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!)++ In general, balance changes are what you want to see when reviewing+ revenues and expenses, and historical end balances are what you want to+ see when reviewing or reconciling asset, liability and equity accounts.++ 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+ journal covers the account's full lifetime.++ 2. Include all of of the account's prior postings in the report, by not+ specifying a report start date, or by using the -H/--historical+ flag. (-H causes report start date to be ignored when summing post-+ ings.)++ Balance report types+ For more flexible reporting, there are three important option groups:++ hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]+ ...++ The first two are the most important: calculation type selects the+ basic calculation to perform for each table cell, while accumulation+ type says which postings should be included in each cell's calculation.+ Typically one or both of these are selected by default, so you don't+ need to write them explicitly. A valuation type can be added if you+ want to convert the basic report to value or cost.++ Calculation type:+ The basic calculation to perform for each table cell. It is one of:++ o --sum : sum the posting amounts (default)++ o --budget : like --sum but also show a goal amount++ o --valuechange : show the change in period-end historical balance val-+ ues++ Accumulation type:+ Which postings should be included in each cell's calculation. It is+ one of:++ o --change : postings from column start to column end, ie within the+ cell's period. Typically used to see revenues/expenses. (default+ for balance, incomestatement)++ o --cumulative : postings from report start to column end, eg to show+ changes accumulated since the report's start date. Rarely used.++ o --historical/-H : postings from journal start to column end, ie all+ postings from account creation to the end of the cell's period. Typ-+ ically used to see historical end balances of assets/liabili-+ ties/equity. (default for balancesheet, balancesheetequity, cash-+ flow)++ Valuation type:+ Which kind of valuation, valuation date(s) and optionally a target val-+ uation commodity to use. It is one of:++ o no valuation, show amounts in their original commodities (default)++ o --value=cost[,COMM] : no valuation, show amounts converted to cost++ o --value=then[,COMM] : show value at transaction dates++ o --value=end[,COMM] : show value at period end date(s) (default with+ --valuechange)++ o --value=now[,COMM] : show value at today's date++ o --value=YYYY-MM-DD[,COMM] : show value at another date++ or one of their aliases: --cost/-B, --market/-V or --exchange/-X.++ 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-+ ancesheet/balancesheetequity commands++ o --cumulative or --historical disables --row-total/-T++ For reference, here is what the combinations of accumulation and valua-+ tion show:+++ Valua- no valuation --value= then --value= end --value= YYYY-+ tion: MM-DD /now+ >Accumu-+ lation:+ v+ ------------------------------------------------------------------------------------++++ --change change in period sum of posting- period-end DATE-value of+ date market val- value of change change in+ ues in period in period period+ --cumu- change from sum of posting- period-end DATE-value of+ lative report 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 end bal- start to period start to period to period end+ ance) end end++ Useful balance reports+ Some frequently used balance options/reports are:++ o bal -M revenues expenses+ 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+ available as the balancesheet command.++ o bal -M -H assets liabilities equity+ 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+ cashflow command.++ Also:++ o bal -M expenses -2 -SA+ Show monthly expenses summarised to depth 2 and sorted by average+ amount.++ o bal -M --budget expenses+ Show monthly expenses and budget goals.++ o bal -M --valuechange investments+ Show monthly change in market value of investment assets.++ o bal investments --valuechange -D date:lastweek amt:'>1000' -STA+ [--invert]+ Show top gainers [or losers] last week++ Budget report+ The --budget report type activates extra columns showing any budget+ goals for each account and period. The budget goals are defined by+ periodic transactions. This is very useful for comparing planned and+ actual income, expenses, time usage, etc.++ For example, you can take average monthly expenses in the common+ expense categories to construct a minimal monthly budget:++ ;; Budget+ ~ monthly+ income $2000+ expenses:food $400+ expenses:bus $50+ expenses:movies $30+ assets:bank:checking++ ;; Two months worth of expenses+ 2017-11-01+ income $1950+ expenses:food $396+ expenses:bus $49+ expenses:movies $30+ expenses:supplies $20+ assets:bank:checking++ 2017-12-01+ income $2100+ expenses:food $412+ expenses:bus $53+ expenses:gifts $100+ assets:bank:checking++ You can now see a monthly budget report:++ $ hledger balance -M --budget+ Budget performance in 2017/11/01-2017/12/31:++ || Nov Dec+ ======================++====================================================+ assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ expenses || $495 [ 103% of $480] $565 [ 118% of $480]+ expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]+ expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]+ expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]+ income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]+ ----------------------++----------------------------------------------------+ || 0 [ 0] 0 [ 0]++ This is different from a normal balance report in several ways:++ o Only accounts with budget goals during the report period are shown,+ by default.++ o In each column, in square brackets after the actual amount, budget+ goal amounts are shown, and the actual/goal percentage. (Note: bud-+ get goals should be in the same commodity as the actual amount.)++ o All parent accounts are always shown, even in list mode. Eg assets,+ assets:bank, and expenses above.++ o Amounts always include all subaccounts, budgeted or unbudgeted, even+ in list mode.++ This means that the numbers displayed will not always add up! Eg above,+ the expenses actual amount includes the gifts and supplies transac-+ tions, but the expenses:gifts and expenses:supplies accounts are not+ shown, as they have no budget amounts declared.++ This can be confusing. When you need to make things clearer, use the+ -E/--empty flag, which will reveal all accounts including unbudgeted+ ones, giving the full picture. Eg:++ $ hledger balance -M --budget --empty+ Budget performance in 2017/11/01-2017/12/31:++ || Nov Dec+ ======================++====================================================+ assets || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ assets:bank || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ assets:bank:checking || $-2445 [ 99% of $-2480] $-2665 [ 107% of $-2480]+ expenses || $495 [ 103% of $480] $565 [ 118% of $480]+ expenses:bus || $49 [ 98% of $50] $53 [ 106% of $50]+ expenses:food || $396 [ 99% of $400] $412 [ 103% of $400]+ expenses:gifts || 0 $100+ expenses:movies || $30 [ 100% of $30] 0 [ 0% of $30]+ expenses:supplies || $20 0+ income || $1950 [ 98% of $2000] $2100 [ 105% of $2000]+ ----------------------++----------------------------------------------------+ || 0 [ 0] 0 [ 0]++ You can roll over unspent budgets to next period with --cumulative:++ $ hledger balance -M --budget --cumulative+ Budget performance in 2017/11/01-2017/12/31:++ || Nov Dec+ ======================++====================================================+ assets || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]+ assets:bank || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]+ assets:bank:checking || $-2445 [ 99% of $-2480] $-5110 [ 103% of $-4960]+ expenses || $495 [ 103% of $480] $1060 [ 110% of $960]+ expenses:bus || $49 [ 98% of $50] $102 [ 102% of $100]+ expenses:food || $396 [ 99% of $400] $808 [ 101% of $800]+ expenses:movies || $30 [ 100% of $30] $30 [ 50% of $60]+ income || $1950 [ 98% of $2000] $4050 [ 101% of $4000]+ ----------------------++----------------------------------------------------+ || 0 [ 0] 0 [ 0]++ For more examples and notes, see Budgeting.++ Budget report start date+ This might be a bug, but for now: when making budget reports, it's a+ good idea to explicitly set the report's start date to the first day of+ a reporting period, because a periodic rule like ~ monthly generates+ its transactions on the 1st of each month, and if your journal has no+ regular transactions on the 1st, the default report start date could+ exclude that budget goal, which can be a little surprising. Eg here+ the default report period is just the day of 2020-01-15:++ ~ monthly in 2020+ (expenses:food) $500++ 2020-01-15+ expenses:food $400+ assets:checking++ $ hledger bal expenses --budget+ Budget performance in 2020-01-15:++ || 2020-01-15+ ==============++============+ <unbudgeted> || $400+ --------------++------------+ || $400++ To avoid this, specify the budget report's period, or at least the+ start date, with -b/-e/-p/date:, to ensure it includes the budget goal+ transactions (periodic transactions) that you want. Eg, adding -b+ 2020/1/1 to the above:++ $ hledger bal expenses --budget -b 2020/1/1+ Budget performance in 2020-01-01..2020-01-15:++ || 2020-01-01..2020-01-15+ ===============++========================+ expenses:food || $400 [80% of $500]+ ---------------++------------------------+ || $400 [80% of $500]++ Nested budgets+ You can add budgets to any account in your account hierarchy. If you+ have budgets on both parent account and some of its children, then bud-+ get(s) of the child account(s) would be added to the budget of their+ parent, much like account balances behave.++ In the most simple case this means that once you add a budget to any+ account, all its parents would have budget as well.++ To illustrate this, consider the following budget:++ ~ monthly from 2019/01+ expenses:personal $1,000.00+ expenses:personal:electronics $100.00+ liabilities++ With this, monthly budget for electronics is defined to be $100 and+ budget for personal expenses is an additional $1000, which implicitly+ means that budget for both expenses:personal and expenses is $1100.++ Transactions in expenses:personal:electronics will be counted both+ towards its $100 budget and $1100 of expenses:personal , and transac-+ tions in any other subaccount of expenses:personal would be counted+ towards only towards the budget of expenses:personal.++ For example, let's consider these transactions:++ ~ monthly from 2019/01+ expenses:personal $1,000.00+ expenses:personal:electronics $100.00+ liabilities++ 2019/01/01 Google home hub+ expenses:personal:electronics $90.00+ liabilities $-90.00++ 2019/01/02 Phone screen protector+ expenses:personal:electronics:upgrades $10.00+ liabilities++ 2019/01/02 Weekly train ticket+ expenses:personal:train tickets $153.00+ liabilities++ 2019/01/03 Flowers+ expenses:personal $30.00+ liabilities++ As you can see, we have transactions in expenses:personal:electron-+ ics:upgrades and expenses:personal:train tickets, and since both of+ these accounts are without explicitly defined budget, these transac-+ tions would be counted towards budgets of expenses:personal:electronics+ and expenses:personal accordingly:++ $ hledger balance --budget -M+ Budget performance in 2019/01:++ || Jan+ ===============================++===============================+ expenses || $283.00 [ 26% of $1100.00]+ expenses:personal || $283.00 [ 26% of $1100.00]+ expenses:personal:electronics || $100.00 [ 100% of $100.00]+ liabilities || $-283.00 [ 26% of $-1100.00]+ -------------------------------++-------------------------------+ || 0 [ 0]++ And with --empty, we can get a better picture of budget allocation and+ consumption:++ $ hledger balance --budget -M --empty+ Budget performance in 2019/01:++ || Jan+ ========================================++===============================+ expenses || $283.00 [ 26% of $1100.00]+ expenses:personal || $283.00 [ 26% of $1100.00]+ expenses:personal:electronics || $100.00 [ 100% of $100.00]+ expenses:personal:electronics:upgrades || $10.00+ expenses:personal:train tickets || $153.00+ liabilities || $-283.00 [ 26% of $-1100.00]+ ----------------------------------------++-------------------------------+ || 0 [ 0]++ Customising single-period balance reports+ For single-period balance reports displayed in the terminal (only), you+ can use --format FMT to customise the format and content of each line.+ Eg:++ $ hledger balance --format "%20(account) %12(total)"+ assets $-1+ bank:saving $1+ cash $-2+ expenses $2+ food $1+ supplies $1+ income $-2+ gifts $-1+ salary $-1+ liabilities:debts $1+ ---------------------------------+ 0++ The FMT format string (plus a newline) specifies the formatting applied+ to each account/balance pair. It may contain any suitable text, with+ data fields interpolated like so:++ %[MIN][.MAX](FIELDNAME)++ o MIN pads with spaces to at least this width (optional)++ o MAX truncates at this width (optional)++ o FIELDNAME must be enclosed in parentheses, and can be one of:++ o depth_spacer - a number of spaces equal to the account's depth, or+ if MIN is specified, MIN * depth spaces.++ o account - the account's name++ o total - the account's balance/posted total, right justified++ Also, FMT can begin with an optional prefix to control how multi-com-+ modity amounts are rendered:++ o %_ - render on multiple lines, bottom-aligned (the default)++ o %^ - render on multiple lines, top-aligned++ o %, - render on one line, comma-separated++ There are some quirks. Eg in one-line mode, %(depth_spacer) has no+ effect, instead %(account) has indentation built in. Experimentation+ may be needed to get pleasing results.++ Some example formats:++ o %(total) - the account's total++ o %-20.20(account) - the account's name, left justified, padded to 20+ characters and clipped at 20 characters++ o %,%-50(account) %25(total) - account name padded to 50 characters,+ total padded to 20 characters, with multiple commodities rendered on+ one line++ o %20(total) %2(depth_spacer)%-(account) - the default format for the+ single-column balance report++ balancesheet+ balancesheet, bs+ This command displays a balance sheet, showing historical ending bal-+ ances of asset and liability accounts. (To see equity as well, use the+ balancesheetequity command.) Amounts are shown with normal positive+ sign, as in conventional financial statements.++ The asset and liability accounts shown are those accounts declared with+ the Asset or Cash or Liability type, or otherwise all accounts under a+ top-level asset or liability account (case insensitive, plurals+ allowed).++ Example:++ $ hledger balancesheet+ Balance Sheet++ Assets:+ $-1 assets+ $1 bank:saving+ $-2 cash+ --------------------+ $-1++ Liabilities:+ $1 liabilities:debts+ --------------------+ $1++ Total:+ --------------------+ 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+ flipped.++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, html, and (experi-+ mental) json.++ balancesheetequity+ balancesheetequity, bse+ This command displays a balance sheet, showing historical ending bal-+ ances of asset, liability and equity accounts. Amounts are shown with+ normal positive sign, as in conventional financial statements.++ The asset, liability and equity accounts shown are those accounts+ declared with the Asset, Cash, Liability or Equity type, or otherwise+ all accounts under a top-level asset, liability or equity account (case+ insensitive, plurals allowed).++ Example:++ $ hledger balancesheetequity+ Balance Sheet With Equity++ Assets:+ $-2 assets+ $1 bank:saving+ $-3 cash+ --------------------+ $-2++ Liabilities:+ $1 liabilities:debts+ --------------------+ $1++ Equity:+ $1 equity:owner+ --------------------+ $1++ Total:+ --------------------+ 0++ This command 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 equity, but with+ smarter account detection, and liabilities/equity displayed with their+ sign flipped.++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, html, and (experi-+ mental) json.++ cashflow+ cashflow, cf+ This command displays a cashflow statement, showing the inflows and+ outflows affecting "cash" (ie, liquid) assets. Amounts are shown with+ normal positive sign, as in conventional financial statements.++ The "cash" accounts shown are those accounts declared with the Cash+ type, or otherwise all accounts under a top-level asset account (case+ insensitive, plural allowed) which do not have fixed, investment,+ receivable or A/R in their name.++ Example:++ $ hledger cashflow+ Cashflow Statement++ Cash flows:+ $-1 assets+ $1 bank:saving+ $-2 cash+ --------------------+ $-1++ Total:+ --------------------+ $-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+ not:receivable, but with smarter account detection.++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, html, and (experi-+ mental) json.++ check+ check+ Check for various kinds of errors in your data.++ hledger provides a number of built-in error checks to help prevent+ problems in your data. Some of these are run automatically; or, you+ can use this check command to run them on demand, with no output and a+ zero exit code if all is well. Specify their names (or a prefix) as+ argument(s).++ Some examples:++ hledger check # basic checks+ hledger check -s # basic + strict checks+ hledger check ordereddates payees # basic + two other checks++ Here are the checks currently available:++ Basic checks+ These checks are always run automatically, by (almost) all hledger com-+ mands, including check:++ 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 transaction prices or automatically-inferred transaction prices++ o assertions - all balance assertions in the journal are passing.+ (This check can be disabled with -I/--ignore-assertions.)++ Strict checks+ These additional checks are run when the -s/--strict (strict mode) flag+ is used. Or, they can be run by giving their names as arguments to+ check:++ o accounts - all account names used by transactions have been declared++ o commodities - all commodity symbols used have been declared++ o balancednoautoconversion - transactions are balanced, possibly using+ explicit transaction prices but not inferred ones++ 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,+ therefore optional:++ o ordereddates - transactions are ordered by date within each file++ o payees - all payees 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+ https://github.com/simonmichael/hledger/tree/master/bin:++ o hledger-check-tagfiles - all tag values containing / (a forward+ slash) exist as file paths++ o hledger-check-fancyassertions - more complex balance assertions are+ passing++ You could make similar scripts to perform your own custom checks. See:+ Cookbook -> Scripting.++ close+ close, equity+ Prints a "closing balances" transaction and an "opening balances"+ transaction that bring account balances to and from zero, respectively.+ These can be added to your journal file(s), eg to bring asset/liability+ balances forward into a new journal file, or to close out rev-+ enues/expenses to retained earnings at the end of a period.++ You can print just one of these transactions by using the --close or+ --open flag. You can customise their descriptions with the --close-+ desc and --open-desc options.++ One amountless posting to "equity:opening/closing balances" is added to+ balance the transactions, by default. You can customise this account+ name with --close-acct and --open-acct; if you specify only one of+ these, it will be used for both.++ With --x/--explicit, the equity posting's amount will be shown. And if+ it involves multiple commodities, a posting for each commodity will be+ shown, as with the print command.++ With --interleaved, the equity postings are shown next to the postings+ they balance, which makes troubleshooting easier.++ By default, transaction prices in the journal are ignored when generat-+ ing the closing/opening transactions. With --show-costs, this cost+ information is preserved (balance -B reports will be unchanged after+ the transition). Separate postings are generated for each cost in each+ commodity. Note this can generate very large journal entries, if you+ have many foreign currency or investment transactions.++ close usage+ If you split your journal files by time (eg yearly), you will typically+ run this command at the end of the year, and save the closing transac-+ tion as last entry of the old file, and the opening transaction as the+ first entry of the new file. This makes the files self contained, so+ that correct balances are reported no matter which of them are loaded.+ Ie, if you load just one file, the balances are initialised correctly;+ or if you load several files, the redundant closing/opening transac-+ tions cancel each other out. (They will show up in print or register+ reports; you can exclude them with a query like not:desc:'(open-+ ing|closing) balances'.)++ If you're running a business, you might also use this command to "close+ the books" at the end of an accounting period, transferring income+ statement account balances to retained earnings. (You may want to+ change the equity account name to something like "equity:retained earn-+ ings".)++ By default, the closing transaction is dated yesterday, the balances+ are calculated as of end of yesterday, and the opening transaction is+ dated today. To close on some other date, use: hledger close -e OPEN-+ INGDATE. Eg, to close/open on the 2018/2019 boundary, use -e 2019.+ You can also use -p or date:PERIOD (any starting date is ignored).++ Both transactions will include balance assertions for the+ closed/reopened accounts. You probably shouldn't use status or real-+ ness filters (like -C or -R or status:) with this command, or the gen-+ erated balance assertions will depend on these flags. Likewise, if you+ run this command with --auto, the balance assertions will probably+ always require --auto.++ Examples:++ Carrying asset/liability balances into a new file for 2019:++ $ hledger close -f 2018.journal -e 2019 assets liabilities --open+ # (copy/paste the output to the start of your 2019 journal file)+ $ hledger close -f 2018.journal -e 2019 assets liabilities --close+ # (copy/paste the output to the end of your 2018 journal file)++ Now:++ $ hledger bs -f 2019.journal # one file - balances are correct+ $ hledger bs -f 2018.journal -f 2019.journal # two files - balances still correct+ $ hledger bs -f 2018.journal not:desc:closing # to see year-end balances, must exclude closing txn++ Transactions spanning the closing date can complicate matters, breaking+ balance assertions:++ 2018/12/30 a purchase made in 2018, clearing the following year+ expenses:food 5+ assets:bank:checking -5 ; [2019/1/2]++ Here's one way to resolve that:++ ; in 2018.journal:+ 2018/12/30 a purchase made in 2018, clearing the following year+ expenses:food 5+ liabilities:pending++ ; in 2019.journal:+ 2019/1/2 clearance of last year's pending transactions+ liabilities:pending 5 = 0+ assets:checking++ codes+ codes+ List the codes seen in transactions, in the order parsed.++ This command prints the value of each transaction's code field, in the+ order transactions were parsed. The transaction code is an optional+ value written in parentheses between the date and description, often+ used to store a cheque number, order number or similar.++ Transactions aren't required to have a code, and missing or empty codes+ will not be shown by default. With the -E/--empty flag, they will be+ printed as blank lines.++ You can add a query to select a subset of transactions.++ Examples:++ 1/1 (123)+ (a) 1++ 1/1 ()+ (a) 1++ 1/1+ (a) 1++ 1/1 (126)+ (a) 1++ $ hledger codes+ 123+ 124+ 126++ $ hledger codes -E+ 123+ 124+++ 126++ commodities+ commodities+ List all commodity/currency symbols used or declared in the journal.++ descriptions+ descriptions+ List the unique descriptions that appear in transactions.++ This command lists the unique descriptions that appear in transactions,+ in alphabetic order. You can add a query to select a subset of trans-+ actions.++ Example:++ $ hledger descriptions+ Store Name+ Gas Station | Petrol+ Person A++ diff+ diff+ Compares a particular account's transactions in two input files. It+ shows any transactions to this account which are in one file but not in+ the other.++ More precisely, for each posting affecting this account in either file,+ it looks for a corresponding posting in the other file which posts the+ same amount to the same account (ignoring date, description, etc.)+ Since postings not transactions are compared, this also works when mul-+ tiple bank transactions have been combined into a single journal entry.++ This is useful eg if you have downloaded an account's transactions from+ your bank (eg as CSV data). When hledger and your bank disagree about+ the account balance, you can compare the bank data with your journal to+ find out the cause.++ Examples:++ $ hledger diff -f $LEDGER_FILE -f bank.csv assets:bank:giro+ These transactions are in the first file only:++ 2014/01/01 Opening Balances+ assets:bank:giro EUR ...+ ...+ equity:opening balances EUR -...++ These transactions are in the second file only:++ files+ files+ List all files included in the journal. With a REGEX argument, only+ file names matching the regular expression (case sensitive) are shown.++ help+ help+ Show the hledger user manual in one of several formats, optionally+ positioned at a given TOPIC (if possible). TOPIC is any heading, or+ heading prefix, in the manual. Some examples: commands, print, 'auto+ postings', periodic.++ This command shows the user manual built in to this hledger version.+ It can be useful if the correct version of the hledger manual, or the+ usual viewing tools, are not installed on your system.++ By default it uses the best viewer it can find in $PATH, in this order:+ info, man, $PAGER (unless a topic is specified), less, or stdout. When+ run non-interactively, it always uses stdout. Or you can select a par-+ ticular viewer with the -i (info), -m (man), or -p (pager) flags.++ import+ import+ Read new transactions added to each FILE since last run, and add them+ to the main journal file. Or with --dry-run, just print the transac-+ tions that would be added. Or with --catchup, just mark all of the+ FILEs' transactions as imported, without actually importing any.++ 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+ hledger import bank.csv or perhaps hledger import *.csv.++ Note you can import from any file format, though CSV files are the most+ common import source, and these docs focus on that case.++ Deduplication+ 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+ already-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-+ potent.)++ Since the items being read (CSV records, eg) often do not come with+ unique identifiers, hledger detects new transactions by date, assuming+ that:++ 1. new items always have the newest dates++ 2. item dates do not change across reads++ 3. and items with the same date remain in the same relative order+ across reads.++ 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+ be the ones affected).++ 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+ 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-+ tain date.++ Note deduplication (and updating of state files) can also be done by+ print --new, but this is less often used.++ Import testing+ 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+ categorised:++ $ hledger import --dry bank.csv | hledger -f- -I print unknown++ or (live updating):++ $ ls bank.csv* | entr bash -c 'echo ====; hledger import --dry bank.csv | hledger -f- -I print unknown'++ Importing balance assignments+ Entries added by import will have their posting amounts made explicit+ (like hledger print -x). This means that any balance assignments in+ imported files must be evaluated; but, imported files don't get to see+ the main file's account balances. As a result, importing entries with+ balance assignments (eg from an institution that provides only balances+ and not posting amounts) will probably generate incorrect posting+ amounts. To avoid this problem, use print instead of import:++ $ hledger print IMPORTFILE [--new] >> $LEDGER_FILE++ (If you think import should leave amounts implicit like print does,+ please test it and send a pull request.)++ Commodity display styles+ Imported amounts will be formatted according to the canonical commodity+ styles (declared or inferred) in the main journal file.++ incomestatement+ incomestatement, is++ This command displays an income statement, showing revenues and+ expenses during one or more periods. Amounts are shown with normal+ positive sign, as in conventional financial statements.++ The revenue and expense accounts shown are those accounts declared with+ the Revenue or Expense type, or otherwise all accounts under a top-+ level revenue or income or expense account (case insensitive, plurals+ allowed).++ Example:++ $ hledger incomestatement+ Income Statement++ Revenues:+ $-2 income+ $-1 gifts+ $-1 salary+ --------------------+ $-2++ Expenses:+ $2 expenses+ $1 food+ $1 supplies+ --------------------+ $2++ Total:+ --------------------+ 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 '(revenues|income)' expenses, but with+ smarter account detection, and revenues/income displayed with their+ sign flipped.++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, html, and (experi-+ mental) json.++ notes+ notes+ List the unique notes that appear in transactions.++ This command lists the unique notes that appear in transactions, in+ alphabetic order. You can add a query to select a subset of transac-+ tions. The note is the part of the transaction description after a |+ character (or if there is no |, the whole description).++ Example:++ $ hledger notes+ Petrol+ Snacks++ payees+ payees+ List the unique payee/payer names that appear in transactions.++ This command lists 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 |+ character (or if there is no |, the whole description).++ You can add query arguments to select a subset of transactions. This+ implies --used.++ Example:++ $ hledger payees+ Store Name+ Gas Station+ Person A++ prices+ prices+ Print market price directives from the journal. With --costs, also+ print synthetic market prices based on transaction prices. With+ --inverted-costs, also print inverse prices based on transaction+ prices. Prices (and postings providing prices) can be filtered by a+ query. Price amounts are always displayed with their full precision.++ print+ print+ Show transaction journal entries, sorted by date.++ The print command displays full journal entries (transactions) from the+ journal file, sorted by date (or with --date2, by secondary date).++ Amounts are shown 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.+ This means the print command is somewhat lossy, and if you are using it+ to reformat your journal you should take care to also copy over the+ directives and file-level comments.++ Eg:++ $ hledger print+ 2008/01/01 income+ assets:bank:checking $1+ income:salary $-1++ 2008/06/01 gift+ assets:bank:checking $1+ income:gifts $-1++ 2008/06/02 save+ assets:bank:saving $1+ assets:bank:checking $-1++ 2008/06/03 * eat & shop+ expenses:food $1+ expenses:supplies $1+ assets:cash $-2++ 2008/12/31 * pay off+ liabilities:debts $1+ assets:bank:checking $-1++ print's output is usually a valid hledger journal, and you can process+ it again with a second hledger command. This can be useful for certain+ kinds of search, eg:++ # Show running total of food expenses paid from cash.+ # -f- reads from stdin. -I/--ignore-assertions is sometimes needed.+ $ hledger print assets:cash | hledger -f- -I reg expenses:food++ There are some situations where print's output can become unparseable:++ o Valuation affects posting amounts but not balance assertion or bal-+ ance assignment amounts, potentially causing those to fail.++ o Auto postings can generate postings with too many missing amounts.++ Normally, the journal entry's explicit or implicit amount style is pre-+ served. For example, when an amount is omitted in the journal, it will+ not appear in the output. Similarly, when a transaction price is+ implied but not written, it will not appear in the output. You can use+ the -x/--explicit flag to make all amounts and transaction prices+ explicit, which can be useful for troubleshooting or for making your+ journal more readable and robust against data entry errors. -x is also+ implied by using any of -B,-V,-X,--value.++ Note, -x/--explicit will cause postings with a multi-commodity amount+ (these can arise when a multi-commodity transaction has an implicit+ amount) to be split into multiple single-commodity postings, keeping+ the output parseable.++ With -B/--cost, amounts with transaction prices are converted to cost+ using that price. This can be used for troubleshooting.++ With -m/--match and a STR argument, print will show at most one trans-+ action: the one one whose description is most similar to STR, and is+ most recent. STR should contain at least two characters. If there is+ no similar-enough match, no transaction will be shown.++ With --new, hledger prints only transactions it has not seen on a pre-+ vious run. This uses the same deduplication system as the import com-+ mand. (See import's docs for details.)++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, and (experimental)+ json and sql.++ Here's an example of print's CSV output:++ $ hledger print -Ocsv+ "txnidx","date","date2","status","code","description","comment","account","amount","commodity","credit","debit","posting-status","posting-comment"+ "1","2008/01/01","","","","income","","assets:bank:checking","1","$","","1","",""+ "1","2008/01/01","","","","income","","income:salary","-1","$","1","","",""+ "2","2008/06/01","","","","gift","","assets:bank:checking","1","$","","1","",""+ "2","2008/06/01","","","","gift","","income:gifts","-1","$","1","","",""+ "3","2008/06/02","","","","save","","assets:bank:saving","1","$","","1","",""+ "3","2008/06/02","","","","save","","assets:bank:checking","-1","$","1","","",""+ "4","2008/06/03","","*","","eat & shop","","expenses:food","1","$","","1","",""+ "4","2008/06/03","","*","","eat & shop","","expenses:supplies","1","$","","1","",""+ "4","2008/06/03","","*","","eat & shop","","assets:cash","-2","$","2","","",""+ "5","2008/12/31","","*","","pay off","","liabilities:debts","1","$","","1","",""+ "5","2008/12/31","","*","","pay off","","assets:bank:checking","-1","$","1","","",""++ o There is one CSV record per posting, with the parent transaction's+ fields repeated.++ o The "txnidx" (transaction index) field shows which postings belong to+ the same transaction. (This number might change if transactions are+ reordered within the file, files are parsed/included in a different+ order, etc.)++ o The amount is separated into "commodity" (the symbol) and "amount"+ (numeric quantity) fields.++ o The numeric amount is repeated in either the "credit" or "debit" col-+ umn, for convenience. (Those names are not accurate in the account-+ ing sense; it just puts negative amounts under credit and zero or+ greater amounts under debit.)++ print-unique+ print-unique+ Print transactions which do not reuse an already-seen description.++ Example:++ $ cat unique.journal+ 1/1 test+ (acct:one) 1+ 2/2 test+ (acct:two) 2+ $ LEDGER_FILE=unique.journal hledger print-unique+ (-f option not supported)+ 2015/01/01 test+ (acct:one) 1++ register+ register, reg+ Show postings and their running total.++ The register command displays matched postings, across all accounts, in+ date order, with their running total or running historical balance.+ (See also the aregister command, which shows matched transactions in a+ specific account.)++ register normally shows line per posting, but note that multi-commodity+ amounts will occupy multiple lines (one line per commodity).++ It is typically used with a query selecting a particular account, to+ see that account's activity:++ $ hledger register checking+ 2008/01/01 income assets:bank:checking $1 $1+ 2008/06/01 gift assets:bank:checking $1 $2+ 2008/06/02 save assets:bank:checking $-1 $1+ 2008/12/31 pay off assets:bank:checking $-1 0++ With --date2, it shows and sorts by secondary date instead.++ The --historical/-H flag adds the balance from any undisplayed prior+ postings to the running total. This is useful when you want to see+ only recent activity, with a historically accurate running balance:++ $ hledger register checking -b 2008/6 --historical+ 2008/06/01 gift assets:bank:checking $1 $2+ 2008/06/02 save assets:bank:checking $-1 $1+ 2008/12/31 pay off assets:bank:checking $-1 0++ The --depth option limits the amount of sub-account detail displayed.++ The --average/-A flag shows the running average posting amount instead+ of the running total (so, the final number displayed is the average for+ the whole report period). This flag implies --empty (see below). It+ is affected by --historical. It works best when showing just one+ account and one commodity.++ The --related/-r flag shows the other postings in the transactions of+ the postings which would normally be shown.++ The --invert flag negates all amounts. For example, it can be used on+ an income account where amounts are normally displayed as negative num-+ bers. It's also useful to show postings on the checking account+ together with the related account:++ $ hledger register --related --invert assets:checking++ With a reporting interval, register shows summary postings, one per+ interval, aggregating the postings to each account:++ $ hledger register --monthly income+ 2008/01 income:salary $-1 $-1+ 2008/06 income:gifts $-1 $-2++ Periods with no activity, and summary postings with a zero amount, are+ not shown by default; use the --empty/-E flag to see them:++ $ hledger register --monthly income -E+ 2008/01 income:salary $-1 $-1+ 2008/02 0 $-1+ 2008/03 0 $-1+ 2008/04 0 $-1+ 2008/05 0 $-1+ 2008/06 income:gifts $-1 $-2+ 2008/07 0 $-2+ 2008/08 0 $-2+ 2008/09 0 $-2+ 2008/10 0 $-2+ 2008/11 0 $-2+ 2008/12 0 $-2++ Often, you'll want to see just one line per interval. The --depth+ option helps with this, causing subaccounts to be aggregated:++ $ hledger register --monthly assets --depth 1h+ 2008/01 assets $1 $1+ 2008/06 assets $-1 0+ 2008/12 assets $-1 $-1++ Note when using report intervals, if you specify start/end dates these+ will be adjusted outward if necessary to contain a whole number of+ intervals. This ensures that the first and last intervals are full+ length and comparable to the others in the report.++ Custom register output+ register uses the full terminal width by default, except on windows.+ You can override this by setting the COLUMNS environment variable (not+ a bash shell variable) or by using the --width/-w option.++ The description and account columns normally share the space equally+ (about half of (width - 40) each). You can adjust this by adding a+ description width as part of --width's argument, comma-separated:+ --width W,D . Here's a diagram (won't display correctly in --help):++ <--------------------------------- width (W) ---------------------------------->+ date (10) description (D) account (W-41-D) amount (12) balance (12)+ DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA++ and some examples:++ $ hledger reg # use terminal width (or 80 on windows)+ $ hledger reg -w 100 # use width 100+ $ COLUMNS=100 hledger reg # set with one-time environment variable+ $ export COLUMNS=100; hledger reg # set till session end (or window resize)+ $ hledger reg -w 100,40 # set overall width 100, description width 40+ $ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40++ This command also supports the output destination and output format+ options The output formats supported are txt, csv, and (experimental)+ json.++ register-match+ register-match+ Print the one posting whose transaction description is closest to DESC,+ in the style of the register command. If there are multiple equally+ good matches, it shows the most recent. Query options (options, not+ arguments) can be used to restrict the search space. Helps ledger-+ autosync detect already-seen transactions when importing.++ rewrite+ rewrite+ Print all transactions, rewriting the postings of matched transactions.+ For now the only rewrite available is adding new postings, like print+ --auto.++ This is a start at a generic rewriter of transaction entries. It reads+ the default journal and prints the transactions, like print, but adds+ one or more specified postings to any transactions matching QUERY. The+ posting amounts can be fixed, or a multiplier of the existing transac-+ tion's first posting amount.++ Examples:++ $ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'+ $ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'+ $ hledger-rewrite.hs -f rewrites.hledger++ rewrites.hledger may consist of entries like:++ = ^income amt:<0 date:2017+ (liabilities:tax) *0.33 ; tax on income+ (reserve:grocery) *0.25 ; reserve 25% for grocery+ (reserve:) *0.25 ; reserve 25% for grocery++ Note the single quotes to protect the dollar sign from bash, and the+ two spaces between account and amount.++ More:++ $ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...+ $ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'+ $ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'+ $ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'++ Argument for --add-posting option is a usual posting of transaction+ with an exception for amount specification. More precisely, you can+ use '*' (star symbol) before the amount to indicate that that this is a+ factor for an amount of original matched posting. If the amount+ includes a commodity name, the new posting amount will be in the new+ commodity; otherwise, it will be in the matched posting amount's com-+ modity.++ Re-write rules in a file+ During the run this tool will execute so called "Automated Transac-+ tions" found in any journal it process. I.e instead of specifying this+ operations in command line you can put them in a journal file.++ $ rewrite-rules.journal++ Make contents look like this:++ = ^income+ (liabilities:tax) *.33++ = expenses:gifts+ budget:gifts *-1+ assets:budget *1++ Note that '=' (equality symbol) that is used instead of date in trans-+ actions you usually write. It indicates the query by which you want to+ match the posting to add new ones.++ $ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal++ This is something similar to the commands pipeline:++ $ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \+ | hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \+ --add-posting 'assets:budget *1' \+ > rewritten-tidy-output.journal++ It is important to understand that relative order of such entries in+ journal is important. You can re-use result of previously added post-+ ings.++ Diff output format+ To use this tool for batch modification of your journal files you may+ find useful output in form of unified diff.++ $ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'++ Output might look like:++ --- /tmp/examples/sample.journal+ +++ /tmp/examples/sample.journal+ @@ -18,3 +18,4 @@+ 2008/01/01 income+ - assets:bank:checking $1+ + assets:bank:checking $1+ income:salary+ + (liabilities:tax) 0+ @@ -22,3 +23,4 @@+ 2008/06/01 gift+ - assets:bank:checking $1+ + assets:bank:checking $1+ income:gifts+ + (liabilities:tax) 0++ If you'll pass this through patch tool you'll get transactions contain-+ ing the posting that matches your query be updated. Note that multiple+ files might be update according to list of input files specified via+ --file options and include directives inside of these files.++ Be careful. Whole transaction being re-formatted in a style of output+ from hledger print.++ See also:++ https://github.com/simonmichael/hledger/issues/99++ rewrite vs. print --auto+ This command predates print --auto, and currently does much the same+ thing, but with these differences:++ o with multiple files, rewrite lets rules in any file affect all other+ files. print --auto uses standard directive scoping; rules affect+ only child files.++ o rewrite's query limits which transactions can be rewritten; all are+ printed. print --auto's query limits which transactions are printed.++ o rewrite applies rules specified on command line or in the journal.+ print --auto applies rules specified in the journal.++ roi+ roi+ Shows the time-weighted (TWR) and money-weighted (IRR) rate of return+ on your investments.++ At a minimum, you need to supply a query (which could be just an+ account name) to select your investment(s) with --inv, and another+ query to identify your profit and loss transactions with --pnl.++ If you do not record changes in the value of your investment manually,+ or do not require computation of time-weighted return (TWR), --pnl+ 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+ display, regardless of the length of reporting interval.++ 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+ becomes negative at some point in time.++ o Error (SearchFailed): Failed to find solution for Internal Rate of+ Return (IRR). Either search does not converge to a solution, or con-+ verges too slowly.++ Examples:++ o Using roi to compute total return of investment in stocks:+ https://github.com/simonmichael/hledger/blob/master/examples/roi-+ unrealised.ledger++ o Cookbook -> Return on Investment++ Spaces and special characters in --inv and --pnl+ Note that --inv and --pnl's argument is a query, and queries could have+ several space-separated terms (see QUERIES).++ To indicate that all search terms form single command-line argument,+ you will need to put them in quotes (see Special characters):++ $ hledger roi --inv 'term1 term2 term3 ...'++ If any query terms contain spaces themselves, you will need an extra+ level of nested quoting, eg:++ $ hledger roi --inv="'Assets:Test 1'" --pnl="'Equity:Unrealized Profit and Loss'"++ Semantics of --inv and --pnl+ Query supplied to --inv has to match all transactions that are related+ 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+ and which is due to the return on investment.++ o "Cash flow" is depositing or withdrawing money, buying or selling+ assets, or otherwise converting between your investment commodity and+ any other commodity. Example:++ 2019-01-01 Investing in Snake Oil+ assets:cash -$100+ investment:snake oil++ 2020-01-01 Selling my Snake Oil+ assets:cash $10+ investment:snake oil = 0++ o "Profit and loss" is change in the value of your investment:++ 2019-06-01 Snake Oil falls in value+ investment:snake oil = $57+ equity:unrealized profit or loss++ All non-investment postings are assumed to be "cash flow", unless they+ match --pnl query. Changes in value of your investment due to "profit+ and loss" postings will be considered as part of your investment+ return.++ Example: if you use --inv snake --pnl equity:unrealized, then postings+ in the example below would be classifed as:++ 2019-01-01 Snake Oil #1+ assets:cash -$100 ; cash flow posting+ investment:snake oil ; investment posting++ 2019-03-01 Snake Oil #2+ equity:unrealized pnl -$100 ; profit and loss posting+ snake oil ; investment posting++ 2019-07-01 Snake Oil #3+ equity:unrealized pnl ; profit and loss posting+ cash -$100 ; cash flow posting+ snake oil $50 ; investment posting++ IRR and TWR explained+ "ROI" stands for "return on investment". Traditionally this was com-+ puted as a difference between current value of investment and its ini-+ tial value, expressed in percentage of the initial value.++ However, this approach is only practical in simple cases, where invest-+ ments receives no in-flows or out-flows of money, and where rate of+ growth is fixed over time. For more complex scenarios you need differ-+ ent ways to compute rate of return, and this command implements two of+ them: IRR and TWR.++ Internal rate of return, or "IRR" (also called "money-weighted rate of+ return") takes into account effects of in-flows and out-flows.+ Naively, if you are withdrawing from your investment, your future gains+ would be smaller (in absolute numbers), and will be a smaller percent-+ age of your initial investment, and if you are adding to your invest-+ ment, you will receive bigger absolute gains (but probably at the same+ rate of return). IRR is a way to compute rate of return for each+ period between in-flow or out-flow of money, and then combine them in a+ way that gives you a compound annual rate of return that investment is+ expected to generate.++ 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.++ If you manually record changes in the value of your investment as+ transactions that balance them against "profit and loss" (or "unreal-+ ized gains") account or use price directives, then in order for IRR to+ compute the precise effect of your in-flows and out-flows on the rate+ of return, you will need to record the value of your investement on or+ close to the days when in- or out-flows occur.++ In technical terms, IRR uses the same approach as computation of net+ present value, and tries to find a discount rate that makes net present+ value of all the cash flows of your investment to add up to zero. This+ could be hard to wrap your head around, especially if you haven't done+ discounted cash flow analysis before. 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+ 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+ and then a compound rate of return. However, internal workings of TWR+ are quite different.++ TWR represents your investment as an imaginary "unit fund" where in-+ flows/ out-flows lead to buying or selling "units" of your investment+ and changes in its value change the value of "investment unit". Change+ in "unit price" over the reporting period gives you rate of return of+ your investment.++ References: * Explanation of rate of return * Explanation of IRR *+ Explanation of TWR * Examples of computing IRR and TWR and discussion+ of the limitations of both metrics++ stats+ stats+ Show some journal statistics.++ The stats command displays summary information for the whole journal,+ or a matched part of it. With a reporting interval, it shows a report+ for each report period.++ Example:++ $ hledger stats+ Main journal file : /src/hledger/examples/sample.journal+ Included journal files :+ Transactions span : 2008-01-01 to 2009-01-01 (366 days)+ Last transaction : 2008-12-31 (2333 days ago)+ Transactions : 5 (0.0 per day)+ Transactions last 30 days: 0 (0.0 per day)+ Transactions last 7 days : 0 (0.0 per day)+ Payees/descriptions : 5+ Accounts : 8 (depth 3)+ Commodities : 1 ($)+ Market prices : 12 ($)++ This command also supports output destination and output format selec-+ tion.++ tags+ tags+ List the unique tag names used in the journal. With a TAGREGEX argu-+ ment, only tag names matching the regular expression (case insensitive)+ are shown. With QUERY arguments, only transactions matching the query+ are considered.++ With the --values flag, the tags' unique values are listed instead.++ With --parsed flag, all tags or values are shown in the order they are+ parsed from the input data, including duplicates.++ With -E/--empty, any blank/empty values will also be shown, otherwise+ they are omitted.++ test+ test+ Run built-in unit tests.++ This command runs the unit tests built in to hledger and hledger-lib,+ printing the results on stdout. If any test fails, the exit code will+ be non-zero.++ This is mainly used by hledger developers, but you can also use it to+ sanity-check the installed hledger executable on your platform. All+ tests are expected to pass - if you ever see a failure, please report+ as a bug!++ This command also accepts tasty test runner options, written after a --+ (double hyphen). Eg to run only the tests in Hledger.Data.Amount, with+ ANSI colour codes disabled:++ $ hledger test -- -pData.Amount --color=never++ For help on these, see https://github.com/feuerbach/tasty#options (--+ --help currently doesn't show them).++ About add-on commands+ Add-on commands are programs or scripts in your PATH++ o whose name starts with hledger-++ o whose name ends with a recognised file extension: .bat,.com,.exe,+ .hs,.lhs,.pl,.py,.rb,.rkt,.sh or none++ o and (on unix, mac) which are executable by the current user.++ Add-ons are a relatively easy way to add local features or experiment+ with new ideas. They can be written in any language, but haskell+ scripts have a big advantage: they can use the same hledger library+ functions that built-in commands use for command-line options, parsing+ and reporting. Some experimental/example add-on scripts can be found+ in the hledger repo's bin/ directory.++ Note in a hledger command line, add-on command flags must have a double+ dash (--) preceding them. Eg you must write:++ $ hledger web -- --serve++ and not:++ $ hledger web --serve++ (because the --serve flag belongs to hledger-web, not hledger).++ The -h/--help and --version flags don't require --.++ If you have any trouble with this, remember you can always run the add-+ on program directly, eg:++ $ hledger-web --serve++JOURNAL FORMAT+ hledger's default file format, representing a General Journal.++ hledger's usual data source is a plain text file containing journal+ entries in hledger journal format. This file represents a standard+ accounting general journal. I use file names ending in .journal, but+ that's not required. The journal file contains a number of transaction+ entries, each describing a transfer of money (or any commodity) between+ two or more named accounts, in a simple format readable by both hledger+ and humans.++ hledger's journal format is a compatible subset, mostly, of ledger's+ journal format, so hledger can work with compatible ledger journal+ files as well. It's safe, and encouraged, to run both hledger and+ ledger on the same journal file, eg to validate the results you're get-+ ting.++ You can use hledger without learning any more about this file; just use+ the add or web or import commands to create and update it.++ Many users, though, edit the journal file with a text editor, and track+ changes with a version control system such as git. Editor addons such+ as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and+ hledger-vscode for Visual Studio Code, make this easier, adding colour,+ formatting, tab completion, and useful commands. See Editor configura-+ tion at hledger.org for the full list.++ Here's a description of each part of the file format (and hledger's+ data model). These are mostly in the order you'll use them, but in+ some cases related concepts have been grouped together for easy refer-+ ence, or linked before they are introduced, so feel free to skip over+ anything that looks unnecessary right now.++ Transactions+ Transactions are the main unit of information in a journal file. They+ represent events, typically a movement of some quantity of commodities+ between two or more named accounts.++ Each transaction is recorded as a journal entry, beginning with a sim-+ ple date in column 0. This can be followed by any of the following+ optional fields, separated by spaces:++ o a status character (empty, !, or *)++ o a code (any short number or text, enclosed in parentheses)++ o a description (any remaining text until end of line or a semicolon)++ o a comment (any remaining text following a semicolon until end of+ line, and any following indented lines beginning with a semicolon)++ o 0 or more indented posting lines, describing what was transferred and+ the accounts involved (indented comment lines are also allowed, but+ not blank lines or non-indented lines).++ Here's a simple journal file containing one transaction:++ 2008/01/01 income+ assets:bank:checking $1+ income:salary $-1++ Dates+ Simple dates+ Dates in the journal file use simple dates format: YYYY-MM-DD or+ YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be+ omitted, in which case it will be inferred from the context: the cur-+ rent transaction, the default year set with a default year directive,+ or the current date when the command is run. Some examples:+ 2010-01-31, 2010/01/31, 2010.1.31, 1/31.++ (The UI also accepts simple dates, as well as the more flexible smart+ dates documented in the hledger manual.)++ Secondary dates+ Real-life transactions sometimes involve more than one date - eg the+ date you write a cheque, and the date it clears in your bank. When you+ want to model this, for more accurate daily balances, you can specify+ individual posting dates.++ Or, you can use the older secondary date feature (Ledger calls it aux-+ iliary date or effective date). Note: we support this for compatibil-+ ity, but I usually recommend avoiding this feature; posting dates are+ almost always clearer and simpler.++ A secondary date is written after the primary date, following an equals+ sign. If the year is omitted, the primary date's year is assumed.+ When running reports, the primary (left) date is used by default, but+ with the --date2 flag (or --aux-date or --effective), the secondary+ (right) date will be used instead.++ The meaning of secondary dates is up to you, but it's best to follow a+ consistent rule. Eg "primary = the bank's clearing date, secondary =+ date the transaction was initiated, if different", as shown here:++ 2010/2/23=2/19 movie ticket+ expenses:cinema $10+ assets:checking++ $ hledger register checking+ 2010-02-23 movie ticket assets:checking $-10 $-10++ $ hledger register checking --date2+ 2010-02-19 movie ticket assets:checking $-10 $-10++ Posting dates+ You can give individual postings a different date from their parent+ transaction, by adding a posting comment containing a tag (see below)+ like date:DATE. This is probably the best way to control posting dates+ precisely. Eg in this example the expense should appear in May+ reports, and the deduction from checking should be reported on 6/1 for+ easy bank reconciliation:++ 2015/5/30+ expenses:food $10 ; food purchased on saturday 5/30+ assets:checking ; bank cleared it on monday, date:6/1++ $ hledger -f t.j register food+ 2015-05-30 expenses:food $10 $10++ $ hledger -f t.j register checking+ 2015-06-01 assets:checking $-10 $-10++ DATE should be a simple date; if the year is not specified it will use+ the year of the transaction's date. You can set the secondary date+ similarly, with date2:DATE2. The date: or date2: tags must have a+ valid simple date value if they are present, eg a date: tag with no+ value is not allowed.++ Ledger's earlier, more compact bracketed date syntax is also supported:+ [DATE], [DATE=DATE2] or [=DATE2]. hledger will attempt to parse any+ square-bracketed sequence of the 0123456789/-.= characters in this way.+ With this syntax, DATE infers its year from the transaction and DATE2+ infers its year from DATE.++ Status+ Transactions, or individual postings within a transaction, can have a+ status mark, which is a single character before the transaction+ description or posting account name, separated from it by a space,+ indicating one of three statuses:+++ mark status+ ------------------+ unmarked+ ! pending+ * cleared++ When reporting, you can filter by status with the -U/--unmarked,+ -P/--pending, and -C/--cleared flags; or the status:, status:!, and+ status:* queries; or the U, P, C keys in hledger-ui.++ Note, in Ledger and in older versions of hledger, the "unmarked" state+ is called "uncleared". As of hledger 1.3 we have renamed it to+ unmarked for clarity.++ To replicate Ledger and old hledger's behaviour of also matching pend-+ ing, combine -U and -P.++ Status marks are optional, but can be helpful eg for reconciling with+ real-world accounts. Some editor modes provide highlighting and short-+ cuts for working with status. Eg in Emacs ledger-mode, you can toggle+ transaction status with C-c C-e, or posting status with C-c C-c.++ What "uncleared", "pending", and "cleared" actually mean is up to you.+ Here's one suggestion:+++ status meaning+ --------------------------------------------------------------------------+ uncleared recorded but not yet reconciled; needs review+ pending tentatively reconciled (if needed, eg during a big reconcil-+ iation)+ cleared complete, reconciled as far as possible, and considered cor-+ rect++ With this scheme, you would use -PC to see the current balance at your+ bank, -U to see things which will probably hit your bank soon (like+ uncashed checks), and no flags to see the most up-to-date state of your+ finances.++ Code+ After the status mark, but before the description, you can optionally+ write a transaction "code", enclosed in parentheses. This is a good+ place to record a check number, or some other important transaction id+ or reference number.++ Description+ A transaction's description is the rest of the line following the date+ and status mark (or until a comment begins). Sometimes called the+ "narration" in traditional bookkeeping, it can be used for whatever you+ wish, or left blank. Transaction descriptions can be queried, unlike+ comments.++ Payee and note+ You can optionally include a | (pipe) character in descriptions to sub-+ divide the description into separate fields for payee/payer name on the+ left (up to the first |) and an additional note field on the right+ (after the first |). This may be worthwhile if you need to do more+ precise querying and pivoting by payee or by note.++ Comments+ Lines in the journal beginning with a semicolon (;) or hash (#) or star+ (*) are comments, and will be ignored. (Star comments cause org-mode+ nodes to be ignored, allowing emacs users to fold and navigate their+ journals with org-mode or orgstruct-mode.)++ You can attach comments to a transaction by writing them after the+ description and/or indented on the following lines (before the post-+ ings). Similarly, you can attach comments to an individual posting by+ writing them after the amount and/or indented on the following lines.+ Transaction and posting comments must begin with a semicolon (;).++ Some examples:++ # a file comment+ ; another file comment+ * also a file comment, useful in org/orgstruct mode++ comment+ A multiline file comment, which continues+ until a line containing just "end comment"+ (or end of file).+ end comment++ 2012/5/14 something ; a transaction comment+ ; the transaction comment, continued+ posting1 1 ; a comment for posting 1+ posting2+ ; a comment for posting 2+ ; another comment line for posting 2+ ; a file comment (because not indented)++ You can also comment larger regions of a file using comment and end+ comment directives.++ Tags+ Tags are a way to add extra labels or labelled data to postings and+ transactions, which you can then search or pivot on.++ A simple tag is a word (which may contain hyphens) followed by a full+ colon, written inside a transaction or posting comment line:++ 2017/1/16 bought groceries ; sometag:++ Tags can have a value, which is the text after the colon, up to the+ next comma or end of line, with leading/trailing whitespace removed:++ expenses:food $10 ; a-posting-tag: the tag value++ Note this means hledger's tag values can not contain commas or new-+ lines. Ending at commas means you can write multiple short tags on one+ line, comma separated:++ assets:checking ; a comment containing tag1:, tag2: some value ...++ Here,++ o "a comment containing" is just comment text, not a tag++ o "tag1" is a tag with no value++ o "tag2" is another tag, whose value is "some value ..."++ Tags in a transaction comment affect the transaction and all of its+ postings, while tags in a posting comment affect only that posting.+ For example, the following transaction has three tags (A, TAG2, third-+ tag) and the posting has four (those plus posting-tag):++ 1/1 a transaction ; A:, TAG2:+ ; third-tag: a third transaction tag, <- with a value+ (a) $1 ; posting-tag:++ Tags are like Ledger's metadata feature, except hledger's tag values+ are simple strings.++ Postings+ A posting is an addition of some amount to, or removal of some amount+ from, an account. Each posting line begins with at least one space or+ tab (2 or 4 spaces is common), followed by:++ o (optional) a status character (empty, !, or *), followed by a space++ o (required) an account name (any text, optionally containing single+ spaces, until end of line or a double space)++ o (optional) two or more spaces or tabs followed by an amount.++ Positive amounts are being added to the account, negative amounts are+ being removed.++ The amounts within a transaction must always sum up to zero. As a con-+ venience, one amount may be left blank; it will be inferred so as to+ balance the transaction.++ Be sure to note the unusual two-space delimiter between account name+ and amount. This makes it easy to write account names containing spa-+ ces. But if you accidentally leave only one space (or tab) before the+ amount, the amount will be considered part of the account name.++ Virtual postings+ A posting with a parenthesised account name is called a virtual posting+ or unbalanced posting, which means it is exempt from the usual rule+ that a transaction's postings must balance add up to zero.++ This is not part of double entry accounting, so you might choose to+ avoid this feature. Or you can use it sparingly for certain special+ cases where it can be convenient. Eg, you could set opening balances+ without using a balancing equity account:++ 1/1 opening balances+ (assets:checking) $1000+ (assets:savings) $2000++ A posting with a bracketed account name is called a balanced virtual+ posting. The balanced virtual postings in a transaction must add up to+ zero (separately from other postings). Eg:++ 1/1 buy food with cash, update budget envelope subaccounts, & something else+ assets:cash $-10 ; <- these balance+ expenses:food $7 ; <-+ expenses:food $3 ; <-+ [assets:checking:budget:food] $-10 ; <- and these balance+ [assets:checking:available] $10 ; <-+ (something:else) $5 ; <- not required to balance++ Ordinary non-parenthesised, non-bracketed postings are called real+ postings. You can exclude virtual postings from reports with the+ -R/--real flag or real:1 query.++ Account names+ Account names typically have several parts separated by a full colon,+ from which hledger derives a hierarchical chart of accounts. They can+ be anything you like, but in finance there are traditionally five top-+ level accounts: assets, liabilities, revenue, expenses, and equity.++ Account names may contain single spaces, eg: assets:accounts receiv-+ able. Because of this, they must always be followed by two or more+ spaces (or newline).++ Account names can be aliased.++ Amounts+ After the account name, there is usually an amount. (Important:+ between account name and amount, there must be two or more spaces.)++ hledger's amount format is flexible, supporting several international+ formats. Here are some examples. Amounts have a number (the "quan-+ tity"):++ 1++ ..and usually a currency symbol or commodity name (more on this below),+ to the left or right of the quantity, with or without a separating+ space:++ $1+ 4000 AAPL+ 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-+ modity symbol:++ -$1+ $-1++ One or more spaces between the sign and the number are acceptable when+ parsing (but they won't be displayed in output):++ + $1+ $- 1++ Scientific E notation is allowed:++ 1E-6+ EUR 1E3++ Decimal marks, digit group marks+ A decimal mark can be written as a period or a comma:++ 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, comma, or period (different from the decimal mark):++ $1,000,000.00+ EUR 2.000.000,00+ INR 9,99,99,999.00+ 1 000 000.9455++ Note, a number containing a single digit group mark and no decimal mark+ is ambiguous. Are these digit group marks or decimal marks ?++ 1,000+ 1.000++ If you don't tell it otherwise, hledger will assume both of the above+ are decimal marks, parsing both numbers as 1. To prevent confusion and+ undetected typos, we recommend adding commodity directives at the top+ of your journal file to explicitly declare the decimal mark (and+ optionally a digit group mark) for each commodity. Read on for more+ about this.++ Commodity+ 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",+ "ABC123").++ 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+ 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+ are the Amount and MixedAmount types.)++ Commodity directives+ You can add commodity directives to the journal, preferably at the top,+ to declare your commodities and help with number parsing (see above)+ and display (see below). These are optional, but recommended. They+ are described in more detail in JOURNAL FORMAT -> Declaring commodi-+ ties. Here's a quick example:++ # number format and display style for $, EUR, INR and the no-symbol commodity:+ commodity $1,000.00+ commodity EUR 1.000,00+ commodity INR 9,99,99,999.00+ commodity 1 000 000.9455+++ Commodity display style+ For the amounts in each commodity, hledger chooses a consistent display+ style to use in most reports. (Exceptions: price amounts, and all+ amounts displayed by the print command, are displayed with all of their+ decimal digits visible.)++ A commodity's display style is inferred as follows.++ 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+ order of preference:++ 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.+ (Posting amounts only; prices and periodic or auto rules are ignored,+ currently.)++ o The built-in fallback style, which looks like this: $1000.00. (Sym-+ bol on the left, period decimal mark, two decimal places.)++ A style is inferred from journal amounts as follows:++ o Use the general style (decimal mark, symbol placement) of the first+ amount++ o Use the first-seen digit group style (digit group mark, digit group+ sizes), if any++ o Use the maximum number of decimal places of all.++ Transaction price amounts don't affect the commodity display style+ directly, but occasionally they can do so indirectly (eg when a post-+ ing's amount is inferred using a transaction price). If you find this+ causing problems, use a commodity 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+ places, use a commodity directive. Some examples:++ # declare euro, dollar, bitcoin and no-symbol commodities and set their+ # input number formats and output display styles:+ commodity EUR 1.000,+ commodity $1000.00+ commodity 1000.00000000 BTC+ commodity 1 000.++ Rounding+ Amounts are stored internally as decimal numbers with up to 255 decimal+ places, and displayed with the number of decimal places specified by+ the commodity display style. Note, hledger uses banker's rounding: it+ rounds to the nearest even number, eg 0.5 displayed with zero decimal+ places is "0"). (Guaranteed since hledger 1.17.1; in older versions+ this could vary if hledger was built with Decimal < 0.5.1.)++ Transaction prices+ Within a transaction, you can note an amount's price in another commod-+ ity. This can be used to document the cost (in a purchase) or selling+ price (in a sale). For example, transaction prices are useful to+ record purchases of a foreign currency. Note transaction prices are+ fixed at the time of the transaction, and do not change over time. See+ also market prices, which represent prevailing exchange rates on a cer-+ tain date.++ There are several ways to record a transaction price:++ 1. Write the price per unit, as @ UNITPRICE after the amount:++ 2009/1/1+ assets:euros EUR100 @ $1.35 ; one hundred euros purchased at $1.35 each+ assets:dollars ; balancing amount is -$135.00++ 2. Write the total price, as @@ TOTALPRICE after the amount:++ 2009/1/1+ assets:euros EUR100 @@ $135 ; one hundred euros purchased at $135 for the lot+ assets:dollars++ 3. Specify amounts for all postings, using exactly two commodities, and+ let hledger infer the price that balances the transaction:++ 2009/1/1+ assets:euros EUR100 ; one hundred euros purchased+ assets:dollars $-135 ; for $135++ 4. Like 1, but the @ is parenthesised, i.e. (@); this is for compati-+ bility with Ledger journals (Virtual posting costs), and is equiva-+ lent to 1 in hledger.++ 5. Like 2, but as in 4 the @@ is parenthesised, i.e. (@@); in hledger,+ this is equivalent to 2.++ Use the -B/--cost flag to convert amounts to their transaction price's+ commodity, if any. (mnemonic: "B" is from "cost Basis", as in Ledger).+ Eg here is how -B affects the balance report for the example above:++ $ hledger bal -N --flat+ $-135 assets:dollars+ EUR100 assets:euros+ $ hledger bal -N --flat -B+ $-135 assets:dollars+ $135 assets:euros # <- the euros' cost++ Note -B is sensitive to the order of postings when a transaction price+ is inferred: the inferred price will be in the commodity of the last+ amount. So if example 3's postings are reversed, while the transaction+ is equivalent, -B shows something different:++ 2009/1/1+ assets:dollars $-135 ; 135 dollars sold+ assets:euros EUR100 ; for 100 euros++ $ hledger bal -N --flat -B+ EUR-100 assets:dollars # <- the dollars' selling price+ EUR100 assets:euros++ Lot prices, lot dates+ Ledger allows another kind of price, lot price (four variants: {UNIT-+ PRICE}, {{TOTALPRICE}}, {=FIXEDUNITPRICE}, {{=FIXEDTOTALPRICE}}),+ and/or a lot date ([DATE]) to be specified. These are normally used to+ select a lot when selling investments. hledger will parse these, for+ compatibility with Ledger journals, but currently ignores them. A+ transaction price, lot price and/or lot date may appear in any order,+ after the posting amount and before the balance assertion if any.++ Balance assertions+ hledger supports Ledger-style balance assertions in journal files.+ These look like, for example, = EXPECTEDBALANCE following a posting's+ amount. Eg here we assert the expected dollar balance in accounts a+ and b after each posting:++ 2013/1/1+ a $1 =$1+ b =$-1++ 2013/1/2+ a $1 =$2+ b $-1 =$-2++ After reading a journal file, hledger will check all balance assertions+ and report an error if any of them fail. Balance assertions can pro-+ tect you from, eg, inadvertently disrupting reconciled balances while+ cleaning up old entries. You can disable them temporarily with the+ -I/--ignore-assertions flag, which can be useful for troubleshooting or+ for reading Ledger files. (Note: this flag currently does not disable+ balance assignments, below).++ Assertions and ordering+ hledger sorts an account's postings and assertions first by date and+ then (for postings on the same day) by parse order. Note this is dif-+ ferent from Ledger, which sorts assertions only by parse order. (Also,+ Ledger assertions do not see the accumulated effect of repeated post-+ ings to the same account within a transaction.)++ So, hledger balance assertions keep working if you reorder differently-+ dated transactions within the journal. But if you reorder same-dated+ transactions or postings, assertions might break and require updating.+ This order dependence does bring an advantage: precise control over the+ order of postings and assertions within a day, so you can assert intra-+ day balances.++ Assertions and included files+ With included files, things are a little more complicated. Including+ preserves the ordering of postings and assertions. If you have multi-+ ple postings to an account on the same day, split across different+ files, and you also want to assert the account's balance on the same+ day, you'll have to put the assertion in the right file.++ Assertions and multiple -f options+ Balance assertions don't work well across files specified with multiple+ -f options. Use include or concatenate the files instead.++ Assertions and commodities+ The asserted balance must be a simple single-commodity amount, and in+ fact the assertion checks only this commodity's balance within the+ (possibly multi-commodity) account balance. This is how assertions+ work in Ledger also. We could call this a "partial" balance assertion.++ To assert the balance of more than one commodity in an account, you can+ write multiple postings, each asserting one commodity's balance.++ You can make a stronger "total" balance assertion by writing a double+ equals sign (== EXPECTEDBALANCE). This asserts that there are no other+ unasserted commodities in the account (or, that their balance is 0).++ 2013/1/1+ a $1+ a 1EUR+ b $-1+ c -1EUR++ 2013/1/2 ; These assertions succeed+ a 0 = $1+ a 0 = 1EUR+ b 0 == $-1+ c 0 == -1EUR++ 2013/1/3 ; This assertion fails as 'a' also contains 1EUR+ a 0 == $1++ It's not yet possible to make a complete assertion about a balance that+ has multiple commodities. One workaround is to isolate each commodity+ into its own subaccount:++ 2013/1/1+ a:usd $1+ a:euro 1EUR+ b++ 2013/1/2+ a 0 == 0+ a:usd 0 == $1+ a:euro 0 == 1EUR++ Assertions and prices+ Balance assertions ignore transaction prices, and should normally be+ written without one:++ 2019/1/1+ (a) $1 @ EUR1 = $1++ We do allow prices to be written there, however, and print shows them,+ even though they don't affect whether the assertion passes or fails.+ This is for backward compatibility (hledger's close command used to+ generate balance assertions with prices), and because balance assign-+ ments do use them (see below).++ Assertions and subaccounts+ The balance assertions above (= and ==) do not count the balance from+ subaccounts; they check the account's exclusive balance only. You can+ assert the balance including subaccounts by writing =* or ==*, eg:++ 2019/1/1+ equity:opening balances+ checking:a 5+ checking:b 5+ checking 1 ==* 11++ Assertions and virtual postings+ Balance assertions are checked against all postings, both real and vir-+ tual. They are not affected by the --real/-R flag or real: query.++ Assertions and precision+ Balance assertions compare the exactly calculated amounts, which are+ not always what is shown by reports. Eg a commodity directive may+ limit the display precision, but this will not affect balance asser-+ tions. Balance assertion failure messages show exact amounts.++ Balance assignments+ Ledger-style balance assignments are also supported. These are like+ balance assertions, but with no posting amount on the left side of the+ equals sign; instead it is calculated automatically so as to satisfy+ the assertion. This can be a convenience during data entry, eg when+ setting opening balances:++ ; starting a new journal, set asset account balances+ 2016/1/1 opening balances+ assets:checking = $409.32+ assets:savings = $735.24+ assets:cash = $42+ equity:opening balances++ or when adjusting a balance to reality:++ ; no cash left; update balance, record any untracked spending as a generic expense+ 2016/1/15+ assets:cash = $0+ expenses:misc++ The calculated amount depends on the account's balance in the commodity+ at that point (which depends on the previously-dated postings of the+ commodity to that account since the last balance assertion or assign-+ ment). Note that using balance assignments makes your journal a little+ less explicit; to know the exact amount posted, you have to run hledger+ or do the calculations yourself, instead of just reading it.++ Balance assignments and prices+ A transaction price in a balance assignment will cause the calculated+ amount to have that price attached:++ 2019/1/1+ (a) = $1 @ EUR2++ $ hledger print --explicit+ 2019-01-01+ (a) $1 @ EUR2 = $1 @ EUR2++ Directives+ A directive is a line in the journal beginning with a special keyword,+ that influences how the journal is processed. hledger's directives are+ based on a subset of Ledger's, but there are many differences (and also+ some differences between hledger versions).++ Directives' behaviour and interactions can get a little bit complex, so+ here is a table summarising the directives and their effects, with+ links to more detailed docs.+++ direc- end subdi- purpose can affect (as of+ tive directive rec- 2018/06)+ tives+ ------------------------------------------------------------------------------------+ account any document account names, all entries in all+ text declare account types & dis- files, before or+ play order after+++++ alias end rewrite account names following entries+ aliases until end of cur-+ rent file or end+ directive+ apply end apply prepend a common parent to following entries+ account account account names until end of cur-+ rent file or end+ directive+ comment end com- ignore part of journal following entries+ ment until end of cur-+ rent file or end+ directive+ commod- format declare a commodity and its number notation:+ ity number notation & display following entries+ style until end of cur-+ rent file; display+ style: amounts of+ that commodity in+ reports+ D declare a commodity to be default commodity:+ used for commodityless following commod-+ amounts, and its number ityless entries+ notation & display style until end of cur-+ rent file; number+ notation: following+ entries in that+ commodity until end+ of current file;+ display style:+ amounts of that+ commodity in+ reports+ include include entries/directives what the included+ from another file directives affect+ payee declare a payee name following entries+ until end of cur-+ rent file+ P declare a market price for a amounts of that+ commodity commodity in+ reports, when -V is+ used+ Y declare a year for yearless following entries+ dates until end of cur-+ rent file+ = declare an auto posting all entries in par-+ rule, adding postings to ent/current/child+ other transactions files (but not sib-+ ling files, see+ #1212)++ And some definitions:+++ subdi- optional indented directive line immediately following a parent+ rec- directive+ tive+ number how to interpret numbers when parsing journal entries (the iden-+ nota- tity of the decimal separator character). (Currently each com-+ tion modity can have its own notation, even in the same file.)+ dis- how to display amounts of a commodity in reports (symbol side+ play and spacing, digit groups, decimal separator, decimal places)+ style+ direc- which entries and (when there are multiple files) which files+ tive are affected by a directive+ scope++ As you can see, directives vary in which journal entries and files they+ affect, and whether they are focussed on input (parsing) or output+ (reports). Some directives have multiple effects.++ Directives and multiple files+ If you use multiple -f/--file options, or the include directive,+ hledger will process multiple input files. But note that directives+ which affect input (see above) typically last only until the end of the+ file in which they occur.++ This may seem inconvenient, but it's intentional; it makes reports sta-+ ble and deterministic, independent of the order of input. Otherwise+ you could see different numbers if you happened to write -f options in+ a different order, or if you moved includes around while cleaning up+ your files.++ It can be surprising though; for example, it means that alias direc-+ tives do not affect parent or sibling files (see below).++ Comment blocks+ A line containing just comment starts a commented region of the file,+ and a line containing just end comment (or the end of the current file)+ ends it. See also comments.++ Including other files+ You can pull in the content of additional files by writing an include+ directive, like this:++ include FILEPATH++ Only journal files can include, and only journal, timeclock or timedot+ files can be included (not CSV files, currently).++ If the file path does not begin with a slash, it is relative to the+ current file's folder.++ A tilde means home directory, eg: include ~/main.journal.++ The path may contain glob patterns to match multiple files, eg: include+ *.journal.++ There is limited support for recursive wildcards: **/ (the slash is+ required) matches 0 or more subdirectories. It's not super convenient+ since you have to avoid include cycles and including directories, but+ this can be done, eg: include */**/*.journal.++ The path may also be prefixed to force a specific file format, overrid-+ ing the file extension (as described in hledger.1 -> Input files):+ include timedot:~/notes/2020*.md.++ Default year+ You can set a default year to be used for subsequent dates which don't+ specify a year. This is a line beginning with Y followed by the year.+ Eg:++ Y2009 ; set default year to 2009++ 12/15 ; equivalent to 2009/12/15+ expenses 1+ assets++ Y2010 ; change default year to 2010++ 2009/1/30 ; specifies the year, not affected+ expenses 1+ assets++ 1/31 ; equivalent to 2010/1/31+ expenses 1+ assets++ Declaring payees+ The payee directive can be used to declare a limited set of payees+ which may appear in transaction descriptions. The "payees" check will+ report an error if any transaction refers to a payee that has not been+ declared. Eg:++ payee Whole Foods++ Declaring commodities+ You can use commodity directives to declare your commodities. In fact+ the commodity directive performs several functions at once:++ 1. It declares commodities which may be used in the journal. This can+ optionally be enforced, providing useful error checking. (Cf Com-+ modity error checking)++ 2. It declares which decimal mark character (period or comma), to+ expect when parsing input - useful to disambiguate international+ number formats in your data. Without this, hledger will parse both+ 1,000 and 1.000 as 1. (Cf Amounts)++ 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+ style)++ 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.++ Generally you should put them at the top of your journal file (since+ for function 2, they affect only following amounts, cf #793).++ A commodity directive is just the word commodity followed by a sample+ amount, like this:++ ;commodity SAMPLEAMOUNT++ commodity $1000.00+ commodity 1,000.0000 AAAA ; optional same-line comment++ It may also be written on multiple lines, and use the format subdirec-+ tive, as in Ledger. Note in this case the commodity symbol appears+ twice; it must be the same in both places:++ ;commodity SYMBOL+ ; format SAMPLEAMOUNT++ ; display indian rupees with currency name on the left,+ ; thousands, lakhs and crores comma-separated,+ ; period as decimal point, and two decimal places.+ commodity INR+ format INR 1,00,00,000.00++ Remember that if the commodity symbol contains spaces, numbers, or+ punctuation, it must be enclosed in double quotes (cf Commodity).++ The amount's quantity does not matter; only the format is significant.+ It must include a decimal mark - either a period or a comma - followed+ by 0 or more decimal digits.++ A few more examples:++ # number formats for $, EUR, INR and the no-symbol commodity:+ commodity $1,000.00+ commodity EUR 1.000,00+ commodity INR 9,99,99,999.0+ commodity 1 000 000.++ Note hledger normally uses banker's rounding, so 0.5 displayed with+ zero decimal digits is "0". (More at Commodity display style.)++ Commodity error checking+ In strict mode, enabled with the -s/--strict flag, hledger will report+ an error if a commodity symbol is used that has not been declared by a+ commodity directive. This works similarly to account error checking,+ see the notes there for more details.++ Default commodity+ The D directive sets a default commodity, to be used for any subsequent+ commodityless amounts (ie, plain numbers) seen while parsing the jour-+ nal. This effect lasts until the next D directive, or the end of the+ journal.++ For compatibility/historical reasons, D also acts like a commodity+ directive (setting the commodity's decimal mark for parsing and display+ style for output).++ As with commodity, the amount must include a decimal mark (either+ period or comma). If both commodity and D directives are used for the+ same commodity, the commodity style takes precedence.++ The syntax is D AMOUNT. Eg:++ ; commodity-less amounts should be treated as dollars+ ; (and displayed with the dollar sign on the left, thousands separators and two decimal places)+ D $1,000.00++ 1/1+ a 5 ; <- commodity-less amount, parsed as $5 and displayed as $5.00+ b++ Declaring market prices+ The P directive declares a market price, which is an exchange rate+ between two commodities on a certain date. (In Ledger, they are called+ "historical prices".) These are often obtained from a stock exchange,+ cryptocurrency exchange, or the foreign exchange market.++ The format is:++ P DATE COMMODITY1SYMBOL COMMODITY2AMOUNT++ DATE is a simple date, COMMODITY1SYMBOL is the symbol of the commodity+ being priced, and COMMODITY2AMOUNT is the amount (symbol and quantity)+ of commodity 2 that one unit of commodity 1 is worth on this date.+ Examples:++ # one euro was worth $1.35 from 2009-01-01 onward:+ P 2009-01-01 EUR $1.35++ # and $1.40 from 2010-01-01 onward:+ P 2010-01-01 EUR $1.40++ The -V, -X and --value flags use these market prices to show amount+ values in another commodity. See Valuation.++ Declaring accounts+ account directives can be used to declare accounts (ie, the places that+ amounts are transferred from and to). Though not required, these dec-+ larations can provide several benefits:++ o They can document your intended chart of accounts, providing a refer-+ ence.++ o They can help hledger know your accounts' types (asset, liability,+ equity, revenue, expense), useful for reports like balancesheet and+ incomestatement.++ o They control account display order in reports, allowing non-alpha-+ betic sorting (eg Revenues to appear above Expenses).++ o They can store extra information about accounts (account numbers,+ notes, etc.)++ o They help with account name completion in the add command, hledger-+ iadd, hledger-web, ledger-mode etc.++ o In strict mode, they restrict which accounts may be posted to by+ transactions, which helps detect typos.++ The simplest form is just the word account followed by a hledger-style+ account name, eg this account directive declares the assets:bank:check-+ ing account:++ account assets:bank:checking++ Account error checking+ By default, accounts come into existence when a transaction references+ them by name. This is convenient, but it means hledger can't warn you+ when you mis-spell an account name in the journal. Usually you'll find+ the error later, as an extra account in balance reports, or an incor-+ rect balance when reconciling.++ In strict mode, enabled with the -s/--strict flag, hledger will report+ an error if any transaction uses an account name that has not been+ declared by an account directive. Some notes:++ o The declaration is case-sensitive; transactions must use the correct+ account name capitalisation.++ o The account directive's scope is "whole file and below" (see direc-+ tives). This means it affects all of the current file, and any files+ it includes, but not parent or sibling files. The position of+ account 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+ included files in other formats).++ o It's currently not possible to declare "all possible subaccounts"+ with a wildcard; every account posted to must be declared.++ Account comments+ Comments, beginning with a semicolon, can be added:++ o on the same line, after two or more spaces (because ; is allowed in+ account names)++ o on the next lines, indented++ An example of both:++ account assets:bank:checking ; same-line comment, note 2+ spaces before ;+ ; next-line comment+ ; another with tag, acctno:12345 (not used yet)++ Same-line comments are not supported by Ledger, or hledger <1.13.++ Account subdirectives+ We also allow (and ignore) Ledger-style indented subdirectives, just+ for compatibility.:++ account assets:bank:checking+ format blah blah ; <- subdirective, ignored++ Here is the full syntax of account directives:++ account ACCTNAME [ACCTTYPE] [;COMMENT]+ [;COMMENTS]+ [LEDGER-STYLE SUBDIRECTIVES, IGNORED]++ Account types+ hledger recognises five main types of account, corresponding to the+ account classes in the accounting equation:++ Asset, Liability, Equity, Revenue, Expense.++ These account types are important for controlling which accounts appear+ in the balancesheet, balancesheetequity, incomestatement reports (and+ probably for other things in future).++ Additionally, we recognise the Cash type, which is also an Asset, and+ which causes accounts to appear in the cashflow report. ("Cash" here+ means liquid assets, eg bank balances but typically not investments or+ receivables.)++ Declaring account types+ Generally, to make these reports work you should declare your top-level+ accounts and their types, using account directives with type: tags.++ The tag's value should be one of: Asset, Liability, Equity, Revenue,+ Expense, Cash, A, L, E, R, X, C (all case insensitive). The type is+ inherited by all subaccounts except where they override it. Here's a+ complete example:++ account assets ; type: Asset+ account assets:bank ; type: Cash+ account assets:cash ; type: Cash+ account liabilities ; type: Liability+ account equity ; type: Equity+ account revenues ; type: Revenue+ account expenses ; type: Expense++ Auto-detected account types+ If you happen to use common english top-level account names, you may+ not need to declare account types, as they will be detected automati-+ cally using the following rules:++ If account's name matches this regular expression: | its type is:+ ------------------------------------------------------------------- | ------------+ ^assets?(:|$) |+ and does not contain regexp (investment|receivable|:A/R|:fixed) | Cash+ otherwise | Asset+ ^(debts?|liabilit(y|ies))(:|$) | Liability+ ^equity(:|$) | Equity+ ^(income|revenue)s?(:|$) | Revenue+ ^expenses?(:|$) | Expense++ Even so, explicit declarations may be a good idea, for clarity and pre-+ dictability.++ Interference from auto-detected account types+ If you assign any account type, it's a good idea to assign all of them,+ to prevent any confusion from mixing declared and auto-detected types.+ Although it's unlikely to happen in real life, here's an example: with+ the following journal, balancesheetequity shows "liabilities" in both+ Liabilities and Equity sections. Declaring another account as+ type:Liability would fix it:++ account liabilities ; type:Equity++ 2020-01-01+ assets 1+ liabilities 1+ equity -2++ Old account type syntax+ In some hledger journals you might instead see this old syntax (the+ letters ALERX, separated from the account name by two or more spaces);+ this is deprecated and may be removed soon:++ account assets A+ account liabilities L+ account equity E+ account revenues R+ account expenses X++ Account display order+ Account directives also set the order in which accounts are displayed,+ eg in reports, the hledger-ui accounts screen, and the hledger-web+ sidebar. By default accounts are listed in alphabetical order. But if+ you have these account directives in the journal:++ account assets+ account liabilities+ account equity+ account revenues+ account expenses++ you'll see those accounts displayed in declaration order, not alphabet-+ ically:++ $ hledger accounts -1+ assets+ liabilities+ equity+ revenues+ expenses++ Undeclared accounts, if any, are displayed last, in alphabetical order.++ Note that sorting is done at each level of the account tree (within+ each group of sibling accounts under the same parent). And currently,+ this directive:++ account other:zoo++ would influence the position of zoo among other's subaccounts, but not+ the position of other among the top-level accounts. This means:++ o you will sometimes declare parent accounts (eg account other above)+ that you don't intend to post to, just to customize their display+ order++ o sibling accounts stay together (you couldn't display x:y in between+ a:b and a:c).++ Rewriting accounts+ You can define account alias rules which rewrite your account names, or+ parts of them, before generating reports. This can be useful for:++ o expanding shorthand account names to their full form, allowing easier+ data entry and a less verbose journal++ o adapting old journals to your current chart of accounts++ o experimenting with new account organisations, like a new hierarchy or+ combining two accounts into one++ o customising reports++ Account aliases also rewrite account names in account directives. They+ do not affect account names being entered via hledger add or hledger-+ web.++ See also Rewrite account names.++ Basic aliases+ To set an account alias, use the alias directive in your journal file.+ This affects all subsequent journal entries in the current file or its+ included files (but note: not sibling or parent files). The spaces+ around the = are optional:++ alias OLD = NEW++ Or, you can use the --alias 'OLD=NEW' option on the command line. This+ affects all entries. It's useful for trying out aliases interactively.++ OLD and NEW are case sensitive full account names. hledger will+ replace any occurrence of the old account name with the new one. Sub-+ accounts are also affected. Eg:++ alias checking = assets:bank:wells fargo:checking+ ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"++ Regex aliases+ There is also a more powerful variant that uses a regular expression,+ indicated by the forward slashes:++ alias /REGEX/ = REPLACEMENT++ or --alias '/REGEX/=REPLACEMENT'.++ REGEX is a case-insensitive regular expression. Anywhere it matches+ inside an account name, the matched part will be replaced by REPLACE-+ MENT. If REGEX contains parenthesised match groups, these can be ref-+ erenced by the usual numeric backreferences in REPLACEMENT. Eg:++ alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3+ ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"++ Also note that REPLACEMENT continues to the end of line (or on command+ line, to end of option argument), so it can contain trailing white-+ space.++ Combining aliases+ You can define as many aliases as you like, using journal directives+ and/or command line options.++ Recursive aliases - where an account name is rewritten by one alias,+ then by another alias, and so on - are allowed. Each alias sees the+ effect of previously applied aliases.++ In such cases it can be important to understand which aliases will be+ applied and in which order. For (each account name in) each journal+ entry, we apply:++ 1. alias directives preceding the journal entry, most recently parsed+ first (ie, reading upward from the journal entry, bottom to top)++ 2. --alias options, in the order they appeared on the command line+ (left to right).++ In other words, for (an account name in) a given journal entry:++ o the nearest alias declaration before/above the entry is applied first++ o the next alias before/above that will be be applied next, and so on++ o aliases defined after/below the entry do not affect it.++ This gives nearby aliases precedence over distant ones, and helps pro-+ vide semantic stability - aliases will keep working the same way inde-+ pendent of which files are being read and in which order.++ In case of trouble, adding --debug=6 to the command line will show+ which aliases are being applied when.++ Aliases and multiple files+ As explained at Directives and multiple files, alias directives do not+ affect parent or sibling files. Eg in this command,++ hledger -f a.aliases -f b.journal++ account aliases defined in a.aliases will not affect b.journal.+ Including the aliases doesn't work either:++ include a.aliases++ 2020-01-01 ; not affected by a.aliases+ foo 1+ bar++ This means that account aliases should usually be declared at the start+ of your top-most file, like this:++ alias foo=Foo+ alias bar=Bar++ 2020-01-01 ; affected by aliases above+ foo 1+ bar++ include c.journal ; also affected++ end aliases+ You can clear (forget) all currently defined aliases with the end+ aliases directive:++ end aliases++ Default parent account+ You can specify a parent account which will be prepended to all+ accounts within a section of the journal. Use the apply account and+ end apply account directives like so:++ apply account home++ 2010/1/1+ food $10+ cash++ end apply account++ which is equivalent to:++ 2010/01/01+ home:food $10+ home:cash $-10++ If end apply account is omitted, the effect lasts to the end of the+ file. Included files are also affected, eg:++ apply account business+ include biz.journal+ end apply account+ apply account personal+ include personal.journal++ Prior to hledger 1.0, legacy account and end spellings were also sup-+ ported.++ A default parent account also affects account directives. It does not+ affect account names being entered via hledger add or hledger-web. If+ account aliases are present, they are applied after the default parent+ account.++ Periodic transactions+ Periodic transaction rules describe transactions that recur. They+ allow hledger to generate temporary future transactions to help with+ forecasting, so you don't have to write out each one in the journal,+ and it's easy to try out different forecasts.++ Periodic transactions can be a little tricky, so before you use them,+ read this whole section - or at least these tips:++ 1. Two spaces accidentally added or omitted will cause you trouble -+ read about this below.++ 2. For troubleshooting, show the generated transactions with hledger+ print --forecast tag:generated or hledger register --forecast+ tag:generated.++ 3. Forecasted transactions will begin only after the last non-fore-+ casted transaction's date.++ 4. Forecasted transactions will end 6 months from today, by default.+ See below for the exact start/end rules.++ 5. period expressions can be tricky. Their documentation needs+ improvement, but is worth studying.++ 6. Some period expressions with a repeating interval must begin on a+ natural boundary of that interval. Eg in weekly from DATE, DATE+ must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an+ error.++ 7. Other period expressions with an interval are automatically expanded+ to cover a whole number of that interval. (This is done to improve+ reports, but it also affects periodic transactions. Yes, it's a bit+ inconsistent with the above.) Eg: ~ every 10th day of month from+ 2020/01, which is equivalent to ~ every 10th day of month from+ 2020/01/01, will be adjusted to start on 2019/12/10.++ Periodic transaction rules also have a second meaning: they are used to+ define budget goals, shown in budget reports.++ Periodic rule syntax+ A periodic transaction rule looks like a normal journal entry, with the+ date replaced by a tilde (~) followed by a period expression (mnemonic:+ ~ looks like a recurring sine wave.):++ ~ monthly+ expenses:rent $2000+ assets:bank:checking++ There is an additional constraint on the period expression: the start+ date must fall on a natural boundary of the interval. Eg monthly from+ 2018/1/1 is valid, but monthly from 2018/1/15 is not.++ Partial or relative dates (M/D, D, tomorrow, last week) in the period+ expression can work (useful or not). They will be relative to today's+ date, unless a Y default year directive is in effect, in which case+ they will be relative to Y/1/1.++ Two spaces between period expression and description!+ If the period expression is followed by a transaction description,+ these must be separated by two or more spaces. This helps hledger know+ where the period expression ends, so that descriptions can not acciden-+ tally alter their meaning, as in this example:++ ; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020"+ ; ||+ ; vv+ ~ every 2 months in 2020, we will review+ assets:bank:checking $1500+ income:acme inc++ So,++ o Do write two spaces between your period expression and your transac-+ tion description, if any.++ o Don't accidentally write two spaces in the middle of your period+ expression.++ Forecasting with periodic transactions+ The --forecast flag activates any periodic transaction rules in the+ journal. They will generate temporary recurring transactions, which+ are not saved in the journal, but will appear in all reports (eg+ print). This can be useful for estimating balances into the future, or+ experimenting with different scenarios. Or, it can be used as a data+ entry aid: describe recurring transactions, and every so often copy the+ output of print --forecast into the journal.++ These transactions will have an extra tag indicating which periodic+ rule generated them: generated-transaction:~ PERIODICEXPR. And a simi-+ lar, hidden tag (beginning with an underscore) which, because it's+ never displayed by print, can be used to match transactions generated+ "just now": _generated-transaction:~ PERIODICEXPR.++ Periodic transactions are generated within some forecast period. By+ default, this++ o begins on the later of++ o the report start date if specified with -b/-p/date:++ o the day after the latest normal (non-periodic) transaction in the+ journal, or today if there are no normal transactions.++ o ends on the report end date if specified with -e/-p/date:, or 6+ months (180 days) from today.++ This means that periodic transactions will begin only after the latest+ recorded transaction. And a recorded transaction dated in the future+ can prevent generation of periodic transactions. (You can avoid that+ by writing the future transaction as a one-time periodic rule instead -+ put tilde before the date, eg ~ YYYY-MM-DD ...).++ Or, you can set your own arbitrary "forecast period", which can overlap+ recorded transactions, and need not be in the future, by providing an+ option argument, like --forecast=PERIODEXPR. Note the equals sign is+ required, a space won't work. PERIODEXPR is a period expression, which+ can specify the start date, end date, or both, like in a date: query.+ (See also hledger.1 -> Report start & end date). Some examples:+ --forecast=202001-202004, --forecast=jan-, --forecast=2020.++ Budgeting with periodic transactions+ With the --budget flag, currently supported by the balance command,+ each periodic transaction rule declares recurring budget goals for the+ specified accounts. Eg the first example above declares a goal of+ spending $2000 on rent (and also, a goal of depositing $2000 into+ checking) every month. Goals and actual performance can then be com-+ pared in budget reports.++ See also: Budgeting and Forecasting.+++ Auto postings+ "Automated postings" or "auto postings" are extra postings which get+ added automatically to transactions which match certain queries,+ defined by "auto posting rules", when you use the --auto flag.++ An auto posting rule looks a bit like a transaction:++ = QUERY+ ACCOUNT AMOUNT+ ...+ ACCOUNT [AMOUNT]++ except the first line is an equals sign (mnemonic: = suggests match-+ ing), followed by a query (which matches existing postings), and each+ "posting" line describes a posting to be generated, and the posting+ amounts can be:++ o a normal amount with a commodity symbol, eg $2. This will be used+ as-is.++ o a number, eg 2. The commodity symbol (if any) from the matched post-+ ing will be added to this.++ o a numeric multiplier, eg *2 (a star followed by a number N). The+ matched posting's amount (and total price, if any) will be multiplied+ by N.++ o a multiplier with a commodity symbol, eg *$2 (a star, number N, and+ symbol S). The matched posting's amount will be multiplied by N, and+ its commodity symbol will be replaced with S.++ Any query term containing spaces must be enclosed in single or double+ quotes, as on the command line. Eg, note the quotes around the second+ query term below:++ = expenses:groceries 'expenses:dining out'+ (budget:funds:dining out) *-1++ Some examples:++ ; every time I buy food, schedule a dollar donation+ = expenses:food+ (liabilities:charity) $-1++ ; when I buy a gift, also deduct that amount from a budget envelope subaccount+ = expenses:gifts+ assets:checking:gifts *-1+ assets:checking *1++ 2017/12/1+ expenses:food $10+ assets:checking++ 2017/12/14+ expenses:gifts $20+ assets:checking++ $ hledger print --auto+ 2017-12-01+ expenses:food $10+ assets:checking+ (liabilities:charity) $-1++ 2017-12-14+ expenses:gifts $20+ assets:checking+ assets:checking:gifts -$20+ assets:checking $20++ Auto postings and multiple files+ An auto posting rule can affect any transaction in the current file, or+ in any parent file or child file. Note, currently it will not affect+ sibling files (when multiple -f/--file are used - see #1212).++ Auto postings and dates+ A posting date (or secondary date) in the matched posting, or (taking+ precedence) a posting date in the auto posting rule itself, will also+ be used in the generated posting.++ Auto postings and transaction balancing / inferred amounts / balance asser-+ tions+ Currently, auto postings are added:++ o after missing amounts are inferred, and transactions are checked for+ balancedness,++ o but before balance assertions are checked.++ Note this means that journal entries must be balanced both before and+ after auto postings are added. This changed in hledger 1.12+; see #893+ for background.++ Auto posting tags+ Automated postings will have some extra tags:++ o generated-posting:= QUERY - shows this was generated by an auto post-+ ing rule, and the query++ o _generated-posting:= QUERY - a hidden tag, which does not appear in+ hledger's output. This can be used to match postings generated "just+ now", rather than generated in the past and saved to the journal.++ Also, any transaction that has been changed by auto posting rules will+ have these tags added:++ o modified: - this transaction was modified++ o _modified: - a hidden tag not appearing in the comment; this transac-+ tion was modified "just now".++CSV FORMAT+ How hledger reads CSV data, and the CSV rules file format.++ hledger can read CSV files (Character Separated Value - usually comma,+ semicolon, or tab) containing dated records as if they were journal+ files, automatically converting each CSV record into a transaction.++ (To learn about writing CSV, see CSV output.)++ We describe each CSV file's format with a corresponding rules file. By+ default this is named like the CSV file with a .rules extension added.+ Eg when reading FILE.csv, hledger also looks for FILE.csv.rules in the+ same directory as FILE.csv. You can specify a different rules file+ with the --rules-file option. If a rules file is not found, hledger+ will create a sample rules file, which you'll need to adjust.++ This file contains rules describing the CSV data (header line, fields+ layout, date format etc.), and how to construct hledger journal entries+ (transactions) from it. Often there will also be a list of conditional+ rules for categorising transactions based on their descriptions.+ Here's an overview of the CSV rules; these are described more fully+ below, after the examples:+++ skip skip one or more header lines or matched CSV+ records+ fields list name CSV fields, assign them to hledger+ fields+ field assignment assign a value to one hledger field, with+ interpolation+ Field names hledger field names, used in the fields list+ and field assignments+ separator a custom field separator++ if block apply some rules to CSV records matched by+ patterns+ if table apply some rules to CSV records matched by+ patterns, alternate syntax+ end skip the remaining CSV records+ date-format how to parse dates in CSV records+ decimal-mark the decimal mark used in CSV amounts, if+ ambiguous+ newest-first disambiguate record order when there's only+ one date+ include inline another CSV rules file+ balance-type choose which type of balance assignments to+ use++ Note, for best error messages when reading CSV files, use a .csv, .tsv+ or .ssv file extension or file prefix - see File Extension below.++ There's an introductory Convert CSV files tutorial on hledger.org.++ Examples+ Here are some sample hledger CSV rules files. See also the full col-+ lection at:+ https://github.com/simonmichael/hledger/tree/master/examples/csv++ Basic+ At minimum, the rules file must identify the date and amount fields,+ and often it also specifies the date format and how many header lines+ there are. Here's a simple CSV file and a rules file for it:++ Date, Description, Id, Amount+ 12/11/2019, Foo, 123, 10.23++ # basic.csv.rules+ skip 1+ fields date, description, _, amount+ date-format %d/%m/%Y++ $ hledger print -f basic.csv+ 2019-11-12 Foo+ expenses:unknown 10.23+ income:unknown -10.23++ Default account names are chosen, since we didn't set them.++ Bank of Ireland+ Here's a CSV with two amount fields (Debit and Credit), and a balance+ field, which we can use to add balance assertions, which is not neces-+ sary but provides extra error checking:++ Date,Details,Debit,Credit,Balance+ 07/12/2012,LODGMENT 529898,,10.0,131.21+ 07/12/2012,PAYMENT,5,,126++ # bankofireland-checking.csv.rules++ # skip the header line+ skip++ # name the csv fields, and assign some of them as journal entry fields+ fields date, description, amount-out, amount-in, balance++ # We generate balance assertions by assigning to "balance"+ # above, but you may sometimes need to remove these because:+ #+ # - the CSV balance differs from the true balance,+ # by up to 0.0000000000005 in my experience+ #+ # - it is sometimes calculated based on non-chronological ordering,+ # eg when multiple transactions clear on the same day++ # date is in UK/Ireland format+ date-format %d/%m/%Y++ # set the currency+ currency EUR++ # set the base account for all txns+ account1 assets:bank:boi:checking++ $ hledger -f bankofireland-checking.csv print+ 2012-12-07 LODGMENT 529898+ assets:bank:boi:checking EUR10.0 = EUR131.2+ income:unknown EUR-10.0++ 2012-12-07 PAYMENT+ assets:bank:boi:checking EUR-5.0 = EUR126.0+ expenses:unknown EUR5.0++ The balance assertions don't raise an error above, because we're read-+ ing directly from CSV, but they will be checked if these entries are+ imported into a journal file.++ Amazon+ Here we convert amazon.com order history, and use an if block to gener-+ ate a third posting if there's a fee. (In practice you'd probably get+ this data from your bank instead, but it's an example.)++ "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"+ "Jul 29, 2012","Payment","To","Foo.","Completed","$20.00","$0.00","16000000000000DGLNJPI1P9B8DKPVHL"+ "Jul 30, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$1.00","17LA58JSKRD4HDGLNJPI1P9B8DKPVHL"++ # amazon-orders.csv.rules++ # skip one header line+ skip 1++ # name the csv fields, and assign the transaction's date, amount and code.+ # Avoided the "status" and "amount" hledger field names to prevent confusion.+ fields date, _, toorfrom, name, amzstatus, amzamount, fees, code++ # how to parse the date+ date-format %b %-d, %Y++ # combine two fields to make the description+ description %toorfrom %name++ # save the status as a tag+ comment status:%amzstatus++ # set the base account for all transactions+ account1 assets:amazon+ # leave amount1 blank so it can balance the other(s).+ # I'm assuming amzamount excludes the fees, don't remember++ # set a generic account2+ account2 expenses:misc+ amount2 %amzamount+ # and maybe refine it further:+ #include categorisation.rules++ # add a third posting for fees, but only if they are non-zero.+ if %fees [1-9]+ account3 expenses:fees+ amount3 %fees++ $ hledger -f amazon-orders.csv print+ 2012-07-29 (16000000000000DGLNJPI1P9B8DKPVHL) To Foo. ; status:Completed+ assets:amazon+ expenses:misc $20.00++ 2012-07-30 (17LA58JSKRD4HDGLNJPI1P9B8DKPVHL) To Adapteva, Inc. ; status:Completed+ assets:amazon+ expenses:misc $25.00+ expenses:fees $1.00++ Paypal+ Here's a real-world rules file for (customised) Paypal CSV, with some+ Paypal-specific rules, and a second rules file included:++ "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"+ "10/01/2019","03:46:20","PDT","Calm Radio","Subscription Payment","Completed","USD","-6.99","0.00","-6.99","simon@joyful.com","memberships@calmradio.com","60P57143A8206782E","MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month","","I-R8YLY094FJYR","","-6.99",""+ "10/01/2019","03:46:20","PDT","","Bank Deposit to PP Account ","Pending","USD","6.99","0.00","6.99","","simon@joyful.com","0TU1544T080463733","","","60P57143A8206782E","","0.00",""+ "10/01/2019","08:57:01","PDT","Patreon","PreApproved Payment Bill User Payment","Completed","USD","-7.00","0.00","-7.00","simon@joyful.com","support@patreon.com","2722394R5F586712G","Patreon* Membership","","B-0PG93074E7M86381M","","-7.00",""+ "10/01/2019","08:57:01","PDT","","Bank Deposit to PP Account ","Pending","USD","7.00","0.00","7.00","","simon@joyful.com","71854087RG994194F","Patreon* Membership","","2722394R5F586712G","","0.00",""+ "10/19/2019","03:02:12","PDT","Wikimedia Foundation, Inc.","Subscription Payment","Completed","USD","-2.00","0.00","-2.00","simon@joyful.com","tle@wikimedia.org","K9U43044RY432050M","Monthly donation to the Wikimedia Foundation","","I-R5C3YUS3285L","","-2.00",""+ "10/19/2019","03:02:12","PDT","","Bank Deposit to PP Account ","Pending","USD","2.00","0.00","2.00","","simon@joyful.com","3XJ107139A851061F","","","K9U43044RY432050M","","0.00",""+ "10/22/2019","05:07:06","PDT","Noble Benefactor","Subscription Payment","Completed","USD","10.00","-0.59","9.41","noble@bene.fac.tor","simon@joyful.com","6L8L1662YP1334033","Joyful Systems","","I-KC9VBGY2GWDB","","9.41",""++ # paypal-custom.csv.rules++ # Tips:+ # Export from Activity -> Statements -> Custom -> Activity download+ # Suggested transaction type: "Balance affecting"+ # Paypal's default fields in 2018 were:+ # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Shipping Address","Address Status","Item Title","Item ID","Shipping and Handling Amount","Insurance Amount","Sales Tax","Option 1 Name","Option 1 Value","Option 2 Name","Option 2 Value","Reference Txn ID","Invoice Number","Custom Number","Quantity","Receipt ID","Balance","Address Line 1","Address Line 2/District/Neighborhood","Town/City","State/Province/Region/County/Territory/Prefecture/Republic","Zip/Postal Code","Country","Contact Phone Number","Subject","Note","Country Code","Balance Impact"+ # This rules file assumes the following more detailed fields, configured in "Customize report fields":+ # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note"++ fields date, time, timezone, description_, type, status_, currency, grossamount, feeamount, netamount, fromemail, toemail, code, itemtitle, itemid, referencetxnid, receiptid, balance, note++ skip 1++ date-format %-m/%-d/%Y++ # ignore some paypal events+ if+ In Progress+ Temporary Hold+ Update to+ skip++ # add more fields to the description+ description %description_ %itemtitle++ # save some other fields as tags+ comment itemid:%itemid, fromemail:%fromemail, toemail:%toemail, time:%time, type:%type, status:%status_++ # convert to short currency symbols+ if %currency USD+ currency $+ if %currency EUR+ currency E+ if %currency GBP+ currency P++ # generate postings++ # the first posting will be the money leaving/entering my paypal account+ # (negative means leaving my account, in all amount fields)+ account1 assets:online:paypal+ amount1 %netamount++ # the second posting will be money sent to/received from other party+ # (account2 is set below)+ amount2 -%grossamount++ # if there's a fee, add a third posting for the money taken by paypal.+ if %feeamount [1-9]+ account3 expenses:banking:paypal+ amount3 -%feeamount+ comment3 business:++ # choose an account for the second posting++ # override the default account names:+ # if the amount is positive, it's income (a debit)+ if %grossamount ^[^-]+ account2 income:unknown+ # if negative, it's an expense (a credit)+ if %grossamount ^-+ account2 expenses:unknown++ # apply common rules for setting account2 & other tweaks+ include common.rules++ # apply some overrides specific to this csv++ # Transfers from/to bank. These are usually marked Pending,+ # which can be disregarded in this case.+ if+ Bank Account+ Bank Deposit to PP Account+ description %type for %referencetxnid %itemtitle+ account2 assets:bank:wf:pchecking+ account1 assets:online:paypal++ # Currency conversions+ if Currency Conversion+ account2 equity:currency conversion++ # common.rules++ if+ darcs+ noble benefactor+ account2 revenues:foss donations:darcshub+ comment2 business:++ if+ Calm Radio+ account2 expenses:online:apps++ if+ electronic frontier foundation+ Patreon+ wikimedia+ Advent of Code+ account2 expenses:dues++ if Google+ account2 expenses:online:apps+ description google | music++ $ hledger -f paypal-custom.csv print+ 2019-10-01 (60P57143A8206782E) Calm Radio MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month ; itemid:, fromemail:simon@joyful.com, toemail:memberships@calmradio.com, time:03:46:20, type:Subscription Payment, status:Completed+ assets:online:paypal $-6.99 = $-6.99+ expenses:online:apps $6.99++ 2019-10-01 (0TU1544T080463733) Bank Deposit to PP Account for 60P57143A8206782E ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:46:20, type:Bank Deposit to PP Account, status:Pending+ assets:online:paypal $6.99 = $0.00+ assets:bank:wf:pchecking $-6.99++ 2019-10-01 (2722394R5F586712G) Patreon Patreon* Membership ; itemid:, fromemail:simon@joyful.com, toemail:support@patreon.com, time:08:57:01, type:PreApproved Payment Bill User Payment, status:Completed+ assets:online:paypal $-7.00 = $-7.00+ expenses:dues $7.00++ 2019-10-01 (71854087RG994194F) Bank Deposit to PP Account for 2722394R5F586712G Patreon* Membership ; itemid:, fromemail:, toemail:simon@joyful.com, time:08:57:01, type:Bank Deposit to PP Account, status:Pending+ assets:online:paypal $7.00 = $0.00+ assets:bank:wf:pchecking $-7.00++ 2019-10-19 (K9U43044RY432050M) Wikimedia Foundation, Inc. Monthly donation to the Wikimedia Foundation ; itemid:, fromemail:simon@joyful.com, toemail:tle@wikimedia.org, time:03:02:12, type:Subscription Payment, status:Completed+ assets:online:paypal $-2.00 = $-2.00+ expenses:dues $2.00+ expenses:banking:paypal ; business:++ 2019-10-19 (3XJ107139A851061F) Bank Deposit to PP Account for K9U43044RY432050M ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:02:12, type:Bank Deposit to PP Account, status:Pending+ assets:online:paypal $2.00 = $0.00+ assets:bank:wf:pchecking $-2.00++ 2019-10-22 (6L8L1662YP1334033) Noble Benefactor Joyful Systems ; itemid:, fromemail:noble@bene.fac.tor, toemail:simon@joyful.com, time:05:07:06, type:Subscription Payment, status:Completed+ assets:online:paypal $9.41 = $9.41+ revenues:foss donations:darcshub $-10.00 ; business:+ expenses:banking:paypal $0.59 ; business:++ CSV rules+ The following kinds of rule can appear in the rules file, in any order.+ Blank lines and lines beginning with # or ; are ignored.++ skip+ skip N++ The word "skip" followed by a number (or no number, meaning 1) tells+ hledger to ignore this many non-empty lines preceding the CSV data.+ (Empty/blank lines are skipped automatically.) You'll need this when-+ ever your CSV data contains header lines.++ It also has a second purpose: it can be used inside if blocks to ignore+ certain CSV records (described below).++ fields list+ fields FIELDNAME1, FIELDNAME2, ...++ A fields list (the word "fields" followed by comma-separated field+ names) is the quick way to assign CSV field values to hledger fields.+ (The other way is field assignments, see below.) A fields list does+ does two things:++ 1. It names the CSV fields. This is optional, but can be convenient+ later for interpolating them.++ 2. Whenever you use a standard hledger field name (defined below), the+ CSV value is assigned to that part of the hledger transaction.++ Here's an example that says "use the 1st, 2nd and 4th fields as the+ transaction's date, description and amount; name the last two fields+ for later reference; and ignore the others":++ fields date, description, , amount, , , somefield, anotherfield++ Tips:++ o The fields list always use commas, even if your CSV data uses another+ separator character.++ o Currently there must be least two items in the list (at least one+ comma).++ o Field names may not contain spaces. Spaces before/after field names+ are optional.++ o If the CSV contains column headings, it's a good idea to use these,+ suitably modified, as the basis for your field names (eg lower-cased,+ with underscores instead of spaces).++ o If some heading names match standard hledger fields, but you don't+ want to set the hledger fields directly, alter those names, eg by+ appending an underscore.++ o Fields you don't care about can be given a dummy name (eg: _ ), or no+ name.++ field assignment+ HLEDGERFIELDNAME FIELDVALUE++ Field assignments are the more flexible way to assign CSV values to+ hledger fields. They can be used instead of or in addition to a fields+ list (see above).++ 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-+ FIELDNAME).++ Some examples:++ # set the amount to the 4th CSV field, with " USD" appended+ amount %4 USD++ # combine three fields to make a comment, containing note: and date: tags+ comment note: %somefield - %anotherfield, date: %1++ Tips:++ o Interpolation strips outer whitespace (so a CSV value like " 1 "+ becomes 1 when interpolated) (#1051).++ o See also Tips below.++ Field names+ Here are the standard hledger field (and pseudo-field) names, which you+ can use in a fields list and in field assignments. For more about the+ transaction parts they refer to, see Transactions.++ date field+ Assigning to date sets the transaction date.++ date2 field+ date2 sets the transaction's secondary date, if any.++ status field+ status sets the transaction's status, if any.++ code field+ code sets the transaction's code, if any.++ description field+ description sets the transaction's description, if any.++ comment field+ comment sets the transaction's comment, if any.++ commentN, where N is a number, sets the Nth posting's comment.++ Tips: - Only single-line comments can be assigned. - Comments can con-+ tain tags, as usual.++ account field+ 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+ each transaction's description, and in conditional blocks.++ If a posting's account name is left unset but its amount is set (see+ below), a default account name will be chosen (like "expenses:unknown"+ or "income:unknown").++ amount field+ amountN sets the amount of the Nth posting, and causes that posting to+ be generated. By assigning to amount1, amount2, ... etc. you can+ generate up to 99 postings.++ amountN-in and amountN-out can be used instead, if the CSV uses sepa-+ rate fields for debits and credits (inflows and outflows). hledger+ assumes both of these CSV fields are unsigned, and will automatically+ negate the "-out" value. If they are signed, see "Setting amounts"+ below.++ amount, or amount-in and amount-out are a legacy mode, to keep pre-+ hledger-1.17 CSV rules files working (and for occasional convenience).+ They are suitable only for two-posting transactions; they set both+ posting 1's and posting 2's amount. Posting 2's amount will be+ negated, and also converted to cost if there's a transaction price.++ If you have an existing rules file using the unnumbered form, you might+ want to use the numbered form in certain conditional blocks, without+ having to update and retest all the old rules. To facilitate this,+ posting 1 ignores amount/amount-in/amount-out if any of+ amount1/amount1-in/amount1-out are assigned, and posting 2 ignores them+ if any of amount2/amount2-in/amount2-out are assigned, avoiding con-+ flicts.++ currency field+ currency sets a currency symbol, to be prepended to all postings'+ amounts. You can use this if the CSV amounts do not have a currency+ symbol, eg if it is in a separate column.++ currencyN prepends a currency symbol to just the Nth posting's amount.++ balance field+ balanceN sets a balance assertion amount (or if the posting amount is+ left empty, a balance assignment) on posting N.++ 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+ rule (see below).++ See Tips below for more about setting amounts and currency.++ separator+ You can use the separator rule to read other kinds of character-sepa-+ rated data. The argument is any single separator character, or the+ words tab or space (case insensitive). Eg, for comma-separated values+ (CSV):++ separator ,++ or for semicolon-separated values (SSV):++ separator ;++ or for tab-separated values (TSV):++ separator TAB++ If the input file has a .csv, .ssv or .tsv file extension (or a csv:,+ ssv:, tsv: prefix), the appropriate separator will be inferred automat-+ ically, and you won't need this rule.++ if block+ if MATCHER+ RULE++ if+ MATCHER+ MATCHER+ MATCHER+ RULE+ RULE++ Conditional blocks ("if blocks") are a block of rules that are applied+ only to CSV records which match certain patterns. They are often used+ for customising account names based on transaction descriptions.++ Matching the whole record+ Each MATCHER can be a record matcher, which looks like this:++ REGEX++ REGEX is a case-insensitive regular expression that tries to match any-+ where within the CSV record. It is a POSIX ERE (extended regular+ expression) that also supports GNU word boundaries (\b, \B, \<, \>),+ and nothing else. If you have trouble, be sure to check our doc:+ https://hledger.org/hledger.html#regular-expressions++ Important note: the record that is matched is not the original record,+ but a synthetic one, with any enclosing double quotes (but not enclos-+ ing whitespace) removed, and always comma-separated (which means that a+ field containing a comma will appear like two fields). Eg, if the+ original record is 2020-01-01; "Acme, Inc."; 1,000, the REGEX will+ actually see 2020-01-01,Acme, Inc., 1,000).++ Matching individual fields+ Or, MATCHER can be a field matcher, like this:++ %CSVFIELD REGEX++ which matches just the content of a particular CSV field. CSVFIELD is+ a percent sign followed by the field's name or column number, like+ %date or %1.++ Combining matchers+ A single matcher can be written on the same line as the "if"; or multi-+ ple matchers can be written on the following lines, non-indented. Mul-+ tiple matchers are OR'd (any one of them can match), unless one begins+ with an & symbol, in which case it is AND'ed with the previous matcher.++ if+ MATCHER+ & MATCHER+ RULE++ Rules applied on successful match+ After the patterns there should be one or more rules to apply, all+ indented by at least one space. Three kinds of rule are allowed in+ conditional blocks:++ o field assignments (to set a hledger field)++ o skip (to skip the matched CSV record)++ o end (to skip all remaining CSV records).++ Examples:++ # if the CSV record contains "groceries", set account2 to "expenses:groceries"+ if groceries+ account2 expenses:groceries++ # if the CSV record contains any of these patterns, set account2 and comment as shown+ if+ monthly service fee+ atm transaction fee+ banking thru software+ account2 expenses:business:banking+ comment XXX deductible ? check it++ if table+ if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn+ MATCHER1,VALUE11,VALUE12,...,VALUE1n+ MATCHER2,VALUE21,VALUE22,...,VALUE2n+ MATCHER3,VALUE31,VALUE32,...,VALUE3n+ <empty line>++ Conditional tables ("if tables") are a different syntax to specify+ field assignments that will be applied only to CSV records which match+ certain patterns.++ MATCHER could be either field or record matcher, as described above.+ When MATCHER matches, values from that row would be assigned to the CSV+ fields named on the if line, in the same order.++ Therefore if table is exactly equivalent to a sequence of of if blocks:++ if MATCHER1+ CSVFIELDNAME1 VALUE11+ CSVFIELDNAME2 VALUE12+ ...+ CSVFIELDNAMEn VALUE1n++ if MATCHER2+ CSVFIELDNAME1 VALUE21+ CSVFIELDNAME2 VALUE22+ ...+ CSVFIELDNAMEn VALUE2n++ if MATCHER3+ CSVFIELDNAME1 VALUE31+ CSVFIELDNAME2 VALUE32+ ...+ CSVFIELDNAMEn VALUE3n++ Each line starting with MATCHER should contain enough (possibly empty)+ values for all the listed fields.++ Rules would be checked and applied in the order they are listed in the+ table and, like with if blocks, later rules (in the same or another ta-+ ble) or if blocks could override the effect of any rule.++ Instead of ',' you can use a variety of other non-alphanumeric charac-+ ters as a separator. First character after if is taken to be the sepa-+ rator for the rest of the table. It is the responsibility of the user+ to ensure that separator does not occur inside MATCHERs and values -+ there is no way to escape separator.++ Example:++ if,account2,comment+ atm transaction fee,expenses:business:banking,deductible? check it+ %description groceries,expenses:groceries,+ 2020/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out++ end+ This rule can be used inside if blocks (only), to make hledger stop+ reading this CSV file and move on to the next input file, or to command+ execution. Eg:++ # ignore everything following the first empty record+ if ,,,,+ end++ date-format+ date-format DATEFMT++ This is a helper for the date (and date2) fields. If your CSV dates+ are not formatted like YYYY-MM-DD, YYYY/MM/DD or YYYY.MM.DD, you'll+ need to add a date-format rule describing them with a strptime date+ parsing pattern, which must parse the CSV date value completely. Some+ examples:++ # MM/DD/YY+ date-format %m/%d/%y++ # D/M/YYYY+ # The - makes leading zeros optional.+ date-format %-d/%-m/%Y++ # YYYY-Mmm-DD+ date-format %Y-%h-%d++ # M/D/YYYY HH:MM AM some other junk+ # Note the time and junk must be fully parsed, though only the date is used.+ date-format %-m/%-d/%Y %l:%M %p some other junk++ For the supported strptime syntax, see:+ https://hackage.haskell.org/package/time/docs/Data-Time-For-+ mat.html#v:formatTime++ Note that although you can parse date-times which include a time zone,+ that time zone is ignored; it will not change the date that is parsed.+ This means when reading CSV data with times not in your local time+ zone, dates can be "off by one".++ decimal-mark+ decimal-mark .++ or:++ decimal-mark ,++ hledger automatically accepts either period or comma as a decimal mark+ when parsing numbers (cf Amounts). However if any numbers in the CSV+ contain digit group marks, such as thousand-separating commas, you+ should declare the decimal mark explicitly with this rule, to avoid+ misparsed numbers.++ newest-first+ hledger always sorts the generated transactions by date. Transactions+ on the same date should appear in the same order as their CSV records,+ as hledger can usually auto-detect whether the CSV's normal order is+ oldest first or newest first. But if all of the following are true:++ o the CSV might sometimes contain just one day of data (all records+ having the same date)++ o the CSV records are normally in reverse chronological order (newest+ at the top)++ o and you care about preserving the order of same-day transactions++ then, you should add the newest-first rule as a hint. Eg:++ # tell hledger explicitly that the CSV is normally newest first+ newest-first++ include+ include RULESFILE++ This includes the contents of another CSV rules file at this point.+ RULESFILE is an absolute file path or a path relative to the current+ file's directory. This can be useful for sharing common rules between+ several rules files, eg:++ # someaccount.csv.rules++ ## someaccount-specific rules+ fields date,description,amount+ account1 assets:someaccount+ account2 expenses:misc++ ## common rules+ include categorisation.rules++ balance-type+ Balance assertions generated by assigning to balanceN are of the simple+ = type by default, which is a single-commodity, subaccount-excluding+ assertion. You may find the subaccount-including variants more useful,+ eg if you have created some virtual subaccounts of checking to help+ with budgeting. You can select a different type of assertion with the+ balance-type rule:++ # balance assertions will consider all commodities and all subaccounts+ balance-type ==*++ Here are the balance assertion types for quick reference:++ = single commodity, exclude subaccounts+ =* single commodity, include subaccounts+ == multi commodity, exclude subaccounts+ ==* multi commodity, include subaccounts++ Tips+ Rapid feedback+ It's a good idea to get rapid feedback while creating/troubleshooting+ CSV rules. Here's a good way, using entr from http://eradman.com/entr-+ project :++ $ ls foo.csv* | entr bash -c 'echo ----; hledger -f foo.csv print desc:SOMEDESC'++ A desc: query (eg) is used to select just one, or a few, transactions+ of interest. "bash -c" is used to run multiple commands, so we can+ echo a separator each time the command re-runs, making it easier to+ read the output.++ Valid CSV+ hledger accepts CSV conforming to RFC 4180. When CSV values are+ enclosed in quotes, note:++ o they must be double quotes (not single quotes)++ o spaces outside the quotes are not allowed++ File Extension+ To help hledger identify the format and show the right error messages,+ CSV/SSV/TSV files should normally be named with a .csv, .ssv or .tsv+ filename extension. Or, the file path should be prefixed with csv:,+ ssv: or tsv:. Eg:++ $ hledger -f foo.ssv print++ or:++ $ cat foo | hledger -f ssv:- foo++ You can override the file extension with a separator rule if needed.+ See also: Input files in the hledger manual.++ Reading multiple CSV files+ If you use multiple -f options to read multiple CSV files at once,+ hledger will look for a correspondingly-named rules file for each CSV+ file. But if you use the --rules-file option, that rules file will be+ used for all the CSV files.++ Valid transactions+ After reading a CSV file, hledger post-processes and validates the gen-+ erated journal entries as it would for a journal file - balancing them,+ applying balance assignments, and canonicalising amount styles. Any+ errors at this stage will be reported in the usual way, displaying the+ problem entry.++ There is one exception: balance assertions, if you have generated them,+ will not be checked, since normally these will work only when the CSV+ data is part of the main journal. If you do need to check balance+ assertions generated from CSV right away, pipe into another hledger:++ $ hledger -f file.csv print | hledger -f- print++ Deduplicating, importing+ When you download a CSV file periodically, eg to get your latest bank+ transactions, the new file may overlap with the old one, containing+ some of the same records.++ The import command will (a) detect the new transactions, and (b) append+ just those transactions to your main journal. It is idempotent, so you+ don't have to remember how many times you ran it or with which version+ of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This+ is the easiest way to import CSV data. Eg:++ # download the latest CSV files, then run this command.+ # Note, no -f flags needed here.+ $ hledger import *.csv [--dry]++ This method works for most CSV files. (Where records have a stable+ chronological order, and new records appear only at the new end.)++ A number of other tools and workflows, hledger-specific and otherwise,+ exist for converting, deduplicating, classifying and managing CSV data.+ See:++ o https://hledger.org -> sidebar -> real world setups++ o https://plaintextaccounting.org -> data import/conversion++ Setting amounts+ Some tips on using the amount-setting rules discussed above.++ Here are the ways to set a posting's amount:++ 1. If the CSV has a single amount field:+ Assign (via a fields list or a field assignment) to amountN. This sets+ the Nth posting's amount. N is usually 1 or 2 but can go up to 99.++ 2. If the CSV has separate amount fields for debit & credit (in & out):++ a. If both fields are unsigned:+ Assign to amountN-in and amountN-out. This sets posting N's amount+ to whichever of these has a non-zero value, and negates the "-out"+ value.++ b. If either field is signed (can contain a minus sign):+ Use a conditional rule to flip the sign (of non-empty values).+ Since hledger always negates amountN-out, if it was already nega-+ tive, we must undo that by negating once more (but only if the+ field is non-empty):++ fields date, description, amount1-in, amount1-out+ if %amount1-out [1-9]+ amount1-out -%amount1-out++ c. If both fields, or neither field, can contain a non-zero value:+ hledger normally expects exactly one of the fields to have a non-+ zero value. Eg, the amountN-in/amountN-out rules would reject+ value pairs like these:++ "", ""+ "0", "0"+ "1", "none"++ So, use smarter conditional rules to set the amount from the appro-+ priate field. Eg, these rules would make it use only the value+ containing non-zero digits, handling the above:++ fields date, description, in, out+ if %in [1-9]+ amount1 %in+ if %out [1-9]+ amount1 %out++ 3. If you are stuck with hledger <1.17, or you want posting 2's amount+ converted to cost:+ Assign to amount (or to amount-in and amount-out). (The old numberless+ syntax, which sets amount1 and amount2.)++ 4. If the CSV has the balance instead of the transaction amount:+ Assign to balanceN, which sets posting N's amount indirectly via a bal-+ ance assignment. (Old syntax: balance, equivalent to balance1.)++ o If hledger guesses the wrong default account name:+ When setting the amount via balance assertion, hledger may guess+ the wrong default account name. So, set the account name explic-+ itly, eg:++ fields date, description, balance1+ account1 assets:checking++ Amount signs+ There is some special handling for amount signs, to simplify parsing+ and sign-flipping:++ o If an amount value begins with a plus sign:+ that will be removed: +AMT becomes AMT++ o If an amount value is parenthesised:+ it will be de-parenthesised and sign-flipped: (AMT) becomes -AMT++ o If an amount value has two minus signs (or two sets of parentheses,+ or a minus sign and parentheses):+ they cancel out and will be removed: --AMT or -(AMT) becomes AMT++ o If an amount value contains just a sign (or just a set of parenthe-+ ses):+ that is removed, making it an empty value. "+" or "-" or "()" becomes+ "".++ Setting currency/commodity+ If the currency/commodity symbol is included in the CSV's amount+ field(s):++ 2020-01-01,foo,$123.00++ you don't have to do anything special for the commodity symbol, it will+ be assigned as part of the amount. Eg:++ fields date,description,amount++ 2020-01-01 foo+ expenses:unknown $123.00+ income:unknown $-123.00++ If the currency is provided as a separate CSV field:++ 2020-01-01,foo,USD,123.00++ You can assign that to the currency pseudo-field, which has the special+ effect of prepending itself to every amount in the transaction (on the+ left, with no separating space):++ fields date,description,currency,amount++ 2020-01-01 foo+ expenses:unknown USD123.00+ income:unknown USD-123.00++ Or, you can use a field assignment to construct the amount yourself,+ with more control. Eg to put the symbol on the right, and separated by+ a space:++ fields date,description,cur,amt+ amount %amt %cur++ 2020-01-01 foo+ expenses:unknown 123.00 USD+ income:unknown -123.00 USD++ Note we used a temporary field name (cur) that is not currency - that+ would trigger the prepending effect, which we don't want here.++ Amount decimal places+ Like amounts in a journal file, the amounts generated by CSV rules like+ 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+ 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+ hledger field:++ # Name the third CSV field "amount1"+ fields date,description,amount1++ # Set hledger's amount1 to the CSV amount1 field followed by USD+ amount1 %amount1 USD++ # Set comment to the CSV amount1 (not the amount1 assigned above)+ comment %amount1++ Here, since there's no CSV amount1 field, %amount1 will produce a lit-+ eral "amount1":++ fields date,description,csvamount+ amount1 %csvamount USD+ # Can't interpolate amount1 here+ comment %amount1++ When there are multiple field assignments to the same hledger field,+ only the last one takes effect. Here, comment's value will be be B, or+ C if "something" is matched, but never A:++ comment A+ comment B+ if something+ comment C++ How CSV rules are evaluated+ Here's how to think of CSV rules being evaluated (if you really need+ to). First,++ o include - all includes are inlined, from top to bottom, depth first.+ (At each include point the file is inlined and scanned for further+ includes, recursively, before proceeding.)++ Then "global" rules are evaluated, top to bottom. If a rule is+ repeated, the last one wins:++ o skip (at top level)++ o date-format++ o newest-first++ o fields - names the CSV fields, optionally sets up initial assignments+ to hledger fields++ Then for each CSV record in turn:++ o test all if blocks. If any of them contain a end rule, skip all+ remaining CSV records. Otherwise if any of them contain a skip rule,+ skip that many CSV records. If there are multiple matched skip+ rules, the first one wins.++ o collect all field assignments at top level and in matched if blocks.+ When there are multiple assignments for a field, keep only the last+ one.++ o compute a value for each hledger field - either the one that was+ assigned to it (and interpolate the %CSVFIELDNAME references), or a+ default++ o generate a synthetic hledger transaction from these values.++ This is all part of the CSV reader, one of several readers hledger can+ use to parse input files. When all files have been read successfully,+ the transactions are passed as input to whichever hledger command the+ user specified.++TIMECLOCK FORMAT+ The time logging format of timeclock.el, as read by hledger.++ hledger can read time logs in timeclock format. As with Ledger, these+ are (a subset of) timeclock.el's format, containing clock-in and clock-+ out entries as in the example below. The date is a simple date. The+ time format is HH:MM[:SS][+-ZZZZ]. Seconds and timezone are optional.+ The timezone, if present, must be four digits and is ignored (currently+ the time is always interpreted as a local time).++ i 2015/03/30 09:00:00 some:account name optional description after two spaces+ o 2015/03/30 09:20:00+ i 2015/03/31 22:21:45 another account+ o 2015/04/01 02:00:34++ hledger treats each clock-in/clock-out pair as a transaction posting+ some number of hours to an account. Or if the session spans more than+ one day, it is split into several transactions, one for each day. For+ the above time log, hledger print generates these journal entries:++ $ hledger -f t.timeclock print+ 2015-03-30 * optional description after two spaces+ (some:account name) 0.33h++ 2015-03-31 * 22:21-23:59+ (another account) 1.64h++ 2015-04-01 * 00:00-02:00+ (another account) 2.01h++ Here is a sample.timeclock to download and some queries to try:++ $ hledger -f sample.timeclock balance # current time balances+ $ hledger -f sample.timeclock register -p 2009/3 # sessions in march 2009+ $ hledger -f sample.timeclock register -p weekly --depth 1 --empty # time summary by week++ To generate time logs, ie to clock in and clock out, you could:++ o use emacs and the built-in timeclock.el, or the extended timeclock-+ x.el and perhaps the extras in ledgerutils.el++ o at the command line, use these bash aliases: shell alias ti="echo+ i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o+ `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"++ o or use the old ti and to scripts in the ledger 2.x repository. These+ rely on a "timeclock" executable which I think is just the ledger 2+ executable renamed.++TIMEDOT FORMAT+ 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+ this:++ 2021-08-04+ hom:errands .... ....+ fos:hledger:timedot .. ; docs+ per:admin:finance++ hledger reads this as three time transactions on this day, with each+ dot representing a quarter-hour spent:++ $ hledger -f a.timedot print # .timedot file extension activates the timedot reader+ 2021-08-04 *+ (hom:errands) 2.00++ 2021-08-04 *+ (fos:hledger:timedot) 0.50++ 2021-08-04 *+ (per:admin:finance) 0++ A day entry begins with a date line:++ o a non-indented simple date (Y-M-D, Y/M/D, or Y.M.D).++ Optionally this can be followed on the same line by++ o a common transaction description for this day++ o a common transaction comment for this day, after a semicolon (;).++ After the date line are zero or more optionally-indented time transac-+ tion lines, consisting of:++ o an account name - any word or phrase, usually a hledger-style account+ name.++ o two or more spaces - a field separator, required if there is an+ amount (as in journal format).++ o a timedot amount - dots representing quarter hours, or a number rep-+ resenting hours.++ o an optional comment beginning with semicolon. This is ignored.++ In more detail, timedot amounts can be:++ o dots: zero or more period characters, each representing one quarter-+ hour. Spaces are ignored and can be used for grouping. Eg: .... ..++ o a number, representing hours. Eg: 1.5++ o a number immediately followed by a unit symbol s, m, h, d, w, mo, or+ y, representing seconds, minutes, hours, days weeks, months or years.+ Eg 1.5h or 90m. The following equivalencies are assumed:+ 60s = 1m, 60m = 1h, 24h = 1d, 7d = 1w, 30d = 1mo, 365d = 1y. (This+ unit will not be visible in the generated transaction amount, which is+ always in hours.)++ There is some added flexibility to help with keeping time log data in+ the same file as your notes, todo lists, etc.:++ o Lines beginning with # or ;, and blank lines, are ignored.++ o Lines not ending with a double-space and amount are parsed as trans-+ actions with zero amount. (Most hledger reports hide these by+ default; add -E to see them.)++ o One or more stars (*) followed by a space, at the start of a line, is+ ignored. So date lines or time transaction lines can also be Org-+ mode headlines.++ o All Org-mode headlines before the first date line are ignored.++ More examples:++ # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.+ 2016/2/1+ inc:client1 .... .... .... .... .... ....+ fos:haskell .... ..+ biz:research .++ 2016/2/2+ inc:client1 .... ....+ biz:research .++ 2016/2/3+ inc:client1 4+ fos:hledger 3+ biz:research 1++ * Time log+ ** 2020-01-01+ *** adm:time .+ *** adm:finance .++ * 2020 Work Diary+ ** Q1+ *** 2020-02-29+ **** DONE+ 0700 yoga+ **** UNPLANNED+ **** BEGUN+ hom:chores+ cleaning ...+ water plants+ outdoor - one full watering can+ indoor - light watering+ **** TODO+ adm:planning: trip+ *** LATER++ Reporting:++ $ hledger -f a.timedot print date:2016/2/2+ 2016-02-02 *+ (inc:client1) 2.00++ 2016-02-02 *+ (biz:research) 0.25++ $ hledger -f a.timedot bal --daily --tree+ Balance changes in 2016-02-01-2016-02-03:++ || 2016-02-01d 2016-02-02d 2016-02-03d+ ============++========================================+ biz || 0.25 0.25 1.00+ research || 0.25 0.25 1.00+ fos || 1.50 0 3.00+ haskell || 1.50 0 0+ hledger || 0 0 3.00+ inc || 6.00 2.00 4.00+ client1 || 6.00 2.00 4.00+ ------------++----------------------------------------+ || 7.75 2.25 8.00++ Using period instead of colon as account name separator:++ 2016/2/4+ fos.hledger.timedot 4+ fos.ledger ..++ $ hledger -f a.timedot --alias /\\./=: bal --tree+ 4.50 fos+ 4.00 hledger:timedot+ 0.50 ledger+ --------------------+ 4.50++ A sample.timedot file.++COMMON TASKS+ Here are some quick examples of how to do some basic tasks with+ hledger. For more details, see the reference section below, the+ hledger_journal(5) manual, or the more extensive docs at+ https://hledger.org.++ Getting help+ $ hledger # show available commands+ $ hledger --help # show common options+ $ hledger CMD --help # show common and command options, and command help+ $ hledger help # show available manuals/topics+ $ hledger help hledger # show hledger manual as info/man/text (auto-chosen)+ $ hledger help journal --man # show the journal manual as a man page+ $ hledger help --help # show more detailed help for the help command++ Find more docs, chat, mail list, reddit, issue tracker:+ https://hledger.org#help-feedback++ Constructing command lines+ hledger has an extensive and powerful command line interface. We+ strive to keep it simple and ergonomic, but you may run into one of the+ confusing real world details described in OPTIONS, below. If that hap-+ pens, here are some tips that may help:++ o command-specific options must go after the command (it's fine to put+ all options there) (hledger CMD OPTS ARGS)++ o running add-on executables directly simplifies command line parsing+ (hledger-ui OPTS ARGS)++ o enclose "problematic" args in single quotes++ o if needed, also add a backslash to hide regular expression metachar-+ acters from the shell++ o to see how a misbehaving command is being parsed, add --debug=2.++ Starting a journal file+ hledger looks for your accounting data in a journal file,+ $HOME/.hledger.journal by default:++ $ hledger stats+ The hledger journal file "/Users/simon/.hledger.journal" was not found.+ Please create it first, eg with "hledger add" or a text editor.+ Or, specify an existing journal file with -f or LEDGER_FILE.++ You can override this by setting the LEDGER_FILE environment variable.+ It's a good practice to keep this important file under version control,+ and to start a new file each year. So you could do something like+ this:++ $ mkdir ~/finance+ $ cd ~/finance+ $ git init+ Initialized empty Git repository in /Users/simon/finance/.git/+ $ touch 2020.journal+ $ echo "export LEDGER_FILE=$HOME/finance/2020.journal" >> ~/.bashrc+ $ source ~/.bashrc+ $ hledger stats+ Main file : /Users/simon/finance/2020.journal+ Included files :+ Transactions span : to (0 days)+ Last transaction : none+ Transactions : 0 (0.0 per day)+ Transactions last 30 days: 0 (0.0 per day)+ Transactions last 7 days : 0 (0.0 per day)+ Payees/descriptions : 0+ Accounts : 0 (depth 0)+ Commodities : 0 ()+ Market prices : 0 ()++ Setting opening balances+ Pick a starting date for which you can look up the balances of some+ real-world assets (bank accounts, wallet..) and liabilities (credit+ cards..).++ To avoid a lot of data entry, you may want to start with just one or+ two accounts, like your checking account or cash wallet; and pick a+ recent starting date, like today or the start of the week. You can+ always come back later and add more accounts and older transactions, eg+ going back to january 1st.++ Add an opening balances transaction to the journal, declaring the bal-+ ances on this date. Here are two ways to do it:++ o The first way: open the journal in any text editor and save an entry+ like this:++ 2020-01-01 * opening balances+ assets:bank:checking $1000 = $1000+ assets:bank:savings $2000 = $2000+ assets:cash $100 = $100+ liabilities:creditcard $-50 = $-50+ equity:opening/closing balances++ These are start-of-day balances, ie whatever was in the account at+ the end of the previous day.++ The * after the date is an optional status flag. Here it means+ "cleared & confirmed".++ The currency symbols are optional, but usually a good idea as you'll+ be dealing with multiple currencies sooner or later.++ The = amounts are optional balance assertions, providing extra error+ checking.++ o The second way: run hledger add and follow the prompts to record a+ similar transaction:++ $ hledger add+ Adding transactions to journal file /Users/simon/finance/2020.journal+ Any command line arguments will be used as defaults.+ Use tab key to complete, readline keys to edit, enter to accept defaults.+ An optional (CODE) may follow transaction dates.+ An optional ; COMMENT may follow descriptions or amounts.+ If you make a mistake, enter < at any prompt to go one step backward.+ To end a transaction, enter . when prompted.+ To quit, enter . at a date prompt or press control-d or control-c.+ Date [2020-02-07]: 2020-01-01+ Description: * opening balances+ Account 1: assets:bank:checking+ Amount 1: $1000+ Account 2: assets:bank:savings+ Amount 2 [$-1000]: $2000+ Account 3: assets:cash+ Amount 3 [$-3000]: $100+ Account 4: liabilities:creditcard+ Amount 4 [$-3100]: $-50+ Account 5: equity:opening/closing balances+ Amount 5 [$-3050]:+ Account 6 (or . or enter to finish this transaction): .+ 2020-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++ Save this transaction to the journal ? [y]:+ Saved.+ Starting the next transaction (. or ctrl-D/ctrl-C to quit)+ Date [2020-01-01]: .++ If you're using version control, this could be a good time to commit+ the journal. Eg:++ $ git commit -m 'initial balances' 2020.journal++ Recording transactions+ As you spend or receive money, you can record these transactions using+ one of the methods above (text editor, hledger add) or by using the+ hledger-iadd or hledger-web add-ons, or by using the import command to+ convert CSV data downloaded from your bank.++ Here are some simple transactions, see the hledger_journal(5) manual+ and hledger.org for more ideas:++ 2020/1/10 * gift received+ assets:cash $20+ income:gifts++ 2020.1.12 * farmers market+ expenses:food $13+ assets:cash++ 2020-01-15 paycheck+ income:salary+ assets:bank:checking $1000++ Reconciling+ Periodically you should reconcile - compare your hledger-reported bal-+ ances against external sources of truth, like bank statements or your+ bank's website - to be sure that your ledger accurately represents the+ real-world balances (and, that the real-world institutions have not+ made a mistake!). This gets easy and fast with (1) practice and (2)+ frequency. If you do it daily, it can take 2-10 minutes. If you let+ it pile up, expect it to take longer as you hunt down errors and dis-+ crepancies.++ A typical workflow:++ 1. Reconcile cash. Count what's in your wallet. Compare with what+ hledger reports (hledger bal cash). If they are different, try to+ remember the missing transaction, or look for the error in the+ already-recorded transactions. A register report can be helpful+ (hledger reg cash). If you can't find the error, add an adjustment+ transaction. Eg if you have $105 after the above, and can't explain+ the missing $2, it could be:++ 2020-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ 2. Reconcile checking. Log in to your bank's website. Compare today's+ (cleared) balance with hledger's cleared balance (hledger bal check-+ ing -C). If they are different, track down the error or record the+ missing transaction(s) or add an adjustment transaction, similar to+ the above. Unlike the cash case, you can usually compare the trans-+ action history and running balance from your bank with the one+ reported by hledger reg checking -C. This will be easier if you+ generally record transaction dates quite similar to your bank's+ clearing dates.++ 3. Repeat for other asset/liability accounts.++ Tip: instead of the register command, use hledger-ui to see a live-+ updating register while you edit the journal: hledger-ui --watch --reg-+ ister checking -C++ After reconciling, it could be a good time to mark the reconciled+ transactions' status as "cleared and confirmed", if you want to track+ that, by adding the * marker. Eg in the paycheck transaction above,+ insert * between 2020-01-15 and paycheck++ If you're using version control, this can be another good time to com-+ mit:++ $ git commit -m 'txns' 2020.journal++ Reporting+ Here are some basic reports.++ Show all transactions:++ $ hledger print+ 2020-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++ 2020-01-10 * gift received+ assets:cash $20+ income:gifts++ 2020-01-12 * farmers market+ expenses:food $13+ assets:cash++ 2020-01-15 * paycheck+ income:salary+ assets:bank:checking $1000++ 2020-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ Show account names, and their hierarchy:++ $ hledger accounts --tree+ assets+ bank+ checking+ savings+ cash+ equity+ opening/closing balances+ expenses+ food+ misc+ income+ gifts+ salary+ liabilities+ creditcard++ Show all account totals:++ $ hledger balance+ $4105 assets+ $4000 bank+ $2000 checking+ $2000 savings+ $105 cash+ $-3050 equity:opening/closing balances+ $15 expenses+ $13 food+ $2 misc+ $-1020 income+ $-20 gifts+ $-1000 salary+ $-50 liabilities:creditcard+ --------------------+ 0++ Show only asset and liability balances, as a flat list, limited to+ depth 2:++ $ hledger bal assets liabilities --flat -2+ $4000 assets:bank+ $105 assets:cash+ $-50 liabilities:creditcard+ --------------------+ $4055++ Show the same thing without negative numbers, formatted as a simple+ balance sheet:++ $ hledger bs --flat -2+ Balance Sheet 2020-01-16++ || 2020-01-16+ ========================++============+ Assets ||+ ------------------------++------------+ assets:bank || $4000+ assets:cash || $105+ ------------------------++------------+ || $4105+ ========================++============+ Liabilities ||+ ------------------------++------------+ liabilities:creditcard || $50+ ------------------------++------------+ || $50+ ========================++============+ Net: || $4055++ The final total is your "net worth" on the end date. (Or use bse for a+ full balance sheet with equity.)++ Show income and expense totals, formatted as an income statement:++ hledger is+ Income Statement 2020-01-01-2020-01-16++ || 2020-01-01-2020-01-16+ ===============++=======================+ Revenues ||+ ---------------++-----------------------+ income:gifts || $20+ income:salary || $1000+ ---------------++-----------------------+ || $1020+ ===============++=======================+ Expenses ||+ ---------------++-----------------------+ expenses:food || $13+ expenses:misc || $2+ ---------------++-----------------------+ || $15+ ===============++=======================+ Net: || $1005++ The final total is your net income during this period.++ Show transactions affecting your wallet, with running total:++ $ hledger register cash+ 2020-01-01 opening balances assets:cash $100 $100+ 2020-01-10 gift received assets:cash $20 $120+ 2020-01-12 farmers market assets:cash $-13 $107+ 2020-01-16 adjust cash assets:cash $-2 $105++ Show weekly posting counts as a bar chart:++ $ hledger activity -W+ 2019-12-30 *****+ 2020-01-06 ****+ 2020-01-13 ****++ Migrating to a new file+ At the end of the year, you may want to continue your journal in a new+ file, so that old transactions don't slow down or clutter your reports,+ and to help ensure the integrity of your accounting history. See the+ close command.++ If using version control, don't forget to git add the new file.++LIMITATIONS+ The need to precede add-on command options with -- when invoked from+ hledger is awkward.++ When input data contains non-ascii characters, a suitable system locale+ must be configured (or there will be an unhelpful error). Eg on POSIX,+ set LANG to something other than C.++ In a Microsoft Windows CMD window, non-ascii characters and colours are+ not supported.++ On Windows, non-ascii characters may not display correctly when running+ a hledger built in CMD in MSYS/CYGWIN, or vice-versa.++ In a Cygwin/MSYS/Mintty window, the tab key is not supported in hledger+ add.++ Not all of Ledger's journal file syntax is supported. See file format+ differences.++ On large data files, hledger is slower and uses more memory than+ Ledger.++TROUBLESHOOTING+ Here are some issues you might encounter when you run hledger (and+ remember you can also seek help from the IRC channel, mail list or bug+ tracker):++ Successfully installed, but "No command 'hledger' found"+ stack and cabal install binaries into a special directory, which should+ be added to your PATH environment variable. Eg on unix-like systems,+ that is ~/.local/bin and ~/.cabal/bin respectively.++ I set a custom LEDGER_FILE, but hledger is still using the default file+ LEDGER_FILE should be a real environment variable, not just a shell+ variable. The command env | grep LEDGER_FILE should show it. You may+ need to use export. Here's an explanation.++ Getting errors like "Illegal byte sequence" or "Invalid or incomplete+ multibyte or wide character" or "commitAndReleaseBuffer: invalid argu-+ ment (invalid character)"+ Programs compiled with GHC (hledger, haskell build tools, etc.) need to+ have a UTF-8-aware locale configured in the environment, otherwise they+ will fail with these kinds of errors when they encounter non-ascii+ characters.++ To fix it, set the LANG environment variable to some locale which sup-+ ports UTF-8. The locale you choose must be installed on your system.++ Here's an example of setting LANG temporarily, on Ubuntu GNU/Linux:++ $ file my.journal+ my.journal: UTF-8 Unicode text # the file is UTF8-encoded+ $ echo $LANG+ C # LANG is set to the default locale, which does not support UTF8+ $ locale -a # which locales are installed ?+ C+ en_US.utf8 # here's a UTF8-aware one we can use+ POSIX+ $ LANG=en_US.utf8 hledger -f my.journal print # ensure it is used for this command++ If available, C.UTF-8 will also work. If your preferred locale isn't+ listed by locale -a, you might need to install it. Eg on+ Ubuntu/Debian:++ $ apt-get install language-pack-fr+ $ locale -a+ C+ en_US.utf8+ fr_BE.utf8+ fr_CA.utf8+ fr_CH.utf8+ fr_FR.utf8+ fr_LU.utf8+ POSIX+ $ LANG=fr_FR.utf8 hledger -f my.journal print++ Here's how you could set it permanently, if you use a bash shell:++ $ echo "export LANG=en_US.utf8" >>~/.bash_profile+ $ bash --login++ Exact spelling and capitalisation may be important. Note the differ-+ ence on MacOS (UTF-8, not utf8). Some platforms (eg ubuntu) allow+ variant spellings, but others (eg macos) require it to be exact:++ $ locale -a | grep -iE en_us.*utf+ en_US.UTF-8+ $ LANG=en_US.UTF-8 hledger -f my.journal print++++REPORTING BUGS+ Report bugs at http://bugs.hledger.org (or on the #hledger IRC channel+ or hledger mail list)+++AUTHORS+ Simon Michael <simon@joyful.com> and contributors+++COPYRIGHT+ Copyright (C) 2007-2020 Simon Michael.+ Released under GNU GPL v3 or later.+++SEE ALSO+ hledger(1), hledger-ui(1), hledger-web(1), ledger(1)++++hledger-1.22.2 August 2021 HLEDGER(1)