hledger 1.33 → 1.33.1
raw patch · 16 files changed
+42069/−42034 lines, 16 filesdep ~hledger-libdep ~processPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: hledger-lib, process
API changes (from Hackage documentation)
- Hledger.Cli.Script: showAmountsCostB :: Amount -> WideBuilder
+ Hledger.Cli.Script: showAmountCostB :: AmountFormat -> Amount -> WideBuilder
- Hledger.Cli.CliOptions: available_width :: HasCliOpts c_aiLN => Lens' c_aiLN Int
+ Hledger.Cli.CliOptions: available_width :: HasCliOpts c_aiNR => Lens' c_aiNR Int
- Hledger.Cli.CliOptions: class HasCliOpts c_aiLN
+ Hledger.Cli.CliOptions: class HasCliOpts c_aiNR
- Hledger.Cli.CliOptions: cliOpts :: HasCliOpts c_aiLN => Lens' c_aiLN CliOpts
+ Hledger.Cli.CliOptions: cliOpts :: HasCliOpts c_aiNR => Lens' c_aiNR CliOpts
- Hledger.Cli.CliOptions: command :: HasCliOpts c_aiLN => Lens' c_aiLN String
+ Hledger.Cli.CliOptions: command :: HasCliOpts c_aiNR => Lens' c_aiNR String
- Hledger.Cli.CliOptions: debug__ :: HasCliOpts c_aiLN => Lens' c_aiLN Int
+ Hledger.Cli.CliOptions: debug__ :: HasCliOpts c_aiNR => Lens' c_aiNR Int
- Hledger.Cli.CliOptions: file__ :: HasCliOpts c_aiLN => Lens' c_aiLN [FilePath]
+ Hledger.Cli.CliOptions: file__ :: HasCliOpts c_aiNR => Lens' c_aiNR [FilePath]
- Hledger.Cli.CliOptions: inputopts :: HasCliOpts c_aiLN => Lens' c_aiLN InputOpts
+ Hledger.Cli.CliOptions: inputopts :: HasCliOpts c_aiNR => Lens' c_aiNR InputOpts
- Hledger.Cli.CliOptions: no_new_accounts :: HasCliOpts c_aiLN => Lens' c_aiLN Bool
+ Hledger.Cli.CliOptions: no_new_accounts :: HasCliOpts c_aiNR => Lens' c_aiNR Bool
- Hledger.Cli.CliOptions: output_file :: HasCliOpts c_aiLN => Lens' c_aiLN (Maybe FilePath)
+ Hledger.Cli.CliOptions: output_file :: HasCliOpts c_aiNR => Lens' c_aiNR (Maybe FilePath)
- Hledger.Cli.CliOptions: output_format :: HasCliOpts c_aiLN => Lens' c_aiLN (Maybe String)
+ Hledger.Cli.CliOptions: output_format :: HasCliOpts c_aiNR => Lens' c_aiNR (Maybe String)
- Hledger.Cli.CliOptions: progstarttime :: HasCliOpts c_aiLN => Lens' c_aiLN POSIXTime
+ Hledger.Cli.CliOptions: progstarttime :: HasCliOpts c_aiNR => Lens' c_aiNR POSIXTime
- Hledger.Cli.CliOptions: rawopts__ :: HasCliOpts c_aiLN => Lens' c_aiLN RawOpts
+ Hledger.Cli.CliOptions: rawopts__ :: HasCliOpts c_aiNR => Lens' c_aiNR RawOpts
- Hledger.Cli.CliOptions: reportspec :: HasCliOpts c_aiLN => Lens' c_aiLN ReportSpec
+ Hledger.Cli.CliOptions: reportspec :: HasCliOpts c_aiNR => Lens' c_aiNR ReportSpec
- Hledger.Cli.CliOptions: width__ :: HasCliOpts c_aiLN => Lens' c_aiLN (Maybe String)
+ Hledger.Cli.CliOptions: width__ :: HasCliOpts c_aiNR => Lens' c_aiNR (Maybe String)
- Hledger.Cli.Script: available_width :: HasCliOpts c_aiLN => Lens' c_aiLN Int
+ Hledger.Cli.Script: available_width :: HasCliOpts c_aiNR => Lens' c_aiNR Int
- Hledger.Cli.Script: class HasCliOpts c_aiLN
+ Hledger.Cli.Script: class HasCliOpts c_aiNR
- Hledger.Cli.Script: cliOpts :: HasCliOpts c_aiLN => Lens' c_aiLN CliOpts
+ Hledger.Cli.Script: cliOpts :: HasCliOpts c_aiNR => Lens' c_aiNR CliOpts
- Hledger.Cli.Script: command :: HasCliOpts c_aiLN => Lens' c_aiLN String
+ Hledger.Cli.Script: command :: HasCliOpts c_aiNR => Lens' c_aiNR String
- Hledger.Cli.Script: debug__ :: HasCliOpts c_aiLN => Lens' c_aiLN Int
+ Hledger.Cli.Script: debug__ :: HasCliOpts c_aiNR => Lens' c_aiNR Int
- Hledger.Cli.Script: file__ :: HasCliOpts c_aiLN => Lens' c_aiLN [FilePath]
+ Hledger.Cli.Script: file__ :: HasCliOpts c_aiNR => Lens' c_aiNR [FilePath]
- Hledger.Cli.Script: inputopts :: HasCliOpts c_aiLN => Lens' c_aiLN InputOpts
+ Hledger.Cli.Script: inputopts :: HasCliOpts c_aiNR => Lens' c_aiNR InputOpts
- Hledger.Cli.Script: no_new_accounts :: HasCliOpts c_aiLN => Lens' c_aiLN Bool
+ Hledger.Cli.Script: no_new_accounts :: HasCliOpts c_aiNR => Lens' c_aiNR Bool
- Hledger.Cli.Script: output_file :: HasCliOpts c_aiLN => Lens' c_aiLN (Maybe FilePath)
+ Hledger.Cli.Script: output_file :: HasCliOpts c_aiNR => Lens' c_aiNR (Maybe FilePath)
- Hledger.Cli.Script: output_format :: HasCliOpts c_aiLN => Lens' c_aiLN (Maybe String)
+ Hledger.Cli.Script: output_format :: HasCliOpts c_aiNR => Lens' c_aiNR (Maybe String)
- Hledger.Cli.Script: progstarttime :: HasCliOpts c_aiLN => Lens' c_aiLN POSIXTime
+ Hledger.Cli.Script: progstarttime :: HasCliOpts c_aiNR => Lens' c_aiNR POSIXTime
- Hledger.Cli.Script: rawopts__ :: HasCliOpts c_aiLN => Lens' c_aiLN RawOpts
+ Hledger.Cli.Script: rawopts__ :: HasCliOpts c_aiNR => Lens' c_aiNR RawOpts
- Hledger.Cli.Script: reportspec :: HasCliOpts c_aiLN => Lens' c_aiLN ReportSpec
+ Hledger.Cli.Script: reportspec :: HasCliOpts c_aiNR => Lens' c_aiNR ReportSpec
- Hledger.Cli.Script: width__ :: HasCliOpts c_aiLN => Lens' c_aiLN (Maybe String)
+ Hledger.Cli.Script: width__ :: HasCliOpts c_aiNR => Lens' c_aiNR (Maybe String)
Files
- CHANGES.md +45/−14
- Hledger/Cli/Commands/Add.hs +5/−7
- Hledger/Cli/Commands/Balance.hs +12/−6
- embeddedfiles/hledger-ui.1 +2/−2
- embeddedfiles/hledger-ui.info +41/−41
- embeddedfiles/hledger-ui.txt +2/−2
- embeddedfiles/hledger-web.1 +2/−2
- embeddedfiles/hledger-web.info +25/−25
- embeddedfiles/hledger-web.txt +107/−107
- embeddedfiles/hledger.1 +2/−2
- embeddedfiles/hledger.info +11805/−11805
- embeddedfiles/hledger.txt +9101/−9101
- hledger.1 +2/−2
- hledger.cabal +12/−12
- hledger.info +11805/−11805
- hledger.txt +9101/−9101
CHANGES.md view
@@ -23,6 +23,30 @@ User-visible changes in the hledger command line tool and library. +# 1.33.1 2024-05-02++- process >=1.6.19.0 seems not strictly needed and is no longer required,+ improving installability.+ [#2149]++- `print` and `close` now show a trailing decimal mark on cost amounts also,+ when needed to disambiguate a digit group mark.++- The balance commands' HTML output now includes digit group marks when+ appropriate (fixes a regression in 1.25).+ [#2196]++- The add command no longer shows ANSI escape codes in terminals that+ don't support them.++- Doc updates:+ - import: Skipping -> Date skipping, discuss commodity styles more+ - csv: Amount decimal places: expand, note import behaviour++[#2149]: https://github.com/simonmichael/hledger/issues/2149+[#2196]: https://github.com/simonmichael/hledger/issues/2196++ # 1.33 2024-04-18 @@ -198,6 +222,7 @@ - examples: invoicing: cleanups, renames - examples: invoicing: pandoc-make-invoice: don't write to $LEDGER_FILE; remove the REMOVE THIS LINE line - examples: csv: daedalus-transactions: update for current daedalus [#2171]+- examples: shared-finances/ @@ -226,20 +251,26 @@ -[#2191]: https://github.com/simonmichael/issue/2191-[#2190]: https://github.com/simonmichael/issue/2190-[#2189]: https://github.com/simonmichael/issue/2189-[#2178]: https://github.com/simonmichael/issue/2178-[#2177]: https://github.com/simonmichael/issue/2177-[#2176]: https://github.com/simonmichael/issue/2176-[#2164]: https://github.com/simonmichael/issue/2164-[#2151]: https://github.com/simonmichael/issue/2151-[#2135]: https://github.com/simonmichael/issue/2135-[#2088]: https://github.com/simonmichael/issue/2088-[#2071]: https://github.com/simonmichael/issue/2071-[#1056]: https://github.com/simonmichael/issue/1056-[#815]: https://github.com/simonmichael/issue/815-+[#815]: https://github.com/simonmichael/hledger/issues/815+[#1056]: https://github.com/simonmichael/hledger/issues/1056+[#2071]: https://github.com/simonmichael/hledger/issues/2071+[#2088]: https://github.com/simonmichael/hledger/issues/2088+[#2119]: https://github.com/simonmichael/hledger/issues/2119+[#2135]: https://github.com/simonmichael/hledger/issues/2135+[#2135]: https://github.com/simonmichael/hledger/issues/2135+[#2148]: https://github.com/simonmichael/hledger/issues/2148+[#2151]: https://github.com/simonmichael/hledger/issues/2151+[#2151]: https://github.com/simonmichael/hledger/issues/2151+[#2158]: https://github.com/simonmichael/hledger/issues/2158+[#2159]: https://github.com/simonmichael/hledger/issues/2159+[#2164]: https://github.com/simonmichael/hledger/issues/2164+[#2171]: https://github.com/simonmichael/hledger/issues/2171+[#2176]: https://github.com/simonmichael/hledger/issues/2176+[#2177]: https://github.com/simonmichael/hledger/issues/2177+[#2178]: https://github.com/simonmichael/hledger/issues/2178+[#2189]: https://github.com/simonmichael/hledger/issues/2189+[#2190]: https://github.com/simonmichael/hledger/issues/2190+[#2191]: https://github.com/simonmichael/hledger/issues/2191 # 1.32.3 2024-01-28
Hledger/Cli/Commands/Add.hs view
@@ -249,7 +249,7 @@ retryMsg "Please enter y or n." $ parser ((fmap (\c -> if c == '<' then Nothing else Just c)) . headMay . map toLower . strip) $ defaultTo' def $ nonEmpty $- line $ green $ printf "Save this transaction to the journal ?%s: " (showDefault def)+ line $ green' $ printf "Save this transaction to the journal ?%s: " (showDefault def) case y of Just 'y' -> return t Just _ -> throw RestartTransactionException@@ -265,7 +265,7 @@ defaultTo' def $ nonEmpty $ maybeExit $ -- maybeShowHelp $- linePrewritten (green $ printf "Date%s: " (showDefault def)) (fromMaybe "" prevDateAndCode) ""+ linePrewritten (green' $ printf "Date%s: " (showDefault def)) (fromMaybe "" prevDateAndCode) "" where parseSmartDateAndCode refdate s = if s == "<" then return Nothing else either (const Nothing) (\(d,c) -> return $ Just (fixSmartDate refdate d, c)) edc where@@ -284,7 +284,7 @@ let def = headDef "" esArgs s <- withCompletion (descriptionCompleter esJournal def) $ defaultTo' def $ nonEmpty $- linePrewritten (green $ printf "Description%s: " (showDefault def)) (fromMaybe "" prevDescAndCmnt) ""+ linePrewritten (green' $ printf "Description%s: " (showDefault def)) (fromMaybe "" prevDescAndCmnt) "" if s == "<" then return Nothing else do@@ -307,7 +307,7 @@ parser (parseAccountOrDotOrNull def canfinish) $ withCompletion (accountCompleter esJournal def) $ defaultTo' def $ -- nonEmpty $- linePrewritten (green $ printf "Account %d%s%s: " pnum (endmsg::String) (showDefault def)) (fromMaybe "" $ prevAccount `atMay` length esPostings) ""+ linePrewritten (green' $ printf "Account %d%s%s: " pnum (endmsg::String) (showDefault def)) (fromMaybe "" $ prevAccount `atMay` length esPostings) "" where canfinish = not (null esPostings) && postingsBalanced esPostings parseAccountOrDotOrNull :: String -> Bool -> String -> Maybe (Maybe String)@@ -344,7 +344,7 @@ withCompletion (amountCompleter def) $ defaultTo' def $ nonEmpty $- linePrewritten (green $ printf "Amount %d%s: " pnum (showDefault def)) (fromMaybe "" $ prevAmountAndCmnt `atMay` length esPostings) ""+ linePrewritten (green' $ printf "Amount %d%s: " pnum (showDefault def)) (fromMaybe "" $ prevAmountAndCmnt `atMay` length esPostings) "" where parseAmountAndComment s = if s == "<" then return Nothing else either (const Nothing) (return . Just) $ runParser@@ -423,8 +423,6 @@ defaultTo' = flip defaultTo withCompletion f = withSettings (setComplete f defaultSettings)--green s = "\ESC[1;32m\STX"++s++"\ESC[0m\STX" showDefault "" = "" showDefault s = " [" ++ s ++ "]"
Hledger/Cli/Commands/Balance.hs view
@@ -545,11 +545,12 @@ allRows = case layout_ of LayoutTidy -> rows -- tidy csv should not include totals or averages _ -> rows ++ totals- (rows, totals) = multiBalanceReportAsCsv' opts report+ (rows, totals) = multiBalanceReportAsCsvOrHtml False opts report maybeTranspose = if transpose_ then transpose else id -multiBalanceReportAsCsv' :: ReportOpts -> MultiBalanceReport -> (CSV, CSV)-multiBalanceReportAsCsv' opts@ReportOpts{..} (PeriodicReport colspans items tr) =+-- Helper used for both CSV and HTML rendering.+multiBalanceReportAsCsvOrHtml :: Bool -> ReportOpts -> MultiBalanceReport -> (CSV, CSV)+multiBalanceReportAsCsvOrHtml ishtml opts@ReportOpts{..} (PeriodicReport colspans items tr) = (headers : concatMap fullRowAsTexts items, totalrows) where headers = "account" : case layout_ of@@ -558,11 +559,12 @@ _ -> dateHeaders dateHeaders = map showDateSpan colspans ++ ["total" | row_total_] ++ ["average" | average_] - fullRowAsTexts row = map (showName row :) $ multiBalanceRowAsCsvText opts colspans row+ fullRowAsTexts row = map (showName row :) $ rowAsText opts colspans row showName = accountNameDrop drop_ . prrFullName totalrows | no_total_ = mempty- | otherwise = map ("total" :) $ multiBalanceRowAsCsvText opts colspans tr+ | otherwise = map ("total" :) $ rowAsText opts colspans tr+ rowAsText = if ishtml then multiBalanceRowAsHtmlText else multiBalanceRowAsCsvText -- | Render a multi-column balance report as HTML. multiBalanceReportAsHtml :: ReportOpts -> MultiBalanceReport -> Html ()@@ -583,7 +585,7 @@ -- TODO: should the commodity_column be displayed as a subaccount in this case as well? (headingsrow:bodyrows, mtotalsrows) | transpose_ ropts = error' "Sorry, --transpose with HTML output is not yet supported" -- PARTIAL:- | otherwise = multiBalanceReportAsCsv' ropts mbr+ | otherwise = multiBalanceReportAsCsvOrHtml True ropts mbr in (multiBalanceReportHtmlHeadRow ropts headingsrow ,map (multiBalanceReportHtmlBodyRow ropts) bodyrows@@ -777,8 +779,12 @@ m (x:xs) = x:xs m [] = [n] + multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[T.Text]] multiBalanceRowAsCsvText opts colspans = fmap (fmap wbToText) . multiBalanceRowAsWbs machineFmt opts colspans++multiBalanceRowAsHtmlText :: ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[T.Text]]+multiBalanceRowAsHtmlText opts colspans = fmap (fmap wbToText) . multiBalanceRowAsWbs oneLineNoCostFmt opts colspans multiBalanceRowAsTableText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]] multiBalanceRowAsTableText opts = multiBalanceRowAsWbs oneLineNoCostFmt{displayColour=color_ opts} opts []
embeddedfiles/hledger-ui.1 view
@@ -1,5 +1,5 @@ -.TH "HLEDGER\-UI" "1" "April 2024" "hledger-ui-1.33 " "hledger User Manuals"+.TH "HLEDGER\-UI" "1" "May 2024" "hledger-ui-1.33.1 " "hledger User Manuals" @@ -12,7 +12,7 @@ .PD \f[CR]hledger ui \-\- [OPTS] [QUERYARGS]\f[R] .SH DESCRIPTION-This manual is for hledger\[aq]s terminal interface, version 1.33.+This manual is for hledger\[aq]s terminal interface, version 1.33.1. See also the hledger manual for common concepts and file formats. .PP hledger is a robust, user\-friendly, cross\-platform set of programs for
embeddedfiles/hledger-ui.info view
@@ -16,7 +16,7 @@ 'hledger-ui [OPTS] [QUERYARGS]' 'hledger ui -- [OPTS] [QUERYARGS]' - This manual is for hledger's terminal interface, version 1.33. See+ This manual is for hledger's terminal interface, version 1.33.1. See also the hledger manual for common concepts and file formats. hledger is a robust, user-friendly, cross-platform set of programs@@ -671,46 +671,46 @@ Tag Table: Node: Top221-Node: OPTIONS1828-Ref: #options1926-Node: General help options2954-Ref: #general-help-options3103-Node: General input options3385-Ref: #general-input-options3570-Node: General reporting options4227-Ref: #general-reporting-options4391-Node: MOUSE7781-Ref: #mouse7876-Node: KEYS8113-Ref: #keys8206-Node: SCREENS12861-Ref: #screens12959-Node: Menu13539-Ref: #menu13632-Node: Cash accounts13827-Ref: #cash-accounts13969-Node: Balance sheet accounts14153-Ref: #balance-sheet-accounts14334-Node: Income statement accounts14454-Ref: #income-statement-accounts14640-Node: All accounts14804-Ref: #all-accounts14950-Node: Register15132-Ref: #register15256-Node: Transaction17540-Ref: #transaction17663-Node: Error19080-Ref: #error19174-Node: TIPS19418-Ref: #tips19517-Node: Watch mode19559-Ref: #watch-mode19666-Node: Debug output21125-Ref: #debug-output21236-Node: ENVIRONMENT21448-Ref: #environment21558-Node: BUGS21749-Ref: #bugs21832+Node: OPTIONS1830+Ref: #options1928+Node: General help options2956+Ref: #general-help-options3105+Node: General input options3387+Ref: #general-input-options3572+Node: General reporting options4229+Ref: #general-reporting-options4393+Node: MOUSE7783+Ref: #mouse7878+Node: KEYS8115+Ref: #keys8208+Node: SCREENS12863+Ref: #screens12961+Node: Menu13541+Ref: #menu13634+Node: Cash accounts13829+Ref: #cash-accounts13971+Node: Balance sheet accounts14155+Ref: #balance-sheet-accounts14336+Node: Income statement accounts14456+Ref: #income-statement-accounts14642+Node: All accounts14806+Ref: #all-accounts14952+Node: Register15134+Ref: #register15258+Node: Transaction17542+Ref: #transaction17665+Node: Error19082+Ref: #error19176+Node: TIPS19420+Ref: #tips19519+Node: Watch mode19561+Ref: #watch-mode19668+Node: Debug output21127+Ref: #debug-output21238+Node: ENVIRONMENT21450+Ref: #environment21560+Node: BUGS21751+Ref: #bugs21834 End Tag Table
embeddedfiles/hledger-ui.txt view
@@ -9,7 +9,7 @@ hledger ui -- [OPTS] [QUERYARGS] DESCRIPTION- This manual is for hledger's terminal interface, version 1.33. See+ This manual is for hledger's terminal interface, version 1.33.1. See also the hledger manual for common concepts and file formats. hledger is a robust, user-friendly, cross-platform set of programs for@@ -535,4 +535,4 @@ SEE ALSO hledger(1), hledger-ui(1), hledger-web(1), ledger(1) -hledger-ui-1.33 April 2024 HLEDGER-UI(1)+hledger-ui-1.33.1 May 2024 HLEDGER-UI(1)
embeddedfiles/hledger-web.1 view
@@ -1,5 +1,5 @@ -.TH "HLEDGER\-WEB" "1" "April 2024" "hledger-web-1.33 " "hledger User Manuals"+.TH "HLEDGER\-WEB" "1" "May 2024" "hledger-web-1.33.1 " "hledger User Manuals" @@ -12,7 +12,7 @@ .PD \f[CR]hledger web \-\- [\-\-serve|\-\-serve\-api] [OPTS] [ARGS]\f[R] .SH DESCRIPTION-This manual is for hledger\[aq]s web interface, version 1.33.+This manual is for hledger\[aq]s web interface, version 1.33.1. See also the hledger manual for common concepts and file formats. .PP hledger is a robust, user\-friendly, cross\-platform set of programs for
embeddedfiles/hledger-web.info view
@@ -16,7 +16,7 @@ 'hledger-web [--serve|--serve-api] [OPTS] [ARGS]' 'hledger web -- [--serve|--serve-api] [OPTS] [ARGS]' - This manual is for hledger's web interface, version 1.33. See also+ This manual is for hledger's web interface, version 1.33.1. See also the hledger manual for common concepts and file formats. hledger is a robust, user-friendly, cross-platform set of programs@@ -638,30 +638,30 @@ Tag Table: Node: Top223-Node: OPTIONS2575-Ref: #options2680-Node: General help options5645-Ref: #general-help-options5795-Node: General input options6077-Ref: #general-input-options6263-Node: General reporting options6920-Ref: #general-reporting-options7085-Node: PERMISSIONS10475-Ref: #permissions10614-Node: EDITING UPLOADING DOWNLOADING11826-Ref: #editing-uploading-downloading12007-Node: RELOADING12841-Ref: #reloading12975-Node: JSON API13408-Ref: #json-api13523-Node: DEBUG OUTPUT19011-Ref: #debug-output19136-Node: Debug output19163-Ref: #debug-output-119264-Node: ENVIRONMENT19681-Ref: #environment19800-Node: BUGS19917-Ref: #bugs20001+Node: OPTIONS2577+Ref: #options2682+Node: General help options5647+Ref: #general-help-options5797+Node: General input options6079+Ref: #general-input-options6265+Node: General reporting options6922+Ref: #general-reporting-options7087+Node: PERMISSIONS10477+Ref: #permissions10616+Node: EDITING UPLOADING DOWNLOADING11828+Ref: #editing-uploading-downloading12009+Node: RELOADING12843+Ref: #reloading12977+Node: JSON API13410+Ref: #json-api13525+Node: DEBUG OUTPUT19013+Ref: #debug-output19138+Node: Debug output19165+Ref: #debug-output-119266+Node: ENVIRONMENT19683+Ref: #environment19802+Node: BUGS19919+Ref: #bugs20003 End Tag Table
embeddedfiles/hledger-web.txt view
@@ -9,41 +9,41 @@ hledger web -- [--serve|--serve-api] [OPTS] [ARGS] DESCRIPTION- This manual is for hledger's web interface, version 1.33. See also the- hledger manual for common concepts and file formats.+ This manual is for hledger's web interface, version 1.33.1. See also+ the hledger manual for common concepts and file formats. - hledger is a robust, user-friendly, cross-platform set of programs for- tracking money, time, or any other commodity, using double-entry ac-- counting and a simple, editable file format. hledger is inspired by- and largely compatible with ledger(1), and largely interconvertible+ hledger is a robust, user-friendly, cross-platform set of programs for+ tracking money, time, or any other commodity, using double-entry ac-+ counting and a simple, editable file format. hledger is inspired by+ and largely compatible with ledger(1), and largely interconvertible with beancount(1). - hledger-web is a simple web application for browsing and adding trans-- actions. It provides a more user-friendly UI than the hledger CLI or- hledger-ui TUI, showing more at once (accounts, the current account+ hledger-web is a simple web application for browsing and adding trans-+ actions. It provides a more user-friendly UI than the hledger CLI or+ hledger-ui TUI, showing more at once (accounts, the current account register, balance charts) and allowing history-aware data entry, inter- active searching, and bookmarking. - hledger-web also lets you share a journal with multiple users, or even- the public web. There is no access control, so if you need that you- should put it behind a suitable web proxy. As a small protection- against data loss when running an unprotected instance, it writes a+ hledger-web also lets you share a journal with multiple users, or even+ the public web. There is no access control, so if you need that you+ should put it behind a suitable web proxy. As a small protection+ against data loss when running an unprotected instance, it writes a numbered backup of the main journal file (only) on every edit. - Like hledger, it reads from (and appends to) a journal file specified- by the LEDGER_FILE environment variable (defaulting to- $HOME/.hledger.journal); or you can specify files with -f options. It- can also read timeclock files, timedot files, or any CSV/SSV/TSV file+ Like hledger, it reads from (and appends to) a journal file specified+ by the LEDGER_FILE environment variable (defaulting to+ $HOME/.hledger.journal); or you can specify files with -f options. It+ can also read timeclock files, timedot files, or any CSV/SSV/TSV file with a date field. (See hledger(1) -> Input for details.) hledger-web can be run in three modes: o Transient mode (the default): your default web browser will be opened- to show the app if possible, and the app exits automatically after- two minutes of inactivity (no requests received and no open browser+ to show the app if possible, and the app exits automatically after+ two minutes of inactivity (no requests received and no open browser windows viewing it). - o With --serve: the app runs without stopping, and without opening a+ o With --serve: the app runs without stopping, and without opening a browser. o With --serve-api: only the JSON API is served.@@ -61,36 +61,36 @@ like --serve, but serve only the JSON web API, not the web UI --allow=view|add|edit- set the user's access level for changing data (default: add).- It also accepts sandstorm for use on that platform (reads per-+ set the user's access level for changing data (default: add).+ It also accepts sandstorm for use on that platform (reads per- missions from the X-Sandstorm-Permissions request header). --cors=ORIGIN- allow cross-origin requests from the specified origin; setting+ allow cross-origin requests from the specified origin; setting ORIGIN to "*" allows requests from any origin --host=IPADDR listen on this IP address (default: 127.0.0.1) - By default the server listens on IP address 127.0.0.1, which is acces-- sible only to requests from the local machine.. You can use --host to- listen on a different address configured on the machine, eg to allow- access from other machines. The special address 0.0.0.0 causes it to+ By default the server listens on IP address 127.0.0.1, which is acces-+ sible only to requests from the local machine.. You can use --host to+ listen on a different address configured on the machine, eg to allow+ access from other machines. The special address 0.0.0.0 causes it to listen on all addresses configured on the machine. --port=PORT listen on this TCP port (default: 5000) - Similarly, you can use --port to listen on a TCP port other than 5000.- This is useful if you want to run multiple hledger-web instances on a+ Similarly, you can use --port to listen on a TCP port other than 5000.+ This is useful if you want to run multiple hledger-web instances on a machine. --socket=SOCKETFILE- listen on the given unix socket instead of an IP address and+ listen on the given unix socket instead of an IP address and port (unix only; implies --serve) - When --socket is used, hledger-web creates and communicates via a- socket file instead of a TCP port. This can be more secure, respects+ When --socket is used, hledger-web creates and communicates via a+ socket file instead of a TCP port. This can be more secure, respects unix file permissions, and makes certain use cases easier, such as run- ning per-user instances behind an nginx reverse proxy. (Eg: proxy_pass http://unix:/tmp/hledger/${remote_user}.socket;.)@@ -98,28 +98,28 @@ --base-url=URL set the base url (default: http://IPADDR:PORT). - You can use --base-url to change the protocol, hostname, port and path- that appear in hledger-web's hyperlinks. This is useful eg when inte-- grating hledger-web within a larger website. The default is- http://HOST:PORT/ using the server's configured host address and TCP- port (or http://HOST if PORT is 80). Note this affects url generation+ You can use --base-url to change the protocol, hostname, port and path+ that appear in hledger-web's hyperlinks. This is useful eg when inte-+ grating hledger-web within a larger website. The default is+ http://HOST:PORT/ using the server's configured host address and TCP+ port (or http://HOST if PORT is 80). Note this affects url generation but not route parsing. - --test run hledger-web's tests and exit. hspec test runner args may+ --test run hledger-web's tests and exit. hspec test runner args may follow a --, eg: hledger-web --test -- --help hledger-web also supports many of hledger's general options. Query op-- tions and arguments may be used to set an initial filter, which al-- though not shown in the UI, will restrict the data shown, in addition+ tions and arguments may be used to set an initial filter, which al-+ though not shown in the UI, will restrict the data shown, in addition to any search query entered in the UI. - Note that hledger-web shows accounts with zero balances by default,- like hledger-ui (and unlike hledger). Using the -E/--empty flag at+ Note that hledger-web shows accounts with zero balances by default,+ like hledger-ui (and unlike hledger). Using the -E/--empty flag at startup will hide them. - If you see accounts which appear to have a zero balance, but cannot be- hidden with -E: these have a mixed-cost balance which looks like zero- when costs are hidden. Currently hledger-web does not show costs at+ If you see accounts which appear to have a zero balance, but cannot be+ hidden with -E: these have a mixed-cost balance which looks like zero+ when costs are hidden. Currently hledger-web does not show costs at all. General help options@@ -142,7 +142,7 @@ $LEDGER_FILE or $HOME/.hledger.journal) --rules-file=RULESFILE- Conversion rules file to use when reading CSV (default:+ Conversion rules file to use when reading CSV (default: FILE.rules) --separator=CHAR@@ -159,7 +159,7 @@ assignments) -s --strict- do extra error checking (check that all posted accounts are de-+ do extra error checking (check that all posted accounts are de- clared) General reporting options@@ -187,7 +187,7 @@ multiperiod/multicolumn report by year -p --period=PERIODEXP- set start date, end date, and/or reporting interval all at once+ set start date, end date, and/or reporting interval all at once using period expressions syntax --date2@@ -195,7 +195,7 @@ fects) --today=DATE- override today's date (affects relative smart dates, for+ override today's date (affects relative smart dates, for tests/examples) -U --unmarked@@ -214,21 +214,21 @@ hide/aggregate accounts or postings more than NUM levels deep -E --empty- show items with zero amount, normally hidden (and vice-versa in+ 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-+ 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+ convert amounts to cost or market value, more flexibly than -B/-V/-X --infer-equity@@ -238,38 +238,38 @@ infer costs from conversion equity postings --infer-market-prices- use costs as additional market prices, as if they were P direc-+ use costs as additional market prices, as if they were P direc- tives --forecast- generate transactions from periodic rules, between the latest- recorded txn and 6 months from today, or during the specified- PERIOD (= is required). Auto posting rules will be applied to- these transactions as well. Also, in hledger-ui make fu-+ generate transactions from periodic rules, between the latest+ recorded txn and 6 months from today, or during the specified+ PERIOD (= is required). Auto posting rules will be applied to+ these transactions as well. Also, in hledger-ui make fu- ture-dated transactions visible. - --auto generate extra postings by applying auto posting rules to all+ --auto generate extra postings by applying auto posting rules to all txns (not just forecast txns) --verbose-tags- add visible tags indicating transactions or postings which have+ add visible tags indicating transactions or postings which have been generated/modified --commodity-style- Override the commodity style in the output for the specified+ Override the commodity style in the output for the specified commodity. For example 'EUR1.000,00'. --color=WHEN (or --colour=WHEN)- Should color-supporting commands use ANSI color codes in text+ 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+ when piping output into 'less -R'. 'never' or 'no': never. A NO_COLOR environment variable overrides this. --pretty[=WHEN]- Show prettier output, e.g. using unicode box-drawing charac-- ters. Accepts 'yes' (the default) or 'no' ('y', 'n', 'always',- 'never' also work). If you provide an argument you must use+ Show prettier output, e.g. using unicode box-drawing charac-+ ters. Accepts 'yes' (the default) or 'no' ('y', 'n', 'always',+ 'never' also work). If you provide an argument you must use '=', e.g. '--pretty=yes'. When a reporting option appears more than once in the command line, the@@ -278,13 +278,13 @@ Some reporting options can also be written as query arguments. PERMISSIONS- By default, hledger-web allows anyone who can reach it to view the+ By default, hledger-web allows anyone who can reach it to view the journal and to add new transactions, but not to change existing data. You can restrict who can reach it by - o setting the IP address it listens on (see --host above). By default- it listens on 127.0.0.1, accessible to all users on the local ma-+ o setting the IP address it listens on (see --host above). By default+ it listens on 127.0.0.1, accessible to all users on the local ma- chine. o putting it behind an authenticating proxy, using eg apache or nginx@@ -294,44 +294,44 @@ You can restrict what the users who reach it can do, by o using the --capabilities=CAP[,CAP..] flag when you start it, enabling- one or more of the following capabilities. The default value is+ one or more of the following capabilities. The default value is view,add: o view - allows viewing the journal file and all included files o add - allows adding new transactions to the main journal file - o manage - allows editing, uploading or downloading the main or in-+ o manage - allows editing, uploading or downloading the main or in- cluded files - o using the --capabilities-header=HTTPHEADER flag to specify a HTTP- header from which it will read capabilities to enable. hledger-web- on Sandstorm uses the X-Sandstorm-Permissions header to integrate+ o using the --capabilities-header=HTTPHEADER flag to specify a HTTP+ header from which it will read capabilities to enable. hledger-web+ on Sandstorm uses the X-Sandstorm-Permissions header to integrate with Sandstorm's permissions. This is disabled by default. EDITING, UPLOADING, DOWNLOADING- If you enable the manage capability mentioned above, you'll see a new- "spanner" button to the right of the search form. Clicking this will- let you edit, upload, or download the journal file or any files it in-+ If you enable the manage capability mentioned above, you'll see a new+ "spanner" button to the right of the search form. Clicking this will+ let you edit, upload, or download the journal file or any files it in- cludes. - Note, unlike any other hledger command, in this mode you (or any visi-+ Note, unlike any other hledger command, in this mode you (or any visi- tor) can alter or wipe the data files. - Normally whenever a file is changed in this way, hledger-web saves a- numbered backup (assuming file permissions allow it, the disk is not- full, etc.) hledger-web is not aware of version control systems, cur-- rently; if you use one, you'll have to arrange to commit the changes+ Normally whenever a file is changed in this way, hledger-web saves a+ numbered backup (assuming file permissions allow it, the disk is not+ full, etc.) hledger-web is not aware of version control systems, cur-+ rently; if you use one, you'll have to arrange to commit the changes yourself (eg with a cron job or a file watcher like entr). - Changes which would leave the journal file(s) unparseable or non-valid- (eg with failing balance assertions) are prevented. (Probably. This+ Changes which would leave the journal file(s) unparseable or non-valid+ (eg with failing balance assertions) are prevented. (Probably. This needs re-testing.) RELOADING hledger-web detects changes made to the files by other means (eg if you- edit it directly, outside of hledger-web), and it will show the new- data when you reload the page or navigate to a new page. If a change+ edit it directly, outside of hledger-web), and it will show the new+ data when you reload the page or navigate to a new page. If a change makes a file unparseable, hledger-web will display an error message un- til the file has been fixed. @@ -339,8 +339,8 @@ that both machine clocks are roughly in step.) JSON API- In addition to the web UI, hledger-web also serves a JSON API that can- be used to get data or add new transactions. If you want the JSON API+ In addition to the web UI, hledger-web also serves a JSON API that can+ be used to get data or add new transactions. If you want the JSON API only, you can use the --serve-api flag. Eg: $ hledger-web -f examples/sample.journal --serve-api@@ -357,7 +357,7 @@ /accounttransactions/ACCOUNTNAME Eg, all account names in the journal (similar to the accounts command).- (hledger-web's JSON does not include newlines, here we use python to+ (hledger-web's JSON does not include newlines, here we use python to prettify it): $ curl -s http://127.0.0.1:5000/accountnames | python -m json.tool@@ -398,25 +398,25 @@ "aprice": null, ... - Most of the JSON corresponds to hledger's data types; for details of- what the fields mean, see the Hledger.Data.Json haddock docs and click- on the various data types, eg Transaction. And for a higher level un-+ Most of the JSON corresponds to hledger's data types; for details of+ what the fields mean, see the Hledger.Data.Json haddock docs and click+ on the various data types, eg Transaction. And for a higher level un- derstanding, see the journal docs. In some cases there is outer JSON corresponding to a "Report" type. To- understand that, go to the Hledger.Web.Handler.MiscR haddock and look- at the source for the appropriate handler to see what it returns. Eg+ understand that, go to the Hledger.Web.Handler.MiscR haddock and look+ at the source for the appropriate handler to see what it returns. Eg for /accounttransactions it's getAccounttransactionsR, returning a "ac-- countTransactionsReport ...". Looking up the haddock for that we can- see that /accounttransactions returns an AccountTransactionsReport,- which consists of a report title and a list of AccountTransactionsRe-+ countTransactionsReport ...". Looking up the haddock for that we can+ see that /accounttransactions returns an AccountTransactionsReport,+ which consists of a report title and a list of AccountTransactionsRe- portItem (etc). - You can add a new transaction to the journal with a PUT request to- /add, if hledger-web was started with the add capability (enabled by+ You can add a new transaction to the journal with a PUT request to+ /add, if hledger-web was started with the add capability (enabled by default). The payload must be the full, exact JSON representation of a- hledger transaction (partial data won't do). You can get sample JSON- from hledger-web's /transactions or /accounttransactions, or you can+ hledger transaction (partial data won't do). You can get sample JSON+ from hledger-web's /transactions or /accounttransactions, or you can export it with hledger-lib, eg like so: .../hledger$ stack ghci hledger-lib@@ -512,28 +512,28 @@ "tstatus": "Unmarked" } - And here's how to test adding it with curl. This should add a new en-+ And here's how to test adding it with curl. This should add a new en- try to your journal: $ curl http://127.0.0.1:5000/add -X PUT -H 'Content-Type: application/json' --data-binary @txn.json DEBUG OUTPUT Debug output- You can add --debug[=N] to the command line to log debug output. N+ You can add --debug[=N] to the command line to log debug output. N ranges from 1 (least output, the default) to 9 (maximum output). Typi-- cally you would start with 1 and increase until you are seeing enough.- Debug output goes to stderr, interleaved with the requests logged on+ cally you would start with 1 and increase until you are seeing enough.+ Debug output goes to stderr, interleaved with the requests logged on stdout. To capture debug output in a log file instead, you can usually redirect stderr, eg: hledger-web --debug=3 2>hledger-web.log. ENVIRONMENT- LEDGER_FILE The main journal file to use when not specified with+ LEDGER_FILE The main journal file to use when not specified with -f/--file. Default: $HOME/.hledger.journal. BUGS We welcome bug reports in the hledger issue tracker (shortcut:- http://bugs.hledger.org), or on the #hledger chat or hledger mail list+ http://bugs.hledger.org), or on the #hledger chat or hledger mail list (https://hledger.org/support). Some known issues:@@ -558,4 +558,4 @@ SEE ALSO hledger(1), hledger-ui(1), hledger-web(1), ledger(1) -hledger-web-1.33 April 2024 HLEDGER-WEB(1)+hledger-web-1.33.1 May 2024 HLEDGER-WEB(1)
embeddedfiles/hledger.1 view
@@ -1,6 +1,6 @@ .\"t -.TH "HLEDGER" "1" "April 2024" "hledger-1.33 " "hledger User Manuals"+.TH "HLEDGER" "1" "May 2024" "hledger-1.33.1 " "hledger User Manuals" @@ -23,7 +23,7 @@ hledger is inspired by and largely compatible with ledger(1), and largely interconvertible with beancount(1). .PP-This manual is for hledger\[aq]s command line interface, version 1.33.+This manual is for hledger\[aq]s command line interface, version 1.33.1. It also describes the common options, file formats and concepts used by all hledger programs. It might accidentally teach you some bookkeeping/accounting as well!
embeddedfiles/hledger.info view
@@ -23,11811 +23,11811 @@ and largely compatible with ledger(1), and largely interconvertible with beancount(1). - This manual is for hledger's command line interface, version 1.33.-It also describes the common options, file formats and concepts used by-all hledger programs. It might accidentally teach you some-bookkeeping/accounting as well! You don't need to know everything in-here to use hledger productively, but when you have a question about-functionality, this doc should answer it. It is detailed, so do skip-ahead or skim when needed. You can read it on hledger.org, or as an-info manual or man page on your system. You can also get it from-hledger itself with-'hledger --man', 'hledger --info' or 'hledger help [TOPIC]'.-- The main function of the hledger CLI is to read plain text files-describing financial transactions, crunch the numbers, and print a-useful report on the terminal (or save it as HTML, CSV, JSON or SQL).-Many reports are available, as subcommands. hledger will also detect-other 'hledger-*' executables as extra subcommands.-- hledger usually reads from (and appends to) a journal file specified-by the 'LEDGER_FILE' environment variable (defaulting to-'$HOME/.hledger.journal'); or you can specify files with '-f' options.-It can also read timeclock files, timedot files, or any CSV/SSV/TSV file-with a date field.-- Here is a small journal file describing one transaction:--2015-10-16 bought food- expenses:food $10- assets:cash-- Transactions are dated movements of money (etc.) between two or more-_accounts_: bank accounts, your wallet, revenue/expense categories,-people, etc. You can choose any account names you wish, using ':' to-indicate subaccounts. There must be at least two spaces between account-name and amount. Positive amounts are inflow to that account (_debit_),-negatives are outflow from it (_credit_). (Some reports show revenue,-liability and equity account balances as negative numbers as a result;-this is normal.)-- hledger's add command can help you add transactions, or you can-install other data entry UIs like hledger-web or hledger-iadd. For more-extensive/efficient changes, use a text editor: Emacs + ledger-mode, VIM-+ vim-ledger, or VS Code + hledger-vscode are some good choices (see-https://hledger.org/editors.html).-- To get started, run 'hledger add' and follow the prompts, or save-some entries like the above in '$HOME/.hledger.journal', then try-commands like:--$ hledger print -x-$ hledger aregister assets-$ hledger balance-$ hledger balancesheet-$ hledger incomestatement-- Run 'hledger' to list the commands. See also the "Starting a journal-file" and "Setting opening balances" sections in PART 5: COMMON TASKS.--* Menu:--* PART 1 USER INTERFACE::-* Input::-* Commands::-* Options::-* Command line tips::-* Output::-* Environment::-* PART 2 DATA FORMATS::-* Journal::-* CSV::-* Timeclock::-* Timedot::-* PART 3 REPORTING CONCEPTS::-* Amount formatting::-* Time periods::-* Depth::-* Queries::-* Pivoting::-* Generating data::-* Forecasting::-* Budgeting::-* Cost reporting::-* Value reporting::-* PART 4 COMMANDS::-* PART 5 COMMON TASKS::-* BUGS::---File: hledger.info, Node: PART 1 USER INTERFACE, Next: Input, Prev: Top, Up: Top--1 PART 1: USER INTERFACE-************************---File: hledger.info, Node: Input, Next: Commands, Prev: PART 1 USER INTERFACE, Up: Top--2 Input-*******--hledger reads one or more data files, each time you run it. You can-specify a file with '-f', like so--$ hledger -f FILE print-- Files are most often in hledger's journal format, with the '.journal'-file extension ('.hledger' or '.j' also work); these files describe-transactions, like an accounting general journal.-- When no file is specified, hledger looks for '.hledger.journal' in-your home directory.-- But most people prefer to keep financial files in a dedicated folder,-perhaps with version control. Also, starting a new journal file each-year is common (it's not required, but helps keep things fast and-organised). So we usually configure a different journal file, by-setting the 'LEDGER_FILE' environment variable, to something like-'~/finance/2023.journal'. For more about how to do that on your system,-see Common tasks > Setting LEDGER_FILE.--* Menu:--* Text encoding::-* Data formats::-* Standard input::-* Multiple files::-* Strict mode::---File: hledger.info, Node: Text encoding, Next: Data formats, Up: Input--2.1 Text encoding-=================--Data files containing non-ascii characters must use UTF-8 encoding. An-optional byte order mark (BOM) is allowed, at the beginning of the file-(only).-- Also, your system should be configured with a locale that can decode-UTF-8 text. On some unix systems, you may need set the 'LANG'-environment variable, eg. You can read more about this in Unicode-characters, below.-- On unix systems you can check a file's encoding with the 'file'-command. If you need to import from a UTF-16-encoded CSV file, say, you-can convert it to UTF-8 with the 'iconv' command.---File: hledger.info, Node: Data formats, Next: Standard input, Prev: Text encoding, Up: Input--2.2 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: Automatically used for- files with extensions:-----------------------------------------------------------------------------'journal' hledger journal files and some '.journal' '.j'- Ledger journals, for '.hledger' '.ledger'- transactions-'timeclock' timeclock files, for precise '.timeclock'- time logging-'timedot' timedot files, for approximate '.timedot'- time logging-'csv' Comma or other character '.csv'- separated values, for data- import-'ssv' Semicolon separated values '.ssv'-'tsv' Tab separated values '.tsv'-'rules' CSV/SSV/TSV/other separated '.rules'- values, alternate way-- These formats are described in more detail below.-- hledger detects the format automatically based on the file extensions-shown above. If it can't recognise the file extension, it assumes-'journal' format. So for non-journal files, it's important to use a-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 containing-tab separated values:--$ hledger -f tsv:/some/file.dat stats---File: hledger.info, Node: Standard input, Next: Multiple files, Prev: Data formats, Up: Input--2.3 Standard input-==================--The file name '-' means standard input:--$ cat FILE | hledger -f- print-- If reading non-journal data in this way, you'll need to add a file-format prefix, like:--$ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:----File: hledger.info, Node: Multiple files, Next: Strict mode, Prev: Standard input, Up: Input--2.4 Multiple files-==================--You can specify multiple '-f' options, to read multiple files as one big-journal. When doing this, note that certain features (described below)-will be affected:-- * Balance assertions will not see the effect of transactions in- previous files. (Usually this doesn't matter as each file will set- the corresponding opening balances.)- * Some directives will not affect previous or subsequent files.-- If needed, you can work around these by using a single parent file-which includes the others, or concatenating the files into one, eg: 'cat-a.journal b.journal | hledger -f- CMD'.---File: hledger.info, Node: Strict mode, Prev: Multiple files, Up: Input--2.5 Strict mode-===============--hledger checks input files for valid data. By default, the most-important errors are detected, while still accepting easy journal files-without a lot of declarations:-- * Are the input files parseable, with valid syntax ?- * Are all transactions balanced ?- * Do all balance assertions pass ?-- With the '-s'/'--strict' flag, additional checks are performed:-- * Are all accounts posted to, declared with an 'account' directive ?- (Account error checking)- * Are all commodities declared with a 'commodity' directive ?- (Commodity error checking)- * Are all commodity conversions declared explicitly ?-- You can use the check command to run individual checks - the ones-listed above and some more.---File: hledger.info, Node: Commands, Next: Options, Prev: Input, Up: Top--3 Commands-**********--hledger provides various subcommands for getting things done. Most of-these commands do not change the journal file; they just read it and-output a report. A few commands assist with adding data and file-management.-- To show the commands list, run 'hledger' with no arguments. The-commands are described in detail in PART 4: COMMANDS, below.-- To use a particular command, run 'hledger CMD [CMDOPTS] [CMDARGS]',-- * CMD is the full command name, or its standard abbreviation shown in- the commands list, or any unambiguous prefix of the name.-- * CMDOPTS are command-specific options, if any. Command-specific- options must be written after the command name. Eg: 'hledger print- -x'.-- * CMDARGS are additional arguments to the command, if any. Most- hledger commands accept arguments representing a query, to limit- the data in some way. Eg: 'hledger reg assets:checking'.-- To list a command's options, arguments, and documentation in the-terminal, run 'hledger CMD -h'. Eg: 'hledger bal -h'.--* Menu:--* Add-on commands::---File: hledger.info, Node: Add-on commands, Up: Commands--3.1 Add-on commands-===================--In addition to the built-in commands, you can install _add-on commands_:-programs or scripts named "hledger-SOMETHING", which will also appear in-hledger's commands list. If you used the hledger-install script, you-will have several add-ons installed already. Some more can be found in-hledger's bin/ directory, documented at-https://hledger.org/scripts.html.-- More precisely, add-on commands are programs or scripts in your-shell's PATH, whose name starts with "hledger-" and ends with no-extension or a recognised extension (".bat", ".com", ".exe", ".hs",-".js", ".lhs", ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"),-and (on unix and mac) which has executable permission for the current-user.-- You can run add-on commands using hledger, much like built-in-commands: 'hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]'. But note-the double hyphen argument, required before add-on-specific options.-Eg: 'hledger ui -- --watch' or 'hledger web -- --serve'. If this causes-difficulty, you can always run the add-on directly, without using-'hledger': 'hledger-ui --watch' or 'hledger-web --serve'.---File: hledger.info, Node: Options, Next: Command line tips, Prev: Commands, Up: Top--4 Options-*********--Run 'hledger -h' to see general command line help, and general options-which are common to most hledger commands. These options can be written-anywhere on the command line. They can be grouped into help, input, and-reporting options:--* Menu:--* General help options::-* General input options::-* General reporting options::---File: hledger.info, Node: General help options, Next: General input options, Up: Options--4.1 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)---File: hledger.info, Node: General input options, Next: General reporting options, Prev: General help options, Up: Options--4.2 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-'--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)---File: hledger.info, Node: General reporting options, Prev: General input options, Up: Options--4.3 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- following 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)-'--today=DATE'-- override today's date (affects relative smart dates, for- tests/examples)-'-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- commodities-'-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-equity'-- infer conversion equity postings from costs-'--infer-costs'-- infer costs from conversion equity postings-'--infer-market-prices'-- use costs as additional market prices, as if they were P directives-'--forecast'-- generate transactions from periodic rules, between the latest- recorded txn and 6 months from today, or during the specified- PERIOD (= is required). Auto posting rules will be applied to- these transactions as well. Also, in hledger-ui make future-dated- transactions visible.-'--auto'-- generate extra postings by applying auto posting rules to all txns- (not just forecast txns)-'--verbose-tags'-- add visible tags indicating transactions or postings which have- been generated/modified-'--commodity-style'-- Override the commodity style in the output for the specified- commodity. For example 'EUR1.000,00'.-'--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.-'--pretty[=WHEN]'-- Show prettier output, e.g. using unicode box-drawing characters.- Accepts 'yes' (the default) or 'no' ('y', 'n', 'always', 'never'- also work). If you provide an argument you must use '=', e.g.- '-pretty=yes'.-- 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.---File: hledger.info, Node: Command line tips, Next: Output, Prev: Options, Up: Top--5 Command line tips-*******************--Here are some details useful to know about for hledger command lines-(and elsewhere). Feel free to skip this section until you need it.--* Menu:--* Option repetition::-* Special characters::-* Unicode characters::-* Regular expressions::-* Argument files::---File: hledger.info, Node: Option repetition, Next: Special characters, Up: Command line tips--5.1 Option repetition-=====================--If options are repeated in a command line, hledger will generally use-the last (right-most) occurence.---File: hledger.info, Node: Special characters, Next: Unicode characters, Prev: Option repetition, Up: Command line tips--5.2 Special characters-======================--* Menu:--* Single escaping shell metacharacters::-* Double escaping regular expression metacharacters::-* Triple escaping for add-on commands::-* Less escaping::---File: hledger.info, Node: Single escaping shell metacharacters, Next: Double escaping regular expression metacharacters, Up: Special characters--5.2.1 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 double 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.---File: hledger.info, Node: Double escaping regular expression metacharacters, Next: Triple escaping for add-on commands, Prev: Single escaping shell metacharacters, Up: Special characters--5.2.2 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:\\$---File: hledger.info, Node: Triple escaping for add-on commands, Next: Less escaping, Prev: Double escaping regular expression metacharacters, Up: Special characters--5.2.3 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-arguments intended for by the add-on command, so those need an extra-level of shell-escaping. Eg to match a literal '$' sign while using the-bash shell and running an add-on command ('ui'):--$ hledger ui cur:'\\$'-- or:--$ hledger ui cur:\\\\$-- If you wondered why _four_ backslashes, perhaps this helps:--unescaped: '$'-escaped: '\$'-double-escaped: '\\$'-triple-escaped: '\\\\$'-- Or, you can avoid the extra escaping by running the add-on executable-directly:--$ hledger-ui cur:\\$---File: hledger.info, Node: Less escaping, Prev: Triple escaping for add-on commands, Up: Special characters--5.2.4 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:-- * an @argumentfile- * hledger-ui's filter field- * hledger-web's search form- * GHCI's prompt (used by developers).---File: hledger.info, Node: Unicode characters, Next: Regular expressions, Prev: Special characters, Up: Command line tips--5.3 Unicode characters-======================--hledger is expected to handle non-ascii characters correctly:-- * 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.)-- * 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:-- * 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 Troubleshooting. This step is essential - without it, hledger- will quit on encountering a non-ascii character (as with all- GHC-compiled programs).-- * your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)- must support unicode-- * the terminal must be using a font which includes the required- unicode glyphs-- * the terminal should be configured to display wide characters as- double width (for report alignment)-- * on Windows, for best results you should run hledger in the same- kind of environment in which it was built. Eg hledger built in the- standard CMD.EXE environment (like the binaries on our download- page) might show display problems when run in a cygwin or msys- terminal, and vice versa. (See eg #961).---File: hledger.info, Node: Regular expressions, Next: Argument files, Prev: Unicode characters, Up: Command line tips--5.4 Regular expressions-=======================--A regular expression (regexp) is a small piece of text where certain-characters (like '.', '^', '$', '+', '*', '()', '|', '[]', '\') have-special meanings, forming a tiny language for matching text precisely --very useful in hledger and elsewhere. To learn all about them, visit-regular-expressions.info.-- hledger supports regexps whenever you are entering a pattern to match-something, eg in query arguments, account aliases, CSV if rules,-hledger-web's search form, hledger-ui's '/' search, etc. You may need-to wrap them in quotes, especially at the command line (see Special-characters above). Here are some examples:-- Account name queries (quoted for command line use):--Regular expression: Matches:-------------------- -------------------------------------------------------------bank assets:bank, assets:bank:savings, expenses:art:banksy, ...-:bank assets:bank:savings, expenses:art:banksy-:bank: assets:bank:savings-'^bank' none of those ( ^ matches beginning of text )-'bank$' assets:bank ( $ matches end of text )-'big \$ bank' big $ bank ( \ disables following character's special meaning )-'\bbank\b' assets:bank, assets:bank:savings ( \b matches word boundaries )-'(sav|check)ing' saving or checking ( (|) matches either alternative )-'saving|checking' saving or checking ( outer parentheses are not needed )-'savings?' saving or savings ( ? matches 0 or 1 of the preceding thing )-'my +bank' my bank, my bank, ... ( + matches 1 or more of the preceding thing )-'my *bank' mybank, my bank, my bank, ... ( * matches 0 or more of the preceding thing )-'b.nk' bank, bonk, b nk, ... ( . matches any character )-- Some other queries:--desc:'amazon|amzn|audible' Amazon transactions-cur:EUR amounts with commodity symbol containing EUR-cur:'\$' amounts with commodity symbol containing $-cur:'^\$$' only $ amounts, not eg AU$ or CA$-cur:....? amounts with 4-or-more-character symbols-tag:.=202[1-3] things with any tag whose value contains 2021, 2022 or 2023-- Account name aliases: accept '.' instead of ':' as account separator:--alias /\./=: replaces all periods in account names with colons-- Show multiple top-level accounts combined as one:----alias='/^[^:]+/=combined' ( [^:] matches any character other than : )-- Show accounts with the second-level part removed:----alias '/^([^:]+):[^:]+/ = \1'- match a top-level account and a second-level account- and replace those with just the top-level account- ( \1 in the replacement text means "whatever was matched- by the first parenthesised part of the regexp"-- CSV rules: match CSV records containing dining-related MCC codes:--if \?MCC581[124]-- Match CSV records with a specific amount around the end/start of-month:--if %amount \b3\.99-& %date (29|30|31|01|02|03)$--* Menu:--* hledger's regular expressions::---File: hledger.info, Node: hledger's regular expressions, Up: Regular expressions--5.4.1 hledger's regular expressions--------------------------------------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. backreferences are supported when doing text replacement in account- aliases or CSV rules, where backreferences can be used in the- replacement string to reference capturing groups in the search- regexp. Otherwise, if you write '\1', it will match the digit '1'.- 6. they do not support mode modifiers ('(?s)'), character classes- ('\w', '\d'), or anything else not mentioned above.-- Some things to note:-- * In the 'alias' directive and '--alias' option, regular expressions- must be enclosed in forward slashes ('/REGEX/'). Elsewhere in- hledger, these are not required.-- * 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:\$'.-- * On the command line, some metacharacters like '$' have a special- meaning to the shell and so must be escaped at least once more.- See Special characters.---File: hledger.info, Node: Argument files, Prev: Regular expressions, Up: Command line tips--5.5 Argument files-==================--You can save a set of command line options and arguments in a file, and-then reuse them by writing '@FILENAME' as a command line argument. Eg:-'hledger bal @foo.args'.-- Inside the argument file, each line should contain just one option or-argument. Don't use spaces except inside quotes (or you'll see a-confusing error); write '=' (or nothing) between a flag and its-argument. For the special characters mentioned above, use one less-level of quoting than you would at the command prompt.---File: hledger.info, Node: Output, Next: Environment, Prev: Command line tips, Up: Top--6 Output-********--* Menu:--* Output destination::-* Output format::-* Commodity styles::-* Colour::-* Box-drawing::-* Paging::-* Debug output::---File: hledger.info, Node: Output destination, Next: Output format, Up: Output--6.1 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-provide 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)---File: hledger.info, Node: Output format, Next: Commodity styles, Prev: Output destination, Up: Output--6.2 Output format-=================--Some commands offer other kinds of output, not just text on the-terminal. Here are those commands and the formats currently supported:--- txt csv/tsv html json sql---------------------------------------------------------------------------------aregister Y Y Y Y-balance Y _1_ Y _1_ Y _1,2_ Y-balancesheet Y _1_ Y _1_ Y _1_ Y-balancesheetequityY _1_ Y _1_ Y _1_ Y-cashflow Y _1_ Y _1_ Y _1_ Y-incomestatement Y _1_ Y _1_ Y _1_ Y-print Y Y Y Y-register Y Y Y-- * _1 Also affected by the balance commands' '--layout' option._- * _2 'balance' does not support html output without a report interval- or with '--budget'._-- The output format is selected by the '-O/--output-format=FMT' option:--$ hledger print -O csv # print CSV on stdout-- or by the filename extension of an output file specified with the-'-o/--output-file=FILE.FMT' option:--$ hledger balancesheet -o foo.csv # write CSV to foo.csv-- The '-O' option can be combined with '-o' to override the file-extension, if needed:--$ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt-- Some notes about the various output formats:--* Menu:--* CSV output::-* HTML output::-* JSON output::-* SQL output::---File: hledger.info, Node: CSV output, Next: HTML output, Up: Output format--6.2.1 CSV output------------------- * In CSV output, digit group marks (such as thousands separators) are- disabled automatically.---File: hledger.info, Node: HTML output, Next: JSON output, Prev: CSV output, Up: Output format--6.2.2 HTML output-------------------- * HTML output can be styled by an optional 'hledger.css' file in the- same directory.---File: hledger.info, Node: JSON output, Next: SQL output, Prev: HTML output, Up: Output format--6.2.3 JSON output-------------------- * This is not yet much used; real-world feedback is welcome.-- * Our JSON is rather large and verbose, since it is a faithful- representation 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.-- * 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)---File: hledger.info, Node: SQL output, Prev: JSON output, Up: Output format--6.2.4 SQL output------------------- * This is not yet much used; real-world feedback is welcome.-- * SQL output is expected to work at least with SQLite, MySQL and- Postgres.-- * For SQLite, it will be more useful if you modify the generated 'id'- field to be a PRIMARY KEY. Eg:-- $ hledger print -O sql | sed 's/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g' | ...-- * SQL output is structured with the expectations that statements will- be executed in the empty database. If you already have tables- created via SQL output of hledger, you would probably want to- either clear tables of existing data (via 'delete' or 'truncate'- SQL statements) or drop tables completely as otherwise your- postings will be duped.---File: hledger.info, Node: Commodity styles, Next: Colour, Prev: Output format, Up: Output--6.3 Commodity styles-====================--When displaying amounts, hledger infers a standard display style for-each commodity/currency, as described below in Commodity display style.-- If needed, this can be overridden by a '-c/--commodity-style' option-(except for cost amounts and amounts displayed by the 'print' command,-which are always displayed with all decimal digits). For example, the-following will force dollar amounts to be displayed as shown:--$ hledger print -c '$1.000,0'-- This option can repeated to set the display style for multiple-commodities/currencies. Its argument is as described in the commodity-directive.-- In some cases hledger will adjust number formatting to improve their-parseability (such as adding trailing decimal marks when needed).---File: hledger.info, Node: Colour, Next: Box-drawing, Prev: Commodity styles, Up: Output--6.4 Colour-==========--In terminal output, some commands can produce colour when the terminal-supports it:-- * if the '--color/--colour' option is given a value of 'yes' or- 'always' (or 'no' or 'never'), colour will (or will not) be used;- * otherwise, if the 'NO_COLOR' environment variable is set, colour- will not be used;- * otherwise, colour will be used if the output (terminal or file)- supports it.---File: hledger.info, Node: Box-drawing, Next: Paging, Prev: Colour, Up: Output--6.5 Box-drawing-===============--In terminal output, you can enable unicode box-drawing characters to-render prettier tables:-- * if the '--pretty' option is given a value of 'yes' or 'always' (or- 'no' or 'never'), unicode characters will (or will not) be used;- * otherwise, unicode characters will not be used.---File: hledger.info, Node: Paging, Next: Debug output, Prev: Box-drawing, Up: Output--6.6 Paging-==========--When showing long output in the terminal, hledger will try to use the-pager specified by the 'PAGER' environment variable, or 'less', or-'more'. (A pager is a helper program that shows one page at a time-rather than scrolling everything off screen). Currently it does this-only for help output, not for reports; specifically,-- * when listing commands, with 'hledger'- * when showing help with 'hledger [CMD] --help',- * when viewing manuals with 'hledger help' or 'hledger --man'.-- Note the pager is expected to handle ANSI codes, which hledger uses-eg for bold emphasis. For the common pager 'less' (and its 'more'-compatibility mode), we add 'R' to the 'LESS' and 'MORE' environment-variables to make this work. If you use a different pager, you might-need to configure it similarly, to avoid seeing junk on screen (let us-know). Otherwise, you can set the 'NO_COLOR' environment variable to 1-to disable all ANSI output (see Colour).---File: hledger.info, Node: Debug output, Prev: Paging, Up: Output--6.7 Debug output-================--We intend hledger to be relatively easy to troubleshoot, introspect and-develop. You can add '--debug[=N]' to any hledger command line to see-additional debug output. N ranges from 1 (least output, the default) to-9 (maximum output). Typically you would start with 1 and increase until-you are seeing enough. Debug output goes to stderr, and is not affected-by '-o/--output-file' (unless you redirect stderr to stdout, eg:-'2>&1'). It will be interleaved with normal output, which can help-reveal when parts of the code are evaluated. To capture debug output in-a log file instead, you can usually redirect stderr, eg:--hledger bal --debug=3 2>hledger.log---File: hledger.info, Node: Environment, Next: PART 2 DATA FORMATS, Prev: Output, Up: Top--7 Environment-*************--These environment variables affect hledger:-- *COLUMNS* This is normally set by your terminal; some hledger-commands ('register') will format their output to this width. If not-set, they will try to use the available terminal width.-- *LEDGER_FILE* The main journal file to use when not specified with-'-f/--file'. Default: '$HOME/.hledger.journal'.-- *NO_COLOR* If this environment variable is set (with any value),-hledger will not use ANSI color codes in terminal output, unless-overridden by an explicit '--color/--colour' option.---File: hledger.info, Node: PART 2 DATA FORMATS, Next: Journal, Prev: Environment, Up: Top--8 PART 2: DATA FORMATS-**********************---File: hledger.info, Node: Journal, Next: CSV, Prev: PART 2 DATA FORMATS, Up: Top--9 Journal-*********--hledger's usual data source is a plain text file containing journal-entries in hledger 'journal' format. If you're looking for a quick-reference, jump ahead to the journal cheatsheet (or use the table of-contents at https://hledger.org/hledger.html).-- This file represents an accounting General Journal. The '.journal'-file extension is most often used, though not strictly 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 compatible with most of Ledger's journal-format, but not all of it. The differences and interoperation tips are-described at hledger and Ledger. With some care, and by avoiding-incompatible features, you can keep your hledger journal readable by-Ledger and vice versa. This can useful eg for comparing the behaviour-of one app against the other.-- 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-configuration at hledger.org for the full list.-- A hledger journal file can contain three kinds of thing: comment-lines, transactions, and/or directives (including periodic transaction-rules and auto posting rules). Understanding the journal file format-will also give you a good understanding of hledger's data model. Here's-a quick cheatsheet/overview, followed by detailed descriptions of each-part.--* Menu:--* Journal cheatsheet::-* Comments::-* Transactions::-* Dates::-* Status::-* Code::-* Description::-* Transaction comments::-* Postings::-* Account names::-* Amounts::-* Balance assertions::-* Posting comments::-* Transaction balancing::-* Tags::-* Directives::-* account directive::-* alias directive::-* commodity directive::-* decimal-mark directive::-* include directive::-* P directive::-* payee directive::-* tag directive::-* Periodic transactions::-* Auto postings::-* Other syntax::---File: hledger.info, Node: Journal cheatsheet, Next: Comments, Up: Journal--9.1 Journal cheatsheet-======================--# Here is the main syntax of hledger's journal format-# (omitting extra Ledger compatibility syntax).--###############################################################################--# 1. These are comment lines, for notes or temporarily disabling things.-; They begin with # or ;--comment-Or, lines can be enclosed within "comment" / "end comment".-This is a block of -commented lines.-end comment--# Some journal entries can have semicolon comments at end of line ; like this-# Some of them require 2 or more spaces before the semicolon.--###############################################################################--# 2. Directives customise processing or output in some way.-# You don't need any directives to get started.-# But they can add more error checking, or change how things are displayed.-# They begin with a word, letter, or symbol. -# They are most often placed at the top, before transactions.--account assets ; Declare valid account names and display order.-account assets:savings ; A subaccount. This one represents a bank account.-account assets:checking ; Another. Note, 2+ spaces after the account name.-account assets:receivable ; Accounting type is inferred from english names,-account passifs ; or declared with a "type" tag, type:L-account expenses ; type:X- ; A follow-on comment line, indented.-account expenses:rent ; Expense and revenue categories are also accounts.- ; Subaccounts inherit their parent's type.--commodity $0.00 ; Declare valid commodities and their display styles.-commodity 1.000,00 EUR--decimal-mark . ; The decimal mark used in this file (if ambiguous).--payee Whole Foods ; Declare a valid payee name.--tag trip ; Declare a valid tag name.--P 2024-03-01 AAPL $179 ; Declare a market price for AAPL in $ on this date.--include other.journal ; Include another journal file here.--# Declare a recurring "periodic transaction", for budget/forecast reports-~ monthly set budget goals ; <- Note, 2+ spaces before the description.- (expenses:rent) $1000- (expenses:food) $500--# Declare an auto posting rule, to modify existing transactions in reports-= revenues:consulting- liabilities:tax:2024:us *0.25 ; Add a tax liability & expense- expenses:tax:2024:us *-0.25 ; for 25% of the revenue.--###############################################################################--# 3. Transactions are what it's all about.-# They are dated events, usually movements of money between 2 or more accounts.-# They begin with a numeric date.-# Here is their basic shape:-#-# DATE DESCRIPTION ; The transaction's date and optional description.-# ACCOUNT1 AMOUNT ; A posting of an amount to/from this account, indented.-# ACCOUNT2 AMOUNT ; A second posting, balancing the first.-# ... ; More if needed. Amounts must sum to zero.-# ; Note, 2+ spaces between account names and amounts.--2024-01-01 opening balances ; At the start, declare pre-existing balances this way.- assets:savings $10000 ; Account names can be anything. lower case is easy to type.- assets:checking $1000 ; assets, liabilities, equity, revenues, expenses are common.- liabilities:credit card $-500 ; liabilities, equity, revenues balances are usually negative.- equity:start ; One amount can be left blank. $-10500 is inferred here.- ; Some of these accounts we didn't declare above,- ; so -s/--strict would complain.--2024-01-03 ! (12345) pay rent- ; Additional transaction comment lines, indented.- ; There can be a ! or * after the date meaning "pending" or "cleared".- ; There can be a parenthesised (code) after the date/status.- ; Amounts' sign shows direction of flow.- assets:checking $-500 ; Minus means removed from this account (credit).- expenses:rent $500 ; Plus means added to this account (debit).--; Keeping transactions in date order is optional (but helps error checking).--2024-01-02 Gringott's Bank | withdrawal ; Description can be PAYEE | NOTE- assets:bank:gold -10 gold- assets:pouch 10 gold--2024-01-02 shopping- expenses:clothing 1 gold- expenses:wands 5 gold- assets:pouch -6 gold--2024-01-02 receive gift- revenues:gifts -3 "Chocolate Frogs" ; Complex commodity symbols- assets:pouch 3 "Chocolate Frogs" ; must be in double quotes.--2024-01-15 buy some shares, in two lots ; Cost can be noted.- assets:investments:2024-01-15 2.0 AAAA @ $1.50 ; @ means per-unit cost- assets:investments:2024-01-15-02 3.0 AAAA @@ $4 ; @@ means total cost- ; ^ Per-lot subaccounts are sometimes useful.- assets:checking $-7--2024-01-15 assert some account balances on this date- ; Balances can be asserted in any transaction, with =, for extra error checking.- ; Assertion txns like this one can be made with hledger close --assert --show-costs- ;- assets:savings $0 = $10000- assets:checking $0 = $493- assets:bank:gold 0 gold = -10 gold- assets:pouch 0 gold = 4 gold- assets:pouch 0 "Chocolate Frogs" = 3 "Chocolate Frogs"- assets:investments:2024-01-15 0.0 AAAA = 2.0 AAAA @ $1.50- assets:investments:2024-01-15-02 0.0 AAAA = 3.0 AAAA @@ $4- liabilities:credit card $0 = $-500--2024-02-01 note some event, or a transaction not yet fully entered, on this date- ; Postings are not required.--; Some other date formats are allowed (but, consistent YYYY-MM-DD is useful).-2024.01.01-2024/1/1---File: hledger.info, Node: Comments, Next: Transactions, Prev: Journal cheatsheet, Up: Journal--9.2 Comments-============--Lines in the journal will be ignored if they begin with a hash ('#') or-a semicolon (';'). (See also Other syntax.) hledger will also ignore-regions beginning with a 'comment' line and ending with an 'end comment'-line (or file end). Here's a suggestion for choosing between them:-- * '#' for top-level notes- * ';' for commenting out things temporarily- * 'comment' for quickly commenting large regions (remember it's- there, or you might get confused)-- Eg:--# a comment line-; another commentline-comment-A multi-line comment block,-continuing until "end comment" directive-or the end of the current file.-end comment-- Some hledger entries can have same-line comments attached to them,-from ; (semicolon) to end of line. See Transaction comments, Posting-comments, and Account comments below.---File: hledger.info, Node: Transactions, Next: Dates, Prev: Comments, Up: Journal--9.3 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-simple date in column 0. This can be followed by any of the following-optional fields, separated by spaces:-- * a status character (empty, '!', or '*')- * a code (any short number or text, enclosed in parentheses)- * a description (any remaining text until end of line or a semicolon)- * a comment (any remaining text following a semicolon until end of- line, and any following indented lines beginning with a semicolon)- * 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---File: hledger.info, Node: Dates, Next: Status, Prev: Transactions, Up: Journal--9.4 Dates-=========--* Menu:--* Simple dates::-* Posting dates::---File: hledger.info, Node: Simple dates, Next: Posting dates, Up: Dates--9.4.1 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-current transaction, the default year set with a 'Y' 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.)---File: hledger.info, Node: Posting dates, Prev: Simple dates, Up: Dates--9.4.2 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.-The 'date:' tag must have a valid simple date value if it is present, eg-a 'date:' tag with no value is not allowed.---File: hledger.info, Node: Status, Next: Code, Prev: Dates, Up: Journal--9.5 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 (and you can combine these, eg-'-UP' to match all except cleared things). Or you can use the-'status:', 'status:!', and 'status:*' queries, or the U, P, C keys in-hledger-ui.-- (Note: in Ledger the "unmarked" state is called "uncleared"; in-hledger we renamed it to "unmarked" for semantic clarity.)-- Status marks are optional, but can be helpful eg for reconciling with-real-world accounts. Some editor modes provide highlighting and-shortcuts for working with status. Eg in Emacs ledger-mode, you can-toggle transaction status with C-c C-e, or posting status with C-c C-c.-- 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- reconciliation)-cleared complete, reconciled as far as possible, and considered- correct-- 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.---File: hledger.info, Node: Code, Next: Description, Prev: Status, Up: Journal--9.6 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.---File: hledger.info, Node: Description, Next: Transaction comments, Prev: Code, Up: Journal--9.7 Description-===============--After the date, status mark and/or code fields, the rest of the line (or-until a comment is begun with ';') is the transaction's description.-Here you can describe the transaction (called the "narration" in-traditional bookkeeping), or you can record a payee/payer name, or you-can leave it empty.-- Transaction descriptions show up in print output and in register-reports, and can be listed with the descriptions command.-- You can query by description with 'desc:DESCREGEX', or pivot on-description with '--pivot desc'.--* Menu:--* Payee and note::---File: hledger.info, Node: Payee and note, Up: Description--9.7.1 Payee and note-----------------------Sometimes people want a dedicated payee/payer field that can be queried-and checked more strictly. If you want that, you can write a '|' (pipe)-character in the description. This divides it into a "payee" field on-the left, and a "note" field on the right. (Either can be empty.)-- You can query these with 'payee:PAYEEREGEX' and 'note:NOTEREGEX',-list their values with the payees and notes commands, or pivot on-'payee' or 'note'.-- Note: in transactions with no '|' character, description, payee, and-note all have the same value. Once a '|' is added, they become-distinct. (If you'd like to change this behaviour, please propose it on-the mail list.)-- If you want more strict error checking, you can declare the valid-payee names with payee directives, and then enforce these with hledger-check payees. (Note: because of the above, for this you'll need to-ensure every transaction description contains a '|' and therefore a-checkable payee name, even if it's empty.)---File: hledger.info, Node: Transaction comments, Next: Postings, Prev: Description, Up: Journal--9.8 Transaction comments-========================--Text following ';', after a transaction description, and/or on indented-lines immediately below it, form comments for that transaction. They-are reproduced by 'print' but otherwise ignored, except they may contain-tags, which are not ignored.--2012-01-01 something ; a transaction comment- ; a second line of transaction comment- expenses 1- assets---File: hledger.info, Node: Postings, Next: Account names, Prev: Transaction comments, Up: Journal--9.9 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:-- * (optional) a status character (empty, '!', or '*'), followed by a- space- * (required) an account name (any text, optionally containing *single- spaces*, until end of line or a double space)- * (optional) *two or more spaces* (or tabs) followed by an amount.-- If the amount is positive, it is being added to the account; if-negative, it is being removed from the account.-- The posting amounts in a transaction must sum up to zero, indicating-that the inflows and outflows are equal. We call this a balanced-transaction. (You can read more about the nitty-gritty details of "sum-up to zero" in Transaction balancing below.)-- As a convenience, you can optionally leave one amount blank; hledger-will infer what it should be so as to balance the transaction.--* Menu:--* Debits and credits::-* The two space delimiter::---File: hledger.info, Node: Debits and credits, Next: The two space delimiter, Up: Postings--9.9.1 Debits and credits---------------------------The traditional accounting concepts of debit and credit of course exist-in hledger, but we represent them with numeric sign, as described above.-Positive and negative posting amounts represent debits and credits-respectively.-- You don't need to remember that, but if you would like to - eg for-helping newcomers or for talking with your accountant - here's a handy-mnemonic:-- _'debit / plus / left / short words'_-_'credit / minus / right / longer words'_---File: hledger.info, Node: The two space delimiter, Prev: Debits and credits, Up: Postings--9.9.2 The two space delimiter--------------------------------Be sure to notice the unusual separator between the account name and the-following amount. Because hledger allows account names with spaces in-them, you must separate the account name and amount (if any) by *two or-more spaces* (or tabs). It's easy to forget at first. If you ever see-the amount being treated as part of the account name, you'll know you-probably need to add another space between them.---File: hledger.info, Node: Account names, Next: Amounts, Prev: Postings, Up: Journal--9.10 Account names-==================--Accounts are the main way of categorising things in hledger. As in-Double Entry Bookkeeping, they can represent real world accounts (such-as a bank account), or more abstract categories such as "money borrowed-from Frank" or "money spent on electricity".-- You can use any account names you like, but we usually start with the-traditional accounting categories, which in english are 'assets',-'liabilities', 'equity', 'revenues', 'expenses'. (You might see these-referred to as A, L, E, R, X for short.)-- For more precise reporting, we usually divide the top level accounts-into more detailed subaccounts, by writing a full colon between account-name parts. For example, from the account names 'assets:bank:checking'-and 'expenses:food', hledger will infer this hierarchy of five accounts:--assets-assets:bank-assets:bank:checking-expenses-expenses:food-- Shown as an outline, the hierarchical tree structure is more clear:--assets- bank- checking-expenses- food-- hledger reports can summarise the account tree to any depth, so you-can go as deep as you like with subcategories, but keeping your account-names relatively simple may be best when starting out.-- Account names may be capitalised or not; they may contain letters,-numbers, symbols, or single spaces. Note, when an account name and an-amount are written on the same line, they must be separated by *two or-more spaces* (or tabs).-- Parentheses or brackets enclosing the full account name indicate-virtual postings, described below. Parentheses or brackets internal to-the account name have no special meaning.-- Account names can be altered temporarily or permanently by account-aliases.---File: hledger.info, Node: Amounts, Next: Balance assertions, Prev: Account names, Up: Journal--9.11 Amounts-============--After the account name, there is usually an amount. (Remember: 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-"quantity"):--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-commodity 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--* Menu:--* Decimal marks::-* Digit group marks::-* Commodity::-* Costs::---File: hledger.info, Node: Decimal marks, Next: Digit group marks, Up: Amounts--9.11.1 Decimal marks-----------------------A _decimal mark_ can be written as a period or a comma:--1.23-1,23-- Both of these are common in international number formats, so hledger-is not biased towards one or the other. Because hledger also supports-digit group marks (eg thousands separators), this means that a number-like '1,000' or '1.000' containing just one period or comma is-ambiguous. In such cases, hledger by default assumes it is a decimal-mark, and will parse both of those as 1.-- To help hledger parse such ambiguous numbers more accurately, if you-use digit group marks, we recommend declaring the decimal mark-explicitly. The best way is to add a 'decimal-mark' directive at the-top of each data file, like this:--decimal-mark .-- Or you can declare it per commodity with 'commodity' directives,-described below.-- hledger also accepts numbers like '10.' with no digits after the-decimal mark (and will sometimes display numbers that way to-disambiguate them - see Trailing decimal marks).---File: hledger.info, Node: Digit group marks, Next: Commodity, Prev: Decimal marks, Up: Amounts--9.11.2 Digit group marks---------------------------In the integer part of the amount quantity (left of the decimal mark),-groups of digits can optionally be separated by a _digit group mark_ - a-comma or period (whichever is not used as decimal mark), or a space-(several Unicode space variants, like no-break space, are also-accepted). So these are all valid amounts in a journal file:-- $1,000,000.00- EUR 2.000.000,00-INR 9,99,99,999.00- 1 000 000.00 ; <- ordinary space - 1 000 000.00 ; <- no-break space---File: hledger.info, Node: Commodity, Next: Costs, Prev: Digit group marks, Up: Amounts--9.11.3 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-punctuation), 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.-- By default, the format of amounts in the journal influences how-hledger displays them in output. This is explained in Commodity display-style below.---File: hledger.info, Node: Costs, Prev: Commodity, Up: Amounts--9.11.4 Costs---------------After a posting amount, you can note its cost (when buying) or selling-price (when selling) in another commodity, by writing either '@-UNITPRICE' or '@@ TOTALPRICE' after it. This indicates a conversion-transaction, where one commodity is exchanged for another.-- (You might also see this called "transaction price" in hledger docs,-discussions, or code; that term was directionally neutral and reminded-that it is a price specific to a transaction, but we now just call it-"cost", with the understanding that the transaction could be a purchase-or a sale.)-- Costs are usually written explicitly with '@' or '@@', but can also-be inferred automatically for simple multi-commodity transactions.-Note, if costs are inferred, the order of postings is significant; the-first posting will have a cost attached, in the commodity of the second.-- As an example, here are several ways to record purchases of a foreign-currency in hledger, using the cost notation either explicitly or-implicitly:-- 1. Write the price per unit, as '@ UNITPRICE' after the amount:-- 2009/1/1- assets:euros €100 @ $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 €100 @@ $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.- Note the effect of posting order: the price is added to first- posting, making it '€100 @@ $135', as in example 2:-- 2009/1/1- assets:euros €100 ; one hundred euros purchased- assets:dollars $-135 ; for $135-- Amounts can be converted to cost at report time using the '-B/--cost'-flag; this is discussed more in the Cost reporting section.-- Note that the cost normally should be a positive amount, though it's-not required to be. This can be a little confusing, see discussion at--infer-market-prices: market prices from transactions.---File: hledger.info, Node: Balance assertions, Next: Posting comments, Prev: Amounts, Up: Journal--9.12 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 protect 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, described below).--* Menu:--* Assertions and ordering::-* Assertions and multiple included files::-* Assertions and multiple -f files::-* Assertions and costs::-* Assertions and commodities::-* Assertions and subaccounts::-* Assertions and virtual postings::-* Assertions and auto postings::-* Assertions and precision::---File: hledger.info, Node: Assertions and ordering, Next: Assertions and multiple included files, Up: Balance assertions--9.12.1 Assertions and ordering---------------------------------hledger calculates and checks an account's balance assertions in date-order (and when there are multiple assertions on the same day, in parse-order). Note this is different from Ledger, which checks assertions-always in parse order, ignoring dates.-- This means in hledger you can freely reorder transactions, postings,-or files, and balance assertions will usually keep working. The-exception is when you reorder multiple postings on the same day, to the-same account, which have balance assertions; those will likely need-updating.---File: hledger.info, Node: Assertions and multiple included files, Next: Assertions and multiple -f files, Prev: Assertions and ordering, Up: Balance assertions--9.12.2 Assertions and multiple included files------------------------------------------------Multiple files included with the 'include' directive are processed as if-concatenated into one file, preserving their order and the posting order-within each file. It means that balance assertions in later files will-see balance from earlier files.-- And if you have multiple postings to an account on the same day,-split across multiple files, and you want to assert the account's-balance on that day, you'll need to put the assertion in the right file-- the last one in the sequence, probably.---File: hledger.info, Node: Assertions and multiple -f files, Next: Assertions and costs, Prev: Assertions and multiple included files, Up: Balance assertions--9.12.3 Assertions and multiple -f files------------------------------------------Unlike 'include', when multiple files are specified on the command line-with multiple '-f/--file' options, balance assertions will not see-balance from earlier files. This can be useful when you do not want-problems in earlier files to disrupt valid assertions in later files.-- If you do want assertions to see balance from earlier files, use-'include', or concatenate the files temporarily.---File: hledger.info, Node: Assertions and costs, Next: Assertions and commodities, Prev: Assertions and multiple -f files, Up: Balance assertions--9.12.4 Assertions and costs------------------------------Balance assertions ignore costs, and should normally be written without-one:--2019/1/1- (a) $1 @ €1 = $1-- We do allow costs to be written in balance assertion amounts,-however, and print shows them, but 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-costs), and because balance _assignments_ do use costs (see below).---File: hledger.info, Node: Assertions and commodities, Next: Assertions and subaccounts, Prev: Assertions and costs, Up: Balance assertions--9.12.5 Assertions and commodities------------------------------------The balance assertions described so far are "*single commodity balance-assertions*": they assert and check the balance in one commodity,-ignoring any others that may be present. This is how balance assertions-work in Ledger also.-- If an account contains multiple commodities, you can assert their-balances by writing multiple postings with balance assertions, one for-each commodity:--2013/1/1- usd $-1- eur €-1- both--2013/1/2- both 0 = $1- both 0 = €1-- In hledger you can make a stronger "*sole commodity balance-assertion*" by writing two equals signs ('== EXPECTEDBALANCE'). This-also asserts that there are no other commodities in the account besides-the asserted one (or at least, that their current balance is zero):--2013/1/1- usd $-1 == $-1 ; these sole commodity assertions succeed- eur €-1 == €-1- both ;== $1 ; this one would fail because 'both' contains $ and €-- It's less easy to make a "*sole commodities balance assertion*" (note-the plural) - ie, asserting that an account contains two or more-specified commodities and no others. It can be done by-- 1. isolating each commodity in a subaccount, and asserting those- 2. and also asserting there are no commodities in the parent account- itself:--2013/1/1- usd $-1- eur €-1- both 0 == 0 ; nothing up my sleeve- both:usd $1 == $1 ; a dollar here- both:eur €1 == €1 ; a euro there---File: hledger.info, Node: Assertions and subaccounts, Next: Assertions and virtual postings, Prev: Assertions and commodities, Up: Balance assertions--9.12.6 Assertions and subaccounts------------------------------------All of the balance assertions above (both '=' and '==') are-"*subaccount-exclusive balance assertions*"; they ignore any balances-that exist in deeper subaccounts.-- In hledger you can make "*subaccount-inclusive balance assertions*"-by adding a star after the equals ('=*' or '==*'):--2019/1/1- equity:start- assets:checking $10- assets:savings $10- assets $0 ==* $20 ; assets + subaccounts contains $20 and nothing else---File: hledger.info, Node: Assertions and virtual postings, Next: Assertions and auto postings, Prev: Assertions and subaccounts, Up: Balance assertions--9.12.7 Assertions and virtual postings-----------------------------------------Balance assertions always consider both real and virtual postings; they-are not affected by the '--real/-R' flag or 'real:' query.---File: hledger.info, Node: Assertions and auto postings, Next: Assertions and precision, Prev: Assertions and virtual postings, Up: Balance assertions--9.12.8 Assertions and auto postings--------------------------------------Balance assertions _are_ affected by the '--auto' flag, which generates-auto postings, which can alter account balances. Because auto postings-are optional in hledger, accounts affected by them effectively have two-balances. But balance assertions can only test one or the other of-these. So to avoid making fragile assertions, either:-- * assert the balance calculated with '--auto', and always use- '--auto' with that file- * or assert the balance calculated without '--auto', and never use- '--auto' with that file- * or avoid balance assertions on accounts affected by auto postings- (or avoid auto postings entirely).---File: hledger.info, Node: Assertions and precision, Prev: Assertions and auto postings, Up: Balance assertions--9.12.9 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 assertions. Balance-assertion failure messages show exact amounts.---File: hledger.info, Node: Posting comments, Next: Transaction balancing, Prev: Balance assertions, Up: Journal--9.13 Posting comments-=====================--Text following ';', at the end of a posting line, and/or on indented-lines immediately below it, form comments for that posting. They are-reproduced by 'print' but otherwise ignored, except they may contain-tags, which are not ignored.--2012-01-01- expenses 1 ; a comment for posting 1- assets- ; a comment for posting 2- ; a second comment line for posting 2---File: hledger.info, Node: Transaction balancing, Next: Tags, Prev: Posting comments, Up: Journal--9.14 Transaction balancing-==========================--How exactly does hledger decide when a transaction is balanced ? The-general goal is that if you look at the journal entry and calculate the-amounts' sum perfectly with pencil and paper, hledger should agree with-you.-- Real world transactions, especially for investments or-cryptocurrencies, often involve imprecise costs, complex decimals,-and/or infinitely-recurring decimals, which are difficult or-inconvenient to handle on a computer. So to be a practical accounting-system, hledger allows some imprecision when checking transaction-balancedness. The question is, how much imprecision should be allowed ?-- hledger currently decides it based on the commodity display styles:-if the postings' sum would appear to be zero when displayed with the-standard display precisions, the transaction is considered balanced.-- Or equivalently: if the journal entry is displayed with amounts-rounded to the standard display precisions (with 'hledger print---round=hard'), and a human with pencil and paper would agree that those-displayed amounts add up to zero, the transaction is considered-balanced.-- This has some advantages: it is fairly intuitive, general not-hard-coded, yet configurable when needed. On the downside it means that-transaction balancedness is related to commodity display precisions, so-eg when using '-c/--commodity-style' to display things with more than-usual precision, you might need to fix some of your journal entries (ie,-add decimal digits to make them balance more precisely).-- Other PTA tools (Ledger, Beancount..) have their own ways of doing-it. Possible improvements are discussed at #1964.-- Note: if you have multiple journal files, and are relying on-commodity directives to make imprecise journal entries balance, the-directives' placement might be important - see 'commodity' directive.---File: hledger.info, Node: Tags, Next: Directives, Prev: Transaction balancing, Up: Journal--9.15 Tags-=========--Tags are a way to add extra labels or data fields to transactions,-postings, or accounts, which you can then search or pivot on.-- A tag is a word, optionally hyphenated, immediately followed by a-full colon, in the comment of a transaction, a posting, or an account-directive. Eg: '2024-01-01 a transaction ; foo:' Note this is an-exception to the usual rule that things in comments are ignored.-- You can write multiple tags on one line, separated by comma. Or you-can write each tag on its own comment line (no comma needed in this-case).-- For example, here are five different tags: one on the-'assets:checking' account, two on the transaction, and two on the-'expenses:food' posting:--account assets:checking ; accounttag:--2017/1/16 bought groceries ; transactiontag-1:- ; transactiontag-2:- assets:checking $-1- expenses:food $1 ; postingtag:, another-posting-tag:-- Postings also inherit tags from their transaction and their account.-And transactions also acquire tags from their postings (and postings'-accounts). So in the example above, the expenses posting effectively-has all five tags (by inheriting from the account and transaction), and-the transaction also has all five tags (by acquiring from the expenses-posting).--* Menu:--* Tag names::-* Special tags::-* Tag values::---File: hledger.info, Node: Tag names, Next: Special tags, Up: Tags--9.15.1 Tag names-------------------Most non-whitespace characters are allowed in tag names. Eg '😀:' is a-valid tag.-- You can list the tag names used in your journal with the tags-command:-'hledger tags [NAMEREGEX]'-- In commands which use a query, you can match by tag name. Eg:-'hledger print tag:NAMEREGEX'-- You can declare valid tag names with the tag directive and then check-them with the check command.---File: hledger.info, Node: Special tags, Next: Tag values, Prev: Tag names, Up: Tags--9.15.2 Special tags----------------------Some tag names have special significance to hledger. There's not much-harm in using them yourself, but some could produce an error message,-particularly the 'date:' and 'type:' tags. They are explained-elsewhere, but here is a quick list for reference:-- Tags you can set to influence hledger's behaviour:-- date -- overrides a posting's date- date2 -- overrides a posting's secondary date- type -- declares an account's type-- Tags hledger adds to indicate generated data:-- t -- appears on postings generated by timedot letters- assert -- appears on txns generated by close --assert- retain -- appears on txns generated by close --retain- start -- appears on txns generated by close --migrate/--close/--open/--assign- generated-transaction -- appears on generated periodic txns (with --verbose-tags)- generated-posting -- appears on generated auto postings (with --verbose-tags)- modified -- appears on txns which have had auto postings added (with --verbose-tags)-Not displayed, but queryable:- _generated-transaction -- exists on generated periodic txns (always)- _generated-posting -- exists on generated auto postings (always)- _modified -- exists on txns which have had auto postings added (always)-- Tags hledger uses internally:-- _conversion-matched -- exists on postings which have been matched with a nearby @/@@ cost annotation---File: hledger.info, Node: Tag values, Prev: Special tags, Up: Tags--9.15.3 Tag values--------------------Tags can have a value, which is any text after the colon up until a-comma or end of line, with surrounding whitespace removed. Ending at-comma allows us to write multiple tags on one line, but also means that-tag values can not contain commas.-- Eg in the following posting, the three tags' values are "value 1",-"value 2", and "" (empty) respectively:-- expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz-- Multiple tags with the same name are additive rather than overriding:-when the same tag name is seen again with a new value, the new-name:value pair is added to the tags. It is not possible to override a-previous tag's value or remove a tag.-- You can list all the values used for a particular tag in the journal-with-'hledger tags TAGNAME --values'-- You can match on tag values with a query like-'tag:NAMEREGEX=VALUEREGEX'---File: hledger.info, Node: Directives, Next: account directive, Prev: Tags, Up: Journal--9.16 Directives-===============--Besides transactions, there is something else you can put in a 'journal'-file: directives. These are declarations, beginning with a keyword,-that modify hledger's behaviour. Some directives can have more specific-subdirectives, indented below them. hledger's directives are similar to-Ledger's in many cases, but there are also many differences. Directives-are not required, but can be useful. Here are the main directives:--purpose directive----------------------------------------------------------------------------*READING DATA:*-Rewrite account names 'alias'-Comment out sections of the file 'comment'-Declare file's decimal mark, to help 'decimal-mark'-parse amounts accurately-Include other data files 'include'-*GENERATING DATA:*-Generate recurring transactions or '~'-budget goals-Generate extra postings on existing '='-transactions-*CHECKING FOR ERRORS:*-Define valid entities to provide more 'account', 'commodity',-error checking 'payee', 'tag'-*REPORTING:*-Declare accounts' type and display 'account'-order-Declare commodity display styles 'commodity'-Declare market prices 'P'--* Menu:--* Directives and multiple files::-* Directive effects::---File: hledger.info, Node: Directives and multiple files, Next: Directive effects, Up: Directives--9.16.1 Directives and multiple files---------------------------------------Directives vary in their scope, ie which journal entries and which input-files they affect. Most often, a directive will affect the following-entries and included files if any, until the end of the current file --and no further. You might find this inconvenient! For example, 'alias'-directives do not affect parent or sibling files. But there are usually-workarounds; for example, put 'alias' directives in your top-most file,-before including other files.-- The restriction, though it may be annoying at first, is in a good-cause; it allows reports to be stable and deterministic, independent of-the order of input. Without it, reports could show different numbers-depending on the order of -f options, or the positions of include-directives in your files.---File: hledger.info, Node: Directive effects, Prev: Directives and multiple files, Up: Directives--9.16.2 Directive effects---------------------------Here are all hledger's directives, with their effects and scope-summarised - nine main directives, plus four others which we consider-non-essential:--directivewhat it does ends- at- file- end?-----------------------------------------------------------------------------*'account'*Declares an account, for checking all entries in all files; andN- its display order and type. Subdirectives: any text, ignored.-*'alias'*Rewrites account names, in following entries until end of Y- current file or 'end aliases'. Command line equivalent:- '--alias'-*'comment'*Ignores part of the journal file, until end of current file orY- 'end comment'.-*'commodity'*Declares up to four things: 1. a commodity symbol, for checkingN,N,Y,Y- all amounts in all files 2. the display style for all amounts- of this commodity 3. the decimal mark for parsing amounts of- this commodity, in the rest of this file and its children, if- there is no 'decimal-mark' directive 4. the precision to use- for balanced-transaction checking in this commodity, in this- file and its children. Takes precedence over 'D'.- Subdirectives: 'format' (ignored). Command line equivalent:- '-c/--commodity-style'-*'decimal-mark'*Declares the decimal mark, for parsing amounts of all Y- commodities in following entries until next 'decimal-mark' or- end of current file. Included files can override. Takes- precedence over 'commodity' and 'D'.-*'include'*Includes entries and directives from another file, as if theyN- were written inline. Command line alternative: multiple- '-f/--file'-*'payee'*Declares a payee name, for checking all entries in all files. N-*'P'*Declares the market price of a commodity on some date, for value N- reports.-*'~'*Declares a periodic transaction rule that generates future N-(tilde)transactions with '--forecast' and budget goals with 'balance- --budget'.-Other-syntax:-*'applyPrepends a common parent account to all account names, in Y-account'*following entries until end of current file or 'end apply- account'.-*'D'*Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N- there is no 'commodity' directive for this commodity: its- decimal mark, balancing precision, and display style, as above.-*'Y'*Sets a default year to use for any yearless dates, in following Y- entries until end of current file.-*'='*Declares an auto posting rule that generates extra postings on partly-(equals)matched transactions with '--auto', in current, parent, and- child files (but not sibling files, see #1212).-*OtherOther directives from Ledger's file format are accepted but-Ledgerignored.-directives*---File: hledger.info, Node: account directive, Next: alias directive, Prev: Directives, Up: Journal--9.17 'account' directive-========================--'account' directives can be used to declare accounts (ie, the places-that amounts are transferred from and to). Though not required, these-declarations can provide several benefits:-- * They can document your intended chart of accounts, providing a- reference.- * They can store additional account information as comments, or as- tags which can be used to filter or pivot reports.- * They can restrict which accounts may be posted to by transactions,- eg in strict mode, which helps prevent errors.- * They influence account display order in reports, allowing- non-alphabetic sorting (eg Revenues to appear above Expenses).- * They can help hledger know your accounts' types (asset, liability,- equity, revenue, expense), enabling reports like balancesheet and- incomestatement.- * They help with account name completion (in hledger add,- hledger-web, hledger-iadd, ledger-mode, etc.)-- They are written as the word 'account' followed by a hledger-style-account name. Eg:--account assets:bank:checking-- Ledger-style indented subdirectives are also accepted, but ignored:--account assets:bank:checking- format subdirective ; currently ignored--* Menu:--* Account comments::-* Account error checking::-* Account display order::-* Account types::---File: hledger.info, Node: Account comments, Next: Account error checking, Up: account directive--9.17.1 Account comments--------------------------Text following *two or more spaces* and ';' at the end of an account-directive line, and/or following ';' on indented lines immediately below-it, form comments for that account. They are ignored except they may-contain tags, which are not ignored.-- The two-space requirement for same-line account comments is because-';' is allowed in account names.--account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon- ; next-line comment- ; some tags - type:A, acctnum:12345---File: hledger.info, Node: Account error checking, Next: Account display order, Prev: Account comments, Up: account directive--9.17.2 Account error checking--------------------------------By default, accounts need not be declared; they come into existence when-a posting references them. This is convenient, but it means hledger-can't warn you when you mis-spell an account name in the journal.-Usually you'll find that error later, as an extra account in balance-reports, or an incorrect 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:-- * The declaration is case-sensitive; transactions must use the- correct account name capitalisation.- * The account directive's scope is "whole file and below" (see- directives). This means it affects all of the current file, and- any files it includes, but not parent or sibling files. The- position of account directives within the file does not matter,- though it's usual to put them at the top.- * Accounts can only be declared in 'journal' files, but will affect- included files of all types.- * It's currently not possible to declare "all possible subaccounts"- with a wildcard; every account posted to must be declared.---File: hledger.info, Node: Account display order, Next: Account types, Prev: Account error checking, Up: account directive--9.17.3 Account display order-------------------------------Account directives also cause hledger to display accounts in a-particular order, not just alphabetically. Eg, here is a conventional-ordering for the top-level accounts:--account assets-account liabilities-account equity-account revenues-account expenses-- Now hledger displays them in that order:--$ hledger accounts-assets-liabilities-equity-revenues-expenses-- If there are undeclared accounts, those will be displayed last, in-alphabetical order.-- Sorting is done within each group of sibling accounts, at each level-of the account tree. Eg, a declaration like 'account parent:child'-influences 'child''s position among its siblings.-- Note, it does not affect 'parent''s position; for that, you need an-'account parent' declaration.-- Sibling accounts are always displayed together; hledger won't display-'x:y' in between 'a:b' and 'a:c'.-- An account directive both declares an account as a valid posting-target, and declares its display order; you can't easily do one without-the other.---File: hledger.info, Node: Account types, Prev: Account display order, Up: account directive--9.17.4 Account types-----------------------hledger knows that accounts come in several types: assets, liabilities,-expenses and so on. This enables easy reports like balancesheet and-incomestatement, and filtering by account type with the 'type:' query.-- As a convenience, hledger will detect these account types-automatically if you are using common english-language top-level account-names (described below). But it's more robust to declare accounts'-types explicitly, by adding 'type:' tags to their account directives.-The tag's value should be one of the five main account types:-- * 'A' or 'Asset' (things you own)- * 'L' or 'Liability' (things you owe)- * 'E' or 'Equity' (investment/ownership; balanced counterpart of- assets & liabilities)- * 'R' or 'Revenue' (what you received money from, AKA income;- technically part of Equity)- * 'X' or 'Expense' (what you spend money on; technically part of- Equity)-- or, it can be (these are used less often):-- * 'C' or 'Cash' (a subtype of Asset, indicating liquid assets for the- cashflow report)- * 'V' or 'Conversion' (a subtype of Equity, for conversions (see Cost- reporting).)-- Subaccounts inherit their parent's type, or they can override it.-Here is a typical set of account type declarations:--account assets ; type: A-account liabilities ; type: L-account equity ; type: E-account revenues ; type: R-account expenses ; type: X--account assets:bank ; type: C-account assets:cash ; type: C--account equity:conversion ; type: V-- Here are some tips for working with account types.-- * The rules for inferring types from account names are as follows.- These are just a convenience that sometimes help new users get- going; if they don't work for you, just ignore them and declare- your account types. See also Regular expressions.-- If account's name contains this (CI) regular expression: | its type is:- --------------------------------------------------------------------|-------------- ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash- ^assets?(:|$) | Asset- ^(debts?|liabilit(y|ies))(:|$) | Liability- ^equity:(trad(e|ing)|conversion)s?(:|$) | Conversion- ^equity(:|$) | Equity- ^(income|revenue)s?(:|$) | Revenue- ^expenses?(:|$) | Expense-- * If you declare any account types, it's a good idea to declare an- account for all of the account types, because a mixture of declared- and name-inferred types can disrupt certain reports.-- * Certain uses of account aliases can disrupt account types. See- Rewriting accounts > Aliases and account types.-- * As mentioned above, subaccounts will inherit a type from their- parent account. More precisely, an account's type is decided by- the first of these that exists:-- 1. A 'type:' declaration for this account.- 2. A 'type:' declaration in the parent accounts above it,- preferring the nearest.- 3. An account type inferred from this account's name.- 4. An account type inferred from a parent account's name,- preferring the nearest parent.- 5. Otherwise, it will have no type.-- * For troubleshooting, you can list accounts and their types with:-- $ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]---File: hledger.info, Node: alias directive, Next: commodity directive, Prev: account directive, Up: Journal--9.18 'alias' directive-======================--You can define account alias rules which rewrite your account names, or-parts of them, before generating reports. This can be useful for:-- * expanding shorthand account names to their full form, allowing- easier data entry and a less verbose journal- * adapting old journals to your current chart of accounts- * experimenting with new account organisations, like a new hierarchy- * combining two accounts into one, eg to see their sum or difference- on one line- * 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.-- Account aliases are very powerful. They are generally easy to use-correctly, but you can also generate invalid account names with them;-more on this below.-- See also Rewrite account names.--* Menu:--* Basic aliases::-* Regex aliases::-* Combining aliases::-* Aliases and multiple files::-* end aliases directive::-* Aliases can generate bad account names::-* Aliases and account types::---File: hledger.info, Node: Basic aliases, Next: Regex aliases, Up: alias directive--9.18.1 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.-Subaccounts 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"---File: hledger.info, Node: Regex aliases, Next: Combining aliases, Prev: Basic aliases, Up: alias directive--9.18.2 Regex aliases-----------------------There is also a more powerful variant that uses a regular expression,-indicated by wrapping the pattern in forward slashes. (This is the only-place where hledger requires forward slashes around a regular-expression.)-- Eg:--alias /REGEX/ = REPLACEMENT-- or:--$ hledger --alias '/REGEX/=REPLACEMENT' ...-- Any part of an account name matched by REGEX will be replaced by-REPLACEMENT. REGEX is case-insensitive as usual.-- If you need to match a forward slash, escape it with a backslash, eg-'/\/=:'.-- If REGEX contains parenthesised match groups, these can be referenced-by the usual backslash and number in REPLACEMENT:--alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3-; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"-- REPLACEMENT continues to the end of line (or on command line, to end-of option argument), so it can contain trailing whitespace.---File: hledger.info, Node: Combining aliases, Next: Aliases and multiple files, Prev: Regex aliases, Up: alias directive--9.18.3 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:-- * the nearest alias declaration before/above the entry is applied- first- * the next alias before/above that will be be applied next, and so on- * aliases defined after/below the entry do not affect it.-- This gives nearby aliases precedence over distant ones, and helps-provide semantic stability - aliases will keep working the same way-independent of which files are being read and in which order.-- In case of trouble, adding '--debug=6' to the command line will show-which aliases are being applied when.---File: hledger.info, Node: Aliases and multiple files, Next: end aliases directive, Prev: Combining aliases, Up: alias directive--9.18.4 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--2023-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--2023-01-01 ; affected by aliases above- foo 1- bar--include c.journal ; also affected---File: hledger.info, Node: end aliases directive, Next: Aliases can generate bad account names, Prev: Aliases and multiple files, Up: alias directive--9.18.5 'end aliases' directive---------------------------------You can clear (forget) all currently defined aliases (seen in the-journal so far, or defined on the command line) with this directive:--end aliases---File: hledger.info, Node: Aliases can generate bad account names, Next: Aliases and account types, Prev: end aliases directive, Up: alias directive--9.18.6 Aliases can generate bad account names------------------------------------------------Be aware that account aliases can produce malformed account names, which-could cause confusing reports or invalid 'print' output. For example,-you could erase all account names:--2021-01-01- a:aa 1- b--$ hledger print --alias '/.*/='-2021-01-01- 1-- The above 'print' output is not a valid journal. Or you could insert-an illegal double space, causing 'print' output that would give a-different journal when reparsed:--2021-01-01- old 1- other--$ hledger print --alias old="new USD" | hledger -f- print-2021-01-01- new USD 1- other---File: hledger.info, Node: Aliases and account types, Prev: Aliases can generate bad account names, Up: alias directive--9.18.7 Aliases and account types-----------------------------------If an account with a type declaration (see Declaring accounts > Account-types) is renamed by an alias, normally the account type remains in-effect.-- However, renaming in a way that reshapes the account tree (eg-renaming parent accounts but not their children, or vice versa) could-prevent child accounts from inheriting the account type of their-parents.-- Secondly, if an account's type is being inferred from its name,-renaming it by an alias could prevent or alter that.-- If you are using account aliases and the 'type:' query is not-matching accounts as you expect, try troubleshooting with the accounts-command, eg something like:--$ hledger accounts --alias assets=bassetts type:a---File: hledger.info, Node: commodity directive, Next: decimal-mark directive, Prev: alias directive, Up: Journal--9.19 'commodity' directive-==========================--The 'commodity' directive performs several functions:-- 1. It declares which commodity symbols may be used in the journal,- enabling useful error checking with strict mode or the check- command. See Commodity error checking below.-- 2. It declares how all amounts in this commodity should be displayed,- eg how many decimals to show. See Commodity display style above.-- 3. (If no 'decimal-mark' directive is in effect:) It sets the decimal- mark to expect (period or comma) when parsing amounts in this- commodity, in this file and files it includes, from the directive- until end of current file. See Decimal marks above.-- 4. It declares the precision with which this commodity's amounts- should be compared when checking for balanced transactions,- anywhere in this file and files it includes, until end of current- file.-- Declaring commodities solves several common parsing/display problems,-so we recommend it.-- Note that effects 3 and 4 above end at the end of the directive's-file, and will not affect sibling or parent files. So if you are-relying on them (especially 4) and using multiple files, placing your-commodity directives in a top-level parent file might be important. Or,-keep your decimal marks unambiguous and your entries well balanced and-precise.-- (Related: #793)--* Menu:--* Commodity directive syntax::-* Commodity error checking::---File: hledger.info, Node: Commodity directive syntax, Next: Commodity error checking, Up: commodity directive--9.19.1 Commodity directive syntax------------------------------------A commodity directive is normally the word 'commodity' followed by a-sample amount (and optionally a comment). Only the amount's symbol and-format is significant. Eg:--commodity $1000.00-commodity 1.000,00 EUR-commodity 1 000 000.0000 ; the no-symbol commodity-- Commodities do not have tags (tags in the comment will be ignored).-- A commodity directive's sample amount must always include a period or-comma decimal mark (this rule helps disambiguate decimal marks and digit-group marks). If you don't want to show any decimal digits, write the-decimal mark at the end:--commodity 1000. AAAA ; show AAAA with no decimals-- Commodity symbols containing spaces, numbers, or punctuation must be-enclosed in double quotes, as usual:--commodity 1.0000 "AAAA 2023"-- Commodity directives normally include a sample amount, but can-declare only a symbol (ie, just function 1 above):--commodity $-commodity INR-commodity "AAAA 2023"-commodity "" ; the no-symbol commodity-- Commodity directives may also be written with an indented 'format'-subdirective, as in Ledger. The symbol is repeated and must be the same-in both places. Other subdirectives are currently ignored:--; 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- an unsupported subdirective ; ignored by hledger---File: hledger.info, Node: Commodity error checking, Prev: Commodity directive syntax, Up: commodity directive--9.19.2 Commodity error checking----------------------------------In strict mode ('-s'/'--strict') (or when you run 'hledger check-commodities'), hledger will report an error if an undeclared commodity-symbol is used. (With one exception: zero amounts are always allowed to-have no commodity symbol.) It works like account error checking-(described above).---File: hledger.info, Node: decimal-mark directive, Next: include directive, Prev: commodity directive, Up: Journal--9.20 'decimal-mark' directive-=============================--You can use a 'decimal-mark' directive - usually one per file, at the-top of the file - to declare which character represents a decimal mark-when parsing amounts in this file. It can look like--decimal-mark .-- or--decimal-mark ,-- This prevents any ambiguity when parsing numbers in the file, so we-recommend it, especially if the file contains digit group marks (eg-thousands separators).---File: hledger.info, Node: include directive, Next: P directive, Prev: decimal-mark directive, Up: Journal--9.21 'include' directive-========================--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,-overriding the file extension (as described in Data formats): 'include-timedot:~/notes/2023*.md'.---File: hledger.info, Node: P directive, Next: payee directive, Prev: include directive, Up: Journal--9.22 'P' directive-==================--The 'P' directive declares a market price, which is a conversion rate-between two commodities on a certain date. This allows value reports to-convert amounts of one commodity to their value in another, on or after-that date. These prices are often obtained from a stock exchange,-cryptocurrency exchange, the or foreign exchange market.-- 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 € $1.35--# and $1.40 from 2010-01-01 onward:-P 2010-01-01 € $1.40-- The '-V', '-X' and '--value' flags use these market prices to show-amount values in another commodity. See Value reporting.---File: hledger.info, Node: payee directive, Next: tag directive, Prev: P directive, Up: Journal--9.23 'payee' directive-======================--'payee PAYEE NAME'-- This 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 ; a comment-- Payees do not have tags (tags in the comment will be ignored).-- To declare the empty payee name, use '""'.--payee ""-- Ledger-style indented subdirectives, if any, are currently ignored.---File: hledger.info, Node: tag directive, Next: Periodic transactions, Prev: payee directive, Up: Journal--9.24 'tag' directive-====================--'tag TAGNAME'-- This directive can be used to declare a limited set of tag names-allowed in tags. TAGNAME should be a valid tag name (no spaces). Eg:--tag item-id-- Any indented subdirectives are currently ignored.-- The "tags" check will report an error if any undeclared tag name is-used. It is quite easy to accidentally create a tag through normal use-of colons in comments; if you want to prevent this, you can declare and-check your tags .---File: hledger.info, Node: Periodic transactions, Next: Auto postings, Prev: tag directive, Up: Journal--9.25 Periodic transactions-==========================--The '~' directive declares a "periodic rule" which generates temporary-extra transactions, usually recurring at some interval, when hledger is-run with the '--forecast' flag. These "forecast transactions" are-useful for forecasting future activity. They exist only for the-duration of the report, and only when '--forecast' is used; they are not-saved in the journal file by hledger.-- Periodic rules also have a second use: with the '--budget' flag they-set budget goals for budgeting.-- Periodic rules can be a little tricky, so before you use them, read-this whole section, or at least the following 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-forecasted 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 2023/01', which is equivalent to '~ every 10th- day of month from 2023/01/01', will be adjusted to start on- 2019/12/10.--* Menu:--* Periodic rule syntax::-* Periodic rules and relative dates::-* Two spaces between period expression and description!::---File: hledger.info, Node: Periodic rule syntax, Next: Periodic rules and relative dates, Up: Periodic transactions--9.25.1 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.):--# every first of month-~ monthly- expenses:rent $2000- assets:bank:checking--# every 15th of month in 2023's first quarter:-~ monthly from 2023-04-15 to 2023-06-16- expenses:utilities $400- assets:bank:checking-- The period expression is the same syntax used for specifying-multi-period reports, just interpreted differently; there, it specifies-report periods; here it specifies recurrence dates (the periods' start-dates).---File: hledger.info, Node: Periodic rules and relative dates, Next: Two spaces between period expression and description!, Prev: Periodic rule syntax, Up: Periodic transactions--9.25.2 Periodic rules and relative dates-------------------------------------------Partial or relative dates (like '12/31', '25', 'tomorrow', 'last week',-'next quarter') are usually not recommended in periodic rules, since the-results will change as time passes. If used, they will be interpreted-relative to, in order of preference:-- 1. the first day of the default year specified by a recent 'Y'- directive- 2. or the date specified with '--today'- 3. or the date on which you are running the report.-- They will not be affected at all by report period or forecast period-dates.---File: hledger.info, Node: Two spaces between period expression and description!, Prev: Periodic rules and relative dates, Up: Periodic transactions--9.25.3 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-accidentally alter their meaning, as in this example:--; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2023"-; ||-; vv-~ every 2 months in 2023, we will review- assets:bank:checking $1500- income:acme inc-- So,-- * Do write two spaces between your period expression and your- transaction description, if any.- * Don't accidentally write two spaces in the middle of your period- expression.---File: hledger.info, Node: Auto postings, Next: Other syntax, Prev: Periodic transactions, Up: Journal--9.26 Auto postings-==================--The '=' directive declares an "auto posting rule", which adds extra-postings to existing transactions. (Remember, postings are the account-name & amount lines below a transaction's date & description.)-- In the journal, an auto posting rule looks quite like a transaction,-but instead of date and description it has '=' (mnemonic: "match") and a-query, like this:--= QUERY- ACCOUNT AMOUNT- ...-- Queries are just like command line queries; an account name substring-is most common. Query terms containing spaces should be enclosed in-single or double quotes.-- Each '=' rule works like this: when hledger is run with the '--auto'-flag, wherever the QUERY matches a posting in the journal, the rule's-postings are added to that transaction, immediately below the matched-posting. Note these generated postings are temporary, existing only for-the duration of the report, and only when '--auto' is used; they are not-saved in the journal file by hledger.-- Generated postings' amounts can depend on the matched posting's-amount. So auto postings can be useful for, eg, adding tax postings-with a standard percentage. AMOUNT can be:-- * a number with no commodity symbol, like '2'. The matched posting's- commodity symbol will be added to this.-- * a normal amount with a commodity symbol, like '$2'. This will be- used as-is.-- * an asterisk followed by a number, like '*2'. This will multiply- the matched posting's amount (and total price, if any) by the- number.-- * an asterisk followed by an amount with commodity symbol, like- '*$2'. This multiplies and also replaces the commodity symbol with- this new one.-- 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-- Note that depending fully on generated data such as this has some-drawbacks - it's less portable, less future-proof, less auditable by-others, and less robust (eg your balance assertions will depend on-whether you use or don't use '--auto'). An alternative is to use auto-postings in "one time" fashion - use them to help build a complex-journal entry, view it with 'hledger print --auto', and then copy that-output into the journal file to make it permanent.--* Menu:--* Auto postings and multiple files::---File: hledger.info, Node: Auto postings and multiple files, Up: Auto postings--9.26.1 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).--* Menu:--* Auto postings and dates::-* Auto postings and transaction balancing / inferred amounts / balance assertions::-* Auto posting tags::-* Auto postings on forecast transactions only::---File: hledger.info, Node: Auto postings and dates, Next: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings and multiple files--9.26.1.1 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.---File: hledger.info, Node: Auto postings and transaction balancing / inferred amounts / balance assertions, Next: Auto posting tags, Prev: Auto postings and dates, Up: Auto postings and multiple files--9.26.1.2 Auto postings and transaction balancing / inferred-...........................................................--amounts / balance assertions Currently, auto postings are added:-- * after missing amounts are inferred, and transactions are checked- for balancedness,- * 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.-- This also means that you cannot have more than one auto-posting with-a missing amount applied to a given transaction, as it will be unable to-infer amounts.---File: hledger.info, Node: Auto posting tags, Next: Auto postings on forecast transactions only, Prev: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings and multiple files--9.26.1.3 Auto posting tags-..........................--Automated postings will have some extra tags:-- * 'generated-posting:= QUERY' - shows this was generated by an auto- posting rule, and the query- * '_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:-- * 'modified:' - this transaction was modified- * '_modified:' - a hidden tag not appearing in the comment; this- transaction was modified "just now".---File: hledger.info, Node: Auto postings on forecast transactions only, Prev: Auto posting tags, Up: Auto postings and multiple files--9.26.1.4 Auto postings on forecast transactions only-....................................................--Tip: you can can make auto postings that will apply to forecast-transactions but not recorded transactions, by adding-'tag:_generated-transaction' to their QUERY. This can be useful when-generating new journal entries to be saved in the journal.---File: hledger.info, Node: Other syntax, Prev: Auto postings, Up: Journal--9.27 Other syntax-=================--hledger journal format supports quite a few other features, mainly to-make interoperating with or converting from Ledger easier. Note some of-the features below are powerful and can be useful in special cases, but-in general, features in this section are considered less important or-even not recommended for most users. Downsides are mentioned to help-you decide if you want to use them.--* Menu:--* Balance assignments::-* Bracketed posting dates::-* D directive::-* apply account directive::-* Y directive::-* Secondary dates::-* Star comments::-* Valuation expressions::-* Virtual postings::-* Other Ledger directives::-* Other cost/lot notations::---File: hledger.info, Node: Balance assignments, Next: Bracketed posting dates, Up: Other syntax--9.27.1 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-assignment).-- Downsides: using balance assignments makes your journal less-explicit; to know the exact amount posted, you have to run hledger or do-the calculations yourself, instead of just reading it. Also balance-assignments' forcing of balances can hide errors. These things make-your financial data less portable, less future-proof, and less-trustworthy in an audit.--* Menu:--* Balance assignments and costs::-* Balance assignments and multiple files::---File: hledger.info, Node: Balance assignments and costs, Next: Balance assignments and multiple files, Up: Balance assignments--9.27.1.1 Balance assignments and costs-......................................--A cost in a balance assignment will cause the calculated amount to have-that cost attached:--2019/1/1- (a) = $1 @ €2--$ hledger print --explicit-2019-01-01- (a) $1 @ €2 = $1 @ €2---File: hledger.info, Node: Balance assignments and multiple files, Prev: Balance assignments and costs, Up: Balance assignments--9.27.1.2 Balance assignments and multiple files-...............................................--Balance assignments handle multiple files like balance assertions. They-see balance from other files previously included from the current file,-but not from previous sibling or parent files.---File: hledger.info, Node: Bracketed posting dates, Next: D directive, Prev: Balance assignments, Up: Other syntax--9.27.2 Bracketed posting dates---------------------------------For setting posting dates and secondary posting dates, Ledger's-bracketed date syntax is also supported: '[DATE]', '[DATE=DATE2]' or-'[=DATE2]' in posting comments. hledger will attempt to parse any-square-bracketed sequence of the '0123456789/-.=' characters in this-way. With this syntax, DATE infers its year from the transaction and-DATE2 infers its year from DATE.-- Downsides: another syntax to learn, redundant with hledger's-'date:'/'date2:' tags, and confusingly similar to Ledger's lot date-syntax.---File: hledger.info, Node: D directive, Next: apply account directive, Prev: Bracketed posting dates, Up: Other syntax--9.27.3 'D' directive-----------------------'D AMOUNT'-- This directive sets a default commodity, to be used for any-subsequent commodityless amounts (ie, plain numbers) seen while parsing-the journal. This effect lasts until the next 'D' directive, or the end-of the current file.-- For compatibility/historical reasons, 'D' also acts like a-'commodity' directive (setting the commodity's decimal mark for parsing-and display style for output). So its argument is not just a commodity-symbol, but a full amount demonstrating the style. The amount must-include a decimal mark (either period or comma). Eg:--; 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-- Interactions with other directives:-- For setting a commodity's display style, a 'commodity' directive has-highest priority, then a 'D' directive.-- For detecting a commodity's decimal mark during parsing,-'decimal-mark' has highest priority, then 'commodity', then 'D'.-- For checking commodity symbols with the check command, a 'commodity'-directive is required ('hledger check commodities' ignores 'D'-directives).-- Downsides: omitting commodity symbols makes your financial data less-explicit, less portable, and less trustworthy in an audit. It is-usually an unsustainable shortcut; sooner or later you will want to-track multiple commodities. D is overloaded with functions redundant-with 'commodity' and 'decimal-mark'. And it works differently from-Ledger's 'D'.---File: hledger.info, Node: apply account directive, Next: Y directive, Prev: D directive, Up: Other syntax--9.27.4 'apply account' directive-----------------------------------This directive sets a default parent account, which will be prepended to-all accounts in following entries, until an 'end apply account'-directive or end of current file. Eg:--apply account home--2010/1/1- food $10- cash--end apply account-- is equivalent to:--2010/01/01- home:food $10- home:cash $-10-- 'account' directives are also affected, and so is any 'include'd-content.-- Account names entered via hledger add or hledger-web are not-affected.-- Account aliases, if any, are applied after the parent account is-prepended.-- Downsides: this can make your financial data less explicit, less-portable, and less trustworthy in an audit.---File: hledger.info, Node: Y directive, Next: Secondary dates, Prev: apply account directive, Up: Other syntax--9.27.5 'Y' directive-----------------------'Y YEAR'-- or (deprecated backward-compatible forms):-- 'year YEAR' 'apply year YEAR'-- The space is optional. This sets a default year to be used for-subsequent dates which don't specify a year. Eg:--Y2009 ; set default year to 2009--12/15 ; equivalent to 2009/12/15- expenses 1- assets--year 2010 ; change default year to 2010--2009/1/30 ; specifies the year, not affected- expenses 1- assets--1/31 ; equivalent to 2010/1/31- expenses 1- assets-- Downsides: omitting the year (from primary transaction dates, at-least) makes your financial data less explicit, less portable, and less-trustworthy in an audit. Such dates can get separated from their-corresponding Y directive, eg when evaluating a region of the journal in-your editor. A missing Y directive makes reports dependent on today's-date.---File: hledger.info, Node: Secondary dates, Next: Star comments, Prev: Y directive, Up: Other syntax--9.27.6 Secondary dates-------------------------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".-- Downsides: makes your financial data more complicated, less portable,-and less trustworthy in an audit. Keeping the meaning of the two dates-consistent requires discipline, and you have to remember which reporting-mode is appropriate for a given report. Posting dates are simpler and-better.---File: hledger.info, Node: Star comments, Next: Valuation expressions, Prev: Secondary dates, Up: Other syntax--9.27.7 Star comments-----------------------Lines beginning with '*' (star/asterisk) are also comment lines. This-feature allows Emacs users to insert org headings in their journal,-allowing them to fold/unfold/navigate it like an outline when viewed-with org mode.-- Downsides: another, unconventional comment syntax to learn.-Decreases your journal's portability. And switching to Emacs org mode-just for folding/unfolding meant losing the benefits of ledger mode;-nowadays you can add outshine mode to ledger mode to get folding without-losing ledger mode's features.---File: hledger.info, Node: Valuation expressions, Next: Virtual postings, Prev: Star comments, Up: Other syntax--9.27.8 Valuation expressions-------------------------------Ledger allows a valuation function or value to be written in double-parentheses after an amount. hledger ignores these.---File: hledger.info, Node: Virtual postings, Next: Other Ledger directives, Prev: Valuation expressions, Up: Other syntax--9.27.9 Virtual postings--------------------------A posting with parentheses around the account name, like '(some:account)-10', is called an _unbalanced virtual posting_. These postings do not-participate in transaction balancing. (And if you write them without an-amount, a zero amount is always inferred.) These can occasionally be-convenient for special circumstances, but they violate double entry-bookkeeping and make your data less portable across applications, so-many people avoid using them at all.-- A posting with brackets around the account name ('[some:account]') is-called a _balanced virtual posting_. The balanced virtual postings in a-transaction must add up to zero, just like ordinary postings, but-separately from them. These are not part of double entry bookkeeping-either, but they are at least balanced. An example:--2022-01-01 buy food with cash, update budget envelope subaccounts, & something else- assets:cash $-10 ; <- these balance each other- expenses:food $7 ; <-- expenses:food $3 ; <-- [assets:checking:budget:food] $-10 ; <- and these balance each other- [assets:checking:available] $10 ; <-- (something:else) $5 ; <- this is not required to balance-- Ordinary postings, whose account names are neither parenthesised nor-bracketed, are called _real postings_. You can exclude virtual postings-from reports with the '-R/--real' flag or a 'real:1' query.---File: hledger.info, Node: Other Ledger directives, Next: Other cost/lot notations, Prev: Virtual postings, Up: Other syntax--9.27.10 Other Ledger directives----------------------------------These other Ledger directives are currently accepted but ignored. This-allows hledger to read more Ledger files, but be aware that hledger's-reports may differ from Ledger's if you use these.--apply fixed COMM AMT-apply tag TAG-assert EXPR-bucket / A ACCT-capture ACCT REGEX-check EXPR-define VAR=EXPR-end apply fixed-end apply tag-end apply year-end tag-eval / expr EXPR-python- PYTHONCODE-tag NAME-value EXPR---command-line-flags-- See also https://hledger.org/ledger.html for a detailed-hledger/Ledger syntax comparison.---File: hledger.info, Node: Other cost/lot notations, Prev: Other Ledger directives, Up: Other syntax--9.27.11 Other cost/lot notations-----------------------------------A slight digression for Ledger and Beancount users. Ledger has a number-of cost/lot-related notations:-- * '@ UNITCOST' and '@@ TOTALCOST'- * expresses a conversion rate, as in hledger- * when buying, also creates a lot than can be selected at- selling time-- * '(@) UNITCOST' and '(@@) TOTALCOST' (virtual cost)- * like the above, but also means "this cost was exceptional,- don't use it when inferring market prices".-- Currently, hledger treats the above like '@' and '@@'; the-parentheses are ignored.-- * '{=FIXEDUNITCOST}' and '{{=FIXEDTOTALCOST}}' (fixed price)- * when buying, means "this cost is also the fixed price, don't- let it fluctuate in value reports"-- * '{UNITCOST}' and '{{TOTALCOST}}' (lot price)- * can be used identically to '@ UNITCOST' and '@@ TOTALCOST',- also creates a lot- * when selling, combined with '@ ...', specifies an investment- lot by its cost basis; does not check if that lot is present-- * and related: '[YYYY/MM/DD]' (lot date)- * when buying, attaches this acquisition date to the lot- * when selling, selects a lot by its acquisition date-- * '(SOME TEXT)' (lot note)- * when buying, attaches this note to the lot- * when selling, selects a lot by its note-- Currently, hledger accepts any or all of the above in any order after-the posting amount, but ignores them. (This can break transaction-balancing.)-- For Beancount users, the notation and behaviour is different:-- * '@ UNITCOST' and '@@ TOTALCOST'- * expresses a cost without creating a lot, as in hledger- * when buying (augmenting) or selling (reducing) a lot, combined- with '{...}': documents the cost/selling price (not used for- transaction balancing)-- * '{UNITCOST}' and '{{TOTALCOST}}'- * when buying (augmenting), expresses the cost for transaction- balancing, and also creates a lot with this cost basis- attached- * when selling (reducing),- * selects a lot by its cost basis- * raises an error if that lot is not present or can not be- selected unambiguously (depending on booking method- configured)- * expresses the selling price for transaction balancing-- Currently, hledger accepts the '{UNITCOST}'/'{{TOTALCOST}}' notation-but ignores it.-- * variations: '{}', '{YYYY-MM-DD}', '{"LABEL"}', '{UNITCOST,- "LABEL"}', '{UNITCOST, YYYY-MM-DD, "LABEL"}' etc.-- Currently, hledger rejects these.---File: hledger.info, Node: CSV, Next: Timeclock, Prev: Journal, Up: Top--10 CSV-******--hledger can read CSV files (Character Separated Value - usually comma,-semicolon, or tab) containing dated records, automatically converting-each record into a transaction.-- (To learn about _writing_ CSV, see CSV output.)-- For best error messages when reading CSV/TSV/SSV files, make sure-they have a corresponding '.csv', '.tsv' or '.ssv' file extension or use-a hledger file prefix (see File Extension below).-- Each CSV file must be described by a corresponding _rules file_.-This contains rules describing the CSV data (header line, fields layout,-date format etc.), how to construct hledger transactions from it, and-how to categorise transactions based on description or other attributes.-- By default, hledger expects this rules file to be named like the CSV-file, with an extra '.rules' extension added, in the same directory. Eg-when asked to read 'foo/FILE.csv', hledger looks for-'foo/FILE.csv.rules'. You can specify a different rules file with the-'--rules-file' option.-- 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-- There's an introductory Importing CSV data tutorial on hledger.org,-and more CSV rules examples below, and a larger collection at-https://github.com/simonmichael/hledger/tree/master/examples/csv.--* Menu:--* CSV rules cheatsheet::-* source::-* separator::-* skip::-* date-format::-* timezone::-* newest-first::-* intra-day-reversed::-* decimal-mark::-* fields list::-* Field assignment::-* Field names::-* if block::-* Matchers::-* if table::-* balance-type::-* include::-* Working with CSV::-* CSV rules examples::---File: hledger.info, Node: CSV rules cheatsheet, Next: source, Up: CSV--10.1 CSV rules cheatsheet-=========================--The following kinds of rule can appear in the rules file, in any order.-(Blank lines and lines beginning with '#' or ';' or '*' are ignored.)--*'source'* optionally declare which file to read data- from-*'separator'* declare the field separator, instead of- relying on file extension-*'skip'* skip one or more header lines at start of file-*'date-format'* declare how to parse CSV dates/date-times-*'timezone'* declare the time zone of ambiguous CSV- date-times-*'newest-first'* improve txn order when: there are multiple- records, newest first, all with the same date-*'intra-day-reversed'* improve txn order when: same-day txns are in- opposite order to the overall file-*'decimal-mark'* declare the decimal mark used in CSV amounts,- when ambiguous-*'fields' list* name CSV fields for easy reference, and- optionally assign their values to hledger- fields-*Field assignment* assign a CSV value or interpolated text value- to a hledger field-*'if' block* conditionally assign values to hledger fields,- or 'skip' a record or 'end' (skip rest of- file)-*'if' table* conditionally assign values to hledger fields,- using compact syntax-*'balance-type'* select which type of balance- assertions/assignments to generate-*'include'* inline another CSV rules file-- Working with CSV tips can be found below, including How CSV rules are-evaluated.---File: hledger.info, Node: source, Next: separator, Prev: CSV rules cheatsheet, Up: CSV--10.2 'source'-=============--If you tell hledger to read a csv file with '-f foo.csv', it will look-for rules in 'foo.csv.rules'. Or, you can tell it to read the rules-file, with '-f foo.csv.rules', and it will look for data in 'foo.csv'-(since 1.30).-- These are mostly equivalent, but the second method provides some-extra features. For one, the data file can be missing, without causing-an error; it is just considered empty. And, you can specify a different-data file by adding a "source" rule:--source ./Checking1.csv-- If you specify just a file name with no path, hledger will look for-it in your system's downloads directory ('~/Downloads', currently):--source Checking1.csv-- And if you specify a glob pattern, hledger will read the most recent-of the matched files (useful with repeated downloads):--source Checking1*.csv-- See also "Working with CSV > Reading files specified by rule".---File: hledger.info, Node: separator, Next: skip, Prev: source, Up: CSV--10.3 'separator'-================--You can use the 'separator' rule to read other kinds of-character-separated 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 automatically, and you won't need this rule.---File: hledger.info, Node: skip, Next: date-format, Prev: separator, Up: CSV--10.4 'skip'-===========--skip N-- The word 'skip' followed by a number (or no number, meaning 1) tells-hledger to ignore this many non-empty lines at the start of the input-data. You'll need this whenever your CSV data contains header lines.-Note, empty and blank lines are skipped automatically, so you don't need-to count those.-- 'skip' has a second meaning: it can be used inside if blocks-(described below), to skip one or more records whenever the condition is-true. Records skipped in this way are ignored, except they are still-required to be valid CSV.---File: hledger.info, Node: date-format, Next: timezone, Prev: skip, Up: CSV--10.5 '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-style date parsing pattern - see-https://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:formatTime.-The pattern must parse the CSV date value completely. Some examples:--# 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---File: hledger.info, Node: timezone, Next: newest-first, Prev: date-format, Up: CSV--10.6 'timezone'-===============--timezone TIMEZONE-- When CSV contains date-times that are implicitly in some time zone-other than yours, but containing no explicit time zone information, you-can use this rule to declare the CSV's native time zone, which helps-prevent off-by-one dates.-- When the CSV date-times do contain time zone information, you don't-need this rule; instead, use '%Z' in 'date-format' (or '%z', '%EZ',-'%Ez'; see the formatTime link above).-- In either of these cases, hledger will do a time-zone-aware-conversion, localising the CSV date-times to your current system time-zone. If you prefer to localise to some other time zone, eg for-reproducibility, you can (on unix at least) set the output timezone with-the TZ environment variable, eg:--$ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv-- 'timezone' currently does not understand timezone names, except-"UTC", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", or "PDT".-For others, use numeric format: +HHMM or -HHMM.---File: hledger.info, Node: newest-first, Next: intra-day-reversed, Prev: timezone, Up: CSV--10.7 'newest-first'-===================--hledger tries to ensure that the generated transactions will be ordered-chronologically, including same-day transactions. Usually it can-auto-detect how the CSV records are ordered. But if it encounters CSV-where all records are on the same date, it assumes that the records are-oldest first. If in fact the CSV's records are normally newest first,-like:--2022-10-01, txn 3...-2022-10-01, txn 2...-2022-10-01, txn 1...-- you can add the 'newest-first' rule to help hledger generate the-transactions in correct order.--# same-day CSV records are newest first-newest-first---File: hledger.info, Node: intra-day-reversed, Next: decimal-mark, Prev: newest-first, Up: CSV--10.8 'intra-day-reversed'-=========================--If CSV records within a single day are ordered opposite to the overall-record order, you can add the 'intra-day-reversed' rule to improve the-order of journal entries. Eg, here the overall record order is newest-first, but same-day records are oldest first:--2022-10-02, txn 3...-2022-10-02, txn 4...-2022-10-01, txn 1...-2022-10-01, txn 2...--# transactions within each day are reversed with respect to the overall date order-intra-day-reversed---File: hledger.info, Node: decimal-mark, Next: fields list, Prev: intra-day-reversed, Up: CSV--10.9 '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.---File: hledger.info, Node: fields list, Next: Field assignment, Prev: decimal-mark, Up: CSV--10.10 'fields' list-===================--fields FIELDNAME1, FIELDNAME2, ...-- A fields list (the word 'fields' followed by comma-separated field-names) is optional, but convenient. It does two things:-- 1. It names the CSV field in each column. This can be convenient if- you are referencing them in other rules, so you can say- '%SomeField' instead of remembering '%13'.-- 2. Whenever you use one of the special hledger field names (described- below), it assigns the CSV value in this position to that hledger- field. This is the quickest way to populate hledger's fields and- build a transaction.-- Here's an example that says "use the 1st, 2nd and 4th fields as the-transaction's date, description and amount; name the last two fields for-later reference; and ignore the others":--fields date, description, , amount, , , somefield, anotherfield-- In a fields list, the separator is always comma; it is unrelated to-the CSV file's separator. Also:-- * There must be least two items in the list (at least one comma).- * Field names may not contain spaces. Spaces before/after field- names are optional.- * Field names may contain '_' (underscore) or '-' (hyphen).- * Fields you don't care about can be given a dummy name or an empty- name.-- If the CSV contains column headings, it's convenient to use these for-your field names, suitably modified (eg lower-cased with spaces replaced-by underscores).-- Sometimes you may want to alter a CSV field name to avoid assigning-to a hledger field with the same name. Eg you could call the CSV's-"balance" field 'balance_' to avoid directly setting hledger's 'balance'-field (and generating a balance assertion).---File: hledger.info, Node: Field assignment, Next: Field names, Prev: fields list, Up: CSV--10.11 Field assignment-======================--HLEDGERFIELD 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-interpolate CSV fields, referenced either by their 1-based position in-the CSV record ('%N') or by the name they were given in the fields list-('%CSVFIELD'), and regular expression match groups ('\N').-- 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:-- * Interpolation strips outer whitespace (so a CSV value like '" 1 "'- becomes '1' when interpolated) (#1051).- * Interpolations always refer to a CSV field - you can't interpolate- a hledger field. (See Referencing other fields below).---File: hledger.info, Node: Field names, Next: if block, Prev: Field assignment, Up: CSV--10.12 Field names-=================--Note the two kinds of field names mentioned here, and used only in-hledger CSV rules files:-- 1. *CSV field names* ('CSVFIELD' in these docs): you can optionally- name the CSV columns for easy reference (since hledger doesn't yet- automatically recognise column headings in a CSV file), by writing- arbitrary names in a 'fields' list, eg:-- fields When, What, Some_Id, Net, Total, Foo, Bar-- 2. Special *hledger field names* ('HLEDGERFIELD' in these docs): you- must set at least some of these to generate the hledger transaction- from a CSV record, by writing them as the left hand side of a field- assignment, eg:-- date %When- code %Some_Id- description %What- comment %Foo %Bar- amount1 $ %Total-- or directly in a 'fields' list:-- fields date, description, code, , amount1, Foo, Bar- currency $- comment %Foo %Bar-- Here are all the special hledger field names available, and what-happens when you assign values to them:--* Menu:--* date field::-* date2 field::-* status field::-* code field::-* description field::-* comment field::-* account field::-* amount field::-* currency field::-* balance field::---File: hledger.info, Node: date field, Next: date2 field, Up: Field names--10.12.1 date field---------------------Assigning to 'date' sets the transaction date.---File: hledger.info, Node: date2 field, Next: status field, Prev: date field, Up: Field names--10.12.2 date2 field----------------------'date2' sets the transaction's secondary date, if any.---File: hledger.info, Node: status field, Next: code field, Prev: date2 field, Up: Field names--10.12.3 status field-----------------------'status' sets the transaction's status, if any.---File: hledger.info, Node: code field, Next: description field, Prev: status field, Up: Field names--10.12.4 code field---------------------'code' sets the transaction's code, if any.---File: hledger.info, Node: description field, Next: comment field, Prev: code field, Up: Field names--10.12.5 description field----------------------------'description' sets the transaction's description, if any.---File: hledger.info, Node: comment field, Next: account field, Prev: description field, Up: Field names--10.12.6 comment field------------------------'comment' sets the transaction's comment, if any.-- 'commentN', where N is a number, sets the Nth posting's comment.-- You can assign multi-line comments by writing literal '\n' in the-code. A comment starting with '\n' will begin on a new line.-- Comments can contain tags, as usual.---File: hledger.info, Node: account field, Next: amount field, Prev: comment field, Up: Field names--10.12.7 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, in conditional rules.-- If a posting's account name is left unset but its amount is set (see-below), a default account name will be chosen (like "expenses:unknown"-or "income:unknown").---File: hledger.info, Node: amount field, Next: currency field, Prev: account field, Up: Field names--10.12.8 amount field-----------------------There are several ways to set posting amounts from CSV, useful in-different situations.-- 1. *'amount'* is the oldest and simplest. Assigning to this sets the- amount of the first and second postings. In the second posting,- the amount will be negated; also, if it has a cost attached, it- will be converted to cost.-- 2. *'amount-in'* and *'amount-out'* work exactly like the above, but- should be used when the CSV has two amount fields (such as "Debit"- and "Credit", or "Inflow" and "Outflow"). Whichever field has a- non-zero value will be used as the amount of the first and second- postings. Here are some tips to avoid confusion:-- * It's not "amount-in for posting 1 and amount-out for posting- 2", it is "extract a single amount from the amount-in or- amount-out field, and use that for posting 1 and (negated) for- posting 2".- * Don't use both 'amount' and 'amount-in'/'amount-out' in the- same rules file; choose based on whether the amount is in a- single CSV field or spread across two fields.- * In each record, at most one of the two CSV fields should- contain a non-zero amount; the other field must contain a zero- or nothing.- * hledger assumes both CSV fields contain unsigned numbers, and- it automatically negates the amount-out values.- * If the data doesn't fit these requirements, you'll probably- need an if rule (see below).-- 3. *'amountN'* (where N is a number from 1 to 99) sets the amount of- only a single posting: the Nth posting in the transaction. You'll- usually need at least two such assignments to make a balanced- transaction. You can also generate more than two postings, to- represent more complex transactions. The posting numbers don't- have to be consecutive; with if rules, higher posting numbers can- be useful to ensure a certain order of postings.-- 4. *'amountN-in'* and *'amountN-out'* work exactly like the above, but- should be used when the CSV has two amount fields. This is- analogous to 'amount-in' and 'amount-out', and those tips also- apply here.-- 5. Remember that a 'fields' list can also do assignments. So in a- fields list if you name a CSV field "amount", that counts as- assigning to 'amount'. (If you don't want that, call it something- else in the fields list, like "amount_".)-- 6. The above don't handle every situation; if you need more- flexibility, use an 'if' rule to set amounts conditionally. See- "Working with CSV > Setting amounts" below for more on this and on- amount-setting generally.---File: hledger.info, Node: currency field, Next: balance field, Prev: amount field, Up: Field names--10.12.9 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.---File: hledger.info, Node: balance field, Prev: currency field, Up: Field names--10.12.10 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 the Working with CSV tips below for more about setting amounts-and currency.---File: hledger.info, Node: if block, Next: Matchers, Prev: Field names, Up: CSV--10.13 'if' block-================--Rules can be applied conditionally, depending on patterns in the CSV-data. This allows flexibility; in particular, it is how you can-categorise transactions, selecting an appropriate account name based on-their description (for example). There are two ways to write-conditional rules: "if blocks", described here, and "if tables",-described below.-- An if block is the word 'if' and one or more "matcher" expressions-(can be a word or phrase), one per line, starting either on the same or-next line; followed by one or more indented rules. Eg,--if MATCHER- RULE-- or--if-MATCHER-MATCHER-MATCHER- RULE- RULE-- If any of the matchers succeeds, all of the indented rules will be-applied. They are usually field assignments, but the following special-rules may also be used within an if block:-- * 'skip' - skips the matched CSV record (generating no transaction- from it)- * 'end' - skips the rest of the current CSV file.-- Some examples:--# if the record contains "groceries", set account2 to "expenses:groceries"-if groceries- account2 expenses:groceries--# if the record contains any of these phrases, set account2 and a transaction comment as shown-if-monthly service fee-atm transaction fee-banking thru software- account2 expenses:business:banking- comment XXX deductible ? check it--# if an empty record is seen (assuming five fields), ignore the rest of the CSV file-if ,,,,- end---File: hledger.info, Node: Matchers, Next: if table, Prev: if block, Up: CSV--10.14 Matchers-==============--There are two kinds:-- 1. A record matcher is a word or single-line text fragment or regular- expression ('REGEX'), which hledger will try to match- case-insensitively anywhere within the CSV record.- Eg: 'whole foods'-- 2. A field matcher is preceded with a percent sign and CSV field name- ('%CSVFIELD REGEX'). hledger will try to match these just within- the named CSV field.- Eg: '%date 2023'-- The regular expression is (as usual in hledger) a POSIX extended-regular expression, that also supports GNU word boundaries ('\b', '\B',-'\<', '\>'), and nothing else. If you have trouble, see "Regular-expressions" in the hledger manual-(https://hledger.org/hledger.html#regular-expressions).--* Menu:--* What matchers match::-* Combining matchers::-* Match groups::---File: hledger.info, Node: What matchers match, Next: Combining matchers, Up: Matchers--10.14.1 What matchers match------------------------------With record matchers, it's important to know that the record matched is-not the original CSV record, but a modified one: separators will be-converted to commas, and enclosing double quotes (but not enclosing-whitespace) are removed. So for example, when reading an SSV file, if-the original record was:--2023-01-01; "Acme, Inc."; 1,000-- the regex would see, and try to match, this modified record text:--2023-01-01,Acme, Inc., 1,000---File: hledger.info, Node: Combining matchers, Next: Match groups, Prev: What matchers match, Up: Matchers--10.14.2 Combining matchers-----------------------------When an if block has multiple matchers, they are combined as follows:-- * By default they are OR'd (any of them can match)- * When a matcher is preceded by ampersand ('&', at the start of the- line) it will be AND'ed with the previous matcher (all in the- AND'ed group must match)- * _Added in 1.32_ When a matcher is preceded by an exclamation mark- ('!'), it is negated (it must not match).-- Note currently there is a limitation: you can't use both '&' and '!'-on the same line (you can't AND a negated matcher).---File: hledger.info, Node: Match groups, Prev: Combining matchers, Up: Matchers--10.14.3 Match groups-----------------------_Added in 1.32_-- Matchers can define match groups: parenthesised portions of the-regular expression which are available for reference in field-assignments. Groups are enclosed in regular parentheses ('(' and ')')-and can be nested. Each group is available in field assignments using-the token '\N', where N is an index into the match groups for this-conditional block (e.g. '\1', '\2', etc.).-- Example: Warp credit card payment postings to the beginning of the-billing period (Month start), to match how they are presented in-statements, using posting dates:--if %date (....-..)-..- comment2 date:\1-01-- Another example: Read the expense account from the CSV field, but-throw away a prefix:--if %account1 liabilities:family:(expenses:.*)- account1 \1---File: hledger.info, Node: if table, Next: balance-type, Prev: Matchers, Up: CSV--10.15 'if' table-================--"if tables" are an alternative to if blocks; they can express many-matchers and field assignments in a more compact tabular format, like-this:--if,HLEDGERFIELD1,HLEDGERFIELD2,...-MATCHERA,VALUE1,VALUE2,...-MATCHERB,VALUE1,VALUE2,...-; Comment line that explains MATCHERC-MATCHERC,VALUE1,VALUE2,...-<empty line>-- The first character after 'if' is taken to be this if table's field-separator. It is unrelated to the separator used in the CSV file. It-should be a non-alphanumeric character like ',' or '|' that does not-appear anywhere else in the table (it should not be used in field names-or matchers or values, and it cannot be escaped with a backslash).-- Each line must contain the same number of separators; empty values-are allowed. Whitespace can be used in the matcher lines for-readability (but not in the if line, currently). You can use the-comment lines in the table body. The table must be terminated by an-empty line (or end of file).-- An if table like the above is interpreted as follows: try all of the-matchers; whenever a matcher succeeds, assign all of the values on that-line to the corresponding hledger fields; If multiple lines match, later-lines will override fields assigned by the earlier ones - just like the-sequence of 'if' blocks would behave.-- If table presented above is equivalent to this sequence of if blocks:--if MATCHERA- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...--if MATCHERB- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...--; Comment line which explains MATCHERC-if MATCHERC- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...-- Example:--if,account2,comment-atm transaction fee,expenses:business:banking,deductible? check it-%description groceries,expenses:groceries,-;; Comment line that desribes why this particular date is special-2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out---File: hledger.info, Node: balance-type, Next: include, Prev: if table, Up: CSV--10.16 '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---File: hledger.info, Node: include, Next: Working with CSV, Prev: balance-type, Up: CSV--10.17 '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---File: hledger.info, Node: Working with CSV, Next: CSV rules examples, Prev: include, Up: CSV--10.18 Working with CSV-======================--Some tips:--* Menu:--* Rapid feedback::-* Valid CSV::-* File Extension::-* Reading CSV from standard input::-* Reading multiple CSV files::-* Reading files specified by rule::-* Valid transactions::-* Deduplicating importing::-* Setting amounts::-* Amount signs::-* Setting currency/commodity::-* Amount decimal places::-* Referencing other fields::-* How CSV rules are evaluated::-* Well factored rules::---File: hledger.info, Node: Rapid feedback, Next: Valid CSV, Up: Working with CSV--10.18.1 Rapid feedback-------------------------It's a good idea to get rapid feedback while creating/troubleshooting-CSV rules. Here's a good way, using entr from eradman.com/entrproject:--$ 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.---File: hledger.info, Node: Valid CSV, Next: File Extension, Prev: Rapid feedback, Up: Working with CSV--10.18.2 Valid CSV--------------------Note that hledger will only accept valid CSV conforming to RFC 4180, and-equivalent SSV and TSV formats (like RFC 4180 but with semicolon or tab-as separators). This means, eg:-- * Values may be enclosed in double quotes, or not. Enclosing in- single quotes is not allowed. (Eg ''A','B'' is rejected.)- * When values are enclosed in double quotes, spaces outside the- quotes are not allowed. (Eg '"A", "B"' is rejected.)- * When values are not enclosed in quotes, they may not contain double- quotes. (Eg 'A"A, B' is rejected.)-- If your CSV/SSV/TSV is not valid in this sense, you'll need to-transform it before reading with hledger. Try using sed, or a more-permissive CSV parser like python's csv lib.---File: hledger.info, Node: File Extension, Next: Reading CSV from standard input, Prev: Valid CSV, Up: Working with CSV--10.18.3 File Extension-------------------------To help hledger choose the CSV file reader and show the right error-messages (and choose the right field separator character by default),-it's best if CSV/SSV/TSV files are named with a '.csv', '.ssv' or '.tsv'-filename extension. (More about this at Data formats.)-- When reading files with the "wrong" extension, you can ensure the CSV-reader (and the default field separator) by prefixing the file path with-'csv:', 'ssv:' or 'tsv:': Eg:--$ hledger -f ssv:foo.dat print-- You can also override the default field separator with a separator-rule if needed.---File: hledger.info, Node: Reading CSV from standard input, Next: Reading multiple CSV files, Prev: File Extension, Up: Working with CSV--10.18.4 Reading CSV from standard input------------------------------------------You'll need the file format prefix when reading CSV from stdin also,-since hledger assumes journal format by default. Eg:--$ cat foo.dat | hledger -f ssv:- print---File: hledger.info, Node: Reading multiple CSV files, Next: Reading files specified by rule, Prev: Reading CSV from standard input, Up: Working with CSV--10.18.5 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.---File: hledger.info, Node: Reading files specified by rule, Next: Valid transactions, Prev: Reading multiple CSV files, Up: Working with CSV--10.18.6 Reading files specified by rule------------------------------------------Instead of specifying a CSV file in the command line, you can specify a-rules file, as in 'hledger -f foo.csv.rules CMD'. By default this will-read data from foo.csv in the same directory, but you can add a source-rule to specify a different data file, perhaps located in your web-browser's download directory.-- This feature was added in hledger 1.30, so you won't see it in most-CSV rules examples. But it helps remove some of the busywork of-managing CSV downloads. Most of your financial institutions's default-CSV filenames are different and can be recognised by a glob pattern. So-you can put a rule like 'source Checking1*.csv' in-foo-checking.csv.rules, and then periodically follow a workflow like:-- 1. Download CSV from Foo's website, using your browser's defaults- 2. Run 'hledger import foo-checking.csv.rules' to import any new- transactions-- After import, you can: discard the CSV, or leave it where it is for a-while, or move it into your archives, as you prefer. If you do nothing,-next time your browser will save something like Checking1-2.csv, and-hledger will use that because of the '*' wild card and because it is the-most recent.---File: hledger.info, Node: Valid transactions, Next: Deduplicating importing, Prev: Reading files specified by rule, Up: Working with CSV--10.18.7 Valid transactions-----------------------------After reading a CSV file, hledger post-processes and validates the-generated journal entries as it would for a journal file - balancing-them, applying balance assignments, and canonicalising amount styles.-Any errors at this stage will be reported in the usual way, displaying-the problem entry.-- 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---File: hledger.info, Node: Deduplicating importing, Next: Setting amounts, Prev: Valid transactions, Up: Working with CSV--10.18.8 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:-- * https://hledger.org/cookbook.html#setups-and-workflows- * https://plaintextaccounting.org -> data import/conversion---File: hledger.info, Node: Setting amounts, Next: Amount signs, Prev: Deduplicating importing, Up: Working with CSV--10.18.9 Setting amounts--------------------------Continuing from amount field above, here are more tips for-amount-setting:-- 1. *If the amount is in a single CSV field:*-- a. *If its sign indicates direction of flow:*- Assign it to 'amountN', to set the Nth posting's amount. N is- usually 1 or 2 but can go up to 99.-- b. *If another field indicates direction of flow:*- Use one or more conditional rules to set the appropriate- amount sign. Eg:-- # assume a withdrawal unless Type contains "deposit":- amount1 -%Amount- if %Type deposit- amount1 %Amount-- 2. *If the amount is in two CSV fields (such as Debit and Credit, or- In and Out):*-- a. *If both fields are unsigned:*- Assign one field to 'amountN-in' and the other to- 'amountN-out'. hledger will automatically negate the "out"- field, and will use whichever field value is non-zero as- posting N's amount.-- b. *If either field is signed:*- You will probably need to override hledger's sign for one or- the other field, as in the following example:-- # Negate the -out value, but only if it is not empty:- fields date, description, amount1-in, amount1-out- if %amount1-out [1-9]- amount1-out -%amount1-out-- c. *If both fields can contain a non-zero value (or both can be- empty):*- The -in/-out rules normally choose the value which is- non-zero/non-empty. Some value pairs can be ambiguous, such- as '1' and 'none'. For such cases, use conditional rules to- help select the amount. Eg, to handle the above you could- select the value containing non-zero digits:-- fields date, description, in, out- if %in [1-9]- amount1 %in- if %out [1-9]- amount1 %out-- 3. *If you want posting 2's amount converted to cost:*- Use the unnumbered 'amount' (or 'amount-in' and 'amount-out')- syntax.-- 4. *If the CSV has only balance amounts, not transaction amounts:*- Assign to 'balanceN', to set a balance assignment on the Nth- posting, causing the posting's amount to be calculated- automatically. 'balance' with no number is equivalent to- 'balance1'. In this situation hledger is more likely to guess the- wrong default account name, so you may need to set that explicitly.---File: hledger.info, Node: Amount signs, Next: Setting currency/commodity, Prev: Setting amounts, Up: Working with CSV--10.18.10 Amount signs------------------------There is some special handling making it easier to parse and to reverse-amount signs. (This only works for whole amounts, not for cost amounts-such as COST in 'amount1 AMT @ COST'):-- * *If an amount value begins with a plus sign:*- that will be removed: '+AMT' becomes 'AMT'-- * *If an amount value is parenthesised:*- it will be de-parenthesised and sign-flipped: '(AMT)' becomes- '-AMT'-- * *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'-- * *If an amount value contains just a sign (or just a set of- parentheses):*- that is removed, making it an empty value. '"+"' or '"-"' or- '"()"' becomes '""'.-- It's not possible (without preprocessing the CSV) to set an amount to-its absolute value, ie discard its sign.---File: hledger.info, Node: Setting currency/commodity, Next: Amount decimal places, Prev: Amount signs, Up: Working with CSV--10.18.11 Setting currency/commodity--------------------------------------If the currency/commodity symbol is included in the CSV's amount-field(s):--2023-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--2023-01-01 foo- expenses:unknown $123.00- income:unknown $-123.00-- If the currency is provided as a separate CSV field:--2023-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--2023-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--2023-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.---File: hledger.info, Node: Amount decimal places, Next: Referencing other fields, Prev: Setting currency/commodity, Up: Working with CSV--10.18.12 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-decimal 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).---File: hledger.info, Node: Referencing other fields, Next: How CSV rules are evaluated, Prev: Amount decimal places, Up: Working with CSV--10.18.13 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-literal "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---File: hledger.info, Node: How CSV rules are evaluated, Next: Well factored rules, Prev: Referencing other fields, Up: Working with CSV--10.18.14 How CSV rules are evaluated---------------------------------------Here's how to think of CSV rules being evaluated (if you really need-to). First,-- * '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:-- * 'skip' (at top level)- * 'date-format'- * 'newest-first'- * 'fields' - names the CSV fields, optionally sets up initial- assignments to hledger fields-- Then for each CSV record in turn:-- * 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.- * 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.- * compute a value for each hledger field - either the one that was- assigned to it (and interpolate the %CSVFIELD references), or a- default- * generate a hledger transaction (journal entry) from these values.-- This is all part of the CSV reader, one of several readers hledger-can use to parse input files. When all files have been read-successfully, the transactions are passed as input to whichever hledger-command the user specified.---File: hledger.info, Node: Well factored rules, Prev: How CSV rules are evaluated, Up: Working with CSV--10.18.15 Well factored rules-------------------------------Some things than can help reduce duplication and complexity in rules-files:-- * Extracting common rules usable with multiple CSV files into a- 'common.rules', and adding 'include common.rules' to each CSV's- rules file.-- * Splitting if blocks into smaller if blocks, extracting the- frequently used parts.---File: hledger.info, Node: CSV rules examples, Prev: Working with CSV, Up: CSV--10.19 CSV rules examples-========================--* Menu:--* Bank of Ireland::-* Coinbase::-* Amazon::-* Paypal::---File: hledger.info, Node: Bank of Ireland, Next: Coinbase, Up: CSV rules examples--10.19.1 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-necessary 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-reading directly from CSV, but they will be checked if these entries are-imported into a journal file.---File: hledger.info, Node: Coinbase, Next: Amazon, Prev: Bank of Ireland, Up: CSV rules examples--10.19.2 Coinbase-------------------A simple example with some CSV from Coinbase. The spot price is-recorded using cost notation. The legacy 'amount' field name-conveniently sets amount 2 (posting 2's amount) to the total cost.--# Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes-# 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,"","","","Received 100.00 USDC from an external account"--# coinbase.csv.rules-skip 1-fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes-date %Timestamp-date-format %Y-%m-%dT%T%Z-description %Notes-account1 assets:coinbase:cc-amount %Quantity_Transacted %Asset @ %Spot_Price_at_Transaction %Spot_Price_Currency--$ hledger print -f coinbase.csv-2021-12-30 Received 100.00 USDC from an external account- assets:coinbase:cc 100 USDC @ 0.740000 GBP- income:unknown -74.000000 GBP---File: hledger.info, Node: Amazon, Next: Paypal, Prev: Coinbase, Up: CSV rules examples--10.19.3 Amazon-----------------Here we convert amazon.com order history, and use an if block to-generate 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---File: hledger.info, Node: Paypal, Prev: Amazon, Up: CSV rules examples--10.19.4 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:---File: hledger.info, Node: Timeclock, Next: Timedot, Prev: CSV, Up: Top--11 Timeclock-************--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). Lines-beginning with '#' or ';' or '*', and blank lines, are ignored.--i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:-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 2 spaces ; optional comment, tags:- (some account) 0.33h--2015-03-31 * 22:21-23:59- (another:account) 1.64h--2015-04-01 * 00:00-02:00- (another:account) 2.01h-- 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:-- * use emacs and the built-in timeclock.el, or the extended- timeclock-x.el and perhaps the extras in ledgerutils.el-- * at the command line, use these bash aliases: 'cli alias ti="echo i- `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o `date- '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"'-- * 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.---File: hledger.info, Node: Timedot, Next: PART 3 REPORTING CONCEPTS, Prev: Timeclock, Up: Top--12 Timedot-**********--'timedot' format is hledger's human-friendly time logging format.-Compared to 'timeclock' format, it is more convenient for quick,-approximate, and retroactive time logging, and more human-readable (you-can see at a glance where time was spent). A quick example:--2023-05-01-hom:errands .... .... ; two hours; the space is ignored-fos:hledger:timedot .. ; half an hour-per:admin:finance ; no time spent yet-- hledger reads this as a transaction on this day with three-(unbalanced) postings, where each dot represents "0.25". No commodity-symbol is assumed, but we typically interpret it as hours.--$ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required-2023-05-01 *- (hom:errands) 2.00 ; two hours- (fos:hledger:timedot) 0.50 ; half an hour- (per:admin:finance) 0-- A timedot file contains a series of transactions (usually one per-day). Each begins with a *simple date* (Y-M-D, Y/M/D, or Y.M.D),-optionally be followed on the same line by a transaction description,-and/or a transaction comment following a semicolon.-- After the date line are zero or more time postings, consisting of:-- * *An account name* - any hledger-style account name, optionally- indented.-- * *Two or more spaces* - required if there is an amount (as in- journal format).-- * *A timedot amount*, which can be-- * empty (representing zero)-- * a number, optionally followed by a unit 's', 'm', 'h', 'd',- 'w', 'mo', or 'y', representing a precise number of seconds,- minutes, hours, days weeks, months or years (hours is assumed- by default), which will be converted to hours according to 60s- = 1m, 60m = 1h, 24h = 1d, 7d = 1w, 30d = 1mo, 365d = 1y.-- * one or more dots (period characters), each representing 0.25.- These are the dots in "timedot". Spaces are ignored and can- be used for grouping/alignment.-- * _Added in 1.32_ one or more letters. These are like dots but- they also generate a tag 't:' (short for "type") with the- letter as its value, and a separate posting for each of the- values. This provides a second dimension of categorisation,- viewable in reports with '--pivot t'.-- * *An optional comment* following a semicolon (a hledger-style- posting comment).-- There is some flexibility to help with keeping time log data and-notes in the same file:-- * Blank lines and lines beginning with '#' or ';' are ignored.-- * After the first date line, lines which do not contain a double- space are parsed as postings with zero amount. (hledger's register- reports will show these if you add -E).-- * Before the first date line, lines beginning with '*' (eg org- headings) are ignored. And from the first date line onward, Emacs- org mode heading prefixes at the start of lines (one or more '*''s- followed by a space) will be ignored. This means the time log can- also be a org outline.--* Menu:--* Timedot examples::---File: hledger.info, Node: Timedot examples, Up: Timedot--12.1 Timedot examples-=====================--Numbers:--2016/2/3-inc:client1 4-fos:hledger 3h-biz:research 60m-- Dots:--# 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 .--$ 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 -- Letters:--# Activity types:-# c cleanup/catchup/repair-# e enhancement-# s support-# l learning/research--2023-11-01-work:adm ccecces--$ hledger -f a.timedot print-2023-11-01- (work:adm) 1 ; t:c- (work:adm) 0.5 ; t:e- (work:adm) 0.25 ; t:s--$ hledger -f a.timedot bal- 1.75 work:adm---------------------- 1.75 --$ hledger -f a.timedot bal --pivot t- 1.00 c- 0.50 e- 0.25 s---------------------- 1.75 -- Org:--* 2023 Work Diary-** Q1-*** 2023-02-29-**** DONE-0700 yoga-**** UNPLANNED-**** BEGUN-hom:chores- cleaning ...- water plants- outdoor - one full watering can- indoor - light watering-**** TODO-adm:planning: trip-*** LATER-- Using '.' as account name separator:--2016/2/4-fos.hledger.timedot 4h-fos.ledger ..--$ hledger -f a.timedot --alias '/\./=:' bal -t- 4.50 fos- 4.00 hledger:timedot- 0.50 ledger---------------------- 4.50---File: hledger.info, Node: PART 3 REPORTING CONCEPTS, Next: Amount formatting, Prev: Timedot, Up: Top--13 PART 3: REPORTING CONCEPTS-*****************************---File: hledger.info, Node: Amount formatting, Next: Time periods, Prev: PART 3 REPORTING CONCEPTS, Up: Top--14 Amount formatting-********************--* Menu:--* Commodity display style::-* Rounding::-* Trailing decimal marks::-* Amount parseability::---File: hledger.info, Node: Commodity display style, Next: Rounding, Up: Amount formatting--14.1 Commodity display style-============================--For the amounts in each commodity, hledger chooses a consistent display-style (symbol placement, decimal mark and digit group marks, number of-decimal digits) to use in most reports. This is inferred as follows:-- First, if there's a 'D' directive declaring a default commodity, that-commodity symbol and amount format is applied to all no-symbol amounts-in the journal.-- Then each commodity's display style is determined from its-'commodity' directive. We recommend always declaring commodities with-'commodity' directives, since they help ensure consistent display styles-and precisions, and bring other benefits such as error checking for-commodity symbols. Here's an example:--# Set display styles (and decimal marks, for parsing, if there is no decimal-mark directive)-# for the $, EUR, INR and no-symbol commodities:-commodity $1,000.00-commodity EUR 1.000,00-commodity INR 9,99,99,999.00-commodity 1 000 000.9455-- But for convenience, if a 'commodity' directive is not present,-hledger infers a commodity's display styles from its amounts as they are-written in the journal (excluding cost amounts and amounts in periodic-transaction rules or auto posting rules). It uses-- * the symbol placement and decimal mark of the first amount seen- * the digit group marks of the first amount with digit group marks- * and the maximum number of decimal digits seen across all amounts.-- And as fallback if no applicable amounts are found, it would use a-default style, like '$1000.00' (symbol on the left with no space, period-as decimal mark, and two decimal digits).-- Finally, commodity styles can be overridden by the-'-c/--commodity-style' command line option.---File: hledger.info, Node: Rounding, Next: Trailing decimal marks, Prev: Commodity display style, Up: Amount formatting--14.2 Rounding-=============--Amounts are stored internally as decimal numbers with up to 255 decimal-places. They are displayed with their original journal precisions by-print and print-like reports, and rounded to their display precision-(the number of decimal digits specified by the commodity display style)-by other reports. When rounding, hledger uses banker's rounding (it-rounds to the nearest even digit). So eg 0.5 displayed with zero-decimal digits appears as "0".---File: hledger.info, Node: Trailing decimal marks, Next: Amount parseability, Prev: Rounding, Up: Amount formatting--14.3 Trailing decimal marks-===========================--If you're wondering why your 'print' report sometimes shows trailing-decimal marks, with no decimal digits; it does this when showing amounts-that have digit group marks but no decimal digits, to disambiguate them-and allow them to be re-parsed reliably (see Decimal marks). Eg:--commodity $1,000.00--2023-01-02- (a) $1000--$ hledger print-2023-01-02- (a) $1,000.-- If this is a problem (eg when exporting to Ledger), you can avoid it-by disabling digit group marks, eg with -c/-commodity (for each affected-commodity):--$ hledger print -c '$1000.00'-2023-01-02- (a) $1000-- or by forcing print to always show decimal digits, with -round:--$ hledger print -c '$1,000.00' --round=soft-2023-01-02- (a) $1,000.00---File: hledger.info, Node: Amount parseability, Prev: Trailing decimal marks, Up: Amount formatting--14.4 Amount parseability-========================--More generally, hledger output falls into three rough categories, which-format amounts a little bit differently to suit different consumers:-- *1. "hledger-readable output" - should be readable by hledger (and-by humans)*-- * This is produced by reports that show full journal entries:- 'print', 'import', 'close', 'rewrite' etc.- * It shows amounts with their original journal precisions, which may- not be consistent.- * It adds a trailing decimal mark when needed to avoid showing- ambiguous amounts.- * It can be parsed reliably (by hledger and ledger2beancount at- least, but perhaps not by Ledger..)-- *2. "human-readable output" - usually for humans*-- * This is produced by all other reports.- * It shows amounts with standard display precisions, which will be- consistent within each commodity.- * It shows ambiguous amounts unmodified.- * It can be parsed reliably in the context of a known report (when- you know decimals are consistently not being shown, you can assume- a single mark is a digit group mark).-- *3. "machine-readable output" - usually for other software*-- * This is produced by all reports when an output format like 'csv',- 'tsv', 'json', or 'sql' is selected.- * It shows amounts as 1 or 2 do, but without digit group marks.- * It can be parsed reliably (if needed, the decimal mark can be- changed with -c/-commodity-style).---File: hledger.info, Node: Time periods, Next: Depth, Prev: Amount formatting, Up: Top--15 Time periods-***************--* Menu:--* Report start & end date::-* Smart dates::-* Report intervals::-* Date adjustment::-* Period expressions::---File: hledger.info, Node: Report start & end date, Next: Smart dates, Up: Time periods--15.1 Report start & end date-============================--By default, most hledger reports will show the full span of time-represented by the journal. The report start date will be the earliest-transaction or posting date, and the report end date will be the latest-transaction, posting, or market price date.-- Often you will want to see a shorter time span, such as the current-month. You can specify a start and/or end date using '-b/--begin',-'-e/--end', '-p/--period' or a 'date:' query (described below). All of-these accept the smart date syntax (below).-- Some notes:-- * End dates are exclusive, as in Ledger, so you should write the date- _after_ the last day you want to see in the report.- * As noted in reporting options: among start/end dates specified with- _options_, the last (i.e. right-most) option takes precedence.- * 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.- * In some cases a report interval will adjust start/end dates to fall- on interval boundaries (see below).-- Examples:--'-b begin on St. Patrick's day 2016-2016/3/17'-'-e 12/1' end at the start of december 1st of the current year- (11/30 will be the last date included)-'-b all transactions on or after the 1st of the current month-thismonth'-'-p all transactions in the current month-thismonth'-'date:2016/3/17..'the above written as queries instead ('..' can also be- replaced with '-')-'date:..12/1'-'date:thismonth..'-'date:thismonth'---File: hledger.info, Node: Smart dates, Next: Report intervals, Prev: Report start & end date, Up: Time periods--15.2 Smart dates-================--hledger's user interfaces accept a "smart date" syntax for added-convenience. Smart dates optionally can be relative to today's date, be-written with english words, and have less-significant parts omitted-(missing parts are inferred as 1). Some examples:--'2004/10/1', exact date, several separators allowed. Year-'2004-01-01', is 4+ digits, month is 1-12, day is 1-31-'2004.9.1'-'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, -1, 0, 1 days from today-tomorrow'-'last/this/next -1, 0, 1 periods from the current period-day/week/month/quarter/year'-'in n n periods from the current period-days/weeks/months/quarters/years'-'n n periods from the current period-days/weeks/months/quarters/years-ahead'-'n -n periods from the current period-days/weeks/months/quarters/years-ago'-'20181201' 8 digit YYYYMMDD with valid year month and- day-'201812' 6 digit YYYYMM with valid year and month-- Some 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-- "Today's date" can be overridden with the '--today' option, in case-it's needed for testing or for recreating old reports. (Except for-periodic transaction rules, which are not affected by '--today'.)---File: hledger.info, Node: Report intervals, Next: Date adjustment, Prev: Smart dates, Up: Time periods--15.3 Report intervals-=====================--A report interval can be specified so that reports like register,-balance or activity become multi-period, showing each subperiod as a-separate row or column.-- The following standard intervals can be enabled with command-line-flags:-- * '-D/--daily'- * '-W/--weekly'- * '-M/--monthly'- * '-Q/--quarterly'- * '-Y/--yearly'-- More complex intervals can be specified using '-p/--period',-described below.---File: hledger.info, Node: Date adjustment, Next: Period expressions, Prev: Report intervals, Up: Time periods--15.4 Date adjustment-====================--When there is a report interval (other than daily), report start/end-dates which have been inferred, eg from the journal, are automatically-adjusted to natural period boundaries. This is convenient for producing-simple periodic reports. More precisely:-- * an inferred start date will be adjusted earlier if needed to fall- on a natural period boundary-- * an inferred end date will be adjusted later if needed to make the- last period the same length as the others.-- By contrast, start/end dates which have been specified explicitly,-with '-b', '-e', '-p' or 'date:', will not be adjusted (since hledger-1.29). This makes it possible to specify non-standard report periods,-but it also means that if you are specifying a start date, you should-pick one that's on a period boundary if you want to see simple report-period headings.---File: hledger.info, Node: Period expressions, Prev: Date adjustment, Up: Time periods--15.5 Period expressions-=======================--The '-p/--period' option specifies a period expression, which is a-compact way of expressing a start date, end date, and/or report-interval.-- Here's a period expression with a start and end date (specifying the-first quarter of 2009):--'-p "from 2009/1/1 to 2009/4/1"'-- Several keywords like "from" and "to" are supported for readability;-these are optional. "to" can also be written as ".." or "-". The-spaces are also optional, as long as you don't run two dates together.-So the following are equivalent to the above:--'-p "2009/1/1 2009/4/1"'-'-p2009/1/1to2009/4/1'-'-p2009/1/1..2009/4/1'-- Dates are smart dates, so if the current year is 2009, these are also-equivalent to the above:--'-p "1/1 4/1"'-'-p "jan-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 date in the journal:--'-p "from 2009/1/1"' everything after january 1, 2009-'-p "since 2009/1"' the same, since is a synonym-'-p "from 2009"' the same-'-p "to 2009"' everything before january 1, 2009-- You can also specify a period by writing a single partial or full-date:--'-p "2009"' the year 2009; equivalent to “2009/1/1 to 2010/1/1”-'-p "2009/1"' the month of january 2009; equivalent to “2009/1/1 to- 2009/2/1”-'-p the first day of 2009; equivalent to “2009/1/1 to-"2009/1/1"' 2009/1/2”-- or by using the "Q" quarter-year syntax (case insensitive):--'-p "2009Q1"' first quarter of 2009, equivalent to “2009/1/1 to- 2009/4/1”-'-p "q4"' fourth quarter of the current year--* Menu:--* Period expressions with a report interval::-* More complex report intervals::-* Multiple weekday intervals::---File: hledger.info, Node: Period expressions with a report interval, Next: More complex report intervals, Up: Period expressions--15.5.1 Period expressions with a report interval---------------------------------------------------A period expression can also begin with a report interval, separated-from the start/end dates (if any) by a space or the word 'in':--'-p "weekly from 2009/1/1 to 2009/4/1"'-'-p "monthly in 2008"'-'-p "quarterly"'---File: hledger.info, Node: More complex report intervals, Next: Multiple weekday intervals, Prev: Period expressions with a report interval, Up: Period expressions--15.5.2 More complex report intervals---------------------------------------Some more complex intervals can be specified within period expressions,-such as:-- * 'biweekly' (every two weeks)- * 'fortnightly'- * 'bimonthly' (every two months)- * 'every day|week|month|quarter|year'- * 'every N days|weeks|months|quarters|years'-- Weekly on a custom day:-- * 'every Nth day of week' ('th', 'nd', 'rd', or 'st' are all accepted- after the number)- * 'every WEEKDAYNAME' (full or three-letter english weekday name,- case insensitive)-- Monthly on a custom day:-- * 'every Nth day [of month]'- * 'every Nth WEEKDAYNAME [of month]'-- Yearly on a custom day:-- * 'every MM/DD [of year]' (month number and day of month number)- * 'every MONTHNAME DDth [of year]' (full or three-letter english- month name, case insensitive, and day of month number)- * 'every DDth MONTHNAME [of year]' (equivalent to the above)-- Examples:--'-p "bimonthly from-2008"'-'-p "every 2 weeks"'-'-p "every 5 months from-2009/03"'-'-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- November-'-p "every 5th November"' same-'-p "every Nov 5th"' same-- Show historical balances at end of the 15th day of each month (N is-an end date, exclusive as always):--$ hledger balance -H -p "every 16th day"-- Group postings from the start of wednesday to end of the following-tuesday (N is both (inclusive) start date and (exclusive) end date):--$ hledger register checking -p "every 3rd day of week"---File: hledger.info, Node: Multiple weekday intervals, Prev: More complex report intervals, Up: Period expressions--15.5.3 Multiple weekday intervals------------------------------------This special form is also supported:-- * 'every WEEKDAYNAME,WEEKDAYNAME,...' (full or three-letter english- weekday names, case insensitive)-- Also, 'weekday' and 'weekendday' are shorthand for-'mon,tue,wed,thu,fri' and 'sat,sun'.-- This is mainly intended for use with '--forecast', to generate-periodic transactions on arbitrary days of the week. It may be less-useful with '-p', since it divides each week into subperiods of unequal-length, which is unusual. (Related: #1632)-- Examples:--'-p "every dates will be Mon, Wed, Fri; periods will be-mon,wed,fri"' Mon-Tue, Wed-Thu, Fri-Sun-'-p "every dates will be Mon, Tue, Wed, Thu, Fri; periods will-weekday"' be Mon, Tue, Wed, Thu, Fri-Sun-'-p "every dates will be Sat, Sun; periods will be Sat, Sun-Fri-weekendday"'---File: hledger.info, Node: Depth, Next: Queries, Prev: Time periods, Up: Top--16 Depth-********--With the '--depth NUM' option (short form: '-NUM'), reports will show-accounts only to the specified depth, hiding deeper subaccounts. Use-this when you want a summary with less detail. This flag has the same-effect as a 'depth:' query argument: 'depth:2', '--depth=2' or '-2' are-equivalent.---File: hledger.info, Node: Queries, Next: Pivoting, Prev: Depth, Up: Top--17 Queries-**********--One of hledger's strengths is being able to quickly report on a precise-subset of your data. Most hledger commands accept query arguments, to-restrict their scope. Multiple query terms can be provided to build up-a more complex query.-- * By default, a query term is interpreted as a case-insensitive- substring pattern for matching account names:-- 'car:fuel'- 'dining groceries'-- * Patterns containing spaces or other special characters must be- enclosed in single or double quotes:-- ''personal care''-- * These patterns are actually regular expressions, so you can add- regexp metacharacters for more precision (see "Regular expressions"- above for details):-- ''^expenses\b''- ''food$''- ''fuel|repair''- ''accounts (payable|receivable)''-- * To match something other than account name, add one of the query- type prefixes described in "Query types" below:-- 'date:202312-'- 'status:'- 'desc:amazon'- 'cur:USD'- 'cur:\\$'- 'amt:'>0''-- * Add a 'not:' prefix to negate a term:-- 'not:status:'*''- 'not:desc:'opening|closing''- 'not:cur:USD'-- * Terms with different types are AND-ed, terms with the same type are- OR-ed (mostly; see "Combining query terms" below). The following- query:-- 'date:2022 desc:amazon desc:amzn'-- is interpreted as:-- _date is in 2022 AND ( transaction description contains "amazon" OR- "amzn" )_--* Menu:--* Query types::-* Combining query terms::-* Queries and command options::-* Queries and account aliases::-* Queries and valuation::---File: hledger.info, Node: Query types, Next: Combining query terms, Up: Queries--17.1 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'* or *'REGEX'*-Match account names containing this case insensitive regular expression.-This is the default query type, so we usually don't bother writing the-"acct:" prefix.-- *'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.-Otherwise, the absolute magnitudes are compared, ignoring sign.-- *'code:REGEX'*-Match by transaction code (eg check number).-- *'cur:REGEX'*-Match postings or transactions including any amounts whose-currency/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.-- *'expr:"TERM AND NOT (TERM OR TERM)"'* (eg)-Match with a boolean combination of queries (which must be enclosed in-quotes). See Combining query terms below.-- *'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.-- *'type:TYPECODES'*-Match by account type (see Declaring accounts > Account types).-'TYPECODES' is one or more of the single-letter account type codes-'ALERXCV', case insensitive. Note 'type:A' and 'type:E' will also match-their respective subtypes 'C' (Cash) and 'V' (Conversion). Certain-kinds of account alias can disrupt account types, see Rewriting accounts-> Aliases and account types.-- *'tag:REGEX[=REGEX]'*-Match by tag name, and optionally also by tag value. (To match only by-value, use 'tag:.=REGEX'.)-- When querying by tag, note that:-- * Accounts also inherit the tags of their parent accounts- * Postings also inherit the tags of their account and their- transaction- * Transactions also acquire the tags of their postings.-- (*'inacct:ACCTNAME'*-A special query term used automatically in hledger-web only: tells-hledger-web to show the transaction register for an account.)---File: hledger.info, Node: Combining query terms, Next: Queries and command options, Prev: Query types, Up: Queries--17.2 Combining query terms-==========================--When given multiple space-separated query terms, most commands select-things which match:-- * any of the description terms AND- * any of the account terms AND- * any of the status terms AND- * all the other terms.-- The print command is a little different, showing transactions which:-- * match any of the description terms AND- * have any postings matching any of the positive account terms AND- * have no postings matching any of the negative account terms AND- * match all the other terms.-- We also support more complex boolean queries with the 'expr:' prefix.-This allows one to combine query terms using 'and', 'or', 'not' keywords-(case insensitive), and to group them by enclosing in parentheses.-- Some examples:-- * Exclude account names containing 'food':-- 'expr:"not food"' ('not:food' is equivalent)-- * Match things which have 'cool' in the description and the 'A' tag:-- 'expr:"desc:cool and tag:A"' ('expr:"desc:cool tag:A"' is- equivalent)-- * Match things which either do not reference the 'expenses:food'- account, or do have the 'A' tag:-- 'expr:"not expenses:food or tag:A"'-- * Match things which either do not reference the 'expenses:food'- account, or which reference the 'expenses:drink' account and also- have the 'A' tag:-- 'expr:"expenses:food or (expenses:drink and tag:A)"'-- 'expr:' has a restriction: 'date:' queries may not be used inside-'or' expressions. That would allow disjoint report periods or disjoint-result sets, with unclear semantics for our reports.---File: hledger.info, Node: Queries and command options, Next: Queries and account aliases, Prev: Combining query terms, Up: Queries--17.3 Queries and command options-================================--Some queries can also be expressed as command-line options: 'depth:2' is-equivalent to '--depth 2', 'date:2023' is equivalent to '-p 2023', etc.-When you mix command options and query arguments, generally the-resulting query is their intersection.---File: hledger.info, Node: Queries and account aliases, Next: Queries and valuation, Prev: Queries and command options, Up: Queries--17.4 Queries and account aliases-================================--When account names are rewritten with '--alias' or 'alias', 'acct:' will-match either the old or the new account name.---File: hledger.info, Node: Queries and valuation, Prev: Queries and account aliases, Up: Queries--17.5 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, #1625.)---File: hledger.info, Node: Pivoting, Next: Generating data, Prev: Queries, Up: Top--18 Pivoting-***********--Normally, hledger groups and sums amounts within each account. The-'--pivot FIELD' option substitutes some other transaction field for-account names, causing amounts to be grouped and summed by that field's-value instead. FIELD can be any of the transaction fields 'acct',-'status', 'code', 'desc', 'payee', 'note', or a tag name. When pivoting-on a tag and a posting has multiple values of that tag, only the first-value is displayed. Values containing 'colon:separated:parts' will be-displayed hierarchically, like account names. Multiple, colon-delimited-fields can be pivoted simultaneously, generating a hierarchical account-name.-- Some examples:--2016/02/16 Yearly Dues Payment- assets:bank account 2 EUR- income:dues -2 EUR ; member: John Doe, kind: Lifetime-- Normal balance report showing account names:--$ hledger balance- 2 EUR assets:bank account- -2 EUR income:dues---------------------- 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):--$ 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-- Hierarchical reports can be generated with multiple pivots:--$ hledger balance Income:Dues --pivot kind:member- -2 EUR Lifetime:John Doe---------------------- -2 EUR---File: hledger.info, Node: Generating data, Next: Forecasting, Prev: Pivoting, Up: Top--19 Generating data-******************--hledger has several features for generating data, such as:-- * Periodic transaction rules can generate single or repeating- transactions following a template. These are usually dated in the- future, eg to help with forecasting. They are activated by the- '--forecast' option.-- * The balance command's '--budget' option uses these same periodic- rules to generate goals for the budget report.-- * Auto posting rules can generate extra postings on certain matched- transactions. They are always applied to forecast transactions;- with the '--auto' flag they are applied to transactions recorded in- the journal as well.-- * The '--infer-equity' flag infers missing conversion equity postings- from @/@@ costs. And the inverse '--infer-costs' flag infers- missing @/@@ costs from conversion equity postings.-- Generated data of this kind is temporary, existing only at report-time. But you can see it in the output of 'hledger print', and you can-save that to your journal, in effect converting it from temporary-generated data to permanent recorded data. This could be useful as a-data entry aid.-- If you are wondering what data is being generated and why, add the-'--verbose-tags' flag. In 'hledger print' output you will see extra-tags like 'generated-transaction', 'generated-posting', and 'modified'-on generated/modified data. Also, even without '--verbose-tags',-generated data always has equivalen hidden tags (with an underscore-prefix), so eg you could match generated transactions with-'tag:_generated-transaction'.---File: hledger.info, Node: Forecasting, Next: Budgeting, Prev: Generating data, Up: Top--20 Forecasting-**************--Forecasting, or speculative future reporting, can be useful for-estimating future balances, or for exploring different future scenarios.-- The simplest and most flexible way to do it with hledger is to-manually record a bunch of future-dated transactions. You could keep-these in a separate 'future.journal' and include that with '-f' only-when you want to see them.--* Menu:--* --forecast::-* Inspecting forecast transactions::-* Forecast reports::-* Forecast tags::-* Forecast period in detail::-* Forecast troubleshooting::---File: hledger.info, Node: --forecast, Next: Inspecting forecast transactions, Up: Forecasting--20.1 -forecast-==============--There is another way: with the '--forecast' option, hledger can generate-temporary "forecast transactions" for reporting purposes, according to-periodic transaction rules defined in the journal. Each rule can-generate multiple recurring transactions, so by changing one rule you-can change many forecasted transactions.-- Forecast transactions usually start after ordinary transactions end.-By default, they begin after your latest-dated ordinary transaction, or-today, whichever is later, and they end six months from today. (The-exact rules are a little more complicated, and are given below.)-- This is the "forecast period", which need not be the same as the-report period. You can override it - eg to forecast farther into the-future, or to force forecast transactions to overlap your ordinary-transactions - by giving the -forecast option a period expression-argument, like '--forecast=..2099' or '--forecast=2023-02-15..'. Note-that the '=' is required.---File: hledger.info, Node: Inspecting forecast transactions, Next: Forecast reports, Prev: --forecast, Up: Forecasting--20.2 Inspecting forecast transactions-=====================================--'print' is the best command for inspecting and troubleshooting forecast-transactions. Eg:--~ monthly from 2022-12-20 rent- assets:bank:checking- expenses:rent $1000--$ hledger print --forecast --today=2023/4/21-2023-05-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000--2023-06-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000--2023-07-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000--2023-08-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000--2023-09-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- Here there are no ordinary transactions, so the forecasted-transactions begin on the first occurence after today's date. (You-won't normally use '--today'; it's just to make these examples-reproducible.)---File: hledger.info, Node: Forecast reports, Next: Forecast tags, Prev: Inspecting forecast transactions, Up: Forecasting--20.3 Forecast reports-=====================--Forecast transactions affect all reports, as you would expect. Eg:--$ hledger areg rent --forecast --today=2023/4/21-Transactions in expenses:rent and subaccounts:-2023-05-20 rent as:ba:checking $1000 $1000-2023-06-20 rent as:ba:checking $1000 $2000-2023-07-20 rent as:ba:checking $1000 $3000-2023-08-20 rent as:ba:checking $1000 $4000-2023-09-20 rent as:ba:checking $1000 $5000--$ hledger bal -M expenses --forecast --today=2023/4/21-Balance changes in 2023-05-01..2023-09-30:-- || May Jun Jul Aug Sep -===============++===================================- expenses:rent || $1000 $1000 $1000 $1000 $1000 ----------------++------------------------------------ || $1000 $1000 $1000 $1000 $1000 ---File: hledger.info, Node: Forecast tags, Next: Forecast period in detail, Prev: Forecast reports, Up: Forecasting--20.4 Forecast tags-==================--Forecast transactions generated by -forecast have a hidden tag,-'_generated-transaction'. So if you ever need to match forecast-transactions, you could use 'tag:_generated-transaction' (or just-'tag:generated') in a query.-- For troubleshooting, you can add the '--verbose-tags' flag. Then,-visible 'generated-transaction' tags will be added also, so you can view-them with the 'print' command. Their value indicates which periodic-rule was responsible.---File: hledger.info, Node: Forecast period in detail, Next: Forecast troubleshooting, Prev: Forecast tags, Up: Forecasting--20.5 Forecast period, in detail-===============================--Forecast start/end dates are chosen so as to do something useful by-default in almost all situations, while also being flexible. Here are-(with luck) the exact rules, to help with troubleshooting:-- The forecast period starts on:-- * the later of- * the start date in the periodic transaction rule- * the start date in '--forecast''s argument-- * otherwise (if those are not available): the later of- * the report start date specified with '-b'/'-p'/'date:'- * the day after the latest ordinary transaction in the journal-- * otherwise (if none of these are available): today.-- The forecast period ends on:-- * the earlier of- * the end date in the periodic transaction rule- * the end date in '--forecast''s argument-- * otherwise: the report end date specified with '-e'/'-p'/'date:'- * otherwise: 180 days (~6 months) from today.---File: hledger.info, Node: Forecast troubleshooting, Prev: Forecast period in detail, Up: Forecasting--20.6 Forecast troubleshooting-=============================--When -forecast is not doing what you expect, one of these tips should-help:-- * Remember to use the '--forecast' option.- * Remember to have at least one periodic transaction rule in your- journal.- * Test with 'print --forecast'.- * Check for typos or too-restrictive start/end dates in your periodic- transaction rule.- * Leave at least 2 spaces between the rule's period expression and- description fields.- * Check for future-dated ordinary transactions suppressing forecasted- transactions.- * Try setting explicit report start and/or end dates with '-b', '-e',- '-p' or 'date:'- * Try adding the '-E' flag to encourage display of empty periods/zero- transactions.- * Try setting explicit forecast start and/or end dates with- '--forecast=START..END'- * Consult Forecast period, in detail, above.- * Check inside the engine: add '--debug=2' (eg).---File: hledger.info, Node: Budgeting, Next: Cost reporting, Prev: Forecasting, Up: Top--21 Budgeting-************--With the balance command's '--budget' report, each periodic transaction-rule generates recurring budget goals in specified accounts, and goals-and actual performance can be compared. See the balance command's doc-below.-- You can generate budget goals and forecast transactions at the same-time, from the same or different periodic transaction rules: 'hledger-bal -M --budget --forecast ...'-- See also: Budgeting and Forecasting.---File: hledger.info, Node: Cost reporting, Next: Value reporting, Prev: Budgeting, Up: Top--22 Cost reporting-*****************--In some transactions - for example a currency conversion, or a purchase-or sale of stock - one commodity is exchanged for another. In these-transactions there is a conversion rate, also called the cost (when-buying) or selling price (when selling). In hledger docs we just say-"cost", for convenience; feel free to mentally translate to "conversion-rate" or "selling price" if helpful.--* Menu:--* Recording costs::-* Reporting at cost::-* Equity conversion postings::-* Inferring equity conversion postings::-* Combining costs and equity conversion postings::-* Requirements for detecting equity conversion postings::-* Infer cost and equity by default ?::---File: hledger.info, Node: Recording costs, Next: Reporting at cost, Up: Cost reporting--22.1 Recording costs-====================--We'll explore several ways of recording transactions involving costs.-These are also summarised at hledger Cookbook > Cost notation.-- Costs can be recorded explicitly in the journal, using the '@-UNITCOST' or '@@ TOTALCOST' notation described in Journal > Costs:-- *Variant 1*--2022-01-01- assets:dollars $-135- assets:euros €100 @ $1.35 ; $1.35 per euro (unit cost)-- *Variant 2*--2022-01-01- assets:dollars $-135- assets:euros €100 @@ $135 ; $135 total cost-- Typically, writing the unit cost (variant 1) is preferable; it can be-more effort, requiring more attention to decimal digits; but it reveals-the per-unit cost basis, and makes stock sales easier.-- Costs can also be left implicit, and hledger will infer the cost that-is consistent with a balanced transaction:-- *Variant 3*--2022-01-01- assets:dollars $-135- assets:euros €100-- Here, hledger will attach a '@@ €100' cost to the first amount (you-can see it with 'hledger print -x'). This form looks convenient, but-there are downsides:-- * It sacrifices some error checking. For example, if you- accidentally wrote €10 instead of €100, hledger would not be able- to detect the mistake.-- * It is sensitive to the order of postings - if they were reversed, a- different entry would be inferred and reports would be different.-- * The per-unit cost basis is not easy to read.-- So generally this kind of entry is not recommended. You can make-sure you have none of these by using '-s' (strict mode), or by running-'hledger check balanced'.---File: hledger.info, Node: Reporting at cost, Next: Equity conversion postings, Prev: Recording costs, Up: Cost reporting--22.2 Reporting at cost-======================--Now when you add the '-B'/'--cost' flag to reports ("B" is from Ledger's--B/-basis/-cost flag), any amounts which have been annotated with costs-will be converted to their cost's commodity (in the report output). Ie-they will be displayed "at cost" or "at sale price".-- Some things to note:-- * Costs are attached to specific posting amounts in specific- transactions, and once recorded they do not change. This contrasts- with market prices, which are ambient and fluctuating.-- * Conversion to cost is performed before conversion to market value- (described below).---File: hledger.info, Node: Equity conversion postings, Next: Inferring equity conversion postings, Prev: Reporting at cost, Up: Cost reporting--22.3 Equity conversion postings-===============================--There is a problem with the entries above - they are not conventional-Double Entry Bookkeeping (DEB) notation, and because of the "magical"-transformation of one commodity into another, they cause an imbalance in-the Accounting Equation. This shows up as a non-zero grand total in-balance reports like 'hledger bse'.-- For most hledger users, this doesn't matter in practice and can-safely be ignored ! But if you'd like to learn more, keep reading.-- Conventional DEB uses an extra pair of equity postings to balance the-transaction. Of course you can do this in hledger as well:-- *Variant 4*--2022-01-01- assets:dollars $-135- assets:euros €100- equity:conversion $135- equity:conversion €-100-- Now the transaction is perfectly balanced according to standard DEB,-and 'hledger bse''s total will not be disrupted.-- And, hledger can still infer the cost for cost reporting, but it's-not done by default - you must add the '--infer-costs' flag like so:--$ hledger print --infer-costs-2022-01-01 one hundred euros purchased at $1.35 each- assets:dollars $-135 @@ €100- assets:euros €100- equity:conversion $135- equity:conversion €-100--$ hledger bal --infer-costs -B- €-100 assets:dollars - €100 assets:euros --------------------- - 0 -- Here are some downsides of this kind of entry:-- * The per-unit cost basis is not easy to read.-- * Instead of '-B' you must remember to type '-B --infer-costs'.-- * '--infer-costs' works only where hledger can identify the two- equity:conversion postings and match them up with the two- non-equity postings. So writing the journal entry in a particular- format becomes more important. More on this below.---File: hledger.info, Node: Inferring equity conversion postings, Next: Combining costs and equity conversion postings, Prev: Equity conversion postings, Up: Cost reporting--22.4 Inferring equity conversion postings-=========================================--Can we go in the other direction ? Yes, if you have transactions-written with the @/@@ cost notation, hledger can infer the missing-equity postings, if you add the '--infer-equity' flag. Eg:--2022-01-01- assets:dollars -$135- assets:euros €100 @ $1.35--$ hledger print --infer-equity-2022-01-01- assets:dollars $-135- assets:euros €100 @ $1.35- equity:conversion:$-€:€ €-100- equity:conversion:$-€:$ $135.00-- The equity account names will be "equity:conversion:A-B:A" and-"equity:conversion:A-B:B" where A is the alphabetically first commodity-symbol. You can customise the "equity:conversion" part by declaring an-account with the 'V'/'Conversion' account type.---File: hledger.info, Node: Combining costs and equity conversion postings, Next: Requirements for detecting equity conversion postings, Prev: Inferring equity conversion postings, Up: Cost reporting--22.5 Combining costs and equity conversion postings-===================================================--Finally, you can use both the @/@@ cost notation and equity postings at-the same time. This in theory gives the best of all worlds - preserving-the accounting equation, revealing the per-unit cost basis, and-providing more flexibility in how you write the entry:-- *Variant 5*--2022-01-01 one hundred euros purchased at $1.35 each- assets:dollars $-135- equity:conversion $135- equity:conversion €-100- assets:euros €100 @ $1.35-- All the other variants above can (usually) be rewritten to this final-form with:--$ hledger print -x --infer-costs --infer-equity-- Downsides:-- * The precise format of the journal entry becomes more important. If- hledger can't detect and match up the cost and equity postings, it- will give a transaction balancing error.-- * The add command does not yet accept this kind of entry (#2056).-- * This is the most verbose form.---File: hledger.info, Node: Requirements for detecting equity conversion postings, Next: Infer cost and equity by default ?, Prev: Combining costs and equity conversion postings, Up: Cost reporting--22.6 Requirements for detecting equity conversion postings-==========================================================--'--infer-costs' has certain requirements (unlike '--infer-equity', which-always works). It will infer costs only in transactions with:-- * Two non-equity postings, in different commodities. Their order is- significant: the cost will be added to the first of them.-- * Two postings to equity conversion accounts, next to one another,- which balance the two non-equity postings. This balancing is- checked to the same precision (number of decimal places) used in- the conversion posting's amount. Equity conversion accounts are:-- * any accounts declared with account type 'V'/'Conversion', or- their subaccounts- * otherwise, accounts named 'equity:conversion', 'equity:trade',- or 'equity:trading', or their subaccounts.-- And multiple such four-posting groups can coexist within a single-transaction. When '--infer-costs' fails, it does not infer a cost in-that transaction, and does not raise an error (ie, it infers costs where-it can).-- Reading variant 5 journal entries, combining cost notation and equity-postings, has all the same requirements. When reading such an entry-fails, hledger raises an "unbalanced transaction" error.---File: hledger.info, Node: Infer cost and equity by default ?, Prev: Requirements for detecting equity conversion postings, Up: Cost reporting--22.7 Infer cost and equity by default ?-=======================================--Should '--infer-costs' and '--infer-equity' be enabled by default ? Try-using them always, eg with a shell alias:--alias h="hledger --infer-equity --infer-costs"-- and let us know what problems you find.---File: hledger.info, Node: Value reporting, Next: PART 4 COMMANDS, Prev: Cost reporting, Up: Top--23 Value reporting-******************--Instead of reporting amounts in their original commodity, hledger can-convert them to cost/sale amount (using the conversion rate recorded in-the transaction), and/or to market value (using some market price on a-certain date). This is controlled by the '--value=TYPE[,COMMODITY]'-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:--* Menu:--* -V Value::-* -X Value in specified commodity::-* Valuation date::-* Finding market price::-* --infer-market-prices market prices from transactions::-* Valuation commodity::-* --value Flexible valuation::-* Valuation examples::-* Interaction of valuation and queries::-* Effect of valuation on reports::---File: hledger.info, Node: -V Value, Next: -X Value in specified commodity, Up: Value reporting--23.1 -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.---File: hledger.info, Node: -X Value in specified commodity, Next: Valuation date, Prev: -V Value, Up: Value reporting--23.2 -X: Value in specified commodity-=====================================--The '-X/--exchange=COMM' option is like '-V', except you tell it which-currency you want to convert to, and it tries to convert everything to-that.---File: hledger.info, Node: Valuation date, Next: Finding market price, Prev: -X Value in specified commodity, Up: Value reporting--23.3 Valuation date-===================--Market prices can change from day to day. hledger will use the prices-on a particular valuation date (or on more than one date). By default-hledger uses "end" dates for valuation. More specifically:-- * For single period reports (including normal print and register- reports):- * If an explicit report end date is specified, that is used- * Otherwise the latest transaction date or P directive date is- used (even if it's in the future)-- * For multiperiod reports, each period is valued on its last day.-- This can be customised with the -value option described below, which-can select either "then", "end", "now", or "custom" dates. (Note, this-has a bug in hledger-ui <=1.31: turning on valuation with the 'V' key-always resets it to "end".)---File: hledger.info, Node: Finding market price, Next: --infer-market-prices market prices from transactions, Prev: Valuation date, Up: Value reporting--23.4 Finding market price-=========================--To convert a commodity A to its market value in another commodity B,-hledger looks for a suitable market price (exchange rate) as follows, 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 directive, or (with the '--infer-market-prices' flag) inferred- from costs.-- 2. A _reverse market price_: the inverse of a declared or inferred- market price from B to A.-- 3. A _forward chain of market prices_: a synthetic price formed by- combining 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-converted.---File: hledger.info, Node: --infer-market-prices market prices from transactions, Next: Valuation commodity, Prev: Finding market price, Up: Value reporting--23.5 -infer-market-prices: 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 costs as additional market prices (as-Ledger does) ? Adding the '--infer-market-prices' flag to '-V', '-X' or-'--value' enables this.-- So for example, 'hledger bs -V --infer-market-prices' will get market-prices both from P directives and from transactions. If both occur on-the same day, the P directive takes precedence.-- There is a downside: value reports can sometimes be affected in-confusing/undesired ways by your journal entries. If this happens to-you, read all of this Value reporting section carefully, and try adding-'--debug' or '--debug=2' to troubleshoot.-- '--infer-market-prices' can infer market prices from:-- * multicommodity transactions with explicit prices ('@'/'@@')-- * multicommodity transactions with implicit prices (no '@', two- commodities, unbalanced). (With these, the order of postings- matters. 'hledger print -x' can be useful for troubleshooting.)-- * multicommodity transactions with equity postings, if cost is- inferred with '--infer-costs'.-- There is a limitation (bug) currently: when a valuation commodity is-not specified, prices inferred with '--infer-market-prices' do not help-select a default valuation commodity, as 'P' prices would. So-conversion might not happen because no valuation commodity was detected-('--debug=2' will show this). To be safe, specify the valuation-commmodity, eg:-- * '-X EUR --infer-market-prices', not '-V --infer-market-prices'- * '--value=then,EUR --infer-market-prices', not '--value=then- --infer-market-prices'-- Signed costs and market prices can be confusing. For reference, here-is the current behaviour, since hledger 1.25. (If you think it should-work differently, see #1870.)--2022-01-01 Positive Unit prices- a A 1- b B -1 @ A 1--2022-01-01 Positive Total prices- a A 1- b B -1 @@ A 1---2022-01-02 Negative unit prices- a A 1- b B 1 @ A -1--2022-01-02 Negative total prices- a A 1- b B 1 @@ A -1---2022-01-03 Double Negative unit prices- a A -1- b B -1 @ A -1--2022-01-03 Double Negative total prices- a A -1- b B -1 @@ A -1-- All of the transactions above are considered balanced (and on each-day, the two transactions are considered equivalent). Here are the-market prices inferred for B:--$ hledger -f- --infer-market-prices prices-P 2022-01-01 B A 1-P 2022-01-01 B A 1.0-P 2022-01-02 B A -1-P 2022-01-02 B A -1.0-P 2022-01-03 B A -1-P 2022-01-03 B A -1.0---File: hledger.info, Node: Valuation commodity, Next: --value Flexible valuation, Prev: --infer-market-prices market prices from transactions, Up: Value reporting--23.6 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-suitable 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-prices' flag is used: the price commodity from the- latest transaction-inferred price for A on or before valuation- date.-- This means:-- * If you have P directives, they determine which commodities '-V'- will convert, and to what.-- * If you have no P directives, and use the '--infer-market-prices'- flag, costs determine it.-- Amounts for which no valuation commodity can be found are not-converted.---File: hledger.info, Node: --value Flexible valuation, Next: Valuation examples, Prev: Valuation commodity, Up: Value reporting--23.7 -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 commodity,- using market prices on each posting's date.-'--value=end'-- Convert amounts to their value in the default valuation commodity,- using market prices on the last day of the report period (or if- unspecified, the journal'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 commodity- using current market prices (as of when report is generated).-'--value=YYYY-MM-DD'-- Convert amounts to their value in the default valuation commodity- 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.---File: hledger.info, Node: Valuation examples, Next: Interaction of valuation and queries, Prev: --value Flexible valuation, Up: Value reporting--23.8 Valuation examples-=======================--Here are some quick examples of '-V':--; one euro is worth this many dollars from nov 1-P 2016/11/01 € $1.10--; purchase some euros on nov 3-2016/11/3- assets:euros €100- assets:checking--; the euro is worth fewer dollars by dec 21-P 2016/12/21 € $1.03-- How many euros do I have ?--$ hledger -f t.j bal -N euros- €100 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-- 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---File: hledger.info, Node: Interaction of valuation and queries, Next: Effect of valuation on reports, Prev: Valuation examples, Up: Value reporting--23.9 Interaction of valuation and queries-=========================================--When matching postings based on queries in the presence of valuation,-the following happens:-- 1. The query is separated into two parts:- 1. the currency ('cur:') or amount ('amt:').- 2. all other parts.-- 2. The postings are matched to the currency and amount queries based- on pre-valued amounts.- 3. Valuation is applied to the postings.- 4. The postings are matched to the other parts of the query based on- post-valued amounts.-- Related: #1625---File: hledger.info, Node: Effect of valuation on reports, Prev: Interaction of valuation and queries, Up: Value reporting--23.10 Effect of valuation on reports-====================================--Here is a reference for how valuation is supposed to affect each part of-hledger's reports. (It's wide, you may need to scroll sideways.) It-may be useful when troubleshooting. If you find problems, please report-them, ideally with a reproducible example. Related: #329, #1083.-- First, a quick 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- subperiods).--Report '-B', '-V', '-X' '--value=then' '--value=end''--value=DATE',-type '--cost' '--value=now'--------------------------------------------------------------------------------*print*-posting cost value at value at posting value at value-amounts report end date report or at- or today journal DATE/today- end-balance unchanged unchanged unchanged unchanged unchanged-assertions/assignments-*register*-starting cost value at valued at day value at value-balance report or each historical report or at-(-H) journal posting was made journal DATE/today- end end-starting cost value at valued at day value at value-balance day before each historical day before at-(-H) report or posting was made report or DATE/today-with journal journal-report start start-interval-posting cost value at value at posting value at value-amounts report or date report or at- journal journal DATE/today- end end-summary summarised value at sum of postings value at value-posting cost period in interval, period at-amounts ends valued at ends DATE/today-with interval start-report-interval-running sum/average sum/average sum/average of sum/average sum/average-total/averageof of displayed values of of- displayed displayed displayed displayed- values values values values-*balance-(bs,-bse, cf,-is)*-balance sums of value at value at posting value at value-changes costs report end date report or at- or today journal DATE/today- of sums of end of of- postings sums of sums- postings of- postings-budget like like like balance like like-amounts balance balance changes balances balance-(-budget) changes changes changes-grand sum of sum of sum of displayed sum of sum of-total displayed displayed valued displayed displayed- values values values values-*balance-(bs,-bse, cf,-is) with-report-interval*-starting sums of value at sums of values value at sums-balances costs of report of postings report of-(-H) postings start of before report start of postings- before sums of start at sums of before- report all respective all report- start postings posting dates postings start- before before- report report- start start-balance sums of same as sums of values balance value-changes costs of -value=end of postings in change in at-(bal, postings period at each DATE/today-is, bs in period respective period, of--change, posting dates valued at sums-cf period of--change) ends postings-end sums of same as sums of values period end value-balances costs of -value=end of postings from balances, at-(bal -H, postings before period valued at DATE/today-is -H, from start to period period of-bs, cf) before end at ends sums- report respective of- start to posting dates postings- period end-budget like like like balance like like-amounts balance balance changes/end balances balance-(-budget) changes/end changes/end balances changes/end- balances balances balances-row sums, sums, sums, averages sums, sums,-totals, averages averages of displayed averages averages-row of of values of of-averages displayed displayed displayed displayed-(-T, -A) values values values values-column sums of sums of sums of sums of sums-totals displayed displayed displayed values displayed of- values values values displayed- values-grand sum, sum, sum, average of sum, sum,-total, average of average of column totals average of average-grand column column column of-average totals totals totals column- totals-- '--cumulative' is omitted to save space, it works like '-H' but with-a zero starting balance.---File: hledger.info, Node: PART 4 COMMANDS, Next: PART 5 COMMON TASKS, Prev: Value reporting, Up: Top--24 PART 4: COMMANDS-*******************--* Menu:--* Commands overview::-* accounts::-* activity::-* add::-* aregister::-* balance::-* balancesheet::-* balancesheetequity::-* cashflow::-* check::-* close::-* codes::-* commodities::-* demo::-* descriptions::-* diff::-* files::-* help::-* import::-* incomestatement::-* notes::-* payees::-* prices::-* print::-* register::-* rewrite::-* roi::-* stats::-* tags::-* test::---File: hledger.info, Node: Commands overview, Next: accounts, Up: PART 4 COMMANDS--24.1 Commands overview-======================--Here are the built-in commands:--* Menu:--* DATA ENTRY::-* DATA CREATION::-* DATA MANAGEMENT::-* REPORTS FINANCIAL::-* REPORTS VERSATILE::-* REPORTS BASIC::-* HELP::-* ADD-ONS::---File: hledger.info, Node: DATA ENTRY, Next: DATA CREATION, Up: Commands overview--24.1.1 DATA ENTRY--------------------These data entry commands are the only ones which can modify your-journal file.-- * add - add transactions using terminal prompts- * import - add new transactions from other files, eg CSV files---File: hledger.info, Node: DATA CREATION, Next: DATA MANAGEMENT, Prev: DATA ENTRY, Up: Commands overview--24.1.2 DATA CREATION----------------------- * close - generate balance-zeroing/restoring transactions- * rewrite - generate auto postings, like print -auto---File: hledger.info, Node: DATA MANAGEMENT, Next: REPORTS FINANCIAL, Prev: DATA CREATION, Up: Commands overview--24.1.3 DATA MANAGEMENT------------------------- * check - check for various kinds of error in the data- * diff - compare account transactions in two journal files---File: hledger.info, Node: REPORTS FINANCIAL, Next: REPORTS VERSATILE, Prev: DATA MANAGEMENT, Up: Commands overview--24.1.4 REPORTS, FINANCIAL---------------------------- * aregister (areg) - show transactions in a particular account- * balancesheet (bs) - show assets, liabilities and net worth- * balancesheetequity (bse) - show assets, liabilities and equity- * cashflow (cf) - show changes in liquid assets- * incomestatement (is) - show revenues and expenses---File: hledger.info, Node: REPORTS VERSATILE, Next: REPORTS BASIC, Prev: REPORTS FINANCIAL, Up: Commands overview--24.1.5 REPORTS, VERSATILE---------------------------- * balance (bal) - show balance changes, end balances, budgets,- gains..- * print - show transactions or export journal data- * register (reg) - show postings in one or more accounts & running- total- * roi - show return on investments---File: hledger.info, Node: REPORTS BASIC, Next: HELP, Prev: REPORTS VERSATILE, Up: Commands overview--24.1.6 REPORTS, BASIC------------------------ * accounts - show account names- * activity - show bar charts of posting counts per period- * codes - show transaction codes- * commodities - show commodity/currency symbols- * descriptions - show transaction descriptions- * files - show input file paths- * notes - show note parts of transaction descriptions- * payees - show payee parts of transaction descriptions- * prices - show market prices- * stats - show journal statistics- * tags - show tag names- * test - run self tests---File: hledger.info, Node: HELP, Next: ADD-ONS, Prev: REPORTS BASIC, Up: Commands overview--24.1.7 HELP-------------- * help - show the hledger manual with info/man/pager- * demo - show small hledger demos in the terminal---File: hledger.info, Node: ADD-ONS, Prev: HELP, Up: Commands overview--24.1.8 ADD-ONS-----------------And here are some typical add-on commands. Some of these are installed-by the hledger-install script. If installed, they will appear in-hledger's commands list:-- * ui - run hledger's terminal UI- * web - run hledger's web UI- * iadd - add transactions using a TUI (currently hard to build)- * interest - generate interest transactions- * stockquotes - download market prices from AlphaVantage- * Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,- pijul, plot, and more..-- Next, each command is described in detail, in alphabetical order.---File: hledger.info, Node: accounts, Next: activity, Prev: Commands overview, Up: PART 4 COMMANDS--24.2 accounts-=============--Show account names.-- This command lists account names. By default it shows all known-accounts, either used in transactions or declared with account-directives.-- With query arguments, only matched account names and account names-referenced by matched postings are shown.-- Or it can show just the used accounts ('--used'/'-u'), the declared-accounts ('--declared'/'-d'), the accounts declared but not used-('--unused'), the accounts used but not declared ('--undeclared'), or-the first account matched by an account name pattern, if any ('--find').-- It shows a flat list by default. With '--tree', it uses indentation-to show the account hierarchy. In flat mode you can add '--drop N' to-omit the first few account name components. Account names can be-depth-clipped with 'depth:N' or '--depth N' or '-N'.-- With '--types', it also shows each account's type, if it's known.-(See Declaring accounts > Account types.)-- With '--positions', it also shows the file and line number of each-account's declaration, if any, and the account's overall declaration-order; these may be useful when troubleshooting account display order.-- With '--directives', it adds the 'account' keyword, showing valid-account directives which can be pasted into a journal file. This is-useful together with '--undeclared' when updating your account-declarations to satisfy 'hledger check accounts'.-- The '--find' flag can be used to look up a single account name, in-the same way that the 'aregister' command does. It returns the-alphanumerically-first matched account name, or if none can be found, it-fails with a non-zero exit code.-- Examples:--$ hledger accounts-assets:bank:checking-assets:bank:saving-assets:cash-expenses:food-expenses:supplies-income:gifts-income:salary-liabilities:debts--$ hledger accounts --undeclared --directives >> $LEDGER_FILE-$ hledger check accounts---File: hledger.info, Node: activity, Next: add, Prev: accounts, Up: PART 4 COMMANDS--24.3 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 **---File: hledger.info, Node: add, Next: aregister, Prev: activity, Up: PART 4 COMMANDS--24.4 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-transactions, and appends them to the main journal file (which should be-in journal format). Existing transactions are not changed. This is one-of the few hledger commands that writes to the journal file (see also-'import').-- To use it, just run 'hledger add' and follow the prompts. You can-add as many transactions as you like; when you are finished, enter '.'-or press control-d or control-c to exit.-- Features:-- * add tries to provide useful defaults, using the most similar (by- description) recent transaction (filtered by the query, if any) as- a template.- * You can also set the initial defaults with command line arguments.- * Readline-style edit keys can be used during data entry.- * The tab key will auto-complete whenever possible - accounts,- payees/descriptions, dates ('yesterday', 'today', 'tomorrow'). If- the input area is empty, it will insert the default value.- * If the journal defines a default commodity, it will be added to any- bare numbers entered.- * A parenthesised transaction code may be entered following a date.- * Comments and tags may be entered following a description or amount.- * If you make a mistake, enter '<' at any prompt to go one step- backward.- * Input prompts are displayed in a different colour when the terminal- supports it.-- Example (see https://hledger.org/add.html for a detailed tutorial):--$ 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> $-- If you enter a number with no commodity symbol, and you have declared-a default commodity with a 'D' directive, you might expect 'add' to add-this symbol for you. It does not do this; we assume that if you are-using a 'D' directive you prefer not to see the commodity symbol-repeated on amounts in the journal.---File: hledger.info, Node: aregister, Next: balance, Prev: add, Up: PART 4 COMMANDS--24.5 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 'aregister' 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.-- When there are multiple matches, the alphabetically-first choice can-be surprising; eg if you have 'assets:per:checking 1' and-'assets:biz:checking 2' accounts, 'hledger areg checking' would select-'assets:biz:checking 2'. It's just a convenience to save typing, so if-in doubt, write the full account name, or a distinctive substring that-matches uniquely.-- 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. 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, see below)- * the names of all the other account(s) involved in this transaction- (probably abbreviated)- * the total change to this account's balance from this transaction- * 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.-- For performance reasons, column widths are chosen based on the first-1000 lines; this means unusually wide values in later lines can cause-visual discontinuities as column widths are adjusted. If you want to-ensure perfect alignment, at the cost of more time and memory, use the-'--align-all' flag.-- This command also supports the output destination and output format-options. The output formats supported are 'txt', 'csv', 'tsv' (_Added-in 1.32_), and 'json'.--* Menu:--* aregister and posting dates::---File: hledger.info, Node: aregister and posting dates, Up: aregister--24.5.1 aregister and posting dates-------------------------------------aregister always shows one line (and date and amount) per transaction.-But sometimes transactions have postings with different dates. Also,-not all of a transaction's postings may be within the report period. To-resolve this, aregister shows the earliest of the transaction's date and-posting dates that is in-period, and the sum of the in-period postings.-In other words it will show a combined line item with just the earliest-date, and the running balance will (temporarily, until the transaction's-last posting) be inaccurate. Use 'register -H' if you need to see the-individual postings.-- There is also a '--txn-dates' flag, which filters strictly by-transaction date, ignoring posting dates. This too can cause an-inaccurate running balance.---File: hledger.info, Node: balance, Next: balancesheet, Prev: aregister, Up: PART 4 COMMANDS--24.6 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',-'balancesheetequity', 'cashflow' and 'incomestatement'. When you need-more control, then use 'balance'.--* Menu:--* balance features::-* Simple balance report::-* Balance report line format::-* Filtered balance report::-* List or tree mode::-* Depth limiting::-* Dropping top-level accounts::-* Showing declared accounts::-* Sorting by amount::-* Percentages::-* Multi-period balance report::-* Balance change end balance::-* Balance report types::-* Budget report::-* Balance report layout::-* Some useful balance reports::---File: hledger.info, Node: balance features, Next: Simple balance report, Up: balance--24.6.1 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..-- * accounts as a list ('-l') or a tree ('-t')- * optionally depth-limited ('-[1-9]')- * sorted by declaration order and name, or by amount-- ..and their..-- * balance changes (the default)- * or actual and planned balance changes ('--budget')- * or value of balance changes ('-V')- * or change of balance values ('--valuechange')- * or unrealised capital gain/loss ('--gain')- * or balance changes from sibling postings ('--related'/'-r')- * or postings count ('--count')-- ..in..-- * one time period (the whole journal period by default)- * or multiple periods ('-D', '-W', '-M', '-Q', '-Y', '-p INTERVAL')-- ..either..-- * per period (the default)- * or accumulated since report start date ('--cumulative')- * or accumulated since account creation ('--historical/-H')-- ..possibly converted to..-- * cost ('--value=cost[,COMM]'/'--cost'/'-B')- * or market value, as of transaction dates ('--value=then[,COMM]')- * or at period ends ('--value=end[,COMM]')- * or now ('--value=now')- * or at some other date ('--value=YYYY-MM-DD')-- ..with..-- * totals ('-T'), averages ('-A'), percentages ('-%'), inverted sign- ('--invert')- * rows and columns swapped ('--transpose')- * another field used as account name ('--pivot')- * custom-formatted line items (single-period reports only)- ('--format')- * commodities displayed on the same line or multiple lines- ('--layout')-- This command supports the output destination and output format-options, with output formats 'txt', 'csv', 'tsv' (_Added in 1.32_),-'json', and (multi-period reports only:) 'html'. In 'txt' output in a-colour-supporting terminal, negative amounts are shown in red.---File: hledger.info, Node: Simple balance report, Next: Balance report line format, Prev: balance features, Up: balance--24.6.2 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. ("Simple" here-means just one column of numbers, covering a single period. You can-also have multi-period reports, described later.)-- For real-world accounts, these numbers will normally be their end-balance at the end of the journal period; more on this below.-- Accounts are sorted by declaration order if any, and then-alphabetically by account name. For instance (using-examples/sample.journal):--$ hledger -f examples/sample.journal bal- $1 assets:bank:saving- $-2 assets:cash- $1 expenses:food- $1 expenses:supplies- $-1 income:gifts- $-1 income:salary- $1 liabilities:debts---------------------- 0 -- 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.---File: hledger.info, Node: Balance report line format, Next: Filtered balance report, Prev: Simple balance report, Up: balance--24.6.3 Balance report line format------------------------------------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 -f examples/sample.journal 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 specifies the formatting applied to each-account/balance pair. It may contain any suitable text, with data-fields interpolated like so:-- '%[MIN][.MAX](FIELDNAME)'-- * MIN pads with spaces to at least this width (optional)-- * MAX truncates at this width (optional)-- * FIELDNAME must be enclosed in parentheses, and can be one of:-- * 'depth_spacer' - a number of spaces equal to the account's- depth, or if MIN is specified, MIN * depth spaces.- * 'account' - the account's name- * 'total' - the account's balance/posted total, right justified-- Also, FMT can begin with an optional prefix to control how-multi-commodity amounts are rendered:-- * '%_' - render on multiple lines, bottom-aligned (the default)- * '%^' - render on multiple lines, top-aligned- * '%,' - 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:-- * '%(total)' - the account's total- * '%-20.20(account)' - the account's name, left justified, padded to- 20 characters and clipped at 20 characters- * '%,%-50(account) %25(total)' - account name padded to 50- characters, total padded to 20 characters, with multiple- commodities rendered on one line- * '%20(total) %2(depth_spacer)%-(account)' - the default format for- the single-column balance report---File: hledger.info, Node: Filtered balance report, Next: List or tree mode, Prev: Balance report line format, Up: balance--24.6.4 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 -f examples/sample.journal bal --cleared assets date:200806- $-2 assets:cash---------------------- $-2 ---File: hledger.info, Node: List or tree mode, Next: Depth limiting, Prev: Filtered balance report, Up: balance--24.6.5 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 -f examples/sample.journal balance- $-1 assets- $1 bank:saving- $-2 cash- $2 expenses- $1 food- $1 supplies- $-2 income- $-1 gifts- $-1 salary- $1 liabilities:debts---------------------- 0-- Notes:-- * "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).-- * 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-plaintextaccounting-users. A tree mode report's final total is- the sum of the top-level balances shown, not of all the balances- shown.-- * Each group of sibling accounts (ie, under a common parent) is- sorted separately.---File: hledger.info, Node: Depth limiting, Next: Dropping top-level accounts, Prev: List or tree mode, Up: balance--24.6.6 Depth limiting------------------------With a 'depth:NUM' query, or '--depth NUM' option, or just '-NUM' (eg:-'-3') balance reports will show accounts only to the specified depth,-hiding the deeper subaccounts. This can be useful for getting an-overview without too much detail.-- Account balances at the depth limit always include the balances from-any deeper subaccounts (even in list mode). Eg, limiting to depth 1:--$ hledger -f examples/sample.journal balance -1- $-1 assets- $2 expenses- $-2 income- $1 liabilities---------------------- 0 ---File: hledger.info, Node: Dropping top-level accounts, Next: Showing declared accounts, Prev: Depth limiting, Up: balance--24.6.7 Dropping top-level accounts-------------------------------------You can also hide one or more top-level account name parts, using-'--drop NUM'. This can be useful for hiding repetitive top-level-account names:--$ hledger -f examples/sample.journal bal expenses --drop 1- $1 food- $1 supplies---------------------- $2 ---File: hledger.info, Node: Showing declared accounts, Next: Sorting by amount, Prev: Dropping top-level accounts, Up: balance--24.6.8 Showing declared accounts-----------------------------------With '--declared', accounts which have been declared with an account-directive will be included in the balance report, even if they have no-transactions. (Since they will have a zero balance, you will also need-'-E/--empty' to see them.)-- More precisely, _leaf_ declared accounts (with no subaccounts) will-be included, since those are usually the more useful in reports.-- The idea of this is to be able to see a useful "complete" balance-report, even when you don't have transactions in all of your declared-accounts yet.---File: hledger.info, Node: Sorting by amount, Next: Percentages, Prev: Showing declared accounts, Up: balance--24.6.9 Sorting by amount---------------------------With '-S/--sort-amount', accounts with the largest (most positive)-balances are shown first. Eg: 'hledger bal expenses -MAS' shows your-biggest averaged monthly expenses first. When more than one commodity-is present, they will be sorted by the alphabetically earliest commodity-first, and then by subsequent commodities (if an amount is missing a-commodity, it is treated as 0).-- Revenues and liability balances are typically negative, however, so-'-S' shows these in reverse order. To work around this, you can add-'--invert' to flip the signs. (Or, use one of the higher-level reports,-which flip the sign automatically. Eg: 'hledger incomestatement -MAS').---File: hledger.info, Node: Percentages, Next: Multi-period balance report, Prev: Sorting by amount, Up: balance--24.6.10 Percentages----------------------With '-%/--percent', balance reports show each account's value expressed-as a percentage of the (column) total.-- Note it is not useful to calculate percentages if the amounts in a-column 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:€---File: hledger.info, Node: Multi-period balance report, Next: Balance change end balance, Prev: Percentages, Up: balance--24.6.11 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),-'balance' shows a tabular report, with columns representing successive-time periods (and a title):--$ hledger -f examples/sample.journal bal --quarterly income expenses -E-Balance changes in 2008:-- || 2008q1 2008q2 2008q3 2008q4 -===================++=================================- expenses:food || 0 $1 0 0 - expenses:supplies || 0 $1 0 0 - income:gifts || 0 $-1 0 0 - income:salary || $-1 0 0 0 --------------------++---------------------------------- || $-1 $1 0 0 -- Notes:-- * The report's start/end dates will be expanded, if necessary, to- fully encompass the displayed subperiods (so that the first and- last subperiods have the same duration as the others).- * Leading and trailing periods (columns) containing all zeroes are- not shown, unless '-E/--empty' is used.- * Accounts (rows) containing all zeroes are not shown, unless- '-E/--empty' is used.- * Amounts with many commodities are shown in abbreviated form, unless- '--no-elide' is used.- * Average and/or total columns can be added with the '-A/--average'- and '-T/--row-total' flags.- * The '--transpose' flag can be used to exchange rows and columns.- * 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:-- * Hide the totals row with '-N/--no-total'- * Filter to a single currency with 'cur:'- * Convert to a single currency with '-V [--infer-market-price]'- * Use a more compact layout like '--layout=bare'- * Maximize the terminal window- * Reduce the terminal's font size- * View with a pager like less, eg: 'hledger bal -D --color=yes | less- -RS'- * 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')- * Output as HTML and view with a browser: 'hledger bal -D -o a.html- && open a.html'---File: hledger.info, Node: Balance change end balance, Next: Balance report types, Prev: Multi-period balance report, Up: balance--24.6.12 Balance change, end balance--------------------------------------It's important to be clear on the meaning of the numbers shown in-balance 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 postings.)---File: hledger.info, Node: Balance report types, Next: Budget report, Prev: Balance change end balance, Up: balance--24.6.13 Balance report types-------------------------------The balance command is quite flexible; here is the full detail on how to-control what it reports. If the following seems complicated, don't-worry - this is for advanced reporting, and it does take time and-experimentation to get familiar with all the report modes.-- There are three important option groups:-- 'hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]-...'--* Menu:--* Calculation type::-* Accumulation type::-* Valuation type::-* Combining balance report types::---File: hledger.info, Node: Calculation type, Next: Accumulation type, Up: Balance report types--24.6.13.1 Calculation type-..........................--The basic calculation to perform for each table cell. It is one of:-- * '--sum' : sum the posting amounts (*default*)- * '--budget' : sum the amounts, but also show the budget goal amount- (for each account/period)- * '--valuechange' : show the change in period-end historical balance- values (caused by deposits, withdrawals, and/or market price- fluctuations)- * '--gain' : show the unrealised capital gain/loss, (the current- valued balance minus each amount's original cost)- * '--count' : show the count of postings---File: hledger.info, Node: Accumulation type, Next: Valuation type, Prev: Calculation type, Up: Balance report types--24.6.13.2 Accumulation type-...........................--How amounts should accumulate across a report's subperiods/columns.-Another way to say it: which time period's postings should contribute to-each cell's calculation. It is one of:-- * '--change' : calculate with postings from column start to column- end, ie "just this column". Typically used to see- revenues/expenses. (*default for balance, cashflow,- incomestatement*)-- * '--cumulative' : calculate with postings from report start to- column end, ie "previous columns plus this column". Typically used- to show changes accumulated since the report's start date. Not- often used.-- * '--historical/-H' : calculate with postings from journal start to- column end, ie "all postings from before report start date until- this column's end". Typically used to see historical end balances- of assets/liabilities/equity. (*default for balancesheet,- balancesheetequity*)---File: hledger.info, Node: Valuation type, Next: Combining balance report types, Prev: Accumulation type, Up: Balance report types--24.6.13.3 Valuation type-........................--Which kind of value or cost conversion should be applied, if any, before-displaying the report. It is one of:-- * no valuation type : don't convert to cost or value (*default*)- * '--value=cost[,COMM]' : convert amounts to cost (then optionally to- some other commodity)- * '--value=then[,COMM]' : convert amounts to market value on- transaction dates- * '--value=end[,COMM]' : convert amounts to market value on period- end date(s)- (*default with '--valuechange', '--gain'*)- * '--value=now[,COMM]' : convert amounts to market value on today's- date- * '--value=YYYY-MM-DD[,COMM]' : convert amounts to market value on- another date-- or one of the equivalent simpler flags:-- * '-B/--cost' : like -value=cost (though, note -cost and -value are- independent options which can both be used at once)- * '-V/--market' : like -value=end- * '-X COMM/--exchange COMM' : like -value=end,COMM-- See Cost reporting and Value reporting for more about these.---File: hledger.info, Node: Combining balance report types, Prev: Valuation type, Up: Balance report types--24.6.13.4 Combining balance report types-........................................--Most combinations of these options should produce reasonable reports,-but if you find any that seem wrong or misleading, let us know. The-following restrictions are applied:-- * '--valuechange' implies '--value=end'- * '--valuechange' makes '--change' the default when used with the- 'balancesheet'/'balancesheetequity' commands- * '--cumulative' or '--historical' disables '--row-total/-T'-- For reference, here is what the combinations of accumulation and-valuation show:--Valuation:>no valuation '--value= then' '--value= end' '--value=-Accumulation:v YYYY-MM-DD- /now'-------------------------------------------------------------------------------'--change'change in sum of period-end DATE-value- period posting-date value of of change in- market values change in period- in period period-'--cumulative'change from sum of period-end DATE-value- report start to posting-date value of of change- period end market values change from from report- from report report start start to- start to period to period end period end- end-'--historicalchange from sum of period-end DATE-value-/-H' journal start posting-date value of of change- to period end market values change from from journal- (historical end from journal journal start start to- balance) start to period to period end period end- end---File: hledger.info, Node: Budget report, Next: Balance report layout, Prev: Balance report types, Up: balance--24.6.14 Budget report------------------------The '--budget' report type is like a regular balance report, but with-two main differences:-- * Budget goals and performance percentages are also shown, in- brackets- * Accounts which don't have budget goals are hidden by default.-- This is useful for comparing planned and actual income, expenses,-time usage, etc.-- Periodic transaction rules are used to define budget goals. For-example, here's a periodic rule defining monthly goals for bus travel-and food expenses:--;; Budget-~ monthly- (expenses:bus) $30- (expenses:food) $400-- After recording some actual expenses,--;; Two months worth of expenses-2017-11-01- income $-1950- expenses:bus $35- expenses:food:groceries $310- expenses:food:dining $42- expenses:movies $38- assets:bank:checking--2017-12-01- income $-2100- expenses:bus $53- expenses:food:groceries $380- expenses:food:dining $32- expenses:gifts $100- assets:bank:checking-- we can see a budget report like this:--$ hledger bal -M --budget-Budget performance in 2017-11-01..2017-12-31:-- || Nov Dec -===============++============================================- <unbudgeted> || $-425 $-565 - expenses || $425 [ 99% of $430] $565 [131% of $430] - expenses:bus || $35 [117% of $30] $53 [177% of $30] - expenses:food || $352 [ 88% of $400] $412 [103% of $400] ----------------++--------------------------------------------- || 0 [ 0% of $430] 0 [ 0% of $430] -- This is "goal-based budgeting"; you define goals for accounts and-periods, often recurring, and hledger shows performance relative to the-goals. This contrasts with "envelope budgeting", which is more detailed-and strict - useful when cash is tight, but also quite a bit more work.-https://plaintextaccounting.org/Budgeting has more on this topic.--* Menu:--* Using the budget report::-* Budget date surprises::-* Selecting budget goals::-* Budgeting vs forecasting::---File: hledger.info, Node: Using the budget report, Next: Budget date surprises, Up: Budget report--24.6.14.1 Using the budget report-.................................--Historically this report has been confusing and fragile. hledger's-version should be relatively robust and intuitive, but you may still-find surprises. Here are more notes to help with learning and-troubleshooting.-- * In the above example, 'expenses:bus' and 'expenses:food' are shown- because they have budget goals during the report period.-- * Their parent 'expenses' is also shown, with budget goals aggregated- from the children.-- * The subaccounts 'expenses:food:groceries' and- 'expenses:food:dining' are not shown since they have no budget goal- of their own, but they contribute to 'expenses:food''s actual- amount.-- * Unbudgeted accounts 'expenses:movies' and 'expenses:gifts' are also- not shown, but they contribute to 'expenses''s actual amount.-- * The other unbudgeted accounts 'income' and 'assets:bank:checking'- are grouped as '<unbudgeted>'.-- * '--depth' or 'depth:' can be used to limit report depth in the- usual way (but will not reveal unbudgeted subaccounts).-- * Amounts are always inclusive of subaccounts (even in '-l/--list'- mode).-- * Numbers displayed in a -budget report will not always agree with- the totals, because of hidden unbudgeted accounts; this is normal.- '-E/--empty' can be used to reveal the hidden accounts.-- * In the periodic rules used for setting budget goals, unbalanced- postings are convenient.-- * You can filter budget reports with the usual queries, eg to focus- on particular accounts. It's common to restrict them to just- expenses. (The '<unbudgeted>' account is occasionally hard to- exclude; this is because of date surprises, discussed below.)-- * When you have multiple currencies, you may want to convert them to- one ('-X COMM --infer-market-prices') and/or show just one at a- time ('cur:COMM'). If you do need to show multiple currencies at- once, '--layout bare' can be helpful.-- * You can "roll over" amounts (actual and budgeted) to the next- period with '--cumulative'.-- See also: https://hledger.org/budgeting.html.---File: hledger.info, Node: Budget date surprises, Next: Selecting budget goals, Prev: Using the budget report, Up: Budget report--24.6.14.2 Budget date surprises-...............................--With small data, or when starting out, some of the generated budget goal-transaction dates might fall outside the report periods. Eg with the-following journal and report, the first period appears to have no-'expenses:food' budget. (Also the '<unbudgeted>' account should be-excluded by the 'expenses' query, but isn't.):--~ monthly in 2020- (expenses:food) $500--2020-01-15- expenses:food $400- assets:checking--$ hledger bal --budget expenses-Budget performance in 2020-01-15:-- || 2020-01-15 -===============++====================- <unbudgeted> || $400 - expenses:food || 0 [ 0% of $500] ----------------++--------------------- || $400 [80% of $500] -- In this case, the budget goal transactions are generated on first-days of of month (this can be seen with 'hledger print --forecast-tag:generated expenses'). Whereas the report period defaults to just-the 15th day of january (this can be seen from the report table's column-headings).-- To fix this kind of thing, be more explicit about the report period-(and/or the periodic rules' dates). In this case, adding '-b 2020' does-the trick.---File: hledger.info, Node: Selecting budget goals, Next: Budgeting vs forecasting, Prev: Budget date surprises, Up: Budget report--24.6.14.3 Selecting budget goals-................................--By default, the budget report uses all available periodic transaction-rules to generate goals. This includes rules with a different report-interval from your report. Eg if you have daily, weekly and monthly-periodic rules, all of these will contribute to the goals in a monthly-budget report.-- You can select a subset of periodic rules by providing an argument to-the '--budget' flag. '--budget=DESCPAT' will match all periodic rules-whose description contains DESCPAT, a case-insensitive substring (not a-regular expression or query). This means you can give your periodic-rules descriptions (remember that two spaces are needed between period-expression and description), and then select from multiple budgets-defined in your journal.---File: hledger.info, Node: Budgeting vs forecasting, Prev: Selecting budget goals, Up: Budget report--24.6.14.4 Budgeting vs forecasting-..................................--'--forecast' and '--budget' both use the periodic transaction rules in-the journal to generate temporary transactions for reporting purposes.-However they are separate features - though you can use both at the same-time if you want. Here are some differences between them:---forecast -budget----------------------------------------------------------------------------is a general option; it enables is a balance command option;-forecasting with all reports it selects the balance- report's budget mode-generates visible transactions which generates invisible-appear in reports transactions which produce- goal amounts-generates forecast transactions from generates budget goal-after the last regular transaction, to transactions throughout the-the end of the report period; or with report period, optionally-an argument '--forecast=PERIODEXPR' restricted by periods-generates them throughout the specified in the periodic-specified period, both optionally transaction rules-restricted by periods specified in the-periodic transaction rules-uses all periodic rules uses all periodic rules; or- with an argument- '--budget=DESCPAT' uses just- the rules matched by DESCPAT---File: hledger.info, Node: Balance report layout, Next: Some useful balance reports, Prev: Budget report, Up: balance--24.6.15 Balance report layout--------------------------------The '--layout' option affects how balance reports show multi-commodity-amounts and commodity symbols, which can improve readability. It can-also normalise the data for easy consumption by other programs. It has-four possible values:-- * '--layout=wide[,WIDTH]': commodities are shown on a single line,- optionally elided to WIDTH- * '--layout=tall': each commodity is shown on a separate line- * '--layout=bare': commodity symbols are in their own column, amounts- are bare numbers- * '--layout=tidy': data is normalised to easily-consumed "tidy" form,- with one row per data value-- Here are the '--layout' modes supported by each output format Only-CSV output supports all of them:--- txt csv html json sql-----------------------------------------wide Y Y Y-tall Y Y Y-bare Y Y Y-tidy Y-- Examples:--* Menu:--* Wide layout::-* Tall layout::-* Bare layout::-* Tidy layout::---File: hledger.info, Node: Wide layout, Next: Tall layout, Up: Balance report layout--24.6.15.1 Wide layout-.....................--With many commodities, reports can be very wide:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide-Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total -==================++====================================================================================================================================================================================================================- Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT -------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT -- A width limit reduces the width, but some commodities will be hidden:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32-Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total -==================++===========================================================================================================================- Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. -------------------++---------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. ---File: hledger.info, Node: Tall layout, Next: Bare layout, Prev: Wide layout, Up: Balance report layout--24.6.15.2 Tall layout-.....................--Each commodity gets a new line (may be different in each column), and-account names are repeated:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall-Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total -==================++==================================================- Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD - Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT - Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD - Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA - Assets:US:ETrade || 18.00 VHT 294.00 VHT -------------------++--------------------------------------------------- || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD - || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT - || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD - || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA - || 18.00 VHT 294.00 VHT ---File: hledger.info, Node: Bare layout, Next: Tidy layout, Prev: Tall layout, Up: Balance report layout--24.6.15.3 Bare layout-.....................--Commodity symbols are kept in one column, each commodity has its own-row, amounts are bare numbers, account names are repeated:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare-Balance changes in 2012-01-01..2014-12-31:-- || Commodity 2012 2013 2014 Total -==================++=============================================- Assets:US:ETrade || GLD 0 70.00 0 70.00 - Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00 - Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50 - Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00 - Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00 -------------------++---------------------------------------------- || GLD 0 70.00 0 70.00 - || ITOT 10.00 18.00 -11.00 17.00 - || USD 337.18 -98.12 4881.44 5120.50 - || VEA 12.00 10.00 14.00 36.00 - || VHT 106.00 18.00 170.00 294.00 -- Bare layout also affects CSV output, which is useful for producing-data that is easier to consume, eg for making charts:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare-"account","commodity","balance"-"Assets:US:ETrade","GLD","70.00"-"Assets:US:ETrade","ITOT","17.00"-"Assets:US:ETrade","USD","5120.50"-"Assets:US:ETrade","VEA","36.00"-"Assets:US:ETrade","VHT","294.00"-"total","GLD","70.00"-"total","ITOT","17.00"-"total","USD","5120.50"-"total","VEA","36.00"-"total","VHT","294.00"-- Bare layout will sometimes display an extra row for the no-symbol-commodity, because of zero amounts (hledger treats zeroes as-commodity-less, usually). This can break 'hledger-bar' confusingly-(workaround: add a 'cur:' query to exclude the no-symbol row).---File: hledger.info, Node: Tidy layout, Prev: Bare layout, Up: Balance report layout--24.6.15.4 Tidy layout-.....................--This produces normalised "tidy data" (see-https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)-where every variable has its own column and each row represents a single-data point. This is the easiest kind of data for other software to-consume:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy-"account","period","start_date","end_date","commodity","value"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","GLD","0"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","ITOT","10.00"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","USD","337.18"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","VEA","12.00"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","VHT","106.00"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","GLD","70.00"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","ITOT","18.00"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","USD","-98.12"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","VEA","10.00"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","VHT","18.00"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","GLD","0"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","ITOT","-11.00"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","USD","4881.44"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","VEA","14.00"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"---File: hledger.info, Node: Some useful balance reports, Prev: Balance report layout, Up: balance--24.6.16 Some useful balance reports--------------------------------------Some frequently used 'balance' options/reports are:-- * 'bal -M revenues expenses'- Show revenues/expenses in each month. Also available as the- 'incomestatement' command.-- * 'bal -M -H assets liabilities'- Show historical asset/liability balances at each month end. Also- available as the 'balancesheet' command.-- * 'bal -M -H assets liabilities equity'- Show historical asset/liability/equity balances at each month end.- Also available as the 'balancesheetequity' command.-- * 'bal -M assets not:receivable'- Show changes to liquid assets in each month. Also available as the- 'cashflow' command.-- Also:-- * 'bal -M expenses -2 -SA'- Show monthly expenses summarised to depth 2 and sorted by average- amount.-- * 'bal -M --budget expenses'- Show monthly expenses and budget goals.-- * 'bal -M --valuechange investments'- Show monthly change in market value of investment assets.-- * 'bal investments --valuechange -D date:lastweek amt:'>1000' -STA- [--invert]'- Show top gainers [or losers] last week---File: hledger.info, Node: balancesheet, Next: balancesheetequity, Prev: balance, Up: PART 4 COMMANDS--24.7 balancesheet-=================--(bs)-- This command displays a balance sheet, showing historical ending-balances of asset and liability accounts. (To see equity as well, use-the balancesheetequity command.) Amounts are shown with normal positive-sign, as in conventional financial statements.-- This report shows accounts declared with the 'Asset', 'Cash' or-'Liability' type (see account types). Or if no such accounts are-declared, it shows top-level accounts named 'asset' or 'liability' (case-insensitive, plurals allowed) and their subaccounts.-- Example:--$ hledger balancesheet-Balance Sheet 2008-12-31-- || 2008-12-31 -====================++============- Assets || ---------------------++------------- assets:bank:saving || $1 - assets:cash || $-2 ---------------------++------------- || $-1 -====================++============- Liabilities || ---------------------++------------- liabilities:debts || $-1 ---------------------++------------- || $-1 -====================++============- Net: || 0 -- This command is a higher-level variant of the 'balance' command, and-supports 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', 'tsv' (_Added in-1.32_), 'html', and 'json'.---File: hledger.info, Node: balancesheetequity, Next: cashflow, Prev: balancesheet, Up: PART 4 COMMANDS--24.8 balancesheetequity-=======================--(bse)-- This command displays a balance sheet, showing historical ending-balances of asset, liability and equity accounts. Amounts are shown-with normal positive sign, as in conventional financial statements.-- This report shows accounts declared with the 'Asset', 'Cash',-'Liability' or 'Equity' type (see account types). Or if no such-accounts are declared, it shows top-level accounts named 'asset',-'liability' or 'equity' (case insensitive, plurals allowed) and their-subaccounts.-- Example:--$ hledger balancesheetequity-Balance Sheet With Equity 2008-12-31-- || 2008-12-31 -====================++============- Assets || ---------------------++------------- assets:bank:saving || $1 - assets:cash || $-2 ---------------------++------------- || $-1 -====================++============- Liabilities || ---------------------++------------- liabilities:debts || $-1 ---------------------++------------- || $-1 -====================++============- Equity || ---------------------++---------------------------------++------------- || 0 -====================++============- Net: || 0 -- This command is a higher-level variant of the 'balance' command, and-supports 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 report is the easiest way to see if the accounting equation-(A+L+E = 0) is satisfied (after you have done a 'close --retain' to-merge revenues and expenses with equity, and perhaps added-'--infer-equity' to balance your commodity conversions).-- This command also supports the output destination and output format-options The output formats supported are 'txt', 'csv', 'tsv', 'html',-and 'json'.---File: hledger.info, Node: cashflow, Next: check, Prev: balancesheetequity, Up: PART 4 COMMANDS--24.9 cashflow-=============--(cf)-- This command displays a (simple) cashflow statement, showing the-inflows and outflows affecting "cash" (ie, liquid, easily convertible)-assets. Amounts are shown with normal positive sign, as in conventional-financial statements.-- This report shows accounts declared with the 'Cash' type (see account-types). Or if no such accounts are declared, it shows accounts-- * under a top-level account named 'asset' (case insensitive, plural- allowed)- * whose name contains some variation of 'cash', 'bank', 'checking' or- 'saving'.-- More precisely: all accounts matching this case insensitive regular-expression:-- '^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)'-- and their subaccounts.-- An example cashflow report:--$ hledger cashflow-Cashflow Statement 2008-- || 2008 -====================++======- Cash flows || ---------------------++------- assets:bank:saving || $1 - assets:cash || $-2 ---------------------++------- || $-1 -- This command is a higher-level variant of the 'balance' command, and-supports 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', 'tsv' (_Added in-1.32_), 'html', and 'json'.---File: hledger.info, Node: check, Next: close, Prev: cashflow, Up: PART 4 COMMANDS--24.10 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-- If you are an Emacs user, you can also configure flycheck-hledger to-run these checks, providing instant feedback as you edit the journal.-- Here are the checks currently available:--* Menu:--* Default checks::-* Strict checks::-* Other checks::-* Custom checks::-* More about specific checks::---File: hledger.info, Node: Default checks, Next: Strict checks, Up: check--24.10.1 Default checks-------------------------These checks are run automatically by (almost) all hledger commands:-- * *parseable* - data files are in a supported format, with no syntax- errors and no invalid include directives.-- * *autobalanced* - all transactions are balanced, after converting to- cost. Missing amounts and missing costs are inferred automatically- where possible.-- * *assertions* - all balance assertions in the journal are passing.- (This check can be disabled with '-I'/'--ignore-assertions'.)---File: hledger.info, Node: Strict checks, Next: Other checks, Prev: Default checks, Up: check--24.10.2 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':-- * *balanced* - all transactions are balanced after converting to- cost, without inferring missing costs. If conversion costs are- required, they must be explicit.-- * *accounts* - all account names used by transactions have been- declared-- * *commodities* - all commodity symbols used have been declared---File: hledger.info, Node: Other checks, Next: Custom checks, Prev: Strict checks, Up: check--24.10.3 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:-- * *ordereddates* - transactions are ordered by date within each file-- * *payees* - all payees used by transactions have been declared-- * *recentassertions* - all accounts with balance assertions have a- balance assertion within 7 days of their latest posting-- * *tags* - all tags used by transactions have been declared-- * *uniqueleafnames* - all account leaf names are unique---File: hledger.info, Node: Custom checks, Next: More about specific checks, Prev: Other checks, Up: check--24.10.4 Custom checks------------------------A few more checks are are available as separate add-on commands, in-https://github.com/simonmichael/hledger/tree/master/bin:-- * *hledger-check-tagfiles* - all tag values containing / (a forward- slash) exist as file paths-- * *hledger-check-fancyassertions* - more complex balance assertions- are passing-- You could make similar scripts to perform your own custom checks.-See: Cookbook -> Scripting.---File: hledger.info, Node: More about specific checks, Prev: Custom checks, Up: check--24.10.5 More about specific checks-------------------------------------'hledger check recentassertions' will complain if any balance-asserted-account has postings more than 7 days after its latest balance-assertion. This aims to prevent the situation where you are regularly-updating your journal, but forgetting to check your balances against the-real world, then one day must dig back through months of data to find an-error. It assumes that adding a balance assertion requires/reminds you-to check the real-world balance. (That may not be true if you-auto-generate balance assertions from bank data; in that case, I-recommend to import transactions uncleared, and when you manually review-and clear them, also check the latest assertion against the real-world-balance.)---File: hledger.info, Node: close, Next: codes, Prev: check, Up: PART 4 COMMANDS--24.11 close-===========--(equity)-- 'close' generates several kinds of "closing" and/or "opening"-transactions, useful in certain situations, including migrating balances-to a new journal file, retaining earnings into equity, consolidating-balances, or viewing lots. Like 'print', it prints valid journal-entries. You can append or copy these to your journal file(s) when you-are happy with how they look.-- 'close' currently has six modes, selected by a single mode flag:--* Menu:--* close --migrate::-* close --close::-* close --open::-* close --assert::-* close --assign::-* close --retain::-* close customisation::-* close and balance assertions::-* close examples::---File: hledger.info, Node: close --migrate, Next: close --close, Up: close--24.11.1 close -migrate-------------------------This is the most common mode. It prints a "closing balances"-transaction that zeroes out all asset and liability balances (by-default), and an opposite "opening balances" transaction that restores-them again. The balancing account will be 'equity:opening/closing-balances' (or another specified by '--close-acct' or '--open-acct').-- This is useful when migrating balances to a new journal file at the-start of a new year. Essentially, you run 'hledger close---migrate=NEWYEAR -e NEWYEAR' and then copy the closing transaction to-the end of the old file and the opening transaction to the start of the-new file. The opening transaction sets correct starting balances in the-new file when it is used alone, and the closing transaction keeps-balances correct when you use both old and new files together, by-cancelling out the following opening transaction and preventing buildup-of duplicated opening balances. Think of the closing/opening pair as-"moving the balances into the next file".-- You can close a different set of accounts by providing a query. Eg-if you want to include equity, you can add 'assets liabilities equity'-or 'type:ALE' arguments. (The balancing account is always excluded.)-Revenues and expenses usually are not migrated to a new file directly;-see '--retain' below.-- The generated transactions will have a 'start:' tag, with its value-set to '--migrate''s 'NEW' argument if any, for easier matching or-exclusion. When 'NEW' is not specified, it will be inferred if possible-by incrementing a number (eg a year number) within the default journal's-main file name. The other modes behave similarly.---File: hledger.info, Node: close --close, Next: close --open, Prev: close --migrate, Up: close--24.11.2 close -close-----------------------This prints just the closing balances transaction of '--migrate'. It is-the default behaviour if you specify no mode flag. Using the-customisation options below, you can move balances from any set of-accounts to a different account.---File: hledger.info, Node: close --open, Next: close --assert, Prev: close --close, Up: close--24.11.3 close -open----------------------This prints just the opening balances transaction of '--migrate'. It is-similar to Ledger's equity command.---File: hledger.info, Node: close --assert, Next: close --assign, Prev: close --open, Up: close--24.11.4 close -assert------------------------This prints a "closing balances" transaction (with 'balances:' tag),-that just declares balance assertions for the current balances without-changing them. It could be useful as documention and to guard against-changes.---File: hledger.info, Node: close --assign, Next: close --retain, Prev: close --assert, Up: close--24.11.5 close -assign------------------------This prints an "opening balances" transaction that restores the account-balances using balance assignments. Balance assignments work regardless-of any previous balance, so a preceding closing balances transaction is-not needed.-- However, omitting the closing balances transaction would unbalance-equity. This is relatively harmless for personal reports, but it-disturbs the accounting equation, removing a source of error detection.-So '--migrate' is generally the best way to set to set balances in new-files, for now.---File: hledger.info, Node: close --retain, Next: close customisation, Prev: close --assign, Up: close--24.11.6 close -retain------------------------This is like '--close' with different defaults: it prints a "retain-earnings" transaction (with 'retain:' tag), that transfers revenue and-expense balances to 'equity:retained earnings'.-- This is a different kind of closing, called "retaining earnings" or-"closing the books"; it is traditionally performed by businesses at the-end of each accounting period, to consolidate revenues and expenses into-the main equity balance. ("Revenues" and "expenses" are actually equity-by another name, kept separate temporarily for reporting purposes.)-- In personal accounting you generally don't need to do this, unless-you want the 'balancesheetequity' report to show a zero total,-demonstrating that the accounting equation (A-L=E) is satisfied.---File: hledger.info, Node: close customisation, Next: close and balance assertions, Prev: close --retain, Up: close--24.11.7 close customisation------------------------------In all modes, the following things can be overridden:-- * the accounts to be closed/opened, with account query arguments- * the balancing account, with '--close-acct=ACCT' and/or- '--open-acct=ACCT'- * the transaction descriptions, with '--close-desc=DESC' and- '--open-desc=DESC'- * the transaction's tag value, with a '--MODE=NEW' option argument- * the closing/opening dates, with '-e OPENDATE'-- By default, the closing date is yesterday, or the journal's end date,-whichever is later; and the opening date is always one day after the-closing date. You can change these by specifying a report end date; the-closing date will be the last day of the report period. Eg '-e 2024'-means "close on 2023-12-31, open on 2024-01-01".-- With '--x/--explicit', the balancing amount will be shown explicitly,-and if it involves multiple commodities, a separate posting will be-generated for each of them (similar to 'print -x').-- With '--interleaved', each individual transfer is shown with source-and destination postings next to each other (perhaps useful for-troubleshooting).-- With '--show-costs', balances' costs are also shown, with different-costs kept separate. This may generate very large journal entries, if-you have many currency conversions or investment transactions. 'close---show-costs' is currently the best way to view investment lots with-hledger. (To move or dispose of lots, see the more capable-'hledger-move' script.)---File: hledger.info, Node: close and balance assertions, Next: close examples, Prev: close customisation, Up: close--24.11.8 close and balance assertions---------------------------------------'close' adds balance assertions verifying that the accounts have been-reset to zero in a closing transaction or restored to their previous-balances in an opening transaction. These provide useful error-checking, but you can ignore them temporarily with '-I', or remove them-if you prefer.-- Single-commodity, subaccount-exclusive balance assertions ('=') are-generated by default. This can be changed with '--assertion-type='==*''-(eg).-- When running 'close' you should probably avoid using '-C', '-R',-'status:' (filtering by status or realness) or '--auto' (generating-postings), since the generated balance assertions would then require-these.-- Transactions with multiple dates (eg posting dates) spanning the file-boundary also can disrupt the balance assertions:--2023-12-30 a purchase made in december, cleared in january- expenses:food 5- assets:bank:checking -5 ; date: 2023-01-02-- To solve this you can transfer the money to and from a temporary-account, splitting the multi-day transaction into two single-day-transactions:--; in 2022.journal:-2022-12-30 a purchase made in december, cleared in january- expenses:food 5- equity:pending -5--; in 2023.journal:-2023-01-02 last year's transaction cleared- equity:pending 5 = 0- assets:bank:checking -5---File: hledger.info, Node: close examples, Prev: close and balance assertions, Up: close--24.11.9 close examples-------------------------* Menu:--* Retain earnings::-* Migrate balances to a new file::-* More detailed close examples::---File: hledger.info, Node: Retain earnings, Next: Migrate balances to a new file, Up: close examples--24.11.9.1 Retain earnings-.........................--Record 2022's revenues/expenses as retained earnings on 2022-12-31,-appending the generated transaction to the journal:--$ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal-- After this, to see 2022's revenues and expenses you must exclude the-retain earnings transaction:--$ hledger -f 2022.journal is not:desc:'retain earnings'---File: hledger.info, Node: Migrate balances to a new file, Next: More detailed close examples, Prev: Retain earnings, Up: close examples--24.11.9.2 Migrate balances to a new file-........................................--Close assets/liabilities on 2022-12-31 and re-open them on 2023-01-01:--$ hledger close --migrate -f 2022.journal -p 2022-# copy/paste the closing transaction to the end of 2022.journal-# copy/paste the opening transaction to the start of 2023.journal-- After this, to see 2022's end-of-year balances you must exclude the-closing balances transaction:--$ hledger -f 2022.journal bs not:desc:'closing balances'-- For more flexibility, it helps to tag closing and opening-transactions with eg 'start:NEWYEAR', then you can ensure correct-balances by excluding all opening/closing transactions except the first,-like so:--$ hledger bs -Y -f 2021.j -f 2022.j -f 2023.j expr:'tag:start=2021 or not tag:start'-$ hledger bs -Y -f 2021.j -f 2022.j expr:'tag:start=2021 or not tag:start'-$ hledger bs -Y -f 2022.j -f 2023.j expr:'tag:start=2022 or not tag:start'-$ hledger bs -Y -f 2021.j expr:'tag:start=2021 or not tag:start'-$ hledger bs -Y -f 2022.j expr:'tag:start=2022 or not tag:start'-$ hledger bs -Y -f 2023.j # unclosed file, no query needed---File: hledger.info, Node: More detailed close examples, Prev: Migrate balances to a new file, Up: close examples--24.11.9.3 More detailed close examples-......................................--See examples/multi-year.---File: hledger.info, Node: codes, Next: commodities, Prev: close, Up: PART 4 COMMANDS--24.12 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:--2022/1/1 (123) Supermarket - Food $5.00- Checking --2022/1/2 (124) Post Office- Postage $8.32- Checking--2022/1/3 Supermarket- Food $11.23- Checking --2022/1/4 (126) Post Office- Postage $3.21- Checking--$ hledger codes-123-124-126--$ hledger codes -E-123-124--126---File: hledger.info, Node: commodities, Next: demo, Prev: codes, Up: PART 4 COMMANDS--24.13 commodities-=================--List all commodity/currency symbols used or declared in the journal.---File: hledger.info, Node: demo, Next: descriptions, Prev: commodities, Up: PART 4 COMMANDS--24.14 demo-==========--Play demos of hledger usage in the terminal, if asciinema is installed.-- Run this command with no argument to list the demos. To play a demo,-write its number or a prefix or substring of its title. Tips:-- Make your terminal window large enough to see the demo clearly.-- Use the -s/-speed SPEED option to set your preferred playback speed,-eg '-s4' to play at 4x original speed or '-s.5' to play at half speed.-The default speed is 2x.-- Other asciinema options can be added following a double dash, eg '----i.1' to limit pauses or '-- -h' to list asciinema's other options.-- During playback, several keys are available: SPACE to pause/unpause,-. to step forward (while paused), CTRL-c quit.-- Examples:--$ hledger demo # list available demos-$ hledger demo 1 # play the first demo at default speed (2x)-$ hledger demo install -s4 # play the "install" demo at 4x speed---File: hledger.info, Node: descriptions, Next: diff, Prev: demo, Up: PART 4 COMMANDS--24.15 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 transactions.-- Example:--$ hledger descriptions-Store Name-Gas Station | Petrol-Person A---File: hledger.info, Node: diff, Next: files, Prev: descriptions, Up: PART 4 COMMANDS--24.16 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-multiple 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:---File: hledger.info, Node: files, Next: help, Prev: diff, Up: PART 4 COMMANDS--24.17 files-===========--List all files included in the journal. With a REGEX argument, only-file names matching the regular expression (case sensitive) are shown.---File: hledger.info, Node: help, Next: import, Prev: files, Up: PART 4 COMMANDS--24.18 help-==========--Show the hledger user manual in the terminal, with 'info', 'man', or a-pager. With a TOPIC argument, open it at that topic if possible. TOPIC-can be any heading in the manual, or a heading prefix, case insensitive.-Eg: 'commands', 'print', 'forecast', 'journal', 'amount', '"auto-postings"'.-- This command shows the hledger manual built in to your hledger-version. It can be useful when offline, or when you prefer the terminal-to a web browser, or when the appropriate hledger manual or viewing-tools are not installed on your system.-- By default it chooses the best viewer found in $PATH, trying (in this-order): 'info', 'man', '$PAGER', 'less', 'more'. You can force the use-of info, man, or a pager with the '-i', '-m', or '-p' flags, If no-viewer can be found, or the command is run non-interactively, it just-prints the manual to stdout.-- If using 'info', note that version 6 or greater is needed for TOPIC-lookup. If you are on mac you will likely have info 4.8, and should-consider installing a newer version, eg with 'brew install texinfo'-(#1770).-- Examples--$ hledger help --help # show how the help command works-$ hledger help # show the hledger manual with info, man or $PAGER-$ hledger help journal # show the journal topic in the hledger manual-$ hledger help -m journal # show it with man, even if info is installed---File: hledger.info, Node: import, Next: incomestatement, Prev: help, Up: PART 4 COMMANDS--24.19 import-============--Read new transactions added to each FILE provided as arguments since-last run, and add them to the journal. Or with -dry-run, just print the-transactions that would be added. Or with -catchup, just mark all of-the FILEs' current transactions as imported, without importing them.-- This command may append new transactions to the main journal file-(which should be in journal format). Existing transactions are not-changed. This is one of the few hledger commands that writes to the-journal file (see also 'add').-- Unlike other hledger commands, with 'import' the journal file is an-output file, and will be modified, though only by appending (existing-data will not be changed). The input files are specified as arguments,-so to import one or more CSV files to your main journal, you will run-'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.--* Menu:--* Deduplication::-* Import testing::-* Importing balance assignments::-* Commodity display styles::---File: hledger.info, Node: Deduplication, Next: Import testing, Up: import--24.19.1 Deduplication------------------------'import' tries to import only the transactions which are new since the-last import, ignoring any that it has seen in previous runs. So if your-bank's CSV includes the last three months of data, you can download and-'import' it every month (or week, or day) and only the new transactions-will be imported each time.-- It works as follows. For each imported 'FILE' (usually CSV, but they-could be any of hledger's input formats):-- * It tries to recall the latest date seen previously, reading it from- a hidden '.latest.FILE' in the same directory.- * Then it processes 'FILE', ignoring any transactions on or before- the "latest seen" date.-- And after a successful import, it updates the '.latest.FILE'(s) for-next time (unless '--dry-run' was used).-- This is a limited kind of deduplication, let's call it "date-skipping". Within each input file, it avoids reprocessing the same-dates across successive runs. This is a simple system that works for-most real-world CSV files; it assumes these are true, or true enough:-- 1. new items always have the newest dates- 2. item dates are stable across successive downloads- 3. the order of same-date items is stable across downloads- 4. the name of the input file is stable across downloads-- If you have a bank whose CSV dates or ordering occasionally change,-you can reduce the chance of this happening in new transactions by-importing more often, and in old transactions it doesn't matter. And-remember you can use CSV rules files as input, which is one way to-ensure a stable file name.-- 'import' doesn't detect other kinds of duplication, such as duplicate-transactions within a single run. (In part, because legitimate-duplicate transactions can easily occur in real-world data.) So, say-you downloaded but forgot to import 'bank.1.csv', and a week later you-downloaded 'bank.2.csv' with overlapping data. Now you should not-import both of these at once ('hledger import bank.1.csv bank.2.csv');-the overlapping transactions which appear twice would not be-deduplicated since this is considered a single import. Instead, import-these files one at a time, and also use the same filename each time for-a common "latest seen" state:--$ mv bank.1.csv bank.csv; hledger import bank.csv-$ mv bank.2.csv bank.csv; hledger import bank.csv-- Normally you can ignore the '.latest.*' files, but if needed, you can-delete them (to make all transactions unseen), or construct/modify them-(to catch up to a certain date). The format is just a single ISO-format-date ('YYYY-MM-DD'), possibly repeated on multiple lines. It means "I-have seen transactions up to this date, and this many of them occurring-on that date".-- 'hledger print --new' also uses and updates these '.latest.*' files,-but it is less often used.-- Related: CSV > Working with CSV > Deduplicating, importing.---File: hledger.info, Node: Import testing, Next: Importing balance assignments, Prev: Deduplication, Up: import--24.19.2 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'-- Note: when importing from multiple files at once, it's currently-possible for some .latest files to be updated successfully, while the-actual import fails because of a problem in one of the files, leaving-them out of sync (and causing some transactions to be missed). To-prevent this, do a -dry-run first and fix any problems before the real-import.---File: hledger.info, Node: Importing balance assignments, Next: Commodity display styles, Prev: Import testing, Up: import--24.19.3 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.)---File: hledger.info, Node: Commodity display styles, Prev: Importing balance assignments, Up: import--24.19.4 Commodity display styles-----------------------------------Imported amounts will be formatted according to the canonical commodity-styles (declared or inferred) in the main journal file.---File: hledger.info, Node: incomestatement, Next: notes, Prev: import, Up: PART 4 COMMANDS--24.20 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.-- This report shows accounts declared with the 'Revenue' or 'Expense'-type (see account types). Or if no such accounts are declared, it shows-top-level accounts named 'revenue' or 'income' or 'expense' (case-insensitive, plurals allowed) and their subaccounts.-- Example:--$ hledger incomestatement-Income Statement 2008-- || 2008 -===================++======- Revenues || --------------------++------- income:gifts || $1 - income:salary || $1 --------------------++------- || $2 -===================++======- Expenses || --------------------++------- expenses:food || $1 - expenses:supplies || $1 --------------------++------- || $2 -===================++======- Net: || 0 -- This command is a higher-level variant of the 'balance' command, and-supports 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', 'tsv' (_Added in-1.32_), 'html', and 'json'.---File: hledger.info, Node: notes, Next: payees, Prev: incomestatement, Up: PART 4 COMMANDS--24.21 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-transactions. 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---File: hledger.info, Node: payees, Next: prices, Prev: notes, Up: PART 4 COMMANDS--24.22 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---File: hledger.info, Node: prices, Next: print, Prev: payees, Up: PART 4 COMMANDS--24.23 prices-============--Print the market prices declared with P directives. With--infer-market-prices, also show any additional prices inferred from-costs. With -show-reverse, also show additional prices inferred by-reversing known prices.-- Price amounts are always displayed with their full precision, except-for reverse prices which are limited to 8 decimal digits.-- Prices can be filtered by a date:, cur: or amt: query.-- Generally if you run this command with -infer-market-prices--show-reverse, it will show the same prices used internally to calculate-value reports. But if in doubt, you can inspect those directly by-running the value report with -debug=2.---File: hledger.info, Node: print, Next: register, Prev: prices, Up: PART 4 COMMANDS--24.24 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).-- 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/regenerate your journal you should take care to also copy-over the directives and inter-transaction comments.-- Eg:--$ hledger print -f examples/sample.journal date:200806-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--* Menu:--* print explicitness::-* print amount style::-* print parseability::-* print other features::-* print output format::---File: hledger.info, Node: print explicitness, Next: print amount style, Up: print--24.24.1 print explicitness-----------------------------Normally, whether posting amounts are implicit or explicit is preserved.-For example, when an amount is omitted in the journal, it will not-appear in the output. Similarly, if a conversion cost is implied but-not written, it will not appear in the output.-- You can use the '-x'/'--explicit' flag to force explicit display of-all amounts and costs. This 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'.-- The '-x'/'--explicit' flag will cause any postings with a-multi-commodity amount (which can arise when a multi-commodity-transaction has an implicit amount) to be split into multiple-single-commodity postings, keeping the output parseable.---File: hledger.info, Node: print amount style, Next: print parseability, Prev: print explicitness, Up: print--24.24.2 print amount style-----------------------------Amounts are shown right-aligned within each transaction (but not aligned-across all transactions; you can do that with ledger-mode in Emacs).-- Amounts will be (mostly) normalised to their commodity display style:-their symbol placement, decimal mark, and digit group marks will be made-consistent. By default, decimal digits are shown as they are written in-the journal.-- With the '--round' (_Added in 1.32_) option, 'print' will try-increasingly hard to display decimal digits according to the commodity-display styles:-- * '--round=none' show amounts with original precisions (default)- * '--round=soft' add/remove decimal zeros in amounts (except costs)- * '--round=hard' round amounts (except costs), possibly hiding- significant digits- * '--round=all' round all amounts and costs-- 'soft' is good for non-lossy cleanup, formatting amounts more-consistently where it's safe to do so.-- 'hard' and 'all' can cause 'print' to show invalid unbalanced journal-entries; they may be useful eg for stronger cleanup, with manual fixups-when needed.---File: hledger.info, Node: print parseability, Next: print other features, Prev: print amount style, Up: print--24.24.3 print parseability-----------------------------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 (though the same can be achieved with 'expr:' queries-now):--# 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:-- * Value reporting affects posting amounts but not balance assertion- or balance assignment amounts, potentially causing those to fail.- * Auto postings can generate postings with too many missing amounts.- * Account aliases can generate bad account names.---File: hledger.info, Node: print other features, Next: print output format, Prev: print parseability, Up: print--24.24.4 print, other features--------------------------------With '-B'/'--cost', amounts with costs are shown converted to cost.-- With '--new', print shows only transactions it has not seen on a-previous run. This uses the same deduplication system as the 'import'-command. (See import's docs for details.)-- With '-m DESC'/'--match=DESC', print shows one recent transaction-whose description is most similar to DESC. DESC should contain at least-two characters. If there is no similar-enough match, no transaction-will be shown and the program exit code will be non-zero.---File: hledger.info, Node: print output format, Prev: print other features, Up: print--24.24.5 print output format------------------------------This command also supports the output destination and output format-options The output formats supported are 'txt', 'beancount' (_Added in-1.32_), 'csv', 'tsv' (_Added in 1.32_), 'json' and 'sql'.-- The 'beancount' format tries to produce Beancount-compatible output,-as follows:-- * Transaction and postings with unmarked status are converted to- cleared ('*') status.- * Transactions' payee and note are backslash-escaped and- double-quote-escaped and wrapped in double quotes.- * Transaction tags are copied to Beancount #tag format.- * Commodity symbols are converted to upper case, and a small number- of currency symbols like '$' are converted to the corresponding- currency names.- * Account name parts are capitalised and unsupported characters are- replaced with '-'. If an account name part does not begin with a- letter, or if the first part is not Assets, Liabilities, Equity,- Income, or Expenses, an error is raised. (Use '--alias' options to- bring your accounts into compliance.)- * An 'open' directive is generated for each account used, on the- earliest transaction date.-- Some limitations:-- * Balance assertions are removed.- * Balance assignments become missing amounts.- * Virtual and balanced virtual postings become regular postings.- * Directives are not converted.-- 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","","",""-- * There is one CSV record per posting, with the parent transaction's- fields repeated.- * 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.)- * The amount is separated into "commodity" (the symbol) and "amount"- (numeric quantity) fields.- * The numeric amount is repeated in either the "credit" or "debit"- column, for convenience. (Those names are not accurate in the- accounting sense; it just puts negative amounts under credit and- zero or greater amounts under debit.)---File: hledger.info, Node: register, Next: rewrite, Prev: print, Up: PART 4 COMMANDS--24.25 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.-- For performance reasons, column widths are chosen based on the first-1000 lines; this means unusually wide values in later lines can cause-visual discontinuities as column widths are adjusted. If you want to-ensure perfect alignment, at the cost of more time and memory, use the-'--align-all' flag.-- The '--historical'/'-H' flag adds the balance from any undisplayed-prior postings to the running total. This is useful when you want to-see 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-numbers. 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.-- With '-m DESC'/'--match=DESC', register does a fuzzy search for one-recent posting whose description is most similar to DESC. DESC should-contain at least two characters. If there is no similar-enough match,-no posting will be shown and the program exit code will be non-zero.--* Menu:--* Custom register output::---File: hledger.info, Node: Custom register output, Up: register--24.25.1 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', 'tsv' (_Added in-1.32_), and 'json'.---File: hledger.info, Node: rewrite, Next: roi, Prev: register, Up: PART 4 COMMANDS--24.26 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-transaction'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-commodity.--* Menu:--* Re-write rules in a file::-* Diff output format::-* rewrite vs print --auto::---File: hledger.info, Node: Re-write rules in a file, Next: Diff output format, Up: rewrite--24.26.1 Re-write rules in a file-----------------------------------During the run this tool will execute so called "Automated Transactions"-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-transactions 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-postings.---File: hledger.info, Node: Diff output format, Next: rewrite vs print --auto, Prev: Re-write rules in a file, Up: rewrite--24.26.2 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-containing 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---File: hledger.info, Node: rewrite vs print --auto, Prev: Diff output format, Up: rewrite--24.26.3 rewrite vs. print -auto----------------------------------This command predates print -auto, and currently does much the same-thing, but with these differences:-- * with multiple files, rewrite lets rules in any file affect all- other files. print -auto uses standard directive scoping; rules- affect only child files.-- * rewrite's query limits which transactions can be rewritten; all are- printed. print -auto's query limits which transactions are- printed.-- * rewrite applies rules specified on command line or in the journal.- print -auto applies rules specified in the journal.---File: hledger.info, Node: roi, Next: stats, Prev: rewrite, Up: PART 4 COMMANDS--24.27 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, also known as money-weighted rate of return) and time-weighted-rate of return (TWR) for your investments for the time period requested.-IRR is always annualized due to the way it is computed, but TWR is-reported both as a rate over the chosen reporting period and as an-annual rate.-- 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:-- * 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.- * Error (SearchFailed): Failed to find solution for Internal Rate of- Return (IRR). Either search does not converge to a solution, or- converges too slowly.-- Examples:-- * Using roi to compute total return of investment in stocks:- https://github.com/simonmichael/hledger/blob/master/examples/investing/roi-unrealised.ledger-- * Cookbook > Return on Investment: https://hledger.org/roi.html--* Menu:--* Spaces and special characters in --inv and --pnl::-* Semantics of --inv and --pnl::-* IRR and TWR explained::---File: hledger.info, Node: Spaces and special characters in --inv and --pnl, Next: Semantics of --inv and --pnl, Up: roi--24.27.1 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'"---File: hledger.info, Node: Semantics of --inv and --pnl, Next: IRR and TWR explained, Prev: Spaces and special characters in --inv and --pnl, Up: roi--24.27.2 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.-- * "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-- * "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---File: hledger.info, Node: IRR and TWR explained, Prev: Semantics of --inv and --pnl, Up: roi--24.27.3 IRR and TWR explained--------------------------------"ROI" stands for "return on investment". Traditionally this was-computed as a difference between current value of investment and its-initial value, expressed in percentage of the initial value.-- However, this approach is only practical in simple cases, where-investments receives no in-flows or out-flows of money, and where rate-of growth is fixed over time. For more complex scenarios you need-different ways to compute rate of return, and this command implements-two of them: IRR and TWR.-- Internal rate of return, or "IRR" (also called "money-weighted rate-of return") takes into account effects of in-flows and out-flows, and-the time between them. Investment at a particular fixed interest rate-is going to give you more interest than the same amount invested at the-same interest rate, but made later in time. If you are withdrawing from-your investment, your future gains would be smaller (in absolute-numbers), and will be a smaller percentage of your initial investment,-so your IRR will be smaller. And if you are adding to your investment,-you will receive bigger absolute gains, which will be a bigger-percentage of your initial investment, so your IRR will be larger.-- 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 "unrealized-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-account for the effect of your in-flows and out-flows, but unlike IRR it-will try to compute the true rate of return of the underlying asset,-compensating for the effect that deposits and withdrawas have on the-apparent rate of growth of your investment.-- 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, and make TWR less sensitive than IRR to the effects of-cash in-flows and out-flows.-- References:-- * Explanation of rate of return- * Explanation of IRR- * Explanation of TWR- * IRR vs TWR- * Examples of computing IRR and TWR and discussion of the limitations- of both metrics---File: hledger.info, Node: stats, Next: tags, Prev: roi, Up: PART 4 COMMANDS--24.28 stats-===========--Show journal and performance statistics.-- The stats command shows summary information for the whole journal, or-a matched part of it. With a reporting interval, it shows a report for-each report period.-- The default output is fairly impersonal, though it reveals the main-file name. With '-v/--verbose', more details are shown, like file-paths, included files, and commodity names.-- It also shows some run time statistics:-- * elapsed time- * throughput: the number of transactions processed per second- * live: the peak memory in use by the program to do its work- * alloc: the peak memory allocation from the OS as seen by GHC.- Measuring this externally, eg with GNU time, is more accurate;- usually that will be a larger number; sometimes (with swapping?)- smaller.-- The 'stats' command's run time is similar to that of a balance-report.-- Example:--$ hledger stats -f examples/1ktxns-1kaccts.journal -Main file : .../1ktxns-1kaccts.journal-Included files : 0-Txns span : 2000-01-01 to 2002-09-27 (1000 days)-Last txn : 2002-09-26 (7827 days ago)-Txns : 1000 (1.0 per day)-Txns last 30 days : 0 (0.0 per day)-Txns last 7 days : 0 (0.0 per day)-Payees/descriptions : 1000-Accounts : 1000 (depth 10)-Commodities : 26-Market prices : 1000-Runtime stats : 0.12 s elapsed, 8266 txns/s, 4 MB live, 16 MB alloc-- This command supports the -o/-output-file option (but not--O/-output-format).---File: hledger.info, Node: tags, Next: test, Prev: stats, Up: PART 4 COMMANDS--24.29 tags-==========--List the tags used in the journal, or their values.-- This command lists the tag names used in the journal, whether on-transactions, postings, or account declarations.-- With a TAGREGEX argument, only tag names matching this regular-expression (case insensitive, infix matched) are shown.-- With QUERY arguments, only transactions and accounts matching this-query are considered. If the query involves transaction fields (date:,-desc:, amt:, ...), the search is restricted to the matched transactions-and their accounts.-- With the -values flag, the tags' unique non-empty values are listed-instead. With -E/-empty, blank/empty values are also shown.-- With -parsed, tags or values are shown in the order they were parsed,-with duplicates included. (Except, tags from account declarations are-always shown first.)-- Tip: remember, accounts also acquire tags from their parents,-postings also acquire tags from their account and transaction,-transactions also acquire tags from their postings.---File: hledger.info, Node: test, Prev: tags, Up: PART 4 COMMANDS--24.30 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).---File: hledger.info, Node: PART 5 COMMON TASKS, Next: BUGS, Prev: PART 4 COMMANDS, Up: Top--25 PART 5: COMMON TASKS-***********************--Here are some quick examples of how to do some basic tasks with hledger.--* Menu:--* Getting help::-* Constructing command lines::-* Starting a journal file::-* Setting LEDGER_FILE::-* Setting opening balances::-* Recording transactions::-* Reconciling::-* Reporting::-* Migrating to a new file::---File: hledger.info, Node: Getting help, Next: Constructing command lines, Up: PART 5 COMMON TASKS--25.1 Getting help-=================--Here's how to list commands and view options and command docs:--$ hledger # show available commands-$ hledger --help # show common options-$ hledger CMD --help # show CMD's options, common options and CMD's documentation-- You can also view your hledger version's manual in several formats by-using the help command. Eg:--$ hledger help # show the hledger manual with info, man or $PAGER (best available)-$ hledger help journal # show the journal topic in the hledger manual-$ hledger help --help # find out more about the help command-- To view manuals and introductory docs on the web, visit-https://hledger.org. Chat and mail list support and discussion archives-can be found at https://hledger.org/support.---File: hledger.info, Node: Constructing command lines, Next: Starting a journal file, Prev: Getting help, Up: PART 5 COMMON TASKS--25.2 Constructing command lines-===============================--hledger has a flexible command line interface. We strive to keep it-simple and ergonomic, but if you run into one of the sharp edges-described in OPTIONS, here are some tips that might help:-- * command-specific options must go after the command (it's fine to- put common options there too: 'hledger CMD OPTS ARGS')- * running add-on executables directly simplifies command line parsing- ('hledger-ui OPTS ARGS')- * enclose "problematic" args in single quotes- * if needed, also add a backslash to hide regular expression- metacharacters from the shell- * to see how a misbehaving command line is being parsed, add- '--debug=2'.---File: hledger.info, Node: Starting a journal file, Next: Setting LEDGER_FILE, Prev: Constructing command lines, Up: PART 5 COMMON TASKS--25.3 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 (see below). 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 2023.journal-$ echo "export LEDGER_FILE=$HOME/finance/2023.journal" >> ~/.profile-$ source ~/.profile-$ hledger stats-Main file : /Users/simon/finance/2023.journal-Included files : -Transactions span : to (0 days)-Last transaction : none-Transactions : 0 (0.0 per day)-Transactions last 30 days: 0 (0.0 per day)-Transactions last 7 days : 0 (0.0 per day)-Payees/descriptions : 0-Accounts : 0 (depth 0)-Commodities : 0 ()-Market prices : 0 ()---File: hledger.info, Node: Setting LEDGER_FILE, Next: Setting opening balances, Prev: Starting a journal file, Up: PART 5 COMMON TASKS--25.4 Setting LEDGER_FILE-========================--How to set 'LEDGER_FILE' permanently depends on your setup:-- On unix and mac, running these commands in the terminal will work for-many people; adapt as needed:--$ echo 'export LEDGER_FILE=~/finance/2023.journal' >> ~/.profile-$ source ~/.profile-- When correctly configured, in a new terminal window 'env | grep-LEDGER_FILE' will show your file, and so will 'hledger files'.-- On mac, this additional step might be helpful for GUI applications-(like Emacs started from the dock): add an entry to-'~/.MacOSX/environment.plist' like--{- "LEDGER_FILE" : "~/finance/2023.journal"-}-- and then run 'killall Dock' in a terminal window (or restart the-machine).-- On Windows, see https://www.java.com/en/download/help/path.html, or-try running these commands in a powershell window (let us know if it-persists across a reboot, and if you need to be an Administrator):--> CD-> MKDIR finance-> SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal"---File: hledger.info, Node: Setting opening balances, Next: Recording transactions, Prev: Setting LEDGER_FILE, Up: PART 5 COMMON TASKS--25.5 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-balances on this date. Here are two ways to do it:-- * The first way: open the journal in any text editor and save an- entry like this:-- 2023-01-01 * opening balances- assets:bank:checking $1000 = $1000- assets:bank:savings $2000 = $2000- assets:cash $100 = $100- liabilities:creditcard $-50 = $-50- equity:opening/closing balances-- 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.-- * 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/2023.journal- Any command line arguments will be used as defaults.- Use tab key to complete, readline keys to edit, enter to accept defaults.- An optional (CODE) may follow transaction dates.- An optional ; COMMENT may follow descriptions or amounts.- If you make a mistake, enter < at any prompt to go one step backward.- To end a transaction, enter . when prompted.- To quit, enter . at a date prompt or press control-d or control-c.- Date [2023-02-07]: 2023-01-01- Description: * opening balances- Account 1: assets:bank:checking- Amount 1: $1000- Account 2: assets:bank:savings- Amount 2 [$-1000]: $2000- Account 3: assets:cash- Amount 3 [$-3000]: $100- Account 4: liabilities:creditcard- Amount 4 [$-3100]: $-50- Account 5: equity:opening/closing balances- Amount 5 [$-3050]: - Account 6 (or . or enter to finish this transaction): .- 2023-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050- - Save this transaction to the journal ? [y]: - Saved.- Starting the next transaction (. or ctrl-D/ctrl-C to quit)- Date [2023-01-01]: .-- If you're using version control, this could be a good time to commit-the journal. Eg:--$ git commit -m 'initial balances' 2023.journal---File: hledger.info, Node: Recording transactions, Next: Reconciling, Prev: Setting opening balances, Up: PART 5 COMMON TASKS--25.6 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:--2023/1/10 * gift received- assets:cash $20- income:gifts--2023.1.12 * farmers market- expenses:food $13- assets:cash--2023-01-15 paycheck- income:salary- assets:bank:checking $1000---File: hledger.info, Node: Reconciling, Next: Reporting, Prev: Recording transactions, Up: PART 5 COMMON TASKS--25.7 Reconciling-================--Periodically you should reconcile - compare your hledger-reported-balances 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-discrepancies.-- 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:-- 2023-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 checking -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 transaction 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---register 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 '2023-01-15' and 'paycheck'-- If you're using version control, this can be another good time to-commit:--$ git commit -m 'txns' 2023.journal---File: hledger.info, Node: Reporting, Next: Migrating to a new file, Prev: Reconciling, Up: PART 5 COMMON TASKS--25.8 Reporting-==============--Here are some basic reports.-- Show all transactions:--$ hledger print-2023-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050--2023-01-10 * gift received- assets:cash $20- income:gifts--2023-01-12 * farmers market- expenses:food $13- assets:cash--2023-01-15 * paycheck- income:salary- assets:bank:checking $1000--2023-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- 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 -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 -2-Balance Sheet 2023-01-16-- || 2023-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 2023-01-01-2023-01-16-- || 2023-01-01-2023-01-16 -===============++=======================- Revenues || ----------------++------------------------ income:gifts || $20 - income:salary || $1000 ----------------++------------------------ || $1020 -===============++=======================- Expenses || ----------------++------------------------ expenses:food || $13 - expenses:misc || $2 ----------------++------------------------ || $15 -===============++=======================- Net: || $1005 -- The final total is your net income during this period.-- Show transactions affecting your wallet, with running total:--$ hledger register cash-2023-01-01 opening balances assets:cash $100 $100-2023-01-10 gift received assets:cash $20 $120-2023-01-12 farmers market assets:cash $-13 $107-2023-01-16 adjust cash assets:cash $-2 $105-- Show weekly posting counts as a bar chart:--$ hledger activity -W-2019-12-30 *****-2023-01-06 ****-2023-01-13 ****---File: hledger.info, Node: Migrating to a new file, Prev: Reporting, Up: PART 5 COMMON TASKS--25.9 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.---File: hledger.info, Node: BUGS, Prev: PART 5 COMMON TASKS, Up: Top--26 BUGS-*******--We welcome bug reports in the hledger issue tracker (shortcut:-http://bugs.hledger.org), or on the #hledger chat or hledger mail list-(https://hledger.org/support).-- Some known issues and limitations:-- The need to precede add-on command options with '--' when invoked-from hledger is awkward. (See Command options, Constructing command-lines.)-- A UTF-8-aware system locale must be configured to work with non-ascii-data. (See Unicode characters, Troubleshooting.)-- On Microsoft Windows, depending whether you are running in a CMD-window or a Cygwin/MSYS/Mintty window and how you installed hledger,-non-ascii characters and colours may not be supported, and the tab key-may not be supported by 'hledger add'. (Running in a WSL window should-resolve these.)-- When processing large data files, hledger uses more memory than-Ledger.--* Menu:--* Troubleshooting::---File: hledger.info, Node: Troubleshooting, Up: BUGS--26.1 Troubleshooting-====================--Here are some common issues you might encounter when you run hledger,-and how to resolve them (and remember also you can usually get quick-Support):-- *PATH issues: I get an error like "No command 'hledger' found"*-Depending how you installed hledger, the executables may not be in your-shell's PATH. Eg on unix systems, stack installs hledger in-'~/.local/bin' and cabal installs it in '~/.cabal/bin'. You may need to-add one of these directories to your shell's PATH, and/or open a new-terminal window.-- *LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not-using it*-- * 'LEDGER_FILE' should be a real environment variable, not just a- shell variable. Eg on unix, the command 'env | grep LEDGER_FILE'- should show it. You may need to use 'export' (see- https://stackoverflow.com/a/7411509).- * You may need to force your shell to see the new configuration. A- simple way is to close your terminal window and open a new one.-- *LANG issues: I get errors like "Illegal byte sequence" or "Invalid-or incomplete multibyte or wide character" or "commitAndReleaseBuffer:-invalid argument (invalid character)"*-Programs compiled with GHC (hledger, haskell build tools, etc.) need-the system locale to be UTF-8-aware, or they will fail when they-encounter non-ascii characters. To fix it, set the LANG environment-variable to a locale which supports UTF-8 and which is installed on your-system.-- On unix, 'locale -a' lists the installed locales. Look for one which-mentions 'utf8', 'UTF-8' or similar. Some examples: 'C.UTF-8',-'en_US.utf-8', 'fr_FR.utf8'. If necessary, use your system package-manager to install one. Then select it by setting the 'LANG'-environment variable. Note, exact spelling and capitalisation of the-locale name may be important: Here's one common way to configure this-permanently for your shell:--$ echo "export LANG=en_US.utf8" >>~/.profile-# close and re-open terminal window-- If you are using Nix (not NixOS) for GHC and Hledger, you might need-to set the 'LOCALE_ARCHIVE' variable:--$ echo "export LOCALE_ARCHIVE=${glibcLocales}/lib/locale/locale-archive" >>~/.profile-# close and re-open terminal window-- *COMPATIBILITY ISSUES: hledger gives an error with my Ledger file*-Not all of Ledger's journal file syntax or feature set is supported.-See hledger and Ledger for full details.---Tag Table:-Node: Top208-Node: PART 1 USER INTERFACE3809-Ref: #part-1-user-interface3948-Node: Input3948-Ref: #input4058-Node: Text encoding5025-Ref: #text-encoding5139-Node: Data formats5705-Ref: #data-formats5840-Node: Standard input7429-Ref: #standard-input7569-Node: Multiple files7796-Ref: #multiple-files7935-Node: Strict mode8533-Ref: #strict-mode8643-Node: Commands9367-Ref: #commands9469-Node: Add-on commands10536-Ref: #add-on-commands10638-Node: Options11754-Ref: #options11866-Node: General help options12194-Ref: #general-help-options12340-Node: General input options12622-Ref: #general-input-options12804-Node: General reporting options13461-Ref: #general-reporting-options13622-Node: Command line tips17012-Ref: #command-line-tips17142-Node: Option repetition17401-Ref: #option-repetition17545-Node: Special characters17649-Ref: #special-characters17822-Node: Single escaping shell metacharacters17985-Ref: #single-escaping-shell-metacharacters18226-Node: Double escaping regular expression metacharacters18829-Ref: #double-escaping-regular-expression-metacharacters19140-Node: Triple escaping for add-on commands19666-Ref: #triple-escaping-for-add-on-commands19926-Node: Less escaping20570-Ref: #less-escaping20724-Node: Unicode characters21048-Ref: #unicode-characters21223-Node: Regular expressions22635-Ref: #regular-expressions22808-Node: hledger's regular expressions25904-Ref: #hledgers-regular-expressions26063-Node: Argument files27449-Ref: #argument-files27585-Node: Output28082-Ref: #output28194-Node: Output destination28321-Ref: #output-destination28452-Node: Output format28877-Ref: #output-format29023-Node: CSV output30620-Ref: #csv-output30736-Node: HTML output30839-Ref: #html-output30977-Node: JSON output31071-Ref: #json-output31209-Node: SQL output32131-Ref: #sql-output32247-Node: Commodity styles32982-Ref: #commodity-styles33122-Node: Colour33860-Ref: #colour33978-Node: Box-drawing34382-Ref: #box-drawing34500-Node: Paging34790-Ref: #paging34904-Node: Debug output35857-Ref: #debug-output35963-Node: Environment36626-Ref: #environment36750-Node: PART 2 DATA FORMATS37294-Ref: #part-2-data-formats37437-Node: Journal37437-Ref: #journal37546-Node: Journal cheatsheet39914-Ref: #journal-cheatsheet40041-Node: Comments46128-Ref: #comments46256-Node: Transactions47072-Ref: #transactions47195-Node: Dates48209-Ref: #dates48316-Node: Simple dates48361-Ref: #simple-dates48477-Node: Posting dates48977-Ref: #posting-dates49095-Node: Status50064-Ref: #status50165-Node: Code51830-Ref: #code51933-Node: Description52165-Ref: #description52296-Node: Payee and note52852-Ref: #payee-and-note52958-Node: Transaction comments53943-Ref: #transaction-comments54096-Node: Postings54459-Ref: #postings54590-Node: Debits and credits55622-Ref: #debits-and-credits55769-Node: The two space delimiter56232-Ref: #the-two-space-delimiter56389-Node: Account names56797-Ref: #account-names56927-Node: Amounts58601-Ref: #amounts58729-Node: Decimal marks59630-Ref: #decimal-marks59757-Node: Digit group marks60734-Ref: #digit-group-marks60887-Node: Commodity61369-Ref: #commodity61498-Node: Costs62486-Ref: #costs62581-Node: Balance assertions64738-Ref: #balance-assertions64891-Node: Assertions and ordering65975-Ref: #assertions-and-ordering66164-Node: Assertions and multiple included files66703-Ref: #assertions-and-multiple-included-files66963-Node: Assertions and multiple -f files67463-Ref: #assertions-and-multiple--f-files67708-Node: Assertions and costs68105-Ref: #assertions-and-costs68314-Node: Assertions and commodities68755-Ref: #assertions-and-commodities68970-Node: Assertions and subaccounts70414-Ref: #assertions-and-subaccounts70640-Node: Assertions and virtual postings71084-Ref: #assertions-and-virtual-postings71322-Node: Assertions and auto postings71454-Ref: #assertions-and-auto-postings71684-Node: Assertions and precision72329-Ref: #assertions-and-precision72511-Node: Posting comments72778-Ref: #posting-comments72941-Node: Transaction balancing73318-Ref: #transaction-balancing73477-Node: Tags75320-Ref: #tags75439-Node: Tag names76782-Ref: #tag-names76889-Node: Special tags77277-Ref: #special-tags77409-Node: Tag values78922-Ref: #tag-values79032-Node: Directives79904-Ref: #directives80031-Node: Directives and multiple files81361-Ref: #directives-and-multiple-files81539-Node: Directive effects82306-Ref: #directive-effects82460-Node: account directive85462-Ref: #account-directive85618-Node: Account comments86912-Ref: #account-comments87063-Node: Account error checking87571-Ref: #account-error-checking87764-Node: Account display order88953-Ref: #account-display-order89141-Node: Account types90151-Ref: #account-types90292-Node: alias directive93925-Ref: #alias-directive94086-Node: Basic aliases95136-Ref: #basic-aliases95267-Node: Regex aliases96011-Ref: #regex-aliases96168-Node: Combining aliases97058-Ref: #combining-aliases97236-Node: Aliases and multiple files98512-Ref: #aliases-and-multiple-files98716-Node: end aliases directive99295-Ref: #end-aliases-directive99514-Node: Aliases can generate bad account names99663-Ref: #aliases-can-generate-bad-account-names99911-Node: Aliases and account types100496-Ref: #aliases-and-account-types100688-Node: commodity directive101384-Ref: #commodity-directive101558-Node: Commodity directive syntax102971-Ref: #commodity-directive-syntax103156-Node: Commodity error checking104607-Ref: #commodity-error-checking104788-Node: decimal-mark directive105082-Ref: #decimal-mark-directive105264-Node: include directive105661-Ref: #include-directive105825-Node: P directive106737-Ref: #p-directive106882-Node: payee directive107771-Ref: #payee-directive107920-Node: tag directive108393-Ref: #tag-directive108548-Node: Periodic transactions109005-Ref: #periodic-transactions109170-Node: Periodic rule syntax111159-Ref: #periodic-rule-syntax111337-Node: Periodic rules and relative dates111982-Ref: #periodic-rules-and-relative-dates112248-Node: Two spaces between period expression and description!112759-Ref: #two-spaces-between-period-expression-and-description113036-Node: Auto postings113720-Ref: #auto-postings113868-Node: Auto postings and multiple files116698-Ref: #auto-postings-and-multiple-files116862-Node: Auto postings and dates117263-Ref: #auto-postings-and-dates117511-Node: Auto postings and transaction balancing / inferred amounts / balance assertions117686-Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions118042-Node: Auto posting tags118545-Ref: #auto-posting-tags118827-Node: Auto postings on forecast transactions only119463-Ref: #auto-postings-on-forecast-transactions-only119709-Node: Other syntax119956-Ref: #other-syntax120072-Node: Balance assignments120728-Ref: #balance-assignments120884-Node: Balance assignments and costs122256-Ref: #balance-assignments-and-costs122468-Node: Balance assignments and multiple files122678-Ref: #balance-assignments-and-multiple-files122908-Node: Bracketed posting dates123101-Ref: #bracketed-posting-dates123285-Node: D directive123799-Ref: #d-directive123967-Node: apply account directive125572-Ref: #apply-account-directive125752-Node: Y directive126439-Ref: #y-directive126599-Node: Secondary dates127427-Ref: #secondary-dates127581-Node: Star comments128395-Ref: #star-comments128555-Node: Valuation expressions129087-Ref: #valuation-expressions129264-Node: Virtual postings129386-Ref: #virtual-postings129563-Node: Other Ledger directives131010-Ref: #other-ledger-directives131206-Node: Other cost/lot notations131772-Ref: #other-costlot-notations131945-Node: CSV134534-Ref: #csv134627-Node: CSV rules cheatsheet136624-Ref: #csv-rules-cheatsheet136753-Node: source138551-Ref: #source138674-Node: separator139554-Ref: #separator139667-Node: skip140207-Ref: #skip140315-Node: date-format140859-Ref: #date-format140980-Node: timezone141704-Ref: #timezone141827-Node: newest-first142832-Ref: #newest-first142970-Node: intra-day-reversed143547-Ref: #intra-day-reversed143701-Node: decimal-mark144149-Ref: #decimal-mark144290-Node: fields list144629-Ref: #fields-list144768-Node: Field assignment146439-Ref: #field-assignment146583-Node: Field names147660-Ref: #field-names147791-Node: date field148994-Ref: #date-field149112-Node: date2 field149160-Ref: #date2-field149301-Node: status field149357-Ref: #status-field149500-Node: code field149549-Ref: #code-field149694-Node: description field149739-Ref: #description-field149899-Node: comment field149958-Ref: #comment-field150113-Node: account field150406-Ref: #account-field150556-Node: amount field151126-Ref: #amount-field151275-Node: currency field153967-Ref: #currency-field154120-Node: balance field154377-Ref: #balance-field154509-Node: if block154902-Ref: #if-block155023-Node: Matchers156431-Ref: #matchers156545-Node: What matchers match157342-Ref: #what-matchers-match157491-Node: Combining matchers157931-Ref: #combining-matchers158099-Node: Match groups158636-Ref: #match-groups158764-Node: if table159532-Ref: #if-table159654-Node: balance-type161535-Ref: #balance-type161664-Node: include162364-Ref: #include162491-Node: Working with CSV162935-Ref: #working-with-csv163082-Node: Rapid feedback163489-Ref: #rapid-feedback163622-Node: Valid CSV164074-Ref: #valid-csv164220-Node: File Extension164952-Ref: #file-extension165125-Node: Reading CSV from standard input165689-Ref: #reading-csv-from-standard-input165913-Node: Reading multiple CSV files166077-Ref: #reading-multiple-csv-files166308-Node: Reading files specified by rule166549-Ref: #reading-files-specified-by-rule166777-Node: Valid transactions167948-Ref: #valid-transactions168147-Node: Deduplicating importing168775-Ref: #deduplicating-importing168970-Node: Setting amounts170006-Ref: #setting-amounts170177-Node: Amount signs172535-Ref: #amount-signs172705-Node: Setting currency/commodity173602-Ref: #setting-currencycommodity173806-Node: Amount decimal places174980-Ref: #amount-decimal-places175186-Node: Referencing other fields175498-Ref: #referencing-other-fields175711-Node: How CSV rules are evaluated176608-Ref: #how-csv-rules-are-evaluated176825-Node: Well factored rules178278-Ref: #well-factored-rules178446-Node: CSV rules examples178770-Ref: #csv-rules-examples178905-Node: Bank of Ireland178970-Ref: #bank-of-ireland179107-Node: Coinbase180569-Ref: #coinbase180707-Node: Amazon181754-Ref: #amazon181879-Node: Paypal183598-Ref: #paypal183706-Node: Timeclock191350-Ref: #timeclock191455-Node: Timedot193631-Ref: #timedot193754-Node: Timedot examples196875-Ref: #timedot-examples196981-Node: PART 3 REPORTING CONCEPTS199152-Ref: #part-3-reporting-concepts199321-Node: Amount formatting199321-Ref: #amount-formatting199477-Node: Commodity display style199579-Ref: #commodity-display-style199733-Node: Rounding201420-Ref: #rounding201575-Node: Trailing decimal marks202025-Ref: #trailing-decimal-marks202204-Node: Amount parseability202958-Ref: #amount-parseability203114-Node: Time periods204539-Ref: #time-periods204665-Node: Report start & end date204783-Ref: #report-start-end-date204935-Node: Smart dates206594-Ref: #smart-dates206747-Node: Report intervals208615-Ref: #report-intervals208770-Node: Date adjustment209188-Ref: #date-adjustment209348-Node: Period expressions210199-Ref: #period-expressions210340-Node: Period expressions with a report interval212104-Ref: #period-expressions-with-a-report-interval212338-Node: More complex report intervals212552-Ref: #more-complex-report-intervals212797-Node: Multiple weekday intervals214598-Ref: #multiple-weekday-intervals214787-Node: Depth215609-Ref: #depth215711-Node: Queries216007-Ref: #queries216109-Node: Query types217705-Ref: #query-types217826-Node: Combining query terms221060-Ref: #combining-query-terms221237-Node: Queries and command options222800-Ref: #queries-and-command-options223005-Node: Queries and account aliases223254-Ref: #queries-and-account-aliases223459-Node: Queries and valuation223579-Ref: #queries-and-valuation223736-Node: Pivoting223941-Ref: #pivoting224055-Node: Generating data225832-Ref: #generating-data225964-Node: Forecasting227547-Ref: #forecasting227672-Node: --forecast228203-Ref: #forecast228334-Node: Inspecting forecast transactions229304-Ref: #inspecting-forecast-transactions229506-Node: Forecast reports230636-Ref: #forecast-reports230809-Node: Forecast tags231745-Ref: #forecast-tags231905-Node: Forecast period in detail232365-Ref: #forecast-period-in-detail232559-Node: Forecast troubleshooting233453-Ref: #forecast-troubleshooting233621-Node: Budgeting234524-Ref: #budgeting234644-Node: Cost reporting235081-Ref: #cost-reporting235215-Node: Recording costs235876-Ref: #recording-costs236012-Node: Reporting at cost237603-Ref: #reporting-at-cost237778-Node: Equity conversion postings238368-Ref: #equity-conversion-postings238582-Node: Inferring equity conversion postings241013-Ref: #inferring-equity-conversion-postings241276-Node: Combining costs and equity conversion postings242028-Ref: #combining-costs-and-equity-conversion-postings242338-Node: Requirements for detecting equity conversion postings243253-Ref: #requirements-for-detecting-equity-conversion-postings243575-Node: Infer cost and equity by default ?244775-Ref: #infer-cost-and-equity-by-default245004-Node: Value reporting245212-Ref: #value-reporting245354-Node: -V Value246093-Ref: #v-value246225-Node: -X Value in specified commodity246420-Ref: #x-value-in-specified-commodity246621-Node: Valuation date246770-Ref: #valuation-date246947-Node: Finding market price247730-Ref: #finding-market-price247941-Node: --infer-market-prices market prices from transactions249110-Ref: #infer-market-prices-market-prices-from-transactions249392-Node: Valuation commodity252154-Ref: #valuation-commodity252374-Node: --value Flexible valuation253587-Ref: #value-flexible-valuation253786-Node: Valuation examples255430-Ref: #valuation-examples255630-Node: Interaction of valuation and queries257562-Ref: #interaction-of-valuation-and-queries257802-Node: Effect of valuation on reports258279-Ref: #effect-of-valuation-on-reports258482-Node: PART 4 COMMANDS266177-Ref: #part-4-commands266326-Node: Commands overview266705-Ref: #commands-overview266839-Node: DATA ENTRY267018-Ref: #data-entry267142-Node: DATA CREATION267341-Ref: #data-creation267495-Node: DATA MANAGEMENT267613-Ref: #data-management267778-Node: REPORTS FINANCIAL267899-Ref: #reports-financial268074-Node: REPORTS VERSATILE268379-Ref: #reports-versatile268552-Node: REPORTS BASIC268805-Ref: #reports-basic268957-Node: HELP269466-Ref: #help269588-Node: ADD-ONS269698-Ref: #add-ons269804-Node: accounts270383-Ref: #accounts270516-Node: activity272403-Ref: #activity272522-Node: add272896-Ref: #add273006-Node: aregister275992-Ref: #aregister276113-Node: aregister and posting dates279019-Ref: #aregister-and-posting-dates279164-Node: balance279920-Ref: #balance280046-Node: balance features281036-Ref: #balance-features281176-Node: Simple balance report283086-Ref: #simple-balance-report283271-Node: Balance report line format284896-Ref: #balance-report-line-format285098-Node: Filtered balance report287256-Ref: #filtered-balance-report287448-Node: List or tree mode287775-Ref: #list-or-tree-mode287943-Node: Depth limiting289288-Ref: #depth-limiting289454-Node: Dropping top-level accounts290055-Ref: #dropping-top-level-accounts290255-Node: Showing declared accounts290565-Ref: #showing-declared-accounts290764-Node: Sorting by amount291295-Ref: #sorting-by-amount291462-Node: Percentages292132-Ref: #percentages292291-Node: Multi-period balance report292839-Ref: #multi-period-balance-report293039-Node: Balance change end balance295416-Ref: #balance-change-end-balance295625-Node: Balance report types297053-Ref: #balance-report-types297234-Node: Calculation type297732-Ref: #calculation-type297887-Node: Accumulation type298436-Ref: #accumulation-type298616-Node: Valuation type299537-Ref: #valuation-type299725-Node: Combining balance report types300726-Ref: #combining-balance-report-types300920-Node: Budget report302758-Ref: #budget-report302920-Node: Using the budget report305063-Ref: #using-the-budget-report305236-Node: Budget date surprises307339-Ref: #budget-date-surprises307539-Node: Selecting budget goals308703-Ref: #selecting-budget-goals308906-Node: Budgeting vs forecasting309651-Ref: #budgeting-vs-forecasting309828-Node: Balance report layout311328-Ref: #balance-report-layout311513-Node: Wide layout312466-Ref: #wide-layout312601-Node: Tall layout314871-Ref: #tall-layout315026-Node: Bare layout316177-Ref: #bare-layout316332-Node: Tidy layout318236-Ref: #tidy-layout318371-Node: Some useful balance reports319780-Ref: #some-useful-balance-reports319955-Node: balancesheet321040-Ref: #balancesheet321185-Node: balancesheetequity322796-Ref: #balancesheetequity322954-Node: cashflow324974-Ref: #cashflow325105-Node: check326592-Ref: #check326706-Node: Default checks327510-Ref: #default-checks327636-Node: Strict checks328133-Ref: #strict-checks328278-Node: Other checks328758-Ref: #other-checks328900-Node: Custom checks329433-Ref: #custom-checks329590-Node: More about specific checks330007-Ref: #more-about-specific-checks330169-Node: close330875-Ref: #close330986-Node: close --migrate331639-Ref: #close---migrate331766-Node: close --close333405-Ref: #close---close333549-Node: close --open333785-Ref: #close---open333926-Node: close --assert334036-Ref: #close---assert334182-Node: close --assign334403-Ref: #close---assign334551-Node: close --retain335077-Ref: #close---retain335230-Node: close customisation335975-Ref: #close-customisation336154-Node: close and balance assertions337621-Ref: #close-and-balance-assertions337818-Node: close examples339145-Ref: #close-examples339286-Node: Retain earnings339384-Ref: #retain-earnings339543-Node: Migrate balances to a new file339889-Ref: #migrate-balances-to-a-new-file340115-Node: More detailed close examples341243-Ref: #more-detailed-close-examples341441-Node: codes341467-Ref: #codes341584-Node: commodities342448-Ref: #commodities342576-Node: demo342646-Ref: #demo342767-Node: descriptions343683-Ref: #descriptions343813-Node: diff344104-Ref: #diff344219-Node: files345261-Ref: #files345370-Node: help345511-Ref: #help-1345620-Node: import346993-Ref: #import347116-Node: Deduplication348224-Ref: #deduplication348349-Node: Import testing351210-Ref: #import-testing351375-Node: Importing balance assignments352218-Ref: #importing-balance-assignments352424-Node: Commodity display styles353073-Ref: #commodity-display-styles353246-Node: incomestatement353375-Ref: #incomestatement353517-Node: notes354991-Ref: #notes355113-Node: payees355475-Ref: #payees355590-Node: prices356109-Ref: #prices356224-Node: print356877-Ref: #print356992-Node: print explicitness357968-Ref: #print-explicitness358111-Node: print amount style358890-Ref: #print-amount-style359060-Node: print parseability360130-Ref: #print-parseability360302-Node: print other features361051-Ref: #print-other-features361230-Node: print output format361751-Ref: #print-output-format361899-Node: register365038-Ref: #register365160-Node: Custom register output370191-Ref: #custom-register-output370322-Node: rewrite371669-Ref: #rewrite371787-Node: Re-write rules in a file373685-Ref: #re-write-rules-in-a-file373848-Node: Diff output format374997-Ref: #diff-output-format375180-Node: rewrite vs print --auto376272-Ref: #rewrite-vs.-print---auto376432-Node: roi376988-Ref: #roi377095-Node: Spaces and special characters in --inv and --pnl378907-Ref: #spaces-and-special-characters-in---inv-and---pnl379147-Node: Semantics of --inv and --pnl379635-Ref: #semantics-of---inv-and---pnl379874-Node: IRR and TWR explained381724-Ref: #irr-and-twr-explained381884-Node: stats385137-Ref: #stats385245-Node: tags386759-Ref: #tags-1386866-Node: test387875-Ref: #test387968-Node: PART 5 COMMON TASKS388710-Ref: #part-5-common-tasks388856-Node: Getting help389154-Ref: #getting-help389295-Node: Constructing command lines390055-Ref: #constructing-command-lines390256-Node: Starting a journal file390913-Ref: #starting-a-journal-file391115-Node: Setting LEDGER_FILE392317-Ref: #setting-ledger_file392509-Node: Setting opening balances393466-Ref: #setting-opening-balances393667-Node: Recording transactions396808-Ref: #recording-transactions396997-Node: Reconciling397553-Ref: #reconciling397705-Node: Reporting399962-Ref: #reporting400111-Node: Migrating to a new file404096-Ref: #migrating-to-a-new-file404253-Node: BUGS404552-Ref: #bugs404642-Node: Troubleshooting405521-Ref: #troubleshooting405621+ This manual is for hledger's command line interface, version 1.33.1.+It also describes the common options, file formats and concepts used by+all hledger programs. It might accidentally teach you some+bookkeeping/accounting as well! You don't need to know everything in+here to use hledger productively, but when you have a question about+functionality, this doc should answer it. It is detailed, so do skip+ahead or skim when needed. You can read it on hledger.org, or as an+info manual or man page on your system. You can also get it from+hledger itself with+'hledger --man', 'hledger --info' or 'hledger help [TOPIC]'.++ The main function of the hledger CLI is to read plain text files+describing financial transactions, crunch the numbers, and print a+useful report on the terminal (or save it as HTML, CSV, JSON or SQL).+Many reports are available, as subcommands. hledger will also detect+other 'hledger-*' executables as extra subcommands.++ hledger usually reads from (and appends to) a journal file specified+by the 'LEDGER_FILE' environment variable (defaulting to+'$HOME/.hledger.journal'); or you can specify files with '-f' options.+It can also read timeclock files, timedot files, or any CSV/SSV/TSV file+with a date field.++ Here is a small journal file describing one transaction:++2015-10-16 bought food+ expenses:food $10+ assets:cash++ Transactions are dated movements of money (etc.) between two or more+_accounts_: bank accounts, your wallet, revenue/expense categories,+people, etc. You can choose any account names you wish, using ':' to+indicate subaccounts. There must be at least two spaces between account+name and amount. Positive amounts are inflow to that account (_debit_),+negatives are outflow from it (_credit_). (Some reports show revenue,+liability and equity account balances as negative numbers as a result;+this is normal.)++ hledger's add command can help you add transactions, or you can+install other data entry UIs like hledger-web or hledger-iadd. For more+extensive/efficient changes, use a text editor: Emacs + ledger-mode, VIM++ vim-ledger, or VS Code + hledger-vscode are some good choices (see+https://hledger.org/editors.html).++ To get started, run 'hledger add' and follow the prompts, or save+some entries like the above in '$HOME/.hledger.journal', then try+commands like:++$ hledger print -x+$ hledger aregister assets+$ hledger balance+$ hledger balancesheet+$ hledger incomestatement++ Run 'hledger' to list the commands. See also the "Starting a journal+file" and "Setting opening balances" sections in PART 5: COMMON TASKS.++* Menu:++* PART 1 USER INTERFACE::+* Input::+* Commands::+* Options::+* Command line tips::+* Output::+* Environment::+* PART 2 DATA FORMATS::+* Journal::+* CSV::+* Timeclock::+* Timedot::+* PART 3 REPORTING CONCEPTS::+* Amount formatting::+* Time periods::+* Depth::+* Queries::+* Pivoting::+* Generating data::+* Forecasting::+* Budgeting::+* Cost reporting::+* Value reporting::+* PART 4 COMMANDS::+* PART 5 COMMON TASKS::+* BUGS::+++File: hledger.info, Node: PART 1 USER INTERFACE, Next: Input, Prev: Top, Up: Top++1 PART 1: USER INTERFACE+************************+++File: hledger.info, Node: Input, Next: Commands, Prev: PART 1 USER INTERFACE, Up: Top++2 Input+*******++hledger reads one or more data files, each time you run it. You can+specify a file with '-f', like so++$ hledger -f FILE print++ Files are most often in hledger's journal format, with the '.journal'+file extension ('.hledger' or '.j' also work); these files describe+transactions, like an accounting general journal.++ When no file is specified, hledger looks for '.hledger.journal' in+your home directory.++ But most people prefer to keep financial files in a dedicated folder,+perhaps with version control. Also, starting a new journal file each+year is common (it's not required, but helps keep things fast and+organised). So we usually configure a different journal file, by+setting the 'LEDGER_FILE' environment variable, to something like+'~/finance/2023.journal'. For more about how to do that on your system,+see Common tasks > Setting LEDGER_FILE.++* Menu:++* Text encoding::+* Data formats::+* Standard input::+* Multiple files::+* Strict mode::+++File: hledger.info, Node: Text encoding, Next: Data formats, Up: Input++2.1 Text encoding+=================++Data files containing non-ascii characters must use UTF-8 encoding. An+optional byte order mark (BOM) is allowed, at the beginning of the file+(only).++ Also, your system should be configured with a locale that can decode+UTF-8 text. On some unix systems, you may need set the 'LANG'+environment variable, eg. You can read more about this in Unicode+characters, below.++ On unix systems you can check a file's encoding with the 'file'+command. If you need to import from a UTF-16-encoded CSV file, say, you+can convert it to UTF-8 with the 'iconv' command.+++File: hledger.info, Node: Data formats, Next: Standard input, Prev: Text encoding, Up: Input++2.2 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: Automatically used for+ files with extensions:+---------------------------------------------------------------------------+'journal' hledger journal files and some '.journal' '.j'+ Ledger journals, for '.hledger' '.ledger'+ transactions+'timeclock' timeclock files, for precise '.timeclock'+ time logging+'timedot' timedot files, for approximate '.timedot'+ time logging+'csv' Comma or other character '.csv'+ separated values, for data+ import+'ssv' Semicolon separated values '.ssv'+'tsv' Tab separated values '.tsv'+'rules' CSV/SSV/TSV/other separated '.rules'+ values, alternate way++ These formats are described in more detail below.++ hledger detects the format automatically based on the file extensions+shown above. If it can't recognise the file extension, it assumes+'journal' format. So for non-journal files, it's important to use a+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 containing+tab separated values:++$ hledger -f tsv:/some/file.dat stats+++File: hledger.info, Node: Standard input, Next: Multiple files, Prev: Data formats, Up: Input++2.3 Standard input+==================++The file name '-' means standard input:++$ cat FILE | hledger -f- print++ If reading non-journal data in this way, you'll need to add a file+format prefix, like:++$ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:-+++File: hledger.info, Node: Multiple files, Next: Strict mode, Prev: Standard input, Up: Input++2.4 Multiple files+==================++You can specify multiple '-f' options, to read multiple files as one big+journal. When doing this, note that certain features (described below)+will be affected:++ * Balance assertions will not see the effect of transactions in+ previous files. (Usually this doesn't matter as each file will set+ the corresponding opening balances.)+ * Some directives will not affect previous or subsequent files.++ If needed, you can work around these by using a single parent file+which includes the others, or concatenating the files into one, eg: 'cat+a.journal b.journal | hledger -f- CMD'.+++File: hledger.info, Node: Strict mode, Prev: Multiple files, Up: Input++2.5 Strict mode+===============++hledger checks input files for valid data. By default, the most+important errors are detected, while still accepting easy journal files+without a lot of declarations:++ * Are the input files parseable, with valid syntax ?+ * Are all transactions balanced ?+ * Do all balance assertions pass ?++ With the '-s'/'--strict' flag, additional checks are performed:++ * Are all accounts posted to, declared with an 'account' directive ?+ (Account error checking)+ * Are all commodities declared with a 'commodity' directive ?+ (Commodity error checking)+ * Are all commodity conversions declared explicitly ?++ You can use the check command to run individual checks - the ones+listed above and some more.+++File: hledger.info, Node: Commands, Next: Options, Prev: Input, Up: Top++3 Commands+**********++hledger provides various subcommands for getting things done. Most of+these commands do not change the journal file; they just read it and+output a report. A few commands assist with adding data and file+management.++ To show the commands list, run 'hledger' with no arguments. The+commands are described in detail in PART 4: COMMANDS, below.++ To use a particular command, run 'hledger CMD [CMDOPTS] [CMDARGS]',++ * CMD is the full command name, or its standard abbreviation shown in+ the commands list, or any unambiguous prefix of the name.++ * CMDOPTS are command-specific options, if any. Command-specific+ options must be written after the command name. Eg: 'hledger print+ -x'.++ * CMDARGS are additional arguments to the command, if any. Most+ hledger commands accept arguments representing a query, to limit+ the data in some way. Eg: 'hledger reg assets:checking'.++ To list a command's options, arguments, and documentation in the+terminal, run 'hledger CMD -h'. Eg: 'hledger bal -h'.++* Menu:++* Add-on commands::+++File: hledger.info, Node: Add-on commands, Up: Commands++3.1 Add-on commands+===================++In addition to the built-in commands, you can install _add-on commands_:+programs or scripts named "hledger-SOMETHING", which will also appear in+hledger's commands list. If you used the hledger-install script, you+will have several add-ons installed already. Some more can be found in+hledger's bin/ directory, documented at+https://hledger.org/scripts.html.++ More precisely, add-on commands are programs or scripts in your+shell's PATH, whose name starts with "hledger-" and ends with no+extension or a recognised extension (".bat", ".com", ".exe", ".hs",+".js", ".lhs", ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"),+and (on unix and mac) which has executable permission for the current+user.++ You can run add-on commands using hledger, much like built-in+commands: 'hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]'. But note+the double hyphen argument, required before add-on-specific options.+Eg: 'hledger ui -- --watch' or 'hledger web -- --serve'. If this causes+difficulty, you can always run the add-on directly, without using+'hledger': 'hledger-ui --watch' or 'hledger-web --serve'.+++File: hledger.info, Node: Options, Next: Command line tips, Prev: Commands, Up: Top++4 Options+*********++Run 'hledger -h' to see general command line help, and general options+which are common to most hledger commands. These options can be written+anywhere on the command line. They can be grouped into help, input, and+reporting options:++* Menu:++* General help options::+* General input options::+* General reporting options::+++File: hledger.info, Node: General help options, Next: General input options, Up: Options++4.1 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)+++File: hledger.info, Node: General input options, Next: General reporting options, Prev: General help options, Up: Options++4.2 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+'--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)+++File: hledger.info, Node: General reporting options, Prev: General input options, Up: Options++4.3 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+ following 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)+'--today=DATE'++ override today's date (affects relative smart dates, for+ tests/examples)+'-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+ commodities+'-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-equity'++ infer conversion equity postings from costs+'--infer-costs'++ infer costs from conversion equity postings+'--infer-market-prices'++ use costs as additional market prices, as if they were P directives+'--forecast'++ generate transactions from periodic rules, between the latest+ recorded txn and 6 months from today, or during the specified+ PERIOD (= is required). Auto posting rules will be applied to+ these transactions as well. Also, in hledger-ui make future-dated+ transactions visible.+'--auto'++ generate extra postings by applying auto posting rules to all txns+ (not just forecast txns)+'--verbose-tags'++ add visible tags indicating transactions or postings which have+ been generated/modified+'--commodity-style'++ Override the commodity style in the output for the specified+ commodity. For example 'EUR1.000,00'.+'--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.+'--pretty[=WHEN]'++ Show prettier output, e.g. using unicode box-drawing characters.+ Accepts 'yes' (the default) or 'no' ('y', 'n', 'always', 'never'+ also work). If you provide an argument you must use '=', e.g.+ '-pretty=yes'.++ 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.+++File: hledger.info, Node: Command line tips, Next: Output, Prev: Options, Up: Top++5 Command line tips+*******************++Here are some details useful to know about for hledger command lines+(and elsewhere). Feel free to skip this section until you need it.++* Menu:++* Option repetition::+* Special characters::+* Unicode characters::+* Regular expressions::+* Argument files::+++File: hledger.info, Node: Option repetition, Next: Special characters, Up: Command line tips++5.1 Option repetition+=====================++If options are repeated in a command line, hledger will generally use+the last (right-most) occurence.+++File: hledger.info, Node: Special characters, Next: Unicode characters, Prev: Option repetition, Up: Command line tips++5.2 Special characters+======================++* Menu:++* Single escaping shell metacharacters::+* Double escaping regular expression metacharacters::+* Triple escaping for add-on commands::+* Less escaping::+++File: hledger.info, Node: Single escaping shell metacharacters, Next: Double escaping regular expression metacharacters, Up: Special characters++5.2.1 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 double 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.+++File: hledger.info, Node: Double escaping regular expression metacharacters, Next: Triple escaping for add-on commands, Prev: Single escaping shell metacharacters, Up: Special characters++5.2.2 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:\\$+++File: hledger.info, Node: Triple escaping for add-on commands, Next: Less escaping, Prev: Double escaping regular expression metacharacters, Up: Special characters++5.2.3 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+arguments intended for by the add-on command, so those need an extra+level of shell-escaping. Eg to match a literal '$' sign while using the+bash shell and running an add-on command ('ui'):++$ hledger ui cur:'\\$'++ or:++$ hledger ui cur:\\\\$++ If you wondered why _four_ backslashes, perhaps this helps:++unescaped: '$'+escaped: '\$'+double-escaped: '\\$'+triple-escaped: '\\\\$'++ Or, you can avoid the extra escaping by running the add-on executable+directly:++$ hledger-ui cur:\\$+++File: hledger.info, Node: Less escaping, Prev: Triple escaping for add-on commands, Up: Special characters++5.2.4 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:++ * an @argumentfile+ * hledger-ui's filter field+ * hledger-web's search form+ * GHCI's prompt (used by developers).+++File: hledger.info, Node: Unicode characters, Next: Regular expressions, Prev: Special characters, Up: Command line tips++5.3 Unicode characters+======================++hledger is expected to handle non-ascii characters correctly:++ * 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.)++ * 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:++ * 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 Troubleshooting. This step is essential - without it, hledger+ will quit on encountering a non-ascii character (as with all+ GHC-compiled programs).++ * your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)+ must support unicode++ * the terminal must be using a font which includes the required+ unicode glyphs++ * the terminal should be configured to display wide characters as+ double width (for report alignment)++ * on Windows, for best results you should run hledger in the same+ kind of environment in which it was built. Eg hledger built in the+ standard CMD.EXE environment (like the binaries on our download+ page) might show display problems when run in a cygwin or msys+ terminal, and vice versa. (See eg #961).+++File: hledger.info, Node: Regular expressions, Next: Argument files, Prev: Unicode characters, Up: Command line tips++5.4 Regular expressions+=======================++A regular expression (regexp) is a small piece of text where certain+characters (like '.', '^', '$', '+', '*', '()', '|', '[]', '\') have+special meanings, forming a tiny language for matching text precisely -+very useful in hledger and elsewhere. To learn all about them, visit+regular-expressions.info.++ hledger supports regexps whenever you are entering a pattern to match+something, eg in query arguments, account aliases, CSV if rules,+hledger-web's search form, hledger-ui's '/' search, etc. You may need+to wrap them in quotes, especially at the command line (see Special+characters above). Here are some examples:++ Account name queries (quoted for command line use):++Regular expression: Matches:+------------------- ------------------------------------------------------------+bank assets:bank, assets:bank:savings, expenses:art:banksy, ...+:bank assets:bank:savings, expenses:art:banksy+:bank: assets:bank:savings+'^bank' none of those ( ^ matches beginning of text )+'bank$' assets:bank ( $ matches end of text )+'big \$ bank' big $ bank ( \ disables following character's special meaning )+'\bbank\b' assets:bank, assets:bank:savings ( \b matches word boundaries )+'(sav|check)ing' saving or checking ( (|) matches either alternative )+'saving|checking' saving or checking ( outer parentheses are not needed )+'savings?' saving or savings ( ? matches 0 or 1 of the preceding thing )+'my +bank' my bank, my bank, ... ( + matches 1 or more of the preceding thing )+'my *bank' mybank, my bank, my bank, ... ( * matches 0 or more of the preceding thing )+'b.nk' bank, bonk, b nk, ... ( . matches any character )++ Some other queries:++desc:'amazon|amzn|audible' Amazon transactions+cur:EUR amounts with commodity symbol containing EUR+cur:'\$' amounts with commodity symbol containing $+cur:'^\$$' only $ amounts, not eg AU$ or CA$+cur:....? amounts with 4-or-more-character symbols+tag:.=202[1-3] things with any tag whose value contains 2021, 2022 or 2023++ Account name aliases: accept '.' instead of ':' as account separator:++alias /\./=: replaces all periods in account names with colons++ Show multiple top-level accounts combined as one:++--alias='/^[^:]+/=combined' ( [^:] matches any character other than : )++ Show accounts with the second-level part removed:++--alias '/^([^:]+):[^:]+/ = \1'+ match a top-level account and a second-level account+ and replace those with just the top-level account+ ( \1 in the replacement text means "whatever was matched+ by the first parenthesised part of the regexp"++ CSV rules: match CSV records containing dining-related MCC codes:++if \?MCC581[124]++ Match CSV records with a specific amount around the end/start of+month:++if %amount \b3\.99+& %date (29|30|31|01|02|03)$++* Menu:++* hledger's regular expressions::+++File: hledger.info, Node: hledger's regular expressions, Up: Regular expressions++5.4.1 hledger's regular expressions+-----------------------------------++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. backreferences are supported when doing text replacement in account+ aliases or CSV rules, where backreferences can be used in the+ replacement string to reference capturing groups in the search+ regexp. Otherwise, if you write '\1', it will match the digit '1'.+ 6. they do not support mode modifiers ('(?s)'), character classes+ ('\w', '\d'), or anything else not mentioned above.++ Some things to note:++ * In the 'alias' directive and '--alias' option, regular expressions+ must be enclosed in forward slashes ('/REGEX/'). Elsewhere in+ hledger, these are not required.++ * 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:\$'.++ * On the command line, some metacharacters like '$' have a special+ meaning to the shell and so must be escaped at least once more.+ See Special characters.+++File: hledger.info, Node: Argument files, Prev: Regular expressions, Up: Command line tips++5.5 Argument files+==================++You can save a set of command line options and arguments in a file, and+then reuse them by writing '@FILENAME' as a command line argument. Eg:+'hledger bal @foo.args'.++ Inside the argument file, each line should contain just one option or+argument. Don't use spaces except inside quotes (or you'll see a+confusing error); write '=' (or nothing) between a flag and its+argument. For the special characters mentioned above, use one less+level of quoting than you would at the command prompt.+++File: hledger.info, Node: Output, Next: Environment, Prev: Command line tips, Up: Top++6 Output+********++* Menu:++* Output destination::+* Output format::+* Commodity styles::+* Colour::+* Box-drawing::+* Paging::+* Debug output::+++File: hledger.info, Node: Output destination, Next: Output format, Up: Output++6.1 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+provide 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)+++File: hledger.info, Node: Output format, Next: Commodity styles, Prev: Output destination, Up: Output++6.2 Output format+=================++Some commands offer other kinds of output, not just text on the+terminal. Here are those commands and the formats currently supported:++- txt csv/tsv html json sql+-------------------------------------------------------------------------------+aregister Y Y Y Y+balance Y _1_ Y _1_ Y _1,2_ Y+balancesheet Y _1_ Y _1_ Y _1_ Y+balancesheetequityY _1_ Y _1_ Y _1_ Y+cashflow Y _1_ Y _1_ Y _1_ Y+incomestatement Y _1_ Y _1_ Y _1_ Y+print Y Y Y Y+register Y Y Y++ * _1 Also affected by the balance commands' '--layout' option._+ * _2 'balance' does not support html output without a report interval+ or with '--budget'._++ The output format is selected by the '-O/--output-format=FMT' option:++$ hledger print -O csv # print CSV on stdout++ or by the filename extension of an output file specified with the+'-o/--output-file=FILE.FMT' option:++$ hledger balancesheet -o foo.csv # write CSV to foo.csv++ The '-O' option can be combined with '-o' to override the file+extension, if needed:++$ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt++ Some notes about the various output formats:++* Menu:++* CSV output::+* HTML output::+* JSON output::+* SQL output::+++File: hledger.info, Node: CSV output, Next: HTML output, Up: Output format++6.2.1 CSV output+----------------++ * In CSV output, digit group marks (such as thousands separators) are+ disabled automatically.+++File: hledger.info, Node: HTML output, Next: JSON output, Prev: CSV output, Up: Output format++6.2.2 HTML output+-----------------++ * HTML output can be styled by an optional 'hledger.css' file in the+ same directory.+++File: hledger.info, Node: JSON output, Next: SQL output, Prev: HTML output, Up: Output format++6.2.3 JSON output+-----------------++ * This is not yet much used; real-world feedback is welcome.++ * Our JSON is rather large and verbose, since it is a faithful+ representation 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.++ * 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)+++File: hledger.info, Node: SQL output, Prev: JSON output, Up: Output format++6.2.4 SQL output+----------------++ * This is not yet much used; real-world feedback is welcome.++ * SQL output is expected to work at least with SQLite, MySQL and+ Postgres.++ * For SQLite, it will be more useful if you modify the generated 'id'+ field to be a PRIMARY KEY. Eg:++ $ hledger print -O sql | sed 's/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g' | ...++ * SQL output is structured with the expectations that statements will+ be executed in the empty database. If you already have tables+ created via SQL output of hledger, you would probably want to+ either clear tables of existing data (via 'delete' or 'truncate'+ SQL statements) or drop tables completely as otherwise your+ postings will be duped.+++File: hledger.info, Node: Commodity styles, Next: Colour, Prev: Output format, Up: Output++6.3 Commodity styles+====================++When displaying amounts, hledger infers a standard display style for+each commodity/currency, as described below in Commodity display style.++ If needed, this can be overridden by a '-c/--commodity-style' option+(except for cost amounts and amounts displayed by the 'print' command,+which are always displayed with all decimal digits). For example, the+following will force dollar amounts to be displayed as shown:++$ hledger print -c '$1.000,0'++ This option can repeated to set the display style for multiple+commodities/currencies. Its argument is as described in the commodity+directive.++ In some cases hledger will adjust number formatting to improve their+parseability (such as adding trailing decimal marks when needed).+++File: hledger.info, Node: Colour, Next: Box-drawing, Prev: Commodity styles, Up: Output++6.4 Colour+==========++In terminal output, some commands can produce colour when the terminal+supports it:++ * if the '--color/--colour' option is given a value of 'yes' or+ 'always' (or 'no' or 'never'), colour will (or will not) be used;+ * otherwise, if the 'NO_COLOR' environment variable is set, colour+ will not be used;+ * otherwise, colour will be used if the output (terminal or file)+ supports it.+++File: hledger.info, Node: Box-drawing, Next: Paging, Prev: Colour, Up: Output++6.5 Box-drawing+===============++In terminal output, you can enable unicode box-drawing characters to+render prettier tables:++ * if the '--pretty' option is given a value of 'yes' or 'always' (or+ 'no' or 'never'), unicode characters will (or will not) be used;+ * otherwise, unicode characters will not be used.+++File: hledger.info, Node: Paging, Next: Debug output, Prev: Box-drawing, Up: Output++6.6 Paging+==========++When showing long output in the terminal, hledger will try to use the+pager specified by the 'PAGER' environment variable, or 'less', or+'more'. (A pager is a helper program that shows one page at a time+rather than scrolling everything off screen). Currently it does this+only for help output, not for reports; specifically,++ * when listing commands, with 'hledger'+ * when showing help with 'hledger [CMD] --help',+ * when viewing manuals with 'hledger help' or 'hledger --man'.++ Note the pager is expected to handle ANSI codes, which hledger uses+eg for bold emphasis. For the common pager 'less' (and its 'more'+compatibility mode), we add 'R' to the 'LESS' and 'MORE' environment+variables to make this work. If you use a different pager, you might+need to configure it similarly, to avoid seeing junk on screen (let us+know). Otherwise, you can set the 'NO_COLOR' environment variable to 1+to disable all ANSI output (see Colour).+++File: hledger.info, Node: Debug output, Prev: Paging, Up: Output++6.7 Debug output+================++We intend hledger to be relatively easy to troubleshoot, introspect and+develop. You can add '--debug[=N]' to any hledger command line to see+additional debug output. N ranges from 1 (least output, the default) to+9 (maximum output). Typically you would start with 1 and increase until+you are seeing enough. Debug output goes to stderr, and is not affected+by '-o/--output-file' (unless you redirect stderr to stdout, eg:+'2>&1'). It will be interleaved with normal output, which can help+reveal when parts of the code are evaluated. To capture debug output in+a log file instead, you can usually redirect stderr, eg:++hledger bal --debug=3 2>hledger.log+++File: hledger.info, Node: Environment, Next: PART 2 DATA FORMATS, Prev: Output, Up: Top++7 Environment+*************++These environment variables affect hledger:++ *COLUMNS* This is normally set by your terminal; some hledger+commands ('register') will format their output to this width. If not+set, they will try to use the available terminal width.++ *LEDGER_FILE* The main journal file to use when not specified with+'-f/--file'. Default: '$HOME/.hledger.journal'.++ *NO_COLOR* If this environment variable is set (with any value),+hledger will not use ANSI color codes in terminal output, unless+overridden by an explicit '--color/--colour' option.+++File: hledger.info, Node: PART 2 DATA FORMATS, Next: Journal, Prev: Environment, Up: Top++8 PART 2: DATA FORMATS+**********************+++File: hledger.info, Node: Journal, Next: CSV, Prev: PART 2 DATA FORMATS, Up: Top++9 Journal+*********++hledger's usual data source is a plain text file containing journal+entries in hledger 'journal' format. If you're looking for a quick+reference, jump ahead to the journal cheatsheet (or use the table of+contents at https://hledger.org/hledger.html).++ This file represents an accounting General Journal. The '.journal'+file extension is most often used, though not strictly 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 compatible with most of Ledger's journal+format, but not all of it. The differences and interoperation tips are+described at hledger and Ledger. With some care, and by avoiding+incompatible features, you can keep your hledger journal readable by+Ledger and vice versa. This can useful eg for comparing the behaviour+of one app against the other.++ 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+configuration at hledger.org for the full list.++ A hledger journal file can contain three kinds of thing: comment+lines, transactions, and/or directives (including periodic transaction+rules and auto posting rules). Understanding the journal file format+will also give you a good understanding of hledger's data model. Here's+a quick cheatsheet/overview, followed by detailed descriptions of each+part.++* Menu:++* Journal cheatsheet::+* Comments::+* Transactions::+* Dates::+* Status::+* Code::+* Description::+* Transaction comments::+* Postings::+* Account names::+* Amounts::+* Balance assertions::+* Posting comments::+* Transaction balancing::+* Tags::+* Directives::+* account directive::+* alias directive::+* commodity directive::+* decimal-mark directive::+* include directive::+* P directive::+* payee directive::+* tag directive::+* Periodic transactions::+* Auto postings::+* Other syntax::+++File: hledger.info, Node: Journal cheatsheet, Next: Comments, Up: Journal++9.1 Journal cheatsheet+======================++# Here is the main syntax of hledger's journal format+# (omitting extra Ledger compatibility syntax).++###############################################################################++# 1. These are comment lines, for notes or temporarily disabling things.+; They begin with # or ;++comment+Or, lines can be enclosed within "comment" / "end comment".+This is a block of +commented lines.+end comment++# Some journal entries can have semicolon comments at end of line ; like this+# Some of them require 2 or more spaces before the semicolon.++###############################################################################++# 2. Directives customise processing or output in some way.+# You don't need any directives to get started.+# But they can add more error checking, or change how things are displayed.+# They begin with a word, letter, or symbol. +# They are most often placed at the top, before transactions.++account assets ; Declare valid account names and display order.+account assets:savings ; A subaccount. This one represents a bank account.+account assets:checking ; Another. Note, 2+ spaces after the account name.+account assets:receivable ; Accounting type is inferred from english names,+account passifs ; or declared with a "type" tag, type:L+account expenses ; type:X+ ; A follow-on comment line, indented.+account expenses:rent ; Expense and revenue categories are also accounts.+ ; Subaccounts inherit their parent's type.++commodity $0.00 ; Declare valid commodities and their display styles.+commodity 1.000,00 EUR++decimal-mark . ; The decimal mark used in this file (if ambiguous).++payee Whole Foods ; Declare a valid payee name.++tag trip ; Declare a valid tag name.++P 2024-03-01 AAPL $179 ; Declare a market price for AAPL in $ on this date.++include other.journal ; Include another journal file here.++# Declare a recurring "periodic transaction", for budget/forecast reports+~ monthly set budget goals ; <- Note, 2+ spaces before the description.+ (expenses:rent) $1000+ (expenses:food) $500++# Declare an auto posting rule, to modify existing transactions in reports+= revenues:consulting+ liabilities:tax:2024:us *0.25 ; Add a tax liability & expense+ expenses:tax:2024:us *-0.25 ; for 25% of the revenue.++###############################################################################++# 3. Transactions are what it's all about.+# They are dated events, usually movements of money between 2 or more accounts.+# They begin with a numeric date.+# Here is their basic shape:+#+# DATE DESCRIPTION ; The transaction's date and optional description.+# ACCOUNT1 AMOUNT ; A posting of an amount to/from this account, indented.+# ACCOUNT2 AMOUNT ; A second posting, balancing the first.+# ... ; More if needed. Amounts must sum to zero.+# ; Note, 2+ spaces between account names and amounts.++2024-01-01 opening balances ; At the start, declare pre-existing balances this way.+ assets:savings $10000 ; Account names can be anything. lower case is easy to type.+ assets:checking $1000 ; assets, liabilities, equity, revenues, expenses are common.+ liabilities:credit card $-500 ; liabilities, equity, revenues balances are usually negative.+ equity:start ; One amount can be left blank. $-10500 is inferred here.+ ; Some of these accounts we didn't declare above,+ ; so -s/--strict would complain.++2024-01-03 ! (12345) pay rent+ ; Additional transaction comment lines, indented.+ ; There can be a ! or * after the date meaning "pending" or "cleared".+ ; There can be a parenthesised (code) after the date/status.+ ; Amounts' sign shows direction of flow.+ assets:checking $-500 ; Minus means removed from this account (credit).+ expenses:rent $500 ; Plus means added to this account (debit).++; Keeping transactions in date order is optional (but helps error checking).++2024-01-02 Gringott's Bank | withdrawal ; Description can be PAYEE | NOTE+ assets:bank:gold -10 gold+ assets:pouch 10 gold++2024-01-02 shopping+ expenses:clothing 1 gold+ expenses:wands 5 gold+ assets:pouch -6 gold++2024-01-02 receive gift+ revenues:gifts -3 "Chocolate Frogs" ; Complex commodity symbols+ assets:pouch 3 "Chocolate Frogs" ; must be in double quotes.++2024-01-15 buy some shares, in two lots ; Cost can be noted.+ assets:investments:2024-01-15 2.0 AAAA @ $1.50 ; @ means per-unit cost+ assets:investments:2024-01-15-02 3.0 AAAA @@ $4 ; @@ means total cost+ ; ^ Per-lot subaccounts are sometimes useful.+ assets:checking $-7++2024-01-15 assert some account balances on this date+ ; Balances can be asserted in any transaction, with =, for extra error checking.+ ; Assertion txns like this one can be made with hledger close --assert --show-costs+ ;+ assets:savings $0 = $10000+ assets:checking $0 = $493+ assets:bank:gold 0 gold = -10 gold+ assets:pouch 0 gold = 4 gold+ assets:pouch 0 "Chocolate Frogs" = 3 "Chocolate Frogs"+ assets:investments:2024-01-15 0.0 AAAA = 2.0 AAAA @ $1.50+ assets:investments:2024-01-15-02 0.0 AAAA = 3.0 AAAA @@ $4+ liabilities:credit card $0 = $-500++2024-02-01 note some event, or a transaction not yet fully entered, on this date+ ; Postings are not required.++; Some other date formats are allowed (but, consistent YYYY-MM-DD is useful).+2024.01.01+2024/1/1+++File: hledger.info, Node: Comments, Next: Transactions, Prev: Journal cheatsheet, Up: Journal++9.2 Comments+============++Lines in the journal will be ignored if they begin with a hash ('#') or+a semicolon (';'). (See also Other syntax.) hledger will also ignore+regions beginning with a 'comment' line and ending with an 'end comment'+line (or file end). Here's a suggestion for choosing between them:++ * '#' for top-level notes+ * ';' for commenting out things temporarily+ * 'comment' for quickly commenting large regions (remember it's+ there, or you might get confused)++ Eg:++# a comment line+; another commentline+comment+A multi-line comment block,+continuing until "end comment" directive+or the end of the current file.+end comment++ Some hledger entries can have same-line comments attached to them,+from ; (semicolon) to end of line. See Transaction comments, Posting+comments, and Account comments below.+++File: hledger.info, Node: Transactions, Next: Dates, Prev: Comments, Up: Journal++9.3 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+simple date in column 0. This can be followed by any of the following+optional fields, separated by spaces:++ * a status character (empty, '!', or '*')+ * a code (any short number or text, enclosed in parentheses)+ * a description (any remaining text until end of line or a semicolon)+ * a comment (any remaining text following a semicolon until end of+ line, and any following indented lines beginning with a semicolon)+ * 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+++File: hledger.info, Node: Dates, Next: Status, Prev: Transactions, Up: Journal++9.4 Dates+=========++* Menu:++* Simple dates::+* Posting dates::+++File: hledger.info, Node: Simple dates, Next: Posting dates, Up: Dates++9.4.1 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+current transaction, the default year set with a 'Y' 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.)+++File: hledger.info, Node: Posting dates, Prev: Simple dates, Up: Dates++9.4.2 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.+The 'date:' tag must have a valid simple date value if it is present, eg+a 'date:' tag with no value is not allowed.+++File: hledger.info, Node: Status, Next: Code, Prev: Dates, Up: Journal++9.5 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 (and you can combine these, eg+'-UP' to match all except cleared things). Or you can use the+'status:', 'status:!', and 'status:*' queries, or the U, P, C keys in+hledger-ui.++ (Note: in Ledger the "unmarked" state is called "uncleared"; in+hledger we renamed it to "unmarked" for semantic clarity.)++ Status marks are optional, but can be helpful eg for reconciling with+real-world accounts. Some editor modes provide highlighting and+shortcuts for working with status. Eg in Emacs ledger-mode, you can+toggle transaction status with C-c C-e, or posting status with C-c C-c.++ 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+ reconciliation)+cleared complete, reconciled as far as possible, and considered+ correct++ 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.+++File: hledger.info, Node: Code, Next: Description, Prev: Status, Up: Journal++9.6 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.+++File: hledger.info, Node: Description, Next: Transaction comments, Prev: Code, Up: Journal++9.7 Description+===============++After the date, status mark and/or code fields, the rest of the line (or+until a comment is begun with ';') is the transaction's description.+Here you can describe the transaction (called the "narration" in+traditional bookkeeping), or you can record a payee/payer name, or you+can leave it empty.++ Transaction descriptions show up in print output and in register+reports, and can be listed with the descriptions command.++ You can query by description with 'desc:DESCREGEX', or pivot on+description with '--pivot desc'.++* Menu:++* Payee and note::+++File: hledger.info, Node: Payee and note, Up: Description++9.7.1 Payee and note+--------------------++Sometimes people want a dedicated payee/payer field that can be queried+and checked more strictly. If you want that, you can write a '|' (pipe)+character in the description. This divides it into a "payee" field on+the left, and a "note" field on the right. (Either can be empty.)++ You can query these with 'payee:PAYEEREGEX' and 'note:NOTEREGEX',+list their values with the payees and notes commands, or pivot on+'payee' or 'note'.++ Note: in transactions with no '|' character, description, payee, and+note all have the same value. Once a '|' is added, they become+distinct. (If you'd like to change this behaviour, please propose it on+the mail list.)++ If you want more strict error checking, you can declare the valid+payee names with payee directives, and then enforce these with hledger+check payees. (Note: because of the above, for this you'll need to+ensure every transaction description contains a '|' and therefore a+checkable payee name, even if it's empty.)+++File: hledger.info, Node: Transaction comments, Next: Postings, Prev: Description, Up: Journal++9.8 Transaction comments+========================++Text following ';', after a transaction description, and/or on indented+lines immediately below it, form comments for that transaction. They+are reproduced by 'print' but otherwise ignored, except they may contain+tags, which are not ignored.++2012-01-01 something ; a transaction comment+ ; a second line of transaction comment+ expenses 1+ assets+++File: hledger.info, Node: Postings, Next: Account names, Prev: Transaction comments, Up: Journal++9.9 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:++ * (optional) a status character (empty, '!', or '*'), followed by a+ space+ * (required) an account name (any text, optionally containing *single+ spaces*, until end of line or a double space)+ * (optional) *two or more spaces* (or tabs) followed by an amount.++ If the amount is positive, it is being added to the account; if+negative, it is being removed from the account.++ The posting amounts in a transaction must sum up to zero, indicating+that the inflows and outflows are equal. We call this a balanced+transaction. (You can read more about the nitty-gritty details of "sum+up to zero" in Transaction balancing below.)++ As a convenience, you can optionally leave one amount blank; hledger+will infer what it should be so as to balance the transaction.++* Menu:++* Debits and credits::+* The two space delimiter::+++File: hledger.info, Node: Debits and credits, Next: The two space delimiter, Up: Postings++9.9.1 Debits and credits+------------------------++The traditional accounting concepts of debit and credit of course exist+in hledger, but we represent them with numeric sign, as described above.+Positive and negative posting amounts represent debits and credits+respectively.++ You don't need to remember that, but if you would like to - eg for+helping newcomers or for talking with your accountant - here's a handy+mnemonic:++ _'debit / plus / left / short words'_+_'credit / minus / right / longer words'_+++File: hledger.info, Node: The two space delimiter, Prev: Debits and credits, Up: Postings++9.9.2 The two space delimiter+-----------------------------++Be sure to notice the unusual separator between the account name and the+following amount. Because hledger allows account names with spaces in+them, you must separate the account name and amount (if any) by *two or+more spaces* (or tabs). It's easy to forget at first. If you ever see+the amount being treated as part of the account name, you'll know you+probably need to add another space between them.+++File: hledger.info, Node: Account names, Next: Amounts, Prev: Postings, Up: Journal++9.10 Account names+==================++Accounts are the main way of categorising things in hledger. As in+Double Entry Bookkeeping, they can represent real world accounts (such+as a bank account), or more abstract categories such as "money borrowed+from Frank" or "money spent on electricity".++ You can use any account names you like, but we usually start with the+traditional accounting categories, which in english are 'assets',+'liabilities', 'equity', 'revenues', 'expenses'. (You might see these+referred to as A, L, E, R, X for short.)++ For more precise reporting, we usually divide the top level accounts+into more detailed subaccounts, by writing a full colon between account+name parts. For example, from the account names 'assets:bank:checking'+and 'expenses:food', hledger will infer this hierarchy of five accounts:++assets+assets:bank+assets:bank:checking+expenses+expenses:food++ Shown as an outline, the hierarchical tree structure is more clear:++assets+ bank+ checking+expenses+ food++ hledger reports can summarise the account tree to any depth, so you+can go as deep as you like with subcategories, but keeping your account+names relatively simple may be best when starting out.++ Account names may be capitalised or not; they may contain letters,+numbers, symbols, or single spaces. Note, when an account name and an+amount are written on the same line, they must be separated by *two or+more spaces* (or tabs).++ Parentheses or brackets enclosing the full account name indicate+virtual postings, described below. Parentheses or brackets internal to+the account name have no special meaning.++ Account names can be altered temporarily or permanently by account+aliases.+++File: hledger.info, Node: Amounts, Next: Balance assertions, Prev: Account names, Up: Journal++9.11 Amounts+============++After the account name, there is usually an amount. (Remember: 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+"quantity"):++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+commodity 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++* Menu:++* Decimal marks::+* Digit group marks::+* Commodity::+* Costs::+++File: hledger.info, Node: Decimal marks, Next: Digit group marks, Up: Amounts++9.11.1 Decimal marks+--------------------++A _decimal mark_ can be written as a period or a comma:++1.23+1,23++ Both of these are common in international number formats, so hledger+is not biased towards one or the other. Because hledger also supports+digit group marks (eg thousands separators), this means that a number+like '1,000' or '1.000' containing just one period or comma is+ambiguous. In such cases, hledger by default assumes it is a decimal+mark, and will parse both of those as 1.++ To help hledger parse such ambiguous numbers more accurately, if you+use digit group marks, we recommend declaring the decimal mark+explicitly. The best way is to add a 'decimal-mark' directive at the+top of each data file, like this:++decimal-mark .++ Or you can declare it per commodity with 'commodity' directives,+described below.++ hledger also accepts numbers like '10.' with no digits after the+decimal mark (and will sometimes display numbers that way to+disambiguate them - see Trailing decimal marks).+++File: hledger.info, Node: Digit group marks, Next: Commodity, Prev: Decimal marks, Up: Amounts++9.11.2 Digit group marks+------------------------++In the integer part of the amount quantity (left of the decimal mark),+groups of digits can optionally be separated by a _digit group mark_ - a+comma or period (whichever is not used as decimal mark), or a space+(several Unicode space variants, like no-break space, are also+accepted). So these are all valid amounts in a journal file:++ $1,000,000.00+ EUR 2.000.000,00+INR 9,99,99,999.00+ 1 000 000.00 ; <- ordinary space + 1 000 000.00 ; <- no-break space+++File: hledger.info, Node: Commodity, Next: Costs, Prev: Digit group marks, Up: Amounts++9.11.3 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+punctuation), 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.++ By default, the format of amounts in the journal influences how+hledger displays them in output. This is explained in Commodity display+style below.+++File: hledger.info, Node: Costs, Prev: Commodity, Up: Amounts++9.11.4 Costs+------------++After a posting amount, you can note its cost (when buying) or selling+price (when selling) in another commodity, by writing either '@+UNITPRICE' or '@@ TOTALPRICE' after it. This indicates a conversion+transaction, where one commodity is exchanged for another.++ (You might also see this called "transaction price" in hledger docs,+discussions, or code; that term was directionally neutral and reminded+that it is a price specific to a transaction, but we now just call it+"cost", with the understanding that the transaction could be a purchase+or a sale.)++ Costs are usually written explicitly with '@' or '@@', but can also+be inferred automatically for simple multi-commodity transactions.+Note, if costs are inferred, the order of postings is significant; the+first posting will have a cost attached, in the commodity of the second.++ As an example, here are several ways to record purchases of a foreign+currency in hledger, using the cost notation either explicitly or+implicitly:++ 1. Write the price per unit, as '@ UNITPRICE' after the amount:++ 2009/1/1+ assets:euros €100 @ $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 €100 @@ $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.+ Note the effect of posting order: the price is added to first+ posting, making it '€100 @@ $135', as in example 2:++ 2009/1/1+ assets:euros €100 ; one hundred euros purchased+ assets:dollars $-135 ; for $135++ Amounts can be converted to cost at report time using the '-B/--cost'+flag; this is discussed more in the Cost reporting section.++ Note that the cost normally should be a positive amount, though it's+not required to be. This can be a little confusing, see discussion at+-infer-market-prices: market prices from transactions.+++File: hledger.info, Node: Balance assertions, Next: Posting comments, Prev: Amounts, Up: Journal++9.12 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 protect 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, described below).++* Menu:++* Assertions and ordering::+* Assertions and multiple included files::+* Assertions and multiple -f files::+* Assertions and costs::+* Assertions and commodities::+* Assertions and subaccounts::+* Assertions and virtual postings::+* Assertions and auto postings::+* Assertions and precision::+++File: hledger.info, Node: Assertions and ordering, Next: Assertions and multiple included files, Up: Balance assertions++9.12.1 Assertions and ordering+------------------------------++hledger calculates and checks an account's balance assertions in date+order (and when there are multiple assertions on the same day, in parse+order). Note this is different from Ledger, which checks assertions+always in parse order, ignoring dates.++ This means in hledger you can freely reorder transactions, postings,+or files, and balance assertions will usually keep working. The+exception is when you reorder multiple postings on the same day, to the+same account, which have balance assertions; those will likely need+updating.+++File: hledger.info, Node: Assertions and multiple included files, Next: Assertions and multiple -f files, Prev: Assertions and ordering, Up: Balance assertions++9.12.2 Assertions and multiple included files+---------------------------------------------++Multiple files included with the 'include' directive are processed as if+concatenated into one file, preserving their order and the posting order+within each file. It means that balance assertions in later files will+see balance from earlier files.++ And if you have multiple postings to an account on the same day,+split across multiple files, and you want to assert the account's+balance on that day, you'll need to put the assertion in the right file+- the last one in the sequence, probably.+++File: hledger.info, Node: Assertions and multiple -f files, Next: Assertions and costs, Prev: Assertions and multiple included files, Up: Balance assertions++9.12.3 Assertions and multiple -f files+---------------------------------------++Unlike 'include', when multiple files are specified on the command line+with multiple '-f/--file' options, balance assertions will not see+balance from earlier files. This can be useful when you do not want+problems in earlier files to disrupt valid assertions in later files.++ If you do want assertions to see balance from earlier files, use+'include', or concatenate the files temporarily.+++File: hledger.info, Node: Assertions and costs, Next: Assertions and commodities, Prev: Assertions and multiple -f files, Up: Balance assertions++9.12.4 Assertions and costs+---------------------------++Balance assertions ignore costs, and should normally be written without+one:++2019/1/1+ (a) $1 @ €1 = $1++ We do allow costs to be written in balance assertion amounts,+however, and print shows them, but 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+costs), and because balance _assignments_ do use costs (see below).+++File: hledger.info, Node: Assertions and commodities, Next: Assertions and subaccounts, Prev: Assertions and costs, Up: Balance assertions++9.12.5 Assertions and commodities+---------------------------------++The balance assertions described so far are "*single commodity balance+assertions*": they assert and check the balance in one commodity,+ignoring any others that may be present. This is how balance assertions+work in Ledger also.++ If an account contains multiple commodities, you can assert their+balances by writing multiple postings with balance assertions, one for+each commodity:++2013/1/1+ usd $-1+ eur €-1+ both++2013/1/2+ both 0 = $1+ both 0 = €1++ In hledger you can make a stronger "*sole commodity balance+assertion*" by writing two equals signs ('== EXPECTEDBALANCE'). This+also asserts that there are no other commodities in the account besides+the asserted one (or at least, that their current balance is zero):++2013/1/1+ usd $-1 == $-1 ; these sole commodity assertions succeed+ eur €-1 == €-1+ both ;== $1 ; this one would fail because 'both' contains $ and €++ It's less easy to make a "*sole commodities balance assertion*" (note+the plural) - ie, asserting that an account contains two or more+specified commodities and no others. It can be done by++ 1. isolating each commodity in a subaccount, and asserting those+ 2. and also asserting there are no commodities in the parent account+ itself:++2013/1/1+ usd $-1+ eur €-1+ both 0 == 0 ; nothing up my sleeve+ both:usd $1 == $1 ; a dollar here+ both:eur €1 == €1 ; a euro there+++File: hledger.info, Node: Assertions and subaccounts, Next: Assertions and virtual postings, Prev: Assertions and commodities, Up: Balance assertions++9.12.6 Assertions and subaccounts+---------------------------------++All of the balance assertions above (both '=' and '==') are+"*subaccount-exclusive balance assertions*"; they ignore any balances+that exist in deeper subaccounts.++ In hledger you can make "*subaccount-inclusive balance assertions*"+by adding a star after the equals ('=*' or '==*'):++2019/1/1+ equity:start+ assets:checking $10+ assets:savings $10+ assets $0 ==* $20 ; assets + subaccounts contains $20 and nothing else+++File: hledger.info, Node: Assertions and virtual postings, Next: Assertions and auto postings, Prev: Assertions and subaccounts, Up: Balance assertions++9.12.7 Assertions and virtual postings+--------------------------------------++Balance assertions always consider both real and virtual postings; they+are not affected by the '--real/-R' flag or 'real:' query.+++File: hledger.info, Node: Assertions and auto postings, Next: Assertions and precision, Prev: Assertions and virtual postings, Up: Balance assertions++9.12.8 Assertions and auto postings+-----------------------------------++Balance assertions _are_ affected by the '--auto' flag, which generates+auto postings, which can alter account balances. Because auto postings+are optional in hledger, accounts affected by them effectively have two+balances. But balance assertions can only test one or the other of+these. So to avoid making fragile assertions, either:++ * assert the balance calculated with '--auto', and always use+ '--auto' with that file+ * or assert the balance calculated without '--auto', and never use+ '--auto' with that file+ * or avoid balance assertions on accounts affected by auto postings+ (or avoid auto postings entirely).+++File: hledger.info, Node: Assertions and precision, Prev: Assertions and auto postings, Up: Balance assertions++9.12.9 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 assertions. Balance+assertion failure messages show exact amounts.+++File: hledger.info, Node: Posting comments, Next: Transaction balancing, Prev: Balance assertions, Up: Journal++9.13 Posting comments+=====================++Text following ';', at the end of a posting line, and/or on indented+lines immediately below it, form comments for that posting. They are+reproduced by 'print' but otherwise ignored, except they may contain+tags, which are not ignored.++2012-01-01+ expenses 1 ; a comment for posting 1+ assets+ ; a comment for posting 2+ ; a second comment line for posting 2+++File: hledger.info, Node: Transaction balancing, Next: Tags, Prev: Posting comments, Up: Journal++9.14 Transaction balancing+==========================++How exactly does hledger decide when a transaction is balanced ? The+general goal is that if you look at the journal entry and calculate the+amounts' sum perfectly with pencil and paper, hledger should agree with+you.++ Real world transactions, especially for investments or+cryptocurrencies, often involve imprecise costs, complex decimals,+and/or infinitely-recurring decimals, which are difficult or+inconvenient to handle on a computer. So to be a practical accounting+system, hledger allows some imprecision when checking transaction+balancedness. The question is, how much imprecision should be allowed ?++ hledger currently decides it based on the commodity display styles:+if the postings' sum would appear to be zero when displayed with the+standard display precisions, the transaction is considered balanced.++ Or equivalently: if the journal entry is displayed with amounts+rounded to the standard display precisions (with 'hledger print+--round=hard'), and a human with pencil and paper would agree that those+displayed amounts add up to zero, the transaction is considered+balanced.++ This has some advantages: it is fairly intuitive, general not+hard-coded, yet configurable when needed. On the downside it means that+transaction balancedness is related to commodity display precisions, so+eg when using '-c/--commodity-style' to display things with more than+usual precision, you might need to fix some of your journal entries (ie,+add decimal digits to make them balance more precisely).++ Other PTA tools (Ledger, Beancount..) have their own ways of doing+it. Possible improvements are discussed at #1964.++ Note: if you have multiple journal files, and are relying on+commodity directives to make imprecise journal entries balance, the+directives' placement might be important - see 'commodity' directive.+++File: hledger.info, Node: Tags, Next: Directives, Prev: Transaction balancing, Up: Journal++9.15 Tags+=========++Tags are a way to add extra labels or data fields to transactions,+postings, or accounts, which you can then search or pivot on.++ A tag is a word, optionally hyphenated, immediately followed by a+full colon, in the comment of a transaction, a posting, or an account+directive. Eg: '2024-01-01 a transaction ; foo:' Note this is an+exception to the usual rule that things in comments are ignored.++ You can write multiple tags on one line, separated by comma. Or you+can write each tag on its own comment line (no comma needed in this+case).++ For example, here are five different tags: one on the+'assets:checking' account, two on the transaction, and two on the+'expenses:food' posting:++account assets:checking ; accounttag:++2017/1/16 bought groceries ; transactiontag-1:+ ; transactiontag-2:+ assets:checking $-1+ expenses:food $1 ; postingtag:, another-posting-tag:++ Postings also inherit tags from their transaction and their account.+And transactions also acquire tags from their postings (and postings'+accounts). So in the example above, the expenses posting effectively+has all five tags (by inheriting from the account and transaction), and+the transaction also has all five tags (by acquiring from the expenses+posting).++* Menu:++* Tag names::+* Special tags::+* Tag values::+++File: hledger.info, Node: Tag names, Next: Special tags, Up: Tags++9.15.1 Tag names+----------------++Most non-whitespace characters are allowed in tag names. Eg '😀:' is a+valid tag.++ You can list the tag names used in your journal with the tags+command:+'hledger tags [NAMEREGEX]'++ In commands which use a query, you can match by tag name. Eg:+'hledger print tag:NAMEREGEX'++ You can declare valid tag names with the tag directive and then check+them with the check command.+++File: hledger.info, Node: Special tags, Next: Tag values, Prev: Tag names, Up: Tags++9.15.2 Special tags+-------------------++Some tag names have special significance to hledger. There's not much+harm in using them yourself, but some could produce an error message,+particularly the 'date:' and 'type:' tags. They are explained+elsewhere, but here is a quick list for reference:++ Tags you can set to influence hledger's behaviour:++ date -- overrides a posting's date+ date2 -- overrides a posting's secondary date+ type -- declares an account's type++ Tags hledger adds to indicate generated data:++ t -- appears on postings generated by timedot letters+ assert -- appears on txns generated by close --assert+ retain -- appears on txns generated by close --retain+ start -- appears on txns generated by close --migrate/--close/--open/--assign+ generated-transaction -- appears on generated periodic txns (with --verbose-tags)+ generated-posting -- appears on generated auto postings (with --verbose-tags)+ modified -- appears on txns which have had auto postings added (with --verbose-tags)+Not displayed, but queryable:+ _generated-transaction -- exists on generated periodic txns (always)+ _generated-posting -- exists on generated auto postings (always)+ _modified -- exists on txns which have had auto postings added (always)++ Tags hledger uses internally:++ _conversion-matched -- exists on postings which have been matched with a nearby @/@@ cost annotation+++File: hledger.info, Node: Tag values, Prev: Special tags, Up: Tags++9.15.3 Tag values+-----------------++Tags can have a value, which is any text after the colon up until a+comma or end of line, with surrounding whitespace removed. Ending at+comma allows us to write multiple tags on one line, but also means that+tag values can not contain commas.++ Eg in the following posting, the three tags' values are "value 1",+"value 2", and "" (empty) respectively:++ expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz++ Multiple tags with the same name are additive rather than overriding:+when the same tag name is seen again with a new value, the new+name:value pair is added to the tags. It is not possible to override a+previous tag's value or remove a tag.++ You can list all the values used for a particular tag in the journal+with+'hledger tags TAGNAME --values'++ You can match on tag values with a query like+'tag:NAMEREGEX=VALUEREGEX'+++File: hledger.info, Node: Directives, Next: account directive, Prev: Tags, Up: Journal++9.16 Directives+===============++Besides transactions, there is something else you can put in a 'journal'+file: directives. These are declarations, beginning with a keyword,+that modify hledger's behaviour. Some directives can have more specific+subdirectives, indented below them. hledger's directives are similar to+Ledger's in many cases, but there are also many differences. Directives+are not required, but can be useful. Here are the main directives:++purpose directive+--------------------------------------------------------------------------+*READING DATA:*+Rewrite account names 'alias'+Comment out sections of the file 'comment'+Declare file's decimal mark, to help 'decimal-mark'+parse amounts accurately+Include other data files 'include'+*GENERATING DATA:*+Generate recurring transactions or '~'+budget goals+Generate extra postings on existing '='+transactions+*CHECKING FOR ERRORS:*+Define valid entities to provide more 'account', 'commodity',+error checking 'payee', 'tag'+*REPORTING:*+Declare accounts' type and display 'account'+order+Declare commodity display styles 'commodity'+Declare market prices 'P'++* Menu:++* Directives and multiple files::+* Directive effects::+++File: hledger.info, Node: Directives and multiple files, Next: Directive effects, Up: Directives++9.16.1 Directives and multiple files+------------------------------------++Directives vary in their scope, ie which journal entries and which input+files they affect. Most often, a directive will affect the following+entries and included files if any, until the end of the current file -+and no further. You might find this inconvenient! For example, 'alias'+directives do not affect parent or sibling files. But there are usually+workarounds; for example, put 'alias' directives in your top-most file,+before including other files.++ The restriction, though it may be annoying at first, is in a good+cause; it allows reports to be stable and deterministic, independent of+the order of input. Without it, reports could show different numbers+depending on the order of -f options, or the positions of include+directives in your files.+++File: hledger.info, Node: Directive effects, Prev: Directives and multiple files, Up: Directives++9.16.2 Directive effects+------------------------++Here are all hledger's directives, with their effects and scope+summarised - nine main directives, plus four others which we consider+non-essential:++directivewhat it does ends+ at+ file+ end?+---------------------------------------------------------------------------+*'account'*Declares an account, for checking all entries in all files; andN+ its display order and type. Subdirectives: any text, ignored.+*'alias'*Rewrites account names, in following entries until end of Y+ current file or 'end aliases'. Command line equivalent:+ '--alias'+*'comment'*Ignores part of the journal file, until end of current file orY+ 'end comment'.+*'commodity'*Declares up to four things: 1. a commodity symbol, for checkingN,N,Y,Y+ all amounts in all files 2. the display style for all amounts+ of this commodity 3. the decimal mark for parsing amounts of+ this commodity, in the rest of this file and its children, if+ there is no 'decimal-mark' directive 4. the precision to use+ for balanced-transaction checking in this commodity, in this+ file and its children. Takes precedence over 'D'.+ Subdirectives: 'format' (ignored). Command line equivalent:+ '-c/--commodity-style'+*'decimal-mark'*Declares the decimal mark, for parsing amounts of all Y+ commodities in following entries until next 'decimal-mark' or+ end of current file. Included files can override. Takes+ precedence over 'commodity' and 'D'.+*'include'*Includes entries and directives from another file, as if theyN+ were written inline. Command line alternative: multiple+ '-f/--file'+*'payee'*Declares a payee name, for checking all entries in all files. N+*'P'*Declares the market price of a commodity on some date, for value N+ reports.+*'~'*Declares a periodic transaction rule that generates future N+(tilde)transactions with '--forecast' and budget goals with 'balance+ --budget'.+Other+syntax:+*'applyPrepends a common parent account to all account names, in Y+account'*following entries until end of current file or 'end apply+ account'.+*'D'*Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N+ there is no 'commodity' directive for this commodity: its+ decimal mark, balancing precision, and display style, as above.+*'Y'*Sets a default year to use for any yearless dates, in following Y+ entries until end of current file.+*'='*Declares an auto posting rule that generates extra postings on partly+(equals)matched transactions with '--auto', in current, parent, and+ child files (but not sibling files, see #1212).+*OtherOther directives from Ledger's file format are accepted but+Ledgerignored.+directives*+++File: hledger.info, Node: account directive, Next: alias directive, Prev: Directives, Up: Journal++9.17 'account' directive+========================++'account' directives can be used to declare accounts (ie, the places+that amounts are transferred from and to). Though not required, these+declarations can provide several benefits:++ * They can document your intended chart of accounts, providing a+ reference.+ * They can store additional account information as comments, or as+ tags which can be used to filter or pivot reports.+ * They can restrict which accounts may be posted to by transactions,+ eg in strict mode, which helps prevent errors.+ * They influence account display order in reports, allowing+ non-alphabetic sorting (eg Revenues to appear above Expenses).+ * They can help hledger know your accounts' types (asset, liability,+ equity, revenue, expense), enabling reports like balancesheet and+ incomestatement.+ * They help with account name completion (in hledger add,+ hledger-web, hledger-iadd, ledger-mode, etc.)++ They are written as the word 'account' followed by a hledger-style+account name. Eg:++account assets:bank:checking++ Ledger-style indented subdirectives are also accepted, but ignored:++account assets:bank:checking+ format subdirective ; currently ignored++* Menu:++* Account comments::+* Account error checking::+* Account display order::+* Account types::+++File: hledger.info, Node: Account comments, Next: Account error checking, Up: account directive++9.17.1 Account comments+-----------------------++Text following *two or more spaces* and ';' at the end of an account+directive line, and/or following ';' on indented lines immediately below+it, form comments for that account. They are ignored except they may+contain tags, which are not ignored.++ The two-space requirement for same-line account comments is because+';' is allowed in account names.++account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon+ ; next-line comment+ ; some tags - type:A, acctnum:12345+++File: hledger.info, Node: Account error checking, Next: Account display order, Prev: Account comments, Up: account directive++9.17.2 Account error checking+-----------------------------++By default, accounts need not be declared; they come into existence when+a posting references them. This is convenient, but it means hledger+can't warn you when you mis-spell an account name in the journal.+Usually you'll find that error later, as an extra account in balance+reports, or an incorrect 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:++ * The declaration is case-sensitive; transactions must use the+ correct account name capitalisation.+ * The account directive's scope is "whole file and below" (see+ directives). This means it affects all of the current file, and+ any files it includes, but not parent or sibling files. The+ position of account directives within the file does not matter,+ though it's usual to put them at the top.+ * Accounts can only be declared in 'journal' files, but will affect+ included files of all types.+ * It's currently not possible to declare "all possible subaccounts"+ with a wildcard; every account posted to must be declared.+++File: hledger.info, Node: Account display order, Next: Account types, Prev: Account error checking, Up: account directive++9.17.3 Account display order+----------------------------++Account directives also cause hledger to display accounts in a+particular order, not just alphabetically. Eg, here is a conventional+ordering for the top-level accounts:++account assets+account liabilities+account equity+account revenues+account expenses++ Now hledger displays them in that order:++$ hledger accounts+assets+liabilities+equity+revenues+expenses++ If there are undeclared accounts, those will be displayed last, in+alphabetical order.++ Sorting is done within each group of sibling accounts, at each level+of the account tree. Eg, a declaration like 'account parent:child'+influences 'child''s position among its siblings.++ Note, it does not affect 'parent''s position; for that, you need an+'account parent' declaration.++ Sibling accounts are always displayed together; hledger won't display+'x:y' in between 'a:b' and 'a:c'.++ An account directive both declares an account as a valid posting+target, and declares its display order; you can't easily do one without+the other.+++File: hledger.info, Node: Account types, Prev: Account display order, Up: account directive++9.17.4 Account types+--------------------++hledger knows that accounts come in several types: assets, liabilities,+expenses and so on. This enables easy reports like balancesheet and+incomestatement, and filtering by account type with the 'type:' query.++ As a convenience, hledger will detect these account types+automatically if you are using common english-language top-level account+names (described below). But it's more robust to declare accounts'+types explicitly, by adding 'type:' tags to their account directives.+The tag's value should be one of the five main account types:++ * 'A' or 'Asset' (things you own)+ * 'L' or 'Liability' (things you owe)+ * 'E' or 'Equity' (investment/ownership; balanced counterpart of+ assets & liabilities)+ * 'R' or 'Revenue' (what you received money from, AKA income;+ technically part of Equity)+ * 'X' or 'Expense' (what you spend money on; technically part of+ Equity)++ or, it can be (these are used less often):++ * 'C' or 'Cash' (a subtype of Asset, indicating liquid assets for the+ cashflow report)+ * 'V' or 'Conversion' (a subtype of Equity, for conversions (see Cost+ reporting).)++ Subaccounts inherit their parent's type, or they can override it.+Here is a typical set of account type declarations:++account assets ; type: A+account liabilities ; type: L+account equity ; type: E+account revenues ; type: R+account expenses ; type: X++account assets:bank ; type: C+account assets:cash ; type: C++account equity:conversion ; type: V++ Here are some tips for working with account types.++ * The rules for inferring types from account names are as follows.+ These are just a convenience that sometimes help new users get+ going; if they don't work for you, just ignore them and declare+ your account types. See also Regular expressions.++ If account's name contains this (CI) regular expression: | its type is:+ --------------------------------------------------------------------|-------------+ ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash+ ^assets?(:|$) | Asset+ ^(debts?|liabilit(y|ies))(:|$) | Liability+ ^equity:(trad(e|ing)|conversion)s?(:|$) | Conversion+ ^equity(:|$) | Equity+ ^(income|revenue)s?(:|$) | Revenue+ ^expenses?(:|$) | Expense++ * If you declare any account types, it's a good idea to declare an+ account for all of the account types, because a mixture of declared+ and name-inferred types can disrupt certain reports.++ * Certain uses of account aliases can disrupt account types. See+ Rewriting accounts > Aliases and account types.++ * As mentioned above, subaccounts will inherit a type from their+ parent account. More precisely, an account's type is decided by+ the first of these that exists:++ 1. A 'type:' declaration for this account.+ 2. A 'type:' declaration in the parent accounts above it,+ preferring the nearest.+ 3. An account type inferred from this account's name.+ 4. An account type inferred from a parent account's name,+ preferring the nearest parent.+ 5. Otherwise, it will have no type.++ * For troubleshooting, you can list accounts and their types with:++ $ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]+++File: hledger.info, Node: alias directive, Next: commodity directive, Prev: account directive, Up: Journal++9.18 'alias' directive+======================++You can define account alias rules which rewrite your account names, or+parts of them, before generating reports. This can be useful for:++ * expanding shorthand account names to their full form, allowing+ easier data entry and a less verbose journal+ * adapting old journals to your current chart of accounts+ * experimenting with new account organisations, like a new hierarchy+ * combining two accounts into one, eg to see their sum or difference+ on one line+ * 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.++ Account aliases are very powerful. They are generally easy to use+correctly, but you can also generate invalid account names with them;+more on this below.++ See also Rewrite account names.++* Menu:++* Basic aliases::+* Regex aliases::+* Combining aliases::+* Aliases and multiple files::+* end aliases directive::+* Aliases can generate bad account names::+* Aliases and account types::+++File: hledger.info, Node: Basic aliases, Next: Regex aliases, Up: alias directive++9.18.1 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.+Subaccounts 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"+++File: hledger.info, Node: Regex aliases, Next: Combining aliases, Prev: Basic aliases, Up: alias directive++9.18.2 Regex aliases+--------------------++There is also a more powerful variant that uses a regular expression,+indicated by wrapping the pattern in forward slashes. (This is the only+place where hledger requires forward slashes around a regular+expression.)++ Eg:++alias /REGEX/ = REPLACEMENT++ or:++$ hledger --alias '/REGEX/=REPLACEMENT' ...++ Any part of an account name matched by REGEX will be replaced by+REPLACEMENT. REGEX is case-insensitive as usual.++ If you need to match a forward slash, escape it with a backslash, eg+'/\/=:'.++ If REGEX contains parenthesised match groups, these can be referenced+by the usual backslash and number in REPLACEMENT:++alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3+; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"++ REPLACEMENT continues to the end of line (or on command line, to end+of option argument), so it can contain trailing whitespace.+++File: hledger.info, Node: Combining aliases, Next: Aliases and multiple files, Prev: Regex aliases, Up: alias directive++9.18.3 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:++ * the nearest alias declaration before/above the entry is applied+ first+ * the next alias before/above that will be be applied next, and so on+ * aliases defined after/below the entry do not affect it.++ This gives nearby aliases precedence over distant ones, and helps+provide semantic stability - aliases will keep working the same way+independent of which files are being read and in which order.++ In case of trouble, adding '--debug=6' to the command line will show+which aliases are being applied when.+++File: hledger.info, Node: Aliases and multiple files, Next: end aliases directive, Prev: Combining aliases, Up: alias directive++9.18.4 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++2023-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++2023-01-01 ; affected by aliases above+ foo 1+ bar++include c.journal ; also affected+++File: hledger.info, Node: end aliases directive, Next: Aliases can generate bad account names, Prev: Aliases and multiple files, Up: alias directive++9.18.5 'end aliases' directive+------------------------------++You can clear (forget) all currently defined aliases (seen in the+journal so far, or defined on the command line) with this directive:++end aliases+++File: hledger.info, Node: Aliases can generate bad account names, Next: Aliases and account types, Prev: end aliases directive, Up: alias directive++9.18.6 Aliases can generate bad account names+---------------------------------------------++Be aware that account aliases can produce malformed account names, which+could cause confusing reports or invalid 'print' output. For example,+you could erase all account names:++2021-01-01+ a:aa 1+ b++$ hledger print --alias '/.*/='+2021-01-01+ 1++ The above 'print' output is not a valid journal. Or you could insert+an illegal double space, causing 'print' output that would give a+different journal when reparsed:++2021-01-01+ old 1+ other++$ hledger print --alias old="new USD" | hledger -f- print+2021-01-01+ new USD 1+ other+++File: hledger.info, Node: Aliases and account types, Prev: Aliases can generate bad account names, Up: alias directive++9.18.7 Aliases and account types+--------------------------------++If an account with a type declaration (see Declaring accounts > Account+types) is renamed by an alias, normally the account type remains in+effect.++ However, renaming in a way that reshapes the account tree (eg+renaming parent accounts but not their children, or vice versa) could+prevent child accounts from inheriting the account type of their+parents.++ Secondly, if an account's type is being inferred from its name,+renaming it by an alias could prevent or alter that.++ If you are using account aliases and the 'type:' query is not+matching accounts as you expect, try troubleshooting with the accounts+command, eg something like:++$ hledger accounts --alias assets=bassetts type:a+++File: hledger.info, Node: commodity directive, Next: decimal-mark directive, Prev: alias directive, Up: Journal++9.19 'commodity' directive+==========================++The 'commodity' directive performs several functions:++ 1. It declares which commodity symbols may be used in the journal,+ enabling useful error checking with strict mode or the check+ command. See Commodity error checking below.++ 2. It declares how all amounts in this commodity should be displayed,+ eg how many decimals to show. See Commodity display style above.++ 3. (If no 'decimal-mark' directive is in effect:) It sets the decimal+ mark to expect (period or comma) when parsing amounts in this+ commodity, in this file and files it includes, from the directive+ until end of current file. See Decimal marks above.++ 4. It declares the precision with which this commodity's amounts+ should be compared when checking for balanced transactions,+ anywhere in this file and files it includes, until end of current+ file.++ Declaring commodities solves several common parsing/display problems,+so we recommend it.++ Note that effects 3 and 4 above end at the end of the directive's+file, and will not affect sibling or parent files. So if you are+relying on them (especially 4) and using multiple files, placing your+commodity directives in a top-level parent file might be important. Or,+keep your decimal marks unambiguous and your entries well balanced and+precise.++ (Related: #793)++* Menu:++* Commodity directive syntax::+* Commodity error checking::+++File: hledger.info, Node: Commodity directive syntax, Next: Commodity error checking, Up: commodity directive++9.19.1 Commodity directive syntax+---------------------------------++A commodity directive is normally the word 'commodity' followed by a+sample amount (and optionally a comment). Only the amount's symbol and+format is significant. Eg:++commodity $1000.00+commodity 1.000,00 EUR+commodity 1 000 000.0000 ; the no-symbol commodity++ Commodities do not have tags (tags in the comment will be ignored).++ A commodity directive's sample amount must always include a period or+comma decimal mark (this rule helps disambiguate decimal marks and digit+group marks). If you don't want to show any decimal digits, write the+decimal mark at the end:++commodity 1000. AAAA ; show AAAA with no decimals++ Commodity symbols containing spaces, numbers, or punctuation must be+enclosed in double quotes, as usual:++commodity 1.0000 "AAAA 2023"++ Commodity directives normally include a sample amount, but can+declare only a symbol (ie, just function 1 above):++commodity $+commodity INR+commodity "AAAA 2023"+commodity "" ; the no-symbol commodity++ Commodity directives may also be written with an indented 'format'+subdirective, as in Ledger. The symbol is repeated and must be the same+in both places. Other subdirectives are currently ignored:++; 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+ an unsupported subdirective ; ignored by hledger+++File: hledger.info, Node: Commodity error checking, Prev: Commodity directive syntax, Up: commodity directive++9.19.2 Commodity error checking+-------------------------------++In strict mode ('-s'/'--strict') (or when you run 'hledger check+commodities'), hledger will report an error if an undeclared commodity+symbol is used. (With one exception: zero amounts are always allowed to+have no commodity symbol.) It works like account error checking+(described above).+++File: hledger.info, Node: decimal-mark directive, Next: include directive, Prev: commodity directive, Up: Journal++9.20 'decimal-mark' directive+=============================++You can use a 'decimal-mark' directive - usually one per file, at the+top of the file - to declare which character represents a decimal mark+when parsing amounts in this file. It can look like++decimal-mark .++ or++decimal-mark ,++ This prevents any ambiguity when parsing numbers in the file, so we+recommend it, especially if the file contains digit group marks (eg+thousands separators).+++File: hledger.info, Node: include directive, Next: P directive, Prev: decimal-mark directive, Up: Journal++9.21 'include' directive+========================++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,+overriding the file extension (as described in Data formats): 'include+timedot:~/notes/2023*.md'.+++File: hledger.info, Node: P directive, Next: payee directive, Prev: include directive, Up: Journal++9.22 'P' directive+==================++The 'P' directive declares a market price, which is a conversion rate+between two commodities on a certain date. This allows value reports to+convert amounts of one commodity to their value in another, on or after+that date. These prices are often obtained from a stock exchange,+cryptocurrency exchange, the or foreign exchange market.++ 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 € $1.35++# and $1.40 from 2010-01-01 onward:+P 2010-01-01 € $1.40++ The '-V', '-X' and '--value' flags use these market prices to show+amount values in another commodity. See Value reporting.+++File: hledger.info, Node: payee directive, Next: tag directive, Prev: P directive, Up: Journal++9.23 'payee' directive+======================++'payee PAYEE NAME'++ This 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 ; a comment++ Payees do not have tags (tags in the comment will be ignored).++ To declare the empty payee name, use '""'.++payee ""++ Ledger-style indented subdirectives, if any, are currently ignored.+++File: hledger.info, Node: tag directive, Next: Periodic transactions, Prev: payee directive, Up: Journal++9.24 'tag' directive+====================++'tag TAGNAME'++ This directive can be used to declare a limited set of tag names+allowed in tags. TAGNAME should be a valid tag name (no spaces). Eg:++tag item-id++ Any indented subdirectives are currently ignored.++ The "tags" check will report an error if any undeclared tag name is+used. It is quite easy to accidentally create a tag through normal use+of colons in comments; if you want to prevent this, you can declare and+check your tags .+++File: hledger.info, Node: Periodic transactions, Next: Auto postings, Prev: tag directive, Up: Journal++9.25 Periodic transactions+==========================++The '~' directive declares a "periodic rule" which generates temporary+extra transactions, usually recurring at some interval, when hledger is+run with the '--forecast' flag. These "forecast transactions" are+useful for forecasting future activity. They exist only for the+duration of the report, and only when '--forecast' is used; they are not+saved in the journal file by hledger.++ Periodic rules also have a second use: with the '--budget' flag they+set budget goals for budgeting.++ Periodic rules can be a little tricky, so before you use them, read+this whole section, or at least the following 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-forecasted 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 2023/01', which is equivalent to '~ every 10th+ day of month from 2023/01/01', will be adjusted to start on+ 2019/12/10.++* Menu:++* Periodic rule syntax::+* Periodic rules and relative dates::+* Two spaces between period expression and description!::+++File: hledger.info, Node: Periodic rule syntax, Next: Periodic rules and relative dates, Up: Periodic transactions++9.25.1 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.):++# every first of month+~ monthly+ expenses:rent $2000+ assets:bank:checking++# every 15th of month in 2023's first quarter:+~ monthly from 2023-04-15 to 2023-06-16+ expenses:utilities $400+ assets:bank:checking++ The period expression is the same syntax used for specifying+multi-period reports, just interpreted differently; there, it specifies+report periods; here it specifies recurrence dates (the periods' start+dates).+++File: hledger.info, Node: Periodic rules and relative dates, Next: Two spaces between period expression and description!, Prev: Periodic rule syntax, Up: Periodic transactions++9.25.2 Periodic rules and relative dates+----------------------------------------++Partial or relative dates (like '12/31', '25', 'tomorrow', 'last week',+'next quarter') are usually not recommended in periodic rules, since the+results will change as time passes. If used, they will be interpreted+relative to, in order of preference:++ 1. the first day of the default year specified by a recent 'Y'+ directive+ 2. or the date specified with '--today'+ 3. or the date on which you are running the report.++ They will not be affected at all by report period or forecast period+dates.+++File: hledger.info, Node: Two spaces between period expression and description!, Prev: Periodic rules and relative dates, Up: Periodic transactions++9.25.3 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+accidentally alter their meaning, as in this example:++; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2023"+; ||+; vv+~ every 2 months in 2023, we will review+ assets:bank:checking $1500+ income:acme inc++ So,++ * Do write two spaces between your period expression and your+ transaction description, if any.+ * Don't accidentally write two spaces in the middle of your period+ expression.+++File: hledger.info, Node: Auto postings, Next: Other syntax, Prev: Periodic transactions, Up: Journal++9.26 Auto postings+==================++The '=' directive declares an "auto posting rule", which adds extra+postings to existing transactions. (Remember, postings are the account+name & amount lines below a transaction's date & description.)++ In the journal, an auto posting rule looks quite like a transaction,+but instead of date and description it has '=' (mnemonic: "match") and a+query, like this:++= QUERY+ ACCOUNT AMOUNT+ ...++ Queries are just like command line queries; an account name substring+is most common. Query terms containing spaces should be enclosed in+single or double quotes.++ Each '=' rule works like this: when hledger is run with the '--auto'+flag, wherever the QUERY matches a posting in the journal, the rule's+postings are added to that transaction, immediately below the matched+posting. Note these generated postings are temporary, existing only for+the duration of the report, and only when '--auto' is used; they are not+saved in the journal file by hledger.++ Generated postings' amounts can depend on the matched posting's+amount. So auto postings can be useful for, eg, adding tax postings+with a standard percentage. AMOUNT can be:++ * a number with no commodity symbol, like '2'. The matched posting's+ commodity symbol will be added to this.++ * a normal amount with a commodity symbol, like '$2'. This will be+ used as-is.++ * an asterisk followed by a number, like '*2'. This will multiply+ the matched posting's amount (and total price, if any) by the+ number.++ * an asterisk followed by an amount with commodity symbol, like+ '*$2'. This multiplies and also replaces the commodity symbol with+ this new one.++ 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++ Note that depending fully on generated data such as this has some+drawbacks - it's less portable, less future-proof, less auditable by+others, and less robust (eg your balance assertions will depend on+whether you use or don't use '--auto'). An alternative is to use auto+postings in "one time" fashion - use them to help build a complex+journal entry, view it with 'hledger print --auto', and then copy that+output into the journal file to make it permanent.++* Menu:++* Auto postings and multiple files::+++File: hledger.info, Node: Auto postings and multiple files, Up: Auto postings++9.26.1 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).++* Menu:++* Auto postings and dates::+* Auto postings and transaction balancing / inferred amounts / balance assertions::+* Auto posting tags::+* Auto postings on forecast transactions only::+++File: hledger.info, Node: Auto postings and dates, Next: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings and multiple files++9.26.1.1 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.+++File: hledger.info, Node: Auto postings and transaction balancing / inferred amounts / balance assertions, Next: Auto posting tags, Prev: Auto postings and dates, Up: Auto postings and multiple files++9.26.1.2 Auto postings and transaction balancing / inferred+...........................................................++amounts / balance assertions Currently, auto postings are added:++ * after missing amounts are inferred, and transactions are checked+ for balancedness,+ * 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.++ This also means that you cannot have more than one auto-posting with+a missing amount applied to a given transaction, as it will be unable to+infer amounts.+++File: hledger.info, Node: Auto posting tags, Next: Auto postings on forecast transactions only, Prev: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings and multiple files++9.26.1.3 Auto posting tags+..........................++Automated postings will have some extra tags:++ * 'generated-posting:= QUERY' - shows this was generated by an auto+ posting rule, and the query+ * '_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:++ * 'modified:' - this transaction was modified+ * '_modified:' - a hidden tag not appearing in the comment; this+ transaction was modified "just now".+++File: hledger.info, Node: Auto postings on forecast transactions only, Prev: Auto posting tags, Up: Auto postings and multiple files++9.26.1.4 Auto postings on forecast transactions only+....................................................++Tip: you can can make auto postings that will apply to forecast+transactions but not recorded transactions, by adding+'tag:_generated-transaction' to their QUERY. This can be useful when+generating new journal entries to be saved in the journal.+++File: hledger.info, Node: Other syntax, Prev: Auto postings, Up: Journal++9.27 Other syntax+=================++hledger journal format supports quite a few other features, mainly to+make interoperating with or converting from Ledger easier. Note some of+the features below are powerful and can be useful in special cases, but+in general, features in this section are considered less important or+even not recommended for most users. Downsides are mentioned to help+you decide if you want to use them.++* Menu:++* Balance assignments::+* Bracketed posting dates::+* D directive::+* apply account directive::+* Y directive::+* Secondary dates::+* Star comments::+* Valuation expressions::+* Virtual postings::+* Other Ledger directives::+* Other cost/lot notations::+++File: hledger.info, Node: Balance assignments, Next: Bracketed posting dates, Up: Other syntax++9.27.1 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+assignment).++ Downsides: using balance assignments makes your journal less+explicit; to know the exact amount posted, you have to run hledger or do+the calculations yourself, instead of just reading it. Also balance+assignments' forcing of balances can hide errors. These things make+your financial data less portable, less future-proof, and less+trustworthy in an audit.++* Menu:++* Balance assignments and costs::+* Balance assignments and multiple files::+++File: hledger.info, Node: Balance assignments and costs, Next: Balance assignments and multiple files, Up: Balance assignments++9.27.1.1 Balance assignments and costs+......................................++A cost in a balance assignment will cause the calculated amount to have+that cost attached:++2019/1/1+ (a) = $1 @ €2++$ hledger print --explicit+2019-01-01+ (a) $1 @ €2 = $1 @ €2+++File: hledger.info, Node: Balance assignments and multiple files, Prev: Balance assignments and costs, Up: Balance assignments++9.27.1.2 Balance assignments and multiple files+...............................................++Balance assignments handle multiple files like balance assertions. They+see balance from other files previously included from the current file,+but not from previous sibling or parent files.+++File: hledger.info, Node: Bracketed posting dates, Next: D directive, Prev: Balance assignments, Up: Other syntax++9.27.2 Bracketed posting dates+------------------------------++For setting posting dates and secondary posting dates, Ledger's+bracketed date syntax is also supported: '[DATE]', '[DATE=DATE2]' or+'[=DATE2]' in posting comments. hledger will attempt to parse any+square-bracketed sequence of the '0123456789/-.=' characters in this+way. With this syntax, DATE infers its year from the transaction and+DATE2 infers its year from DATE.++ Downsides: another syntax to learn, redundant with hledger's+'date:'/'date2:' tags, and confusingly similar to Ledger's lot date+syntax.+++File: hledger.info, Node: D directive, Next: apply account directive, Prev: Bracketed posting dates, Up: Other syntax++9.27.3 'D' directive+--------------------++'D AMOUNT'++ This directive sets a default commodity, to be used for any+subsequent commodityless amounts (ie, plain numbers) seen while parsing+the journal. This effect lasts until the next 'D' directive, or the end+of the current file.++ For compatibility/historical reasons, 'D' also acts like a+'commodity' directive (setting the commodity's decimal mark for parsing+and display style for output). So its argument is not just a commodity+symbol, but a full amount demonstrating the style. The amount must+include a decimal mark (either period or comma). Eg:++; 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++ Interactions with other directives:++ For setting a commodity's display style, a 'commodity' directive has+highest priority, then a 'D' directive.++ For detecting a commodity's decimal mark during parsing,+'decimal-mark' has highest priority, then 'commodity', then 'D'.++ For checking commodity symbols with the check command, a 'commodity'+directive is required ('hledger check commodities' ignores 'D'+directives).++ Downsides: omitting commodity symbols makes your financial data less+explicit, less portable, and less trustworthy in an audit. It is+usually an unsustainable shortcut; sooner or later you will want to+track multiple commodities. D is overloaded with functions redundant+with 'commodity' and 'decimal-mark'. And it works differently from+Ledger's 'D'.+++File: hledger.info, Node: apply account directive, Next: Y directive, Prev: D directive, Up: Other syntax++9.27.4 'apply account' directive+--------------------------------++This directive sets a default parent account, which will be prepended to+all accounts in following entries, until an 'end apply account'+directive or end of current file. Eg:++apply account home++2010/1/1+ food $10+ cash++end apply account++ is equivalent to:++2010/01/01+ home:food $10+ home:cash $-10++ 'account' directives are also affected, and so is any 'include'd+content.++ Account names entered via hledger add or hledger-web are not+affected.++ Account aliases, if any, are applied after the parent account is+prepended.++ Downsides: this can make your financial data less explicit, less+portable, and less trustworthy in an audit.+++File: hledger.info, Node: Y directive, Next: Secondary dates, Prev: apply account directive, Up: Other syntax++9.27.5 'Y' directive+--------------------++'Y YEAR'++ or (deprecated backward-compatible forms):++ 'year YEAR' 'apply year YEAR'++ The space is optional. This sets a default year to be used for+subsequent dates which don't specify a year. Eg:++Y2009 ; set default year to 2009++12/15 ; equivalent to 2009/12/15+ expenses 1+ assets++year 2010 ; change default year to 2010++2009/1/30 ; specifies the year, not affected+ expenses 1+ assets++1/31 ; equivalent to 2010/1/31+ expenses 1+ assets++ Downsides: omitting the year (from primary transaction dates, at+least) makes your financial data less explicit, less portable, and less+trustworthy in an audit. Such dates can get separated from their+corresponding Y directive, eg when evaluating a region of the journal in+your editor. A missing Y directive makes reports dependent on today's+date.+++File: hledger.info, Node: Secondary dates, Next: Star comments, Prev: Y directive, Up: Other syntax++9.27.6 Secondary dates+----------------------++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".++ Downsides: makes your financial data more complicated, less portable,+and less trustworthy in an audit. Keeping the meaning of the two dates+consistent requires discipline, and you have to remember which reporting+mode is appropriate for a given report. Posting dates are simpler and+better.+++File: hledger.info, Node: Star comments, Next: Valuation expressions, Prev: Secondary dates, Up: Other syntax++9.27.7 Star comments+--------------------++Lines beginning with '*' (star/asterisk) are also comment lines. This+feature allows Emacs users to insert org headings in their journal,+allowing them to fold/unfold/navigate it like an outline when viewed+with org mode.++ Downsides: another, unconventional comment syntax to learn.+Decreases your journal's portability. And switching to Emacs org mode+just for folding/unfolding meant losing the benefits of ledger mode;+nowadays you can add outshine mode to ledger mode to get folding without+losing ledger mode's features.+++File: hledger.info, Node: Valuation expressions, Next: Virtual postings, Prev: Star comments, Up: Other syntax++9.27.8 Valuation expressions+----------------------------++Ledger allows a valuation function or value to be written in double+parentheses after an amount. hledger ignores these.+++File: hledger.info, Node: Virtual postings, Next: Other Ledger directives, Prev: Valuation expressions, Up: Other syntax++9.27.9 Virtual postings+-----------------------++A posting with parentheses around the account name, like '(some:account)+10', is called an _unbalanced virtual posting_. These postings do not+participate in transaction balancing. (And if you write them without an+amount, a zero amount is always inferred.) These can occasionally be+convenient for special circumstances, but they violate double entry+bookkeeping and make your data less portable across applications, so+many people avoid using them at all.++ A posting with brackets around the account name ('[some:account]') is+called a _balanced virtual posting_. The balanced virtual postings in a+transaction must add up to zero, just like ordinary postings, but+separately from them. These are not part of double entry bookkeeping+either, but they are at least balanced. An example:++2022-01-01 buy food with cash, update budget envelope subaccounts, & something else+ assets:cash $-10 ; <- these balance each other+ expenses:food $7 ; <-+ expenses:food $3 ; <-+ [assets:checking:budget:food] $-10 ; <- and these balance each other+ [assets:checking:available] $10 ; <-+ (something:else) $5 ; <- this is not required to balance++ Ordinary postings, whose account names are neither parenthesised nor+bracketed, are called _real postings_. You can exclude virtual postings+from reports with the '-R/--real' flag or a 'real:1' query.+++File: hledger.info, Node: Other Ledger directives, Next: Other cost/lot notations, Prev: Virtual postings, Up: Other syntax++9.27.10 Other Ledger directives+-------------------------------++These other Ledger directives are currently accepted but ignored. This+allows hledger to read more Ledger files, but be aware that hledger's+reports may differ from Ledger's if you use these.++apply fixed COMM AMT+apply tag TAG+assert EXPR+bucket / A ACCT+capture ACCT REGEX+check EXPR+define VAR=EXPR+end apply fixed+end apply tag+end apply year+end tag+eval / expr EXPR+python+ PYTHONCODE+tag NAME+value EXPR+--command-line-flags++ See also https://hledger.org/ledger.html for a detailed+hledger/Ledger syntax comparison.+++File: hledger.info, Node: Other cost/lot notations, Prev: Other Ledger directives, Up: Other syntax++9.27.11 Other cost/lot notations+--------------------------------++A slight digression for Ledger and Beancount users. Ledger has a number+of cost/lot-related notations:++ * '@ UNITCOST' and '@@ TOTALCOST'+ * expresses a conversion rate, as in hledger+ * when buying, also creates a lot than can be selected at+ selling time++ * '(@) UNITCOST' and '(@@) TOTALCOST' (virtual cost)+ * like the above, but also means "this cost was exceptional,+ don't use it when inferring market prices".++ Currently, hledger treats the above like '@' and '@@'; the+parentheses are ignored.++ * '{=FIXEDUNITCOST}' and '{{=FIXEDTOTALCOST}}' (fixed price)+ * when buying, means "this cost is also the fixed price, don't+ let it fluctuate in value reports"++ * '{UNITCOST}' and '{{TOTALCOST}}' (lot price)+ * can be used identically to '@ UNITCOST' and '@@ TOTALCOST',+ also creates a lot+ * when selling, combined with '@ ...', specifies an investment+ lot by its cost basis; does not check if that lot is present++ * and related: '[YYYY/MM/DD]' (lot date)+ * when buying, attaches this acquisition date to the lot+ * when selling, selects a lot by its acquisition date++ * '(SOME TEXT)' (lot note)+ * when buying, attaches this note to the lot+ * when selling, selects a lot by its note++ Currently, hledger accepts any or all of the above in any order after+the posting amount, but ignores them. (This can break transaction+balancing.)++ For Beancount users, the notation and behaviour is different:++ * '@ UNITCOST' and '@@ TOTALCOST'+ * expresses a cost without creating a lot, as in hledger+ * when buying (augmenting) or selling (reducing) a lot, combined+ with '{...}': documents the cost/selling price (not used for+ transaction balancing)++ * '{UNITCOST}' and '{{TOTALCOST}}'+ * when buying (augmenting), expresses the cost for transaction+ balancing, and also creates a lot with this cost basis+ attached+ * when selling (reducing),+ * selects a lot by its cost basis+ * raises an error if that lot is not present or can not be+ selected unambiguously (depending on booking method+ configured)+ * expresses the selling price for transaction balancing++ Currently, hledger accepts the '{UNITCOST}'/'{{TOTALCOST}}' notation+but ignores it.++ * variations: '{}', '{YYYY-MM-DD}', '{"LABEL"}', '{UNITCOST,+ "LABEL"}', '{UNITCOST, YYYY-MM-DD, "LABEL"}' etc.++ Currently, hledger rejects these.+++File: hledger.info, Node: CSV, Next: Timeclock, Prev: Journal, Up: Top++10 CSV+******++hledger can read CSV files (Character Separated Value - usually comma,+semicolon, or tab) containing dated records, automatically converting+each record into a transaction.++ (To learn about _writing_ CSV, see CSV output.)++ For best error messages when reading CSV/TSV/SSV files, make sure+they have a corresponding '.csv', '.tsv' or '.ssv' file extension or use+a hledger file prefix (see File Extension below).++ Each CSV file must be described by a corresponding _rules file_.+This contains rules describing the CSV data (header line, fields layout,+date format etc.), how to construct hledger transactions from it, and+how to categorise transactions based on description or other attributes.++ By default, hledger expects this rules file to be named like the CSV+file, with an extra '.rules' extension added, in the same directory. Eg+when asked to read 'foo/FILE.csv', hledger looks for+'foo/FILE.csv.rules'. You can specify a different rules file with the+'--rules-file' option.++ 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++ There's an introductory Importing CSV data tutorial on hledger.org,+and more CSV rules examples below, and a larger collection at+https://github.com/simonmichael/hledger/tree/master/examples/csv.++* Menu:++* CSV rules cheatsheet::+* source::+* separator::+* skip::+* date-format::+* timezone::+* newest-first::+* intra-day-reversed::+* decimal-mark::+* fields list::+* Field assignment::+* Field names::+* if block::+* Matchers::+* if table::+* balance-type::+* include::+* Working with CSV::+* CSV rules examples::+++File: hledger.info, Node: CSV rules cheatsheet, Next: source, Up: CSV++10.1 CSV rules cheatsheet+=========================++The following kinds of rule can appear in the rules file, in any order.+(Blank lines and lines beginning with '#' or ';' or '*' are ignored.)++*'source'* optionally declare which file to read data+ from+*'separator'* declare the field separator, instead of+ relying on file extension+*'skip'* skip one or more header lines at start of file+*'date-format'* declare how to parse CSV dates/date-times+*'timezone'* declare the time zone of ambiguous CSV+ date-times+*'newest-first'* improve txn order when: there are multiple+ records, newest first, all with the same date+*'intra-day-reversed'* improve txn order when: same-day txns are in+ opposite order to the overall file+*'decimal-mark'* declare the decimal mark used in CSV amounts,+ when ambiguous+*'fields' list* name CSV fields for easy reference, and+ optionally assign their values to hledger+ fields+*Field assignment* assign a CSV value or interpolated text value+ to a hledger field+*'if' block* conditionally assign values to hledger fields,+ or 'skip' a record or 'end' (skip rest of+ file)+*'if' table* conditionally assign values to hledger fields,+ using compact syntax+*'balance-type'* select which type of balance+ assertions/assignments to generate+*'include'* inline another CSV rules file++ Working with CSV tips can be found below, including How CSV rules are+evaluated.+++File: hledger.info, Node: source, Next: separator, Prev: CSV rules cheatsheet, Up: CSV++10.2 'source'+=============++If you tell hledger to read a csv file with '-f foo.csv', it will look+for rules in 'foo.csv.rules'. Or, you can tell it to read the rules+file, with '-f foo.csv.rules', and it will look for data in 'foo.csv'+(since 1.30).++ These are mostly equivalent, but the second method provides some+extra features. For one, the data file can be missing, without causing+an error; it is just considered empty. And, you can specify a different+data file by adding a "source" rule:++source ./Checking1.csv++ If you specify just a file name with no path, hledger will look for+it in your system's downloads directory ('~/Downloads', currently):++source Checking1.csv++ And if you specify a glob pattern, hledger will read the most recent+of the matched files (useful with repeated downloads):++source Checking1*.csv++ See also "Working with CSV > Reading files specified by rule".+++File: hledger.info, Node: separator, Next: skip, Prev: source, Up: CSV++10.3 'separator'+================++You can use the 'separator' rule to read other kinds of+character-separated 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 automatically, and you won't need this rule.+++File: hledger.info, Node: skip, Next: date-format, Prev: separator, Up: CSV++10.4 'skip'+===========++skip N++ The word 'skip' followed by a number (or no number, meaning 1) tells+hledger to ignore this many non-empty lines at the start of the input+data. You'll need this whenever your CSV data contains header lines.+Note, empty and blank lines are skipped automatically, so you don't need+to count those.++ 'skip' has a second meaning: it can be used inside if blocks+(described below), to skip one or more records whenever the condition is+true. Records skipped in this way are ignored, except they are still+required to be valid CSV.+++File: hledger.info, Node: date-format, Next: timezone, Prev: skip, Up: CSV++10.5 '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-style date parsing pattern - see+https://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:formatTime.+The pattern must parse the CSV date value completely. Some examples:++# 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+++File: hledger.info, Node: timezone, Next: newest-first, Prev: date-format, Up: CSV++10.6 'timezone'+===============++timezone TIMEZONE++ When CSV contains date-times that are implicitly in some time zone+other than yours, but containing no explicit time zone information, you+can use this rule to declare the CSV's native time zone, which helps+prevent off-by-one dates.++ When the CSV date-times do contain time zone information, you don't+need this rule; instead, use '%Z' in 'date-format' (or '%z', '%EZ',+'%Ez'; see the formatTime link above).++ In either of these cases, hledger will do a time-zone-aware+conversion, localising the CSV date-times to your current system time+zone. If you prefer to localise to some other time zone, eg for+reproducibility, you can (on unix at least) set the output timezone with+the TZ environment variable, eg:++$ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv++ 'timezone' currently does not understand timezone names, except+"UTC", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", or "PDT".+For others, use numeric format: +HHMM or -HHMM.+++File: hledger.info, Node: newest-first, Next: intra-day-reversed, Prev: timezone, Up: CSV++10.7 'newest-first'+===================++hledger tries to ensure that the generated transactions will be ordered+chronologically, including same-day transactions. Usually it can+auto-detect how the CSV records are ordered. But if it encounters CSV+where all records are on the same date, it assumes that the records are+oldest first. If in fact the CSV's records are normally newest first,+like:++2022-10-01, txn 3...+2022-10-01, txn 2...+2022-10-01, txn 1...++ you can add the 'newest-first' rule to help hledger generate the+transactions in correct order.++# same-day CSV records are newest first+newest-first+++File: hledger.info, Node: intra-day-reversed, Next: decimal-mark, Prev: newest-first, Up: CSV++10.8 'intra-day-reversed'+=========================++If CSV records within a single day are ordered opposite to the overall+record order, you can add the 'intra-day-reversed' rule to improve the+order of journal entries. Eg, here the overall record order is newest+first, but same-day records are oldest first:++2022-10-02, txn 3...+2022-10-02, txn 4...+2022-10-01, txn 1...+2022-10-01, txn 2...++# transactions within each day are reversed with respect to the overall date order+intra-day-reversed+++File: hledger.info, Node: decimal-mark, Next: fields list, Prev: intra-day-reversed, Up: CSV++10.9 '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.+++File: hledger.info, Node: fields list, Next: Field assignment, Prev: decimal-mark, Up: CSV++10.10 'fields' list+===================++fields FIELDNAME1, FIELDNAME2, ...++ A fields list (the word 'fields' followed by comma-separated field+names) is optional, but convenient. It does two things:++ 1. It names the CSV field in each column. This can be convenient if+ you are referencing them in other rules, so you can say+ '%SomeField' instead of remembering '%13'.++ 2. Whenever you use one of the special hledger field names (described+ below), it assigns the CSV value in this position to that hledger+ field. This is the quickest way to populate hledger's fields and+ build a transaction.++ Here's an example that says "use the 1st, 2nd and 4th fields as the+transaction's date, description and amount; name the last two fields for+later reference; and ignore the others":++fields date, description, , amount, , , somefield, anotherfield++ In a fields list, the separator is always comma; it is unrelated to+the CSV file's separator. Also:++ * There must be least two items in the list (at least one comma).+ * Field names may not contain spaces. Spaces before/after field+ names are optional.+ * Field names may contain '_' (underscore) or '-' (hyphen).+ * Fields you don't care about can be given a dummy name or an empty+ name.++ If the CSV contains column headings, it's convenient to use these for+your field names, suitably modified (eg lower-cased with spaces replaced+by underscores).++ Sometimes you may want to alter a CSV field name to avoid assigning+to a hledger field with the same name. Eg you could call the CSV's+"balance" field 'balance_' to avoid directly setting hledger's 'balance'+field (and generating a balance assertion).+++File: hledger.info, Node: Field assignment, Next: Field names, Prev: fields list, Up: CSV++10.11 Field assignment+======================++HLEDGERFIELD 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+interpolate CSV fields, referenced either by their 1-based position in+the CSV record ('%N') or by the name they were given in the fields list+('%CSVFIELD'), and regular expression match groups ('\N').++ 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:++ * Interpolation strips outer whitespace (so a CSV value like '" 1 "'+ becomes '1' when interpolated) (#1051).+ * Interpolations always refer to a CSV field - you can't interpolate+ a hledger field. (See Referencing other fields below).+++File: hledger.info, Node: Field names, Next: if block, Prev: Field assignment, Up: CSV++10.12 Field names+=================++Note the two kinds of field names mentioned here, and used only in+hledger CSV rules files:++ 1. *CSV field names* ('CSVFIELD' in these docs): you can optionally+ name the CSV columns for easy reference (since hledger doesn't yet+ automatically recognise column headings in a CSV file), by writing+ arbitrary names in a 'fields' list, eg:++ fields When, What, Some_Id, Net, Total, Foo, Bar++ 2. Special *hledger field names* ('HLEDGERFIELD' in these docs): you+ must set at least some of these to generate the hledger transaction+ from a CSV record, by writing them as the left hand side of a field+ assignment, eg:++ date %When+ code %Some_Id+ description %What+ comment %Foo %Bar+ amount1 $ %Total++ or directly in a 'fields' list:++ fields date, description, code, , amount1, Foo, Bar+ currency $+ comment %Foo %Bar++ Here are all the special hledger field names available, and what+happens when you assign values to them:++* Menu:++* date field::+* date2 field::+* status field::+* code field::+* description field::+* comment field::+* account field::+* amount field::+* currency field::+* balance field::+++File: hledger.info, Node: date field, Next: date2 field, Up: Field names++10.12.1 date field+------------------++Assigning to 'date' sets the transaction date.+++File: hledger.info, Node: date2 field, Next: status field, Prev: date field, Up: Field names++10.12.2 date2 field+-------------------++'date2' sets the transaction's secondary date, if any.+++File: hledger.info, Node: status field, Next: code field, Prev: date2 field, Up: Field names++10.12.3 status field+--------------------++'status' sets the transaction's status, if any.+++File: hledger.info, Node: code field, Next: description field, Prev: status field, Up: Field names++10.12.4 code field+------------------++'code' sets the transaction's code, if any.+++File: hledger.info, Node: description field, Next: comment field, Prev: code field, Up: Field names++10.12.5 description field+-------------------------++'description' sets the transaction's description, if any.+++File: hledger.info, Node: comment field, Next: account field, Prev: description field, Up: Field names++10.12.6 comment field+---------------------++'comment' sets the transaction's comment, if any.++ 'commentN', where N is a number, sets the Nth posting's comment.++ You can assign multi-line comments by writing literal '\n' in the+code. A comment starting with '\n' will begin on a new line.++ Comments can contain tags, as usual.+++File: hledger.info, Node: account field, Next: amount field, Prev: comment field, Up: Field names++10.12.7 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, in conditional rules.++ If a posting's account name is left unset but its amount is set (see+below), a default account name will be chosen (like "expenses:unknown"+or "income:unknown").+++File: hledger.info, Node: amount field, Next: currency field, Prev: account field, Up: Field names++10.12.8 amount field+--------------------++There are several ways to set posting amounts from CSV, useful in+different situations.++ 1. *'amount'* is the oldest and simplest. Assigning to this sets the+ amount of the first and second postings. In the second posting,+ the amount will be negated; also, if it has a cost attached, it+ will be converted to cost.++ 2. *'amount-in'* and *'amount-out'* work exactly like the above, but+ should be used when the CSV has two amount fields (such as "Debit"+ and "Credit", or "Inflow" and "Outflow"). Whichever field has a+ non-zero value will be used as the amount of the first and second+ postings. Here are some tips to avoid confusion:++ * It's not "amount-in for posting 1 and amount-out for posting+ 2", it is "extract a single amount from the amount-in or+ amount-out field, and use that for posting 1 and (negated) for+ posting 2".+ * Don't use both 'amount' and 'amount-in'/'amount-out' in the+ same rules file; choose based on whether the amount is in a+ single CSV field or spread across two fields.+ * In each record, at most one of the two CSV fields should+ contain a non-zero amount; the other field must contain a zero+ or nothing.+ * hledger assumes both CSV fields contain unsigned numbers, and+ it automatically negates the amount-out values.+ * If the data doesn't fit these requirements, you'll probably+ need an if rule (see below).++ 3. *'amountN'* (where N is a number from 1 to 99) sets the amount of+ only a single posting: the Nth posting in the transaction. You'll+ usually need at least two such assignments to make a balanced+ transaction. You can also generate more than two postings, to+ represent more complex transactions. The posting numbers don't+ have to be consecutive; with if rules, higher posting numbers can+ be useful to ensure a certain order of postings.++ 4. *'amountN-in'* and *'amountN-out'* work exactly like the above, but+ should be used when the CSV has two amount fields. This is+ analogous to 'amount-in' and 'amount-out', and those tips also+ apply here.++ 5. Remember that a 'fields' list can also do assignments. So in a+ fields list if you name a CSV field "amount", that counts as+ assigning to 'amount'. (If you don't want that, call it something+ else in the fields list, like "amount_".)++ 6. The above don't handle every situation; if you need more+ flexibility, use an 'if' rule to set amounts conditionally. See+ "Working with CSV > Setting amounts" below for more on this and on+ amount-setting generally.+++File: hledger.info, Node: currency field, Next: balance field, Prev: amount field, Up: Field names++10.12.9 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.+++File: hledger.info, Node: balance field, Prev: currency field, Up: Field names++10.12.10 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 the Working with CSV tips below for more about setting amounts+and currency.+++File: hledger.info, Node: if block, Next: Matchers, Prev: Field names, Up: CSV++10.13 'if' block+================++Rules can be applied conditionally, depending on patterns in the CSV+data. This allows flexibility; in particular, it is how you can+categorise transactions, selecting an appropriate account name based on+their description (for example). There are two ways to write+conditional rules: "if blocks", described here, and "if tables",+described below.++ An if block is the word 'if' and one or more "matcher" expressions+(can be a word or phrase), one per line, starting either on the same or+next line; followed by one or more indented rules. Eg,++if MATCHER+ RULE++ or++if+MATCHER+MATCHER+MATCHER+ RULE+ RULE++ If any of the matchers succeeds, all of the indented rules will be+applied. They are usually field assignments, but the following special+rules may also be used within an if block:++ * 'skip' - skips the matched CSV record (generating no transaction+ from it)+ * 'end' - skips the rest of the current CSV file.++ Some examples:++# if the record contains "groceries", set account2 to "expenses:groceries"+if groceries+ account2 expenses:groceries++# if the record contains any of these phrases, set account2 and a transaction comment as shown+if+monthly service fee+atm transaction fee+banking thru software+ account2 expenses:business:banking+ comment XXX deductible ? check it++# if an empty record is seen (assuming five fields), ignore the rest of the CSV file+if ,,,,+ end+++File: hledger.info, Node: Matchers, Next: if table, Prev: if block, Up: CSV++10.14 Matchers+==============++There are two kinds:++ 1. A record matcher is a word or single-line text fragment or regular+ expression ('REGEX'), which hledger will try to match+ case-insensitively anywhere within the CSV record.+ Eg: 'whole foods'++ 2. A field matcher is preceded with a percent sign and CSV field name+ ('%CSVFIELD REGEX'). hledger will try to match these just within+ the named CSV field.+ Eg: '%date 2023'++ The regular expression is (as usual in hledger) a POSIX extended+regular expression, that also supports GNU word boundaries ('\b', '\B',+'\<', '\>'), and nothing else. If you have trouble, see "Regular+expressions" in the hledger manual+(https://hledger.org/hledger.html#regular-expressions).++* Menu:++* What matchers match::+* Combining matchers::+* Match groups::+++File: hledger.info, Node: What matchers match, Next: Combining matchers, Up: Matchers++10.14.1 What matchers match+---------------------------++With record matchers, it's important to know that the record matched is+not the original CSV record, but a modified one: separators will be+converted to commas, and enclosing double quotes (but not enclosing+whitespace) are removed. So for example, when reading an SSV file, if+the original record was:++2023-01-01; "Acme, Inc."; 1,000++ the regex would see, and try to match, this modified record text:++2023-01-01,Acme, Inc., 1,000+++File: hledger.info, Node: Combining matchers, Next: Match groups, Prev: What matchers match, Up: Matchers++10.14.2 Combining matchers+--------------------------++When an if block has multiple matchers, they are combined as follows:++ * By default they are OR'd (any of them can match)+ * When a matcher is preceded by ampersand ('&', at the start of the+ line) it will be AND'ed with the previous matcher (all in the+ AND'ed group must match)+ * _Added in 1.32_ When a matcher is preceded by an exclamation mark+ ('!'), it is negated (it must not match).++ Note currently there is a limitation: you can't use both '&' and '!'+on the same line (you can't AND a negated matcher).+++File: hledger.info, Node: Match groups, Prev: Combining matchers, Up: Matchers++10.14.3 Match groups+--------------------++_Added in 1.32_++ Matchers can define match groups: parenthesised portions of the+regular expression which are available for reference in field+assignments. Groups are enclosed in regular parentheses ('(' and ')')+and can be nested. Each group is available in field assignments using+the token '\N', where N is an index into the match groups for this+conditional block (e.g. '\1', '\2', etc.).++ Example: Warp credit card payment postings to the beginning of the+billing period (Month start), to match how they are presented in+statements, using posting dates:++if %date (....-..)-..+ comment2 date:\1-01++ Another example: Read the expense account from the CSV field, but+throw away a prefix:++if %account1 liabilities:family:(expenses:.*)+ account1 \1+++File: hledger.info, Node: if table, Next: balance-type, Prev: Matchers, Up: CSV++10.15 'if' table+================++"if tables" are an alternative to if blocks; they can express many+matchers and field assignments in a more compact tabular format, like+this:++if,HLEDGERFIELD1,HLEDGERFIELD2,...+MATCHERA,VALUE1,VALUE2,...+MATCHERB,VALUE1,VALUE2,...+; Comment line that explains MATCHERC+MATCHERC,VALUE1,VALUE2,...+<empty line>++ The first character after 'if' is taken to be this if table's field+separator. It is unrelated to the separator used in the CSV file. It+should be a non-alphanumeric character like ',' or '|' that does not+appear anywhere else in the table (it should not be used in field names+or matchers or values, and it cannot be escaped with a backslash).++ Each line must contain the same number of separators; empty values+are allowed. Whitespace can be used in the matcher lines for+readability (but not in the if line, currently). You can use the+comment lines in the table body. The table must be terminated by an+empty line (or end of file).++ An if table like the above is interpreted as follows: try all of the+matchers; whenever a matcher succeeds, assign all of the values on that+line to the corresponding hledger fields; If multiple lines match, later+lines will override fields assigned by the earlier ones - just like the+sequence of 'if' blocks would behave.++ If table presented above is equivalent to this sequence of if blocks:++if MATCHERA+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++if MATCHERB+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++; Comment line which explains MATCHERC+if MATCHERC+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++ Example:++if,account2,comment+atm transaction fee,expenses:business:banking,deductible? check it+%description groceries,expenses:groceries,+;; Comment line that desribes why this particular date is special+2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out+++File: hledger.info, Node: balance-type, Next: include, Prev: if table, Up: CSV++10.16 '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+++File: hledger.info, Node: include, Next: Working with CSV, Prev: balance-type, Up: CSV++10.17 '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+++File: hledger.info, Node: Working with CSV, Next: CSV rules examples, Prev: include, Up: CSV++10.18 Working with CSV+======================++Some tips:++* Menu:++* Rapid feedback::+* Valid CSV::+* File Extension::+* Reading CSV from standard input::+* Reading multiple CSV files::+* Reading files specified by rule::+* Valid transactions::+* Deduplicating importing::+* Setting amounts::+* Amount signs::+* Setting currency/commodity::+* Amount decimal places::+* Referencing other fields::+* How CSV rules are evaluated::+* Well factored rules::+++File: hledger.info, Node: Rapid feedback, Next: Valid CSV, Up: Working with CSV++10.18.1 Rapid feedback+----------------------++It's a good idea to get rapid feedback while creating/troubleshooting+CSV rules. Here's a good way, using entr from eradman.com/entrproject:++$ 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.+++File: hledger.info, Node: Valid CSV, Next: File Extension, Prev: Rapid feedback, Up: Working with CSV++10.18.2 Valid CSV+-----------------++Note that hledger will only accept valid CSV conforming to RFC 4180, and+equivalent SSV and TSV formats (like RFC 4180 but with semicolon or tab+as separators). This means, eg:++ * Values may be enclosed in double quotes, or not. Enclosing in+ single quotes is not allowed. (Eg ''A','B'' is rejected.)+ * When values are enclosed in double quotes, spaces outside the+ quotes are not allowed. (Eg '"A", "B"' is rejected.)+ * When values are not enclosed in quotes, they may not contain double+ quotes. (Eg 'A"A, B' is rejected.)++ If your CSV/SSV/TSV is not valid in this sense, you'll need to+transform it before reading with hledger. Try using sed, or a more+permissive CSV parser like python's csv lib.+++File: hledger.info, Node: File Extension, Next: Reading CSV from standard input, Prev: Valid CSV, Up: Working with CSV++10.18.3 File Extension+----------------------++To help hledger choose the CSV file reader and show the right error+messages (and choose the right field separator character by default),+it's best if CSV/SSV/TSV files are named with a '.csv', '.ssv' or '.tsv'+filename extension. (More about this at Data formats.)++ When reading files with the "wrong" extension, you can ensure the CSV+reader (and the default field separator) by prefixing the file path with+'csv:', 'ssv:' or 'tsv:': Eg:++$ hledger -f ssv:foo.dat print++ You can also override the default field separator with a separator+rule if needed.+++File: hledger.info, Node: Reading CSV from standard input, Next: Reading multiple CSV files, Prev: File Extension, Up: Working with CSV++10.18.4 Reading CSV from standard input+---------------------------------------++You'll need the file format prefix when reading CSV from stdin also,+since hledger assumes journal format by default. Eg:++$ cat foo.dat | hledger -f ssv:- print+++File: hledger.info, Node: Reading multiple CSV files, Next: Reading files specified by rule, Prev: Reading CSV from standard input, Up: Working with CSV++10.18.5 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.+++File: hledger.info, Node: Reading files specified by rule, Next: Valid transactions, Prev: Reading multiple CSV files, Up: Working with CSV++10.18.6 Reading files specified by rule+---------------------------------------++Instead of specifying a CSV file in the command line, you can specify a+rules file, as in 'hledger -f foo.csv.rules CMD'. By default this will+read data from foo.csv in the same directory, but you can add a source+rule to specify a different data file, perhaps located in your web+browser's download directory.++ This feature was added in hledger 1.30, so you won't see it in most+CSV rules examples. But it helps remove some of the busywork of+managing CSV downloads. Most of your financial institutions's default+CSV filenames are different and can be recognised by a glob pattern. So+you can put a rule like 'source Checking1*.csv' in+foo-checking.csv.rules, and then periodically follow a workflow like:++ 1. Download CSV from Foo's website, using your browser's defaults+ 2. Run 'hledger import foo-checking.csv.rules' to import any new+ transactions++ After import, you can: discard the CSV, or leave it where it is for a+while, or move it into your archives, as you prefer. If you do nothing,+next time your browser will save something like Checking1-2.csv, and+hledger will use that because of the '*' wild card and because it is the+most recent.+++File: hledger.info, Node: Valid transactions, Next: Deduplicating importing, Prev: Reading files specified by rule, Up: Working with CSV++10.18.7 Valid transactions+--------------------------++After reading a CSV file, hledger post-processes and validates the+generated journal entries as it would for a journal file - balancing+them, applying balance assignments, and canonicalising amount styles.+Any errors at this stage will be reported in the usual way, displaying+the problem entry.++ 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+++File: hledger.info, Node: Deduplicating importing, Next: Setting amounts, Prev: Valid transactions, Up: Working with CSV++10.18.8 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:++ * https://hledger.org/cookbook.html#setups-and-workflows+ * https://plaintextaccounting.org -> data import/conversion+++File: hledger.info, Node: Setting amounts, Next: Amount signs, Prev: Deduplicating importing, Up: Working with CSV++10.18.9 Setting amounts+-----------------------++Continuing from amount field above, here are more tips for+amount-setting:++ 1. *If the amount is in a single CSV field:*++ a. *If its sign indicates direction of flow:*+ Assign it to 'amountN', to set the Nth posting's amount. N is+ usually 1 or 2 but can go up to 99.++ b. *If another field indicates direction of flow:*+ Use one or more conditional rules to set the appropriate+ amount sign. Eg:++ # assume a withdrawal unless Type contains "deposit":+ amount1 -%Amount+ if %Type deposit+ amount1 %Amount++ 2. *If the amount is in two CSV fields (such as Debit and Credit, or+ In and Out):*++ a. *If both fields are unsigned:*+ Assign one field to 'amountN-in' and the other to+ 'amountN-out'. hledger will automatically negate the "out"+ field, and will use whichever field value is non-zero as+ posting N's amount.++ b. *If either field is signed:*+ You will probably need to override hledger's sign for one or+ the other field, as in the following example:++ # Negate the -out value, but only if it is not empty:+ fields date, description, amount1-in, amount1-out+ if %amount1-out [1-9]+ amount1-out -%amount1-out++ c. *If both fields can contain a non-zero value (or both can be+ empty):*+ The -in/-out rules normally choose the value which is+ non-zero/non-empty. Some value pairs can be ambiguous, such+ as '1' and 'none'. For such cases, use conditional rules to+ help select the amount. Eg, to handle the above you could+ select the value containing non-zero digits:++ fields date, description, in, out+ if %in [1-9]+ amount1 %in+ if %out [1-9]+ amount1 %out++ 3. *If you want posting 2's amount converted to cost:*+ Use the unnumbered 'amount' (or 'amount-in' and 'amount-out')+ syntax.++ 4. *If the CSV has only balance amounts, not transaction amounts:*+ Assign to 'balanceN', to set a balance assignment on the Nth+ posting, causing the posting's amount to be calculated+ automatically. 'balance' with no number is equivalent to+ 'balance1'. In this situation hledger is more likely to guess the+ wrong default account name, so you may need to set that explicitly.+++File: hledger.info, Node: Amount signs, Next: Setting currency/commodity, Prev: Setting amounts, Up: Working with CSV++10.18.10 Amount signs+---------------------++There is some special handling making it easier to parse and to reverse+amount signs. (This only works for whole amounts, not for cost amounts+such as COST in 'amount1 AMT @ COST'):++ * *If an amount value begins with a plus sign:*+ that will be removed: '+AMT' becomes 'AMT'++ * *If an amount value is parenthesised:*+ it will be de-parenthesised and sign-flipped: '(AMT)' becomes+ '-AMT'++ * *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'++ * *If an amount value contains just a sign (or just a set of+ parentheses):*+ that is removed, making it an empty value. '"+"' or '"-"' or+ '"()"' becomes '""'.++ It's not possible (without preprocessing the CSV) to set an amount to+its absolute value, ie discard its sign.+++File: hledger.info, Node: Setting currency/commodity, Next: Amount decimal places, Prev: Amount signs, Up: Working with CSV++10.18.11 Setting currency/commodity+-----------------------------------++If the currency/commodity symbol is included in the CSV's amount+field(s):++2023-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++2023-01-01 foo+ expenses:unknown $123.00+ income:unknown $-123.00++ If the currency is provided as a separate CSV field:++2023-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++2023-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++2023-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.+++File: hledger.info, Node: Amount decimal places, Next: Referencing other fields, Prev: Setting currency/commodity, Up: Working with CSV++10.18.12 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+decimal 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).+++File: hledger.info, Node: Referencing other fields, Next: How CSV rules are evaluated, Prev: Amount decimal places, Up: Working with CSV++10.18.13 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+literal "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+++File: hledger.info, Node: How CSV rules are evaluated, Next: Well factored rules, Prev: Referencing other fields, Up: Working with CSV++10.18.14 How CSV rules are evaluated+------------------------------------++Here's how to think of CSV rules being evaluated (if you really need+to). First,++ * '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:++ * 'skip' (at top level)+ * 'date-format'+ * 'newest-first'+ * 'fields' - names the CSV fields, optionally sets up initial+ assignments to hledger fields++ Then for each CSV record in turn:++ * 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.+ * 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.+ * compute a value for each hledger field - either the one that was+ assigned to it (and interpolate the %CSVFIELD references), or a+ default+ * generate a hledger transaction (journal entry) from these values.++ This is all part of the CSV reader, one of several readers hledger+can use to parse input files. When all files have been read+successfully, the transactions are passed as input to whichever hledger+command the user specified.+++File: hledger.info, Node: Well factored rules, Prev: How CSV rules are evaluated, Up: Working with CSV++10.18.15 Well factored rules+----------------------------++Some things than can help reduce duplication and complexity in rules+files:++ * Extracting common rules usable with multiple CSV files into a+ 'common.rules', and adding 'include common.rules' to each CSV's+ rules file.++ * Splitting if blocks into smaller if blocks, extracting the+ frequently used parts.+++File: hledger.info, Node: CSV rules examples, Prev: Working with CSV, Up: CSV++10.19 CSV rules examples+========================++* Menu:++* Bank of Ireland::+* Coinbase::+* Amazon::+* Paypal::+++File: hledger.info, Node: Bank of Ireland, Next: Coinbase, Up: CSV rules examples++10.19.1 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+necessary 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+reading directly from CSV, but they will be checked if these entries are+imported into a journal file.+++File: hledger.info, Node: Coinbase, Next: Amazon, Prev: Bank of Ireland, Up: CSV rules examples++10.19.2 Coinbase+----------------++A simple example with some CSV from Coinbase. The spot price is+recorded using cost notation. The legacy 'amount' field name+conveniently sets amount 2 (posting 2's amount) to the total cost.++# Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes+# 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,"","","","Received 100.00 USDC from an external account"++# coinbase.csv.rules+skip 1+fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes+date %Timestamp+date-format %Y-%m-%dT%T%Z+description %Notes+account1 assets:coinbase:cc+amount %Quantity_Transacted %Asset @ %Spot_Price_at_Transaction %Spot_Price_Currency++$ hledger print -f coinbase.csv+2021-12-30 Received 100.00 USDC from an external account+ assets:coinbase:cc 100 USDC @ 0.740000 GBP+ income:unknown -74.000000 GBP+++File: hledger.info, Node: Amazon, Next: Paypal, Prev: Coinbase, Up: CSV rules examples++10.19.3 Amazon+--------------++Here we convert amazon.com order history, and use an if block to+generate 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+++File: hledger.info, Node: Paypal, Prev: Amazon, Up: CSV rules examples++10.19.4 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:+++File: hledger.info, Node: Timeclock, Next: Timedot, Prev: CSV, Up: Top++11 Timeclock+************++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). Lines+beginning with '#' or ';' or '*', and blank lines, are ignored.++i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:+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 2 spaces ; optional comment, tags:+ (some account) 0.33h++2015-03-31 * 22:21-23:59+ (another:account) 1.64h++2015-04-01 * 00:00-02:00+ (another:account) 2.01h++ 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:++ * use emacs and the built-in timeclock.el, or the extended+ timeclock-x.el and perhaps the extras in ledgerutils.el++ * at the command line, use these bash aliases: 'cli alias ti="echo i+ `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o `date+ '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"'++ * 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.+++File: hledger.info, Node: Timedot, Next: PART 3 REPORTING CONCEPTS, Prev: Timeclock, Up: Top++12 Timedot+**********++'timedot' format is hledger's human-friendly time logging format.+Compared to 'timeclock' format, it is more convenient for quick,+approximate, and retroactive time logging, and more human-readable (you+can see at a glance where time was spent). A quick example:++2023-05-01+hom:errands .... .... ; two hours; the space is ignored+fos:hledger:timedot .. ; half an hour+per:admin:finance ; no time spent yet++ hledger reads this as a transaction on this day with three+(unbalanced) postings, where each dot represents "0.25". No commodity+symbol is assumed, but we typically interpret it as hours.++$ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required+2023-05-01 *+ (hom:errands) 2.00 ; two hours+ (fos:hledger:timedot) 0.50 ; half an hour+ (per:admin:finance) 0++ A timedot file contains a series of transactions (usually one per+day). Each begins with a *simple date* (Y-M-D, Y/M/D, or Y.M.D),+optionally be followed on the same line by a transaction description,+and/or a transaction comment following a semicolon.++ After the date line are zero or more time postings, consisting of:++ * *An account name* - any hledger-style account name, optionally+ indented.++ * *Two or more spaces* - required if there is an amount (as in+ journal format).++ * *A timedot amount*, which can be++ * empty (representing zero)++ * a number, optionally followed by a unit 's', 'm', 'h', 'd',+ 'w', 'mo', or 'y', representing a precise number of seconds,+ minutes, hours, days weeks, months or years (hours is assumed+ by default), which will be converted to hours according to 60s+ = 1m, 60m = 1h, 24h = 1d, 7d = 1w, 30d = 1mo, 365d = 1y.++ * one or more dots (period characters), each representing 0.25.+ These are the dots in "timedot". Spaces are ignored and can+ be used for grouping/alignment.++ * _Added in 1.32_ one or more letters. These are like dots but+ they also generate a tag 't:' (short for "type") with the+ letter as its value, and a separate posting for each of the+ values. This provides a second dimension of categorisation,+ viewable in reports with '--pivot t'.++ * *An optional comment* following a semicolon (a hledger-style+ posting comment).++ There is some flexibility to help with keeping time log data and+notes in the same file:++ * Blank lines and lines beginning with '#' or ';' are ignored.++ * After the first date line, lines which do not contain a double+ space are parsed as postings with zero amount. (hledger's register+ reports will show these if you add -E).++ * Before the first date line, lines beginning with '*' (eg org+ headings) are ignored. And from the first date line onward, Emacs+ org mode heading prefixes at the start of lines (one or more '*''s+ followed by a space) will be ignored. This means the time log can+ also be a org outline.++* Menu:++* Timedot examples::+++File: hledger.info, Node: Timedot examples, Up: Timedot++12.1 Timedot examples+=====================++Numbers:++2016/2/3+inc:client1 4+fos:hledger 3h+biz:research 60m++ Dots:++# 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 .++$ 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 ++ Letters:++# Activity types:+# c cleanup/catchup/repair+# e enhancement+# s support+# l learning/research++2023-11-01+work:adm ccecces++$ hledger -f a.timedot print+2023-11-01+ (work:adm) 1 ; t:c+ (work:adm) 0.5 ; t:e+ (work:adm) 0.25 ; t:s++$ hledger -f a.timedot bal+ 1.75 work:adm+--------------------+ 1.75 ++$ hledger -f a.timedot bal --pivot t+ 1.00 c+ 0.50 e+ 0.25 s+--------------------+ 1.75 ++ Org:++* 2023 Work Diary+** Q1+*** 2023-02-29+**** DONE+0700 yoga+**** UNPLANNED+**** BEGUN+hom:chores+ cleaning ...+ water plants+ outdoor - one full watering can+ indoor - light watering+**** TODO+adm:planning: trip+*** LATER++ Using '.' as account name separator:++2016/2/4+fos.hledger.timedot 4h+fos.ledger ..++$ hledger -f a.timedot --alias '/\./=:' bal -t+ 4.50 fos+ 4.00 hledger:timedot+ 0.50 ledger+--------------------+ 4.50+++File: hledger.info, Node: PART 3 REPORTING CONCEPTS, Next: Amount formatting, Prev: Timedot, Up: Top++13 PART 3: REPORTING CONCEPTS+*****************************+++File: hledger.info, Node: Amount formatting, Next: Time periods, Prev: PART 3 REPORTING CONCEPTS, Up: Top++14 Amount formatting+********************++* Menu:++* Commodity display style::+* Rounding::+* Trailing decimal marks::+* Amount parseability::+++File: hledger.info, Node: Commodity display style, Next: Rounding, Up: Amount formatting++14.1 Commodity display style+============================++For the amounts in each commodity, hledger chooses a consistent display+style (symbol placement, decimal mark and digit group marks, number of+decimal digits) to use in most reports. This is inferred as follows:++ First, if there's a 'D' directive declaring a default commodity, that+commodity symbol and amount format is applied to all no-symbol amounts+in the journal.++ Then each commodity's display style is determined from its+'commodity' directive. We recommend always declaring commodities with+'commodity' directives, since they help ensure consistent display styles+and precisions, and bring other benefits such as error checking for+commodity symbols. Here's an example:++# Set display styles (and decimal marks, for parsing, if there is no decimal-mark directive)+# for the $, EUR, INR and no-symbol commodities:+commodity $1,000.00+commodity EUR 1.000,00+commodity INR 9,99,99,999.00+commodity 1 000 000.9455++ But for convenience, if a 'commodity' directive is not present,+hledger infers a commodity's display styles from its amounts as they are+written in the journal (excluding cost amounts and amounts in periodic+transaction rules or auto posting rules). It uses++ * the symbol placement and decimal mark of the first amount seen+ * the digit group marks of the first amount with digit group marks+ * and the maximum number of decimal digits seen across all amounts.++ And as fallback if no applicable amounts are found, it would use a+default style, like '$1000.00' (symbol on the left with no space, period+as decimal mark, and two decimal digits).++ Finally, commodity styles can be overridden by the+'-c/--commodity-style' command line option.+++File: hledger.info, Node: Rounding, Next: Trailing decimal marks, Prev: Commodity display style, Up: Amount formatting++14.2 Rounding+=============++Amounts are stored internally as decimal numbers with up to 255 decimal+places. They are displayed with their original journal precisions by+print and print-like reports, and rounded to their display precision+(the number of decimal digits specified by the commodity display style)+by other reports. When rounding, hledger uses banker's rounding (it+rounds to the nearest even digit). So eg 0.5 displayed with zero+decimal digits appears as "0".+++File: hledger.info, Node: Trailing decimal marks, Next: Amount parseability, Prev: Rounding, Up: Amount formatting++14.3 Trailing decimal marks+===========================++If you're wondering why your 'print' report sometimes shows trailing+decimal marks, with no decimal digits; it does this when showing amounts+that have digit group marks but no decimal digits, to disambiguate them+and allow them to be re-parsed reliably (see Decimal marks). Eg:++commodity $1,000.00++2023-01-02+ (a) $1000++$ hledger print+2023-01-02+ (a) $1,000.++ If this is a problem (eg when exporting to Ledger), you can avoid it+by disabling digit group marks, eg with -c/-commodity (for each affected+commodity):++$ hledger print -c '$1000.00'+2023-01-02+ (a) $1000++ or by forcing print to always show decimal digits, with -round:++$ hledger print -c '$1,000.00' --round=soft+2023-01-02+ (a) $1,000.00+++File: hledger.info, Node: Amount parseability, Prev: Trailing decimal marks, Up: Amount formatting++14.4 Amount parseability+========================++More generally, hledger output falls into three rough categories, which+format amounts a little bit differently to suit different consumers:++ *1. "hledger-readable output" - should be readable by hledger (and+by humans)*++ * This is produced by reports that show full journal entries:+ 'print', 'import', 'close', 'rewrite' etc.+ * It shows amounts with their original journal precisions, which may+ not be consistent.+ * It adds a trailing decimal mark when needed to avoid showing+ ambiguous amounts.+ * It can be parsed reliably (by hledger and ledger2beancount at+ least, but perhaps not by Ledger..)++ *2. "human-readable output" - usually for humans*++ * This is produced by all other reports.+ * It shows amounts with standard display precisions, which will be+ consistent within each commodity.+ * It shows ambiguous amounts unmodified.+ * It can be parsed reliably in the context of a known report (when+ you know decimals are consistently not being shown, you can assume+ a single mark is a digit group mark).++ *3. "machine-readable output" - usually for other software*++ * This is produced by all reports when an output format like 'csv',+ 'tsv', 'json', or 'sql' is selected.+ * It shows amounts as 1 or 2 do, but without digit group marks.+ * It can be parsed reliably (if needed, the decimal mark can be+ changed with -c/-commodity-style).+++File: hledger.info, Node: Time periods, Next: Depth, Prev: Amount formatting, Up: Top++15 Time periods+***************++* Menu:++* Report start & end date::+* Smart dates::+* Report intervals::+* Date adjustment::+* Period expressions::+++File: hledger.info, Node: Report start & end date, Next: Smart dates, Up: Time periods++15.1 Report start & end date+============================++By default, most hledger reports will show the full span of time+represented by the journal. The report start date will be the earliest+transaction or posting date, and the report end date will be the latest+transaction, posting, or market price date.++ Often you will want to see a shorter time span, such as the current+month. You can specify a start and/or end date using '-b/--begin',+'-e/--end', '-p/--period' or a 'date:' query (described below). All of+these accept the smart date syntax (below).++ Some notes:++ * End dates are exclusive, as in Ledger, so you should write the date+ _after_ the last day you want to see in the report.+ * As noted in reporting options: among start/end dates specified with+ _options_, the last (i.e. right-most) option takes precedence.+ * 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.+ * In some cases a report interval will adjust start/end dates to fall+ on interval boundaries (see below).++ Examples:++'-b begin on St. Patrick's day 2016+2016/3/17'+'-e 12/1' end at the start of december 1st of the current year+ (11/30 will be the last date included)+'-b all transactions on or after the 1st of the current month+thismonth'+'-p all transactions in the current month+thismonth'+'date:2016/3/17..'the above written as queries instead ('..' can also be+ replaced with '-')+'date:..12/1'+'date:thismonth..'+'date:thismonth'+++File: hledger.info, Node: Smart dates, Next: Report intervals, Prev: Report start & end date, Up: Time periods++15.2 Smart dates+================++hledger's user interfaces accept a "smart date" syntax for added+convenience. Smart dates optionally can be relative to today's date, be+written with english words, and have less-significant parts omitted+(missing parts are inferred as 1). Some examples:++'2004/10/1', exact date, several separators allowed. Year+'2004-01-01', is 4+ digits, month is 1-12, day is 1-31+'2004.9.1'+'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, -1, 0, 1 days from today+tomorrow'+'last/this/next -1, 0, 1 periods from the current period+day/week/month/quarter/year'+'in n n periods from the current period+days/weeks/months/quarters/years'+'n n periods from the current period+days/weeks/months/quarters/years+ahead'+'n -n periods from the current period+days/weeks/months/quarters/years+ago'+'20181201' 8 digit YYYYMMDD with valid year month and+ day+'201812' 6 digit YYYYMM with valid year and month++ Some 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++ "Today's date" can be overridden with the '--today' option, in case+it's needed for testing or for recreating old reports. (Except for+periodic transaction rules, which are not affected by '--today'.)+++File: hledger.info, Node: Report intervals, Next: Date adjustment, Prev: Smart dates, Up: Time periods++15.3 Report intervals+=====================++A report interval can be specified so that reports like register,+balance or activity become multi-period, showing each subperiod as a+separate row or column.++ The following standard intervals can be enabled with command-line+flags:++ * '-D/--daily'+ * '-W/--weekly'+ * '-M/--monthly'+ * '-Q/--quarterly'+ * '-Y/--yearly'++ More complex intervals can be specified using '-p/--period',+described below.+++File: hledger.info, Node: Date adjustment, Next: Period expressions, Prev: Report intervals, Up: Time periods++15.4 Date adjustment+====================++When there is a report interval (other than daily), report start/end+dates which have been inferred, eg from the journal, are automatically+adjusted to natural period boundaries. This is convenient for producing+simple periodic reports. More precisely:++ * an inferred start date will be adjusted earlier if needed to fall+ on a natural period boundary++ * an inferred end date will be adjusted later if needed to make the+ last period the same length as the others.++ By contrast, start/end dates which have been specified explicitly,+with '-b', '-e', '-p' or 'date:', will not be adjusted (since hledger+1.29). This makes it possible to specify non-standard report periods,+but it also means that if you are specifying a start date, you should+pick one that's on a period boundary if you want to see simple report+period headings.+++File: hledger.info, Node: Period expressions, Prev: Date adjustment, Up: Time periods++15.5 Period expressions+=======================++The '-p/--period' option specifies a period expression, which is a+compact way of expressing a start date, end date, and/or report+interval.++ Here's a period expression with a start and end date (specifying the+first quarter of 2009):++'-p "from 2009/1/1 to 2009/4/1"'++ Several keywords like "from" and "to" are supported for readability;+these are optional. "to" can also be written as ".." or "-". The+spaces are also optional, as long as you don't run two dates together.+So the following are equivalent to the above:++'-p "2009/1/1 2009/4/1"'+'-p2009/1/1to2009/4/1'+'-p2009/1/1..2009/4/1'++ Dates are smart dates, so if the current year is 2009, these are also+equivalent to the above:++'-p "1/1 4/1"'+'-p "jan-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 date in the journal:++'-p "from 2009/1/1"' everything after january 1, 2009+'-p "since 2009/1"' the same, since is a synonym+'-p "from 2009"' the same+'-p "to 2009"' everything before january 1, 2009++ You can also specify a period by writing a single partial or full+date:++'-p "2009"' the year 2009; equivalent to “2009/1/1 to 2010/1/1”+'-p "2009/1"' the month of january 2009; equivalent to “2009/1/1 to+ 2009/2/1”+'-p the first day of 2009; equivalent to “2009/1/1 to+"2009/1/1"' 2009/1/2”++ or by using the "Q" quarter-year syntax (case insensitive):++'-p "2009Q1"' first quarter of 2009, equivalent to “2009/1/1 to+ 2009/4/1”+'-p "q4"' fourth quarter of the current year++* Menu:++* Period expressions with a report interval::+* More complex report intervals::+* Multiple weekday intervals::+++File: hledger.info, Node: Period expressions with a report interval, Next: More complex report intervals, Up: Period expressions++15.5.1 Period expressions with a report interval+------------------------------------------------++A period expression can also begin with a report interval, separated+from the start/end dates (if any) by a space or the word 'in':++'-p "weekly from 2009/1/1 to 2009/4/1"'+'-p "monthly in 2008"'+'-p "quarterly"'+++File: hledger.info, Node: More complex report intervals, Next: Multiple weekday intervals, Prev: Period expressions with a report interval, Up: Period expressions++15.5.2 More complex report intervals+------------------------------------++Some more complex intervals can be specified within period expressions,+such as:++ * 'biweekly' (every two weeks)+ * 'fortnightly'+ * 'bimonthly' (every two months)+ * 'every day|week|month|quarter|year'+ * 'every N days|weeks|months|quarters|years'++ Weekly on a custom day:++ * 'every Nth day of week' ('th', 'nd', 'rd', or 'st' are all accepted+ after the number)+ * 'every WEEKDAYNAME' (full or three-letter english weekday name,+ case insensitive)++ Monthly on a custom day:++ * 'every Nth day [of month]'+ * 'every Nth WEEKDAYNAME [of month]'++ Yearly on a custom day:++ * 'every MM/DD [of year]' (month number and day of month number)+ * 'every MONTHNAME DDth [of year]' (full or three-letter english+ month name, case insensitive, and day of month number)+ * 'every DDth MONTHNAME [of year]' (equivalent to the above)++ Examples:++'-p "bimonthly from+2008"'+'-p "every 2 weeks"'+'-p "every 5 months from+2009/03"'+'-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+ November+'-p "every 5th November"' same+'-p "every Nov 5th"' same++ Show historical balances at end of the 15th day of each month (N is+an end date, exclusive as always):++$ hledger balance -H -p "every 16th day"++ Group postings from the start of wednesday to end of the following+tuesday (N is both (inclusive) start date and (exclusive) end date):++$ hledger register checking -p "every 3rd day of week"+++File: hledger.info, Node: Multiple weekday intervals, Prev: More complex report intervals, Up: Period expressions++15.5.3 Multiple weekday intervals+---------------------------------++This special form is also supported:++ * 'every WEEKDAYNAME,WEEKDAYNAME,...' (full or three-letter english+ weekday names, case insensitive)++ Also, 'weekday' and 'weekendday' are shorthand for+'mon,tue,wed,thu,fri' and 'sat,sun'.++ This is mainly intended for use with '--forecast', to generate+periodic transactions on arbitrary days of the week. It may be less+useful with '-p', since it divides each week into subperiods of unequal+length, which is unusual. (Related: #1632)++ Examples:++'-p "every dates will be Mon, Wed, Fri; periods will be+mon,wed,fri"' Mon-Tue, Wed-Thu, Fri-Sun+'-p "every dates will be Mon, Tue, Wed, Thu, Fri; periods will+weekday"' be Mon, Tue, Wed, Thu, Fri-Sun+'-p "every dates will be Sat, Sun; periods will be Sat, Sun-Fri+weekendday"'+++File: hledger.info, Node: Depth, Next: Queries, Prev: Time periods, Up: Top++16 Depth+********++With the '--depth NUM' option (short form: '-NUM'), reports will show+accounts only to the specified depth, hiding deeper subaccounts. Use+this when you want a summary with less detail. This flag has the same+effect as a 'depth:' query argument: 'depth:2', '--depth=2' or '-2' are+equivalent.+++File: hledger.info, Node: Queries, Next: Pivoting, Prev: Depth, Up: Top++17 Queries+**********++One of hledger's strengths is being able to quickly report on a precise+subset of your data. Most hledger commands accept query arguments, to+restrict their scope. Multiple query terms can be provided to build up+a more complex query.++ * By default, a query term is interpreted as a case-insensitive+ substring pattern for matching account names:++ 'car:fuel'+ 'dining groceries'++ * Patterns containing spaces or other special characters must be+ enclosed in single or double quotes:++ ''personal care''++ * These patterns are actually regular expressions, so you can add+ regexp metacharacters for more precision (see "Regular expressions"+ above for details):++ ''^expenses\b''+ ''food$''+ ''fuel|repair''+ ''accounts (payable|receivable)''++ * To match something other than account name, add one of the query+ type prefixes described in "Query types" below:++ 'date:202312-'+ 'status:'+ 'desc:amazon'+ 'cur:USD'+ 'cur:\\$'+ 'amt:'>0''++ * Add a 'not:' prefix to negate a term:++ 'not:status:'*''+ 'not:desc:'opening|closing''+ 'not:cur:USD'++ * Terms with different types are AND-ed, terms with the same type are+ OR-ed (mostly; see "Combining query terms" below). The following+ query:++ 'date:2022 desc:amazon desc:amzn'++ is interpreted as:++ _date is in 2022 AND ( transaction description contains "amazon" OR+ "amzn" )_++* Menu:++* Query types::+* Combining query terms::+* Queries and command options::+* Queries and account aliases::+* Queries and valuation::+++File: hledger.info, Node: Query types, Next: Combining query terms, Up: Queries++17.1 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'* or *'REGEX'*+Match account names containing this case insensitive regular expression.+This is the default query type, so we usually don't bother writing the+"acct:" prefix.++ *'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.+Otherwise, the absolute magnitudes are compared, ignoring sign.++ *'code:REGEX'*+Match by transaction code (eg check number).++ *'cur:REGEX'*+Match postings or transactions including any amounts whose+currency/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.++ *'expr:"TERM AND NOT (TERM OR TERM)"'* (eg)+Match with a boolean combination of queries (which must be enclosed in+quotes). See Combining query terms below.++ *'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.++ *'type:TYPECODES'*+Match by account type (see Declaring accounts > Account types).+'TYPECODES' is one or more of the single-letter account type codes+'ALERXCV', case insensitive. Note 'type:A' and 'type:E' will also match+their respective subtypes 'C' (Cash) and 'V' (Conversion). Certain+kinds of account alias can disrupt account types, see Rewriting accounts+> Aliases and account types.++ *'tag:REGEX[=REGEX]'*+Match by tag name, and optionally also by tag value. (To match only by+value, use 'tag:.=REGEX'.)++ When querying by tag, note that:++ * Accounts also inherit the tags of their parent accounts+ * Postings also inherit the tags of their account and their+ transaction+ * Transactions also acquire the tags of their postings.++ (*'inacct:ACCTNAME'*+A special query term used automatically in hledger-web only: tells+hledger-web to show the transaction register for an account.)+++File: hledger.info, Node: Combining query terms, Next: Queries and command options, Prev: Query types, Up: Queries++17.2 Combining query terms+==========================++When given multiple space-separated query terms, most commands select+things which match:++ * any of the description terms AND+ * any of the account terms AND+ * any of the status terms AND+ * all the other terms.++ The print command is a little different, showing transactions which:++ * match any of the description terms AND+ * have any postings matching any of the positive account terms AND+ * have no postings matching any of the negative account terms AND+ * match all the other terms.++ We also support more complex boolean queries with the 'expr:' prefix.+This allows one to combine query terms using 'and', 'or', 'not' keywords+(case insensitive), and to group them by enclosing in parentheses.++ Some examples:++ * Exclude account names containing 'food':++ 'expr:"not food"' ('not:food' is equivalent)++ * Match things which have 'cool' in the description and the 'A' tag:++ 'expr:"desc:cool and tag:A"' ('expr:"desc:cool tag:A"' is+ equivalent)++ * Match things which either do not reference the 'expenses:food'+ account, or do have the 'A' tag:++ 'expr:"not expenses:food or tag:A"'++ * Match things which either do not reference the 'expenses:food'+ account, or which reference the 'expenses:drink' account and also+ have the 'A' tag:++ 'expr:"expenses:food or (expenses:drink and tag:A)"'++ 'expr:' has a restriction: 'date:' queries may not be used inside+'or' expressions. That would allow disjoint report periods or disjoint+result sets, with unclear semantics for our reports.+++File: hledger.info, Node: Queries and command options, Next: Queries and account aliases, Prev: Combining query terms, Up: Queries++17.3 Queries and command options+================================++Some queries can also be expressed as command-line options: 'depth:2' is+equivalent to '--depth 2', 'date:2023' is equivalent to '-p 2023', etc.+When you mix command options and query arguments, generally the+resulting query is their intersection.+++File: hledger.info, Node: Queries and account aliases, Next: Queries and valuation, Prev: Queries and command options, Up: Queries++17.4 Queries and account aliases+================================++When account names are rewritten with '--alias' or 'alias', 'acct:' will+match either the old or the new account name.+++File: hledger.info, Node: Queries and valuation, Prev: Queries and account aliases, Up: Queries++17.5 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, #1625.)+++File: hledger.info, Node: Pivoting, Next: Generating data, Prev: Queries, Up: Top++18 Pivoting+***********++Normally, hledger groups and sums amounts within each account. The+'--pivot FIELD' option substitutes some other transaction field for+account names, causing amounts to be grouped and summed by that field's+value instead. FIELD can be any of the transaction fields 'acct',+'status', 'code', 'desc', 'payee', 'note', or a tag name. When pivoting+on a tag and a posting has multiple values of that tag, only the first+value is displayed. Values containing 'colon:separated:parts' will be+displayed hierarchically, like account names. Multiple, colon-delimited+fields can be pivoted simultaneously, generating a hierarchical account+name.++ Some examples:++2016/02/16 Yearly Dues Payment+ assets:bank account 2 EUR+ income:dues -2 EUR ; member: John Doe, kind: Lifetime++ Normal balance report showing account names:++$ hledger balance+ 2 EUR assets:bank account+ -2 EUR income:dues+--------------------+ 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):++$ 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++ Hierarchical reports can be generated with multiple pivots:++$ hledger balance Income:Dues --pivot kind:member+ -2 EUR Lifetime:John Doe+--------------------+ -2 EUR+++File: hledger.info, Node: Generating data, Next: Forecasting, Prev: Pivoting, Up: Top++19 Generating data+******************++hledger has several features for generating data, such as:++ * Periodic transaction rules can generate single or repeating+ transactions following a template. These are usually dated in the+ future, eg to help with forecasting. They are activated by the+ '--forecast' option.++ * The balance command's '--budget' option uses these same periodic+ rules to generate goals for the budget report.++ * Auto posting rules can generate extra postings on certain matched+ transactions. They are always applied to forecast transactions;+ with the '--auto' flag they are applied to transactions recorded in+ the journal as well.++ * The '--infer-equity' flag infers missing conversion equity postings+ from @/@@ costs. And the inverse '--infer-costs' flag infers+ missing @/@@ costs from conversion equity postings.++ Generated data of this kind is temporary, existing only at report+time. But you can see it in the output of 'hledger print', and you can+save that to your journal, in effect converting it from temporary+generated data to permanent recorded data. This could be useful as a+data entry aid.++ If you are wondering what data is being generated and why, add the+'--verbose-tags' flag. In 'hledger print' output you will see extra+tags like 'generated-transaction', 'generated-posting', and 'modified'+on generated/modified data. Also, even without '--verbose-tags',+generated data always has equivalen hidden tags (with an underscore+prefix), so eg you could match generated transactions with+'tag:_generated-transaction'.+++File: hledger.info, Node: Forecasting, Next: Budgeting, Prev: Generating data, Up: Top++20 Forecasting+**************++Forecasting, or speculative future reporting, can be useful for+estimating future balances, or for exploring different future scenarios.++ The simplest and most flexible way to do it with hledger is to+manually record a bunch of future-dated transactions. You could keep+these in a separate 'future.journal' and include that with '-f' only+when you want to see them.++* Menu:++* --forecast::+* Inspecting forecast transactions::+* Forecast reports::+* Forecast tags::+* Forecast period in detail::+* Forecast troubleshooting::+++File: hledger.info, Node: --forecast, Next: Inspecting forecast transactions, Up: Forecasting++20.1 -forecast+==============++There is another way: with the '--forecast' option, hledger can generate+temporary "forecast transactions" for reporting purposes, according to+periodic transaction rules defined in the journal. Each rule can+generate multiple recurring transactions, so by changing one rule you+can change many forecasted transactions.++ Forecast transactions usually start after ordinary transactions end.+By default, they begin after your latest-dated ordinary transaction, or+today, whichever is later, and they end six months from today. (The+exact rules are a little more complicated, and are given below.)++ This is the "forecast period", which need not be the same as the+report period. You can override it - eg to forecast farther into the+future, or to force forecast transactions to overlap your ordinary+transactions - by giving the -forecast option a period expression+argument, like '--forecast=..2099' or '--forecast=2023-02-15..'. Note+that the '=' is required.+++File: hledger.info, Node: Inspecting forecast transactions, Next: Forecast reports, Prev: --forecast, Up: Forecasting++20.2 Inspecting forecast transactions+=====================================++'print' is the best command for inspecting and troubleshooting forecast+transactions. Eg:++~ monthly from 2022-12-20 rent+ assets:bank:checking+ expenses:rent $1000++$ hledger print --forecast --today=2023/4/21+2023-05-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++2023-06-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++2023-07-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++2023-08-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++2023-09-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ Here there are no ordinary transactions, so the forecasted+transactions begin on the first occurence after today's date. (You+won't normally use '--today'; it's just to make these examples+reproducible.)+++File: hledger.info, Node: Forecast reports, Next: Forecast tags, Prev: Inspecting forecast transactions, Up: Forecasting++20.3 Forecast reports+=====================++Forecast transactions affect all reports, as you would expect. Eg:++$ hledger areg rent --forecast --today=2023/4/21+Transactions in expenses:rent and subaccounts:+2023-05-20 rent as:ba:checking $1000 $1000+2023-06-20 rent as:ba:checking $1000 $2000+2023-07-20 rent as:ba:checking $1000 $3000+2023-08-20 rent as:ba:checking $1000 $4000+2023-09-20 rent as:ba:checking $1000 $5000++$ hledger bal -M expenses --forecast --today=2023/4/21+Balance changes in 2023-05-01..2023-09-30:++ || May Jun Jul Aug Sep +===============++===================================+ expenses:rent || $1000 $1000 $1000 $1000 $1000 +---------------++-----------------------------------+ || $1000 $1000 $1000 $1000 $1000 +++File: hledger.info, Node: Forecast tags, Next: Forecast period in detail, Prev: Forecast reports, Up: Forecasting++20.4 Forecast tags+==================++Forecast transactions generated by -forecast have a hidden tag,+'_generated-transaction'. So if you ever need to match forecast+transactions, you could use 'tag:_generated-transaction' (or just+'tag:generated') in a query.++ For troubleshooting, you can add the '--verbose-tags' flag. Then,+visible 'generated-transaction' tags will be added also, so you can view+them with the 'print' command. Their value indicates which periodic+rule was responsible.+++File: hledger.info, Node: Forecast period in detail, Next: Forecast troubleshooting, Prev: Forecast tags, Up: Forecasting++20.5 Forecast period, in detail+===============================++Forecast start/end dates are chosen so as to do something useful by+default in almost all situations, while also being flexible. Here are+(with luck) the exact rules, to help with troubleshooting:++ The forecast period starts on:++ * the later of+ * the start date in the periodic transaction rule+ * the start date in '--forecast''s argument++ * otherwise (if those are not available): the later of+ * the report start date specified with '-b'/'-p'/'date:'+ * the day after the latest ordinary transaction in the journal++ * otherwise (if none of these are available): today.++ The forecast period ends on:++ * the earlier of+ * the end date in the periodic transaction rule+ * the end date in '--forecast''s argument++ * otherwise: the report end date specified with '-e'/'-p'/'date:'+ * otherwise: 180 days (~6 months) from today.+++File: hledger.info, Node: Forecast troubleshooting, Prev: Forecast period in detail, Up: Forecasting++20.6 Forecast troubleshooting+=============================++When -forecast is not doing what you expect, one of these tips should+help:++ * Remember to use the '--forecast' option.+ * Remember to have at least one periodic transaction rule in your+ journal.+ * Test with 'print --forecast'.+ * Check for typos or too-restrictive start/end dates in your periodic+ transaction rule.+ * Leave at least 2 spaces between the rule's period expression and+ description fields.+ * Check for future-dated ordinary transactions suppressing forecasted+ transactions.+ * Try setting explicit report start and/or end dates with '-b', '-e',+ '-p' or 'date:'+ * Try adding the '-E' flag to encourage display of empty periods/zero+ transactions.+ * Try setting explicit forecast start and/or end dates with+ '--forecast=START..END'+ * Consult Forecast period, in detail, above.+ * Check inside the engine: add '--debug=2' (eg).+++File: hledger.info, Node: Budgeting, Next: Cost reporting, Prev: Forecasting, Up: Top++21 Budgeting+************++With the balance command's '--budget' report, each periodic transaction+rule generates recurring budget goals in specified accounts, and goals+and actual performance can be compared. See the balance command's doc+below.++ You can generate budget goals and forecast transactions at the same+time, from the same or different periodic transaction rules: 'hledger+bal -M --budget --forecast ...'++ See also: Budgeting and Forecasting.+++File: hledger.info, Node: Cost reporting, Next: Value reporting, Prev: Budgeting, Up: Top++22 Cost reporting+*****************++In some transactions - for example a currency conversion, or a purchase+or sale of stock - one commodity is exchanged for another. In these+transactions there is a conversion rate, also called the cost (when+buying) or selling price (when selling). In hledger docs we just say+"cost", for convenience; feel free to mentally translate to "conversion+rate" or "selling price" if helpful.++* Menu:++* Recording costs::+* Reporting at cost::+* Equity conversion postings::+* Inferring equity conversion postings::+* Combining costs and equity conversion postings::+* Requirements for detecting equity conversion postings::+* Infer cost and equity by default ?::+++File: hledger.info, Node: Recording costs, Next: Reporting at cost, Up: Cost reporting++22.1 Recording costs+====================++We'll explore several ways of recording transactions involving costs.+These are also summarised at hledger Cookbook > Cost notation.++ Costs can be recorded explicitly in the journal, using the '@+UNITCOST' or '@@ TOTALCOST' notation described in Journal > Costs:++ *Variant 1*++2022-01-01+ assets:dollars $-135+ assets:euros €100 @ $1.35 ; $1.35 per euro (unit cost)++ *Variant 2*++2022-01-01+ assets:dollars $-135+ assets:euros €100 @@ $135 ; $135 total cost++ Typically, writing the unit cost (variant 1) is preferable; it can be+more effort, requiring more attention to decimal digits; but it reveals+the per-unit cost basis, and makes stock sales easier.++ Costs can also be left implicit, and hledger will infer the cost that+is consistent with a balanced transaction:++ *Variant 3*++2022-01-01+ assets:dollars $-135+ assets:euros €100++ Here, hledger will attach a '@@ €100' cost to the first amount (you+can see it with 'hledger print -x'). This form looks convenient, but+there are downsides:++ * It sacrifices some error checking. For example, if you+ accidentally wrote €10 instead of €100, hledger would not be able+ to detect the mistake.++ * It is sensitive to the order of postings - if they were reversed, a+ different entry would be inferred and reports would be different.++ * The per-unit cost basis is not easy to read.++ So generally this kind of entry is not recommended. You can make+sure you have none of these by using '-s' (strict mode), or by running+'hledger check balanced'.+++File: hledger.info, Node: Reporting at cost, Next: Equity conversion postings, Prev: Recording costs, Up: Cost reporting++22.2 Reporting at cost+======================++Now when you add the '-B'/'--cost' flag to reports ("B" is from Ledger's+-B/-basis/-cost flag), any amounts which have been annotated with costs+will be converted to their cost's commodity (in the report output). Ie+they will be displayed "at cost" or "at sale price".++ Some things to note:++ * Costs are attached to specific posting amounts in specific+ transactions, and once recorded they do not change. This contrasts+ with market prices, which are ambient and fluctuating.++ * Conversion to cost is performed before conversion to market value+ (described below).+++File: hledger.info, Node: Equity conversion postings, Next: Inferring equity conversion postings, Prev: Reporting at cost, Up: Cost reporting++22.3 Equity conversion postings+===============================++There is a problem with the entries above - they are not conventional+Double Entry Bookkeeping (DEB) notation, and because of the "magical"+transformation of one commodity into another, they cause an imbalance in+the Accounting Equation. This shows up as a non-zero grand total in+balance reports like 'hledger bse'.++ For most hledger users, this doesn't matter in practice and can+safely be ignored ! But if you'd like to learn more, keep reading.++ Conventional DEB uses an extra pair of equity postings to balance the+transaction. Of course you can do this in hledger as well:++ *Variant 4*++2022-01-01+ assets:dollars $-135+ assets:euros €100+ equity:conversion $135+ equity:conversion €-100++ Now the transaction is perfectly balanced according to standard DEB,+and 'hledger bse''s total will not be disrupted.++ And, hledger can still infer the cost for cost reporting, but it's+not done by default - you must add the '--infer-costs' flag like so:++$ hledger print --infer-costs+2022-01-01 one hundred euros purchased at $1.35 each+ assets:dollars $-135 @@ €100+ assets:euros €100+ equity:conversion $135+ equity:conversion €-100++$ hledger bal --infer-costs -B+ €-100 assets:dollars + €100 assets:euros +-------------------- + 0 ++ Here are some downsides of this kind of entry:++ * The per-unit cost basis is not easy to read.++ * Instead of '-B' you must remember to type '-B --infer-costs'.++ * '--infer-costs' works only where hledger can identify the two+ equity:conversion postings and match them up with the two+ non-equity postings. So writing the journal entry in a particular+ format becomes more important. More on this below.+++File: hledger.info, Node: Inferring equity conversion postings, Next: Combining costs and equity conversion postings, Prev: Equity conversion postings, Up: Cost reporting++22.4 Inferring equity conversion postings+=========================================++Can we go in the other direction ? Yes, if you have transactions+written with the @/@@ cost notation, hledger can infer the missing+equity postings, if you add the '--infer-equity' flag. Eg:++2022-01-01+ assets:dollars -$135+ assets:euros €100 @ $1.35++$ hledger print --infer-equity+2022-01-01+ assets:dollars $-135+ assets:euros €100 @ $1.35+ equity:conversion:$-€:€ €-100+ equity:conversion:$-€:$ $135.00++ The equity account names will be "equity:conversion:A-B:A" and+"equity:conversion:A-B:B" where A is the alphabetically first commodity+symbol. You can customise the "equity:conversion" part by declaring an+account with the 'V'/'Conversion' account type.+++File: hledger.info, Node: Combining costs and equity conversion postings, Next: Requirements for detecting equity conversion postings, Prev: Inferring equity conversion postings, Up: Cost reporting++22.5 Combining costs and equity conversion postings+===================================================++Finally, you can use both the @/@@ cost notation and equity postings at+the same time. This in theory gives the best of all worlds - preserving+the accounting equation, revealing the per-unit cost basis, and+providing more flexibility in how you write the entry:++ *Variant 5*++2022-01-01 one hundred euros purchased at $1.35 each+ assets:dollars $-135+ equity:conversion $135+ equity:conversion €-100+ assets:euros €100 @ $1.35++ All the other variants above can (usually) be rewritten to this final+form with:++$ hledger print -x --infer-costs --infer-equity++ Downsides:++ * The precise format of the journal entry becomes more important. If+ hledger can't detect and match up the cost and equity postings, it+ will give a transaction balancing error.++ * The add command does not yet accept this kind of entry (#2056).++ * This is the most verbose form.+++File: hledger.info, Node: Requirements for detecting equity conversion postings, Next: Infer cost and equity by default ?, Prev: Combining costs and equity conversion postings, Up: Cost reporting++22.6 Requirements for detecting equity conversion postings+==========================================================++'--infer-costs' has certain requirements (unlike '--infer-equity', which+always works). It will infer costs only in transactions with:++ * Two non-equity postings, in different commodities. Their order is+ significant: the cost will be added to the first of them.++ * Two postings to equity conversion accounts, next to one another,+ which balance the two non-equity postings. This balancing is+ checked to the same precision (number of decimal places) used in+ the conversion posting's amount. Equity conversion accounts are:++ * any accounts declared with account type 'V'/'Conversion', or+ their subaccounts+ * otherwise, accounts named 'equity:conversion', 'equity:trade',+ or 'equity:trading', or their subaccounts.++ And multiple such four-posting groups can coexist within a single+transaction. When '--infer-costs' fails, it does not infer a cost in+that transaction, and does not raise an error (ie, it infers costs where+it can).++ Reading variant 5 journal entries, combining cost notation and equity+postings, has all the same requirements. When reading such an entry+fails, hledger raises an "unbalanced transaction" error.+++File: hledger.info, Node: Infer cost and equity by default ?, Prev: Requirements for detecting equity conversion postings, Up: Cost reporting++22.7 Infer cost and equity by default ?+=======================================++Should '--infer-costs' and '--infer-equity' be enabled by default ? Try+using them always, eg with a shell alias:++alias h="hledger --infer-equity --infer-costs"++ and let us know what problems you find.+++File: hledger.info, Node: Value reporting, Next: PART 4 COMMANDS, Prev: Cost reporting, Up: Top++23 Value reporting+******************++Instead of reporting amounts in their original commodity, hledger can+convert them to cost/sale amount (using the conversion rate recorded in+the transaction), and/or to market value (using some market price on a+certain date). This is controlled by the '--value=TYPE[,COMMODITY]'+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:++* Menu:++* -V Value::+* -X Value in specified commodity::+* Valuation date::+* Finding market price::+* --infer-market-prices market prices from transactions::+* Valuation commodity::+* --value Flexible valuation::+* Valuation examples::+* Interaction of valuation and queries::+* Effect of valuation on reports::+++File: hledger.info, Node: -V Value, Next: -X Value in specified commodity, Up: Value reporting++23.1 -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.+++File: hledger.info, Node: -X Value in specified commodity, Next: Valuation date, Prev: -V Value, Up: Value reporting++23.2 -X: Value in specified commodity+=====================================++The '-X/--exchange=COMM' option is like '-V', except you tell it which+currency you want to convert to, and it tries to convert everything to+that.+++File: hledger.info, Node: Valuation date, Next: Finding market price, Prev: -X Value in specified commodity, Up: Value reporting++23.3 Valuation date+===================++Market prices can change from day to day. hledger will use the prices+on a particular valuation date (or on more than one date). By default+hledger uses "end" dates for valuation. More specifically:++ * For single period reports (including normal print and register+ reports):+ * If an explicit report end date is specified, that is used+ * Otherwise the latest transaction date or P directive date is+ used (even if it's in the future)++ * For multiperiod reports, each period is valued on its last day.++ This can be customised with the -value option described below, which+can select either "then", "end", "now", or "custom" dates. (Note, this+has a bug in hledger-ui <=1.31: turning on valuation with the 'V' key+always resets it to "end".)+++File: hledger.info, Node: Finding market price, Next: --infer-market-prices market prices from transactions, Prev: Valuation date, Up: Value reporting++23.4 Finding market price+=========================++To convert a commodity A to its market value in another commodity B,+hledger looks for a suitable market price (exchange rate) as follows, 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 directive, or (with the '--infer-market-prices' flag) inferred+ from costs.++ 2. A _reverse market price_: the inverse of a declared or inferred+ market price from B to A.++ 3. A _forward chain of market prices_: a synthetic price formed by+ combining 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+converted.+++File: hledger.info, Node: --infer-market-prices market prices from transactions, Next: Valuation commodity, Prev: Finding market price, Up: Value reporting++23.5 -infer-market-prices: 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 costs as additional market prices (as+Ledger does) ? Adding the '--infer-market-prices' flag to '-V', '-X' or+'--value' enables this.++ So for example, 'hledger bs -V --infer-market-prices' will get market+prices both from P directives and from transactions. If both occur on+the same day, the P directive takes precedence.++ There is a downside: value reports can sometimes be affected in+confusing/undesired ways by your journal entries. If this happens to+you, read all of this Value reporting section carefully, and try adding+'--debug' or '--debug=2' to troubleshoot.++ '--infer-market-prices' can infer market prices from:++ * multicommodity transactions with explicit prices ('@'/'@@')++ * multicommodity transactions with implicit prices (no '@', two+ commodities, unbalanced). (With these, the order of postings+ matters. 'hledger print -x' can be useful for troubleshooting.)++ * multicommodity transactions with equity postings, if cost is+ inferred with '--infer-costs'.++ There is a limitation (bug) currently: when a valuation commodity is+not specified, prices inferred with '--infer-market-prices' do not help+select a default valuation commodity, as 'P' prices would. So+conversion might not happen because no valuation commodity was detected+('--debug=2' will show this). To be safe, specify the valuation+commmodity, eg:++ * '-X EUR --infer-market-prices', not '-V --infer-market-prices'+ * '--value=then,EUR --infer-market-prices', not '--value=then+ --infer-market-prices'++ Signed costs and market prices can be confusing. For reference, here+is the current behaviour, since hledger 1.25. (If you think it should+work differently, see #1870.)++2022-01-01 Positive Unit prices+ a A 1+ b B -1 @ A 1++2022-01-01 Positive Total prices+ a A 1+ b B -1 @@ A 1+++2022-01-02 Negative unit prices+ a A 1+ b B 1 @ A -1++2022-01-02 Negative total prices+ a A 1+ b B 1 @@ A -1+++2022-01-03 Double Negative unit prices+ a A -1+ b B -1 @ A -1++2022-01-03 Double Negative total prices+ a A -1+ b B -1 @@ A -1++ All of the transactions above are considered balanced (and on each+day, the two transactions are considered equivalent). Here are the+market prices inferred for B:++$ hledger -f- --infer-market-prices prices+P 2022-01-01 B A 1+P 2022-01-01 B A 1.0+P 2022-01-02 B A -1+P 2022-01-02 B A -1.0+P 2022-01-03 B A -1+P 2022-01-03 B A -1.0+++File: hledger.info, Node: Valuation commodity, Next: --value Flexible valuation, Prev: --infer-market-prices market prices from transactions, Up: Value reporting++23.6 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+suitable 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-prices' flag is used: the price commodity from the+ latest transaction-inferred price for A on or before valuation+ date.++ This means:++ * If you have P directives, they determine which commodities '-V'+ will convert, and to what.++ * If you have no P directives, and use the '--infer-market-prices'+ flag, costs determine it.++ Amounts for which no valuation commodity can be found are not+converted.+++File: hledger.info, Node: --value Flexible valuation, Next: Valuation examples, Prev: Valuation commodity, Up: Value reporting++23.7 -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 commodity,+ using market prices on each posting's date.+'--value=end'++ Convert amounts to their value in the default valuation commodity,+ using market prices on the last day of the report period (or if+ unspecified, the journal'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 commodity+ using current market prices (as of when report is generated).+'--value=YYYY-MM-DD'++ Convert amounts to their value in the default valuation commodity+ 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.+++File: hledger.info, Node: Valuation examples, Next: Interaction of valuation and queries, Prev: --value Flexible valuation, Up: Value reporting++23.8 Valuation examples+=======================++Here are some quick examples of '-V':++; one euro is worth this many dollars from nov 1+P 2016/11/01 € $1.10++; purchase some euros on nov 3+2016/11/3+ assets:euros €100+ assets:checking++; the euro is worth fewer dollars by dec 21+P 2016/12/21 € $1.03++ How many euros do I have ?++$ hledger -f t.j bal -N euros+ €100 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++ 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+++File: hledger.info, Node: Interaction of valuation and queries, Next: Effect of valuation on reports, Prev: Valuation examples, Up: Value reporting++23.9 Interaction of valuation and queries+=========================================++When matching postings based on queries in the presence of valuation,+the following happens:++ 1. The query is separated into two parts:+ 1. the currency ('cur:') or amount ('amt:').+ 2. all other parts.++ 2. The postings are matched to the currency and amount queries based+ on pre-valued amounts.+ 3. Valuation is applied to the postings.+ 4. The postings are matched to the other parts of the query based on+ post-valued amounts.++ Related: #1625+++File: hledger.info, Node: Effect of valuation on reports, Prev: Interaction of valuation and queries, Up: Value reporting++23.10 Effect of valuation on reports+====================================++Here is a reference for how valuation is supposed to affect each part of+hledger's reports. (It's wide, you may need to scroll sideways.) It+may be useful when troubleshooting. If you find problems, please report+them, ideally with a reproducible example. Related: #329, #1083.++ First, a quick 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+ subperiods).++Report '-B', '-V', '-X' '--value=then' '--value=end''--value=DATE',+type '--cost' '--value=now'+------------------------------------------------------------------------------+*print*+posting cost value at value at posting value at value+amounts report end date report or at+ or today journal DATE/today+ end+balance unchanged unchanged unchanged unchanged unchanged+assertions/assignments+*register*+starting cost value at valued at day value at value+balance report or each historical report or at+(-H) journal posting was made journal DATE/today+ end end+starting cost value at valued at day value at value+balance day before each historical day before at+(-H) report or posting was made report or DATE/today+with journal journal+report start start+interval+posting cost value at value at posting value at value+amounts report or date report or at+ journal journal DATE/today+ end end+summary summarised value at sum of postings value at value+posting cost period in interval, period at+amounts ends valued at ends DATE/today+with interval start+report+interval+running sum/average sum/average sum/average of sum/average sum/average+total/averageof of displayed values of of+ displayed displayed displayed displayed+ values values values values+*balance+(bs,+bse, cf,+is)*+balance sums of value at value at posting value at value+changes costs report end date report or at+ or today journal DATE/today+ of sums of end of of+ postings sums of sums+ postings of+ postings+budget like like like balance like like+amounts balance balance changes balances balance+(-budget) changes changes changes+grand sum of sum of sum of displayed sum of sum of+total displayed displayed valued displayed displayed+ values values values values+*balance+(bs,+bse, cf,+is) with+report+interval*+starting sums of value at sums of values value at sums+balances costs of report of postings report of+(-H) postings start of before report start of postings+ before sums of start at sums of before+ report all respective all report+ start postings posting dates postings start+ before before+ report report+ start start+balance sums of same as sums of values balance value+changes costs of -value=end of postings in change in at+(bal, postings period at each DATE/today+is, bs in period respective period, of+-change, posting dates valued at sums+cf period of+-change) ends postings+end sums of same as sums of values period end value+balances costs of -value=end of postings from balances, at+(bal -H, postings before period valued at DATE/today+is -H, from start to period period of+bs, cf) before end at ends sums+ report respective of+ start to posting dates postings+ period end+budget like like like balance like like+amounts balance balance changes/end balances balance+(-budget) changes/end changes/end balances changes/end+ balances balances balances+row sums, sums, sums, averages sums, sums,+totals, averages averages of displayed averages averages+row of of values of of+averages displayed displayed displayed displayed+(-T, -A) values values values values+column sums of sums of sums of sums of sums+totals displayed displayed displayed values displayed of+ values values values displayed+ values+grand sum, sum, sum, average of sum, sum,+total, average of average of column totals average of average+grand column column column of+average totals totals totals column+ totals++ '--cumulative' is omitted to save space, it works like '-H' but with+a zero starting balance.+++File: hledger.info, Node: PART 4 COMMANDS, Next: PART 5 COMMON TASKS, Prev: Value reporting, Up: Top++24 PART 4: COMMANDS+*******************++* Menu:++* Commands overview::+* accounts::+* activity::+* add::+* aregister::+* balance::+* balancesheet::+* balancesheetequity::+* cashflow::+* check::+* close::+* codes::+* commodities::+* demo::+* descriptions::+* diff::+* files::+* help::+* import::+* incomestatement::+* notes::+* payees::+* prices::+* print::+* register::+* rewrite::+* roi::+* stats::+* tags::+* test::+++File: hledger.info, Node: Commands overview, Next: accounts, Up: PART 4 COMMANDS++24.1 Commands overview+======================++Here are the built-in commands:++* Menu:++* DATA ENTRY::+* DATA CREATION::+* DATA MANAGEMENT::+* REPORTS FINANCIAL::+* REPORTS VERSATILE::+* REPORTS BASIC::+* HELP::+* ADD-ONS::+++File: hledger.info, Node: DATA ENTRY, Next: DATA CREATION, Up: Commands overview++24.1.1 DATA ENTRY+-----------------++These data entry commands are the only ones which can modify your+journal file.++ * add - add transactions using terminal prompts+ * import - add new transactions from other files, eg CSV files+++File: hledger.info, Node: DATA CREATION, Next: DATA MANAGEMENT, Prev: DATA ENTRY, Up: Commands overview++24.1.2 DATA CREATION+--------------------++ * close - generate balance-zeroing/restoring transactions+ * rewrite - generate auto postings, like print -auto+++File: hledger.info, Node: DATA MANAGEMENT, Next: REPORTS FINANCIAL, Prev: DATA CREATION, Up: Commands overview++24.1.3 DATA MANAGEMENT+----------------------++ * check - check for various kinds of error in the data+ * diff - compare account transactions in two journal files+++File: hledger.info, Node: REPORTS FINANCIAL, Next: REPORTS VERSATILE, Prev: DATA MANAGEMENT, Up: Commands overview++24.1.4 REPORTS, FINANCIAL+-------------------------++ * aregister (areg) - show transactions in a particular account+ * balancesheet (bs) - show assets, liabilities and net worth+ * balancesheetequity (bse) - show assets, liabilities and equity+ * cashflow (cf) - show changes in liquid assets+ * incomestatement (is) - show revenues and expenses+++File: hledger.info, Node: REPORTS VERSATILE, Next: REPORTS BASIC, Prev: REPORTS FINANCIAL, Up: Commands overview++24.1.5 REPORTS, VERSATILE+-------------------------++ * balance (bal) - show balance changes, end balances, budgets,+ gains..+ * print - show transactions or export journal data+ * register (reg) - show postings in one or more accounts & running+ total+ * roi - show return on investments+++File: hledger.info, Node: REPORTS BASIC, Next: HELP, Prev: REPORTS VERSATILE, Up: Commands overview++24.1.6 REPORTS, BASIC+---------------------++ * accounts - show account names+ * activity - show bar charts of posting counts per period+ * codes - show transaction codes+ * commodities - show commodity/currency symbols+ * descriptions - show transaction descriptions+ * files - show input file paths+ * notes - show note parts of transaction descriptions+ * payees - show payee parts of transaction descriptions+ * prices - show market prices+ * stats - show journal statistics+ * tags - show tag names+ * test - run self tests+++File: hledger.info, Node: HELP, Next: ADD-ONS, Prev: REPORTS BASIC, Up: Commands overview++24.1.7 HELP+-----------++ * help - show the hledger manual with info/man/pager+ * demo - show small hledger demos in the terminal+++File: hledger.info, Node: ADD-ONS, Prev: HELP, Up: Commands overview++24.1.8 ADD-ONS+--------------++And here are some typical add-on commands. Some of these are installed+by the hledger-install script. If installed, they will appear in+hledger's commands list:++ * ui - run hledger's terminal UI+ * web - run hledger's web UI+ * iadd - add transactions using a TUI (currently hard to build)+ * interest - generate interest transactions+ * stockquotes - download market prices from AlphaVantage+ * Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,+ pijul, plot, and more..++ Next, each command is described in detail, in alphabetical order.+++File: hledger.info, Node: accounts, Next: activity, Prev: Commands overview, Up: PART 4 COMMANDS++24.2 accounts+=============++Show account names.++ This command lists account names. By default it shows all known+accounts, either used in transactions or declared with account+directives.++ With query arguments, only matched account names and account names+referenced by matched postings are shown.++ Or it can show just the used accounts ('--used'/'-u'), the declared+accounts ('--declared'/'-d'), the accounts declared but not used+('--unused'), the accounts used but not declared ('--undeclared'), or+the first account matched by an account name pattern, if any ('--find').++ It shows a flat list by default. With '--tree', it uses indentation+to show the account hierarchy. In flat mode you can add '--drop N' to+omit the first few account name components. Account names can be+depth-clipped with 'depth:N' or '--depth N' or '-N'.++ With '--types', it also shows each account's type, if it's known.+(See Declaring accounts > Account types.)++ With '--positions', it also shows the file and line number of each+account's declaration, if any, and the account's overall declaration+order; these may be useful when troubleshooting account display order.++ With '--directives', it adds the 'account' keyword, showing valid+account directives which can be pasted into a journal file. This is+useful together with '--undeclared' when updating your account+declarations to satisfy 'hledger check accounts'.++ The '--find' flag can be used to look up a single account name, in+the same way that the 'aregister' command does. It returns the+alphanumerically-first matched account name, or if none can be found, it+fails with a non-zero exit code.++ Examples:++$ hledger accounts+assets:bank:checking+assets:bank:saving+assets:cash+expenses:food+expenses:supplies+income:gifts+income:salary+liabilities:debts++$ hledger accounts --undeclared --directives >> $LEDGER_FILE+$ hledger check accounts+++File: hledger.info, Node: activity, Next: add, Prev: accounts, Up: PART 4 COMMANDS++24.3 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 **+++File: hledger.info, Node: add, Next: aregister, Prev: activity, Up: PART 4 COMMANDS++24.4 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+transactions, and appends them to the main journal file (which should be+in journal format). Existing transactions are not changed. This is one+of the few hledger commands that writes to the journal file (see also+'import').++ To use it, just run 'hledger add' and follow the prompts. You can+add as many transactions as you like; when you are finished, enter '.'+or press control-d or control-c to exit.++ Features:++ * add tries to provide useful defaults, using the most similar (by+ description) recent transaction (filtered by the query, if any) as+ a template.+ * You can also set the initial defaults with command line arguments.+ * Readline-style edit keys can be used during data entry.+ * The tab key will auto-complete whenever possible - accounts,+ payees/descriptions, dates ('yesterday', 'today', 'tomorrow'). If+ the input area is empty, it will insert the default value.+ * If the journal defines a default commodity, it will be added to any+ bare numbers entered.+ * A parenthesised transaction code may be entered following a date.+ * Comments and tags may be entered following a description or amount.+ * If you make a mistake, enter '<' at any prompt to go one step+ backward.+ * Input prompts are displayed in a different colour when the terminal+ supports it.++ Example (see https://hledger.org/add.html for a detailed tutorial):++$ 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> $++ If you enter a number with no commodity symbol, and you have declared+a default commodity with a 'D' directive, you might expect 'add' to add+this symbol for you. It does not do this; we assume that if you are+using a 'D' directive you prefer not to see the commodity symbol+repeated on amounts in the journal.+++File: hledger.info, Node: aregister, Next: balance, Prev: add, Up: PART 4 COMMANDS++24.5 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 'aregister' 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.++ When there are multiple matches, the alphabetically-first choice can+be surprising; eg if you have 'assets:per:checking 1' and+'assets:biz:checking 2' accounts, 'hledger areg checking' would select+'assets:biz:checking 2'. It's just a convenience to save typing, so if+in doubt, write the full account name, or a distinctive substring that+matches uniquely.++ 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. 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, see below)+ * the names of all the other account(s) involved in this transaction+ (probably abbreviated)+ * the total change to this account's balance from this transaction+ * 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.++ For performance reasons, column widths are chosen based on the first+1000 lines; this means unusually wide values in later lines can cause+visual discontinuities as column widths are adjusted. If you want to+ensure perfect alignment, at the cost of more time and memory, use the+'--align-all' flag.++ This command also supports the output destination and output format+options. The output formats supported are 'txt', 'csv', 'tsv' (_Added+in 1.32_), and 'json'.++* Menu:++* aregister and posting dates::+++File: hledger.info, Node: aregister and posting dates, Up: aregister++24.5.1 aregister and posting dates+----------------------------------++aregister always shows one line (and date and amount) per transaction.+But sometimes transactions have postings with different dates. Also,+not all of a transaction's postings may be within the report period. To+resolve this, aregister shows the earliest of the transaction's date and+posting dates that is in-period, and the sum of the in-period postings.+In other words it will show a combined line item with just the earliest+date, and the running balance will (temporarily, until the transaction's+last posting) be inaccurate. Use 'register -H' if you need to see the+individual postings.++ There is also a '--txn-dates' flag, which filters strictly by+transaction date, ignoring posting dates. This too can cause an+inaccurate running balance.+++File: hledger.info, Node: balance, Next: balancesheet, Prev: aregister, Up: PART 4 COMMANDS++24.6 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',+'balancesheetequity', 'cashflow' and 'incomestatement'. When you need+more control, then use 'balance'.++* Menu:++* balance features::+* Simple balance report::+* Balance report line format::+* Filtered balance report::+* List or tree mode::+* Depth limiting::+* Dropping top-level accounts::+* Showing declared accounts::+* Sorting by amount::+* Percentages::+* Multi-period balance report::+* Balance change end balance::+* Balance report types::+* Budget report::+* Balance report layout::+* Some useful balance reports::+++File: hledger.info, Node: balance features, Next: Simple balance report, Up: balance++24.6.1 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..++ * accounts as a list ('-l') or a tree ('-t')+ * optionally depth-limited ('-[1-9]')+ * sorted by declaration order and name, or by amount++ ..and their..++ * balance changes (the default)+ * or actual and planned balance changes ('--budget')+ * or value of balance changes ('-V')+ * or change of balance values ('--valuechange')+ * or unrealised capital gain/loss ('--gain')+ * or balance changes from sibling postings ('--related'/'-r')+ * or postings count ('--count')++ ..in..++ * one time period (the whole journal period by default)+ * or multiple periods ('-D', '-W', '-M', '-Q', '-Y', '-p INTERVAL')++ ..either..++ * per period (the default)+ * or accumulated since report start date ('--cumulative')+ * or accumulated since account creation ('--historical/-H')++ ..possibly converted to..++ * cost ('--value=cost[,COMM]'/'--cost'/'-B')+ * or market value, as of transaction dates ('--value=then[,COMM]')+ * or at period ends ('--value=end[,COMM]')+ * or now ('--value=now')+ * or at some other date ('--value=YYYY-MM-DD')++ ..with..++ * totals ('-T'), averages ('-A'), percentages ('-%'), inverted sign+ ('--invert')+ * rows and columns swapped ('--transpose')+ * another field used as account name ('--pivot')+ * custom-formatted line items (single-period reports only)+ ('--format')+ * commodities displayed on the same line or multiple lines+ ('--layout')++ This command supports the output destination and output format+options, with output formats 'txt', 'csv', 'tsv' (_Added in 1.32_),+'json', and (multi-period reports only:) 'html'. In 'txt' output in a+colour-supporting terminal, negative amounts are shown in red.+++File: hledger.info, Node: Simple balance report, Next: Balance report line format, Prev: balance features, Up: balance++24.6.2 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. ("Simple" here+means just one column of numbers, covering a single period. You can+also have multi-period reports, described later.)++ For real-world accounts, these numbers will normally be their end+balance at the end of the journal period; more on this below.++ Accounts are sorted by declaration order if any, and then+alphabetically by account name. For instance (using+examples/sample.journal):++$ hledger -f examples/sample.journal bal+ $1 assets:bank:saving+ $-2 assets:cash+ $1 expenses:food+ $1 expenses:supplies+ $-1 income:gifts+ $-1 income:salary+ $1 liabilities:debts+--------------------+ 0 ++ 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.+++File: hledger.info, Node: Balance report line format, Next: Filtered balance report, Prev: Simple balance report, Up: balance++24.6.3 Balance report line format+---------------------------------++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 -f examples/sample.journal 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 specifies the formatting applied to each+account/balance pair. It may contain any suitable text, with data+fields interpolated like so:++ '%[MIN][.MAX](FIELDNAME)'++ * MIN pads with spaces to at least this width (optional)++ * MAX truncates at this width (optional)++ * FIELDNAME must be enclosed in parentheses, and can be one of:++ * 'depth_spacer' - a number of spaces equal to the account's+ depth, or if MIN is specified, MIN * depth spaces.+ * 'account' - the account's name+ * 'total' - the account's balance/posted total, right justified++ Also, FMT can begin with an optional prefix to control how+multi-commodity amounts are rendered:++ * '%_' - render on multiple lines, bottom-aligned (the default)+ * '%^' - render on multiple lines, top-aligned+ * '%,' - 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:++ * '%(total)' - the account's total+ * '%-20.20(account)' - the account's name, left justified, padded to+ 20 characters and clipped at 20 characters+ * '%,%-50(account) %25(total)' - account name padded to 50+ characters, total padded to 20 characters, with multiple+ commodities rendered on one line+ * '%20(total) %2(depth_spacer)%-(account)' - the default format for+ the single-column balance report+++File: hledger.info, Node: Filtered balance report, Next: List or tree mode, Prev: Balance report line format, Up: balance++24.6.4 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 -f examples/sample.journal bal --cleared assets date:200806+ $-2 assets:cash+--------------------+ $-2 +++File: hledger.info, Node: List or tree mode, Next: Depth limiting, Prev: Filtered balance report, Up: balance++24.6.5 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 -f examples/sample.journal balance+ $-1 assets+ $1 bank:saving+ $-2 cash+ $2 expenses+ $1 food+ $1 supplies+ $-2 income+ $-1 gifts+ $-1 salary+ $1 liabilities:debts+--------------------+ 0++ Notes:++ * "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).++ * 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-plaintextaccounting-users. A tree mode report's final total is+ the sum of the top-level balances shown, not of all the balances+ shown.++ * Each group of sibling accounts (ie, under a common parent) is+ sorted separately.+++File: hledger.info, Node: Depth limiting, Next: Dropping top-level accounts, Prev: List or tree mode, Up: balance++24.6.6 Depth limiting+---------------------++With a 'depth:NUM' query, or '--depth NUM' option, or just '-NUM' (eg:+'-3') balance reports will show accounts only to the specified depth,+hiding the deeper subaccounts. This can be useful for getting an+overview without too much detail.++ Account balances at the depth limit always include the balances from+any deeper subaccounts (even in list mode). Eg, limiting to depth 1:++$ hledger -f examples/sample.journal balance -1+ $-1 assets+ $2 expenses+ $-2 income+ $1 liabilities+--------------------+ 0 +++File: hledger.info, Node: Dropping top-level accounts, Next: Showing declared accounts, Prev: Depth limiting, Up: balance++24.6.7 Dropping top-level accounts+----------------------------------++You can also hide one or more top-level account name parts, using+'--drop NUM'. This can be useful for hiding repetitive top-level+account names:++$ hledger -f examples/sample.journal bal expenses --drop 1+ $1 food+ $1 supplies+--------------------+ $2 +++File: hledger.info, Node: Showing declared accounts, Next: Sorting by amount, Prev: Dropping top-level accounts, Up: balance++24.6.8 Showing declared accounts+--------------------------------++With '--declared', accounts which have been declared with an account+directive will be included in the balance report, even if they have no+transactions. (Since they will have a zero balance, you will also need+'-E/--empty' to see them.)++ More precisely, _leaf_ declared accounts (with no subaccounts) will+be included, since those are usually the more useful in reports.++ The idea of this is to be able to see a useful "complete" balance+report, even when you don't have transactions in all of your declared+accounts yet.+++File: hledger.info, Node: Sorting by amount, Next: Percentages, Prev: Showing declared accounts, Up: balance++24.6.9 Sorting by amount+------------------------++With '-S/--sort-amount', accounts with the largest (most positive)+balances are shown first. Eg: 'hledger bal expenses -MAS' shows your+biggest averaged monthly expenses first. When more than one commodity+is present, they will be sorted by the alphabetically earliest commodity+first, and then by subsequent commodities (if an amount is missing a+commodity, it is treated as 0).++ Revenues and liability balances are typically negative, however, so+'-S' shows these in reverse order. To work around this, you can add+'--invert' to flip the signs. (Or, use one of the higher-level reports,+which flip the sign automatically. Eg: 'hledger incomestatement -MAS').+++File: hledger.info, Node: Percentages, Next: Multi-period balance report, Prev: Sorting by amount, Up: balance++24.6.10 Percentages+-------------------++With '-%/--percent', balance reports show each account's value expressed+as a percentage of the (column) total.++ Note it is not useful to calculate percentages if the amounts in a+column 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:€+++File: hledger.info, Node: Multi-period balance report, Next: Balance change end balance, Prev: Percentages, Up: balance++24.6.11 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),+'balance' shows a tabular report, with columns representing successive+time periods (and a title):++$ hledger -f examples/sample.journal bal --quarterly income expenses -E+Balance changes in 2008:++ || 2008q1 2008q2 2008q3 2008q4 +===================++=================================+ expenses:food || 0 $1 0 0 + expenses:supplies || 0 $1 0 0 + income:gifts || 0 $-1 0 0 + income:salary || $-1 0 0 0 +-------------------++---------------------------------+ || $-1 $1 0 0 ++ Notes:++ * The report's start/end dates will be expanded, if necessary, to+ fully encompass the displayed subperiods (so that the first and+ last subperiods have the same duration as the others).+ * Leading and trailing periods (columns) containing all zeroes are+ not shown, unless '-E/--empty' is used.+ * Accounts (rows) containing all zeroes are not shown, unless+ '-E/--empty' is used.+ * Amounts with many commodities are shown in abbreviated form, unless+ '--no-elide' is used.+ * Average and/or total columns can be added with the '-A/--average'+ and '-T/--row-total' flags.+ * The '--transpose' flag can be used to exchange rows and columns.+ * 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:++ * Hide the totals row with '-N/--no-total'+ * Filter to a single currency with 'cur:'+ * Convert to a single currency with '-V [--infer-market-price]'+ * Use a more compact layout like '--layout=bare'+ * Maximize the terminal window+ * Reduce the terminal's font size+ * View with a pager like less, eg: 'hledger bal -D --color=yes | less+ -RS'+ * 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')+ * Output as HTML and view with a browser: 'hledger bal -D -o a.html+ && open a.html'+++File: hledger.info, Node: Balance change end balance, Next: Balance report types, Prev: Multi-period balance report, Up: balance++24.6.12 Balance change, end balance+-----------------------------------++It's important to be clear on the meaning of the numbers shown in+balance 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 postings.)+++File: hledger.info, Node: Balance report types, Next: Budget report, Prev: Balance change end balance, Up: balance++24.6.13 Balance report types+----------------------------++The balance command is quite flexible; here is the full detail on how to+control what it reports. If the following seems complicated, don't+worry - this is for advanced reporting, and it does take time and+experimentation to get familiar with all the report modes.++ There are three important option groups:++ 'hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]+...'++* Menu:++* Calculation type::+* Accumulation type::+* Valuation type::+* Combining balance report types::+++File: hledger.info, Node: Calculation type, Next: Accumulation type, Up: Balance report types++24.6.13.1 Calculation type+..........................++The basic calculation to perform for each table cell. It is one of:++ * '--sum' : sum the posting amounts (*default*)+ * '--budget' : sum the amounts, but also show the budget goal amount+ (for each account/period)+ * '--valuechange' : show the change in period-end historical balance+ values (caused by deposits, withdrawals, and/or market price+ fluctuations)+ * '--gain' : show the unrealised capital gain/loss, (the current+ valued balance minus each amount's original cost)+ * '--count' : show the count of postings+++File: hledger.info, Node: Accumulation type, Next: Valuation type, Prev: Calculation type, Up: Balance report types++24.6.13.2 Accumulation type+...........................++How amounts should accumulate across a report's subperiods/columns.+Another way to say it: which time period's postings should contribute to+each cell's calculation. It is one of:++ * '--change' : calculate with postings from column start to column+ end, ie "just this column". Typically used to see+ revenues/expenses. (*default for balance, cashflow,+ incomestatement*)++ * '--cumulative' : calculate with postings from report start to+ column end, ie "previous columns plus this column". Typically used+ to show changes accumulated since the report's start date. Not+ often used.++ * '--historical/-H' : calculate with postings from journal start to+ column end, ie "all postings from before report start date until+ this column's end". Typically used to see historical end balances+ of assets/liabilities/equity. (*default for balancesheet,+ balancesheetequity*)+++File: hledger.info, Node: Valuation type, Next: Combining balance report types, Prev: Accumulation type, Up: Balance report types++24.6.13.3 Valuation type+........................++Which kind of value or cost conversion should be applied, if any, before+displaying the report. It is one of:++ * no valuation type : don't convert to cost or value (*default*)+ * '--value=cost[,COMM]' : convert amounts to cost (then optionally to+ some other commodity)+ * '--value=then[,COMM]' : convert amounts to market value on+ transaction dates+ * '--value=end[,COMM]' : convert amounts to market value on period+ end date(s)+ (*default with '--valuechange', '--gain'*)+ * '--value=now[,COMM]' : convert amounts to market value on today's+ date+ * '--value=YYYY-MM-DD[,COMM]' : convert amounts to market value on+ another date++ or one of the equivalent simpler flags:++ * '-B/--cost' : like -value=cost (though, note -cost and -value are+ independent options which can both be used at once)+ * '-V/--market' : like -value=end+ * '-X COMM/--exchange COMM' : like -value=end,COMM++ See Cost reporting and Value reporting for more about these.+++File: hledger.info, Node: Combining balance report types, Prev: Valuation type, Up: Balance report types++24.6.13.4 Combining balance report types+........................................++Most combinations of these options should produce reasonable reports,+but if you find any that seem wrong or misleading, let us know. The+following restrictions are applied:++ * '--valuechange' implies '--value=end'+ * '--valuechange' makes '--change' the default when used with the+ 'balancesheet'/'balancesheetequity' commands+ * '--cumulative' or '--historical' disables '--row-total/-T'++ For reference, here is what the combinations of accumulation and+valuation show:++Valuation:>no valuation '--value= then' '--value= end' '--value=+Accumulation:v YYYY-MM-DD+ /now'+-----------------------------------------------------------------------------+'--change'change in sum of period-end DATE-value+ period posting-date value of of change in+ market values change in period+ in period period+'--cumulative'change from sum of period-end DATE-value+ report start to posting-date value of of change+ period end market values change from from report+ from report report start start to+ start to period to period end period end+ end+'--historicalchange from sum of period-end DATE-value+/-H' journal start posting-date value of of change+ to period end market values change from from journal+ (historical end from journal journal start start to+ balance) start to period to period end period end+ end+++File: hledger.info, Node: Budget report, Next: Balance report layout, Prev: Balance report types, Up: balance++24.6.14 Budget report+---------------------++The '--budget' report type is like a regular balance report, but with+two main differences:++ * Budget goals and performance percentages are also shown, in+ brackets+ * Accounts which don't have budget goals are hidden by default.++ This is useful for comparing planned and actual income, expenses,+time usage, etc.++ Periodic transaction rules are used to define budget goals. For+example, here's a periodic rule defining monthly goals for bus travel+and food expenses:++;; Budget+~ monthly+ (expenses:bus) $30+ (expenses:food) $400++ After recording some actual expenses,++;; Two months worth of expenses+2017-11-01+ income $-1950+ expenses:bus $35+ expenses:food:groceries $310+ expenses:food:dining $42+ expenses:movies $38+ assets:bank:checking++2017-12-01+ income $-2100+ expenses:bus $53+ expenses:food:groceries $380+ expenses:food:dining $32+ expenses:gifts $100+ assets:bank:checking++ we can see a budget report like this:++$ hledger bal -M --budget+Budget performance in 2017-11-01..2017-12-31:++ || Nov Dec +===============++============================================+ <unbudgeted> || $-425 $-565 + expenses || $425 [ 99% of $430] $565 [131% of $430] + expenses:bus || $35 [117% of $30] $53 [177% of $30] + expenses:food || $352 [ 88% of $400] $412 [103% of $400] +---------------++--------------------------------------------+ || 0 [ 0% of $430] 0 [ 0% of $430] ++ This is "goal-based budgeting"; you define goals for accounts and+periods, often recurring, and hledger shows performance relative to the+goals. This contrasts with "envelope budgeting", which is more detailed+and strict - useful when cash is tight, but also quite a bit more work.+https://plaintextaccounting.org/Budgeting has more on this topic.++* Menu:++* Using the budget report::+* Budget date surprises::+* Selecting budget goals::+* Budgeting vs forecasting::+++File: hledger.info, Node: Using the budget report, Next: Budget date surprises, Up: Budget report++24.6.14.1 Using the budget report+.................................++Historically this report has been confusing and fragile. hledger's+version should be relatively robust and intuitive, but you may still+find surprises. Here are more notes to help with learning and+troubleshooting.++ * In the above example, 'expenses:bus' and 'expenses:food' are shown+ because they have budget goals during the report period.++ * Their parent 'expenses' is also shown, with budget goals aggregated+ from the children.++ * The subaccounts 'expenses:food:groceries' and+ 'expenses:food:dining' are not shown since they have no budget goal+ of their own, but they contribute to 'expenses:food''s actual+ amount.++ * Unbudgeted accounts 'expenses:movies' and 'expenses:gifts' are also+ not shown, but they contribute to 'expenses''s actual amount.++ * The other unbudgeted accounts 'income' and 'assets:bank:checking'+ are grouped as '<unbudgeted>'.++ * '--depth' or 'depth:' can be used to limit report depth in the+ usual way (but will not reveal unbudgeted subaccounts).++ * Amounts are always inclusive of subaccounts (even in '-l/--list'+ mode).++ * Numbers displayed in a -budget report will not always agree with+ the totals, because of hidden unbudgeted accounts; this is normal.+ '-E/--empty' can be used to reveal the hidden accounts.++ * In the periodic rules used for setting budget goals, unbalanced+ postings are convenient.++ * You can filter budget reports with the usual queries, eg to focus+ on particular accounts. It's common to restrict them to just+ expenses. (The '<unbudgeted>' account is occasionally hard to+ exclude; this is because of date surprises, discussed below.)++ * When you have multiple currencies, you may want to convert them to+ one ('-X COMM --infer-market-prices') and/or show just one at a+ time ('cur:COMM'). If you do need to show multiple currencies at+ once, '--layout bare' can be helpful.++ * You can "roll over" amounts (actual and budgeted) to the next+ period with '--cumulative'.++ See also: https://hledger.org/budgeting.html.+++File: hledger.info, Node: Budget date surprises, Next: Selecting budget goals, Prev: Using the budget report, Up: Budget report++24.6.14.2 Budget date surprises+...............................++With small data, or when starting out, some of the generated budget goal+transaction dates might fall outside the report periods. Eg with the+following journal and report, the first period appears to have no+'expenses:food' budget. (Also the '<unbudgeted>' account should be+excluded by the 'expenses' query, but isn't.):++~ monthly in 2020+ (expenses:food) $500++2020-01-15+ expenses:food $400+ assets:checking++$ hledger bal --budget expenses+Budget performance in 2020-01-15:++ || 2020-01-15 +===============++====================+ <unbudgeted> || $400 + expenses:food || 0 [ 0% of $500] +---------------++--------------------+ || $400 [80% of $500] ++ In this case, the budget goal transactions are generated on first+days of of month (this can be seen with 'hledger print --forecast+tag:generated expenses'). Whereas the report period defaults to just+the 15th day of january (this can be seen from the report table's column+headings).++ To fix this kind of thing, be more explicit about the report period+(and/or the periodic rules' dates). In this case, adding '-b 2020' does+the trick.+++File: hledger.info, Node: Selecting budget goals, Next: Budgeting vs forecasting, Prev: Budget date surprises, Up: Budget report++24.6.14.3 Selecting budget goals+................................++By default, the budget report uses all available periodic transaction+rules to generate goals. This includes rules with a different report+interval from your report. Eg if you have daily, weekly and monthly+periodic rules, all of these will contribute to the goals in a monthly+budget report.++ You can select a subset of periodic rules by providing an argument to+the '--budget' flag. '--budget=DESCPAT' will match all periodic rules+whose description contains DESCPAT, a case-insensitive substring (not a+regular expression or query). This means you can give your periodic+rules descriptions (remember that two spaces are needed between period+expression and description), and then select from multiple budgets+defined in your journal.+++File: hledger.info, Node: Budgeting vs forecasting, Prev: Selecting budget goals, Up: Budget report++24.6.14.4 Budgeting vs forecasting+..................................++'--forecast' and '--budget' both use the periodic transaction rules in+the journal to generate temporary transactions for reporting purposes.+However they are separate features - though you can use both at the same+time if you want. Here are some differences between them:++-forecast -budget+--------------------------------------------------------------------------+is a general option; it enables is a balance command option;+forecasting with all reports it selects the balance+ report's budget mode+generates visible transactions which generates invisible+appear in reports transactions which produce+ goal amounts+generates forecast transactions from generates budget goal+after the last regular transaction, to transactions throughout the+the end of the report period; or with report period, optionally+an argument '--forecast=PERIODEXPR' restricted by periods+generates them throughout the specified in the periodic+specified period, both optionally transaction rules+restricted by periods specified in the+periodic transaction rules+uses all periodic rules uses all periodic rules; or+ with an argument+ '--budget=DESCPAT' uses just+ the rules matched by DESCPAT+++File: hledger.info, Node: Balance report layout, Next: Some useful balance reports, Prev: Budget report, Up: balance++24.6.15 Balance report layout+-----------------------------++The '--layout' option affects how balance reports show multi-commodity+amounts and commodity symbols, which can improve readability. It can+also normalise the data for easy consumption by other programs. It has+four possible values:++ * '--layout=wide[,WIDTH]': commodities are shown on a single line,+ optionally elided to WIDTH+ * '--layout=tall': each commodity is shown on a separate line+ * '--layout=bare': commodity symbols are in their own column, amounts+ are bare numbers+ * '--layout=tidy': data is normalised to easily-consumed "tidy" form,+ with one row per data value++ Here are the '--layout' modes supported by each output format Only+CSV output supports all of them:++- txt csv html json sql+---------------------------------------+wide Y Y Y+tall Y Y Y+bare Y Y Y+tidy Y++ Examples:++* Menu:++* Wide layout::+* Tall layout::+* Bare layout::+* Tidy layout::+++File: hledger.info, Node: Wide layout, Next: Tall layout, Up: Balance report layout++24.6.15.1 Wide layout+.....................++With many commodities, reports can be very wide:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide+Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total +==================++====================================================================================================================================================================================================================+ Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT +------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT ++ A width limit reduces the width, but some commodities will be hidden:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32+Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total +==================++===========================================================================================================================+ Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. +------------------++---------------------------------------------------------------------------------------------------------------------------+ || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. +++File: hledger.info, Node: Tall layout, Next: Bare layout, Prev: Wide layout, Up: Balance report layout++24.6.15.2 Tall layout+.....................++Each commodity gets a new line (may be different in each column), and+account names are repeated:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall+Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total +==================++==================================================+ Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD + Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT + Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD + Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA + Assets:US:ETrade || 18.00 VHT 294.00 VHT +------------------++--------------------------------------------------+ || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD + || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT + || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD + || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA + || 18.00 VHT 294.00 VHT +++File: hledger.info, Node: Bare layout, Next: Tidy layout, Prev: Tall layout, Up: Balance report layout++24.6.15.3 Bare layout+.....................++Commodity symbols are kept in one column, each commodity has its own+row, amounts are bare numbers, account names are repeated:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare+Balance changes in 2012-01-01..2014-12-31:++ || Commodity 2012 2013 2014 Total +==================++=============================================+ Assets:US:ETrade || GLD 0 70.00 0 70.00 + Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00 + Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50 + Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00 + Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00 +------------------++---------------------------------------------+ || GLD 0 70.00 0 70.00 + || ITOT 10.00 18.00 -11.00 17.00 + || USD 337.18 -98.12 4881.44 5120.50 + || VEA 12.00 10.00 14.00 36.00 + || VHT 106.00 18.00 170.00 294.00 ++ Bare layout also affects CSV output, which is useful for producing+data that is easier to consume, eg for making charts:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare+"account","commodity","balance"+"Assets:US:ETrade","GLD","70.00"+"Assets:US:ETrade","ITOT","17.00"+"Assets:US:ETrade","USD","5120.50"+"Assets:US:ETrade","VEA","36.00"+"Assets:US:ETrade","VHT","294.00"+"total","GLD","70.00"+"total","ITOT","17.00"+"total","USD","5120.50"+"total","VEA","36.00"+"total","VHT","294.00"++ Bare layout will sometimes display an extra row for the no-symbol+commodity, because of zero amounts (hledger treats zeroes as+commodity-less, usually). This can break 'hledger-bar' confusingly+(workaround: add a 'cur:' query to exclude the no-symbol row).+++File: hledger.info, Node: Tidy layout, Prev: Bare layout, Up: Balance report layout++24.6.15.4 Tidy layout+.....................++This produces normalised "tidy data" (see+https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)+where every variable has its own column and each row represents a single+data point. This is the easiest kind of data for other software to+consume:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy+"account","period","start_date","end_date","commodity","value"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","GLD","0"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","ITOT","10.00"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","USD","337.18"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","VEA","12.00"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","VHT","106.00"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","GLD","70.00"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","ITOT","18.00"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","USD","-98.12"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","VEA","10.00"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","VHT","18.00"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","GLD","0"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","ITOT","-11.00"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","USD","4881.44"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","VEA","14.00"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"+++File: hledger.info, Node: Some useful balance reports, Prev: Balance report layout, Up: balance++24.6.16 Some useful balance reports+-----------------------------------++Some frequently used 'balance' options/reports are:++ * 'bal -M revenues expenses'+ Show revenues/expenses in each month. Also available as the+ 'incomestatement' command.++ * 'bal -M -H assets liabilities'+ Show historical asset/liability balances at each month end. Also+ available as the 'balancesheet' command.++ * 'bal -M -H assets liabilities equity'+ Show historical asset/liability/equity balances at each month end.+ Also available as the 'balancesheetequity' command.++ * 'bal -M assets not:receivable'+ Show changes to liquid assets in each month. Also available as the+ 'cashflow' command.++ Also:++ * 'bal -M expenses -2 -SA'+ Show monthly expenses summarised to depth 2 and sorted by average+ amount.++ * 'bal -M --budget expenses'+ Show monthly expenses and budget goals.++ * 'bal -M --valuechange investments'+ Show monthly change in market value of investment assets.++ * 'bal investments --valuechange -D date:lastweek amt:'>1000' -STA+ [--invert]'+ Show top gainers [or losers] last week+++File: hledger.info, Node: balancesheet, Next: balancesheetequity, Prev: balance, Up: PART 4 COMMANDS++24.7 balancesheet+=================++(bs)++ This command displays a balance sheet, showing historical ending+balances of asset and liability accounts. (To see equity as well, use+the balancesheetequity command.) Amounts are shown with normal positive+sign, as in conventional financial statements.++ This report shows accounts declared with the 'Asset', 'Cash' or+'Liability' type (see account types). Or if no such accounts are+declared, it shows top-level accounts named 'asset' or 'liability' (case+insensitive, plurals allowed) and their subaccounts.++ Example:++$ hledger balancesheet+Balance Sheet 2008-12-31++ || 2008-12-31 +====================++============+ Assets || +--------------------++------------+ assets:bank:saving || $1 + assets:cash || $-2 +--------------------++------------+ || $-1 +====================++============+ Liabilities || +--------------------++------------+ liabilities:debts || $-1 +--------------------++------------+ || $-1 +====================++============+ Net: || 0 ++ This command is a higher-level variant of the 'balance' command, and+supports 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', 'tsv' (_Added in+1.32_), 'html', and 'json'.+++File: hledger.info, Node: balancesheetequity, Next: cashflow, Prev: balancesheet, Up: PART 4 COMMANDS++24.8 balancesheetequity+=======================++(bse)++ This command displays a balance sheet, showing historical ending+balances of asset, liability and equity accounts. Amounts are shown+with normal positive sign, as in conventional financial statements.++ This report shows accounts declared with the 'Asset', 'Cash',+'Liability' or 'Equity' type (see account types). Or if no such+accounts are declared, it shows top-level accounts named 'asset',+'liability' or 'equity' (case insensitive, plurals allowed) and their+subaccounts.++ Example:++$ hledger balancesheetequity+Balance Sheet With Equity 2008-12-31++ || 2008-12-31 +====================++============+ Assets || +--------------------++------------+ assets:bank:saving || $1 + assets:cash || $-2 +--------------------++------------+ || $-1 +====================++============+ Liabilities || +--------------------++------------+ liabilities:debts || $-1 +--------------------++------------+ || $-1 +====================++============+ Equity || +--------------------++------------+--------------------++------------+ || 0 +====================++============+ Net: || 0 ++ This command is a higher-level variant of the 'balance' command, and+supports 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 report is the easiest way to see if the accounting equation+(A+L+E = 0) is satisfied (after you have done a 'close --retain' to+merge revenues and expenses with equity, and perhaps added+'--infer-equity' to balance your commodity conversions).++ This command also supports the output destination and output format+options The output formats supported are 'txt', 'csv', 'tsv', 'html',+and 'json'.+++File: hledger.info, Node: cashflow, Next: check, Prev: balancesheetequity, Up: PART 4 COMMANDS++24.9 cashflow+=============++(cf)++ This command displays a (simple) cashflow statement, showing the+inflows and outflows affecting "cash" (ie, liquid, easily convertible)+assets. Amounts are shown with normal positive sign, as in conventional+financial statements.++ This report shows accounts declared with the 'Cash' type (see account+types). Or if no such accounts are declared, it shows accounts++ * under a top-level account named 'asset' (case insensitive, plural+ allowed)+ * whose name contains some variation of 'cash', 'bank', 'checking' or+ 'saving'.++ More precisely: all accounts matching this case insensitive regular+expression:++ '^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)'++ and their subaccounts.++ An example cashflow report:++$ hledger cashflow+Cashflow Statement 2008++ || 2008 +====================++======+ Cash flows || +--------------------++------+ assets:bank:saving || $1 + assets:cash || $-2 +--------------------++------+ || $-1 ++ This command is a higher-level variant of the 'balance' command, and+supports 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', 'tsv' (_Added in+1.32_), 'html', and 'json'.+++File: hledger.info, Node: check, Next: close, Prev: cashflow, Up: PART 4 COMMANDS++24.10 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++ If you are an Emacs user, you can also configure flycheck-hledger to+run these checks, providing instant feedback as you edit the journal.++ Here are the checks currently available:++* Menu:++* Default checks::+* Strict checks::+* Other checks::+* Custom checks::+* More about specific checks::+++File: hledger.info, Node: Default checks, Next: Strict checks, Up: check++24.10.1 Default checks+----------------------++These checks are run automatically by (almost) all hledger commands:++ * *parseable* - data files are in a supported format, with no syntax+ errors and no invalid include directives.++ * *autobalanced* - all transactions are balanced, after converting to+ cost. Missing amounts and missing costs are inferred automatically+ where possible.++ * *assertions* - all balance assertions in the journal are passing.+ (This check can be disabled with '-I'/'--ignore-assertions'.)+++File: hledger.info, Node: Strict checks, Next: Other checks, Prev: Default checks, Up: check++24.10.2 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':++ * *balanced* - all transactions are balanced after converting to+ cost, without inferring missing costs. If conversion costs are+ required, they must be explicit.++ * *accounts* - all account names used by transactions have been+ declared++ * *commodities* - all commodity symbols used have been declared+++File: hledger.info, Node: Other checks, Next: Custom checks, Prev: Strict checks, Up: check++24.10.3 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:++ * *ordereddates* - transactions are ordered by date within each file++ * *payees* - all payees used by transactions have been declared++ * *recentassertions* - all accounts with balance assertions have a+ balance assertion within 7 days of their latest posting++ * *tags* - all tags used by transactions have been declared++ * *uniqueleafnames* - all account leaf names are unique+++File: hledger.info, Node: Custom checks, Next: More about specific checks, Prev: Other checks, Up: check++24.10.4 Custom checks+---------------------++A few more checks are are available as separate add-on commands, in+https://github.com/simonmichael/hledger/tree/master/bin:++ * *hledger-check-tagfiles* - all tag values containing / (a forward+ slash) exist as file paths++ * *hledger-check-fancyassertions* - more complex balance assertions+ are passing++ You could make similar scripts to perform your own custom checks.+See: Cookbook -> Scripting.+++File: hledger.info, Node: More about specific checks, Prev: Custom checks, Up: check++24.10.5 More about specific checks+----------------------------------++'hledger check recentassertions' will complain if any balance-asserted+account has postings more than 7 days after its latest balance+assertion. This aims to prevent the situation where you are regularly+updating your journal, but forgetting to check your balances against the+real world, then one day must dig back through months of data to find an+error. It assumes that adding a balance assertion requires/reminds you+to check the real-world balance. (That may not be true if you+auto-generate balance assertions from bank data; in that case, I+recommend to import transactions uncleared, and when you manually review+and clear them, also check the latest assertion against the real-world+balance.)+++File: hledger.info, Node: close, Next: codes, Prev: check, Up: PART 4 COMMANDS++24.11 close+===========++(equity)++ 'close' generates several kinds of "closing" and/or "opening"+transactions, useful in certain situations, including migrating balances+to a new journal file, retaining earnings into equity, consolidating+balances, or viewing lots. Like 'print', it prints valid journal+entries. You can append or copy these to your journal file(s) when you+are happy with how they look.++ 'close' currently has six modes, selected by a single mode flag:++* Menu:++* close --migrate::+* close --close::+* close --open::+* close --assert::+* close --assign::+* close --retain::+* close customisation::+* close and balance assertions::+* close examples::+++File: hledger.info, Node: close --migrate, Next: close --close, Up: close++24.11.1 close -migrate+----------------------++This is the most common mode. It prints a "closing balances"+transaction that zeroes out all asset and liability balances (by+default), and an opposite "opening balances" transaction that restores+them again. The balancing account will be 'equity:opening/closing+balances' (or another specified by '--close-acct' or '--open-acct').++ This is useful when migrating balances to a new journal file at the+start of a new year. Essentially, you run 'hledger close+--migrate=NEWYEAR -e NEWYEAR' and then copy the closing transaction to+the end of the old file and the opening transaction to the start of the+new file. The opening transaction sets correct starting balances in the+new file when it is used alone, and the closing transaction keeps+balances correct when you use both old and new files together, by+cancelling out the following opening transaction and preventing buildup+of duplicated opening balances. Think of the closing/opening pair as+"moving the balances into the next file".++ You can close a different set of accounts by providing a query. Eg+if you want to include equity, you can add 'assets liabilities equity'+or 'type:ALE' arguments. (The balancing account is always excluded.)+Revenues and expenses usually are not migrated to a new file directly;+see '--retain' below.++ The generated transactions will have a 'start:' tag, with its value+set to '--migrate''s 'NEW' argument if any, for easier matching or+exclusion. When 'NEW' is not specified, it will be inferred if possible+by incrementing a number (eg a year number) within the default journal's+main file name. The other modes behave similarly.+++File: hledger.info, Node: close --close, Next: close --open, Prev: close --migrate, Up: close++24.11.2 close -close+--------------------++This prints just the closing balances transaction of '--migrate'. It is+the default behaviour if you specify no mode flag. Using the+customisation options below, you can move balances from any set of+accounts to a different account.+++File: hledger.info, Node: close --open, Next: close --assert, Prev: close --close, Up: close++24.11.3 close -open+-------------------++This prints just the opening balances transaction of '--migrate'. It is+similar to Ledger's equity command.+++File: hledger.info, Node: close --assert, Next: close --assign, Prev: close --open, Up: close++24.11.4 close -assert+---------------------++This prints a "closing balances" transaction (with 'balances:' tag),+that just declares balance assertions for the current balances without+changing them. It could be useful as documention and to guard against+changes.+++File: hledger.info, Node: close --assign, Next: close --retain, Prev: close --assert, Up: close++24.11.5 close -assign+---------------------++This prints an "opening balances" transaction that restores the account+balances using balance assignments. Balance assignments work regardless+of any previous balance, so a preceding closing balances transaction is+not needed.++ However, omitting the closing balances transaction would unbalance+equity. This is relatively harmless for personal reports, but it+disturbs the accounting equation, removing a source of error detection.+So '--migrate' is generally the best way to set to set balances in new+files, for now.+++File: hledger.info, Node: close --retain, Next: close customisation, Prev: close --assign, Up: close++24.11.6 close -retain+---------------------++This is like '--close' with different defaults: it prints a "retain+earnings" transaction (with 'retain:' tag), that transfers revenue and+expense balances to 'equity:retained earnings'.++ This is a different kind of closing, called "retaining earnings" or+"closing the books"; it is traditionally performed by businesses at the+end of each accounting period, to consolidate revenues and expenses into+the main equity balance. ("Revenues" and "expenses" are actually equity+by another name, kept separate temporarily for reporting purposes.)++ In personal accounting you generally don't need to do this, unless+you want the 'balancesheetequity' report to show a zero total,+demonstrating that the accounting equation (A-L=E) is satisfied.+++File: hledger.info, Node: close customisation, Next: close and balance assertions, Prev: close --retain, Up: close++24.11.7 close customisation+---------------------------++In all modes, the following things can be overridden:++ * the accounts to be closed/opened, with account query arguments+ * the balancing account, with '--close-acct=ACCT' and/or+ '--open-acct=ACCT'+ * the transaction descriptions, with '--close-desc=DESC' and+ '--open-desc=DESC'+ * the transaction's tag value, with a '--MODE=NEW' option argument+ * the closing/opening dates, with '-e OPENDATE'++ By default, the closing date is yesterday, or the journal's end date,+whichever is later; and the opening date is always one day after the+closing date. You can change these by specifying a report end date; the+closing date will be the last day of the report period. Eg '-e 2024'+means "close on 2023-12-31, open on 2024-01-01".++ With '--x/--explicit', the balancing amount will be shown explicitly,+and if it involves multiple commodities, a separate posting will be+generated for each of them (similar to 'print -x').++ With '--interleaved', each individual transfer is shown with source+and destination postings next to each other (perhaps useful for+troubleshooting).++ With '--show-costs', balances' costs are also shown, with different+costs kept separate. This may generate very large journal entries, if+you have many currency conversions or investment transactions. 'close+--show-costs' is currently the best way to view investment lots with+hledger. (To move or dispose of lots, see the more capable+'hledger-move' script.)+++File: hledger.info, Node: close and balance assertions, Next: close examples, Prev: close customisation, Up: close++24.11.8 close and balance assertions+------------------------------------++'close' adds balance assertions verifying that the accounts have been+reset to zero in a closing transaction or restored to their previous+balances in an opening transaction. These provide useful error+checking, but you can ignore them temporarily with '-I', or remove them+if you prefer.++ Single-commodity, subaccount-exclusive balance assertions ('=') are+generated by default. This can be changed with '--assertion-type='==*''+(eg).++ When running 'close' you should probably avoid using '-C', '-R',+'status:' (filtering by status or realness) or '--auto' (generating+postings), since the generated balance assertions would then require+these.++ Transactions with multiple dates (eg posting dates) spanning the file+boundary also can disrupt the balance assertions:++2023-12-30 a purchase made in december, cleared in january+ expenses:food 5+ assets:bank:checking -5 ; date: 2023-01-02++ To solve this you can transfer the money to and from a temporary+account, splitting the multi-day transaction into two single-day+transactions:++; in 2022.journal:+2022-12-30 a purchase made in december, cleared in january+ expenses:food 5+ equity:pending -5++; in 2023.journal:+2023-01-02 last year's transaction cleared+ equity:pending 5 = 0+ assets:bank:checking -5+++File: hledger.info, Node: close examples, Prev: close and balance assertions, Up: close++24.11.9 close examples+----------------------++* Menu:++* Retain earnings::+* Migrate balances to a new file::+* More detailed close examples::+++File: hledger.info, Node: Retain earnings, Next: Migrate balances to a new file, Up: close examples++24.11.9.1 Retain earnings+.........................++Record 2022's revenues/expenses as retained earnings on 2022-12-31,+appending the generated transaction to the journal:++$ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal++ After this, to see 2022's revenues and expenses you must exclude the+retain earnings transaction:++$ hledger -f 2022.journal is not:desc:'retain earnings'+++File: hledger.info, Node: Migrate balances to a new file, Next: More detailed close examples, Prev: Retain earnings, Up: close examples++24.11.9.2 Migrate balances to a new file+........................................++Close assets/liabilities on 2022-12-31 and re-open them on 2023-01-01:++$ hledger close --migrate -f 2022.journal -p 2022+# copy/paste the closing transaction to the end of 2022.journal+# copy/paste the opening transaction to the start of 2023.journal++ After this, to see 2022's end-of-year balances you must exclude the+closing balances transaction:++$ hledger -f 2022.journal bs not:desc:'closing balances'++ For more flexibility, it helps to tag closing and opening+transactions with eg 'start:NEWYEAR', then you can ensure correct+balances by excluding all opening/closing transactions except the first,+like so:++$ hledger bs -Y -f 2021.j -f 2022.j -f 2023.j expr:'tag:start=2021 or not tag:start'+$ hledger bs -Y -f 2021.j -f 2022.j expr:'tag:start=2021 or not tag:start'+$ hledger bs -Y -f 2022.j -f 2023.j expr:'tag:start=2022 or not tag:start'+$ hledger bs -Y -f 2021.j expr:'tag:start=2021 or not tag:start'+$ hledger bs -Y -f 2022.j expr:'tag:start=2022 or not tag:start'+$ hledger bs -Y -f 2023.j # unclosed file, no query needed+++File: hledger.info, Node: More detailed close examples, Prev: Migrate balances to a new file, Up: close examples++24.11.9.3 More detailed close examples+......................................++See examples/multi-year.+++File: hledger.info, Node: codes, Next: commodities, Prev: close, Up: PART 4 COMMANDS++24.12 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:++2022/1/1 (123) Supermarket + Food $5.00+ Checking ++2022/1/2 (124) Post Office+ Postage $8.32+ Checking++2022/1/3 Supermarket+ Food $11.23+ Checking ++2022/1/4 (126) Post Office+ Postage $3.21+ Checking++$ hledger codes+123+124+126++$ hledger codes -E+123+124++126+++File: hledger.info, Node: commodities, Next: demo, Prev: codes, Up: PART 4 COMMANDS++24.13 commodities+=================++List all commodity/currency symbols used or declared in the journal.+++File: hledger.info, Node: demo, Next: descriptions, Prev: commodities, Up: PART 4 COMMANDS++24.14 demo+==========++Play demos of hledger usage in the terminal, if asciinema is installed.++ Run this command with no argument to list the demos. To play a demo,+write its number or a prefix or substring of its title. Tips:++ Make your terminal window large enough to see the demo clearly.++ Use the -s/-speed SPEED option to set your preferred playback speed,+eg '-s4' to play at 4x original speed or '-s.5' to play at half speed.+The default speed is 2x.++ Other asciinema options can be added following a double dash, eg '--+-i.1' to limit pauses or '-- -h' to list asciinema's other options.++ During playback, several keys are available: SPACE to pause/unpause,+. to step forward (while paused), CTRL-c quit.++ Examples:++$ hledger demo # list available demos+$ hledger demo 1 # play the first demo at default speed (2x)+$ hledger demo install -s4 # play the "install" demo at 4x speed+++File: hledger.info, Node: descriptions, Next: diff, Prev: demo, Up: PART 4 COMMANDS++24.15 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 transactions.++ Example:++$ hledger descriptions+Store Name+Gas Station | Petrol+Person A+++File: hledger.info, Node: diff, Next: files, Prev: descriptions, Up: PART 4 COMMANDS++24.16 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+multiple 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:+++File: hledger.info, Node: files, Next: help, Prev: diff, Up: PART 4 COMMANDS++24.17 files+===========++List all files included in the journal. With a REGEX argument, only+file names matching the regular expression (case sensitive) are shown.+++File: hledger.info, Node: help, Next: import, Prev: files, Up: PART 4 COMMANDS++24.18 help+==========++Show the hledger user manual in the terminal, with 'info', 'man', or a+pager. With a TOPIC argument, open it at that topic if possible. TOPIC+can be any heading in the manual, or a heading prefix, case insensitive.+Eg: 'commands', 'print', 'forecast', 'journal', 'amount', '"auto+postings"'.++ This command shows the hledger manual built in to your hledger+version. It can be useful when offline, or when you prefer the terminal+to a web browser, or when the appropriate hledger manual or viewing+tools are not installed on your system.++ By default it chooses the best viewer found in $PATH, trying (in this+order): 'info', 'man', '$PAGER', 'less', 'more'. You can force the use+of info, man, or a pager with the '-i', '-m', or '-p' flags, If no+viewer can be found, or the command is run non-interactively, it just+prints the manual to stdout.++ If using 'info', note that version 6 or greater is needed for TOPIC+lookup. If you are on mac you will likely have info 4.8, and should+consider installing a newer version, eg with 'brew install texinfo'+(#1770).++ Examples++$ hledger help --help # show how the help command works+$ hledger help # show the hledger manual with info, man or $PAGER+$ hledger help journal # show the journal topic in the hledger manual+$ hledger help -m journal # show it with man, even if info is installed+++File: hledger.info, Node: import, Next: incomestatement, Prev: help, Up: PART 4 COMMANDS++24.19 import+============++Read new transactions added to each FILE provided as arguments since+last run, and add them to the journal. Or with -dry-run, just print the+transactions that would be added. Or with -catchup, just mark all of+the FILEs' current transactions as imported, without importing them.++ This command may append new transactions to the main journal file+(which should be in journal format). Existing transactions are not+changed. This is one of the few hledger commands that writes to the+journal file (see also 'add').++ Unlike other hledger commands, with 'import' the journal file is an+output file, and will be modified, though only by appending (existing+data will not be changed). The input files are specified as arguments,+so to import one or more CSV files to your main journal, you will run+'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.++* Menu:++* Deduplication::+* Import testing::+* Importing balance assignments::+* Commodity display styles::+++File: hledger.info, Node: Deduplication, Next: Import testing, Up: import++24.19.1 Deduplication+---------------------++'import' tries to import only the transactions which are new since the+last import, ignoring any that it has seen in previous runs. So if your+bank's CSV includes the last three months of data, you can download and+'import' it every month (or week, or day) and only the new transactions+will be imported each time.++ It works as follows. For each imported 'FILE' (usually CSV, but they+could be any of hledger's input formats):++ * It tries to recall the latest date seen previously, reading it from+ a hidden '.latest.FILE' in the same directory.+ * Then it processes 'FILE', ignoring any transactions on or before+ the "latest seen" date.++ And after a successful import, it updates the '.latest.FILE'(s) for+next time (unless '--dry-run' was used).++ This is a limited kind of deduplication, let's call it "date+skipping". Within each input file, it avoids reprocessing the same+dates across successive runs. This is a simple system that works for+most real-world CSV files; it assumes these are true, or true enough:++ 1. new items always have the newest dates+ 2. item dates are stable across successive downloads+ 3. the order of same-date items is stable across downloads+ 4. the name of the input file is stable across downloads++ If you have a bank whose CSV dates or ordering occasionally change,+you can reduce the chance of this happening in new transactions by+importing more often, and in old transactions it doesn't matter. And+remember you can use CSV rules files as input, which is one way to+ensure a stable file name.++ 'import' doesn't detect other kinds of duplication, such as duplicate+transactions within a single run. (In part, because legitimate+duplicate transactions can easily occur in real-world data.) So, say+you downloaded but forgot to import 'bank.1.csv', and a week later you+downloaded 'bank.2.csv' with overlapping data. Now you should not+import both of these at once ('hledger import bank.1.csv bank.2.csv');+the overlapping transactions which appear twice would not be+deduplicated since this is considered a single import. Instead, import+these files one at a time, and also use the same filename each time for+a common "latest seen" state:++$ mv bank.1.csv bank.csv; hledger import bank.csv+$ mv bank.2.csv bank.csv; hledger import bank.csv++ Normally you can ignore the '.latest.*' files, but if needed, you can+delete them (to make all transactions unseen), or construct/modify them+(to catch up to a certain date). The format is just a single ISO-format+date ('YYYY-MM-DD'), possibly repeated on multiple lines. It means "I+have seen transactions up to this date, and this many of them occurring+on that date".++ 'hledger print --new' also uses and updates these '.latest.*' files,+but it is less often used.++ Related: CSV > Working with CSV > Deduplicating, importing.+++File: hledger.info, Node: Import testing, Next: Importing balance assignments, Prev: Deduplication, Up: import++24.19.2 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'++ Note: when importing from multiple files at once, it's currently+possible for some .latest files to be updated successfully, while the+actual import fails because of a problem in one of the files, leaving+them out of sync (and causing some transactions to be missed). To+prevent this, do a -dry-run first and fix any problems before the real+import.+++File: hledger.info, Node: Importing balance assignments, Next: Commodity display styles, Prev: Import testing, Up: import++24.19.3 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.)+++File: hledger.info, Node: Commodity display styles, Prev: Importing balance assignments, Up: import++24.19.4 Commodity display styles+--------------------------------++Imported amounts will be formatted according to the canonical commodity+styles (declared or inferred) in the main journal file.+++File: hledger.info, Node: incomestatement, Next: notes, Prev: import, Up: PART 4 COMMANDS++24.20 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.++ This report shows accounts declared with the 'Revenue' or 'Expense'+type (see account types). Or if no such accounts are declared, it shows+top-level accounts named 'revenue' or 'income' or 'expense' (case+insensitive, plurals allowed) and their subaccounts.++ Example:++$ hledger incomestatement+Income Statement 2008++ || 2008 +===================++======+ Revenues || +-------------------++------+ income:gifts || $1 + income:salary || $1 +-------------------++------+ || $2 +===================++======+ Expenses || +-------------------++------+ expenses:food || $1 + expenses:supplies || $1 +-------------------++------+ || $2 +===================++======+ Net: || 0 ++ This command is a higher-level variant of the 'balance' command, and+supports 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', 'tsv' (_Added in+1.32_), 'html', and 'json'.+++File: hledger.info, Node: notes, Next: payees, Prev: incomestatement, Up: PART 4 COMMANDS++24.21 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+transactions. 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+++File: hledger.info, Node: payees, Next: prices, Prev: notes, Up: PART 4 COMMANDS++24.22 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+++File: hledger.info, Node: prices, Next: print, Prev: payees, Up: PART 4 COMMANDS++24.23 prices+============++Print the market prices declared with P directives. With+-infer-market-prices, also show any additional prices inferred from+costs. With -show-reverse, also show additional prices inferred by+reversing known prices.++ Price amounts are always displayed with their full precision, except+for reverse prices which are limited to 8 decimal digits.++ Prices can be filtered by a date:, cur: or amt: query.++ Generally if you run this command with -infer-market-prices+-show-reverse, it will show the same prices used internally to calculate+value reports. But if in doubt, you can inspect those directly by+running the value report with -debug=2.+++File: hledger.info, Node: print, Next: register, Prev: prices, Up: PART 4 COMMANDS++24.24 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).++ 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/regenerate your journal you should take care to also copy+over the directives and inter-transaction comments.++ Eg:++$ hledger print -f examples/sample.journal date:200806+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++* Menu:++* print explicitness::+* print amount style::+* print parseability::+* print other features::+* print output format::+++File: hledger.info, Node: print explicitness, Next: print amount style, Up: print++24.24.1 print explicitness+--------------------------++Normally, whether posting amounts are implicit or explicit is preserved.+For example, when an amount is omitted in the journal, it will not+appear in the output. Similarly, if a conversion cost is implied but+not written, it will not appear in the output.++ You can use the '-x'/'--explicit' flag to force explicit display of+all amounts and costs. This 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'.++ The '-x'/'--explicit' flag will cause any postings with a+multi-commodity amount (which can arise when a multi-commodity+transaction has an implicit amount) to be split into multiple+single-commodity postings, keeping the output parseable.+++File: hledger.info, Node: print amount style, Next: print parseability, Prev: print explicitness, Up: print++24.24.2 print amount style+--------------------------++Amounts are shown right-aligned within each transaction (but not aligned+across all transactions; you can do that with ledger-mode in Emacs).++ Amounts will be (mostly) normalised to their commodity display style:+their symbol placement, decimal mark, and digit group marks will be made+consistent. By default, decimal digits are shown as they are written in+the journal.++ With the '--round' (_Added in 1.32_) option, 'print' will try+increasingly hard to display decimal digits according to the commodity+display styles:++ * '--round=none' show amounts with original precisions (default)+ * '--round=soft' add/remove decimal zeros in amounts (except costs)+ * '--round=hard' round amounts (except costs), possibly hiding+ significant digits+ * '--round=all' round all amounts and costs++ 'soft' is good for non-lossy cleanup, formatting amounts more+consistently where it's safe to do so.++ 'hard' and 'all' can cause 'print' to show invalid unbalanced journal+entries; they may be useful eg for stronger cleanup, with manual fixups+when needed.+++File: hledger.info, Node: print parseability, Next: print other features, Prev: print amount style, Up: print++24.24.3 print parseability+--------------------------++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 (though the same can be achieved with 'expr:' queries+now):++# 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:++ * Value reporting affects posting amounts but not balance assertion+ or balance assignment amounts, potentially causing those to fail.+ * Auto postings can generate postings with too many missing amounts.+ * Account aliases can generate bad account names.+++File: hledger.info, Node: print other features, Next: print output format, Prev: print parseability, Up: print++24.24.4 print, other features+-----------------------------++With '-B'/'--cost', amounts with costs are shown converted to cost.++ With '--new', print shows only transactions it has not seen on a+previous run. This uses the same deduplication system as the 'import'+command. (See import's docs for details.)++ With '-m DESC'/'--match=DESC', print shows one recent transaction+whose description is most similar to DESC. DESC should contain at least+two characters. If there is no similar-enough match, no transaction+will be shown and the program exit code will be non-zero.+++File: hledger.info, Node: print output format, Prev: print other features, Up: print++24.24.5 print output format+---------------------------++This command also supports the output destination and output format+options The output formats supported are 'txt', 'beancount' (_Added in+1.32_), 'csv', 'tsv' (_Added in 1.32_), 'json' and 'sql'.++ The 'beancount' format tries to produce Beancount-compatible output,+as follows:++ * Transaction and postings with unmarked status are converted to+ cleared ('*') status.+ * Transactions' payee and note are backslash-escaped and+ double-quote-escaped and wrapped in double quotes.+ * Transaction tags are copied to Beancount #tag format.+ * Commodity symbols are converted to upper case, and a small number+ of currency symbols like '$' are converted to the corresponding+ currency names.+ * Account name parts are capitalised and unsupported characters are+ replaced with '-'. If an account name part does not begin with a+ letter, or if the first part is not Assets, Liabilities, Equity,+ Income, or Expenses, an error is raised. (Use '--alias' options to+ bring your accounts into compliance.)+ * An 'open' directive is generated for each account used, on the+ earliest transaction date.++ Some limitations:++ * Balance assertions are removed.+ * Balance assignments become missing amounts.+ * Virtual and balanced virtual postings become regular postings.+ * Directives are not converted.++ 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","","",""++ * There is one CSV record per posting, with the parent transaction's+ fields repeated.+ * 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.)+ * The amount is separated into "commodity" (the symbol) and "amount"+ (numeric quantity) fields.+ * The numeric amount is repeated in either the "credit" or "debit"+ column, for convenience. (Those names are not accurate in the+ accounting sense; it just puts negative amounts under credit and+ zero or greater amounts under debit.)+++File: hledger.info, Node: register, Next: rewrite, Prev: print, Up: PART 4 COMMANDS++24.25 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.++ For performance reasons, column widths are chosen based on the first+1000 lines; this means unusually wide values in later lines can cause+visual discontinuities as column widths are adjusted. If you want to+ensure perfect alignment, at the cost of more time and memory, use the+'--align-all' flag.++ The '--historical'/'-H' flag adds the balance from any undisplayed+prior postings to the running total. This is useful when you want to+see 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+numbers. 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.++ With '-m DESC'/'--match=DESC', register does a fuzzy search for one+recent posting whose description is most similar to DESC. DESC should+contain at least two characters. If there is no similar-enough match,+no posting will be shown and the program exit code will be non-zero.++* Menu:++* Custom register output::+++File: hledger.info, Node: Custom register output, Up: register++24.25.1 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', 'tsv' (_Added in+1.32_), and 'json'.+++File: hledger.info, Node: rewrite, Next: roi, Prev: register, Up: PART 4 COMMANDS++24.26 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+transaction'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+commodity.++* Menu:++* Re-write rules in a file::+* Diff output format::+* rewrite vs print --auto::+++File: hledger.info, Node: Re-write rules in a file, Next: Diff output format, Up: rewrite++24.26.1 Re-write rules in a file+--------------------------------++During the run this tool will execute so called "Automated Transactions"+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+transactions 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+postings.+++File: hledger.info, Node: Diff output format, Next: rewrite vs print --auto, Prev: Re-write rules in a file, Up: rewrite++24.26.2 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+containing 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+++File: hledger.info, Node: rewrite vs print --auto, Prev: Diff output format, Up: rewrite++24.26.3 rewrite vs. print -auto+-------------------------------++This command predates print -auto, and currently does much the same+thing, but with these differences:++ * with multiple files, rewrite lets rules in any file affect all+ other files. print -auto uses standard directive scoping; rules+ affect only child files.++ * rewrite's query limits which transactions can be rewritten; all are+ printed. print -auto's query limits which transactions are+ printed.++ * rewrite applies rules specified on command line or in the journal.+ print -auto applies rules specified in the journal.+++File: hledger.info, Node: roi, Next: stats, Prev: rewrite, Up: PART 4 COMMANDS++24.27 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, also known as money-weighted rate of return) and time-weighted+rate of return (TWR) for your investments for the time period requested.+IRR is always annualized due to the way it is computed, but TWR is+reported both as a rate over the chosen reporting period and as an+annual rate.++ 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:++ * 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.+ * Error (SearchFailed): Failed to find solution for Internal Rate of+ Return (IRR). Either search does not converge to a solution, or+ converges too slowly.++ Examples:++ * Using roi to compute total return of investment in stocks:+ https://github.com/simonmichael/hledger/blob/master/examples/investing/roi-unrealised.ledger++ * Cookbook > Return on Investment: https://hledger.org/roi.html++* Menu:++* Spaces and special characters in --inv and --pnl::+* Semantics of --inv and --pnl::+* IRR and TWR explained::+++File: hledger.info, Node: Spaces and special characters in --inv and --pnl, Next: Semantics of --inv and --pnl, Up: roi++24.27.1 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'"+++File: hledger.info, Node: Semantics of --inv and --pnl, Next: IRR and TWR explained, Prev: Spaces and special characters in --inv and --pnl, Up: roi++24.27.2 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.++ * "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++ * "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+++File: hledger.info, Node: IRR and TWR explained, Prev: Semantics of --inv and --pnl, Up: roi++24.27.3 IRR and TWR explained+-----------------------------++"ROI" stands for "return on investment". Traditionally this was+computed as a difference between current value of investment and its+initial value, expressed in percentage of the initial value.++ However, this approach is only practical in simple cases, where+investments receives no in-flows or out-flows of money, and where rate+of growth is fixed over time. For more complex scenarios you need+different ways to compute rate of return, and this command implements+two of them: IRR and TWR.++ Internal rate of return, or "IRR" (also called "money-weighted rate+of return") takes into account effects of in-flows and out-flows, and+the time between them. Investment at a particular fixed interest rate+is going to give you more interest than the same amount invested at the+same interest rate, but made later in time. If you are withdrawing from+your investment, your future gains would be smaller (in absolute+numbers), and will be a smaller percentage of your initial investment,+so your IRR will be smaller. And if you are adding to your investment,+you will receive bigger absolute gains, which will be a bigger+percentage of your initial investment, so your IRR will be larger.++ 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 "unrealized+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+account for the effect of your in-flows and out-flows, but unlike IRR it+will try to compute the true rate of return of the underlying asset,+compensating for the effect that deposits and withdrawas have on the+apparent rate of growth of your investment.++ 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, and make TWR less sensitive than IRR to the effects of+cash in-flows and out-flows.++ References:++ * Explanation of rate of return+ * Explanation of IRR+ * Explanation of TWR+ * IRR vs TWR+ * Examples of computing IRR and TWR and discussion of the limitations+ of both metrics+++File: hledger.info, Node: stats, Next: tags, Prev: roi, Up: PART 4 COMMANDS++24.28 stats+===========++Show journal and performance statistics.++ The stats command shows summary information for the whole journal, or+a matched part of it. With a reporting interval, it shows a report for+each report period.++ The default output is fairly impersonal, though it reveals the main+file name. With '-v/--verbose', more details are shown, like file+paths, included files, and commodity names.++ It also shows some run time statistics:++ * elapsed time+ * throughput: the number of transactions processed per second+ * live: the peak memory in use by the program to do its work+ * alloc: the peak memory allocation from the OS as seen by GHC.+ Measuring this externally, eg with GNU time, is more accurate;+ usually that will be a larger number; sometimes (with swapping?)+ smaller.++ The 'stats' command's run time is similar to that of a balance+report.++ Example:++$ hledger stats -f examples/1ktxns-1kaccts.journal +Main file : .../1ktxns-1kaccts.journal+Included files : 0+Txns span : 2000-01-01 to 2002-09-27 (1000 days)+Last txn : 2002-09-26 (7827 days ago)+Txns : 1000 (1.0 per day)+Txns last 30 days : 0 (0.0 per day)+Txns last 7 days : 0 (0.0 per day)+Payees/descriptions : 1000+Accounts : 1000 (depth 10)+Commodities : 26+Market prices : 1000+Runtime stats : 0.12 s elapsed, 8266 txns/s, 4 MB live, 16 MB alloc++ This command supports the -o/-output-file option (but not+-O/-output-format).+++File: hledger.info, Node: tags, Next: test, Prev: stats, Up: PART 4 COMMANDS++24.29 tags+==========++List the tags used in the journal, or their values.++ This command lists the tag names used in the journal, whether on+transactions, postings, or account declarations.++ With a TAGREGEX argument, only tag names matching this regular+expression (case insensitive, infix matched) are shown.++ With QUERY arguments, only transactions and accounts matching this+query are considered. If the query involves transaction fields (date:,+desc:, amt:, ...), the search is restricted to the matched transactions+and their accounts.++ With the -values flag, the tags' unique non-empty values are listed+instead. With -E/-empty, blank/empty values are also shown.++ With -parsed, tags or values are shown in the order they were parsed,+with duplicates included. (Except, tags from account declarations are+always shown first.)++ Tip: remember, accounts also acquire tags from their parents,+postings also acquire tags from their account and transaction,+transactions also acquire tags from their postings.+++File: hledger.info, Node: test, Prev: tags, Up: PART 4 COMMANDS++24.30 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).+++File: hledger.info, Node: PART 5 COMMON TASKS, Next: BUGS, Prev: PART 4 COMMANDS, Up: Top++25 PART 5: COMMON TASKS+***********************++Here are some quick examples of how to do some basic tasks with hledger.++* Menu:++* Getting help::+* Constructing command lines::+* Starting a journal file::+* Setting LEDGER_FILE::+* Setting opening balances::+* Recording transactions::+* Reconciling::+* Reporting::+* Migrating to a new file::+++File: hledger.info, Node: Getting help, Next: Constructing command lines, Up: PART 5 COMMON TASKS++25.1 Getting help+=================++Here's how to list commands and view options and command docs:++$ hledger # show available commands+$ hledger --help # show common options+$ hledger CMD --help # show CMD's options, common options and CMD's documentation++ You can also view your hledger version's manual in several formats by+using the help command. Eg:++$ hledger help # show the hledger manual with info, man or $PAGER (best available)+$ hledger help journal # show the journal topic in the hledger manual+$ hledger help --help # find out more about the help command++ To view manuals and introductory docs on the web, visit+https://hledger.org. Chat and mail list support and discussion archives+can be found at https://hledger.org/support.+++File: hledger.info, Node: Constructing command lines, Next: Starting a journal file, Prev: Getting help, Up: PART 5 COMMON TASKS++25.2 Constructing command lines+===============================++hledger has a flexible command line interface. We strive to keep it+simple and ergonomic, but if you run into one of the sharp edges+described in OPTIONS, here are some tips that might help:++ * command-specific options must go after the command (it's fine to+ put common options there too: 'hledger CMD OPTS ARGS')+ * running add-on executables directly simplifies command line parsing+ ('hledger-ui OPTS ARGS')+ * enclose "problematic" args in single quotes+ * if needed, also add a backslash to hide regular expression+ metacharacters from the shell+ * to see how a misbehaving command line is being parsed, add+ '--debug=2'.+++File: hledger.info, Node: Starting a journal file, Next: Setting LEDGER_FILE, Prev: Constructing command lines, Up: PART 5 COMMON TASKS++25.3 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 (see below). 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 2023.journal+$ echo "export LEDGER_FILE=$HOME/finance/2023.journal" >> ~/.profile+$ source ~/.profile+$ hledger stats+Main file : /Users/simon/finance/2023.journal+Included files : +Transactions span : to (0 days)+Last transaction : none+Transactions : 0 (0.0 per day)+Transactions last 30 days: 0 (0.0 per day)+Transactions last 7 days : 0 (0.0 per day)+Payees/descriptions : 0+Accounts : 0 (depth 0)+Commodities : 0 ()+Market prices : 0 ()+++File: hledger.info, Node: Setting LEDGER_FILE, Next: Setting opening balances, Prev: Starting a journal file, Up: PART 5 COMMON TASKS++25.4 Setting LEDGER_FILE+========================++How to set 'LEDGER_FILE' permanently depends on your setup:++ On unix and mac, running these commands in the terminal will work for+many people; adapt as needed:++$ echo 'export LEDGER_FILE=~/finance/2023.journal' >> ~/.profile+$ source ~/.profile++ When correctly configured, in a new terminal window 'env | grep+LEDGER_FILE' will show your file, and so will 'hledger files'.++ On mac, this additional step might be helpful for GUI applications+(like Emacs started from the dock): add an entry to+'~/.MacOSX/environment.plist' like++{+ "LEDGER_FILE" : "~/finance/2023.journal"+}++ and then run 'killall Dock' in a terminal window (or restart the+machine).++ On Windows, see https://www.java.com/en/download/help/path.html, or+try running these commands in a powershell window (let us know if it+persists across a reboot, and if you need to be an Administrator):++> CD+> MKDIR finance+> SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal"+++File: hledger.info, Node: Setting opening balances, Next: Recording transactions, Prev: Setting LEDGER_FILE, Up: PART 5 COMMON TASKS++25.5 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+balances on this date. Here are two ways to do it:++ * The first way: open the journal in any text editor and save an+ entry like this:++ 2023-01-01 * opening balances+ assets:bank:checking $1000 = $1000+ assets:bank:savings $2000 = $2000+ assets:cash $100 = $100+ liabilities:creditcard $-50 = $-50+ equity:opening/closing balances++ 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.++ * 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/2023.journal+ Any command line arguments will be used as defaults.+ Use tab key to complete, readline keys to edit, enter to accept defaults.+ An optional (CODE) may follow transaction dates.+ An optional ; COMMENT may follow descriptions or amounts.+ If you make a mistake, enter < at any prompt to go one step backward.+ To end a transaction, enter . when prompted.+ To quit, enter . at a date prompt or press control-d or control-c.+ Date [2023-02-07]: 2023-01-01+ Description: * opening balances+ Account 1: assets:bank:checking+ Amount 1: $1000+ Account 2: assets:bank:savings+ Amount 2 [$-1000]: $2000+ Account 3: assets:cash+ Amount 3 [$-3000]: $100+ Account 4: liabilities:creditcard+ Amount 4 [$-3100]: $-50+ Account 5: equity:opening/closing balances+ Amount 5 [$-3050]: + Account 6 (or . or enter to finish this transaction): .+ 2023-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050+ + Save this transaction to the journal ? [y]: + Saved.+ Starting the next transaction (. or ctrl-D/ctrl-C to quit)+ Date [2023-01-01]: .++ If you're using version control, this could be a good time to commit+the journal. Eg:++$ git commit -m 'initial balances' 2023.journal+++File: hledger.info, Node: Recording transactions, Next: Reconciling, Prev: Setting opening balances, Up: PART 5 COMMON TASKS++25.6 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:++2023/1/10 * gift received+ assets:cash $20+ income:gifts++2023.1.12 * farmers market+ expenses:food $13+ assets:cash++2023-01-15 paycheck+ income:salary+ assets:bank:checking $1000+++File: hledger.info, Node: Reconciling, Next: Reporting, Prev: Recording transactions, Up: PART 5 COMMON TASKS++25.7 Reconciling+================++Periodically you should reconcile - compare your hledger-reported+balances 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+discrepancies.++ 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:++ 2023-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 checking -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 transaction 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+--register 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 '2023-01-15' and 'paycheck'++ If you're using version control, this can be another good time to+commit:++$ git commit -m 'txns' 2023.journal+++File: hledger.info, Node: Reporting, Next: Migrating to a new file, Prev: Reconciling, Up: PART 5 COMMON TASKS++25.8 Reporting+==============++Here are some basic reports.++ Show all transactions:++$ hledger print+2023-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++2023-01-10 * gift received+ assets:cash $20+ income:gifts++2023-01-12 * farmers market+ expenses:food $13+ assets:cash++2023-01-15 * paycheck+ income:salary+ assets:bank:checking $1000++2023-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ 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 -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 -2+Balance Sheet 2023-01-16++ || 2023-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 2023-01-01-2023-01-16++ || 2023-01-01-2023-01-16 +===============++=======================+ Revenues || +---------------++-----------------------+ income:gifts || $20 + income:salary || $1000 +---------------++-----------------------+ || $1020 +===============++=======================+ Expenses || +---------------++-----------------------+ expenses:food || $13 + expenses:misc || $2 +---------------++-----------------------+ || $15 +===============++=======================+ Net: || $1005 ++ The final total is your net income during this period.++ Show transactions affecting your wallet, with running total:++$ hledger register cash+2023-01-01 opening balances assets:cash $100 $100+2023-01-10 gift received assets:cash $20 $120+2023-01-12 farmers market assets:cash $-13 $107+2023-01-16 adjust cash assets:cash $-2 $105++ Show weekly posting counts as a bar chart:++$ hledger activity -W+2019-12-30 *****+2023-01-06 ****+2023-01-13 ****+++File: hledger.info, Node: Migrating to a new file, Prev: Reporting, Up: PART 5 COMMON TASKS++25.9 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.+++File: hledger.info, Node: BUGS, Prev: PART 5 COMMON TASKS, Up: Top++26 BUGS+*******++We welcome bug reports in the hledger issue tracker (shortcut:+http://bugs.hledger.org), or on the #hledger chat or hledger mail list+(https://hledger.org/support).++ Some known issues and limitations:++ The need to precede add-on command options with '--' when invoked+from hledger is awkward. (See Command options, Constructing command+lines.)++ A UTF-8-aware system locale must be configured to work with non-ascii+data. (See Unicode characters, Troubleshooting.)++ On Microsoft Windows, depending whether you are running in a CMD+window or a Cygwin/MSYS/Mintty window and how you installed hledger,+non-ascii characters and colours may not be supported, and the tab key+may not be supported by 'hledger add'. (Running in a WSL window should+resolve these.)++ When processing large data files, hledger uses more memory than+Ledger.++* Menu:++* Troubleshooting::+++File: hledger.info, Node: Troubleshooting, Up: BUGS++26.1 Troubleshooting+====================++Here are some common issues you might encounter when you run hledger,+and how to resolve them (and remember also you can usually get quick+Support):++ *PATH issues: I get an error like "No command 'hledger' found"*+Depending how you installed hledger, the executables may not be in your+shell's PATH. Eg on unix systems, stack installs hledger in+'~/.local/bin' and cabal installs it in '~/.cabal/bin'. You may need to+add one of these directories to your shell's PATH, and/or open a new+terminal window.++ *LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not+using it*++ * 'LEDGER_FILE' should be a real environment variable, not just a+ shell variable. Eg on unix, the command 'env | grep LEDGER_FILE'+ should show it. You may need to use 'export' (see+ https://stackoverflow.com/a/7411509).+ * You may need to force your shell to see the new configuration. A+ simple way is to close your terminal window and open a new one.++ *LANG issues: I get errors like "Illegal byte sequence" or "Invalid+or incomplete multibyte or wide character" or "commitAndReleaseBuffer:+invalid argument (invalid character)"*+Programs compiled with GHC (hledger, haskell build tools, etc.) need+the system locale to be UTF-8-aware, or they will fail when they+encounter non-ascii characters. To fix it, set the LANG environment+variable to a locale which supports UTF-8 and which is installed on your+system.++ On unix, 'locale -a' lists the installed locales. Look for one which+mentions 'utf8', 'UTF-8' or similar. Some examples: 'C.UTF-8',+'en_US.utf-8', 'fr_FR.utf8'. If necessary, use your system package+manager to install one. Then select it by setting the 'LANG'+environment variable. Note, exact spelling and capitalisation of the+locale name may be important: Here's one common way to configure this+permanently for your shell:++$ echo "export LANG=en_US.utf8" >>~/.profile+# close and re-open terminal window++ If you are using Nix (not NixOS) for GHC and Hledger, you might need+to set the 'LOCALE_ARCHIVE' variable:++$ echo "export LOCALE_ARCHIVE=${glibcLocales}/lib/locale/locale-archive" >>~/.profile+# close and re-open terminal window++ *COMPATIBILITY ISSUES: hledger gives an error with my Ledger file*+Not all of Ledger's journal file syntax or feature set is supported.+See hledger and Ledger for full details.+++Tag Table:+Node: Top208+Node: PART 1 USER INTERFACE3811+Ref: #part-1-user-interface3950+Node: Input3950+Ref: #input4060+Node: Text encoding5027+Ref: #text-encoding5141+Node: Data formats5707+Ref: #data-formats5842+Node: Standard input7431+Ref: #standard-input7571+Node: Multiple files7798+Ref: #multiple-files7937+Node: Strict mode8535+Ref: #strict-mode8645+Node: Commands9369+Ref: #commands9471+Node: Add-on commands10538+Ref: #add-on-commands10640+Node: Options11756+Ref: #options11868+Node: General help options12196+Ref: #general-help-options12342+Node: General input options12624+Ref: #general-input-options12806+Node: General reporting options13463+Ref: #general-reporting-options13624+Node: Command line tips17014+Ref: #command-line-tips17144+Node: Option repetition17403+Ref: #option-repetition17547+Node: Special characters17651+Ref: #special-characters17824+Node: Single escaping shell metacharacters17987+Ref: #single-escaping-shell-metacharacters18228+Node: Double escaping regular expression metacharacters18831+Ref: #double-escaping-regular-expression-metacharacters19142+Node: Triple escaping for add-on commands19668+Ref: #triple-escaping-for-add-on-commands19928+Node: Less escaping20572+Ref: #less-escaping20726+Node: Unicode characters21050+Ref: #unicode-characters21225+Node: Regular expressions22637+Ref: #regular-expressions22810+Node: hledger's regular expressions25906+Ref: #hledgers-regular-expressions26065+Node: Argument files27451+Ref: #argument-files27587+Node: Output28084+Ref: #output28196+Node: Output destination28323+Ref: #output-destination28454+Node: Output format28879+Ref: #output-format29025+Node: CSV output30622+Ref: #csv-output30738+Node: HTML output30841+Ref: #html-output30979+Node: JSON output31073+Ref: #json-output31211+Node: SQL output32133+Ref: #sql-output32249+Node: Commodity styles32984+Ref: #commodity-styles33124+Node: Colour33862+Ref: #colour33980+Node: Box-drawing34384+Ref: #box-drawing34502+Node: Paging34792+Ref: #paging34906+Node: Debug output35859+Ref: #debug-output35965+Node: Environment36628+Ref: #environment36752+Node: PART 2 DATA FORMATS37296+Ref: #part-2-data-formats37439+Node: Journal37439+Ref: #journal37548+Node: Journal cheatsheet39916+Ref: #journal-cheatsheet40043+Node: Comments46130+Ref: #comments46258+Node: Transactions47074+Ref: #transactions47197+Node: Dates48211+Ref: #dates48318+Node: Simple dates48363+Ref: #simple-dates48479+Node: Posting dates48979+Ref: #posting-dates49097+Node: Status50066+Ref: #status50167+Node: Code51832+Ref: #code51935+Node: Description52167+Ref: #description52298+Node: Payee and note52854+Ref: #payee-and-note52960+Node: Transaction comments53945+Ref: #transaction-comments54098+Node: Postings54461+Ref: #postings54592+Node: Debits and credits55624+Ref: #debits-and-credits55771+Node: The two space delimiter56234+Ref: #the-two-space-delimiter56391+Node: Account names56799+Ref: #account-names56929+Node: Amounts58603+Ref: #amounts58731+Node: Decimal marks59632+Ref: #decimal-marks59759+Node: Digit group marks60736+Ref: #digit-group-marks60889+Node: Commodity61371+Ref: #commodity61500+Node: Costs62488+Ref: #costs62583+Node: Balance assertions64740+Ref: #balance-assertions64893+Node: Assertions and ordering65977+Ref: #assertions-and-ordering66166+Node: Assertions and multiple included files66705+Ref: #assertions-and-multiple-included-files66965+Node: Assertions and multiple -f files67465+Ref: #assertions-and-multiple--f-files67710+Node: Assertions and costs68107+Ref: #assertions-and-costs68316+Node: Assertions and commodities68757+Ref: #assertions-and-commodities68972+Node: Assertions and subaccounts70416+Ref: #assertions-and-subaccounts70642+Node: Assertions and virtual postings71086+Ref: #assertions-and-virtual-postings71324+Node: Assertions and auto postings71456+Ref: #assertions-and-auto-postings71686+Node: Assertions and precision72331+Ref: #assertions-and-precision72513+Node: Posting comments72780+Ref: #posting-comments72943+Node: Transaction balancing73320+Ref: #transaction-balancing73479+Node: Tags75322+Ref: #tags75441+Node: Tag names76784+Ref: #tag-names76891+Node: Special tags77279+Ref: #special-tags77411+Node: Tag values78924+Ref: #tag-values79034+Node: Directives79906+Ref: #directives80033+Node: Directives and multiple files81363+Ref: #directives-and-multiple-files81541+Node: Directive effects82308+Ref: #directive-effects82462+Node: account directive85464+Ref: #account-directive85620+Node: Account comments86914+Ref: #account-comments87065+Node: Account error checking87573+Ref: #account-error-checking87766+Node: Account display order88955+Ref: #account-display-order89143+Node: Account types90153+Ref: #account-types90294+Node: alias directive93927+Ref: #alias-directive94088+Node: Basic aliases95138+Ref: #basic-aliases95269+Node: Regex aliases96013+Ref: #regex-aliases96170+Node: Combining aliases97060+Ref: #combining-aliases97238+Node: Aliases and multiple files98514+Ref: #aliases-and-multiple-files98718+Node: end aliases directive99297+Ref: #end-aliases-directive99516+Node: Aliases can generate bad account names99665+Ref: #aliases-can-generate-bad-account-names99913+Node: Aliases and account types100498+Ref: #aliases-and-account-types100690+Node: commodity directive101386+Ref: #commodity-directive101560+Node: Commodity directive syntax102973+Ref: #commodity-directive-syntax103158+Node: Commodity error checking104609+Ref: #commodity-error-checking104790+Node: decimal-mark directive105084+Ref: #decimal-mark-directive105266+Node: include directive105663+Ref: #include-directive105827+Node: P directive106739+Ref: #p-directive106884+Node: payee directive107773+Ref: #payee-directive107922+Node: tag directive108395+Ref: #tag-directive108550+Node: Periodic transactions109007+Ref: #periodic-transactions109172+Node: Periodic rule syntax111161+Ref: #periodic-rule-syntax111339+Node: Periodic rules and relative dates111984+Ref: #periodic-rules-and-relative-dates112250+Node: Two spaces between period expression and description!112761+Ref: #two-spaces-between-period-expression-and-description113038+Node: Auto postings113722+Ref: #auto-postings113870+Node: Auto postings and multiple files116700+Ref: #auto-postings-and-multiple-files116864+Node: Auto postings and dates117265+Ref: #auto-postings-and-dates117513+Node: Auto postings and transaction balancing / inferred amounts / balance assertions117688+Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions118044+Node: Auto posting tags118547+Ref: #auto-posting-tags118829+Node: Auto postings on forecast transactions only119465+Ref: #auto-postings-on-forecast-transactions-only119711+Node: Other syntax119958+Ref: #other-syntax120074+Node: Balance assignments120730+Ref: #balance-assignments120886+Node: Balance assignments and costs122258+Ref: #balance-assignments-and-costs122470+Node: Balance assignments and multiple files122680+Ref: #balance-assignments-and-multiple-files122910+Node: Bracketed posting dates123103+Ref: #bracketed-posting-dates123287+Node: D directive123801+Ref: #d-directive123969+Node: apply account directive125574+Ref: #apply-account-directive125754+Node: Y directive126441+Ref: #y-directive126601+Node: Secondary dates127429+Ref: #secondary-dates127583+Node: Star comments128397+Ref: #star-comments128557+Node: Valuation expressions129089+Ref: #valuation-expressions129266+Node: Virtual postings129388+Ref: #virtual-postings129565+Node: Other Ledger directives131012+Ref: #other-ledger-directives131208+Node: Other cost/lot notations131774+Ref: #other-costlot-notations131947+Node: CSV134536+Ref: #csv134629+Node: CSV rules cheatsheet136626+Ref: #csv-rules-cheatsheet136755+Node: source138553+Ref: #source138676+Node: separator139556+Ref: #separator139669+Node: skip140209+Ref: #skip140317+Node: date-format140861+Ref: #date-format140982+Node: timezone141706+Ref: #timezone141829+Node: newest-first142834+Ref: #newest-first142972+Node: intra-day-reversed143549+Ref: #intra-day-reversed143703+Node: decimal-mark144151+Ref: #decimal-mark144292+Node: fields list144631+Ref: #fields-list144770+Node: Field assignment146441+Ref: #field-assignment146585+Node: Field names147662+Ref: #field-names147793+Node: date field148996+Ref: #date-field149114+Node: date2 field149162+Ref: #date2-field149303+Node: status field149359+Ref: #status-field149502+Node: code field149551+Ref: #code-field149696+Node: description field149741+Ref: #description-field149901+Node: comment field149960+Ref: #comment-field150115+Node: account field150408+Ref: #account-field150558+Node: amount field151128+Ref: #amount-field151277+Node: currency field153969+Ref: #currency-field154122+Node: balance field154379+Ref: #balance-field154511+Node: if block154904+Ref: #if-block155025+Node: Matchers156433+Ref: #matchers156547+Node: What matchers match157344+Ref: #what-matchers-match157493+Node: Combining matchers157933+Ref: #combining-matchers158101+Node: Match groups158638+Ref: #match-groups158766+Node: if table159534+Ref: #if-table159656+Node: balance-type161537+Ref: #balance-type161666+Node: include162366+Ref: #include162493+Node: Working with CSV162937+Ref: #working-with-csv163084+Node: Rapid feedback163491+Ref: #rapid-feedback163624+Node: Valid CSV164076+Ref: #valid-csv164222+Node: File Extension164954+Ref: #file-extension165127+Node: Reading CSV from standard input165691+Ref: #reading-csv-from-standard-input165915+Node: Reading multiple CSV files166079+Ref: #reading-multiple-csv-files166310+Node: Reading files specified by rule166551+Ref: #reading-files-specified-by-rule166779+Node: Valid transactions167950+Ref: #valid-transactions168149+Node: Deduplicating importing168777+Ref: #deduplicating-importing168972+Node: Setting amounts170008+Ref: #setting-amounts170179+Node: Amount signs172537+Ref: #amount-signs172707+Node: Setting currency/commodity173604+Ref: #setting-currencycommodity173808+Node: Amount decimal places174982+Ref: #amount-decimal-places175188+Node: Referencing other fields175500+Ref: #referencing-other-fields175713+Node: How CSV rules are evaluated176610+Ref: #how-csv-rules-are-evaluated176827+Node: Well factored rules178280+Ref: #well-factored-rules178448+Node: CSV rules examples178772+Ref: #csv-rules-examples178907+Node: Bank of Ireland178972+Ref: #bank-of-ireland179109+Node: Coinbase180571+Ref: #coinbase180709+Node: Amazon181756+Ref: #amazon181881+Node: Paypal183600+Ref: #paypal183708+Node: Timeclock191352+Ref: #timeclock191457+Node: Timedot193633+Ref: #timedot193756+Node: Timedot examples196877+Ref: #timedot-examples196983+Node: PART 3 REPORTING CONCEPTS199154+Ref: #part-3-reporting-concepts199323+Node: Amount formatting199323+Ref: #amount-formatting199479+Node: Commodity display style199581+Ref: #commodity-display-style199735+Node: Rounding201422+Ref: #rounding201577+Node: Trailing decimal marks202027+Ref: #trailing-decimal-marks202206+Node: Amount parseability202960+Ref: #amount-parseability203116+Node: Time periods204541+Ref: #time-periods204667+Node: Report start & end date204785+Ref: #report-start-end-date204937+Node: Smart dates206596+Ref: #smart-dates206749+Node: Report intervals208617+Ref: #report-intervals208772+Node: Date adjustment209190+Ref: #date-adjustment209350+Node: Period expressions210201+Ref: #period-expressions210342+Node: Period expressions with a report interval212106+Ref: #period-expressions-with-a-report-interval212340+Node: More complex report intervals212554+Ref: #more-complex-report-intervals212799+Node: Multiple weekday intervals214600+Ref: #multiple-weekday-intervals214789+Node: Depth215611+Ref: #depth215713+Node: Queries216009+Ref: #queries216111+Node: Query types217707+Ref: #query-types217828+Node: Combining query terms221062+Ref: #combining-query-terms221239+Node: Queries and command options222802+Ref: #queries-and-command-options223007+Node: Queries and account aliases223256+Ref: #queries-and-account-aliases223461+Node: Queries and valuation223581+Ref: #queries-and-valuation223738+Node: Pivoting223943+Ref: #pivoting224057+Node: Generating data225834+Ref: #generating-data225966+Node: Forecasting227549+Ref: #forecasting227674+Node: --forecast228205+Ref: #forecast228336+Node: Inspecting forecast transactions229306+Ref: #inspecting-forecast-transactions229508+Node: Forecast reports230638+Ref: #forecast-reports230811+Node: Forecast tags231747+Ref: #forecast-tags231907+Node: Forecast period in detail232367+Ref: #forecast-period-in-detail232561+Node: Forecast troubleshooting233455+Ref: #forecast-troubleshooting233623+Node: Budgeting234526+Ref: #budgeting234646+Node: Cost reporting235083+Ref: #cost-reporting235217+Node: Recording costs235878+Ref: #recording-costs236014+Node: Reporting at cost237605+Ref: #reporting-at-cost237780+Node: Equity conversion postings238370+Ref: #equity-conversion-postings238584+Node: Inferring equity conversion postings241015+Ref: #inferring-equity-conversion-postings241278+Node: Combining costs and equity conversion postings242030+Ref: #combining-costs-and-equity-conversion-postings242340+Node: Requirements for detecting equity conversion postings243255+Ref: #requirements-for-detecting-equity-conversion-postings243577+Node: Infer cost and equity by default ?244777+Ref: #infer-cost-and-equity-by-default245006+Node: Value reporting245214+Ref: #value-reporting245356+Node: -V Value246095+Ref: #v-value246227+Node: -X Value in specified commodity246422+Ref: #x-value-in-specified-commodity246623+Node: Valuation date246772+Ref: #valuation-date246949+Node: Finding market price247732+Ref: #finding-market-price247943+Node: --infer-market-prices market prices from transactions249112+Ref: #infer-market-prices-market-prices-from-transactions249394+Node: Valuation commodity252156+Ref: #valuation-commodity252376+Node: --value Flexible valuation253589+Ref: #value-flexible-valuation253788+Node: Valuation examples255432+Ref: #valuation-examples255632+Node: Interaction of valuation and queries257564+Ref: #interaction-of-valuation-and-queries257804+Node: Effect of valuation on reports258281+Ref: #effect-of-valuation-on-reports258484+Node: PART 4 COMMANDS266179+Ref: #part-4-commands266328+Node: Commands overview266707+Ref: #commands-overview266841+Node: DATA ENTRY267020+Ref: #data-entry267144+Node: DATA CREATION267343+Ref: #data-creation267497+Node: DATA MANAGEMENT267615+Ref: #data-management267780+Node: REPORTS FINANCIAL267901+Ref: #reports-financial268076+Node: REPORTS VERSATILE268381+Ref: #reports-versatile268554+Node: REPORTS BASIC268807+Ref: #reports-basic268959+Node: HELP269468+Ref: #help269590+Node: ADD-ONS269700+Ref: #add-ons269806+Node: accounts270385+Ref: #accounts270518+Node: activity272405+Ref: #activity272524+Node: add272898+Ref: #add273008+Node: aregister275994+Ref: #aregister276115+Node: aregister and posting dates279021+Ref: #aregister-and-posting-dates279166+Node: balance279922+Ref: #balance280048+Node: balance features281038+Ref: #balance-features281178+Node: Simple balance report283088+Ref: #simple-balance-report283273+Node: Balance report line format284898+Ref: #balance-report-line-format285100+Node: Filtered balance report287258+Ref: #filtered-balance-report287450+Node: List or tree mode287777+Ref: #list-or-tree-mode287945+Node: Depth limiting289290+Ref: #depth-limiting289456+Node: Dropping top-level accounts290057+Ref: #dropping-top-level-accounts290257+Node: Showing declared accounts290567+Ref: #showing-declared-accounts290766+Node: Sorting by amount291297+Ref: #sorting-by-amount291464+Node: Percentages292134+Ref: #percentages292293+Node: Multi-period balance report292841+Ref: #multi-period-balance-report293041+Node: Balance change end balance295418+Ref: #balance-change-end-balance295627+Node: Balance report types297055+Ref: #balance-report-types297236+Node: Calculation type297734+Ref: #calculation-type297889+Node: Accumulation type298438+Ref: #accumulation-type298618+Node: Valuation type299539+Ref: #valuation-type299727+Node: Combining balance report types300728+Ref: #combining-balance-report-types300922+Node: Budget report302760+Ref: #budget-report302922+Node: Using the budget report305065+Ref: #using-the-budget-report305238+Node: Budget date surprises307341+Ref: #budget-date-surprises307541+Node: Selecting budget goals308705+Ref: #selecting-budget-goals308908+Node: Budgeting vs forecasting309653+Ref: #budgeting-vs-forecasting309830+Node: Balance report layout311330+Ref: #balance-report-layout311515+Node: Wide layout312468+Ref: #wide-layout312603+Node: Tall layout314873+Ref: #tall-layout315028+Node: Bare layout316179+Ref: #bare-layout316334+Node: Tidy layout318238+Ref: #tidy-layout318373+Node: Some useful balance reports319782+Ref: #some-useful-balance-reports319957+Node: balancesheet321042+Ref: #balancesheet321187+Node: balancesheetequity322798+Ref: #balancesheetequity322956+Node: cashflow324976+Ref: #cashflow325107+Node: check326594+Ref: #check326708+Node: Default checks327512+Ref: #default-checks327638+Node: Strict checks328135+Ref: #strict-checks328280+Node: Other checks328760+Ref: #other-checks328902+Node: Custom checks329435+Ref: #custom-checks329592+Node: More about specific checks330009+Ref: #more-about-specific-checks330171+Node: close330877+Ref: #close330988+Node: close --migrate331641+Ref: #close---migrate331768+Node: close --close333407+Ref: #close---close333551+Node: close --open333787+Ref: #close---open333928+Node: close --assert334038+Ref: #close---assert334184+Node: close --assign334405+Ref: #close---assign334553+Node: close --retain335079+Ref: #close---retain335232+Node: close customisation335977+Ref: #close-customisation336156+Node: close and balance assertions337623+Ref: #close-and-balance-assertions337820+Node: close examples339147+Ref: #close-examples339288+Node: Retain earnings339386+Ref: #retain-earnings339545+Node: Migrate balances to a new file339891+Ref: #migrate-balances-to-a-new-file340117+Node: More detailed close examples341245+Ref: #more-detailed-close-examples341443+Node: codes341469+Ref: #codes341586+Node: commodities342450+Ref: #commodities342578+Node: demo342648+Ref: #demo342769+Node: descriptions343685+Ref: #descriptions343815+Node: diff344106+Ref: #diff344221+Node: files345263+Ref: #files345372+Node: help345513+Ref: #help-1345622+Node: import346995+Ref: #import347118+Node: Deduplication348226+Ref: #deduplication348351+Node: Import testing351212+Ref: #import-testing351377+Node: Importing balance assignments352220+Ref: #importing-balance-assignments352426+Node: Commodity display styles353075+Ref: #commodity-display-styles353248+Node: incomestatement353377+Ref: #incomestatement353519+Node: notes354993+Ref: #notes355115+Node: payees355477+Ref: #payees355592+Node: prices356111+Ref: #prices356226+Node: print356879+Ref: #print356994+Node: print explicitness357970+Ref: #print-explicitness358113+Node: print amount style358892+Ref: #print-amount-style359062+Node: print parseability360132+Ref: #print-parseability360304+Node: print other features361053+Ref: #print-other-features361232+Node: print output format361753+Ref: #print-output-format361901+Node: register365040+Ref: #register365162+Node: Custom register output370193+Ref: #custom-register-output370324+Node: rewrite371671+Ref: #rewrite371789+Node: Re-write rules in a file373687+Ref: #re-write-rules-in-a-file373850+Node: Diff output format374999+Ref: #diff-output-format375182+Node: rewrite vs print --auto376274+Ref: #rewrite-vs.-print---auto376434+Node: roi376990+Ref: #roi377097+Node: Spaces and special characters in --inv and --pnl378909+Ref: #spaces-and-special-characters-in---inv-and---pnl379149+Node: Semantics of --inv and --pnl379637+Ref: #semantics-of---inv-and---pnl379876+Node: IRR and TWR explained381726+Ref: #irr-and-twr-explained381886+Node: stats385139+Ref: #stats385247+Node: tags386761+Ref: #tags-1386868+Node: test387877+Ref: #test387970+Node: PART 5 COMMON TASKS388712+Ref: #part-5-common-tasks388858+Node: Getting help389156+Ref: #getting-help389297+Node: Constructing command lines390057+Ref: #constructing-command-lines390258+Node: Starting a journal file390915+Ref: #starting-a-journal-file391117+Node: Setting LEDGER_FILE392319+Ref: #setting-ledger_file392511+Node: Setting opening balances393468+Ref: #setting-opening-balances393669+Node: Recording transactions396810+Ref: #recording-transactions396999+Node: Reconciling397555+Ref: #reconciling397707+Node: Reporting399964+Ref: #reporting400113+Node: Migrating to a new file404098+Ref: #migrating-to-a-new-file404255+Node: BUGS404554+Ref: #bugs404644+Node: Troubleshooting405523+Ref: #troubleshooting405623 End Tag Table
embeddedfiles/hledger.txt view
@@ -16,9104 +16,9104 @@ and largely compatible with ledger(1), and largely interconvertible with beancount(1). - This manual is for hledger's command line interface, version 1.33. It- also describes the common options, file formats and concepts used by- all hledger programs. It might accidentally teach you some bookkeep-- ing/accounting as well! You don't need to know everything in here to- use hledger productively, but when you have a question about function-- ality, this doc should answer it. It is detailed, so do skip ahead or- skim when needed. You can read it on hledger.org, or as an info manual- or man page on your system. You can also get it from hledger itself- with- hledger --man, hledger --info or hledger help [TOPIC].-- The main function of the hledger CLI is to read plain text files de-- scribing financial transactions, crunch the numbers, and print a useful- report on the terminal (or save it as HTML, CSV, JSON or SQL). Many- reports are available, as subcommands. hledger will also detect other- hledger-* executables as extra subcommands.-- hledger usually reads from (and appends to) a journal file specified by- the LEDGER_FILE environment variable (defaulting to- $HOME/.hledger.journal); or you can specify files with -f options. It- can also read timeclock files, timedot files, or any CSV/SSV/TSV file- with a date field.-- Here is a small journal file describing one transaction:-- 2015-10-16 bought food- expenses:food $10- assets:cash-- Transactions are dated movements of money (etc.) between two or more- accounts: bank accounts, your wallet, revenue/expense categories, peo-- ple, etc. You can choose any account names you wish, using : to indi-- cate subaccounts. There must be at least two spaces between account- name and amount. Positive amounts are inflow to that account (debit),- negatives are outflow from it (credit). (Some reports show revenue,- liability and equity account balances as negative numbers as a result;- this is normal.)-- hledger's add command can help you add transactions, or you can install- other data entry UIs like hledger-web or hledger-iadd. For more exten-- sive/efficient changes, use a text editor: Emacs + ledger-mode, VIM +- vim-ledger, or VS Code + hledger-vscode are some good choices (see- https://hledger.org/editors.html).-- To get started, run hledger add and follow the prompts, or save some- entries like the above in $HOME/.hledger.journal, then try commands- like:-- $ hledger print -x- $ hledger aregister assets- $ hledger balance- $ hledger balancesheet- $ hledger incomestatement-- Run hledger to list the commands. See also the "Starting a journal- file" and "Setting opening balances" sections in PART 5: COMMON TASKS.--PART 1: USER INTERFACE-Input- hledger reads one or more data files, each time you run it. You can- specify a file with -f, like so-- $ hledger -f FILE print-- Files are most often in hledger's journal format, with the .journal- file extension (.hledger or .j also work); these files describe trans-- actions, like an accounting general journal.-- When no file is specified, hledger looks for .hledger.journal in your- home directory.-- But most people prefer to keep financial files in a dedicated folder,- perhaps with version control. Also, starting a new journal file each- year is common (it's not required, but helps keep things fast and or-- ganised). So we usually configure a different journal file, by setting- the LEDGER_FILE environment variable, to something like ~/fi-- nance/2023.journal. For more about how to do that on your system, see- Common tasks > Setting LEDGER_FILE.-- Text encoding- Data files containing non-ascii characters must use UTF-8 encoding. An- optional byte order mark (BOM) is allowed, at the beginning of the file- (only).-- Also, your system should be configured with a locale that can decode- UTF-8 text. On some unix systems, you may need set the LANG environ-- ment variable, eg. You can read more about this in Unicode characters,- below.-- On unix systems you can check a file's encoding with the file command.- If you need to import from a UTF-16-encoded CSV file, say, you can con-- vert it to UTF-8 with the iconv command.-- 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: Automatically used for- files with extensions:- ------------------------------------------------------------------------------ journal hledger journal files and some .journal .j .hledger- Ledger journals, for transactions .ledger- timeclock timeclock files, for precise time .timeclock- logging- timedot timedot files, for approximate .timedot- time logging- csv Comma or other character sepa- .csv- rated values, for data import- ssv Semicolon separated values .ssv- tsv Tab separated values .tsv- rules CSV/SSV/TSV/other separated val- .rules- ues, alternate way-- These formats are described in more detail below.-- hledger detects the format automatically based on the file extensions- shown above. If it can't recognise the file extension, it assumes- journal format. So for non-journal files, it's important to use a- 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 containing tab- separated values:-- $ hledger -f tsv:/some/file.dat stats-- Standard input- The file name - means standard input:-- $ cat FILE | hledger -f- print-- If reading non-journal data in this way, you'll need to add a file for-- mat prefix, like:-- $ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:--- Multiple files- You can specify multiple -f options, to read multiple files as one big- journal. When doing this, note that certain features (described below)- will be affected:-- o Balance assertions will not see the effect of transactions in previ-- ous files. (Usually this doesn't matter as each file will set the- corresponding opening balances.)-- o Some directives will not affect previous or subsequent files.-- If needed, you can work around these by using a single parent file- which includes the others, or concatenating the files into one, 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 use the check command to run individual checks -- the ones- listed above and some more.--Commands- hledger provides various subcommands for getting things done. Most of- these commands do not change the journal file; they just read it and- output a report. A few commands assist with adding data and file man-- agement.-- To show the commands list, run hledger with no arguments. The commands- are described in detail in PART 4: COMMANDS, below.-- To use a particular command, run hledger CMD [CMDOPTS] [CMDARGS],-- o CMD is the full command name, or its standard abbreviation shown in- the commands list, or any unambiguous prefix of the name.-- o CMDOPTS are command-specific options, if any. Command-specific op-- tions must be written after the command name. Eg: hledger print -x.-- o CMDARGS are additional arguments to the command, if any. Most- hledger commands accept arguments representing a query, to limit the- data in some way. Eg: hledger reg assets:checking.-- To list a command's options, arguments, and documentation in the termi-- nal, run hledger CMD -h. Eg: hledger bal -h.-- Add-on commands- In addition to the built-in commands, you can install add-on commands:- programs or scripts named "hledger-SOMETHING", which will also appear- in hledger's commands list. If you used the hledger-install script,- you will have several add-ons installed already. Some more can be- found in hledger's bin/ directory, documented at- https://hledger.org/scripts.html.-- More precisely, add-on commands are programs or scripts in your shell's- PATH, whose name starts with "hledger-" and ends with no extension or a- recognised extension (".bat", ".com", ".exe", ".hs", ".js", ".lhs",- ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"), and (on unix- and mac) which has executable permission for the current user.-- You can run add-on commands using hledger, much like built-in commands:- hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]. But note the double- hyphen argument, required before add-on-specific options. Eg: hledger- ui -- --watch or hledger web -- --serve. If this causes difficulty,- you can always run the add-on directly, without using hledger:- hledger-ui --watch or hledger-web --serve.--Options- Run hledger -h to see general command line help, and general options- which are common to most hledger commands. These options can be writ-- ten anywhere on the command line. They can be grouped into help, in-- put, and reporting options:-- 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-- --pivot FIELDNAME- use some other field or tag for the account name-- -I --ignore-assertions- disable balance assertion checks (note: does not disable balance- assignments)-- -s --strict- do extra error checking (check that all posted accounts are de-- clared)-- General reporting options- -b --begin=DATE- include postings/txns on or after this date (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 ef-- fects)-- --today=DATE- override today's date (affects relative smart dates, for- tests/examples)-- -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-equity- infer conversion equity postings from costs-- --infer-costs- infer costs from conversion equity postings-- --infer-market-prices- use costs as additional market prices, as if they were P direc-- tives-- --forecast- generate transactions from periodic rules, between the latest- recorded txn and 6 months from today, or during the specified- PERIOD (= is required). Auto posting rules will be applied to- these transactions as well. Also, in hledger-ui make fu-- ture-dated transactions visible.-- --auto generate extra postings by applying auto posting rules to all- txns (not just forecast txns)-- --verbose-tags- add visible tags indicating transactions or postings which have- been generated/modified-- --commodity-style- Override the commodity style in the output for the specified- commodity. For example 'EUR1.000,00'.-- --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.-- --pretty[=WHEN]- Show prettier output, e.g. using unicode box-drawing charac-- ters. Accepts 'yes' (the default) or 'no' ('y', 'n', 'always',- 'never' also work). If you provide an argument you must use- '=', e.g. '--pretty=yes'.-- 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 line tips- Here are some details useful to know about for hledger command lines- (and elsewhere). Feel free to skip this section until you need it.-- Option repetition- If options are repeated in a command line, hledger will generally use- the last (right-most) occurence.-- Special characters- Single escaping (shell metacharacters)- In shell command lines, characters significant to your shell - such as- spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want- hledger to see them. This is done by enclosing them in single or dou-- ble quotes, or by writing a backslash before them. Eg to match an ac-- count 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 be-- low), one level of shell-escaping is lost from any options or arguments- intended for by the add-on command, so those need an extra level of- shell-escaping. Eg to match a literal $ sign while using the bash- shell and running an add-on command (ui):-- $ hledger ui cur:'\\$'-- or:-- $ hledger ui cur:\\\\$-- If you wondered why four backslashes, perhaps this helps:-- unescaped: $- escaped: \$- double-escaped: \\$- triple-escaped: \\\\$-- Or, you can avoid the extra escaping by running the add-on executable- directly:-- $ hledger-ui cur:\\$-- Less escaping- Options and arguments are sometimes used in places other than the shell- command line, where shell-escaping is not needed, so there you should- use one less level of escaping. Those places include:-- o an @argumentfile-- o hledger-ui's filter field-- o hledger-web's search form-- o GHCI's prompt (used by developers).-- Unicode characters- hledger is expected to handle non-ascii characters correctly:-- o they should be parsed correctly in input files and on the command- line, by all hledger tools (add, iadd, hledger-web's search/add/edit- forms, etc.)-- o they should be displayed correctly by all hledger tools, and- on-screen alignment should be preserved.-- This requires a well-configured environment. Here are some tips:-- o A system locale must be configured, and it must be one that can de-- code the characters being used. In bash, you can set a locale like- this: export LANG=en_US.UTF-8. There are some more details in Trou-- bleshooting. This step is essential - without it, hledger will quit- on encountering a non-ascii character (as with all GHC-compiled pro-- grams).-- o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)- must support unicode-- o the terminal must be using a font which includes the required unicode- glyphs-- o the terminal should be configured to display wide characters as dou-- ble width (for report alignment)-- o on Windows, for best results you should run hledger in the same kind- of environment in which it was built. Eg hledger built in the stan-- dard CMD.EXE environment (like the binaries on our download page)- might show display problems when run in a cygwin or msys terminal,- and vice versa. (See eg #961).-- Regular expressions- A regular expression (regexp) is a small piece of text where certain- characters (like ., ^, $, +, *, (), |, [], \) have special meanings,- forming a tiny language for matching text precisely - very useful in- hledger and elsewhere. To learn all about them, visit regular-expres-- sions.info.-- hledger supports regexps whenever you are entering a pattern to match- something, eg in query arguments, account aliases, CSV if rules,- hledger-web's search form, hledger-ui's / search, etc. You may need to- wrap them in quotes, especially at the command line (see Special char-- acters above). Here are some examples:-- Account name queries (quoted for command line use):-- Regular expression: Matches:- ------------------- ------------------------------------------------------------- bank assets:bank, assets:bank:savings, expenses:art:banksy, ...- :bank assets:bank:savings, expenses:art:banksy- :bank: assets:bank:savings- '^bank' none of those ( ^ matches beginning of text )- 'bank$' assets:bank ( $ matches end of text )- 'big \$ bank' big $ bank ( \ disables following character's special meaning )- '\bbank\b' assets:bank, assets:bank:savings ( \b matches word boundaries )- '(sav|check)ing' saving or checking ( (|) matches either alternative )- 'saving|checking' saving or checking ( outer parentheses are not needed )- 'savings?' saving or savings ( ? matches 0 or 1 of the preceding thing )- 'my +bank' my bank, my bank, ... ( + matches 1 or more of the preceding thing )- 'my *bank' mybank, my bank, my bank, ... ( * matches 0 or more of the preceding thing )- 'b.nk' bank, bonk, b nk, ... ( . matches any character )-- Some other queries:-- desc:'amazon|amzn|audible' Amazon transactions- cur:EUR amounts with commodity symbol containing EUR- cur:'\$' amounts with commodity symbol containing $- cur:'^\$$' only $ amounts, not eg AU$ or CA$- cur:....? amounts with 4-or-more-character symbols- tag:.=202[1-3] things with any tag whose value contains 2021, 2022 or 2023-- Account name aliases: accept . instead of : as account separator:-- alias /\./=: replaces all periods in account names with colons-- Show multiple top-level accounts combined as one:-- --alias='/^[^:]+/=combined' ( [^:] matches any character other than : )-- Show accounts with the second-level part removed:-- --alias '/^([^:]+):[^:]+/ = \1'- match a top-level account and a second-level account- and replace those with just the top-level account- ( \1 in the replacement text means "whatever was matched- by the first parenthesised part of the regexp"-- CSV rules: match CSV records containing dining-related MCC codes:-- if \?MCC581[124]-- Match CSV records with a specific amount around the end/start of month:-- if %amount \b3\.99- & %date (29|30|31|01|02|03)$-- hledger's regular expressions- 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. backreferences are supported when doing text replacement in account- aliases or CSV rules, where backreferences can be used in the re-- placement string to reference capturing groups in the search regexp.- Otherwise, if you write \1, it will match the digit 1.-- 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.-- Argument files- You can save a set of command line options and arguments in a file, and- then reuse them by writing @FILENAME as a command line argument. Eg:- hledger bal @foo.args.-- Inside the argument file, each line should contain just one option or- argument. Don't use spaces except inside quotes (or you'll see a con-- fusing error); write = (or nothing) between a flag and its argument.- For the special characters mentioned above, use one less level of quot-- ing than you would at the command prompt.--Output- Output destination- hledger commands send their output to the terminal by default. You can- of course redirect this, eg into a file, using standard shell syntax:-- $ hledger print > foo.txt-- Some commands (print, register, stats, the balance commands) also pro-- vide the -o/--output-file option, which does the same thing without- needing the shell. Eg:-- $ hledger print -o foo.txt- $ hledger print -o - # write to stdout (the default)-- Output format- Some commands offer other kinds of output, not just text on the termi-- nal. Here are those commands and the formats currently supported:-- - txt csv/tsv html json sql- --------------------------------------------------------------------------------------- aregister Y Y Y Y- balance Y 1 Y 1 Y 1,2 Y- balancesheet Y 1 Y 1 Y 1 Y- balancesheete- Y 1 Y 1 Y 1 Y- quity- cashflow Y 1 Y 1 Y 1 Y- incomestatement Y 1 Y 1 Y 1 Y- print Y Y Y Y- register Y Y Y-- o 1 Also affected by the balance commands' --layout option.-- o 2 balance does not support html output without a report interval or- with --budget.-- The output format is selected by the -O/--output-format=FMT option:-- $ hledger print -O csv # print CSV on stdout-- or by the filename extension of an output file specified with the- -o/--output-file=FILE.FMT option:-- $ hledger balancesheet -o foo.csv # write CSV to foo.csv-- The -O option can be combined with -o to override the file extension,- if needed:-- $ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt-- Some notes about the various output formats:-- CSV output- o In CSV output, digit group marks (such as thousands separators) are- disabled automatically.-- HTML output- o HTML output can be styled by an optional hledger.css file in the same- directory.-- JSON output- o This is not yet much used; real-world feedback is welcome.-- o Our JSON is rather large and verbose, since it is a faithful repre-- sentation of hledger's internal data types. To understand the JSON,- read the Haskell type definitions, which are mostly in- https://github.com/simonmichael/hledger/blob/mas-- ter/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)-- SQL output- o This is not yet much used; real-world feedback is welcome.-- o SQL output is expected to work at least with SQLite, MySQL and Post-- gres.-- o For SQLite, it will be more useful if you modify the generated id- field to be a PRIMARY KEY. Eg:-- $ hledger print -O sql | sed 's/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g' | ...-- 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.-- Commodity styles- When displaying amounts, hledger infers a standard display style for- each commodity/currency, as described below in Commodity display style.-- If needed, this can be overridden by a -c/--commodity-style option (ex-- cept for cost amounts and amounts displayed by the print command, which- are always displayed with all decimal digits). For example, the fol-- lowing will force dollar amounts to be displayed as shown:-- $ hledger print -c '$1.000,0'-- This option can repeated to set the display style for multiple commodi-- ties/currencies. Its argument is as described in the commodity direc-- tive.-- In some cases hledger will adjust number formatting to improve their- parseability (such as adding trailing decimal marks when needed).-- Colour- In terminal output, some commands can produce colour when the terminal- supports it:-- o if the --color/--colour option is given a value of yes or always (or- no or never), colour will (or will not) be used;-- o otherwise, if the NO_COLOR environment variable is set, colour will- not be used;-- o otherwise, colour will be used if the output (terminal or file) sup-- ports it.-- Box-drawing- In terminal output, you can enable unicode box-drawing characters to- render prettier tables:-- o if the --pretty option is given a value of yes or always (or no or- never), unicode characters will (or will not) be used;-- o otherwise, unicode characters will not be used.-- Paging- When showing long output in the terminal, hledger will try to use the- pager specified by the PAGER environment variable, or less, or more.- (A pager is a helper program that shows one page at a time rather than- scrolling everything off screen). Currently it does this only for help- output, not for reports; specifically,-- o when listing commands, with hledger-- o when showing help with hledger [CMD] --help,-- o when viewing manuals with hledger help or hledger --man.-- Note the pager is expected to handle ANSI codes, which hledger uses eg- for bold emphasis. For the common pager less (and its more compatibil-- ity mode), we add R to the LESS and MORE environment variables to make- this work. If you use a different pager, you might need to configure- it similarly, to avoid seeing junk on screen (let us know). Otherwise,- you can set the NO_COLOR environment variable to 1 to disable all ANSI- output (see Colour).-- Debug output- We intend hledger to be relatively easy to troubleshoot, introspect and- develop. You can add --debug[=N] to any hledger command line to see- additional debug output. N ranges from 1 (least output, the default)- to 9 (maximum output). Typically you would start with 1 and increase- until you are seeing enough. Debug output goes to stderr, and is not- affected by -o/--output-file (unless you redirect stderr to stdout, eg:- 2>&1). It will be interleaved with normal output, which can help re-- veal when parts of the code are evaluated. To capture debug output in- a log file instead, you can usually redirect stderr, eg:-- hledger bal --debug=3 2>hledger.log--Environment- These environment variables affect hledger:-- COLUMNS This is normally set by your terminal; some hledger commands- (register) will format their output to this width. If not set, they- will try to use the available terminal width.-- LEDGER_FILE The main journal file to use when not specified with- -f/--file. Default: $HOME/.hledger.journal.-- NO_COLOR If this environment variable is set (with any value), hledger- will not use ANSI color codes in terminal output, unless overridden by- an explicit --color/--colour option.--PART 2: DATA FORMATS-Journal- hledger's usual data source is a plain text file containing journal en-- tries in hledger journal format. If you're looking for a quick refer-- ence, jump ahead to the journal cheatsheet (or use the table of con-- tents at https://hledger.org/hledger.html).-- This file represents an accounting General Journal. The .journal file- extension is most often used, though not strictly required. The jour-- nal file contains a number of transaction entries, each describing a- transfer of money (or any commodity) between two or more named ac-- counts, in a simple format readable by both hledger and humans.-- hledger's journal format is compatible with most of Ledger's journal- format, but not all of it. The differences and interoperation tips are- described at hledger and Ledger. With some care, and by avoiding in-- compatible features, you can keep your hledger journal readable by- Ledger and vice versa. This can useful eg for comparing the behaviour- of one app against the other.-- You can use hledger without learning any more about this file; just use- the add or web or import commands to create and update it.-- Many users, though, edit the journal file with a text editor, and track- changes with a version control system such as git. Editor addons such- as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and- 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.-- A hledger journal file can contain three kinds of thing: comment lines,- transactions, and/or directives (including periodic transaction rules- and auto posting rules). Understanding the journal file format will- also give you a good understanding of hledger's data model. Here's a- quick cheatsheet/overview, followed by detailed descriptions of each- part.-- Journal cheatsheet- # Here is the main syntax of hledger's journal format- # (omitting extra Ledger compatibility syntax).-- ###############################################################################-- # 1. These are comment lines, for notes or temporarily disabling things.- ; They begin with # or ;-- comment- Or, lines can be enclosed within "comment" / "end comment".- This is a block of- commented lines.- end comment-- # Some journal entries can have semicolon comments at end of line ; like this- # Some of them require 2 or more spaces before the semicolon.-- ###############################################################################-- # 2. Directives customise processing or output in some way.- # You don't need any directives to get started.- # But they can add more error checking, or change how things are displayed.- # They begin with a word, letter, or symbol.- # They are most often placed at the top, before transactions.-- account assets ; Declare valid account names and display order.- account assets:savings ; A subaccount. This one represents a bank account.- account assets:checking ; Another. Note, 2+ spaces after the account name.- account assets:receivable ; Accounting type is inferred from english names,- account passifs ; or declared with a "type" tag, type:L- account expenses ; type:X- ; A follow-on comment line, indented.- account expenses:rent ; Expense and revenue categories are also accounts.- ; Subaccounts inherit their parent's type.-- commodity $0.00 ; Declare valid commodities and their display styles.- commodity 1.000,00 EUR-- decimal-mark . ; The decimal mark used in this file (if ambiguous).-- payee Whole Foods ; Declare a valid payee name.-- tag trip ; Declare a valid tag name.-- P 2024-03-01 AAPL $179 ; Declare a market price for AAPL in $ on this date.-- include other.journal ; Include another journal file here.-- # Declare a recurring "periodic transaction", for budget/forecast reports- ~ monthly set budget goals ; <- Note, 2+ spaces before the description.- (expenses:rent) $1000- (expenses:food) $500-- # Declare an auto posting rule, to modify existing transactions in reports- = revenues:consulting- liabilities:tax:2024:us *0.25 ; Add a tax liability & expense- expenses:tax:2024:us *-0.25 ; for 25% of the revenue.-- ###############################################################################-- # 3. Transactions are what it's all about.- # They are dated events, usually movements of money between 2 or more accounts.- # They begin with a numeric date.- # Here is their basic shape:- #- # DATE DESCRIPTION ; The transaction's date and optional description.- # ACCOUNT1 AMOUNT ; A posting of an amount to/from this account, indented.- # ACCOUNT2 AMOUNT ; A second posting, balancing the first.- # ... ; More if needed. Amounts must sum to zero.- # ; Note, 2+ spaces between account names and amounts.-- 2024-01-01 opening balances ; At the start, declare pre-existing balances this way.- assets:savings $10000 ; Account names can be anything. lower case is easy to type.- assets:checking $1000 ; assets, liabilities, equity, revenues, expenses are common.- liabilities:credit card $-500 ; liabilities, equity, revenues balances are usually negative.- equity:start ; One amount can be left blank. $-10500 is inferred here.- ; Some of these accounts we didn't declare above,- ; so -s/--strict would complain.-- 2024-01-03 ! (12345) pay rent- ; Additional transaction comment lines, indented.- ; There can be a ! or * after the date meaning "pending" or "cleared".- ; There can be a parenthesised (code) after the date/status.- ; Amounts' sign shows direction of flow.- assets:checking $-500 ; Minus means removed from this account (credit).- expenses:rent $500 ; Plus means added to this account (debit).-- ; Keeping transactions in date order is optional (but helps error checking).-- 2024-01-02 Gringott's Bank | withdrawal ; Description can be PAYEE | NOTE- assets:bank:gold -10 gold- assets:pouch 10 gold-- 2024-01-02 shopping- expenses:clothing 1 gold- expenses:wands 5 gold- assets:pouch -6 gold-- 2024-01-02 receive gift- revenues:gifts -3 "Chocolate Frogs" ; Complex commodity symbols- assets:pouch 3 "Chocolate Frogs" ; must be in double quotes.-- 2024-01-15 buy some shares, in two lots ; Cost can be noted.- assets:investments:2024-01-15 2.0 AAAA @ $1.50 ; @ means per-unit cost- assets:investments:2024-01-15-02 3.0 AAAA @@ $4 ; @@ means total cost- ; ^ Per-lot subaccounts are sometimes useful.- assets:checking $-7-- 2024-01-15 assert some account balances on this date- ; Balances can be asserted in any transaction, with =, for extra error checking.- ; Assertion txns like this one can be made with hledger close --assert --show-costs- ;- assets:savings $0 = $10000- assets:checking $0 = $493- assets:bank:gold 0 gold = -10 gold- assets:pouch 0 gold = 4 gold- assets:pouch 0 "Chocolate Frogs" = 3 "Chocolate Frogs"- assets:investments:2024-01-15 0.0 AAAA = 2.0 AAAA @ $1.50- assets:investments:2024-01-15-02 0.0 AAAA = 3.0 AAAA @@ $4- liabilities:credit card $0 = $-500-- 2024-02-01 note some event, or a transaction not yet fully entered, on this date- ; Postings are not required.-- ; Some other date formats are allowed (but, consistent YYYY-MM-DD is useful).- 2024.01.01- 2024/1/1-- Comments- Lines in the journal will be ignored if they begin with a hash (#) or a- semicolon (;). (See also Other syntax.) hledger will also ignore re-- gions beginning with a comment line and ending with an end comment line- (or file end). Here's a suggestion for choosing between them:-- o # for top-level notes-- o ; for commenting out things temporarily-- o comment for quickly commenting large regions (remember it's there, or- you might get confused)-- Eg:-- # a comment line- ; another commentline- comment- A multi-line comment block,- continuing until "end comment" directive- or the end of the current file.- end comment-- Some hledger entries can have same-line comments attached to them, from- ; (semicolon) to end of line. See Transaction comments, Posting com-- ments, and Account comments below.-- Transactions- Transactions are the main unit of information in a journal file. They- represent events, typically a movement of some quantity of commodities- between two or more named accounts.-- Each transaction is recorded as a journal entry, beginning with a sim-- ple date in column 0. This can be followed by any of the following op-- tional fields, separated by spaces:-- o a status character (empty, !, or *)-- o a code (any short number or text, enclosed in parentheses)-- o a description (any remaining text until end of line or a semicolon)-- o a comment (any remaining text following a semicolon until end of- line, and any following indented lines beginning with a semicolon)-- o 0 or more indented posting lines, describing what was transferred and- the accounts involved (indented comment lines are also allowed, but- not blank lines or non-indented lines).-- Here's a simple journal file containing one transaction:-- 2008/01/01 income- assets:bank:checking $1- income:salary $-1-- Dates- Simple dates- Dates in the journal file use simple dates format: YYYY-MM-DD or- YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be- omitted, in which case it will be inferred from the context: the cur-- rent transaction, the default year set with a Y directive, or the cur-- rent date when the command is run. Some examples: 2010-01-31,- 2010/01/31, 2010.1.31, 1/31.-- (The UI also accepts simple dates, as well as the more flexible smart- dates documented in the hledger manual.)-- Posting dates- You can give individual postings a different date from their parent- transaction, by adding a posting comment containing a tag (see below)- like date:DATE. This is probably the best way to control posting dates- precisely. Eg in this example the expense should appear in May re-- ports, and the deduction from checking should be reported on 6/1 for- easy bank reconciliation:-- 2015/5/30- expenses:food $10 ; food purchased on saturday 5/30- assets:checking ; bank cleared it on monday, date:6/1-- $ hledger -f t.j register food- 2015-05-30 expenses:food $10 $10-- $ hledger -f t.j register checking- 2015-06-01 assets:checking $-10 $-10-- DATE should be a simple date; if the year is not specified it will use- the year of the transaction's date.- The date: tag must have a valid simple date value if it is present, eg- a date: tag with no value is not allowed.-- Status- Transactions (or individual postings within a transaction) can have a- status mark, which is a single character before the transaction de-- scription (or posting account name), separated from it by a space, in-- dicating 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 (and you can combine these, eg -UP- to match all except cleared things). Or you can use the status:, sta-- tus:!, and status:* queries, or the U, P, C keys in hledger-ui.-- (Note: in Ledger the "unmarked" state is called "uncleared"; in hledger- we renamed it to "unmarked" for semantic clarity.)-- Status marks are optional, but can be helpful eg for reconciling with- real-world accounts. Some editor modes provide highlighting and short-- cuts for working with status. Eg in Emacs ledger-mode, you can toggle- transaction status with C-c C-e, or posting status with C-c C-c.-- What "uncleared", "pending", and "cleared" actually mean is up to you.- Here's one suggestion:-- status meaning- --------------------------------------------------------------------------- uncleared recorded but not yet reconciled; needs review- pending tentatively reconciled (if needed, eg during a big reconcil-- iation)- cleared complete, reconciled as far as possible, and considered cor-- rect-- With this scheme, you would use -PC to see the current balance at your- bank, -U to see things which will probably hit your bank soon (like un-- cashed checks), and no flags to see the most up-to-date state of your- finances.-- 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- After the date, status mark and/or code fields, the rest of the line- (or until a comment is begun with ;) is the transaction's description.- Here you can describe the transaction (called the "narration" in tradi-- tional bookkeeping), or you can record a payee/payer name, or you can- leave it empty.-- Transaction descriptions show up in print output and in register re-- ports, and can be listed with the descriptions command.-- You can query by description with desc:DESCREGEX, or pivot on descrip-- tion with --pivot desc.-- Payee and note- Sometimes people want a dedicated payee/payer field that can be queried- and checked more strictly. If you want that, you can write a | (pipe)- character in the description. This divides it into a "payee" field on- the left, and a "note" field on the right. (Either can be empty.)-- You can query these with payee:PAYEEREGEX and note:NOTEREGEX, list- their values with the payees and notes commands, or pivot on payee or- note.-- Note: in transactions with no | character, description, payee, and note- all have the same value. Once a | is added, they become distinct. (If- you'd like to change this behaviour, please propose it on the mail- list.)-- If you want more strict error checking, you can declare the valid payee- names with payee directives, and then enforce these with hledger check- payees. (Note: because of the above, for this you'll need to ensure- every transaction description contains a | and therefore a checkable- payee name, even if it's empty.)-- Transaction comments- Text following ;, after a transaction description, and/or on indented- lines immediately below it, form comments for that transaction. They- are reproduced by print but otherwise ignored, except they may contain- tags, which are not ignored.-- 2012-01-01 something ; a transaction comment- ; a second line of transaction comment- expenses 1- assets-- 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.-- If the amount is positive, it is being added to the account; if nega-- tive, it is being removed from the account.-- The posting amounts in a transaction must sum up to zero, indicating- that the inflows and outflows are equal. We call this a balanced- transaction. (You can read more about the nitty-gritty details of "sum- up to zero" in Transaction balancing below.)-- As a convenience, you can optionally leave one amount blank; hledger- will infer what it should be so as to balance the transaction.-- Debits and credits- The traditional accounting concepts of debit and credit of course exist- in hledger, but we represent them with numeric sign, as described- above. Positive and negative posting amounts represent debits and- credits respectively.-- You don't need to remember that, but if you would like to - eg for- helping newcomers or for talking with your accountant - here's a handy- mnemonic:-- debit / plus / left / short words- credit / minus / right / longer words-- The two space delimiter- Be sure to notice the unusual separator between the account name and- the following amount. Because hledger allows account names with spaces- in them, you must separate the account name and amount (if any) by two- or more spaces (or tabs). It's easy to forget at first. If you ever- see the amount being treated as part of the account name, you'll know- you probably need to add another space between them.-- Account names- Accounts are the main way of categorising things in hledger. As in- Double Entry Bookkeeping, they can represent real world accounts (such- as a bank account), or more abstract categories such as "money borrowed- from Frank" or "money spent on electricity".-- You can use any account names you like, but we usually start with the- traditional accounting categories, which in english are assets, liabil-- ities, equity, revenues, expenses. (You might see these referred to as- A, L, E, R, X for short.)-- For more precise reporting, we usually divide the top level accounts- into more detailed subaccounts, by writing a full colon between account- name parts. For example, from the account names assets:bank:checking- and expenses:food, hledger will infer this hierarchy of five accounts:-- assets- assets:bank- assets:bank:checking- expenses- expenses:food-- Shown as an outline, the hierarchical tree structure is more clear:-- assets- bank- checking- expenses- food-- hledger reports can summarise the account tree to any depth, so you can- go as deep as you like with subcategories, but keeping your account- names relatively simple may be best when starting out.-- Account names may be capitalised or not; they may contain letters, num-- bers, symbols, or single spaces. Note, when an account name and an- amount are written on the same line, they must be separated by two or- more spaces (or tabs).-- Parentheses or brackets enclosing the full account name indicate vir-- tual postings, described below. Parentheses or brackets internal to- the account name have no special meaning.-- Account names can be altered temporarily or permanently by account- aliases.-- Amounts- After the account name, there is usually an amount. (Remember: 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- A decimal mark can be written as a period or a comma:-- 1.23- 1,23-- Both of these are common in international number formats, so hledger is- not biased towards one or the other. Because hledger also supports- digit group marks (eg thousands separators), this means that a number- like 1,000 or 1.000 containing just one period or comma is ambiguous.- In such cases, hledger by default assumes it is a decimal mark, and- will parse both of those as 1.-- To help hledger parse such ambiguous numbers more accurately, if you- use digit group marks, we recommend declaring the decimal mark explic-- itly. The best way is to add a decimal-mark directive at the top of- each data file, like this:-- decimal-mark .-- Or you can declare it per commodity with commodity directives, de-- scribed below.-- hledger also accepts numbers like 10. with no digits after the decimal- mark (and will sometimes display numbers that way to disambiguate them- - see Trailing decimal marks).-- Digit group marks- In the integer part of the amount quantity (left of the decimal mark),- groups of digits can optionally be separated by a digit group mark - a- comma or period (whichever is not used as decimal mark), or a space- (several Unicode space variants, like no-break space, are also ac-- cepted). So these are all valid amounts in a journal file:-- $1,000,000.00- EUR 2.000.000,00- INR 9,99,99,999.00- 1 000 000.00 ; <- ordinary space- 1 000 000.00 ; <- no-break space-- 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.-- By default, the format of amounts in the journal influences how hledger- displays them in output. This is explained in Commodity display style- below.-- Costs- After a posting amount, you can note its cost (when buying) or selling- price (when selling) in another commodity, by writing either @ UNIT-- PRICE or @@ TOTALPRICE after it. This indicates a conversion transac-- tion, where one commodity is exchanged for another.-- (You might also see this called "transaction price" in hledger docs,- discussions, or code; that term was directionally neutral and reminded- that it is a price specific to a transaction, but we now just call it- "cost", with the understanding that the transaction could be a purchase- or a sale.)-- Costs are usually written explicitly with @ or @@, but can also be in-- ferred automatically for simple multi-commodity transactions. Note, if- costs are inferred, the order of postings is significant; the first- posting will have a cost attached, in the commodity of the second.-- As an example, here are several ways to record purchases of a foreign- currency in hledger, using the cost notation either explicitly or im-- plicitly:-- 1. Write the price per unit, as @ UNITPRICE after the amount:-- 2009/1/1- assets:euros 100 @ $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 100 @@ $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. Note the- effect of posting order: the price is added to first posting, making- it 100 @@ $135, as in example 2:-- 2009/1/1- assets:euros 100 ; one hundred euros purchased- assets:dollars $-135 ; for $135-- Amounts can be converted to cost at report time using the -B/--cost- flag; this is discussed more in the Cost reporting section.-- Note that the cost normally should be a positive amount, though it's- not required to be. This can be a little confusing, see discussion at- --infer-market-prices: market prices from transactions.-- 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, described below).-- Assertions and ordering- hledger calculates and checks an account's balance assertions in date- order (and when there are multiple assertions on the same day, in parse- order). Note this is different from Ledger, which checks assertions- always in parse order, ignoring dates.-- This means in hledger you can freely reorder transactions, postings, or- files, and balance assertions will usually keep working. The exception- is when you reorder multiple postings on the same day, to the same ac-- count, which have balance assertions; those will likely need updating.-- Assertions and multiple included files- Multiple files included with the include directive are processed as if- concatenated into one file, preserving their order and the posting or-- der within each file. It means that balance assertions in later files- will see balance from earlier files.-- And if you have multiple postings to an account on the same day, split- across multiple files, and you want to assert the account's balance on- that day, you'll need to put the assertion in the right file - the last- one in the sequence, probably.-- Assertions and multiple -f files- Unlike include, when multiple files are specified on the command line- with multiple -f/--file options, balance assertions will not see bal-- ance from earlier files. This can be useful when you do not want prob-- lems in earlier files to disrupt valid assertions in later files.-- If you do want assertions to see balance from earlier files, use in-- clude, or concatenate the files temporarily.-- Assertions and costs- Balance assertions ignore costs, and should normally be written without- one:-- 2019/1/1- (a) $1 @ 1 = $1-- We do allow costs to be written in balance assertion amounts, however,- and print shows them, but 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 costs), and because- balance assignments do use costs (see below).-- Assertions and commodities- The balance assertions described so far are "single commodity balance- assertions": they assert and check the balance in one commodity, ignor-- ing any others that may be present. This is how balance assertions- work in Ledger also.-- If an account contains multiple commodities, you can assert their bal-- ances by writing multiple postings with balance assertions, one for- each commodity:-- 2013/1/1- usd $-1- eur -1- both-- 2013/1/2- both 0 = $1- both 0 = 1-- In hledger you can make a stronger "sole commodity balance assertion"- by writing two equals signs (== EXPECTEDBALANCE). This also asserts- that there are no other commodities in the account besides the asserted- one (or at least, that their current balance is zero):-- 2013/1/1- usd $-1 == $-1 ; these sole commodity assertions succeed- eur -1 == -1- both ;== $1 ; this one would fail because 'both' contains $ and-- It's less easy to make a "sole commodities balance assertion" (note the- plural) - ie, asserting that an account contains two or more specified- commodities and no others. It can be done by-- 1. isolating each commodity in a subaccount, and asserting those-- 2. and also asserting there are no commodities in the parent account- itself:-- 2013/1/1- usd $-1- eur -1- both 0 == 0 ; nothing up my sleeve- both:usd $1 == $1 ; a dollar here- both:eur 1 == 1 ; a euro there-- Assertions and subaccounts- All of the balance assertions above (both = and ==) are "subaccount-ex-- clusive balance assertions"; they ignore any balances that exist in- deeper subaccounts.-- In hledger you can make "subaccount-inclusive balance assertions" by- adding a star after the equals (=* or ==*):-- 2019/1/1- equity:start- assets:checking $10- assets:savings $10- assets $0 ==* $20 ; assets + subaccounts contains $20 and nothing else-- Assertions and virtual postings- Balance assertions always consider both real and virtual postings; they- are not affected by the --real/-R flag or real: query.-- Assertions and auto postings- Balance assertions are affected by the --auto flag, which generates- auto postings, which can alter account balances. Because auto postings- are optional in hledger, accounts affected by them effectively have two- balances. But balance assertions can only test one or the other of- these. So to avoid making fragile assertions, either:-- o assert the balance calculated with --auto, and always use --auto with- that file-- o or assert the balance calculated without --auto, and never use --auto- with that file-- o or avoid balance assertions on accounts affected by auto postings (or- avoid auto postings entirely).-- Assertions and precision- Balance assertions compare the exactly calculated amounts, which are- not always what is shown by reports. Eg a commodity directive may- limit the display precision, but this will not affect balance asser-- tions. Balance assertion failure messages show exact amounts.-- Posting comments- Text following ;, at the end of a posting line, and/or on indented- lines immediately below it, form comments for that posting. They are- reproduced by print but otherwise ignored, except they may contain- tags, which are not ignored.-- 2012-01-01- expenses 1 ; a comment for posting 1- assets- ; a comment for posting 2- ; a second comment line for posting 2-- Transaction balancing- How exactly does hledger decide when a transaction is balanced ? The- general goal is that if you look at the journal entry and calculate the- amounts' sum perfectly with pencil and paper, hledger should agree with- you.-- Real world transactions, especially for investments or cryptocurren-- cies, often involve imprecise costs, complex decimals, and/or infi-- nitely-recurring decimals, which are difficult or inconvenient to han-- dle on a computer. So to be a practical accounting system, hledger al-- lows some imprecision when checking transaction balancedness. The- question is, how much imprecision should be allowed ?-- hledger currently decides it based on the commodity display styles: if- the postings' sum would appear to be zero when displayed with the stan-- dard display precisions, the transaction is considered balanced.-- Or equivalently: if the journal entry is displayed with amounts rounded- to the standard display precisions (with hledger print --round=hard),- and a human with pencil and paper would agree that those displayed- amounts add up to zero, the transaction is considered balanced.-- This has some advantages: it is fairly intuitive, general not- hard-coded, yet configurable when needed. On the downside it means- that transaction balancedness is related to commodity display preci-- sions, so eg when using -c/--commodity-style to display things with- more than usual precision, you might need to fix some of your journal- entries (ie, add decimal digits to make them balance more precisely).-- Other PTA tools (Ledger, Beancount..) have their own ways of doing it.- Possible improvements are discussed at #1964.-- Note: if you have multiple journal files, and are relying on commodity- directives to make imprecise journal entries balance, the directives'- placement might be important - see commodity directive.-- Tags- Tags are a way to add extra labels or data fields to transactions,- postings, or accounts, which you can then search or pivot on.-- A tag is a word, optionally hyphenated, immediately followed by a full- colon, in the comment of a transaction, a posting, or an account direc-- tive. Eg: 2024-01-01 a transaction ; foo: Note this is an exception- to the usual rule that things in comments are ignored.-- You can write multiple tags on one line, separated by comma. Or you- can write each tag on its own comment line (no comma needed in this- case).-- For example, here are five different tags: one on the assets:checking- account, two on the transaction, and two on the expenses:food posting:-- account assets:checking ; accounttag:-- 2017/1/16 bought groceries ; transactiontag-1:- ; transactiontag-2:- assets:checking $-1- expenses:food $1 ; postingtag:, another-posting-tag:-- Postings also inherit tags from their transaction and their account.- And transactions also acquire tags from their postings (and postings'- accounts). So in the example above, the expenses posting effectively- has all five tags (by inheriting from the account and transaction), and- the transaction also has all five tags (by acquiring from the expenses- posting).-- Tag names- Most non-whitespace characters are allowed in tag names. Eg : is a- valid tag.-- You can list the tag names used in your journal with the tags command:- hledger tags [NAMEREGEX]-- In commands which use a query, you can match by tag name. Eg:- hledger print tag:NAMEREGEX-- You can declare valid tag names with the tag directive and then check- them with the check command.-- Special tags- Some tag names have special significance to hledger. There's not much- harm in using them yourself, but some could produce an error message,- particularly the date: and type: tags. They are explained elsewhere,- but here is a quick list for reference:-- Tags you can set to influence hledger's behaviour:-- date -- overrides a posting's date- date2 -- overrides a posting's secondary date- type -- declares an account's type-- Tags hledger adds to indicate generated data:-- t -- appears on postings generated by timedot letters- assert -- appears on txns generated by close --assert- retain -- appears on txns generated by close --retain- start -- appears on txns generated by close --migrate/--close/--open/--assign- generated-transaction -- appears on generated periodic txns (with --verbose-tags)- generated-posting -- appears on generated auto postings (with --verbose-tags)- modified -- appears on txns which have had auto postings added (with --verbose-tags)- Not displayed, but queryable:- _generated-transaction -- exists on generated periodic txns (always)- _generated-posting -- exists on generated auto postings (always)- _modified -- exists on txns which have had auto postings added (always)-- Tags hledger uses internally:-- _conversion-matched -- exists on postings which have been matched with a nearby @/@@ cost annotation-- Tag values- Tags can have a value, which is any text after the colon up until a- comma or end of line, with surrounding whitespace removed. Ending at- comma allows us to write multiple tags on one line, but also means that- tag values can not contain commas.-- Eg in the following posting, the three tags' values are "value 1",- "value 2", and "" (empty) respectively:-- expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz-- Multiple tags with the same name are additive rather than overriding:- when the same tag name is seen again with a new value, the new- name:value pair is added to the tags. It is not possible to override a- previous tag's value or remove a tag.-- You can list all the values used for a particular tag in the journal- with- hledger tags TAGNAME --values-- You can match on tag values with a query like tag:NAMEREGEX=VALUEREGEX-- Directives- Besides transactions, there is something else you can put in a journal- file: directives. These are declarations, beginning with a keyword,- that modify hledger's behaviour. Some directives can have more spe-- cific subdirectives, indented below them. hledger's directives are- similar to Ledger's in many cases, but there are also many differences.- Directives are not required, but can be useful. Here are the main di-- rectives:-- purpose directive- --------------------------------------------------------------------------- READING DATA:- Rewrite account names alias- Comment out sections of the file comment- Declare file's decimal mark, to help decimal-mark- parse amounts accurately- Include other data files include- GENERATING DATA:- Generate recurring transactions or bud- ~- get goals- Generate extra postings on existing =- transactions- CHECKING FOR ERRORS:- Define valid entities to provide more account, commodity, payee, tag- error checking- REPORTING:- Declare accounts' type and display order account- Declare commodity display styles commodity- Declare market prices P-- Directives and multiple files- Directives vary in their scope, ie which journal entries and which in-- put files they affect. Most often, a directive will affect the follow-- ing entries and included files if any, until the end of the current- file - and no further. You might find this inconvenient! For example,- alias directives do not affect parent or sibling files. But there are- usually workarounds; for example, put alias directives in your top-most- file, before including other files.-- The restriction, though it may be annoying at first, is in a good- cause; it allows reports to be stable and deterministic, independent of- the order of input. Without it, reports could show different numbers- depending on the order of -f options, or the positions of include di-- rectives in your files.-- Directive effects- Here are all hledger's directives, with their effects and scope sum-- marised - nine main directives, plus four others which we consider- non-essential:-- di- what it does ends- rec- at- tive file- end?- --------------------------------------------------------------------------------------- ac- Declares an account, for checking all entries in all files; and N- count its display order and type. Subdirectives: any text, ignored.- alias Rewrites account names, in following entries until end of cur- Y- rent file or end aliases. Command line equivalent: --alias- com- Ignores part of the journal file, until end of current file or Y- ment end comment.- com- Declares up to four things: 1. a commodity symbol, for checking N,N,Y,Y- mod- all amounts in all files 2. the display style for all amounts- ity of this commodity 3. the decimal mark for parsing amounts of- this commodity, in the rest of this file and its children, if- there is no decimal-mark directive 4. the precision to use for- balanced-transaction checking in this commodity, in this file- and its children. Takes precedence over D. Subdirectives:- format (ignored). Command line equivalent: -c/--commodity-style- deci- Declares the decimal mark, for parsing amounts of all commodi- Y- mal-mark ties in following entries until next decimal-mark or end of cur-- rent file. Included files can override. Takes precedence over- commodity and D.- include Includes entries and directives from another file, as if they N- were written inline. Command line alternative: multiple- -f/--file- payee Declares a payee name, for checking all entries in all files. N- P Declares the market price of a commodity on some date, for value N- reports.- ~ Declares a periodic transaction rule that generates future N- (tilde) transactions with --forecast and budget goals with balance- --budget.- Other- syntax:- apply Prepends a common parent account to all account names, in fol- Y- account lowing entries until end of current file or end apply account.- D Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N- there is no commodity directive for this commodity: its decimal- mark, balancing precision, and display style, as above.- Y Sets a default year to use for any yearless dates, in following Y- entries until end of current file.- = Declares an auto posting rule that generates extra postings on partly- (equals) matched transactions with --auto, in current, parent, and child- files (but not sibling files, see #1212).- Other Other directives from Ledger's file format are accepted but ig-- Ledger nored.- direc-- tives-- account directive- account directives can be used to declare accounts (ie, the places that- amounts are transferred from and to). Though not required, these dec-- larations can provide several benefits:-- o They can document your intended chart of accounts, providing a refer-- ence.-- o They can store additional account information as comments, or as tags- which can be used to filter or pivot reports.-- o They can restrict which accounts may be posted to by transactions, eg- in strict mode, which helps prevent errors.-- o They influence account display order in reports, allowing non-alpha-- betic sorting (eg Revenues to appear above Expenses).-- o They can help hledger know your accounts' types (asset, liability,- equity, revenue, expense), enabling reports like balancesheet and in-- comestatement.-- o They help with account name completion (in hledger add, hledger-web,- hledger-iadd, ledger-mode, etc.)-- They are written as the word account followed by a hledger-style ac-- count name. Eg:-- account assets:bank:checking-- Ledger-style indented subdirectives are also accepted, but ignored:-- account assets:bank:checking- format subdirective ; currently ignored-- Account comments- Text following two or more spaces and ; at the end of an account direc-- tive line, and/or following ; on indented lines immediately below it,- form comments for that account. They are ignored except they may con-- tain tags, which are not ignored.-- The two-space requirement for same-line account comments is because ;- is allowed in account names.-- account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon- ; next-line comment- ; some tags - type:A, acctnum:12345-- Account error checking- By default, accounts need not be declared; they come into existence- when a posting references them. This is convenient, but it means- hledger can't warn you when you mis-spell an account name in the jour-- nal. Usually you'll find that error later, as an extra account in bal-- ance reports, or an incorrect balance when reconciling.-- In strict mode, enabled with the -s/--strict flag, hledger will report- an error if any transaction uses an account name that has not been de-- clared by an account directive. Some notes:-- o The declaration is case-sensitive; transactions must use the correct- account name capitalisation.-- o The account directive's scope is "whole file and below" (see direc-- tives). This means it affects all of the current file, and any files- it includes, but not parent or sibling files. The position of ac-- count directives within the file does not matter, though it's usual- to put them at the top.-- o Accounts can only be declared in journal files, but will affect in-- cluded files of all types.-- o It's currently not possible to declare "all possible subaccounts"- with a wildcard; every account posted to must be declared.-- Account display order- Account directives also cause hledger to display accounts in a particu-- lar order, not just alphabetically. Eg, here is a conventional order-- ing for the top-level accounts:-- account assets- account liabilities- account equity- account revenues- account expenses-- Now hledger displays them in that order:-- $ hledger accounts- assets- liabilities- equity- revenues- expenses-- If there are undeclared accounts, those will be displayed last, in al-- phabetical order.-- Sorting is done within each group of sibling accounts, at each level of- the account tree. Eg, a declaration like account parent:child influ-- ences child's position among its siblings.-- Note, it does not affect parent's position; for that, you need an ac-- count parent declaration.-- Sibling accounts are always displayed together; hledger won't display- x:y in between a:b and a:c.-- An account directive both declares an account as a valid posting tar-- get, and declares its display order; you can't easily do one without- the other.-- Account types- hledger knows that accounts come in several types: assets, liabilities,- expenses and so on. This enables easy reports like balancesheet and- incomestatement, and filtering by account type with the type: query.-- As a convenience, hledger will detect these account types automatically- if you are using common english-language top-level account names (de-- scribed below). But it's more robust to declare accounts' types ex-- plicitly, by adding type: tags to their account directives. The tag's- value should be one of the five main account types:-- o A or Asset (things you own)-- o L or Liability (things you owe)-- o E or Equity (investment/ownership; balanced counterpart of assets &- liabilities)-- o R or Revenue (what you received money from, AKA income; technically- part of Equity)-- o X or Expense (what you spend money on; technically part of Equity)-- or, it can be (these are used less often):-- o C or Cash (a subtype of Asset, indicating liquid assets for the cash-- flow report)-- o V or Conversion (a subtype of Equity, for conversions (see Cost re-- porting).)-- Subaccounts inherit their parent's type, or they can override it. Here- is a typical set of account type declarations:-- account assets ; type: A- account liabilities ; type: L- account equity ; type: E- account revenues ; type: R- account expenses ; type: X-- account assets:bank ; type: C- account assets:cash ; type: C-- account equity:conversion ; type: V-- Here are some tips for working with account types.-- o The rules for inferring types from account names are as follows.- These are just a convenience that sometimes help new users get going;- if they don't work for you, just ignore them and declare your account- types. See also Regular expressions.-- If account's name contains this (CI) regular expression: | its type is:- --------------------------------------------------------------------|-------------- ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash- ^assets?(:|$) | Asset- ^(debts?|liabilit(y|ies))(:|$) | Liability- ^equity:(trad(e|ing)|conversion)s?(:|$) | Conversion- ^equity(:|$) | Equity- ^(income|revenue)s?(:|$) | Revenue- ^expenses?(:|$) | Expense-- o If you declare any account types, it's a good idea to declare an ac-- count for all of the account types, because a mixture of declared and- name-inferred types can disrupt certain reports.-- o Certain uses of account aliases can disrupt account types. See- Rewriting accounts > Aliases and account types.-- o As mentioned above, subaccounts will inherit a type from their parent- account. More precisely, an account's type is decided by the first- of these that exists:-- 1. A type: declaration for this account.-- 2. A type: declaration in the parent accounts above it, preferring- the nearest.-- 3. An account type inferred from this account's name.-- 4. An account type inferred from a parent account's name, preferring- the nearest parent.-- 5. Otherwise, it will have no type.-- o For troubleshooting, you can list accounts and their types with:-- $ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]-- alias directive- 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-- o combining two accounts into one, eg to see their sum or difference on- one line-- 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.-- Account aliases are very powerful. They are generally easy to use cor-- rectly, but you can also generate invalid account names with them; more- on this below.-- 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 re-- place any occurrence of the old account name with the new one. Subac-- counts are also affected. Eg:-- alias checking = assets:bank:wells fargo:checking- ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"-- Regex aliases- There is also a more powerful variant that uses a regular expression,- indicated by wrapping the pattern in forward slashes. (This is the- only place where hledger requires forward slashes around a regular ex-- pression.)-- Eg:-- alias /REGEX/ = REPLACEMENT-- or:-- $ hledger --alias '/REGEX/=REPLACEMENT' ...-- Any part of an account name matched by REGEX will be replaced by RE-- PLACEMENT. REGEX is case-insensitive as usual.-- If you need to match a forward slash, escape it with a backslash, eg- /\/=:.-- If REGEX contains parenthesised match groups, these can be referenced- by the usual backslash and number in REPLACEMENT:-- alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3- ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"-- REPLACEMENT continues to the end of line (or on command line, to end of- option argument), so it can contain trailing whitespace.-- Combining aliases- You can define as many aliases as you like, using journal directives- and/or command line options.-- Recursive aliases - where an account name is rewritten by one alias,- then by another alias, and so on - are allowed. Each alias sees the- effect of previously applied aliases.-- In such cases it can be important to understand which aliases will be- applied and in which order. For (each account name in) each journal- entry, we apply:-- 1. alias directives preceding the journal entry, most recently parsed- first (ie, reading upward from the journal entry, bottom to top)-- 2. --alias options, in the order they appeared on the command line- (left to right).-- In other words, for (an account name in) a given journal entry:-- o the nearest alias declaration before/above the entry is applied first-- o the next alias before/above that will be be applied next, and so on-- o aliases defined after/below the entry do not affect it.-- This gives nearby aliases precedence over distant ones, and helps pro-- vide semantic stability - aliases will keep working the same way inde-- pendent of which files are being read and in which order.-- In case of trouble, adding --debug=6 to the command line will show- which aliases are being applied when.-- Aliases and multiple files- As explained at Directives and multiple files, alias directives do not- affect parent or sibling files. Eg in this command,-- hledger -f a.aliases -f b.journal-- account aliases defined in a.aliases will not affect b.journal. In-- cluding the aliases doesn't work either:-- include a.aliases-- 2023-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-- 2023-01-01 ; affected by aliases above- foo 1- bar-- include c.journal ; also affected-- end aliases directive- You can clear (forget) all currently defined aliases (seen in the jour-- nal so far, or defined on the command line) with this directive:-- end aliases-- Aliases can generate bad account names- Be aware that account aliases can produce malformed account names,- which could cause confusing reports or invalid print output. For exam-- ple, you could erase all account names:-- 2021-01-01- a:aa 1- b-- $ hledger print --alias '/.*/='- 2021-01-01- 1-- The above print output is not a valid journal. Or you could insert an- illegal double space, causing print output that would give a different- journal when reparsed:-- 2021-01-01- old 1- other-- $ hledger print --alias old="new USD" | hledger -f- print- 2021-01-01- new USD 1- other-- Aliases and account types- If an account with a type declaration (see Declaring accounts > Account- types) is renamed by an alias, normally the account type remains in ef-- fect.-- However, renaming in a way that reshapes the account tree (eg renaming- parent accounts but not their children, or vice versa) could prevent- child accounts from inheriting the account type of their parents.-- Secondly, if an account's type is being inferred from its name, renam-- ing it by an alias could prevent or alter that.-- If you are using account aliases and the type: query is not matching- accounts as you expect, try troubleshooting with the accounts command,- eg something like:-- $ hledger accounts --alias assets=bassetts type:a-- commodity directive- The commodity directive performs several functions:-- 1. It declares which commodity symbols may be used in the journal, en-- abling useful error checking with strict mode or the check command.- See Commodity error checking below.-- 2. It declares how all amounts in this commodity should be displayed,- eg how many decimals to show. See Commodity display style above.-- 3. (If no decimal-mark directive is in effect:) It sets the decimal- mark to expect (period or comma) when parsing amounts in this com-- modity, in this file and files it includes, from the directive until- end of current file. See Decimal marks above.-- 4. It declares the precision with which this commodity's amounts should- be compared when checking for balanced transactions, anywhere in- this file and files it includes, until end of current file.-- Declaring commodities solves several common parsing/display problems,- so we recommend it.-- Note that effects 3 and 4 above end at the end of the directive's file,- and will not affect sibling or parent files. So if you are relying on- them (especially 4) and using multiple files, placing your commodity- directives in a top-level parent file might be important. Or, keep- your decimal marks unambiguous and your entries well balanced and pre-- cise.-- (Related: #793)-- Commodity directive syntax- A commodity directive is normally the word commodity followed by a sam-- ple amount (and optionally a comment). Only the amount's symbol and- format is significant. Eg:-- commodity $1000.00- commodity 1.000,00 EUR- commodity 1 000 000.0000 ; the no-symbol commodity-- Commodities do not have tags (tags in the comment will be ignored).-- A commodity directive's sample amount must always include a period or- comma decimal mark (this rule helps disambiguate decimal marks and- digit group marks). If you don't want to show any decimal digits,- write the decimal mark at the end:-- commodity 1000. AAAA ; show AAAA with no decimals-- Commodity symbols containing spaces, numbers, or punctuation must be- enclosed in double quotes, as usual:-- commodity 1.0000 "AAAA 2023"-- Commodity directives normally include a sample amount, but can declare- only a symbol (ie, just function 1 above):-- commodity $- commodity INR- commodity "AAAA 2023"- commodity "" ; the no-symbol commodity-- Commodity directives may also be written with an indented format subdi-- rective, as in Ledger. The symbol is repeated and must be the same in- both places. Other subdirectives are currently ignored:-- ; 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- an unsupported subdirective ; ignored by hledger-- Commodity error checking- In strict mode (-s/--strict) (or when you run hledger check commodi-- ties), hledger will report an error if an undeclared commodity symbol- is used. (With one exception: zero amounts are always allowed to have- no commodity symbol.) It works like account error checking (described- above).-- decimal-mark directive- You can use a decimal-mark directive - usually one per file, at the top- of the file - to declare which character represents a decimal mark when- parsing amounts in this file. It can look like-- decimal-mark .-- or-- decimal-mark ,-- This prevents any ambiguity when parsing numbers in the file, so we- recommend it, especially if the file contains digit group marks (eg- thousands separators).-- include directive- You can pull in the content of additional files by writing an include- directive, like this:-- include FILEPATH-- Only journal files can include, and only journal, timeclock or timedot- files can be included (not CSV files, currently).-- If the file path does not begin with a slash, it is relative to the- current file's folder.-- A tilde means home directory, eg: include ~/main.journal.-- The path may contain glob patterns to match multiple files, eg: include- *.journal.-- There is limited support for recursive wildcards: **/ (the slash is re-- quired) matches 0 or more subdirectories. It's not super convenient- since you have to avoid include cycles and including directories, but- this can be done, eg: include */**/*.journal.-- The path may also be prefixed to force a specific file format, overrid-- ing the file extension (as described in Data formats): include time-- dot:~/notes/2023*.md.-- P directive- The P directive declares a market price, which is a conversion rate be-- tween two commodities on a certain date. This allows value reports to- convert amounts of one commodity to their value in another, on or after- that date. These prices are often obtained from a stock exchange,- cryptocurrency exchange, the or foreign exchange market.-- 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. Ex-- amples:-- # one euro was worth $1.35 from 2009-01-01 onward:- P 2009-01-01 $1.35-- # and $1.40 from 2010-01-01 onward:- P 2010-01-01 $1.40-- The -V, -X and --value flags use these market prices to show amount- values in another commodity. See Value reporting.-- payee directive- payee PAYEE NAME-- This 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 ; a comment-- Payees do not have tags (tags in the comment will be ignored).-- To declare the empty payee name, use "".-- payee ""-- Ledger-style indented subdirectives, if any, are currently ignored.-- tag directive- tag TAGNAME-- This directive can be used to declare a limited set of tag names al-- lowed in tags. TAGNAME should be a valid tag name (no spaces). Eg:-- tag item-id-- Any indented subdirectives are currently ignored.-- The "tags" check will report an error if any undeclared tag name is- used. It is quite easy to accidentally create a tag through normal use- of colons in comments; if you want to prevent this, you can declare and- check your tags .-- Periodic transactions- The ~ directive declares a "periodic rule" which generates temporary- extra transactions, usually recurring at some interval, when hledger is- run with the --forecast flag. These "forecast transactions" are useful- for forecasting future activity. They exist only for the duration of- the report, and only when --forecast is used; they are not saved in the- journal file by hledger.-- Periodic rules also have a second use: with the --budget flag they set- budget goals for budgeting.-- Periodic rules can be a little tricky, so before you use them, read- this whole section, or at least the following tips:-- 1. Two spaces accidentally added or omitted will cause you trouble -- read about this below.-- 2. For troubleshooting, show the generated transactions with hledger- print --forecast tag:generated or hledger register --forecast- tag:generated.-- 3. Forecasted transactions will begin only after the last non-fore-- casted transaction's date.-- 4. Forecasted transactions will end 6 months from today, by default.- See below for the exact start/end rules.-- 5. period expressions can be tricky. Their documentation needs im-- provement, but is worth studying.-- 6. Some period expressions with a repeating interval must begin on a- natural boundary of that interval. Eg in weekly from DATE, DATE- must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an- error.-- 7. Other period expressions with an interval are automatically expanded- to cover a whole number of that interval. (This is done to improve- reports, but it also affects periodic transactions. Yes, it's a bit- inconsistent with the above.) Eg: ~ every 10th day of month from- 2023/01, which is equivalent to ~ every 10th day of month from- 2023/01/01, will be adjusted to start on 2019/12/10.-- 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.):-- # every first of month- ~ monthly- expenses:rent $2000- assets:bank:checking-- # every 15th of month in 2023's first quarter:- ~ monthly from 2023-04-15 to 2023-06-16- expenses:utilities $400- assets:bank:checking-- The period expression is the same syntax used for specifying multi-pe-- riod reports, just interpreted differently; there, it specifies report- periods; here it specifies recurrence dates (the periods' start dates).-- Periodic rules and relative dates- Partial or relative dates (like 12/31, 25, tomorrow, last week, next- quarter) are usually not recommended in periodic rules, since the re-- sults will change as time passes. If used, they will be interpreted- relative to, in order of preference:-- 1. the first day of the default year specified by a recent Y directive-- 2. or the date specified with --today-- 3. or the date on which you are running the report.-- They will not be affected at all by report period or forecast period- dates.-- 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 2023"- ; ||- ; vv- ~ every 2 months in 2023, we will review- assets:bank:checking $1500- income:acme inc-- So,-- o Do write two spaces between your period expression and your transac-- tion description, if any.-- o Don't accidentally write two spaces in the middle of your period ex-- pression.-- Auto postings- The = directive declares an "auto posting rule", which adds extra post-- ings to existing transactions. (Remember, postings are the account- name & amount lines below a transaction's date & description.)-- In the journal, an auto posting rule looks quite like a transaction,- but instead of date and description it has = (mnemonic: "match") and a- query, like this:-- = QUERY- ACCOUNT AMOUNT- ...-- Queries are just like command line queries; an account name substring- is most common. Query terms containing spaces should be enclosed in- single or double quotes.-- Each = rule works like this: when hledger is run with the --auto flag,- wherever the QUERY matches a posting in the journal, the rule's post-- ings are added to that transaction, immediately below the matched post-- ing. Note these generated postings are temporary, existing only for- the duration of the report, and only when --auto is used; they are not- saved in the journal file by hledger.-- Generated postings' amounts can depend on the matched posting's amount.- So auto postings can be useful for, eg, adding tax postings with a- standard percentage. AMOUNT can be:-- o a number with no commodity symbol, like 2. The matched posting's- commodity symbol will be added to this.-- o a normal amount with a commodity symbol, like $2. This will be used- as-is.-- o an asterisk followed by a number, like *2. This will multiply the- matched posting's amount (and total price, if any) by the number.-- o an asterisk followed by an amount with commodity symbol, like *$2.- This multiplies and also replaces the commodity symbol with this new- one.-- 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-- Note that depending fully on generated data such as this has some draw-- backs - it's less portable, less future-proof, less auditable by oth-- ers, and less robust (eg your balance assertions will depend on whether- you use or don't use --auto). An alternative is to use auto postings- in "one time" fashion - use them to help build a complex journal entry,- view it with hledger print --auto, and then copy that output into the- journal file to make it permanent.-- 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.-- This also means that you cannot have more than one auto-posting with a- missing amount applied to a given transaction, as it will be unable to- infer amounts.-- 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".-- Auto postings on forecast transactions only- Tip: you can can make auto postings that will apply to forecast trans-- actions but not recorded transactions, by adding tag:_generated-trans-- action to their QUERY. This can be useful when generating new journal- entries to be saved in the journal.-- Other syntax- hledger journal format supports quite a few other features, mainly to- make interoperating with or converting from Ledger easier. Note some- of the features below are powerful and can be useful in special cases,- but in general, features in this section are considered less important- or even not recommended for most users. Downsides are mentioned to- help you decide if you want to use them.-- Balance assignments- Ledger-style balance assignments are also supported. These are like- balance assertions, but with no posting amount on the left side of the- equals sign; instead it is calculated automatically so as to satisfy- the assertion. This can be a convenience during data entry, eg when- 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).-- Downsides: using balance assignments makes your journal less explicit;- to know the exact amount posted, you have to run hledger or do the cal-- culations yourself, instead of just reading it. Also balance assign-- ments' forcing of balances can hide errors. These things make your fi-- nancial data less portable, less future-proof, and less trustworthy in- an audit.-- Balance assignments and costs- A cost in a balance assignment will cause the calculated amount to have- that cost attached:-- 2019/1/1- (a) = $1 @ 2-- $ hledger print --explicit- 2019-01-01- (a) $1 @ 2 = $1 @ 2-- Balance assignments and multiple files- Balance assignments handle multiple files like balance assertions.- They see balance from other files previously included from the current- file, but not from previous sibling or parent files.-- Bracketed posting dates- For setting posting dates and secondary posting dates, Ledger's brack-- eted date syntax is also supported: [DATE], [DATE=DATE2] or [=DATE2] in- posting comments. hledger will attempt to parse any square-bracketed- sequence of the 0123456789/-.= characters in this way. With this syn-- tax, DATE infers its year from the transaction and DATE2 infers its- year from DATE.-- Downsides: another syntax to learn, redundant with hledger's- date:/date2: tags, and confusingly similar to Ledger's lot date syntax.-- D directive- D AMOUNT-- This 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- current file.-- For compatibility/historical reasons, D also acts like a commodity di-- rective (setting the commodity's decimal mark for parsing and display- style for output). So its argument is not just a commodity symbol, but- a full amount demonstrating the style. The amount must include a deci-- mal mark (either period or comma). 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-- Interactions with other directives:-- For setting a commodity's display style, a commodity directive has- highest priority, then a D directive.-- For detecting a commodity's decimal mark during parsing, decimal-mark- has highest priority, then commodity, then D.-- For checking commodity symbols with the check command, a commodity di-- rective is required (hledger check commodities ignores D directives).-- Downsides: omitting commodity symbols makes your financial data less- explicit, less portable, and less trustworthy in an audit. It is usu-- ally an unsustainable shortcut; sooner or later you will want to track- multiple commodities. D is overloaded with functions redundant with- commodity and decimal-mark. And it works differently from Ledger's D.-- apply account directive- This directive sets a default parent account, which will be prepended- to all accounts in following entries, until an end apply account direc-- tive or end of current file. Eg:-- apply account home-- 2010/1/1- food $10- cash-- end apply account-- is equivalent to:-- 2010/01/01- home:food $10- home:cash $-10-- account directives are also affected, and so is any included content.-- Account names entered via hledger add or hledger-web are not affected.-- Account aliases, if any, are applied after the parent account is- prepended.-- Downsides: this can make your financial data less explicit, less- portable, and less trustworthy in an audit.-- Y directive- Y YEAR-- or (deprecated backward-compatible forms):-- year YEAR apply year YEAR-- The space is optional. This sets a default year to be used for subse-- quent dates which don't specify a year. Eg:-- Y2009 ; set default year to 2009-- 12/15 ; equivalent to 2009/12/15- expenses 1- assets-- year 2010 ; change default year to 2010-- 2009/1/30 ; specifies the year, not affected- expenses 1- assets-- 1/31 ; equivalent to 2010/1/31- expenses 1- assets-- Downsides: omitting the year (from primary transaction dates, at least)- makes your financial data less explicit, less portable, and less trust-- worthy in an audit. Such dates can get separated from their corre-- sponding Y directive, eg when evaluating a region of the journal in- your editor. A missing Y directive makes reports dependent on today's- date.-- Secondary dates- 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".-- Downsides: makes your financial data more complicated, less portable,- and less trustworthy in an audit. Keeping the meaning of the two dates- consistent requires discipline, and you have to remember which report-- ing mode is appropriate for a given report. Posting dates are simpler- and better.-- Star comments- Lines beginning with * (star/asterisk) are also comment lines. This- feature allows Emacs users to insert org headings in their journal, al-- lowing them to fold/unfold/navigate it like an outline when viewed with- org mode.-- Downsides: another, unconventional comment syntax to learn. Decreases- your journal's portability. And switching to Emacs org mode just for- folding/unfolding meant losing the benefits of ledger mode; nowadays- you can add outshine mode to ledger mode to get folding without losing- ledger mode's features.-- Valuation expressions- Ledger allows a valuation function or value to be written in double- parentheses after an amount. hledger ignores these.-- Virtual postings- A posting with parentheses around the account name, like (some:account)- 10, is called an unbalanced virtual posting. These postings do not- participate in transaction balancing. (And if you write them without- an amount, a zero amount is always inferred.) These can occasionally- be convenient for special circumstances, but they violate double entry- bookkeeping and make your data less portable across applications, so- many people avoid using them at all.-- A posting with brackets around the account name ([some:account]) is- called a balanced virtual posting. The balanced virtual postings in a- transaction must add up to zero, just like ordinary postings, but sepa-- rately from them. These are not part of double entry bookkeeping ei-- ther, but they are at least balanced. An example:-- 2022-01-01 buy food with cash, update budget envelope subaccounts, & something else- assets:cash $-10 ; <- these balance each other- expenses:food $7 ; <-- expenses:food $3 ; <-- [assets:checking:budget:food] $-10 ; <- and these balance each other- [assets:checking:available] $10 ; <-- (something:else) $5 ; <- this is not required to balance-- Ordinary postings, whose account names are neither parenthesised nor- bracketed, are called real postings. You can exclude virtual postings- from reports with the -R/--real flag or a real:1 query.-- Other Ledger directives- These other Ledger directives are currently accepted but ignored. This- allows hledger to read more Ledger files, but be aware that hledger's- reports may differ from Ledger's if you use these.-- apply fixed COMM AMT- apply tag TAG- assert EXPR- bucket / A ACCT- capture ACCT REGEX- check EXPR- define VAR=EXPR- end apply fixed- end apply tag- end apply year- end tag- eval / expr EXPR- python- PYTHONCODE- tag NAME- value EXPR- --command-line-flags-- See also https://hledger.org/ledger.html for a detailed hledger/Ledger- syntax comparison.-- Other cost/lot notations- A slight digression for Ledger and Beancount users. Ledger has a num-- ber of cost/lot-related notations:-- o @ UNITCOST and @@ TOTALCOST-- o expresses a conversion rate, as in hledger-- o when buying, also creates a lot than can be selected at selling- time-- o (@) UNITCOST and (@@) TOTALCOST (virtual cost)-- o like the above, but also means "this cost was exceptional, don't- use it when inferring market prices".-- Currently, hledger treats the above like @ and @@; the parentheses are- ignored.-- o {=FIXEDUNITCOST} and {{=FIXEDTOTALCOST}} (fixed price)-- o when buying, means "this cost is also the fixed price, don't let it- fluctuate in value reports"-- o {UNITCOST} and {{TOTALCOST}} (lot price)-- o can be used identically to @ UNITCOST and @@ TOTALCOST, also cre-- ates a lot-- o when selling, combined with @ ..., specifies an investment lot by- its cost basis; does not check if that lot is present-- o and related: [YYYY/MM/DD] (lot date)-- o when buying, attaches this acquisition date to the lot-- o when selling, selects a lot by its acquisition date-- o (SOME TEXT) (lot note)-- o when buying, attaches this note to the lot-- o when selling, selects a lot by its note-- Currently, hledger accepts any or all of the above in any order after- the posting amount, but ignores them. (This can break transaction bal-- ancing.)-- For Beancount users, the notation and behaviour is different:-- o @ UNITCOST and @@ TOTALCOST-- o expresses a cost without creating a lot, as in hledger-- o when buying (augmenting) or selling (reducing) a lot, combined with- {...}: documents the cost/selling price (not used for transaction- balancing)-- o {UNITCOST} and {{TOTALCOST}}-- o when buying (augmenting), expresses the cost for transaction bal-- ancing, and also creates a lot with this cost basis attached-- o when selling (reducing),-- o selects a lot by its cost basis-- o raises an error if that lot is not present or can not be selected- unambiguously (depending on booking method configured)-- o expresses the selling price for transaction balancing-- Currently, hledger accepts the {UNITCOST}/{{TOTALCOST}} notation but- ignores it.-- o variations: {}, {YYYY-MM-DD}, {"LABEL"}, {UNITCOST, "LABEL"}, {UNIT-- COST, YYYY-MM-DD, "LABEL"} etc.-- Currently, hledger rejects these.--CSV- hledger can read CSV files (Character Separated Value - usually comma,- semicolon, or tab) containing dated records, automatically converting- each record into a transaction.-- (To learn about writing CSV, see CSV output.)-- For best error messages when reading CSV/TSV/SSV files, make sure they- have a corresponding .csv, .tsv or .ssv file extension or use a hledger- file prefix (see File Extension below).-- Each CSV file must be described by a corresponding rules file.- This contains rules describing the CSV data (header line, fields lay-- out, date format etc.), how to construct hledger transactions from it,- and how to categorise transactions based on description or other at-- tributes.-- By default, hledger expects this rules file to be named like the CSV- file, with an extra .rules extension added, in the same directory. Eg- when asked to read foo/FILE.csv, hledger looks for foo/FILE.csv.rules.- You can specify a different rules file with the --rules-file option.-- 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-- There's an introductory Importing CSV data tutorial on hledger.org, and- more CSV rules examples below, and a larger collection at- https://github.com/simonmichael/hledger/tree/master/examples/csv.-- CSV rules cheatsheet- The following kinds of rule can appear in the rules file, in any order.- (Blank lines and lines beginning with # or ; or * are ignored.)-- source optionally declare which file to read data- from- separator declare the field separator, instead of rely-- ing on file extension- skip skip one or more header lines at start of file- date-format declare how to parse CSV dates/date-times- timezone declare the time zone of ambiguous CSV- date-times- newest-first improve txn order when: there are multiple- records, newest first, all with the same date- intra-day-reversed improve txn order when: same-day txns are in- opposite order to the overall file- decimal-mark declare the decimal mark used in CSV amounts,- when ambiguous- fields list name CSV fields for easy reference, and op-- tionally assign their values to hledger fields- Field assignment assign a CSV value or interpolated text value- to a hledger field- if block conditionally assign values to hledger fields,- or skip a record or end (skip rest of file)- if table conditionally assign values to hledger fields,- using compact syntax- balance-type select which type of balance assertions/as-- signments to generate- include inline another CSV rules file-- Working with CSV tips can be found below, including How CSV rules are- evaluated.-- source- If you tell hledger to read a csv file with -f foo.csv, it will look- for rules in foo.csv.rules. Or, you can tell it to read the rules- file, with -f foo.csv.rules, and it will look for data in foo.csv- (since 1.30).-- These are mostly equivalent, but the second method provides some extra- features. For one, the data file can be missing, without causing an- error; it is just considered empty. And, you can specify a different- data file by adding a "source" rule:-- source ./Checking1.csv-- If you specify just a file name with no path, hledger will look for it- in your system's downloads directory (~/Downloads, currently):-- source Checking1.csv-- And if you specify a glob pattern, hledger will read the most recent of- the matched files (useful with repeated downloads):-- source Checking1*.csv-- See also "Working with CSV > Reading files specified by rule".-- 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.-- skip- skip N-- The word skip followed by a number (or no number, meaning 1) tells- hledger to ignore this many non-empty lines at the start of the input- data. You'll need this whenever your CSV data contains header lines.- Note, empty and blank lines are skipped automatically, so you don't- need to count those.-- skip has a second meaning: it can be used inside if blocks (described- below), to skip one or more records whenever the condition is true.- Records skipped in this way are ignored, except they are still required- to be valid CSV.-- 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-style- date parsing pattern - see https://hackage.haskell.org/pack-- age/time/docs/Data-Time-Format.html#v:formatTime. The pattern 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-- timezone- timezone TIMEZONE-- When CSV contains date-times that are implicitly in some time zone- other than yours, but containing no explicit time zone information, you- can use this rule to declare the CSV's native time zone, which helps- prevent off-by-one dates.-- When the CSV date-times do contain time zone information, you don't- need this rule; instead, use %Z in date-format (or %z, %EZ, %Ez; see- the formatTime link above).-- In either of these cases, hledger will do a time-zone-aware conversion,- localising the CSV date-times to your current system time zone. If you- prefer to localise to some other time zone, eg for reproducibility, you- can (on unix at least) set the output timezone with the TZ environment- variable, eg:-- $ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv-- timezone currently does not understand timezone names, except "UTC",- "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", or "PDT". For- others, use numeric format: +HHMM or -HHMM.-- newest-first- hledger tries to ensure that the generated transactions will be ordered- chronologically, including same-day transactions. Usually it can- auto-detect how the CSV records are ordered. But if it encounters CSV- where all records are on the same date, it assumes that the records are- oldest first. If in fact the CSV's records are normally newest first,- like:-- 2022-10-01, txn 3...- 2022-10-01, txn 2...- 2022-10-01, txn 1...-- you can add the newest-first rule to help hledger generate the transac-- tions in correct order.-- # same-day CSV records are newest first- newest-first-- intra-day-reversed- If CSV records within a single day are ordered opposite to the overall- record order, you can add the intra-day-reversed rule to improve the- order of journal entries. Eg, here the overall record order is newest- first, but same-day records are oldest first:-- 2022-10-02, txn 3...- 2022-10-02, txn 4...- 2022-10-01, txn 1...- 2022-10-01, txn 2...-- # transactions within each day are reversed with respect to the overall date order- intra-day-reversed-- 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.-- fields list- fields FIELDNAME1, FIELDNAME2, ...-- A fields list (the word fields followed by comma-separated field names)- is optional, but convenient. It does two things:-- 1. It names the CSV field in each column. This can be convenient if- you are referencing them in other rules, so you can say %SomeField- instead of remembering %13.-- 2. Whenever you use one of the special hledger field names (described- below), it assigns the CSV value in this position to that hledger- field. This is the quickest way to populate hledger's fields and- build a transaction.-- Here's an example that says "use the 1st, 2nd and 4th fields as the- transaction's date, description and amount; name the last two fields- for later reference; and ignore the others":-- fields date, description, , amount, , , somefield, anotherfield-- In a fields list, the separator is always comma; it is unrelated to the- CSV file's separator. Also:-- o 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 Field names may contain _ (underscore) or - (hyphen).-- o Fields you don't care about can be given a dummy name or an empty- name.-- If the CSV contains column headings, it's convenient to use these for- your field names, suitably modified (eg lower-cased with spaces re-- placed by underscores).-- Sometimes you may want to alter a CSV field name to avoid assigning to- a hledger field with the same name. Eg you could call the CSV's "bal-- ance" field balance_ to avoid directly setting hledger's balance field- (and generating a balance assertion).-- Field assignment- HLEDGERFIELD 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 either by their 1-based position in the- CSV record (%N) or by the name they were given in the fields list- (%CSVFIELD), and regular expression match groups (\N).-- 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 " be-- comes 1 when interpolated) (#1051).-- o Interpolations always refer to a CSV field - you can't interpolate a- hledger field. (See Referencing other fields below).-- Field names- Note the two kinds of field names mentioned here, and used only in- hledger CSV rules files:-- 1. CSV field names (CSVFIELD in these docs): you can optionally name- the CSV columns for easy reference (since hledger doesn't yet auto-- matically recognise column headings in a CSV file), by writing arbi-- trary names in a fields list, eg:-- fields When, What, Some_Id, Net, Total, Foo, Bar-- 2. Special hledger field names (HLEDGERFIELD in these docs): you must- set at least some of these to generate the hledger transaction from- a CSV record, by writing them as the left hand side of a field as-- signment, eg:-- date %When- code %Some_Id- description %What- comment %Foo %Bar- amount1 $ %Total-- or directly in a fields list:-- fields date, description, code, , amount1, Foo, Bar- currency $- comment %Foo %Bar-- Here are all the special hledger field names available, and what hap-- pens when you assign values to them:-- 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.-- You can assign multi-line comments by writing literal \n in the code.- A comment starting with \n will begin on a new line.-- Comments can contain 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, in conditional rules.-- If a posting's account name is left unset but its amount is set (see- below), a default account name will be chosen (like "expenses:unknown"- or "income:unknown").-- amount field- There are several ways to set posting amounts from CSV, useful in dif-- ferent situations.-- 1. amount is the oldest and simplest. Assigning to this sets the- amount of the first and second postings. In the second posting, the- amount will be negated; also, if it has a cost attached, it will be- converted to cost.-- 2. amount-in and amount-out work exactly like the above, but should be- used when the CSV has two amount fields (such as "Debit" and- "Credit", or "Inflow" and "Outflow"). Whichever field has a- non-zero value will be used as the amount of the first and second- postings. Here are some tips to avoid confusion:-- o It's not "amount-in for posting 1 and amount-out for posting 2",- it is "extract a single amount from the amount-in or amount-out- field, and use that for posting 1 and (negated) for posting 2".-- o Don't use both amount and amount-in/amount-out in the same rules- file; choose based on whether the amount is in a single CSV field- or spread across two fields.-- o In each record, at most one of the two CSV fields should contain- a non-zero amount; the other field must contain a zero or noth-- ing.-- o hledger assumes both CSV fields contain unsigned numbers, and it- automatically negates the amount-out values.-- o If the data doesn't fit these requirements, you'll probably need- an if rule (see below).-- 3. amountN (where N is a number from 1 to 99) sets the amount of only a- single posting: the Nth posting in the transaction. You'll usually- need at least two such assignments to make a balanced transaction.- You can also generate more than two postings, to represent more com-- plex transactions. The posting numbers don't have to be consecu-- tive; with if rules, higher posting numbers can be useful to ensure- a certain order of postings.-- 4. amountN-in and amountN-out work exactly like the above, but should- be used when the CSV has two amount fields. This is analogous to- amount-in and amount-out, and those tips also apply here.-- 5. Remember that a fields list can also do assignments. So in a fields- list if you name a CSV field "amount", that counts as assigning to- amount. (If you don't want that, call it something else in the- fields list, like "amount_".)-- 6. The above don't handle every situation; if you need more flexibil-- ity, use an if rule to set amounts conditionally. See "Working with- CSV > Setting amounts" below for more on this and on amount-setting- generally.-- currency field- currency sets a currency symbol, to be prepended to all postings'- 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 the Working with CSV tips below for more about setting amounts and- currency.-- if block- Rules can be applied conditionally, depending on patterns in the CSV- data. This allows flexibility; in particular, it is how you can cate-- gorise transactions, selecting an appropriate account name based on- their description (for example). There are two ways to write condi-- tional rules: "if blocks", described here, and "if tables", described- below.-- An if block is the word if and one or more "matcher" expressions (can- be a word or phrase), one per line, starting either on the same or next- line; followed by one or more indented rules. Eg,-- if MATCHER- RULE-- or-- if- MATCHER- MATCHER- MATCHER- RULE- RULE-- If any of the matchers succeeds, all of the indented rules will be ap-- plied. They are usually field assignments, but the following special- rules may also be used within an if block:-- o skip - skips the matched CSV record (generating no transaction from- it)-- o end - skips the rest of the current CSV file.-- Some examples:-- # if the record contains "groceries", set account2 to "expenses:groceries"- if groceries- account2 expenses:groceries-- # if the record contains any of these phrases, set account2 and a transaction comment as shown- if- monthly service fee- atm transaction fee- banking thru software- account2 expenses:business:banking- comment XXX deductible ? check it-- # if an empty record is seen (assuming five fields), ignore the rest of the CSV file- if ,,,,- end-- Matchers- There are two kinds:-- 1. A record matcher is a word or single-line text fragment or regular- expression (REGEX), which hledger will try to match case-insensi-- tively anywhere within the CSV record.- Eg: whole foods-- 2. A field matcher is preceded with a percent sign and CSV field name- (%CSVFIELD REGEX). hledger will try to match these just within the- named CSV field.- Eg: %date 2023-- The regular expression is (as usual in hledger) a POSIX extended regu-- lar expression, that also supports GNU word boundaries (\b, \B, \<,- \>), and nothing else. If you have trouble, see "Regular expressions"- in the hledger manual (https://hledger.org/hledger.html#regular-expres-- sions).-- What matchers match- With record matchers, it's important to know that the record matched is- not the original CSV record, but a modified one: separators will be- converted to commas, and enclosing double quotes (but not enclosing- whitespace) are removed. So for example, when reading an SSV file, if- the original record was:-- 2023-01-01; "Acme, Inc."; 1,000-- the regex would see, and try to match, this modified record text:-- 2023-01-01,Acme, Inc., 1,000-- Combining matchers- When an if block has multiple matchers, they are combined as follows:-- o By default they are OR'd (any of them can match)-- o When a matcher is preceded by ampersand (&, at the start of the line)- it will be AND'ed with the previous matcher (all in the AND'ed group- must match)-- o Added in 1.32 When a matcher is preceded by an exclamation mark (!),- it is negated (it must not match).-- Note currently there is a limitation: you can't use both & and ! on the- same line (you can't AND a negated matcher).-- Match groups- Added in 1.32-- Matchers can define match groups: parenthesised portions of the regular- expression which are available for reference in field assignments.- Groups are enclosed in regular parentheses (( and )) and can be nested.- Each group is available in field assignments using the token \N, where- N is an index into the match groups for this conditional block (e.g.- \1, \2, etc.).-- Example: Warp credit card payment postings to the beginning of the- billing period (Month start), to match how they are presented in state-- ments, using posting dates:-- if %date (....-..)-..- comment2 date:\1-01-- Another example: Read the expense account from the CSV field, but throw- away a prefix:-- if %account1 liabilities:family:(expenses:.*)- account1 \1-- if table- "if tables" are an alternative to if blocks; they can express many- matchers and field assignments in a more compact tabular format, like- this:-- if,HLEDGERFIELD1,HLEDGERFIELD2,...- MATCHERA,VALUE1,VALUE2,...- MATCHERB,VALUE1,VALUE2,...- ; Comment line that explains MATCHERC- MATCHERC,VALUE1,VALUE2,...- <empty line>-- The first character after if is taken to be this if table's field sepa-- rator. It is unrelated to the separator used in the CSV file. It- should be a non-alphanumeric character like , or | that does not appear- anywhere else in the table (it should not be used in field names or- matchers or values, and it cannot be escaped with a backslash).-- Each line must contain the same number of separators; empty values are- allowed. Whitespace can be used in the matcher lines for readability- (but not in the if line, currently). You can use the comment lines in- the table body. The table must be terminated by an empty line (or end- of file).-- An if table like the above is interpreted as follows: try all of the- matchers; whenever a matcher succeeds, assign all of the values on that- line to the corresponding hledger fields; If multiple lines match,- later lines will override fields assigned by the earlier ones - just- like the sequence of if blocks would behave.-- If table presented above is equivalent to this sequence of if blocks:-- if MATCHERA- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...-- if MATCHERB- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...-- ; Comment line which explains MATCHERC- if MATCHERC- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...-- Example:-- if,account2,comment- atm transaction fee,expenses:business:banking,deductible? check it- %description groceries,expenses:groceries,- ;; Comment line that desribes why this particular date is special- 2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out-- 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-- 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-- Working with CSV- Some 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 eradman.com/entrproject:-- $ 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- Note that hledger will only accept valid CSV conforming to RFC 4180,- and equivalent SSV and TSV formats (like RFC 4180 but with semicolon or- tab as separators). This means, eg:-- o Values may be enclosed in double quotes, or not. Enclosing in single- quotes is not allowed. (Eg 'A','B' is rejected.)-- o When values are enclosed in double quotes, spaces outside the quotes- are not allowed. (Eg "A", "B" is rejected.)-- o When values are not enclosed in quotes, they may not contain double- quotes. (Eg A"A, B is rejected.)-- If your CSV/SSV/TSV is not valid in this sense, you'll need to trans-- form it before reading with hledger. Try using sed, or a more permis-- sive CSV parser like python's csv lib.-- File Extension- To help hledger choose the CSV file reader and show the right error- messages (and choose the right field separator character by default),- it's best if CSV/SSV/TSV files are named with a .csv, .ssv or .tsv- filename extension. (More about this at Data formats.)-- When reading files with the "wrong" extension, you can ensure the CSV- reader (and the default field separator) by prefixing the file path- with csv:, ssv: or tsv:: Eg:-- $ hledger -f ssv:foo.dat print-- You can also override the default field separator with a separator rule- if needed.-- Reading CSV from standard input- You'll need the file format prefix when reading CSV from stdin also,- since hledger assumes journal format by default. Eg:-- $ cat foo.dat | hledger -f ssv:- print-- Reading multiple CSV files- If you use multiple -f options to read multiple CSV files at once,- hledger will look for a correspondingly-named rules file for each CSV- file. But if you use the --rules-file option, that rules file will be- used for all the CSV files.-- Reading files specified by rule- Instead of specifying a CSV file in the command line, you can specify a- rules file, as in hledger -f foo.csv.rules CMD. By default this will- read data from foo.csv in the same directory, but you can add a source- rule to specify a different data file, perhaps located in your web- browser's download directory.-- This feature was added in hledger 1.30, so you won't see it in most CSV- rules examples. But it helps remove some of the busywork of managing- CSV downloads. Most of your financial institutions's default CSV file-- names are different and can be recognised by a glob pattern. So you- can put a rule like source Checking1*.csv in foo-checking.csv.rules,- and then periodically follow a workflow like:-- 1. Download CSV from Foo's website, using your browser's defaults-- 2. Run hledger import foo-checking.csv.rules to import any new transac-- tions-- After import, you can: discard the CSV, or leave it where it is for a- while, or move it into your archives, as you prefer. If you do noth-- ing, next time your browser will save something like Checking1-2.csv,- and hledger will use that because of the * wild card and because it is- the most recent.-- Valid transactions- After reading a CSV file, hledger post-processes and validates the gen-- erated journal entries as it would for a journal file - balancing them,- applying balance assignments, and canonicalising amount styles. Any- errors at this stage will be reported in the usual way, displaying the- problem entry.-- There is one exception: balance assertions, if you have generated them,- will not be checked, since normally these will work only when the CSV- data is part of the main journal. If you do need to check balance as-- sertions generated from CSV right away, pipe into another hledger:-- $ hledger -f file.csv print | hledger -f- print-- Deduplicating, importing- When you download a CSV file periodically, eg to get your latest bank- transactions, the new file may overlap with the old one, containing- some of the same records.-- The import command will (a) detect the new transactions, and (b) append- just those transactions to your main journal. It is idempotent, so you- don't have to remember how many times you ran it or with which version- of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This- is the easiest way to import CSV data. Eg:-- # download the latest CSV files, then run this command.- # Note, no -f flags needed here.- $ hledger import *.csv [--dry]-- This method works for most CSV files. (Where records have a stable- chronological order, and new records appear only at the new end.)-- A number of other tools and workflows, hledger-specific and otherwise,- exist for converting, deduplicating, classifying and managing CSV data.- See:-- o https://hledger.org/cookbook.html#setups-and-workflows-- o https://plaintextaccounting.org -> data import/conversion-- Setting amounts- Continuing from amount field above, here are more tips for amount-set-- ting:-- 1. If the amount is in a single CSV field:- a. If its sign indicates direction of flow:- Assign it to amountN, to set the Nth posting's amount. N is usu-- ally 1 or 2 but can go up to 99.-- b. If another field indicates direction of flow:- Use one or more conditional rules to set the appropriate amount- sign. Eg:-- # assume a withdrawal unless Type contains "deposit":- amount1 -%Amount- if %Type deposit- amount1 %Amount-- 2. If the amount is in two CSV fields (such as Debit and Credit, or In- and Out):- a. If both fields are unsigned:- Assign one field to amountN-in and the other to amountN-out.- hledger will automatically negate the "out" field, and will use- whichever field value is non-zero as posting N's amount.-- b. If either field is signed:- You will probably need to override hledger's sign for one or the- other field, as in the following example:-- # Negate the -out value, but only if it is not empty:- fields date, description, amount1-in, amount1-out- if %amount1-out [1-9]- amount1-out -%amount1-out-- c. If both fields can contain a non-zero value (or both can be- empty):- The -in/-out rules normally choose the value which is- non-zero/non-empty. Some value pairs can be ambiguous, such as 1- and none. For such cases, use conditional rules to help select the- amount. Eg, to handle the above you could select the value con-- taining non-zero digits:-- fields date, description, in, out- if %in [1-9]- amount1 %in- if %out [1-9]- amount1 %out-- 3. If you want posting 2's amount converted to cost:- Use the unnumbered amount (or amount-in and amount-out) syntax.-- 4. If the CSV has only balance amounts, not transaction amounts:- Assign to balanceN, to set a balance assignment on the Nth posting,- causing the posting's amount to be calculated automatically. balance- with no number is equivalent to balance1. In this situation hledger is- more likely to guess the wrong default account name, so you may need to- set that explicitly.-- Amount signs- There is some special handling making it easier to parse and to reverse- amount signs. (This only works for whole amounts, not for cost amounts- such as COST in amount1 AMT @ COST):-- 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- "".-- It's not possible (without preprocessing the CSV) to set an amount to- its absolute value, ie discard its sign.-- Setting currency/commodity- If the currency/commodity symbol is included in the CSV's amount- field(s):-- 2023-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-- 2023-01-01 foo- expenses:unknown $123.00- income:unknown $-123.00-- If the currency is provided as a separate CSV field:-- 2023-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-- 2023-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-- 2023-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 re-- peated, the last one wins:-- o skip (at top level)-- o date-format-- o newest-first-- o fields - names the CSV fields, optionally sets up initial assignments- to hledger fields-- Then for each CSV record in turn:-- o test all if blocks. If any of them contain a end rule, skip all re-- maining CSV records. Otherwise if any of them contain a skip rule,- skip that many CSV records. If there are multiple matched skip- rules, the first one wins.-- o collect all field assignments at top level and in matched if blocks.- When there are multiple assignments for a field, keep only the last- one.-- o compute a value for each hledger field - either the one that was as-- signed to it (and interpolate the %CSVFIELD references), or a default-- o generate a hledger transaction (journal entry) from these values.-- This is all part of the CSV reader, one of several readers hledger can- use to parse input files. When all files have been read successfully,- the transactions are passed as input to whichever hledger command the- user specified.-- Well factored rules- Some things than can help reduce duplication and complexity in rules- files:-- o Extracting common rules usable with multiple CSV files into a com-- mon.rules, and adding include common.rules to each CSV's rules file.-- o Splitting if blocks into smaller if blocks, extracting the frequently- used parts.-- CSV rules examples- 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.-- Coinbase- A simple example with some CSV from Coinbase. The spot price is- recorded using cost notation. The legacy amount field name conve-- niently sets amount 2 (posting 2's amount) to the total cost.-- # Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes- # 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,"","","","Received 100.00 USDC from an external account"-- # coinbase.csv.rules- skip 1- fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes- date %Timestamp- date-format %Y-%m-%dT%T%Z- description %Notes- account1 assets:coinbase:cc- amount %Quantity_Transacted %Asset @ %Spot_Price_at_Transaction %Spot_Price_Currency-- $ hledger print -f coinbase.csv- 2021-12-30 Received 100.00 USDC from an external account- assets:coinbase:cc 100 USDC @ 0.740000 GBP- income:unknown -74.000000 GBP-- 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:--Timeclock- 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 op-- tional. The timezone, if present, must be four digits and is ignored- (currently the time is always interpreted as a local time). Lines be-- ginning with # or ; or *, and blank lines, are ignored.-- i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:- 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 2 spaces ; optional comment, tags:- (some account) 0.33h-- 2015-03-31 * 22:21-23:59- (another:account) 1.64h-- 2015-04-01 * 00:00-02:00- (another:account) 2.01h-- 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 time-- clock-x.el and perhaps the extras in ledgerutils.el-- o at the command line, use these bash aliases: cli 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- timedot format is hledger's human-friendly time logging format. Com-- pared to timeclock format, it is more convenient for quick, approxi-- mate, and retroactive time logging, and more human-readable (you can- see at a glance where time was spent). A quick example:-- 2023-05-01- hom:errands .... .... ; two hours; the space is ignored- fos:hledger:timedot .. ; half an hour- per:admin:finance ; no time spent yet-- hledger reads this as a transaction on this day with three (unbalanced)- postings, where each dot represents "0.25". No commodity symbol is as-- sumed, but we typically interpret it as hours.-- $ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required- 2023-05-01 *- (hom:errands) 2.00 ; two hours- (fos:hledger:timedot) 0.50 ; half an hour- (per:admin:finance) 0-- A timedot file contains a series of transactions (usually one per day).- Each begins with a simple date (Y-M-D, Y/M/D, or Y.M.D), optionally be- followed on the same line by a transaction description, and/or a trans-- action comment following a semicolon.-- After the date line are zero or more time postings, consisting of:-- o An account name - any hledger-style account name, optionally in-- dented.-- o Two or more spaces - required if there is an amount (as in journal- format).-- o A timedot amount, which can be-- o empty (representing zero)-- o a number, optionally followed by a unit s, m, h, d, w, mo, or y,- representing a precise number of seconds, minutes, hours, days- weeks, months or years (hours is assumed by default), which will be- converted to hours according to 60s = 1m, 60m = 1h, 24h = 1d, 7d =- 1w, 30d = 1mo, 365d = 1y.-- o one or more dots (period characters), each representing 0.25.- These are the dots in "timedot". Spaces are ignored and can be- used for grouping/alignment.-- o Added in 1.32 one or more letters. These are like dots but they- also generate a tag t: (short for "type") with the letter as its- value, and a separate posting for each of the values. This pro-- vides a second dimension of categorisation, viewable in reports- with --pivot t.-- o An optional comment following a semicolon (a hledger-style posting- comment).-- There is some flexibility to help with keeping time log data and notes- in the same file:-- o Blank lines and lines beginning with # or ; are ignored.-- o After the first date line, lines which do not contain a double space- are parsed as postings with zero amount. (hledger's register reports- will show these if you add -E).-- o Before the first date line, lines beginning with * (eg org headings)- are ignored. And from the first date line onward, Emacs org mode- heading prefixes at the start of lines (one or more *'s followed by a- space) will be ignored. This means the time log can also be a org- outline.-- Timedot examples- Numbers:-- 2016/2/3- inc:client1 4- fos:hledger 3h- biz:research 60m-- Dots:-- # 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 .-- $ 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-- Letters:-- # Activity types:- # c cleanup/catchup/repair- # e enhancement- # s support- # l learning/research-- 2023-11-01- work:adm ccecces-- $ hledger -f a.timedot print- 2023-11-01- (work:adm) 1 ; t:c- (work:adm) 0.5 ; t:e- (work:adm) 0.25 ; t:s-- $ hledger -f a.timedot bal- 1.75 work:adm- --------------------- 1.75-- $ hledger -f a.timedot bal --pivot t- 1.00 c- 0.50 e- 0.25 s- --------------------- 1.75-- Org:-- * 2023 Work Diary- ** Q1- *** 2023-02-29- **** DONE- 0700 yoga- **** UNPLANNED- **** BEGUN- hom:chores- cleaning ...- water plants- outdoor - one full watering can- indoor - light watering- **** TODO- adm:planning: trip- *** LATER-- Using . as account name separator:-- 2016/2/4- fos.hledger.timedot 4h- fos.ledger ..-- $ hledger -f a.timedot --alias '/\./=:' bal -t- 4.50 fos- 4.00 hledger:timedot- 0.50 ledger- --------------------- 4.50--PART 3: REPORTING CONCEPTS-Amount formatting- Commodity display style- For the amounts in each commodity, hledger chooses a consistent display- style (symbol placement, decimal mark and digit group marks, number of- decimal digits) to use in most reports. This is inferred as follows:-- First, if there's a D directive declaring a default commodity, that- commodity symbol and amount format is applied to all no-symbol amounts- in the journal.-- Then each commodity's display style is determined from its commodity- directive. We recommend always declaring commodities with commodity- directives, since they help ensure consistent display styles and preci-- sions, and bring other benefits such as error checking for commodity- symbols. Here's an example:-- # Set display styles (and decimal marks, for parsing, if there is no decimal-mark directive)- # for the $, EUR, INR and no-symbol commodities:- commodity $1,000.00- commodity EUR 1.000,00- commodity INR 9,99,99,999.00- commodity 1 000 000.9455-- But for convenience, if a commodity directive is not present, hledger- infers a commodity's display styles from its amounts as they are writ-- ten in the journal (excluding cost amounts and amounts in periodic- transaction rules or auto posting rules). It uses-- o the symbol placement and decimal mark of the first amount seen-- o the digit group marks of the first amount with digit group marks-- o and the maximum number of decimal digits seen across all amounts.-- And as fallback if no applicable amounts are found, it would use a de-- fault style, like $1000.00 (symbol on the left with no space, period as- decimal mark, and two decimal digits).-- Finally, commodity styles can be overridden by the -c/--commodity-style- command line option.-- Rounding- Amounts are stored internally as decimal numbers with up to 255 decimal- places. They are displayed with their original journal precisions by- print and print-like reports, and rounded to their display precision- (the number of decimal digits specified by the commodity display style)- by other reports. When rounding, hledger uses banker's rounding (it- rounds to the nearest even digit). So eg 0.5 displayed with zero deci-- mal digits appears as "0".-- Trailing decimal marks- If you're wondering why your print report sometimes shows trailing dec-- imal marks, with no decimal digits; it does this when showing amounts- that have digit group marks but no decimal digits, to disambiguate them- and allow them to be re-parsed reliably (see Decimal marks). Eg:-- commodity $1,000.00-- 2023-01-02- (a) $1000-- $ hledger print- 2023-01-02- (a) $1,000.-- If this is a problem (eg when exporting to Ledger), you can avoid it by- disabling digit group marks, eg with -c/--commodity (for each affected- commodity):-- $ hledger print -c '$1000.00'- 2023-01-02- (a) $1000-- or by forcing print to always show decimal digits, with --round:-- $ hledger print -c '$1,000.00' --round=soft- 2023-01-02- (a) $1,000.00-- Amount parseability- More generally, hledger output falls into three rough categories, which- format amounts a little bit differently to suit different consumers:-- 1. "hledger-readable output" - should be readable by hledger (and by- humans)-- o This is produced by reports that show full journal entries: print,- import, close, rewrite etc.-- o It shows amounts with their original journal precisions, which may- not be consistent.-- o It adds a trailing decimal mark when needed to avoid showing ambigu-- ous amounts.-- o It can be parsed reliably (by hledger and ledger2beancount at least,- but perhaps not by Ledger..)-- 2. "human-readable output" - usually for humans-- o This is produced by all other reports.-- o It shows amounts with standard display precisions, which will be con-- sistent within each commodity.-- o It shows ambiguous amounts unmodified.-- o It can be parsed reliably in the context of a known report (when you- know decimals are consistently not being shown, you can assume a sin-- gle mark is a digit group mark).-- 3. "machine-readable output" - usually for other software-- o This is produced by all reports when an output format like csv, tsv,- json, or sql is selected.-- o It shows amounts as 1 or 2 do, but without digit group marks.-- o It can be parsed reliably (if needed, the decimal mark can be changed- with -c/--commodity-style).--Time periods- Report start & end date- By default, most hledger reports will show the full span of time repre-- sented by the journal. The report start date will be the earliest- transaction or posting date, and the report end date will be the latest- transaction, posting, or market price date.-- Often you will want to see a shorter time span, such as the current- month. You can specify a start and/or end date using -b/--begin,- -e/--end, -p/--period or a date: query (described below). All of these- accept the smart date syntax (below).-- Some notes:-- o End dates are exclusive, as in Ledger, so you should write the date- after the last day you want to see in the report.-- 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 In some cases a report interval will adjust start/end dates to fall- on interval boundaries (see below).-- Examples:-- -b 2016/3/17 begin on St. Patrick's day 2016- -e 12/1 end at the start of december 1st of the current year- (11/30 will be the last date included)- -b thismonth all transactions on or after the 1st of the current month- -p thismonth all transactions in the current month- date:2016/3/17.. the above written as queries instead (.. can also be re-- placed with -)- date:..12/1- date:thismonth..- date:thismonth-- Smart dates- hledger's user interfaces accept a "smart date" syntax for added conve-- nience. Smart dates optionally can be relative to today's date, be- written with english words, and have less-significant parts omitted- (missing parts are inferred as 1). Some 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- in n n periods from the current period- days/weeks/months/quar-- ters/years- n n periods from the current period- days/weeks/months/quar-- ters/years ahead- n -n periods from the current period- days/weeks/months/quar-- ters/years ago- 20181201 8 digit YYYYMMDD with valid year month and day- 201812 6 digit YYYYMM with valid year and month-- Some 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-- "Today's date" can be overridden with the --today option, in case it's- needed for testing or for recreating old reports. (Except for periodic- transaction rules, which are not affected by --today.)-- Report intervals- A report interval can be specified so that reports like register, bal-- ance or activity become multi-period, showing each subperiod as a sepa-- rate row or column.-- The following standard intervals can be enabled with command-line- flags:-- o -D/--daily-- o -W/--weekly-- o -M/--monthly-- o -Q/--quarterly-- o -Y/--yearly-- More complex intervals can be specified using -p/--period, described- below.-- Date adjustment- When there is a report interval (other than daily), report start/end- dates which have been inferred, eg from the journal, are automatically- adjusted to natural period boundaries. This is convenient for produc-- ing simple periodic reports. More precisely:-- o an inferred start date will be adjusted earlier if needed to fall on- a natural period boundary-- o an inferred end date will be adjusted later if needed to make the- last period the same length as the others.-- By contrast, start/end dates which have been specified explicitly, with- -b, -e, -p or date:, will not be adjusted (since hledger 1.29). This- makes it possible to specify non-standard report periods, but it also- means that if you are specifying a start date, you should pick one- that's on a period boundary if you want to see simple report period- headings.-- Period expressions- The -p/--period option specifies a period expression, which is a com-- pact way of expressing a start date, end date, and/or report interval.-- Here's a period expression with a start and end date (specifying the- first quarter of 2009):-- -p "from 2009/1/1 to 2009/4/1"-- Several keywords like "from" and "to" are supported for readability;- these are optional. "to" can also be written as ".." or "-". The- spaces are also optional, as long as you don't run two dates together.- So the following are equivalent to the above:-- -p "2009/1/1 2009/4/1"- -p2009/1/1to2009/4/1- -p2009/1/1..2009/4/1-- Dates are smart dates, so if the current year is 2009, these are also- equivalent to the above:-- -p "1/1 4/1"- -p "jan-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 date in the journal:-- -p "from 2009/1/1" everything after january- 1, 2009- -p "since 2009/1" the same, since is a syn-- onym- -p "from 2009" the same- -p "to 2009" everything before january- 1, 2009-- You can also specify a period by writing a single partial or full date:-- -p "2009" the year 2009; equivalent to "2009/1/1 to 2010/1/1"- -p "2009/1" the month of january 2009; equivalent to "2009/1/1 to- 2009/2/1"- -p "2009/1/1" the first day of 2009; equivalent to "2009/1/1 to- 2009/1/2"-- or by using the "Q" quarter-year syntax (case insensitive):-- -p "2009Q1" first quarter of 2009, equivalent to "2009/1/1 to- 2009/4/1"- -p "q4" fourth quarter of the current year-- Period expressions with a report interval- A period expression can also begin with a report interval, separated- from the start/end dates (if any) by a space or the word in:-- -p "weekly from 2009/1/1 to 2009/4/1"- -p "monthly in 2008"- -p "quarterly"-- More complex report intervals- Some more complex intervals can be specified within period expressions,- such as:-- o biweekly (every two weeks)-- o fortnightly-- o bimonthly (every two months)-- o every day|week|month|quarter|year-- o every N days|weeks|months|quarters|years-- Weekly on a custom day:-- o every Nth day of week (th, nd, rd, or st are all accepted after the- number)-- o every WEEKDAYNAME (full or three-letter english weekday name, case- insensitive)-- Monthly on a custom day:-- o every Nth day [of month]-- o every Nth WEEKDAYNAME [of month]-- Yearly on a custom day:-- o every MM/DD [of year] (month number and day of month number)-- o every MONTHNAME DDth [of year] (full or three-letter english month- name, case insensitive, and day of month number)-- o every DDth MONTHNAME [of year] (equivalent to the above)-- Examples:-- -p "bimonthly from 2008"- -p "every 2 weeks"- -p "every 5 months from- 2009/03"- -p "every 2nd day of week" periods will go from Tue to Tue- -p "every Tue" same- -p "every 15th day" period boundaries will be on 15th of each- 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- November- -p "every 5th November" same- -p "every Nov 5th" same-- Show historical balances at end of the 15th day of each month (N is an- end date, exclusive as always):-- $ hledger balance -H -p "every 16th day"-- Group postings from the start of wednesday to end of the following- tuesday (N is both (inclusive) start date and (exclusive) end date):-- $ hledger register checking -p "every 3rd day of week"-- Multiple weekday intervals- This special form is also supported:-- o every WEEKDAYNAME,WEEKDAYNAME,... (full or three-letter english week-- day names, case insensitive)-- Also, weekday and weekendday are shorthand for mon,tue,wed,thu,fri and- sat,sun.-- This is mainly intended for use with --forecast, to generate periodic- transactions on arbitrary days of the week. It may be less useful with- -p, since it divides each week into subperiods of unequal length, which- is unusual. (Related: #1632)-- Examples:-- -p "every dates will be Mon, Wed, Fri; periods will be- mon,wed,fri" Mon-Tue, Wed-Thu, Fri-Sun- -p "every weekday" dates will be Mon, Tue, Wed, Thu, Fri; periods will- be Mon, Tue, Wed, Thu, Fri-Sun- -p "every weekend- dates will be Sat, Sun; periods will be Sat, Sun-Fri- day"--Depth- With the --depth NUM option (short form: -NUM), reports will show ac-- counts only to the specified depth, hiding deeper subaccounts. Use- this when you want a summary with less detail. This flag has the same- effect as a depth: query argument: depth:2, --depth=2 or -2 are equiva-- lent.--Queries- One of hledger's strengths is being able to quickly report on a precise- subset of your data. Most hledger commands accept query arguments, to- restrict their scope. Multiple query terms can be provided to build up- a more complex query.-- o By default, a query term is interpreted as a case-insensitive sub-- string pattern for matching account names:-- car:fuel- dining groceries- o Patterns containing spaces or other special characters must be en-- closed in single or double quotes:-- 'personal care'- o These patterns are actually regular expressions, so you can add reg-- exp metacharacters for more precision (see "Regular expressions"- above for details):-- '^expenses\b'- 'food$'- 'fuel|repair'- 'accounts (payable|receivable)'- o To match something other than account name, add one of the query type- prefixes described in "Query types" below:-- date:202312-- status:- desc:amazon- cur:USD- cur:\\$- amt:'>0'- o Add a not: prefix to negate a term:-- not:status:'*'- not:desc:'opening|closing'- not:cur:USD- o Terms with different types are AND-ed, terms with the same type are- OR-ed (mostly; see "Combining query terms" below). The following- query:-- date:2022 desc:amazon desc:amzn-- is interpreted as:-- date is in 2022 AND ( transaction description contains "amazon" OR- "amzn" )-- 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 or REGEX- Match account names containing this case insensitive regular expres-- sion. This is the default query type, so we usually don't bother writ-- ing the "acct:" prefix.-- 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 es-- caping. 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 in-- terval. 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.-- expr:"TERM AND NOT (TERM OR TERM)" (eg)- Match with a boolean combination of queries (which must be enclosed in- quotes). See Combining query terms below.-- 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.-- type:TYPECODES- Match by account type (see Declaring accounts > Account types). TYPE-- CODES is one or more of the single-letter account type codes ALERXCV,- case insensitive. Note type:A and type:E will also match their respec-- tive subtypes C (Cash) and V (Conversion). Certain kinds of account- alias can disrupt account types, see Rewriting accounts > Aliases and- account types.-- tag:REGEX[=REGEX]- Match by tag name, and optionally also by tag value. (To match only by- value, use tag:.=REGEX.)-- When querying by tag, note that:-- o Accounts also inherit the tags of their parent accounts-- o Postings also inherit the tags of their account and their transaction-- o Transactions also acquire the tags of their postings.-- (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- When given multiple space-separated 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.-- The print command is a little different, showing 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.-- We also support more complex boolean queries with the expr: prefix.- This allows one to combine query terms using and, or, not keywords- (case insensitive), and to group them by enclosing in parentheses.-- Some examples:-- o Exclude account names containing 'food':-- expr:"not food" (not:food is equivalent)-- o Match things which have 'cool' in the description and the 'A' tag:-- expr:"desc:cool and tag:A" (expr:"desc:cool tag:A" is equivalent)-- o Match things which either do not reference the 'expenses:food' ac-- count, or do have the 'A' tag:-- expr:"not expenses:food or tag:A"-- o Match things which either do not reference the 'expenses:food' ac-- count, or which reference the 'expenses:drink' account and also have- the 'A' tag:-- expr:"expenses:food or (expenses:drink and tag:A)"-- expr: has a restriction: date: queries may not be used inside or ex-- pressions. That would allow disjoint report periods or disjoint result- sets, with unclear semantics for our reports.-- Queries and command options- Some queries can also be expressed as command-line options: depth:2 is- equivalent to --depth 2, date:2023 is equivalent to -p 2023, etc. When- you mix command options and query arguments, generally the resulting- 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 re-- ports, cur: and amt: match the old commodity symbol and the old amount- quantity, not the new ones. (Except in hledger 1.22, #1625.)--Pivoting- Normally, hledger groups and sums amounts within each account. The- --pivot FIELD option substitutes some other transaction field for ac-- count names, causing amounts to be grouped and summed by that field's- value instead. FIELD can be any of the transaction fields acct, sta-- tus, code, desc, payee, note, or a tag name. When pivoting on a tag- and a posting has multiple values of that tag, only the first value is- displayed. Values containing colon:separated:parts will be displayed- hierarchically, like account names. Multiple, colon-delimited fields- can be pivoted simultaneously, generating a hierarchical account name.-- Some examples:-- 2016/02/16 Yearly Dues Payment- assets:bank account 2 EUR- income:dues -2 EUR ; member: John Doe, kind: Lifetime-- Normal balance report showing account names:-- $ hledger balance- 2 EUR assets:bank account- -2 EUR income:dues- --------------------- 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):-- $ 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-- Hierarchical reports can be generated with multiple pivots:-- $ hledger balance Income:Dues --pivot kind:member- -2 EUR Lifetime:John Doe- --------------------- -2 EUR--Generating data- hledger has several features for generating data, such as:-- o Periodic transaction rules can generate single or repeating transac-- tions following a template. These are usually dated in the future,- eg to help with forecasting. They are activated by the --forecast- option.-- o The balance command's --budget option uses these same periodic rules- to generate goals for the budget report.-- o Auto posting rules can generate extra postings on certain matched- transactions. They are always applied to forecast transactions; with- the --auto flag they are applied to transactions recorded in the- journal as well.-- o The --infer-equity flag infers missing conversion equity postings- from @/@@ costs. And the inverse --infer-costs flag infers missing- @/@@ costs from conversion equity postings.-- Generated data of this kind is temporary, existing only at report time.- But you can see it in the output of hledger print, and you can save- that to your journal, in effect converting it from temporary generated- data to permanent recorded data. This could be useful as a data entry- aid.-- If you are wondering what data is being generated and why, add the- --verbose-tags flag. In hledger print output you will see extra tags- like generated-transaction, generated-posting, and modified on gener-- ated/modified data. Also, even without --verbose-tags, generated data- always has equivalen hidden tags (with an underscore prefix), so eg you- could match generated transactions with tag:_generated-transaction.--Forecasting- Forecasting, or speculative future reporting, can be useful for esti-- mating future balances, or for exploring different future scenarios.-- The simplest and most flexible way to do it with hledger is to manually- record a bunch of future-dated transactions. You could keep these in a- separate future.journal and include that with -f only when you want to- see them.-- --forecast- There is another way: with the --forecast option, hledger can generate- temporary "forecast transactions" for reporting purposes, according to- periodic transaction rules defined in the journal. Each rule can gen-- erate multiple recurring transactions, so by changing one rule you can- change many forecasted transactions.-- Forecast transactions usually start after ordinary transactions end.- By default, they begin after your latest-dated ordinary transaction, or- today, whichever is later, and they end six months from today. (The- exact rules are a little more complicated, and are given below.)-- This is the "forecast period", which need not be the same as the report- period. You can override it - eg to forecast farther into the future,- or to force forecast transactions to overlap your ordinary transactions- - by giving the --forecast option a period expression argument, like- --forecast=..2099 or --forecast=2023-02-15... Note that the = is re-- quired.-- Inspecting forecast transactions- print is the best command for inspecting and troubleshooting forecast- transactions. Eg:-- ~ monthly from 2022-12-20 rent- assets:bank:checking- expenses:rent $1000-- $ hledger print --forecast --today=2023/4/21- 2023-05-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- 2023-06-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- 2023-07-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- 2023-08-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- 2023-09-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- Here there are no ordinary transactions, so the forecasted transactions- begin on the first occurence after today's date. (You won't normally- use --today; it's just to make these examples reproducible.)-- Forecast reports- Forecast transactions affect all reports, as you would expect. Eg:-- $ hledger areg rent --forecast --today=2023/4/21- Transactions in expenses:rent and subaccounts:- 2023-05-20 rent as:ba:checking $1000 $1000- 2023-06-20 rent as:ba:checking $1000 $2000- 2023-07-20 rent as:ba:checking $1000 $3000- 2023-08-20 rent as:ba:checking $1000 $4000- 2023-09-20 rent as:ba:checking $1000 $5000-- $ hledger bal -M expenses --forecast --today=2023/4/21- Balance changes in 2023-05-01..2023-09-30:-- || May Jun Jul Aug Sep- ===============++===================================- expenses:rent || $1000 $1000 $1000 $1000 $1000- ---------------++------------------------------------ || $1000 $1000 $1000 $1000 $1000-- Forecast tags- Forecast transactions generated by --forecast have a hidden tag, _gen-- erated-transaction. So if you ever need to match forecast transac-- tions, you could use tag:_generated-transaction (or just tag:generated)- in a query.-- For troubleshooting, you can add the --verbose-tags flag. Then, visi-- ble generated-transaction tags will be added also, so you can view them- with the print command. Their value indicates which periodic rule was- responsible.-- Forecast period, in detail- Forecast start/end dates are chosen so as to do something useful by de-- fault in almost all situations, while also being flexible. Here are- (with luck) the exact rules, to help with troubleshooting:-- The forecast period starts on:-- o the later of-- o the start date in the periodic transaction rule-- o the start date in --forecast's argument-- o otherwise (if those are not available): the later of-- o the report start date specified with -b/-p/date:-- o the day after the latest ordinary transaction in the journal-- o otherwise (if none of these are available): today.-- The forecast period ends on:-- o the earlier of-- o the end date in the periodic transaction rule-- o the end date in --forecast's argument-- o otherwise: the report end date specified with -e/-p/date:-- o otherwise: 180 days (~6 months) from today.-- Forecast troubleshooting- When --forecast is not doing what you expect, one of these tips should- help:-- o Remember to use the --forecast option.-- o Remember to have at least one periodic transaction rule in your jour-- nal.-- o Test with print --forecast.-- o Check for typos or too-restrictive start/end dates in your periodic- transaction rule.-- o Leave at least 2 spaces between the rule's period expression and de-- scription fields.-- o Check for future-dated ordinary transactions suppressing forecasted- transactions.-- o Try setting explicit report start and/or end dates with -b, -e, -p or- date:-- o Try adding the -E flag to encourage display of empty periods/zero- transactions.-- o Try setting explicit forecast start and/or end dates with --fore-- cast=START..END-- o Consult Forecast period, in detail, above.-- o Check inside the engine: add --debug=2 (eg).--Budgeting- With the balance command's --budget report, each periodic transaction- rule generates recurring budget goals in specified accounts, and goals- and actual performance can be compared. See the balance command's doc- below.-- You can generate budget goals and forecast transactions at the same- time, from the same or different periodic transaction rules: hledger- bal -M --budget --forecast ...-- See also: Budgeting and Forecasting.--Cost reporting- In some transactions - for example a currency conversion, or a purchase- or sale of stock - one commodity is exchanged for another. In these- transactions there is a conversion rate, also called the cost (when- buying) or selling price (when selling). In hledger docs we just say- "cost", for convenience; feel free to mentally translate to "conversion- rate" or "selling price" if helpful.-- Recording costs- We'll explore several ways of recording transactions involving costs.- These are also summarised at hledger Cookbook > Cost notation.-- Costs can be recorded explicitly in the journal, using the @ UNITCOST- or @@ TOTALCOST notation described in Journal > Costs:-- Variant 1-- 2022-01-01- assets:dollars $-135- assets:euros 100 @ $1.35 ; $1.35 per euro (unit cost)-- Variant 2-- 2022-01-01- assets:dollars $-135- assets:euros 100 @@ $135 ; $135 total cost-- Typically, writing the unit cost (variant 1) is preferable; it can be- more effort, requiring more attention to decimal digits; but it reveals- the per-unit cost basis, and makes stock sales easier.-- Costs can also be left implicit, and hledger will infer the cost that- is consistent with a balanced transaction:-- Variant 3-- 2022-01-01- assets:dollars $-135- assets:euros 100-- Here, hledger will attach a @@ 100 cost to the first amount (you can- see it with hledger print -x). This form looks convenient, but there- are downsides:-- o It sacrifices some error checking. For example, if you accidentally- wrote 10 instead of 100, hledger would not be able to detect the mis-- take.-- o It is sensitive to the order of postings - if they were reversed, a- different entry would be inferred and reports would be different.-- o The per-unit cost basis is not easy to read.-- So generally this kind of entry is not recommended. You can make sure- you have none of these by using -s (strict mode), or by running hledger- check balanced.-- Reporting at cost- Now when you add the -B/--cost flag to reports ("B" is from Ledger's- -B/--basis/--cost flag), any amounts which have been annotated with- costs will be converted to their cost's commodity (in the report out-- put). Ie they will be displayed "at cost" or "at sale price".-- Some things to note:-- o Costs are attached to specific posting amounts in specific transac-- tions, and once recorded they do not change. This contrasts with- market prices, which are ambient and fluctuating.-- o Conversion to cost is performed before conversion to market value- (described below).-- Equity conversion postings- There is a problem with the entries above - they are not conventional- Double Entry Bookkeeping (DEB) notation, and because of the "magical"- transformation of one commodity into another, they cause an imbalance- in the Accounting Equation. This shows up as a non-zero grand total in- balance reports like hledger bse.-- For most hledger users, this doesn't matter in practice and can safely- be ignored ! But if you'd like to learn more, keep reading.-- Conventional DEB uses an extra pair of equity postings to balance the- transaction. Of course you can do this in hledger as well:-- Variant 4-- 2022-01-01- assets:dollars $-135- assets:euros 100- equity:conversion $135- equity:conversion -100-- Now the transaction is perfectly balanced according to standard DEB,- and hledger bse's total will not be disrupted.-- And, hledger can still infer the cost for cost reporting, but it's not- done by default - you must add the --infer-costs flag like so:-- $ hledger print --infer-costs- 2022-01-01 one hundred euros purchased at $1.35 each- assets:dollars $-135 @@ 100- assets:euros 100- equity:conversion $135- equity:conversion -100-- $ hledger bal --infer-costs -B- -100 assets:dollars- 100 assets:euros- --------------------- 0-- Here are some downsides of this kind of entry:-- o The per-unit cost basis is not easy to read.-- o Instead of -B you must remember to type -B --infer-costs.-- o --infer-costs works only where hledger can identify the two eq-- uity:conversion postings and match them up with the two non-equity- postings. So writing the journal entry in a particular format be-- comes more important. More on this below.-- Inferring equity conversion postings- Can we go in the other direction ? Yes, if you have transactions writ-- ten with the @/@@ cost notation, hledger can infer the missing equity- postings, if you add the --infer-equity flag. Eg:-- 2022-01-01- assets:dollars -$135- assets:euros 100 @ $1.35-- $ hledger print --infer-equity- 2022-01-01- assets:dollars $-135- assets:euros 100 @ $1.35- equity:conversion:$-: -100- equity:conversion:$-:$ $135.00-- The equity account names will be "equity:conversion:A-B:A" and "eq-- uity:conversion:A-B:B" where A is the alphabetically first commodity- symbol. You can customise the "equity:conversion" part by declaring an- account with the V/Conversion account type.-- Combining costs and equity conversion postings- Finally, you can use both the @/@@ cost notation and equity postings at- the same time. This in theory gives the best of all worlds - preserv-- ing the accounting equation, revealing the per-unit cost basis, and- providing more flexibility in how you write the entry:-- Variant 5-- 2022-01-01 one hundred euros purchased at $1.35 each- assets:dollars $-135- equity:conversion $135- equity:conversion -100- assets:euros 100 @ $1.35-- All the other variants above can (usually) be rewritten to this final- form with:-- $ hledger print -x --infer-costs --infer-equity-- Downsides:-- o The precise format of the journal entry becomes more important. If- hledger can't detect and match up the cost and equity postings, it- will give a transaction balancing error.-- o The add command does not yet accept this kind of entry (#2056).-- o This is the most verbose form.-- Requirements for detecting equity conversion postings- --infer-costs has certain requirements (unlike --infer-equity, which- always works). It will infer costs only in transactions with:-- o Two non-equity postings, in different commodities. Their order is- significant: the cost will be added to the first of them.-- o Two postings to equity conversion accounts, next to one another,- which balance the two non-equity postings. This balancing is checked- to the same precision (number of decimal places) used in the conver-- sion posting's amount. Equity conversion accounts are:-- o any accounts declared with account type V/Conversion, or their sub-- accounts-- o otherwise, accounts named equity:conversion, equity:trade, or eq-- uity:trading, or their subaccounts.-- And multiple such four-posting groups can coexist within a single- transaction. When --infer-costs fails, it does not infer a cost in- that transaction, and does not raise an error (ie, it infers costs- where it can).-- Reading variant 5 journal entries, combining cost notation and equity- postings, has all the same requirements. When reading such an entry- fails, hledger raises an "unbalanced transaction" error.-- Infer cost and equity by default ?- Should --infer-costs and --infer-equity be enabled by default ? Try- using them always, eg with a shell alias:-- alias h="hledger --infer-equity --infer-costs"-- and let us know what problems you find.--Value reporting- Instead of reporting amounts in their original commodity, hledger can- convert them to cost/sale amount (using the conversion rate recorded in- the transaction), and/or to market value (using some market price on a- certain date). This is controlled by the --value=TYPE[,COMMODITY] op-- tion, which will be described below. We also provide the simpler -V- 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- Market prices can change from day to day. hledger will use the prices- on a particular valuation date (or on more than one date). By default- hledger uses "end" dates for valuation. More specifically:-- o For single period reports (including normal print and register re-- ports):-- o If an explicit report end date is specified, that is used-- o Otherwise the latest transaction date or P directive date is used- (even if it's in the future)-- o For multiperiod reports, each period is valued on its last day.-- This can be customised with the --value option described below, which- can select either "then", "end", "now", or "custom" dates. (Note, this- has a bug in hledger-ui <=1.31: turning on valuation with the V key al-- ways resets it to "end".)-- Finding market price- To convert a commodity A to its market value in another commodity B,- hledger looks for a suitable market price (exchange rate) as follows,- 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-prices flag) inferred from costs.-- 2. A reverse market price: the inverse of a declared or inferred market- price from B to A.-- 3. A forward chain of market prices: a synthetic price formed by com-- 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-prices: 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 costs as additional market prices (as- Ledger does) ? Adding the --infer-market-prices flag to -V, -X or- --value enables this.-- So for example, hledger bs -V --infer-market-prices will get market- prices both from P directives and from transactions. 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 Value reporting section carefully, and try adding- --debug or --debug=2 to troubleshoot.-- --infer-market-prices can infer market prices from:-- o multicommodity transactions with explicit prices (@/@@)-- o multicommodity transactions with implicit prices (no @, two commodi-- ties, unbalanced). (With these, the order of postings matters.- hledger print -x can be useful for troubleshooting.)-- o multicommodity transactions with equity postings, if cost is inferred- with --infer-costs.-- There is a limitation (bug) currently: when a valuation commodity is- not specified, prices inferred with --infer-market-prices do not help- select a default valuation commodity, as P prices would. So conversion- might not happen because no valuation commodity was detected (--debug=2- will show this). To be safe, specify the valuation commmodity, eg:-- o -X EUR --infer-market-prices, not -V --infer-market-prices-- o --value=then,EUR --infer-market-prices, not --value=then --infer-mar-- ket-prices-- Signed costs and market prices can be confusing. For reference, here- is the current behaviour, since hledger 1.25. (If you think it should- work differently, see #1870.)-- 2022-01-01 Positive Unit prices- a A 1- b B -1 @ A 1-- 2022-01-01 Positive Total prices- a A 1- b B -1 @@ A 1--- 2022-01-02 Negative unit prices- a A 1- b B 1 @ A -1-- 2022-01-02 Negative total prices- a A 1- b B 1 @@ A -1--- 2022-01-03 Double Negative unit prices- a A -1- b B -1 @ A -1-- 2022-01-03 Double Negative total prices- a A -1- b B -1 @@ A -1-- All of the transactions above are considered balanced (and on each day,- the two transactions are considered equivalent). Here are the market- prices inferred for B:-- $ hledger -f- --infer-market-prices prices- P 2022-01-01 B A 1- P 2022-01-01 B A 1.0- P 2022-01-02 B A -1- P 2022-01-02 B A -1.0- P 2022-01-03 B A -1- P 2022-01-03 B A -1.0-- 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-prices flag is used: the price commodity from the- latest transaction-inferred price for A on or before valuation date.-- This means:-- o If you have P directives, they determine which commodities -V will- convert, and to what.-- o If you have no P directives, and use the --infer-market-prices flag,- costs determine it.-- Amounts for which no valuation commodity can be found are not con-- verted.-- --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.-- Valuation examples- Here are some quick examples of -V:-- ; one euro is worth this many dollars from nov 1- P 2016/11/01 $1.10-- ; purchase some euros on nov 3- 2016/11/3- assets:euros 100- assets:checking-- ; the euro is worth fewer dollars by dec 21- P 2016/12/21 $1.03-- How many euros do I have ?-- $ hledger -f t.j bal -N euros- 100 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-- 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-- Interaction of valuation and queries- When matching postings based on queries in the presence of valuation,- the following happens:-- 1. The query is separated into two parts:-- 1. the currency (cur:) or amount (amt:).-- 2. all other parts.-- 2. The postings are matched to the currency and amount queries based on- pre-valued amounts.-- 3. Valuation is applied to the postings.-- 4. The postings are matched to the other parts of the query based on- post-valued amounts.-- Related: #1625-- Effect of valuation on reports- Here is a reference for how valuation is supposed to affect each part- of hledger's reports. (It's wide, you may need to scroll sideways.)- It may be useful when troubleshooting. If you find problems, please- report them, ideally with a reproducible example. Related: #329,- #1083.-- First, a quick 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).-- Report -B, --cost -V, -X --value=then --value=end --value=DATE,- type --value=now- --------------------------------------------------------------------------------------------- print- posting cost value at re- value at posting value at re- value at- amounts port end or date port or DATE/today- today journal end- balance unchanged unchanged unchanged unchanged unchanged- asser-- tions/as-- signments-- register- starting cost value at re- valued at day value at re- value at- balance port or each historical port or DATE/today- (-H) journal end posting was made journal end- starting cost value at day valued at day value at day value at- balance before re- each historical before re- DATE/today- (-H) with port or posting was made port or- report journal journal- interval start start- posting cost value at re- value at posting value at re- value at- amounts port or date port or DATE/today- journal end journal end- summary summarised value at pe- sum of postings value at pe- value at- posting cost riod ends in interval, val- riod ends DATE/today- amounts ued at interval- with re- start- port in-- terval- running sum/average sum/average sum/average of sum/average sum/average- total/av- of displayed of displayed displayed values of displayed of displayed- erage values values values values-- balance- (bs, bse,- cf, is)- balance sums of value at re- value at posting value at re- value at- changes costs port end or date port or DATE/today of- 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- (--bud-- get)- grand to- sum of dis- sum of dis- sum of displayed sum of dis- sum of dis-- tal played val- played val- valued played val- played values- ues ues ues-- balance- (bs, bse,- cf, is)- with re-- port in-- terval- starting sums of value at re- sums of values of value at re- sums of post-- balances costs of port start postings before port start ings before- (-H) postings be- of sums of report start at of sums of report start- fore report all postings respective post- all postings- start before re- ing dates before re-- port start port start- balance sums of same as sums of values of balance value at- changes costs of --value=end postings in pe- change in DATE/today of- (bal, is, postings in riod at respec- each period, sums of post-- bs period tive posting valued at ings- --change, dates period ends- cf- --change)- end bal- sums of same as sums of values of period end value at- ances costs of --value=end postings from be- balances, DATE/today of- (bal -H, postings fore period start valued at sums of post-- is --H, from before to period end at period ends ings- bs, cf) report start respective post-- to period ing dates- end- budget like balance like balance like balance like bal- like balance- amounts changes/end changes/end changes/end bal- ances changes/end- (--bud- balances balances ances balances- get)- row to- sums, aver- sums, aver- sums, averages of sums, aver- sums, aver-- tals, row ages of dis- ages of dis- displayed values ages of dis- ages of dis-- averages played val- played val- played val- played values- (-T, -A) ues ues ues- column sums of dis- sums of dis- sums of displayed sums of dis- sums of dis-- totals played val- played val- values played val- played values- ues ues ues- grand to- sum, average sum, average sum, average of sum, average sum, average- tal, of column of column column totals of column of column to-- grand av- totals totals totals tals- erage--- --cumulative is omitted to save space, it works like -H but with a zero- starting balance.--PART 4: COMMANDS- Commands overview- Here are the built-in commands:-- DATA ENTRY- These data entry commands are the only ones which can modify your jour-- nal file.-- o add - add transactions using terminal prompts-- o import - add new transactions from other files, eg CSV files-- DATA CREATION- o close - generate balance-zeroing/restoring transactions-- o rewrite - generate auto postings, like print --auto-- DATA MANAGEMENT- o check - check for various kinds of error in the data-- o diff - compare account transactions in two journal files-- REPORTS, FINANCIAL- 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-- REPORTS, VERSATILE- o balance (bal) - show balance changes, end balances, budgets, gains..-- o print - show transactions or export journal data-- o register (reg) - show postings in one or more accounts & running to-- tal-- o roi - show return on investments-- REPORTS, BASIC- o accounts - show account names-- o activity - show bar charts of posting counts per period-- o codes - show transaction codes-- o commodities - show commodity/currency symbols-- o descriptions - show transaction descriptions-- o files - show input file paths-- o notes - show note parts of transaction descriptions-- o payees - show payee parts of transaction descriptions-- o prices - show market prices-- o stats - show journal statistics-- o tags - show tag names-- o test - run self tests-- HELP- o help - show the hledger manual with info/man/pager-- o demo - show small hledger demos in the terminal-- ADD-ONS- And here are some typical add-on commands. Some of these are installed- by the hledger-install script. If installed, they will appear in- hledger's commands list:-- o ui - run hledger's terminal UI-- o web - run hledger's web UI-- o iadd - add transactions using a TUI (currently hard to build)-- o interest - generate interest transactions-- o stockquotes - download market prices from AlphaVantage-- o Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,- pijul, plot, and more..-- Next, each command is described in detail, in alphabetical order.-- accounts- Show account names.-- This command lists account names. By default it shows all known ac-- counts, either used in transactions or declared with account direc-- tives.-- With query arguments, only matched account names and account names ref-- erenced by matched postings are shown.-- Or it can show just the used accounts (--used/-u), the declared ac-- counts (--declared/-d), the accounts declared but not used (--unused),- the accounts used but not declared (--undeclared), or the first account- matched by an account name pattern, if any (--find).-- It shows a flat list by default. With --tree, it uses indentation to- show the account hierarchy. In flat mode you can add --drop N to omit- the first few account name components. Account names can be- depth-clipped with depth:N or --depth N or -N.-- With --types, it also shows each account's type, if it's known. (See- Declaring accounts > Account types.)-- With --positions, it also shows the file and line number of each ac-- count's declaration, if any, and the account's overall declaration or-- der; these may be useful when troubleshooting account display order.-- With --directives, it adds the account keyword, showing valid account- directives which can be pasted into a journal file. This is useful to-- gether with --undeclared when updating your account declarations to- satisfy hledger check accounts.-- The --find flag can be used to look up a single account name, in the- same way that the aregister command does. It returns the alphanumeri-- cally-first matched account name, or if none can be found, it fails- with a non-zero exit code.-- Examples:-- $ hledger accounts- assets:bank:checking- assets:bank:saving- assets:cash- expenses:food- expenses:supplies- income:gifts- income:salary- liabilities:debts-- $ hledger accounts --undeclared --directives >> $LEDGER_FILE- $ hledger check accounts-- 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- 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 main journal file (which should be in- journal format). Existing transactions are not changed. This is one- of the few hledger commands that writes to the journal file (see also- import).-- To use it, just run hledger add and follow the prompts. You can add as- many transactions as you like; when you are finished, enter . or press- control-d or control-c to exit.-- Features:-- o add tries to provide useful defaults, using the most similar (by de-- scription) recent transaction (filtered by the query, if any) as a- template.-- o You can also set the initial defaults with command line arguments.-- o Readline-style edit keys can be used during data entry.-- o The tab key will auto-complete whenever possible - accounts, pay-- ees/descriptions, dates (yesterday, today, tomorrow). If the input- area is empty, it will insert the default value.-- o If the journal defines a default commodity, it will be added to any- 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 https://hledger.org/add.html for a detailed tutorial):-- $ 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> $-- If you enter a number with no commodity symbol, and you have declared a- default commodity with a D directive, you might expect add to add this- symbol for you. It does not do this; we assume that if you are using a- D directive you prefer not to see the commodity symbol repeated on- amounts in the journal.-- aregister- (areg)-- Show the transactions and running historical balance of a single ac-- count, with each transaction displayed as one line.-- aregister shows the overall transactions affecting a particular account- (and any subaccounts). Each report line represents one transaction in- this account. Transactions before the report start date are always in-- cluded in the running balance (--historical mode is always on).-- This is a more "real world", bank-like view than the register command- (which shows individual postings, possibly from multiple accounts, not- necessarily in historical mode). As a quick rule of thumb: - use areg-- ister for reviewing and reconciling real-world asset/liability accounts- - use register for reviewing detailed revenues/expenses.-- aregister requires one argument: the account to report on. You can- write either the full account name, or a case-insensitive regular ex-- pression which will select the alphabetically first matched account.-- When there are multiple matches, the alphabetically-first choice can be- surprising; eg if you have assets:per:checking 1 and assets:biz:check-- ing 2 accounts, hledger areg checking would select assets:biz:checking- 2. It's just a convenience to save typing, so if in doubt, write the- full account name, or a distinctive substring that matches uniquely.-- 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.-- For performance reasons, column widths are chosen based on the first- 1000 lines; this means unusually wide values in later lines can cause- visual discontinuities as column widths are adjusted. If you want to- ensure perfect alignment, at the cost of more time and memory, use the- --align-all flag.-- This command also supports the output destination and output format op-- tions. The output formats supported are txt, csv, tsv (Added in 1.32),- and json.-- aregister and posting dates- aregister always shows one line (and date and amount) per transaction.- But sometimes transactions have postings with different dates. Also,- not all of a transaction's postings may be within the report period.- To resolve this, aregister shows the earliest of the transaction's date- and posting dates that is in-period, and the sum of the in-period post-- ings. In other words it will show a combined line item with just the- earliest date, and the running balance will (temporarily, until the- transaction's last posting) be inaccurate. Use register -H if you need- to see the individual postings.-- There is also a --txn-dates flag, which filters strictly by transaction- date, ignoring posting dates. This too can cause an inaccurate running- 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)-- o or unrealised capital gain/loss (--gain)-- o or balance changes from sibling postings (--related/-r)-- o or postings count (--count)-- ..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 (--in-- vert)-- o rows and columns swapped (--transpose)-- o another field used as account name (--pivot)-- o custom-formatted line items (single-period reports only) (--format)-- o commodities displayed on the same line or multiple lines (--layout)-- This command supports the output destination and output format options,- with output formats txt, csv, tsv (Added in 1.32), json, and (multi-pe-- riod reports only:) html. In txt output in a colour-supporting termi-- nal, 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. ("Simple" here- means just one column of numbers, covering a single period. You can- also have multi-period reports, described later.)-- For real-world accounts, these numbers will normally be their end bal-- ance 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 -f examples/sample.journal bal- $1 assets:bank:saving- $-2 assets:cash- $1 expenses:food- $1 expenses:supplies- $-1 income:gifts- $-1 income:salary- $1 liabilities:debts- --------------------- 0-- Accounts with a zero balance (and no non-zero subaccounts, in tree mode- - see below) are hidden by default. Use -E/--empty to show them (re-- vealing 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.-- Balance report line format- 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 -f examples/sample.journal 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 specifies the formatting applied to each ac-- count/balance pair. It may contain any suitable text, with data fields- interpolated like so:-- %[MIN][.MAX](FIELDNAME)-- o MIN pads with spaces to at least this width (optional)-- o MAX truncates at this width (optional)-- o FIELDNAME must be enclosed in parentheses, and can be one of:-- o depth_spacer - a number of spaces equal to the account's depth, or- if MIN is specified, MIN * depth spaces.-- o account - the account's name-- o total - the account's balance/posted total, right justified-- Also, FMT can begin with an optional prefix to control how multi-com-- modity amounts are rendered:-- o %_ - render on multiple lines, bottom-aligned (the default)-- o %^ - render on multiple lines, top-aligned-- o %, - render on one line, comma-separated-- There are some quirks. Eg in one-line mode, %(depth_spacer) has no ef-- fect, instead %(account) has indentation built in. Experimentation- may be needed to get pleasing results.-- Some example formats:-- o %(total) - the account's total-- o %-20.20(account) - the account's name, left justified, padded to 20- characters and clipped at 20 characters-- o %,%-50(account) %25(total) - account name padded to 50 characters,- total padded to 20 characters, with multiple commodities rendered on- one line-- o %20(total) %2(depth_spacer)%-(account) - the default format for the- single-column balance report-- 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 -f examples/sample.journal 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 -f examples/sample.journal balance- $-1 assets- $1 bank:saving- $-2 cash- $2 expenses- $1 food- $1 supplies- $-2 income- $-1 gifts- $-1 salary- $1 liabilities:debts- --------------------- 0-- 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:NUM query, or --depth NUM option, or just -NUM (eg: -3)- balance reports will show accounts only to the specified depth, hiding- the deeper subaccounts. This can be useful for getting an overview- without too much detail.-- Account balances at the depth limit always include the balances from- any deeper subaccounts (even in list mode). Eg, limiting to depth 1:-- $ hledger -f examples/sample.journal balance -1- $-1 assets- $2 expenses- $-2 income- $1 liabilities- --------------------- 0-- Dropping top-level accounts- You can also hide one or more top-level account name parts, using- --drop NUM. This can be useful for hiding repetitive top-level account- names:-- $ hledger -f examples/sample.journal bal expenses --drop 1- $1 food- $1 supplies- --------------------- $2-- Showing declared accounts- With --declared, accounts which have been declared with an account di-- rective will be included in the balance report, even if they have no- transactions. (Since they will have a zero balance, you will also need- -E/--empty to see them.)-- More precisely, leaf declared accounts (with no subaccounts) will be- included, since those are usually the more useful in reports.-- The idea of this is to be able to see a useful "complete" balance re-- port, even when you don't have transactions in all of your declared ac-- counts yet.-- Sorting by amount- With -S/--sort-amount, accounts with the largest (most positive) bal-- ances are shown first. Eg: hledger bal expenses -MAS shows your- biggest averaged monthly expenses first. When more than one commodity- is present, they will be sorted by the alphabetically earliest commod-- ity first, and then by subsequent commodities (if an amount is missing- a commodity, it is treated as 0).-- Revenues and liability balances are typically negative, however, so -S- shows these in reverse order. To work around this, you can add --in-- vert to flip the signs. (Or, use one of the higher-level reports,- 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.-- 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:-- 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 -f examples/sample.journal bal --quarterly income expenses -E- Balance changes in 2008:-- || 2008q1 2008q2 2008q3 2008q4- ===================++=================================- expenses:food || 0 $1 0 0- expenses:supplies || 0 $1 0 0- income:gifts || 0 $-1 0 0- income:salary || $-1 0 0 0- -------------------++---------------------------------- || $-1 $1 0 0-- 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.-- 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 Filter to a single currency with cur:-- o Convert to a single currency with -V [--infer-market-price]-- o Use a more compact layout like --layout=bare-- 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-- 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 ac-- count during some period.-- An end balance is the amount accumulated in an account as of some date- (and some time, but hledger doesn't store that; assume end of day in- 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- The balance command is quite flexible; here is the full detail on how- to control what it reports. If the following seems complicated, don't- worry - this is for advanced reporting, and it does take time and ex-- perimentation to get familiar with all the report modes.-- There are three important option groups:-- hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]- ...-- Calculation type- The basic calculation to perform for each table cell. It is one of:-- o --sum : sum the posting amounts (default)-- o --budget : sum the amounts, but also show the budget goal amount (for- each account/period)-- o --valuechange : show the change in period-end historical balance val-- ues (caused by deposits, withdrawals, and/or market price fluctua-- tions)-- o --gain : show the unrealised capital gain/loss, (the current valued- balance minus each amount's original cost)-- o --count : show the count of postings-- Accumulation type- How amounts should accumulate across a report's subperiods/columns.- Another way to say it: which time period's postings should contribute- to each cell's calculation. It is one of:-- o --change : calculate with postings from column start to column end,- ie "just this column". Typically used to see revenues/expenses.- (default for balance, cashflow, incomestatement)-- o --cumulative : calculate with postings from report start to column- end, ie "previous columns plus this column". Typically used to show- changes accumulated since the report's start date. Not often used.-- o --historical/-H : calculate with postings from journal start to col-- umn end, ie "all postings from before report start date until this- column's end". Typically used to see historical end balances of as-- sets/liabilities/equity. (default for balancesheet, balancesheete-- quity)-- Valuation type- Which kind of value or cost conversion should be applied, if any, be-- fore displaying the report. It is one of:-- o no valuation type : don't convert to cost or value (default)-- o --value=cost[,COMM] : convert amounts to cost (then optionally to- some other commodity)-- o --value=then[,COMM] : convert amounts to market value on transaction- dates-- o --value=end[,COMM] : convert amounts to market value on period end- date(s)- (default with --valuechange, --gain)-- o --value=now[,COMM] : convert amounts to market value on today's date-- o --value=YYYY-MM-DD[,COMM] : convert amounts to market value on an-- other date-- or one of the equivalent simpler flags:-- o -B/--cost : like --value=cost (though, note --cost and --value are- independent options which can both be used at once)-- o -V/--market : like --value=end-- o -X COMM/--exchange COMM : like --value=end,COMM-- See Cost reporting and Value reporting for more about these.-- Combining balance report types- Most combinations of these options should produce reasonable reports,- but if you find any that seem wrong or misleading, let us know. The- 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=- tion:> YYYY-MM-DD- Accumu- /now- lation:v- ------------------------------------------------------------------------------------ --change change in period sum of post- period-end DATE-value of- ing-date market value of change change in pe-- values in period in period riod- --cumu- change from re- sum of post- period-end DATE-value of- lative port start to ing-date market value of change change from- period end values from re- from report report start- port start to pe- start to period to period end- riod end end- --his- change from sum of post- period-end DATE-value of- torical journal start to ing-date market value of change change from- /-H period end (his- values from jour- from journal journal start- torical end bal- nal start to pe- start to period to period end- ance) riod end end-- Budget report- The --budget report type is like a regular balance report, but with two- main differences:-- o Budget goals and performance percentages are also shown, in brackets-- o Accounts which don't have budget goals are hidden by default.-- This is useful for comparing planned and actual income, expenses, time- usage, etc.-- Periodic transaction rules are used to define budget goals. For exam-- ple, here's a periodic rule defining monthly goals for bus travel and- food expenses:-- ;; Budget- ~ monthly- (expenses:bus) $30- (expenses:food) $400-- After recording some actual expenses,-- ;; Two months worth of expenses- 2017-11-01- income $-1950- expenses:bus $35- expenses:food:groceries $310- expenses:food:dining $42- expenses:movies $38- assets:bank:checking-- 2017-12-01- income $-2100- expenses:bus $53- expenses:food:groceries $380- expenses:food:dining $32- expenses:gifts $100- assets:bank:checking-- we can see a budget report like this:-- $ hledger bal -M --budget- Budget performance in 2017-11-01..2017-12-31:-- || Nov Dec- ===============++============================================- <unbudgeted> || $-425 $-565- expenses || $425 [ 99% of $430] $565 [131% of $430]- expenses:bus || $35 [117% of $30] $53 [177% of $30]- expenses:food || $352 [ 88% of $400] $412 [103% of $400]- ---------------++--------------------------------------------- || 0 [ 0% of $430] 0 [ 0% of $430]-- This is "goal-based budgeting"; you define goals for accounts and peri-- ods, often recurring, and hledger shows performance relative to the- goals. This contrasts with "envelope budgeting", which is more de-- tailed and strict - useful when cash is tight, but also quite a bit- more work. https://plaintextaccounting.org/Budgeting has more on this- topic.-- Using the budget report- Historically this report has been confusing and fragile. hledger's- version should be relatively robust and intuitive, but you may still- find surprises. Here are more notes to help with learning and trou-- bleshooting.-- o In the above example, expenses:bus and expenses:food are shown be-- cause they have budget goals during the report period.-- o Their parent expenses is also shown, with budget goals aggregated- from the children.-- o The subaccounts expenses:food:groceries and expenses:food:dining are- not shown since they have no budget goal of their own, but they con-- tribute to expenses:food's actual amount.-- o Unbudgeted accounts expenses:movies and expenses:gifts are also not- shown, but they contribute to expenses's actual amount.-- o The other unbudgeted accounts income and assets:bank:checking are- grouped as <unbudgeted>.-- o --depth or depth: can be used to limit report depth in the usual way- (but will not reveal unbudgeted subaccounts).-- o Amounts are always inclusive of subaccounts (even in -l/--list mode).-- o Numbers displayed in a --budget report will not always agree with the- totals, because of hidden unbudgeted accounts; this is normal.- -E/--empty can be used to reveal the hidden accounts.-- o In the periodic rules used for setting budget goals, unbalanced post-- ings are convenient.-- o You can filter budget reports with the usual queries, eg to focus on- particular accounts. It's common to restrict them to just expenses.- (The <unbudgeted> account is occasionally hard to exclude; this is- because of date surprises, discussed below.)-- o When you have multiple currencies, you may want to convert them to- one (-X COMM --infer-market-prices) and/or show just one at a time- (cur:COMM). If you do need to show multiple currencies at once,- --layout bare can be helpful.-- o You can "roll over" amounts (actual and budgeted) to the next period- with --cumulative.-- See also: https://hledger.org/budgeting.html.-- Budget date surprises- With small data, or when starting out, some of the generated budget- goal transaction dates might fall outside the report periods. Eg with- the following journal and report, the first period appears to have no- expenses:food budget. (Also the <unbudgeted> account should be ex-- cluded by the expenses query, but isn't.):-- ~ monthly in 2020- (expenses:food) $500-- 2020-01-15- expenses:food $400- assets:checking-- $ hledger bal --budget expenses- Budget performance in 2020-01-15:-- || 2020-01-15- ===============++====================- <unbudgeted> || $400- expenses:food || 0 [ 0% of $500]- ---------------++--------------------- || $400 [80% of $500]-- In this case, the budget goal transactions are generated on first days- of of month (this can be seen with hledger print --forecast tag:gener-- ated expenses). Whereas the report period defaults to just the 15th- day of january (this can be seen from the report table's column head-- ings).-- To fix this kind of thing, be more explicit about the report period- (and/or the periodic rules' dates). In this case, adding -b 2020 does- the trick.-- Selecting budget goals- By default, the budget report uses all available periodic transaction- rules to generate goals. This includes rules with a different report- interval from your report. Eg if you have daily, weekly and monthly- periodic rules, all of these will contribute to the goals in a monthly- budget report.-- You can select a subset of periodic rules by providing an argument to- the --budget flag. --budget=DESCPAT will match all periodic rules- whose description contains DESCPAT, a case-insensitive substring (not a- regular expression or query). This means you can give your periodic- rules descriptions (remember that two spaces are needed between period- expression and description), and then select from multiple budgets de-- fined in your journal.-- Budgeting vs forecasting- --forecast and --budget both use the periodic transaction rules in the- journal to generate temporary transactions for reporting purposes.- However they are separate features - though you can use both at the- same time if you want. Here are some differences between them:-- --forecast --budget- --------------------------------------------------------------------------- is a general option; it enables fore- is a balance command option; it- casting with all reports selects the balance report's- budget mode- generates visible transactions which generates invisible transactions- appear in reports which produce goal amounts- generates forecast transactions from generates budget goal transac-- after the last regular transaction, to tions throughout the report pe-- the end of the report period; or with riod, optionally restricted by- an argument --forecast=PERIODEXPR gen- periods specified in the peri-- erates them throughout the specified odic transaction rules- period, both optionally restricted by- periods specified in the periodic- transaction rules- uses all periodic rules uses all periodic rules; or with- an argument --budget=DESCPAT- uses just the rules matched by- DESCPAT-- Balance report layout- The --layout option affects how balance reports show multi-commodity- amounts and commodity symbols, which can improve readability. It can- also normalise the data for easy consumption by other programs. It has- four possible values:-- o --layout=wide[,WIDTH]: commodities are shown on a single line, op-- tionally elided to WIDTH-- o --layout=tall: each commodity is shown on a separate line-- o --layout=bare: commodity symbols are in their own column, amounts are- bare numbers-- o --layout=tidy: data is normalised to easily-consumed "tidy" form,- with one row per data value-- Here are the --layout modes supported by each output format Only CSV- output supports all of them:-- - txt csv html json sql- -------------------------------------- wide Y Y Y- tall Y Y Y- bare Y Y Y- tidy Y-- Examples:-- Wide layout- With many commodities, reports can be very wide:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide- Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total- ==================++====================================================================================================================================================================================================================- Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT- ------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT-- A width limit reduces the width, but some commodities will be hidden:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32- Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total- ==================++===========================================================================================================================- Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..- ------------------++---------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..-- Tall layout- Each commodity gets a new line (may be different in each column), and- account names are repeated:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall- Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total- ==================++==================================================- Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD- Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT- Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD- Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA- Assets:US:ETrade || 18.00 VHT 294.00 VHT- ------------------++--------------------------------------------------- || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD- || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT- || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD- || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA- || 18.00 VHT 294.00 VHT-- Bare layout- Commodity symbols are kept in one column, each commodity has its own- row, amounts are bare numbers, account names are repeated:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare- Balance changes in 2012-01-01..2014-12-31:-- || Commodity 2012 2013 2014 Total- ==================++=============================================- Assets:US:ETrade || GLD 0 70.00 0 70.00- Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00- Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50- Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00- Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00- ------------------++---------------------------------------------- || GLD 0 70.00 0 70.00- || ITOT 10.00 18.00 -11.00 17.00- || USD 337.18 -98.12 4881.44 5120.50- || VEA 12.00 10.00 14.00 36.00- || VHT 106.00 18.00 170.00 294.00-- Bare layout also affects CSV output, which is useful for producing data- that is easier to consume, eg for making charts:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare- "account","commodity","balance"- "Assets:US:ETrade","GLD","70.00"- "Assets:US:ETrade","ITOT","17.00"- "Assets:US:ETrade","USD","5120.50"- "Assets:US:ETrade","VEA","36.00"- "Assets:US:ETrade","VHT","294.00"- "total","GLD","70.00"- "total","ITOT","17.00"- "total","USD","5120.50"- "total","VEA","36.00"- "total","VHT","294.00"-- Bare layout will sometimes display an extra row for the no-symbol com-- modity, because of zero amounts (hledger treats zeroes as commod-- ity-less, usually). This can break hledger-bar confusingly- (workaround: add a cur: query to exclude the no-symbol row).-- Tidy layout- This produces normalised "tidy data" (see- https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)- where every variable has its own column and each row represents a sin-- gle data point. This is the easiest kind of data for other software to- consume:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy- "account","period","start_date","end_date","commodity","value"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","GLD","0"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","ITOT","10.00"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","USD","337.18"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","VEA","12.00"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","VHT","106.00"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","GLD","70.00"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","ITOT","18.00"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","USD","-98.12"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","VEA","10.00"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","VHT","18.00"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","GLD","0"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","ITOT","-11.00"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","USD","4881.44"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VEA","14.00"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"-- Some 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-- 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.-- This report shows accounts declared with the Asset, Cash or Liability- type (see account types). Or if no such accounts are declared, it- shows top-level accounts named asset or liability (case insensitive,- plurals allowed) and their subaccounts.-- Example:-- $ hledger balancesheet- Balance Sheet 2008-12-31-- || 2008-12-31- ====================++============- Assets ||- --------------------++------------- assets:bank:saving || $1- assets:cash || $-2- --------------------++------------- || $-1- ====================++============- Liabilities ||- --------------------++------------- liabilities:debts || $-1- --------------------++------------- || $-1- ====================++============- Net: || 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 op-- tions The output formats supported are txt, csv, tsv (Added in 1.32),- html, and json.-- 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.-- This report shows accounts declared with the Asset, Cash, Liability or- Equity type (see account types). Or if no such accounts are declared,- it shows top-level accounts named asset, liability or equity (case in-- sensitive, plurals allowed) and their subaccounts.-- Example:-- $ hledger balancesheetequity- Balance Sheet With Equity 2008-12-31-- || 2008-12-31- ====================++============- Assets ||- --------------------++------------- assets:bank:saving || $1- assets:cash || $-2- --------------------++------------- || $-1- ====================++============- Liabilities ||- --------------------++------------- liabilities:debts || $-1- --------------------++------------- || $-1- ====================++============- Equity ||- --------------------++------------- --------------------++------------- || 0- ====================++============- Net: || 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 report is the easiest way to see if the accounting equation (A+L+E- = 0) is satisfied (after you have done a close --retain to merge rev-- enues and expenses with equity, and perhaps added --infer-equity to- balance your commodity conversions).-- This command also supports the output destination and output format op-- tions The output formats supported are txt, csv, tsv, html, and json.-- cashflow- (cf)-- This command displays a (simple) cashflow statement, showing the in-- flows and outflows affecting "cash" (ie, liquid, easily convertible)- assets. Amounts are shown with normal positive sign, as in conven-- tional financial statements.-- This report shows accounts declared with the Cash type (see account- types). Or if no such accounts are declared, it shows accounts-- o under a top-level account named asset (case insensitive, plural al-- lowed)-- o whose name contains some variation of cash, bank, checking or saving.-- More precisely: all accounts matching this case insensitive regular ex-- pression:-- ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)-- and their subaccounts.-- An example cashflow report:-- $ hledger cashflow- Cashflow Statement 2008-- || 2008- ====================++======- Cash flows ||- --------------------++------- assets:bank:saving || $1- assets:cash || $-2- --------------------++------- || $-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 op-- tions The output formats supported are txt, csv, tsv (Added in 1.32),- html, and json.-- 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-- If you are an Emacs user, you can also configure flycheck-hledger to- run these checks, providing instant feedback as you edit the journal.-- Here are the checks currently available:-- Default checks- These checks are run automatically by (almost) all hledger commands:-- o parseable - data files are in a supported format, with no syntax er-- rors and no invalid include directives.-- o autobalanced - all transactions are balanced, after converting to- cost. Missing amounts and missing costs are inferred automatically- where possible.-- o assertions - all balance assertions in the journal are passing.- (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 balanced - all transactions are balanced after converting to cost,- without inferring missing costs. If conversion costs are required,- they must be explicit.-- o accounts - all account names used by transactions have been declared-- o commodities - all commodity symbols used have been declared-- Other checks- These checks can be run only by giving their names as arguments to- check. They are more specialised and not desirable for everyone:-- o ordereddates - transactions are ordered by date within each file-- o payees - all payees used by transactions have been declared-- o recentassertions - all accounts with balance assertions have a bal-- ance assertion within 7 days of their latest posting-- o tags - all tags used by transactions have been declared-- o uniqueleafnames - all account leaf names are unique-- Custom checks- A few more checks are are available as separate add-on commands, in- 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.-- More about specific checks- hledger check recentassertions will complain if any balance-asserted- account has postings more than 7 days after its latest balance asser-- tion. This aims to prevent the situation where you are regularly up-- dating your journal, but forgetting to check your balances against the- real world, then one day must dig back through months of data to find- an error. It assumes that adding a balance assertion requires/reminds- you to check the real-world balance. (That may not be true if you- auto-generate balance assertions from bank data; in that case, I recom-- mend to import transactions uncleared, and when you manually review and- clear them, also check the latest assertion against the real-world bal-- ance.)-- close- (equity)-- close generates several kinds of "closing" and/or "opening" transac-- tions, useful in certain situations, including migrating balances to a- new journal file, retaining earnings into equity, consolidating bal-- ances, or viewing lots. Like print, it prints valid journal entries.- You can append or copy these to your journal file(s) when you are happy- with how they look.-- close currently has six modes, selected by a single mode flag:-- close --migrate- This is the most common mode. It prints a "closing balances" transac-- tion that zeroes out all asset and liability balances (by default), and- an opposite "opening balances" transaction that restores them again.- The balancing account will be equity:opening/closing balances (or an-- other specified by --close-acct or --open-acct).-- This is useful when migrating balances to a new journal file at the- start of a new year. Essentially, you run hledger close --mi-- grate=NEWYEAR -e NEWYEAR and then copy the closing transaction to the- end of the old file and the opening transaction to the start of the new- file. The opening transaction sets correct starting balances in the- new file when it is used alone, and the closing transaction keeps bal-- ances correct when you use both old and new files together, by can-- celling out the following opening transaction and preventing buildup of- duplicated opening balances. Think of the closing/opening pair as- "moving the balances into the next file".-- You can close a different set of accounts by providing a query. Eg if- you want to include equity, you can add assets liabilities equity or- type:ALE arguments. (The balancing account is always excluded.) Rev-- enues and expenses usually are not migrated to a new file directly; see- --retain below.-- The generated transactions will have a start: tag, with its value set- to --migrate's NEW argument if any, for easier matching or exclusion.- When NEW is not specified, it will be inferred if possible by incre-- menting a number (eg a year number) within the default journal's main- file name. The other modes behave similarly.-- close --close- This prints just the closing balances transaction of --migrate. It is- the default behaviour if you specify no mode flag. Using the customi-- sation options below, you can move balances from any set of accounts to- a different account.-- close --open- This prints just the opening balances transaction of --migrate. It is- similar to Ledger's equity command.-- close --assert- This prints a "closing balances" transaction (with balances: tag), that- just declares balance assertions for the current balances without- changing them. It could be useful as documention and to guard against- changes.-- close --assign- This prints an "opening balances" transaction that restores the account- balances using balance assignments. Balance assignments work regard-- less of any previous balance, so a preceding closing balances transac-- tion is not needed.-- However, omitting the closing balances transaction would unbalance eq-- uity. This is relatively harmless for personal reports, but it dis-- turbs the accounting equation, removing a source of error detection.- So --migrate is generally the best way to set to set balances in new- files, for now.-- close --retain- This is like --close with different defaults: it prints a "retain earn-- ings" transaction (with retain: tag), that transfers revenue and ex-- pense balances to equity:retained earnings.-- This is a different kind of closing, called "retaining earnings" or- "closing the books"; it is traditionally performed by businesses at the- end of each accounting period, to consolidate revenues and expenses- into the main equity balance. ("Revenues" and "expenses" are actually- equity by another name, kept separate temporarily for reporting pur-- poses.)-- In personal accounting you generally don't need to do this, unless you- want the balancesheetequity report to show a zero total, demonstrating- that the accounting equation (A-L=E) is satisfied.-- close customisation- In all modes, the following things can be overridden:-- o the accounts to be closed/opened, with account query arguments-- o the balancing account, with --close-acct=ACCT and/or --open-acct=ACCT-- o the transaction descriptions, with --close-desc=DESC and- --open-desc=DESC-- o the transaction's tag value, with a --MODE=NEW option argument-- o the closing/opening dates, with -e OPENDATE-- By default, the closing date is yesterday, or the journal's end date,- whichever is later; and the opening date is always one day after the- closing date. You can change these by specifying a report end date;- the closing date will be the last day of the report period. Eg -e 2024- means "close on 2023-12-31, open on 2024-01-01".-- With --x/--explicit, the balancing amount will be shown explicitly, and- if it involves multiple commodities, a separate posting will be gener-- ated for each of them (similar to print -x).-- With --interleaved, each individual transfer is shown with source and- destination postings next to each other (perhaps useful for trou-- bleshooting).-- With --show-costs, balances' costs are also shown, with different costs- kept separate. This may generate very large journal entries, if you- have many currency conversions or investment transactions. close- --show-costs is currently the best way to view investment lots with- hledger. (To move or dispose of lots, see the more capable- hledger-move script.)-- close and balance assertions- close adds balance assertions verifying that the accounts have been re-- set to zero in a closing transaction or restored to their previous bal-- ances in an opening transaction. These provide useful error checking,- but you can ignore them temporarily with -I, or remove them if you pre-- fer.-- Single-commodity, subaccount-exclusive balance assertions (=) are gen-- erated by default. This can be changed with --assertion-type='==*'- (eg).-- When running close you should probably avoid using -C, -R, status:- (filtering by status or realness) or --auto (generating postings),- since the generated balance assertions would then require these.-- Transactions with multiple dates (eg posting dates) spanning the file- boundary also can disrupt the balance assertions:-- 2023-12-30 a purchase made in december, cleared in january- expenses:food 5- assets:bank:checking -5 ; date: 2023-01-02-- To solve this you can transfer the money to and from a temporary ac-- count, splitting the multi-day transaction into two single-day transac-- tions:-- ; in 2022.journal:- 2022-12-30 a purchase made in december, cleared in january- expenses:food 5- equity:pending -5-- ; in 2023.journal:- 2023-01-02 last year's transaction cleared- equity:pending 5 = 0- assets:bank:checking -5-- close examples- Retain earnings- Record 2022's revenues/expenses as retained earnings on 2022-12-31, ap-- pending the generated transaction to the journal:-- $ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal-- After this, to see 2022's revenues and expenses you must exclude the- retain earnings transaction:-- $ hledger -f 2022.journal is not:desc:'retain earnings'-- Migrate balances to a new file- Close assets/liabilities on 2022-12-31 and re-open them on 2023-01-01:-- $ hledger close --migrate -f 2022.journal -p 2022- # copy/paste the closing transaction to the end of 2022.journal- # copy/paste the opening transaction to the start of 2023.journal-- After this, to see 2022's end-of-year balances you must exclude the- closing balances transaction:-- $ hledger -f 2022.journal bs not:desc:'closing balances'-- For more flexibility, it helps to tag closing and opening transactions- with eg start:NEWYEAR, then you can ensure correct balances by exclud-- ing all opening/closing transactions except the first, like so:-- $ hledger bs -Y -f 2021.j -f 2022.j -f 2023.j expr:'tag:start=2021 or not tag:start'- $ hledger bs -Y -f 2021.j -f 2022.j expr:'tag:start=2021 or not tag:start'- $ hledger bs -Y -f 2022.j -f 2023.j expr:'tag:start=2022 or not tag:start'- $ hledger bs -Y -f 2021.j expr:'tag:start=2021 or not tag:start'- $ hledger bs -Y -f 2022.j expr:'tag:start=2022 or not tag:start'- $ hledger bs -Y -f 2023.j # unclosed file, no query needed-- More detailed close examples- See examples/multi-year.-- 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:-- 2022/1/1 (123) Supermarket- Food $5.00- Checking-- 2022/1/2 (124) Post Office- Postage $8.32- Checking-- 2022/1/3 Supermarket- Food $11.23- Checking-- 2022/1/4 (126) Post Office- Postage $3.21- Checking-- $ hledger codes- 123- 124- 126-- $ hledger codes -E- 123- 124-- 126-- commodities- List all commodity/currency symbols used or declared in the journal.-- demo- Play demos of hledger usage in the terminal, if asciinema is installed.-- Run this command with no argument to list the demos. To play a demo,- write its number or a prefix or substring of its title. Tips:-- Make your terminal window large enough to see the demo clearly.-- Use the -s/--speed SPEED option to set your preferred playback speed,- eg -s4 to play at 4x original speed or -s.5 to play at half speed. The- default speed is 2x.-- Other asciinema options can be added following a double dash, eg --- -i.1 to limit pauses or -- -h to list asciinema's other options.-- During playback, several keys are available: SPACE to pause/unpause, .- to step forward (while paused), CTRL-c quit.-- Examples:-- $ hledger demo # list available demos- $ hledger demo 1 # play the first demo at default speed (2x)- $ hledger demo install -s4 # play the "install" demo at 4x speed-- 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- 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- List all files included in the journal. With a REGEX argument, only- file names matching the regular expression (case sensitive) are shown.-- help- Show the hledger user manual in the terminal, with info, man, or a- pager. With a TOPIC argument, open it at that topic if possible.- TOPIC can be any heading in the manual, or a heading prefix, case in-- sensitive. Eg: commands, print, forecast, journal, amount, "auto post-- ings".-- This command shows the hledger manual built in to your hledger version.- It can be useful when offline, or when you prefer the terminal to a web- browser, or when the appropriate hledger manual or viewing tools are- not installed on your system.-- By default it chooses the best viewer found in $PATH, trying (in this- order): info, man, $PAGER, less, more. You can force the use of info,- man, or a pager with the -i, -m, or -p flags, If no viewer can be- found, or the command is run non-interactively, it just prints the man-- ual to stdout.-- If using info, note that version 6 or greater is needed for TOPIC- lookup. If you are on mac you will likely have info 4.8, and should- consider installing a newer version, eg with brew install texinfo- (#1770).-- Examples-- $ hledger help --help # show how the help command works- $ hledger help # show the hledger manual with info, man or $PAGER- $ hledger help journal # show the journal topic in the hledger manual- $ hledger help -m journal # show it with man, even if info is installed-- import- Read new transactions added to each FILE provided as arguments since- last run, and add them to the journal. Or with --dry-run, just print- the transactions that would be added. Or with --catchup, just mark all- of the FILEs' current transactions as imported, without importing them.-- This command may append new transactions to the main journal file- (which should be in journal format). Existing transactions are not- changed. This is one of the few hledger commands that writes to the- journal file (see also add).-- Unlike other hledger commands, with import the journal file is an out-- 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- import tries to import only the transactions which are new since the- last import, ignoring any that it has seen in previous runs. So if- your bank's CSV includes the last three months of data, you can down-- load and import it every month (or week, or day) and only the new- transactions will be imported each time.-- It works as follows. For each imported FILE (usually CSV, but they- could be any of hledger's input formats):-- o It tries to recall the latest date seen previously, reading it from a- hidden .latest.FILE in the same directory.-- o Then it processes FILE, ignoring any transactions on or before the- "latest seen" date.-- And after a successful import, it updates the .latest.FILE(s) for next- time (unless --dry-run was used).-- This is a limited kind of deduplication, let's call it "date skipping".- Within each input file, it avoids reprocessing the same dates across- successive runs. This is a simple system that works for most- real-world CSV files; it assumes these are true, or true enough:-- 1. new items always have the newest dates-- 2. item dates are stable across successive downloads-- 3. the order of same-date items is stable across downloads-- 4. the name of the input file is stable across downloads-- If you have a bank whose CSV dates or ordering occasionally change, you- can reduce the chance of this happening in new transactions by import-- ing more often, and in old transactions it doesn't matter. And remem-- ber you can use CSV rules files as input, which is one way to ensure a- stable file name.-- import doesn't detect other kinds of duplication, such as duplicate- transactions within a single run. (In part, because legitimate dupli-- cate transactions can easily occur in real-world data.) So, say you- downloaded but forgot to import bank.1.csv, and a week later you down-- loaded bank.2.csv with overlapping data. Now you should not import- both of these at once (hledger import bank.1.csv bank.2.csv); the over-- lapping transactions which appear twice would not be deduplicated since- this is considered a single import. Instead, import these files one at- a time, and also use the same filename each time for a common "latest- seen" state:-- $ mv bank.1.csv bank.csv; hledger import bank.csv- $ mv bank.2.csv bank.csv; hledger import bank.csv-- Normally you can ignore the .latest.* files, but if needed, you can- delete them (to make all transactions unseen), or construct/modify them- (to catch up to a certain date). The format is just a single ISO-for-- mat date (YYYY-MM-DD), possibly repeated on multiple lines. It means- "I have seen transactions up to this date, and this many of them occur-- ring on that date".-- hledger print --new also uses and updates these .latest.* files, but it- is less often used.-- Related: CSV > Working with CSV > Deduplicating, importing.-- Import testing- With --dry-run, the transactions that will be imported are printed to- 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'-- Note: when importing from multiple files at once, it's currently possi-- ble for some .latest files to be updated successfully, while the actual- import fails because of a problem in one of the files, leaving them out- of sync (and causing some transactions to be missed). To prevent this,- do a --dry-run first and fix any problems before the real import.-- 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- (is)-- This command displays an income statement, showing revenues and ex-- penses during one or more periods. Amounts are shown with normal posi-- tive sign, as in conventional financial statements.-- This report shows accounts declared with the Revenue or Expense type- (see account types). Or if no such accounts are declared, it shows- top-level accounts named revenue or income or expense (case insensi-- tive, plurals allowed) and their subaccounts.-- Example:-- $ hledger incomestatement- Income Statement 2008-- || 2008- ===================++======- Revenues ||- -------------------++------- income:gifts || $1- income:salary || $1- -------------------++------- || $2- ===================++======- Expenses ||- -------------------++------- expenses:food || $1- expenses:supplies || $1- -------------------++------- || $2- ===================++======- Net: || 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 op-- tions The output formats supported are txt, csv, tsv (Added in 1.32),- html, and json.-- notes- List the unique notes that appear in transactions.-- This command lists the unique notes that appear in transactions, in al-- phabetic order. You can add a query to select a subset of transac-- tions. The note is the part of the transaction description after a |- character (or if there is no |, the whole description).-- Example:-- $ hledger notes- Petrol- Snacks-- payees- 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- Print the market prices declared with P directives. With --infer-mar-- ket-prices, also show any additional prices inferred from costs. With- --show-reverse, also show additional prices inferred by reversing known- prices.-- Price amounts are always displayed with their full precision, except- for reverse prices which are limited to 8 decimal digits.-- Prices can be filtered by a date:, cur: or amt: query.-- Generally if you run this command with --infer-market-prices --show-re-- verse, it will show the same prices used internally to calculate value- reports. But if in doubt, you can inspect those directly by running- the value report with --debug=2.-- 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).-- 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/regenerate your journal you should take care to also copy- over the directives and inter-transaction comments.-- Eg:-- $ hledger print -f examples/sample.journal date:200806- 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-- print explicitness- Normally, whether posting amounts are implicit or explicit is pre-- served. For example, when an amount is omitted in the journal, it will- not appear in the output. Similarly, if a conversion cost is implied- but not written, it will not appear in the output.-- You can use the -x/--explicit flag to force explicit display of all- amounts and costs. This can be useful for troubleshooting or for mak-- ing your journal more readable and robust against data entry errors.- -x is also implied by using any of -B,-V,-X,--value.-- The -x/--explicit flag will cause any postings with a multi-commodity- amount (which can arise when a multi-commodity transaction has an im-- plicit amount) to be split into multiple single-commodity postings,- keeping the output parseable.-- print amount style- Amounts are shown right-aligned within each transaction (but not- aligned across all transactions; you can do that with ledger-mode in- Emacs).-- Amounts will be (mostly) normalised to their commodity display style:- their symbol placement, decimal mark, and digit group marks will be- made consistent. By default, decimal digits are shown as they are- written in the journal.-- With the --round (Added in 1.32) option, print will try increasingly- hard to display decimal digits according to the commodity display- styles:-- o --round=none show amounts with original precisions (default)-- o --round=soft add/remove decimal zeros in amounts (except costs)-- o --round=hard round amounts (except costs), possibly hiding signifi-- cant digits-- o --round=all round all amounts and costs-- soft is good for non-lossy cleanup, formatting amounts more consis-- tently where it's safe to do so.-- hard and all can cause print to show invalid unbalanced journal en-- tries; they may be useful eg for stronger cleanup, with manual fixups- when needed.-- print parseability- 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 (though the same can be achieved with expr: queries- now):-- # 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 Value reporting affects posting amounts but not balance assertion or- balance assignment amounts, potentially causing those to fail.-- o Auto postings can generate postings with too many missing amounts.-- o Account aliases can generate bad account names.-- print, other features- With -B/--cost, amounts with costs are shown converted to cost.-- With --new, print shows only transactions it has not seen on a previous- run. This uses the same deduplication system as the import command.- (See import's docs for details.)-- With -m DESC/--match=DESC, print shows one recent transaction whose de-- scription is most similar to DESC. DESC should contain at least two- characters. If there is no similar-enough match, no transaction will- be shown and the program exit code will be non-zero.-- print output format- This command also supports the output destination and output format op-- tions The output formats supported are txt, beancount (Added in 1.32),- csv, tsv (Added in 1.32), json and sql.-- The beancount format tries to produce Beancount-compatible output, as- follows:-- o Transaction and postings with unmarked status are converted to- cleared (*) status.-- o Transactions' payee and note are backslash-escaped and dou-- ble-quote-escaped and wrapped in double quotes.-- o Transaction tags are copied to Beancount #tag format.-- o Commodity symbols are converted to upper case, and a small number of- currency symbols like $ are converted to the corresponding currency- names.-- o Account name parts are capitalised and unsupported characters are re-- placed with -. If an account name part does not begin with a letter,- or if the first part is not Assets, Liabilities, Equity, Income, or- Expenses, an error is raised. (Use --alias options to bring your ac-- counts into compliance.)-- o An open directive is generated for each account used, on the earliest- transaction date.-- Some limitations:-- o Balance assertions are removed.-- o Balance assignments become missing amounts.-- o Virtual and balanced virtual postings become regular postings.-- o Directives are not converted.-- 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.)-- 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.-- For performance reasons, column widths are chosen based on the first- 1000 lines; this means unusually wide values in later lines can cause- visual discontinuities as column widths are adjusted. If you want to- ensure perfect alignment, at the cost of more time and memory, use the- --align-all flag.-- The --historical/-H flag adds the balance from any undisplayed prior- postings to the running total. This is useful when you want to see- only recent activity, with a historically accurate running balance:-- $ hledger register checking -b 2008/6 --historical- 2008/06/01 gift assets:bank:checking $1 $2- 2008/06/02 save assets:bank:checking $-1 $1- 2008/12/31 pay off assets:bank:checking $-1 0-- The --depth option limits the amount of sub-account detail displayed.-- The --average/-A flag shows the running average posting amount instead- of the running total (so, the final number displayed is the average for- the whole report period). This flag implies --empty (see below). It- is affected by --historical. It works best when showing just one ac-- count and one commodity.-- The --related/-r flag shows the other postings in the transactions of- the postings which would normally be shown.-- The --invert flag negates all amounts. For example, it can be used on- an income account where amounts are normally displayed as negative num-- bers. It's also useful to show postings on the checking account to-- gether with the related account:-- $ hledger register --related --invert assets:checking-- With a reporting interval, register shows summary postings, one per in-- terval, aggregating the postings to each account:-- $ hledger register --monthly income- 2008/01 income:salary $-1 $-1- 2008/06 income:gifts $-1 $-2-- Periods with no activity, and summary postings with a zero amount, are- not shown by default; use the --empty/-E flag to see them:-- $ hledger register --monthly income -E- 2008/01 income:salary $-1 $-1- 2008/02 0 $-1- 2008/03 0 $-1- 2008/04 0 $-1- 2008/05 0 $-1- 2008/06 income:gifts $-1 $-2- 2008/07 0 $-2- 2008/08 0 $-2- 2008/09 0 $-2- 2008/10 0 $-2- 2008/11 0 $-2- 2008/12 0 $-2-- Often, you'll want to see just one line per interval. The --depth op-- tion helps with this, causing subaccounts to be aggregated:-- $ hledger register --monthly assets --depth 1h- 2008/01 assets $1 $1- 2008/06 assets $-1 0- 2008/12 assets $-1 $-1-- Note when using report intervals, if you specify start/end dates these- will be adjusted outward if necessary to contain a whole number of in-- tervals. This ensures that the first and last intervals are full- length and comparable to the others in the report.-- With -m DESC/--match=DESC, register does a fuzzy search for one recent- posting whose description is most similar to DESC. DESC should contain- at least two characters. If there is no similar-enough match, no post-- ing will be shown and the program exit code will be non-zero.-- Custom register output- register uses the full terminal width by default, except on windows.- You can override this by setting the COLUMNS environment variable (not- a bash shell variable) or by using the --width/-w option.-- The description and account columns normally share the space equally- (about half of (width - 40) each). You can adjust this by adding a de-- scription width as part of --width's argument, comma-separated: --width- W,D . Here's a diagram (won't display correctly in --help):-- <--------------------------------- width (W) ---------------------------------->- date (10) description (D) account (W-41-D) amount (12) balance (12)- DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA-- and some examples:-- $ hledger reg # use terminal width (or 80 on windows)- $ hledger reg -w 100 # use width 100- $ COLUMNS=100 hledger reg # set with one-time environment variable- $ export COLUMNS=100; hledger reg # set till session end (or window resize)- $ hledger reg -w 100,40 # set overall width 100, description width 40- $ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40-- This command also supports the output destination and output format op-- tions The output formats supported are txt, csv, tsv (Added in 1.32),- and json.-- rewrite- Print all transactions, rewriting the postings of matched transactions.- For now the only rewrite available is adding new postings, like print- --auto.-- This is a start at a generic rewriter of transaction entries. It reads- the default journal and prints the transactions, like print, but adds- one or more specified postings to any transactions matching QUERY. The- posting amounts can be fixed, or a multiplier of the existing transac-- tion's first posting amount.-- Examples:-- $ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'- $ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'- $ hledger-rewrite.hs -f rewrites.hledger-- rewrites.hledger may consist of entries like:-- = ^income amt:<0 date:2017- (liabilities:tax) *0.33 ; tax on income- (reserve:grocery) *0.25 ; reserve 25% for grocery- (reserve:) *0.25 ; reserve 25% for grocery-- Note the single quotes to protect the dollar sign from bash, and the- two spaces between account and amount.-- More:-- $ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...- $ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'- $ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'- $ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'-- Argument for --add-posting option is a usual posting of transaction- with an exception for amount specification. More precisely, you can- use '*' (star symbol) before the amount to indicate that that this is a- factor for an amount of original matched posting. If the amount in-- cludes a commodity name, the new posting amount will be in the new com-- modity; otherwise, it will be in the matched posting amount's commod-- ity.-- Re-write rules in a file- During the run this tool will execute so called "Automated Transac-- tions" found in any journal it process. I.e instead of specifying this- operations in command line you can put them in a journal file.-- $ rewrite-rules.journal-- Make contents look like this:-- = ^income- (liabilities:tax) *.33-- = expenses:gifts- budget:gifts *-1- assets:budget *1-- Note that '=' (equality symbol) that is used instead of date in trans-- actions you usually write. It indicates the query by which you want to- match the posting to add new ones.-- $ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal-- This is something similar to the commands pipeline:-- $ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \- | hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \- --add-posting 'assets:budget *1' \- > rewritten-tidy-output.journal-- It is important to understand that relative order of such entries in- journal is important. You can re-use result of previously added post-- ings.-- Diff output format- To use this tool for batch modification of your journal files you may- find useful output in form of unified diff.-- $ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'-- Output might look like:-- --- /tmp/examples/sample.journal- +++ /tmp/examples/sample.journal- @@ -18,3 +18,4 @@- 2008/01/01 income- - assets:bank:checking $1- + assets:bank:checking $1- income:salary- + (liabilities:tax) 0- @@ -22,3 +23,4 @@- 2008/06/01 gift- - assets:bank:checking $1- + assets:bank:checking $1- income:gifts- + (liabilities:tax) 0-- If you'll pass this through patch tool you'll get transactions contain-- ing the posting that matches your query be updated. Note that multiple- files might be update according to list of input files specified via- --file options and include directives inside of these files.-- Be careful. Whole transaction being re-formatted in a style of output- from hledger print.-- See also:-- https://github.com/simonmichael/hledger/issues/99-- rewrite vs. print --auto- This command predates print --auto, and currently does much the same- thing, but with these differences:-- o with multiple files, rewrite lets rules in any file affect all other- files. print --auto uses standard directive scoping; rules affect- only child files.-- o rewrite's query limits which transactions can be rewritten; all are- printed. print --auto's query limits which transactions are printed.-- o rewrite applies rules specified on command line or in the journal.- print --auto applies rules specified in the journal.-- roi- 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 ac-- count 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, also known as money-weighted rate of return) and time-weighted- rate of return (TWR) for your investments for the time period re-- quested. IRR is always annualized due to the way it is computed, but- TWR is reported both as a rate over the chosen reporting period and as- an annual rate.-- Price directives will be taken into account if you supply appropriate- --cost or --value flags (see VALUATION).-- Note, in some cases this report can fail, for these reasons:-- o Error (NotBracketed): No solution for Internal Rate of Return (IRR).- Possible causes: IRR is huge (>1000000%), balance of investment be-- comes negative at some point in time.-- o Error (SearchFailed): Failed to find solution for Internal Rate of- Return (IRR). Either search does not converge to a solution, or con-- verges too slowly.-- Examples:-- o Using roi to compute total return of investment in stocks:- https://github.com/simonmichael/hledger/blob/master/examples/invest-- ing/roi-unrealised.ledger-- o Cookbook > Return on Investment: https://hledger.org/roi.html-- 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 as-- sets, 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 re-- turn.-- 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, and the- time between them. Investment at a particular fixed interest rate is- going to give you more interest than the same amount invested at the- same interest rate, but made later in time. If you are withdrawing- from your investment, your future gains would be smaller (in absolute- numbers), and will be a smaller percentage of your initial investment,- so your IRR will be smaller. And if you are adding to your investment,- you will receive bigger absolute gains, which will be a bigger percent-- age of your initial investment, so your IRR will be larger.-- 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 ac-- count for the effect of your in-flows and out-flows, but unlike IRR it- will try to compute the true rate of return of the underlying asset,- compensating for the effect that deposits and withdrawas have on the- apparent rate of growth of your investment.-- TWR represents your investment as an imaginary "unit fund" where- in-flows/ out-flows lead to buying or selling "units" of your invest-- ment and changes in its value change the value of "investment unit".- Change in "unit price" over the reporting period gives you rate of re-- turn of your investment, and make TWR less sensitive than IRR to the- effects of cash in-flows and out-flows.-- References:-- o Explanation of rate of return-- o Explanation of IRR-- o Explanation of TWR-- o IRR vs TWR-- o Examples of computing IRR and TWR and discussion of the limitations- of both metrics-- stats- Show journal and performance statistics.-- The stats command shows summary information for the whole journal, or a- matched part of it. With a reporting interval, it shows a report for- each report period.-- The default output is fairly impersonal, though it reveals the main- file name. With -v/--verbose, more details are shown, like file paths,- included files, and commodity names.-- It also shows some run time statistics:-- o elapsed time-- o throughput: the number of transactions processed per second-- o live: the peak memory in use by the program to do its work-- o alloc: the peak memory allocation from the OS as seen by GHC. Mea-- suring this externally, eg with GNU time, is more accurate; usually- that will be a larger number; sometimes (with swapping?) smaller.-- The stats command's run time is similar to that of a balance report.-- Example:-- $ hledger stats -f examples/1ktxns-1kaccts.journal- Main file : .../1ktxns-1kaccts.journal- Included files : 0- Txns span : 2000-01-01 to 2002-09-27 (1000 days)- Last txn : 2002-09-26 (7827 days ago)- Txns : 1000 (1.0 per day)- Txns last 30 days : 0 (0.0 per day)- Txns last 7 days : 0 (0.0 per day)- Payees/descriptions : 1000- Accounts : 1000 (depth 10)- Commodities : 26- Market prices : 1000- Runtime stats : 0.12 s elapsed, 8266 txns/s, 4 MB live, 16 MB alloc-- This command supports the -o/--output-file option (but not -O/--out-- put-format).-- tags- List the tags used in the journal, or their values.-- This command lists the tag names used in the journal, whether on trans-- actions, postings, or account declarations.-- With a TAGREGEX argument, only tag names matching this regular expres-- sion (case insensitive, infix matched) are shown.-- With QUERY arguments, only transactions and accounts matching this- query are considered. If the query involves transaction fields (date:,- desc:, amt:, ...), the search is restricted to the matched transactions- and their accounts.-- With the --values flag, the tags' unique non-empty values are listed- instead. With -E/--empty, blank/empty values are also shown.-- With --parsed, tags or values are shown in the order they were parsed,- with duplicates included. (Except, tags from account declarations are- always shown first.)-- Tip: remember, accounts also acquire tags from their parents, postings- also acquire tags from their account and transaction, transactions also- acquire tags from their postings.-- 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).--PART 5: COMMON TASKS- Here are some quick examples of how to do some basic tasks with- hledger.-- Getting help- Here's how to list commands and view options and command docs:-- $ hledger # show available commands- $ hledger --help # show common options- $ hledger CMD --help # show CMD's options, common options and CMD's documentation-- You can also view your hledger version's manual in several formats by- using the help command. Eg:-- $ hledger help # show the hledger manual with info, man or $PAGER (best available)- $ hledger help journal # show the journal topic in the hledger manual- $ hledger help --help # find out more about the help command-- To view manuals and introductory docs on the web, visit- https://hledger.org. Chat and mail list support and discussion- archives can be found at https://hledger.org/support.-- Constructing command lines- hledger has a flexible command line interface. We strive to keep it- simple and ergonomic, but if you run into one of the sharp edges de-- scribed in OPTIONS, here are some tips that might help:-- o command-specific options must go after the command (it's fine to put- common options there too: 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 line 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- (see below). 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 2023.journal- $ echo "export LEDGER_FILE=$HOME/finance/2023.journal" >> ~/.profile- $ source ~/.profile- $ hledger stats- Main file : /Users/simon/finance/2023.journal- Included files :- Transactions span : to (0 days)- Last transaction : none- Transactions : 0 (0.0 per day)- Transactions last 30 days: 0 (0.0 per day)- Transactions last 7 days : 0 (0.0 per day)- Payees/descriptions : 0- Accounts : 0 (depth 0)- Commodities : 0 ()- Market prices : 0 ()-- Setting LEDGER_FILE- How to set LEDGER_FILE permanently depends on your setup:-- On unix and mac, running these commands in the terminal will work for- many people; adapt as needed:-- $ echo 'export LEDGER_FILE=~/finance/2023.journal' >> ~/.profile- $ source ~/.profile-- When correctly configured, in a new terminal window env | grep- LEDGER_FILE will show your file, and so will hledger files.-- On mac, this additional step might be helpful for GUI applications- (like Emacs started from the dock): add an entry to ~/.MacOSX/environ-- ment.plist like-- {- "LEDGER_FILE" : "~/finance/2023.journal"- }-- and then run killall Dock in a terminal window (or restart the ma-- chine).-- On Windows, see https://www.java.com/en/download/help/path.html, or try- running these commands in a powershell window (let us know if it per-- sists across a reboot, and if you need to be an Administrator):-- > CD- > MKDIR finance- > SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal"-- Setting opening balances- Pick a starting date for which you can look up the balances of some- real-world assets (bank accounts, wallet..) and liabilities (credit- cards..).-- To avoid a lot of data entry, you may want to start with just one or- two accounts, like your checking account or cash wallet; and pick a re-- cent starting date, like today or the start of the week. You can al-- ways come back later and add more accounts and older transactions, eg- going back to january 1st.-- Add an opening balances transaction to the journal, declaring the bal-- ances on this date. Here are two ways to do it:-- o The first way: open the journal in any text editor and save an entry- like this:-- 2023-01-01 * opening balances- assets:bank:checking $1000 = $1000- assets:bank:savings $2000 = $2000- assets:cash $100 = $100- liabilities:creditcard $-50 = $-50- equity:opening/closing balances-- 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/2023.journal- Any command line arguments will be used as defaults.- Use tab key to complete, readline keys to edit, enter to accept defaults.- An optional (CODE) may follow transaction dates.- An optional ; COMMENT may follow descriptions or amounts.- If you make a mistake, enter < at any prompt to go one step backward.- To end a transaction, enter . when prompted.- To quit, enter . at a date prompt or press control-d or control-c.- Date [2023-02-07]: 2023-01-01- Description: * opening balances- Account 1: assets:bank:checking- Amount 1: $1000- Account 2: assets:bank:savings- Amount 2 [$-1000]: $2000- Account 3: assets:cash- Amount 3 [$-3000]: $100- Account 4: liabilities:creditcard- Amount 4 [$-3100]: $-50- Account 5: equity:opening/closing balances- Amount 5 [$-3050]:- Account 6 (or . or enter to finish this transaction): .- 2023-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050-- Save this transaction to the journal ? [y]:- Saved.- Starting the next transaction (. or ctrl-D/ctrl-C to quit)- Date [2023-01-01]: .-- If you're using version control, this could be a good time to commit- the journal. Eg:-- $ git commit -m 'initial balances' 2023.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:-- 2023/1/10 * gift received- assets:cash $20- income:gifts-- 2023.1.12 * farmers market- expenses:food $13- assets:cash-- 2023-01-15 paycheck- income:salary- assets:bank:checking $1000-- Reconciling- Periodically you should reconcile - compare your hledger-reported bal-- ances against external sources of truth, like bank statements or your- bank's website - to be sure that your ledger accurately represents the- real-world balances (and, that the real-world institutions have not- made a mistake!). This gets easy and fast with (1) practice and (2)- frequency. If you do it daily, it can take 2-10 minutes. If you let- it pile up, expect it to take longer as you hunt down errors and dis-- crepancies.-- A typical workflow:-- 1. Reconcile cash. Count what's in your wallet. Compare with what- hledger reports (hledger bal cash). If they are different, try to- remember the missing transaction, or look for the error in the al-- ready-recorded transactions. A register report can be helpful- (hledger reg cash). If you can't find the error, add an adjustment- transaction. Eg if you have $105 after the above, and can't explain- the missing $2, it could be:-- 2023-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- 2. Reconcile checking. Log in to your bank's website. Compare today's- (cleared) balance with hledger's cleared balance (hledger bal check-- ing -C). If they are different, track down the error or record the- missing transaction(s) or add an adjustment transaction, similar to- the above. Unlike the cash case, you can usually compare the trans-- action history and running balance from your bank with the one re-- ported by hledger reg checking -C. This will be easier if you gen-- erally record transaction dates quite similar to your bank's clear-- ing dates.-- 3. Repeat for other asset/liability accounts.-- Tip: instead of the register command, use hledger-ui to see a live-up-- dating register while you edit the journal: hledger-ui --watch --regis-- ter checking -C-- After reconciling, it could be a good time to mark the reconciled- transactions' status as "cleared and confirmed", if you want to track- that, by adding the * marker. Eg in the paycheck transaction above,- insert * between 2023-01-15 and paycheck-- If you're using version control, this can be another good time to com-- mit:-- $ git commit -m 'txns' 2023.journal-- Reporting- Here are some basic reports.-- Show all transactions:-- $ hledger print- 2023-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050-- 2023-01-10 * gift received- assets:cash $20- income:gifts-- 2023-01-12 * farmers market- expenses:food $13- assets:cash-- 2023-01-15 * paycheck- income:salary- assets:bank:checking $1000-- 2023-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- 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 -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 -2- Balance Sheet 2023-01-16-- || 2023-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 2023-01-01-2023-01-16-- || 2023-01-01-2023-01-16- ===============++=======================- Revenues ||- ---------------++------------------------ income:gifts || $20- income:salary || $1000- ---------------++------------------------ || $1020- ===============++=======================- Expenses ||- ---------------++------------------------ expenses:food || $13- expenses:misc || $2- ---------------++------------------------ || $15- ===============++=======================- Net: || $1005-- The final total is your net income during this period.-- Show transactions affecting your wallet, with running total:-- $ hledger register cash- 2023-01-01 opening balances assets:cash $100 $100- 2023-01-10 gift received assets:cash $20 $120- 2023-01-12 farmers market assets:cash $-13 $107- 2023-01-16 adjust cash assets:cash $-2 $105-- Show weekly posting counts as a bar chart:-- $ hledger activity -W- 2019-12-30 *****- 2023-01-06 ****- 2023-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.--BUGS- We welcome bug reports in the hledger issue tracker (shortcut:- http://bugs.hledger.org), or on the #hledger chat or hledger mail list- (https://hledger.org/support).-- Some known issues and limitations:-- The need to precede add-on command options with -- when invoked from- hledger is awkward. (See Command options, Constructing command lines.)-- A UTF-8-aware system locale must be configured to work with non-ascii- data. (See Unicode characters, Troubleshooting.)-- On Microsoft Windows, depending whether you are running in a CMD window- or a Cygwin/MSYS/Mintty window and how you installed hledger, non-ascii- characters and colours may not be supported, and the tab key may not be- supported by hledger add. (Running in a WSL window should resolve- these.)-- When processing large data files, hledger uses more memory than Ledger.-- Troubleshooting- Here are some common issues you might encounter when you run hledger,- and how to resolve them (and remember also you can usually get quick- Support):-- PATH issues: I get an error like "No command 'hledger' found"- Depending how you installed hledger, the executables may not be in your- shell's PATH. Eg on unix systems, stack installs hledger in ~/.lo-- cal/bin and cabal installs it in ~/.cabal/bin. You may need to add one- of these directories to your shell's PATH, and/or open a new terminal- window.-- LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not using- it- o LEDGER_FILE should be a real environment variable, not just a shell- variable. Eg on unix, the command env | grep LEDGER_FILE should show- it. You may need to use export (see https://stackover-- flow.com/a/7411509).-- o You may need to force your shell to see the new configuration. A- simple way is to close your terminal window and open a new one.-- LANG issues: I get errors like "Illegal byte sequence" or "Invalid or- incomplete multibyte or wide character" or "commitAndReleaseBuffer: in-- valid argument (invalid character)"- Programs compiled with GHC (hledger, haskell build tools, etc.) need- the system locale to be UTF-8-aware, or they will fail when they en-- counter non-ascii characters. To fix it, set the LANG environment- variable to a locale which supports UTF-8 and which is installed on- your system.-- On unix, locale -a lists the installed locales. Look for one which- mentions utf8, UTF-8 or similar. Some examples: C.UTF-8, en_US.utf-8,- fr_FR.utf8. If necessary, use your system package manager to install- one. Then select it by setting the LANG environment variable. Note,- exact spelling and capitalisation of the locale name may be important:- Here's one common way to configure this permanently for your shell:-- $ echo "export LANG=en_US.utf8" >>~/.profile- # close and re-open terminal window-- If you are using Nix (not NixOS) for GHC and Hledger, you might need to- set the LOCALE_ARCHIVE variable:-- $ echo "export LOCALE_ARCHIVE=${glibcLocales}/lib/locale/locale-archive" >>~/.profile- # close and re-open terminal window-- COMPATIBILITY ISSUES: hledger gives an error with my Ledger file- Not all of Ledger's journal file syntax or feature set is supported.- See hledger and Ledger for full details.----AUTHORS- Simon Michael <simon@joyful.com> and contributors.- See http://hledger.org/CREDITS.html---COPYRIGHT- Copyright 2007-2023 Simon Michael and contributors.---LICENSE- Released under GNU GPL v3 or later.---SEE ALSO- hledger(1), hledger-ui(1), hledger-web(1), ledger(1)--hledger-1.33 April 2024 HLEDGER(1)+ This manual is for hledger's command line interface, version 1.33.1.+ It also describes the common options, file formats and concepts used by+ all hledger programs. It might accidentally teach you some bookkeep-+ ing/accounting as well! You don't need to know everything in here to+ use hledger productively, but when you have a question about function-+ ality, this doc should answer it. It is detailed, so do skip ahead or+ skim when needed. You can read it on hledger.org, or as an info manual+ or man page on your system. You can also get it from hledger itself+ with+ hledger --man, hledger --info or hledger help [TOPIC].++ The main function of the hledger CLI is to read plain text files de-+ scribing financial transactions, crunch the numbers, and print a useful+ report on the terminal (or save it as HTML, CSV, JSON or SQL). Many+ reports are available, as subcommands. hledger will also detect other+ hledger-* executables as extra subcommands.++ hledger usually reads from (and appends to) a journal file specified by+ the LEDGER_FILE environment variable (defaulting to+ $HOME/.hledger.journal); or you can specify files with -f options. It+ can also read timeclock files, timedot files, or any CSV/SSV/TSV file+ with a date field.++ Here is a small journal file describing one transaction:++ 2015-10-16 bought food+ expenses:food $10+ assets:cash++ Transactions are dated movements of money (etc.) between two or more+ accounts: bank accounts, your wallet, revenue/expense categories, peo-+ ple, etc. You can choose any account names you wish, using : to indi-+ cate subaccounts. There must be at least two spaces between account+ name and amount. Positive amounts are inflow to that account (debit),+ negatives are outflow from it (credit). (Some reports show revenue,+ liability and equity account balances as negative numbers as a result;+ this is normal.)++ hledger's add command can help you add transactions, or you can install+ other data entry UIs like hledger-web or hledger-iadd. For more exten-+ sive/efficient changes, use a text editor: Emacs + ledger-mode, VIM ++ vim-ledger, or VS Code + hledger-vscode are some good choices (see+ https://hledger.org/editors.html).++ To get started, run hledger add and follow the prompts, or save some+ entries like the above in $HOME/.hledger.journal, then try commands+ like:++ $ hledger print -x+ $ hledger aregister assets+ $ hledger balance+ $ hledger balancesheet+ $ hledger incomestatement++ Run hledger to list the commands. See also the "Starting a journal+ file" and "Setting opening balances" sections in PART 5: COMMON TASKS.++PART 1: USER INTERFACE+Input+ hledger reads one or more data files, each time you run it. You can+ specify a file with -f, like so++ $ hledger -f FILE print++ Files are most often in hledger's journal format, with the .journal+ file extension (.hledger or .j also work); these files describe trans-+ actions, like an accounting general journal.++ When no file is specified, hledger looks for .hledger.journal in your+ home directory.++ But most people prefer to keep financial files in a dedicated folder,+ perhaps with version control. Also, starting a new journal file each+ year is common (it's not required, but helps keep things fast and or-+ ganised). So we usually configure a different journal file, by setting+ the LEDGER_FILE environment variable, to something like ~/fi-+ nance/2023.journal. For more about how to do that on your system, see+ Common tasks > Setting LEDGER_FILE.++ Text encoding+ Data files containing non-ascii characters must use UTF-8 encoding. An+ optional byte order mark (BOM) is allowed, at the beginning of the file+ (only).++ Also, your system should be configured with a locale that can decode+ UTF-8 text. On some unix systems, you may need set the LANG environ-+ ment variable, eg. You can read more about this in Unicode characters,+ below.++ On unix systems you can check a file's encoding with the file command.+ If you need to import from a UTF-16-encoded CSV file, say, you can con-+ vert it to UTF-8 with the iconv command.++ 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: Automatically used for+ files with extensions:+ -----------------------------------------------------------------------------+ journal hledger journal files and some .journal .j .hledger+ Ledger journals, for transactions .ledger+ timeclock timeclock files, for precise time .timeclock+ logging+ timedot timedot files, for approximate .timedot+ time logging+ csv Comma or other character sepa- .csv+ rated values, for data import+ ssv Semicolon separated values .ssv+ tsv Tab separated values .tsv+ rules CSV/SSV/TSV/other separated val- .rules+ ues, alternate way++ These formats are described in more detail below.++ hledger detects the format automatically based on the file extensions+ shown above. If it can't recognise the file extension, it assumes+ journal format. So for non-journal files, it's important to use a+ 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 containing tab+ separated values:++ $ hledger -f tsv:/some/file.dat stats++ Standard input+ The file name - means standard input:++ $ cat FILE | hledger -f- print++ If reading non-journal data in this way, you'll need to add a file for-+ mat prefix, like:++ $ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:-++ Multiple files+ You can specify multiple -f options, to read multiple files as one big+ journal. When doing this, note that certain features (described below)+ will be affected:++ o Balance assertions will not see the effect of transactions in previ-+ ous files. (Usually this doesn't matter as each file will set the+ corresponding opening balances.)++ o Some directives will not affect previous or subsequent files.++ If needed, you can work around these by using a single parent file+ which includes the others, or concatenating the files into one, 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 use the check command to run individual checks -- the ones+ listed above and some more.++Commands+ hledger provides various subcommands for getting things done. Most of+ these commands do not change the journal file; they just read it and+ output a report. A few commands assist with adding data and file man-+ agement.++ To show the commands list, run hledger with no arguments. The commands+ are described in detail in PART 4: COMMANDS, below.++ To use a particular command, run hledger CMD [CMDOPTS] [CMDARGS],++ o CMD is the full command name, or its standard abbreviation shown in+ the commands list, or any unambiguous prefix of the name.++ o CMDOPTS are command-specific options, if any. Command-specific op-+ tions must be written after the command name. Eg: hledger print -x.++ o CMDARGS are additional arguments to the command, if any. Most+ hledger commands accept arguments representing a query, to limit the+ data in some way. Eg: hledger reg assets:checking.++ To list a command's options, arguments, and documentation in the termi-+ nal, run hledger CMD -h. Eg: hledger bal -h.++ Add-on commands+ In addition to the built-in commands, you can install add-on commands:+ programs or scripts named "hledger-SOMETHING", which will also appear+ in hledger's commands list. If you used the hledger-install script,+ you will have several add-ons installed already. Some more can be+ found in hledger's bin/ directory, documented at+ https://hledger.org/scripts.html.++ More precisely, add-on commands are programs or scripts in your shell's+ PATH, whose name starts with "hledger-" and ends with no extension or a+ recognised extension (".bat", ".com", ".exe", ".hs", ".js", ".lhs",+ ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"), and (on unix+ and mac) which has executable permission for the current user.++ You can run add-on commands using hledger, much like built-in commands:+ hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]. But note the double+ hyphen argument, required before add-on-specific options. Eg: hledger+ ui -- --watch or hledger web -- --serve. If this causes difficulty,+ you can always run the add-on directly, without using hledger:+ hledger-ui --watch or hledger-web --serve.++Options+ Run hledger -h to see general command line help, and general options+ which are common to most hledger commands. These options can be writ-+ ten anywhere on the command line. They can be grouped into help, in-+ put, and reporting options:++ 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++ --pivot FIELDNAME+ use some other field or tag for the account name++ -I --ignore-assertions+ disable balance assertion checks (note: does not disable balance+ assignments)++ -s --strict+ do extra error checking (check that all posted accounts are de-+ clared)++ General reporting options+ -b --begin=DATE+ include postings/txns on or after this date (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 ef-+ fects)++ --today=DATE+ override today's date (affects relative smart dates, for+ tests/examples)++ -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-equity+ infer conversion equity postings from costs++ --infer-costs+ infer costs from conversion equity postings++ --infer-market-prices+ use costs as additional market prices, as if they were P direc-+ tives++ --forecast+ generate transactions from periodic rules, between the latest+ recorded txn and 6 months from today, or during the specified+ PERIOD (= is required). Auto posting rules will be applied to+ these transactions as well. Also, in hledger-ui make fu-+ ture-dated transactions visible.++ --auto generate extra postings by applying auto posting rules to all+ txns (not just forecast txns)++ --verbose-tags+ add visible tags indicating transactions or postings which have+ been generated/modified++ --commodity-style+ Override the commodity style in the output for the specified+ commodity. For example 'EUR1.000,00'.++ --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.++ --pretty[=WHEN]+ Show prettier output, e.g. using unicode box-drawing charac-+ ters. Accepts 'yes' (the default) or 'no' ('y', 'n', 'always',+ 'never' also work). If you provide an argument you must use+ '=', e.g. '--pretty=yes'.++ 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 line tips+ Here are some details useful to know about for hledger command lines+ (and elsewhere). Feel free to skip this section until you need it.++ Option repetition+ If options are repeated in a command line, hledger will generally use+ the last (right-most) occurence.++ Special characters+ Single escaping (shell metacharacters)+ In shell command lines, characters significant to your shell - such as+ spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want+ hledger to see them. This is done by enclosing them in single or dou-+ ble quotes, or by writing a backslash before them. Eg to match an ac-+ count 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 be-+ low), one level of shell-escaping is lost from any options or arguments+ intended for by the add-on command, so those need an extra level of+ shell-escaping. Eg to match a literal $ sign while using the bash+ shell and running an add-on command (ui):++ $ hledger ui cur:'\\$'++ or:++ $ hledger ui cur:\\\\$++ If you wondered why four backslashes, perhaps this helps:++ unescaped: $+ escaped: \$+ double-escaped: \\$+ triple-escaped: \\\\$++ Or, you can avoid the extra escaping by running the add-on executable+ directly:++ $ hledger-ui cur:\\$++ Less escaping+ Options and arguments are sometimes used in places other than the shell+ command line, where shell-escaping is not needed, so there you should+ use one less level of escaping. Those places include:++ o an @argumentfile++ o hledger-ui's filter field++ o hledger-web's search form++ o GHCI's prompt (used by developers).++ Unicode characters+ hledger is expected to handle non-ascii characters correctly:++ o they should be parsed correctly in input files and on the command+ line, by all hledger tools (add, iadd, hledger-web's search/add/edit+ forms, etc.)++ o they should be displayed correctly by all hledger tools, and+ on-screen alignment should be preserved.++ This requires a well-configured environment. Here are some tips:++ o A system locale must be configured, and it must be one that can de-+ code the characters being used. In bash, you can set a locale like+ this: export LANG=en_US.UTF-8. There are some more details in Trou-+ bleshooting. This step is essential - without it, hledger will quit+ on encountering a non-ascii character (as with all GHC-compiled pro-+ grams).++ o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)+ must support unicode++ o the terminal must be using a font which includes the required unicode+ glyphs++ o the terminal should be configured to display wide characters as dou-+ ble width (for report alignment)++ o on Windows, for best results you should run hledger in the same kind+ of environment in which it was built. Eg hledger built in the stan-+ dard CMD.EXE environment (like the binaries on our download page)+ might show display problems when run in a cygwin or msys terminal,+ and vice versa. (See eg #961).++ Regular expressions+ A regular expression (regexp) is a small piece of text where certain+ characters (like ., ^, $, +, *, (), |, [], \) have special meanings,+ forming a tiny language for matching text precisely - very useful in+ hledger and elsewhere. To learn all about them, visit regular-expres-+ sions.info.++ hledger supports regexps whenever you are entering a pattern to match+ something, eg in query arguments, account aliases, CSV if rules,+ hledger-web's search form, hledger-ui's / search, etc. You may need to+ wrap them in quotes, especially at the command line (see Special char-+ acters above). Here are some examples:++ Account name queries (quoted for command line use):++ Regular expression: Matches:+ ------------------- ------------------------------------------------------------+ bank assets:bank, assets:bank:savings, expenses:art:banksy, ...+ :bank assets:bank:savings, expenses:art:banksy+ :bank: assets:bank:savings+ '^bank' none of those ( ^ matches beginning of text )+ 'bank$' assets:bank ( $ matches end of text )+ 'big \$ bank' big $ bank ( \ disables following character's special meaning )+ '\bbank\b' assets:bank, assets:bank:savings ( \b matches word boundaries )+ '(sav|check)ing' saving or checking ( (|) matches either alternative )+ 'saving|checking' saving or checking ( outer parentheses are not needed )+ 'savings?' saving or savings ( ? matches 0 or 1 of the preceding thing )+ 'my +bank' my bank, my bank, ... ( + matches 1 or more of the preceding thing )+ 'my *bank' mybank, my bank, my bank, ... ( * matches 0 or more of the preceding thing )+ 'b.nk' bank, bonk, b nk, ... ( . matches any character )++ Some other queries:++ desc:'amazon|amzn|audible' Amazon transactions+ cur:EUR amounts with commodity symbol containing EUR+ cur:'\$' amounts with commodity symbol containing $+ cur:'^\$$' only $ amounts, not eg AU$ or CA$+ cur:....? amounts with 4-or-more-character symbols+ tag:.=202[1-3] things with any tag whose value contains 2021, 2022 or 2023++ Account name aliases: accept . instead of : as account separator:++ alias /\./=: replaces all periods in account names with colons++ Show multiple top-level accounts combined as one:++ --alias='/^[^:]+/=combined' ( [^:] matches any character other than : )++ Show accounts with the second-level part removed:++ --alias '/^([^:]+):[^:]+/ = \1'+ match a top-level account and a second-level account+ and replace those with just the top-level account+ ( \1 in the replacement text means "whatever was matched+ by the first parenthesised part of the regexp"++ CSV rules: match CSV records containing dining-related MCC codes:++ if \?MCC581[124]++ Match CSV records with a specific amount around the end/start of month:++ if %amount \b3\.99+ & %date (29|30|31|01|02|03)$++ hledger's regular expressions+ 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. backreferences are supported when doing text replacement in account+ aliases or CSV rules, where backreferences can be used in the re-+ placement string to reference capturing groups in the search regexp.+ Otherwise, if you write \1, it will match the digit 1.++ 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.++ Argument files+ You can save a set of command line options and arguments in a file, and+ then reuse them by writing @FILENAME as a command line argument. Eg:+ hledger bal @foo.args.++ Inside the argument file, each line should contain just one option or+ argument. Don't use spaces except inside quotes (or you'll see a con-+ fusing error); write = (or nothing) between a flag and its argument.+ For the special characters mentioned above, use one less level of quot-+ ing than you would at the command prompt.++Output+ Output destination+ hledger commands send their output to the terminal by default. You can+ of course redirect this, eg into a file, using standard shell syntax:++ $ hledger print > foo.txt++ Some commands (print, register, stats, the balance commands) also pro-+ vide the -o/--output-file option, which does the same thing without+ needing the shell. Eg:++ $ hledger print -o foo.txt+ $ hledger print -o - # write to stdout (the default)++ Output format+ Some commands offer other kinds of output, not just text on the termi-+ nal. Here are those commands and the formats currently supported:++ - txt csv/tsv html json sql+ --------------------------------------------------------------------------------------+ aregister Y Y Y Y+ balance Y 1 Y 1 Y 1,2 Y+ balancesheet Y 1 Y 1 Y 1 Y+ balancesheete- Y 1 Y 1 Y 1 Y+ quity+ cashflow Y 1 Y 1 Y 1 Y+ incomestatement Y 1 Y 1 Y 1 Y+ print Y Y Y Y+ register Y Y Y++ o 1 Also affected by the balance commands' --layout option.++ o 2 balance does not support html output without a report interval or+ with --budget.++ The output format is selected by the -O/--output-format=FMT option:++ $ hledger print -O csv # print CSV on stdout++ or by the filename extension of an output file specified with the+ -o/--output-file=FILE.FMT option:++ $ hledger balancesheet -o foo.csv # write CSV to foo.csv++ The -O option can be combined with -o to override the file extension,+ if needed:++ $ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt++ Some notes about the various output formats:++ CSV output+ o In CSV output, digit group marks (such as thousands separators) are+ disabled automatically.++ HTML output+ o HTML output can be styled by an optional hledger.css file in the same+ directory.++ JSON output+ o This is not yet much used; real-world feedback is welcome.++ o Our JSON is rather large and verbose, since it is a faithful repre-+ sentation of hledger's internal data types. To understand the JSON,+ read the Haskell type definitions, which are mostly in+ https://github.com/simonmichael/hledger/blob/mas-+ ter/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)++ SQL output+ o This is not yet much used; real-world feedback is welcome.++ o SQL output is expected to work at least with SQLite, MySQL and Post-+ gres.++ o For SQLite, it will be more useful if you modify the generated id+ field to be a PRIMARY KEY. Eg:++ $ hledger print -O sql | sed 's/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g' | ...++ 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.++ Commodity styles+ When displaying amounts, hledger infers a standard display style for+ each commodity/currency, as described below in Commodity display style.++ If needed, this can be overridden by a -c/--commodity-style option (ex-+ cept for cost amounts and amounts displayed by the print command, which+ are always displayed with all decimal digits). For example, the fol-+ lowing will force dollar amounts to be displayed as shown:++ $ hledger print -c '$1.000,0'++ This option can repeated to set the display style for multiple commodi-+ ties/currencies. Its argument is as described in the commodity direc-+ tive.++ In some cases hledger will adjust number formatting to improve their+ parseability (such as adding trailing decimal marks when needed).++ Colour+ In terminal output, some commands can produce colour when the terminal+ supports it:++ o if the --color/--colour option is given a value of yes or always (or+ no or never), colour will (or will not) be used;++ o otherwise, if the NO_COLOR environment variable is set, colour will+ not be used;++ o otherwise, colour will be used if the output (terminal or file) sup-+ ports it.++ Box-drawing+ In terminal output, you can enable unicode box-drawing characters to+ render prettier tables:++ o if the --pretty option is given a value of yes or always (or no or+ never), unicode characters will (or will not) be used;++ o otherwise, unicode characters will not be used.++ Paging+ When showing long output in the terminal, hledger will try to use the+ pager specified by the PAGER environment variable, or less, or more.+ (A pager is a helper program that shows one page at a time rather than+ scrolling everything off screen). Currently it does this only for help+ output, not for reports; specifically,++ o when listing commands, with hledger++ o when showing help with hledger [CMD] --help,++ o when viewing manuals with hledger help or hledger --man.++ Note the pager is expected to handle ANSI codes, which hledger uses eg+ for bold emphasis. For the common pager less (and its more compatibil-+ ity mode), we add R to the LESS and MORE environment variables to make+ this work. If you use a different pager, you might need to configure+ it similarly, to avoid seeing junk on screen (let us know). Otherwise,+ you can set the NO_COLOR environment variable to 1 to disable all ANSI+ output (see Colour).++ Debug output+ We intend hledger to be relatively easy to troubleshoot, introspect and+ develop. You can add --debug[=N] to any hledger command line to see+ additional debug output. N ranges from 1 (least output, the default)+ to 9 (maximum output). Typically you would start with 1 and increase+ until you are seeing enough. Debug output goes to stderr, and is not+ affected by -o/--output-file (unless you redirect stderr to stdout, eg:+ 2>&1). It will be interleaved with normal output, which can help re-+ veal when parts of the code are evaluated. To capture debug output in+ a log file instead, you can usually redirect stderr, eg:++ hledger bal --debug=3 2>hledger.log++Environment+ These environment variables affect hledger:++ COLUMNS This is normally set by your terminal; some hledger commands+ (register) will format their output to this width. If not set, they+ will try to use the available terminal width.++ LEDGER_FILE The main journal file to use when not specified with+ -f/--file. Default: $HOME/.hledger.journal.++ NO_COLOR If this environment variable is set (with any value), hledger+ will not use ANSI color codes in terminal output, unless overridden by+ an explicit --color/--colour option.++PART 2: DATA FORMATS+Journal+ hledger's usual data source is a plain text file containing journal en-+ tries in hledger journal format. If you're looking for a quick refer-+ ence, jump ahead to the journal cheatsheet (or use the table of con-+ tents at https://hledger.org/hledger.html).++ This file represents an accounting General Journal. The .journal file+ extension is most often used, though not strictly required. The jour-+ nal file contains a number of transaction entries, each describing a+ transfer of money (or any commodity) between two or more named ac-+ counts, in a simple format readable by both hledger and humans.++ hledger's journal format is compatible with most of Ledger's journal+ format, but not all of it. The differences and interoperation tips are+ described at hledger and Ledger. With some care, and by avoiding in-+ compatible features, you can keep your hledger journal readable by+ Ledger and vice versa. This can useful eg for comparing the behaviour+ of one app against the other.++ You can use hledger without learning any more about this file; just use+ the add or web or import commands to create and update it.++ Many users, though, edit the journal file with a text editor, and track+ changes with a version control system such as git. Editor addons such+ as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and+ 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.++ A hledger journal file can contain three kinds of thing: comment lines,+ transactions, and/or directives (including periodic transaction rules+ and auto posting rules). Understanding the journal file format will+ also give you a good understanding of hledger's data model. Here's a+ quick cheatsheet/overview, followed by detailed descriptions of each+ part.++ Journal cheatsheet+ # Here is the main syntax of hledger's journal format+ # (omitting extra Ledger compatibility syntax).++ ###############################################################################++ # 1. These are comment lines, for notes or temporarily disabling things.+ ; They begin with # or ;++ comment+ Or, lines can be enclosed within "comment" / "end comment".+ This is a block of+ commented lines.+ end comment++ # Some journal entries can have semicolon comments at end of line ; like this+ # Some of them require 2 or more spaces before the semicolon.++ ###############################################################################++ # 2. Directives customise processing or output in some way.+ # You don't need any directives to get started.+ # But they can add more error checking, or change how things are displayed.+ # They begin with a word, letter, or symbol.+ # They are most often placed at the top, before transactions.++ account assets ; Declare valid account names and display order.+ account assets:savings ; A subaccount. This one represents a bank account.+ account assets:checking ; Another. Note, 2+ spaces after the account name.+ account assets:receivable ; Accounting type is inferred from english names,+ account passifs ; or declared with a "type" tag, type:L+ account expenses ; type:X+ ; A follow-on comment line, indented.+ account expenses:rent ; Expense and revenue categories are also accounts.+ ; Subaccounts inherit their parent's type.++ commodity $0.00 ; Declare valid commodities and their display styles.+ commodity 1.000,00 EUR++ decimal-mark . ; The decimal mark used in this file (if ambiguous).++ payee Whole Foods ; Declare a valid payee name.++ tag trip ; Declare a valid tag name.++ P 2024-03-01 AAPL $179 ; Declare a market price for AAPL in $ on this date.++ include other.journal ; Include another journal file here.++ # Declare a recurring "periodic transaction", for budget/forecast reports+ ~ monthly set budget goals ; <- Note, 2+ spaces before the description.+ (expenses:rent) $1000+ (expenses:food) $500++ # Declare an auto posting rule, to modify existing transactions in reports+ = revenues:consulting+ liabilities:tax:2024:us *0.25 ; Add a tax liability & expense+ expenses:tax:2024:us *-0.25 ; for 25% of the revenue.++ ###############################################################################++ # 3. Transactions are what it's all about.+ # They are dated events, usually movements of money between 2 or more accounts.+ # They begin with a numeric date.+ # Here is their basic shape:+ #+ # DATE DESCRIPTION ; The transaction's date and optional description.+ # ACCOUNT1 AMOUNT ; A posting of an amount to/from this account, indented.+ # ACCOUNT2 AMOUNT ; A second posting, balancing the first.+ # ... ; More if needed. Amounts must sum to zero.+ # ; Note, 2+ spaces between account names and amounts.++ 2024-01-01 opening balances ; At the start, declare pre-existing balances this way.+ assets:savings $10000 ; Account names can be anything. lower case is easy to type.+ assets:checking $1000 ; assets, liabilities, equity, revenues, expenses are common.+ liabilities:credit card $-500 ; liabilities, equity, revenues balances are usually negative.+ equity:start ; One amount can be left blank. $-10500 is inferred here.+ ; Some of these accounts we didn't declare above,+ ; so -s/--strict would complain.++ 2024-01-03 ! (12345) pay rent+ ; Additional transaction comment lines, indented.+ ; There can be a ! or * after the date meaning "pending" or "cleared".+ ; There can be a parenthesised (code) after the date/status.+ ; Amounts' sign shows direction of flow.+ assets:checking $-500 ; Minus means removed from this account (credit).+ expenses:rent $500 ; Plus means added to this account (debit).++ ; Keeping transactions in date order is optional (but helps error checking).++ 2024-01-02 Gringott's Bank | withdrawal ; Description can be PAYEE | NOTE+ assets:bank:gold -10 gold+ assets:pouch 10 gold++ 2024-01-02 shopping+ expenses:clothing 1 gold+ expenses:wands 5 gold+ assets:pouch -6 gold++ 2024-01-02 receive gift+ revenues:gifts -3 "Chocolate Frogs" ; Complex commodity symbols+ assets:pouch 3 "Chocolate Frogs" ; must be in double quotes.++ 2024-01-15 buy some shares, in two lots ; Cost can be noted.+ assets:investments:2024-01-15 2.0 AAAA @ $1.50 ; @ means per-unit cost+ assets:investments:2024-01-15-02 3.0 AAAA @@ $4 ; @@ means total cost+ ; ^ Per-lot subaccounts are sometimes useful.+ assets:checking $-7++ 2024-01-15 assert some account balances on this date+ ; Balances can be asserted in any transaction, with =, for extra error checking.+ ; Assertion txns like this one can be made with hledger close --assert --show-costs+ ;+ assets:savings $0 = $10000+ assets:checking $0 = $493+ assets:bank:gold 0 gold = -10 gold+ assets:pouch 0 gold = 4 gold+ assets:pouch 0 "Chocolate Frogs" = 3 "Chocolate Frogs"+ assets:investments:2024-01-15 0.0 AAAA = 2.0 AAAA @ $1.50+ assets:investments:2024-01-15-02 0.0 AAAA = 3.0 AAAA @@ $4+ liabilities:credit card $0 = $-500++ 2024-02-01 note some event, or a transaction not yet fully entered, on this date+ ; Postings are not required.++ ; Some other date formats are allowed (but, consistent YYYY-MM-DD is useful).+ 2024.01.01+ 2024/1/1++ Comments+ Lines in the journal will be ignored if they begin with a hash (#) or a+ semicolon (;). (See also Other syntax.) hledger will also ignore re-+ gions beginning with a comment line and ending with an end comment line+ (or file end). Here's a suggestion for choosing between them:++ o # for top-level notes++ o ; for commenting out things temporarily++ o comment for quickly commenting large regions (remember it's there, or+ you might get confused)++ Eg:++ # a comment line+ ; another commentline+ comment+ A multi-line comment block,+ continuing until "end comment" directive+ or the end of the current file.+ end comment++ Some hledger entries can have same-line comments attached to them, from+ ; (semicolon) to end of line. See Transaction comments, Posting com-+ ments, and Account comments below.++ Transactions+ Transactions are the main unit of information in a journal file. They+ represent events, typically a movement of some quantity of commodities+ between two or more named accounts.++ Each transaction is recorded as a journal entry, beginning with a sim-+ ple date in column 0. This can be followed by any of the following op-+ tional fields, separated by spaces:++ o a status character (empty, !, or *)++ o a code (any short number or text, enclosed in parentheses)++ o a description (any remaining text until end of line or a semicolon)++ o a comment (any remaining text following a semicolon until end of+ line, and any following indented lines beginning with a semicolon)++ o 0 or more indented posting lines, describing what was transferred and+ the accounts involved (indented comment lines are also allowed, but+ not blank lines or non-indented lines).++ Here's a simple journal file containing one transaction:++ 2008/01/01 income+ assets:bank:checking $1+ income:salary $-1++ Dates+ Simple dates+ Dates in the journal file use simple dates format: YYYY-MM-DD or+ YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be+ omitted, in which case it will be inferred from the context: the cur-+ rent transaction, the default year set with a Y directive, or the cur-+ rent date when the command is run. Some examples: 2010-01-31,+ 2010/01/31, 2010.1.31, 1/31.++ (The UI also accepts simple dates, as well as the more flexible smart+ dates documented in the hledger manual.)++ Posting dates+ You can give individual postings a different date from their parent+ transaction, by adding a posting comment containing a tag (see below)+ like date:DATE. This is probably the best way to control posting dates+ precisely. Eg in this example the expense should appear in May re-+ ports, and the deduction from checking should be reported on 6/1 for+ easy bank reconciliation:++ 2015/5/30+ expenses:food $10 ; food purchased on saturday 5/30+ assets:checking ; bank cleared it on monday, date:6/1++ $ hledger -f t.j register food+ 2015-05-30 expenses:food $10 $10++ $ hledger -f t.j register checking+ 2015-06-01 assets:checking $-10 $-10++ DATE should be a simple date; if the year is not specified it will use+ the year of the transaction's date.+ The date: tag must have a valid simple date value if it is present, eg+ a date: tag with no value is not allowed.++ Status+ Transactions (or individual postings within a transaction) can have a+ status mark, which is a single character before the transaction de-+ scription (or posting account name), separated from it by a space, in-+ dicating 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 (and you can combine these, eg -UP+ to match all except cleared things). Or you can use the status:, sta-+ tus:!, and status:* queries, or the U, P, C keys in hledger-ui.++ (Note: in Ledger the "unmarked" state is called "uncleared"; in hledger+ we renamed it to "unmarked" for semantic clarity.)++ Status marks are optional, but can be helpful eg for reconciling with+ real-world accounts. Some editor modes provide highlighting and short-+ cuts for working with status. Eg in Emacs ledger-mode, you can toggle+ transaction status with C-c C-e, or posting status with C-c C-c.++ What "uncleared", "pending", and "cleared" actually mean is up to you.+ Here's one suggestion:++ status meaning+ --------------------------------------------------------------------------+ uncleared recorded but not yet reconciled; needs review+ pending tentatively reconciled (if needed, eg during a big reconcil-+ iation)+ cleared complete, reconciled as far as possible, and considered cor-+ rect++ With this scheme, you would use -PC to see the current balance at your+ bank, -U to see things which will probably hit your bank soon (like un-+ cashed checks), and no flags to see the most up-to-date state of your+ finances.++ 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+ After the date, status mark and/or code fields, the rest of the line+ (or until a comment is begun with ;) is the transaction's description.+ Here you can describe the transaction (called the "narration" in tradi-+ tional bookkeeping), or you can record a payee/payer name, or you can+ leave it empty.++ Transaction descriptions show up in print output and in register re-+ ports, and can be listed with the descriptions command.++ You can query by description with desc:DESCREGEX, or pivot on descrip-+ tion with --pivot desc.++ Payee and note+ Sometimes people want a dedicated payee/payer field that can be queried+ and checked more strictly. If you want that, you can write a | (pipe)+ character in the description. This divides it into a "payee" field on+ the left, and a "note" field on the right. (Either can be empty.)++ You can query these with payee:PAYEEREGEX and note:NOTEREGEX, list+ their values with the payees and notes commands, or pivot on payee or+ note.++ Note: in transactions with no | character, description, payee, and note+ all have the same value. Once a | is added, they become distinct. (If+ you'd like to change this behaviour, please propose it on the mail+ list.)++ If you want more strict error checking, you can declare the valid payee+ names with payee directives, and then enforce these with hledger check+ payees. (Note: because of the above, for this you'll need to ensure+ every transaction description contains a | and therefore a checkable+ payee name, even if it's empty.)++ Transaction comments+ Text following ;, after a transaction description, and/or on indented+ lines immediately below it, form comments for that transaction. They+ are reproduced by print but otherwise ignored, except they may contain+ tags, which are not ignored.++ 2012-01-01 something ; a transaction comment+ ; a second line of transaction comment+ expenses 1+ assets++ 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.++ If the amount is positive, it is being added to the account; if nega-+ tive, it is being removed from the account.++ The posting amounts in a transaction must sum up to zero, indicating+ that the inflows and outflows are equal. We call this a balanced+ transaction. (You can read more about the nitty-gritty details of "sum+ up to zero" in Transaction balancing below.)++ As a convenience, you can optionally leave one amount blank; hledger+ will infer what it should be so as to balance the transaction.++ Debits and credits+ The traditional accounting concepts of debit and credit of course exist+ in hledger, but we represent them with numeric sign, as described+ above. Positive and negative posting amounts represent debits and+ credits respectively.++ You don't need to remember that, but if you would like to - eg for+ helping newcomers or for talking with your accountant - here's a handy+ mnemonic:++ debit / plus / left / short words+ credit / minus / right / longer words++ The two space delimiter+ Be sure to notice the unusual separator between the account name and+ the following amount. Because hledger allows account names with spaces+ in them, you must separate the account name and amount (if any) by two+ or more spaces (or tabs). It's easy to forget at first. If you ever+ see the amount being treated as part of the account name, you'll know+ you probably need to add another space between them.++ Account names+ Accounts are the main way of categorising things in hledger. As in+ Double Entry Bookkeeping, they can represent real world accounts (such+ as a bank account), or more abstract categories such as "money borrowed+ from Frank" or "money spent on electricity".++ You can use any account names you like, but we usually start with the+ traditional accounting categories, which in english are assets, liabil-+ ities, equity, revenues, expenses. (You might see these referred to as+ A, L, E, R, X for short.)++ For more precise reporting, we usually divide the top level accounts+ into more detailed subaccounts, by writing a full colon between account+ name parts. For example, from the account names assets:bank:checking+ and expenses:food, hledger will infer this hierarchy of five accounts:++ assets+ assets:bank+ assets:bank:checking+ expenses+ expenses:food++ Shown as an outline, the hierarchical tree structure is more clear:++ assets+ bank+ checking+ expenses+ food++ hledger reports can summarise the account tree to any depth, so you can+ go as deep as you like with subcategories, but keeping your account+ names relatively simple may be best when starting out.++ Account names may be capitalised or not; they may contain letters, num-+ bers, symbols, or single spaces. Note, when an account name and an+ amount are written on the same line, they must be separated by two or+ more spaces (or tabs).++ Parentheses or brackets enclosing the full account name indicate vir-+ tual postings, described below. Parentheses or brackets internal to+ the account name have no special meaning.++ Account names can be altered temporarily or permanently by account+ aliases.++ Amounts+ After the account name, there is usually an amount. (Remember: 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+ A decimal mark can be written as a period or a comma:++ 1.23+ 1,23++ Both of these are common in international number formats, so hledger is+ not biased towards one or the other. Because hledger also supports+ digit group marks (eg thousands separators), this means that a number+ like 1,000 or 1.000 containing just one period or comma is ambiguous.+ In such cases, hledger by default assumes it is a decimal mark, and+ will parse both of those as 1.++ To help hledger parse such ambiguous numbers more accurately, if you+ use digit group marks, we recommend declaring the decimal mark explic-+ itly. The best way is to add a decimal-mark directive at the top of+ each data file, like this:++ decimal-mark .++ Or you can declare it per commodity with commodity directives, de-+ scribed below.++ hledger also accepts numbers like 10. with no digits after the decimal+ mark (and will sometimes display numbers that way to disambiguate them+ - see Trailing decimal marks).++ Digit group marks+ In the integer part of the amount quantity (left of the decimal mark),+ groups of digits can optionally be separated by a digit group mark - a+ comma or period (whichever is not used as decimal mark), or a space+ (several Unicode space variants, like no-break space, are also ac-+ cepted). So these are all valid amounts in a journal file:++ $1,000,000.00+ EUR 2.000.000,00+ INR 9,99,99,999.00+ 1 000 000.00 ; <- ordinary space+ 1 000 000.00 ; <- no-break space++ 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.++ By default, the format of amounts in the journal influences how hledger+ displays them in output. This is explained in Commodity display style+ below.++ Costs+ After a posting amount, you can note its cost (when buying) or selling+ price (when selling) in another commodity, by writing either @ UNIT-+ PRICE or @@ TOTALPRICE after it. This indicates a conversion transac-+ tion, where one commodity is exchanged for another.++ (You might also see this called "transaction price" in hledger docs,+ discussions, or code; that term was directionally neutral and reminded+ that it is a price specific to a transaction, but we now just call it+ "cost", with the understanding that the transaction could be a purchase+ or a sale.)++ Costs are usually written explicitly with @ or @@, but can also be in-+ ferred automatically for simple multi-commodity transactions. Note, if+ costs are inferred, the order of postings is significant; the first+ posting will have a cost attached, in the commodity of the second.++ As an example, here are several ways to record purchases of a foreign+ currency in hledger, using the cost notation either explicitly or im-+ plicitly:++ 1. Write the price per unit, as @ UNITPRICE after the amount:++ 2009/1/1+ assets:euros 100 @ $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 100 @@ $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. Note the+ effect of posting order: the price is added to first posting, making+ it 100 @@ $135, as in example 2:++ 2009/1/1+ assets:euros 100 ; one hundred euros purchased+ assets:dollars $-135 ; for $135++ Amounts can be converted to cost at report time using the -B/--cost+ flag; this is discussed more in the Cost reporting section.++ Note that the cost normally should be a positive amount, though it's+ not required to be. This can be a little confusing, see discussion at+ --infer-market-prices: market prices from transactions.++ 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, described below).++ Assertions and ordering+ hledger calculates and checks an account's balance assertions in date+ order (and when there are multiple assertions on the same day, in parse+ order). Note this is different from Ledger, which checks assertions+ always in parse order, ignoring dates.++ This means in hledger you can freely reorder transactions, postings, or+ files, and balance assertions will usually keep working. The exception+ is when you reorder multiple postings on the same day, to the same ac-+ count, which have balance assertions; those will likely need updating.++ Assertions and multiple included files+ Multiple files included with the include directive are processed as if+ concatenated into one file, preserving their order and the posting or-+ der within each file. It means that balance assertions in later files+ will see balance from earlier files.++ And if you have multiple postings to an account on the same day, split+ across multiple files, and you want to assert the account's balance on+ that day, you'll need to put the assertion in the right file - the last+ one in the sequence, probably.++ Assertions and multiple -f files+ Unlike include, when multiple files are specified on the command line+ with multiple -f/--file options, balance assertions will not see bal-+ ance from earlier files. This can be useful when you do not want prob-+ lems in earlier files to disrupt valid assertions in later files.++ If you do want assertions to see balance from earlier files, use in-+ clude, or concatenate the files temporarily.++ Assertions and costs+ Balance assertions ignore costs, and should normally be written without+ one:++ 2019/1/1+ (a) $1 @ 1 = $1++ We do allow costs to be written in balance assertion amounts, however,+ and print shows them, but 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 costs), and because+ balance assignments do use costs (see below).++ Assertions and commodities+ The balance assertions described so far are "single commodity balance+ assertions": they assert and check the balance in one commodity, ignor-+ ing any others that may be present. This is how balance assertions+ work in Ledger also.++ If an account contains multiple commodities, you can assert their bal-+ ances by writing multiple postings with balance assertions, one for+ each commodity:++ 2013/1/1+ usd $-1+ eur -1+ both++ 2013/1/2+ both 0 = $1+ both 0 = 1++ In hledger you can make a stronger "sole commodity balance assertion"+ by writing two equals signs (== EXPECTEDBALANCE). This also asserts+ that there are no other commodities in the account besides the asserted+ one (or at least, that their current balance is zero):++ 2013/1/1+ usd $-1 == $-1 ; these sole commodity assertions succeed+ eur -1 == -1+ both ;== $1 ; this one would fail because 'both' contains $ and++ It's less easy to make a "sole commodities balance assertion" (note the+ plural) - ie, asserting that an account contains two or more specified+ commodities and no others. It can be done by++ 1. isolating each commodity in a subaccount, and asserting those++ 2. and also asserting there are no commodities in the parent account+ itself:++ 2013/1/1+ usd $-1+ eur -1+ both 0 == 0 ; nothing up my sleeve+ both:usd $1 == $1 ; a dollar here+ both:eur 1 == 1 ; a euro there++ Assertions and subaccounts+ All of the balance assertions above (both = and ==) are "subaccount-ex-+ clusive balance assertions"; they ignore any balances that exist in+ deeper subaccounts.++ In hledger you can make "subaccount-inclusive balance assertions" by+ adding a star after the equals (=* or ==*):++ 2019/1/1+ equity:start+ assets:checking $10+ assets:savings $10+ assets $0 ==* $20 ; assets + subaccounts contains $20 and nothing else++ Assertions and virtual postings+ Balance assertions always consider both real and virtual postings; they+ are not affected by the --real/-R flag or real: query.++ Assertions and auto postings+ Balance assertions are affected by the --auto flag, which generates+ auto postings, which can alter account balances. Because auto postings+ are optional in hledger, accounts affected by them effectively have two+ balances. But balance assertions can only test one or the other of+ these. So to avoid making fragile assertions, either:++ o assert the balance calculated with --auto, and always use --auto with+ that file++ o or assert the balance calculated without --auto, and never use --auto+ with that file++ o or avoid balance assertions on accounts affected by auto postings (or+ avoid auto postings entirely).++ Assertions and precision+ Balance assertions compare the exactly calculated amounts, which are+ not always what is shown by reports. Eg a commodity directive may+ limit the display precision, but this will not affect balance asser-+ tions. Balance assertion failure messages show exact amounts.++ Posting comments+ Text following ;, at the end of a posting line, and/or on indented+ lines immediately below it, form comments for that posting. They are+ reproduced by print but otherwise ignored, except they may contain+ tags, which are not ignored.++ 2012-01-01+ expenses 1 ; a comment for posting 1+ assets+ ; a comment for posting 2+ ; a second comment line for posting 2++ Transaction balancing+ How exactly does hledger decide when a transaction is balanced ? The+ general goal is that if you look at the journal entry and calculate the+ amounts' sum perfectly with pencil and paper, hledger should agree with+ you.++ Real world transactions, especially for investments or cryptocurren-+ cies, often involve imprecise costs, complex decimals, and/or infi-+ nitely-recurring decimals, which are difficult or inconvenient to han-+ dle on a computer. So to be a practical accounting system, hledger al-+ lows some imprecision when checking transaction balancedness. The+ question is, how much imprecision should be allowed ?++ hledger currently decides it based on the commodity display styles: if+ the postings' sum would appear to be zero when displayed with the stan-+ dard display precisions, the transaction is considered balanced.++ Or equivalently: if the journal entry is displayed with amounts rounded+ to the standard display precisions (with hledger print --round=hard),+ and a human with pencil and paper would agree that those displayed+ amounts add up to zero, the transaction is considered balanced.++ This has some advantages: it is fairly intuitive, general not+ hard-coded, yet configurable when needed. On the downside it means+ that transaction balancedness is related to commodity display preci-+ sions, so eg when using -c/--commodity-style to display things with+ more than usual precision, you might need to fix some of your journal+ entries (ie, add decimal digits to make them balance more precisely).++ Other PTA tools (Ledger, Beancount..) have their own ways of doing it.+ Possible improvements are discussed at #1964.++ Note: if you have multiple journal files, and are relying on commodity+ directives to make imprecise journal entries balance, the directives'+ placement might be important - see commodity directive.++ Tags+ Tags are a way to add extra labels or data fields to transactions,+ postings, or accounts, which you can then search or pivot on.++ A tag is a word, optionally hyphenated, immediately followed by a full+ colon, in the comment of a transaction, a posting, or an account direc-+ tive. Eg: 2024-01-01 a transaction ; foo: Note this is an exception+ to the usual rule that things in comments are ignored.++ You can write multiple tags on one line, separated by comma. Or you+ can write each tag on its own comment line (no comma needed in this+ case).++ For example, here are five different tags: one on the assets:checking+ account, two on the transaction, and two on the expenses:food posting:++ account assets:checking ; accounttag:++ 2017/1/16 bought groceries ; transactiontag-1:+ ; transactiontag-2:+ assets:checking $-1+ expenses:food $1 ; postingtag:, another-posting-tag:++ Postings also inherit tags from their transaction and their account.+ And transactions also acquire tags from their postings (and postings'+ accounts). So in the example above, the expenses posting effectively+ has all five tags (by inheriting from the account and transaction), and+ the transaction also has all five tags (by acquiring from the expenses+ posting).++ Tag names+ Most non-whitespace characters are allowed in tag names. Eg : is a+ valid tag.++ You can list the tag names used in your journal with the tags command:+ hledger tags [NAMEREGEX]++ In commands which use a query, you can match by tag name. Eg:+ hledger print tag:NAMEREGEX++ You can declare valid tag names with the tag directive and then check+ them with the check command.++ Special tags+ Some tag names have special significance to hledger. There's not much+ harm in using them yourself, but some could produce an error message,+ particularly the date: and type: tags. They are explained elsewhere,+ but here is a quick list for reference:++ Tags you can set to influence hledger's behaviour:++ date -- overrides a posting's date+ date2 -- overrides a posting's secondary date+ type -- declares an account's type++ Tags hledger adds to indicate generated data:++ t -- appears on postings generated by timedot letters+ assert -- appears on txns generated by close --assert+ retain -- appears on txns generated by close --retain+ start -- appears on txns generated by close --migrate/--close/--open/--assign+ generated-transaction -- appears on generated periodic txns (with --verbose-tags)+ generated-posting -- appears on generated auto postings (with --verbose-tags)+ modified -- appears on txns which have had auto postings added (with --verbose-tags)+ Not displayed, but queryable:+ _generated-transaction -- exists on generated periodic txns (always)+ _generated-posting -- exists on generated auto postings (always)+ _modified -- exists on txns which have had auto postings added (always)++ Tags hledger uses internally:++ _conversion-matched -- exists on postings which have been matched with a nearby @/@@ cost annotation++ Tag values+ Tags can have a value, which is any text after the colon up until a+ comma or end of line, with surrounding whitespace removed. Ending at+ comma allows us to write multiple tags on one line, but also means that+ tag values can not contain commas.++ Eg in the following posting, the three tags' values are "value 1",+ "value 2", and "" (empty) respectively:++ expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz++ Multiple tags with the same name are additive rather than overriding:+ when the same tag name is seen again with a new value, the new+ name:value pair is added to the tags. It is not possible to override a+ previous tag's value or remove a tag.++ You can list all the values used for a particular tag in the journal+ with+ hledger tags TAGNAME --values++ You can match on tag values with a query like tag:NAMEREGEX=VALUEREGEX++ Directives+ Besides transactions, there is something else you can put in a journal+ file: directives. These are declarations, beginning with a keyword,+ that modify hledger's behaviour. Some directives can have more spe-+ cific subdirectives, indented below them. hledger's directives are+ similar to Ledger's in many cases, but there are also many differences.+ Directives are not required, but can be useful. Here are the main di-+ rectives:++ purpose directive+ --------------------------------------------------------------------------+ READING DATA:+ Rewrite account names alias+ Comment out sections of the file comment+ Declare file's decimal mark, to help decimal-mark+ parse amounts accurately+ Include other data files include+ GENERATING DATA:+ Generate recurring transactions or bud- ~+ get goals+ Generate extra postings on existing =+ transactions+ CHECKING FOR ERRORS:+ Define valid entities to provide more account, commodity, payee, tag+ error checking+ REPORTING:+ Declare accounts' type and display order account+ Declare commodity display styles commodity+ Declare market prices P++ Directives and multiple files+ Directives vary in their scope, ie which journal entries and which in-+ put files they affect. Most often, a directive will affect the follow-+ ing entries and included files if any, until the end of the current+ file - and no further. You might find this inconvenient! For example,+ alias directives do not affect parent or sibling files. But there are+ usually workarounds; for example, put alias directives in your top-most+ file, before including other files.++ The restriction, though it may be annoying at first, is in a good+ cause; it allows reports to be stable and deterministic, independent of+ the order of input. Without it, reports could show different numbers+ depending on the order of -f options, or the positions of include di-+ rectives in your files.++ Directive effects+ Here are all hledger's directives, with their effects and scope sum-+ marised - nine main directives, plus four others which we consider+ non-essential:++ di- what it does ends+ rec- at+ tive file+ end?+ --------------------------------------------------------------------------------------+ ac- Declares an account, for checking all entries in all files; and N+ count its display order and type. Subdirectives: any text, ignored.+ alias Rewrites account names, in following entries until end of cur- Y+ rent file or end aliases. Command line equivalent: --alias+ com- Ignores part of the journal file, until end of current file or Y+ ment end comment.+ com- Declares up to four things: 1. a commodity symbol, for checking N,N,Y,Y+ mod- all amounts in all files 2. the display style for all amounts+ ity of this commodity 3. the decimal mark for parsing amounts of+ this commodity, in the rest of this file and its children, if+ there is no decimal-mark directive 4. the precision to use for+ balanced-transaction checking in this commodity, in this file+ and its children. Takes precedence over D. Subdirectives:+ format (ignored). Command line equivalent: -c/--commodity-style+ deci- Declares the decimal mark, for parsing amounts of all commodi- Y+ mal-mark ties in following entries until next decimal-mark or end of cur-+ rent file. Included files can override. Takes precedence over+ commodity and D.+ include Includes entries and directives from another file, as if they N+ were written inline. Command line alternative: multiple+ -f/--file+ payee Declares a payee name, for checking all entries in all files. N+ P Declares the market price of a commodity on some date, for value N+ reports.+ ~ Declares a periodic transaction rule that generates future N+ (tilde) transactions with --forecast and budget goals with balance+ --budget.+ Other+ syntax:+ apply Prepends a common parent account to all account names, in fol- Y+ account lowing entries until end of current file or end apply account.+ D Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N+ there is no commodity directive for this commodity: its decimal+ mark, balancing precision, and display style, as above.+ Y Sets a default year to use for any yearless dates, in following Y+ entries until end of current file.+ = Declares an auto posting rule that generates extra postings on partly+ (equals) matched transactions with --auto, in current, parent, and child+ files (but not sibling files, see #1212).+ Other Other directives from Ledger's file format are accepted but ig-+ Ledger nored.+ direc-+ tives++ account directive+ account directives can be used to declare accounts (ie, the places that+ amounts are transferred from and to). Though not required, these dec-+ larations can provide several benefits:++ o They can document your intended chart of accounts, providing a refer-+ ence.++ o They can store additional account information as comments, or as tags+ which can be used to filter or pivot reports.++ o They can restrict which accounts may be posted to by transactions, eg+ in strict mode, which helps prevent errors.++ o They influence account display order in reports, allowing non-alpha-+ betic sorting (eg Revenues to appear above Expenses).++ o They can help hledger know your accounts' types (asset, liability,+ equity, revenue, expense), enabling reports like balancesheet and in-+ comestatement.++ o They help with account name completion (in hledger add, hledger-web,+ hledger-iadd, ledger-mode, etc.)++ They are written as the word account followed by a hledger-style ac-+ count name. Eg:++ account assets:bank:checking++ Ledger-style indented subdirectives are also accepted, but ignored:++ account assets:bank:checking+ format subdirective ; currently ignored++ Account comments+ Text following two or more spaces and ; at the end of an account direc-+ tive line, and/or following ; on indented lines immediately below it,+ form comments for that account. They are ignored except they may con-+ tain tags, which are not ignored.++ The two-space requirement for same-line account comments is because ;+ is allowed in account names.++ account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon+ ; next-line comment+ ; some tags - type:A, acctnum:12345++ Account error checking+ By default, accounts need not be declared; they come into existence+ when a posting references them. This is convenient, but it means+ hledger can't warn you when you mis-spell an account name in the jour-+ nal. Usually you'll find that error later, as an extra account in bal-+ ance reports, or an incorrect balance when reconciling.++ In strict mode, enabled with the -s/--strict flag, hledger will report+ an error if any transaction uses an account name that has not been de-+ clared by an account directive. Some notes:++ o The declaration is case-sensitive; transactions must use the correct+ account name capitalisation.++ o The account directive's scope is "whole file and below" (see direc-+ tives). This means it affects all of the current file, and any files+ it includes, but not parent or sibling files. The position of ac-+ count directives within the file does not matter, though it's usual+ to put them at the top.++ o Accounts can only be declared in journal files, but will affect in-+ cluded files of all types.++ o It's currently not possible to declare "all possible subaccounts"+ with a wildcard; every account posted to must be declared.++ Account display order+ Account directives also cause hledger to display accounts in a particu-+ lar order, not just alphabetically. Eg, here is a conventional order-+ ing for the top-level accounts:++ account assets+ account liabilities+ account equity+ account revenues+ account expenses++ Now hledger displays them in that order:++ $ hledger accounts+ assets+ liabilities+ equity+ revenues+ expenses++ If there are undeclared accounts, those will be displayed last, in al-+ phabetical order.++ Sorting is done within each group of sibling accounts, at each level of+ the account tree. Eg, a declaration like account parent:child influ-+ ences child's position among its siblings.++ Note, it does not affect parent's position; for that, you need an ac-+ count parent declaration.++ Sibling accounts are always displayed together; hledger won't display+ x:y in between a:b and a:c.++ An account directive both declares an account as a valid posting tar-+ get, and declares its display order; you can't easily do one without+ the other.++ Account types+ hledger knows that accounts come in several types: assets, liabilities,+ expenses and so on. This enables easy reports like balancesheet and+ incomestatement, and filtering by account type with the type: query.++ As a convenience, hledger will detect these account types automatically+ if you are using common english-language top-level account names (de-+ scribed below). But it's more robust to declare accounts' types ex-+ plicitly, by adding type: tags to their account directives. The tag's+ value should be one of the five main account types:++ o A or Asset (things you own)++ o L or Liability (things you owe)++ o E or Equity (investment/ownership; balanced counterpart of assets &+ liabilities)++ o R or Revenue (what you received money from, AKA income; technically+ part of Equity)++ o X or Expense (what you spend money on; technically part of Equity)++ or, it can be (these are used less often):++ o C or Cash (a subtype of Asset, indicating liquid assets for the cash-+ flow report)++ o V or Conversion (a subtype of Equity, for conversions (see Cost re-+ porting).)++ Subaccounts inherit their parent's type, or they can override it. Here+ is a typical set of account type declarations:++ account assets ; type: A+ account liabilities ; type: L+ account equity ; type: E+ account revenues ; type: R+ account expenses ; type: X++ account assets:bank ; type: C+ account assets:cash ; type: C++ account equity:conversion ; type: V++ Here are some tips for working with account types.++ o The rules for inferring types from account names are as follows.+ These are just a convenience that sometimes help new users get going;+ if they don't work for you, just ignore them and declare your account+ types. See also Regular expressions.++ If account's name contains this (CI) regular expression: | its type is:+ --------------------------------------------------------------------|-------------+ ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash+ ^assets?(:|$) | Asset+ ^(debts?|liabilit(y|ies))(:|$) | Liability+ ^equity:(trad(e|ing)|conversion)s?(:|$) | Conversion+ ^equity(:|$) | Equity+ ^(income|revenue)s?(:|$) | Revenue+ ^expenses?(:|$) | Expense++ o If you declare any account types, it's a good idea to declare an ac-+ count for all of the account types, because a mixture of declared and+ name-inferred types can disrupt certain reports.++ o Certain uses of account aliases can disrupt account types. See+ Rewriting accounts > Aliases and account types.++ o As mentioned above, subaccounts will inherit a type from their parent+ account. More precisely, an account's type is decided by the first+ of these that exists:++ 1. A type: declaration for this account.++ 2. A type: declaration in the parent accounts above it, preferring+ the nearest.++ 3. An account type inferred from this account's name.++ 4. An account type inferred from a parent account's name, preferring+ the nearest parent.++ 5. Otherwise, it will have no type.++ o For troubleshooting, you can list accounts and their types with:++ $ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]++ alias directive+ 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++ o combining two accounts into one, eg to see their sum or difference on+ one line++ 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.++ Account aliases are very powerful. They are generally easy to use cor-+ rectly, but you can also generate invalid account names with them; more+ on this below.++ 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 re-+ place any occurrence of the old account name with the new one. Subac-+ counts are also affected. Eg:++ alias checking = assets:bank:wells fargo:checking+ ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"++ Regex aliases+ There is also a more powerful variant that uses a regular expression,+ indicated by wrapping the pattern in forward slashes. (This is the+ only place where hledger requires forward slashes around a regular ex-+ pression.)++ Eg:++ alias /REGEX/ = REPLACEMENT++ or:++ $ hledger --alias '/REGEX/=REPLACEMENT' ...++ Any part of an account name matched by REGEX will be replaced by RE-+ PLACEMENT. REGEX is case-insensitive as usual.++ If you need to match a forward slash, escape it with a backslash, eg+ /\/=:.++ If REGEX contains parenthesised match groups, these can be referenced+ by the usual backslash and number in REPLACEMENT:++ alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3+ ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"++ REPLACEMENT continues to the end of line (or on command line, to end of+ option argument), so it can contain trailing whitespace.++ Combining aliases+ You can define as many aliases as you like, using journal directives+ and/or command line options.++ Recursive aliases - where an account name is rewritten by one alias,+ then by another alias, and so on - are allowed. Each alias sees the+ effect of previously applied aliases.++ In such cases it can be important to understand which aliases will be+ applied and in which order. For (each account name in) each journal+ entry, we apply:++ 1. alias directives preceding the journal entry, most recently parsed+ first (ie, reading upward from the journal entry, bottom to top)++ 2. --alias options, in the order they appeared on the command line+ (left to right).++ In other words, for (an account name in) a given journal entry:++ o the nearest alias declaration before/above the entry is applied first++ o the next alias before/above that will be be applied next, and so on++ o aliases defined after/below the entry do not affect it.++ This gives nearby aliases precedence over distant ones, and helps pro-+ vide semantic stability - aliases will keep working the same way inde-+ pendent of which files are being read and in which order.++ In case of trouble, adding --debug=6 to the command line will show+ which aliases are being applied when.++ Aliases and multiple files+ As explained at Directives and multiple files, alias directives do not+ affect parent or sibling files. Eg in this command,++ hledger -f a.aliases -f b.journal++ account aliases defined in a.aliases will not affect b.journal. In-+ cluding the aliases doesn't work either:++ include a.aliases++ 2023-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++ 2023-01-01 ; affected by aliases above+ foo 1+ bar++ include c.journal ; also affected++ end aliases directive+ You can clear (forget) all currently defined aliases (seen in the jour-+ nal so far, or defined on the command line) with this directive:++ end aliases++ Aliases can generate bad account names+ Be aware that account aliases can produce malformed account names,+ which could cause confusing reports or invalid print output. For exam-+ ple, you could erase all account names:++ 2021-01-01+ a:aa 1+ b++ $ hledger print --alias '/.*/='+ 2021-01-01+ 1++ The above print output is not a valid journal. Or you could insert an+ illegal double space, causing print output that would give a different+ journal when reparsed:++ 2021-01-01+ old 1+ other++ $ hledger print --alias old="new USD" | hledger -f- print+ 2021-01-01+ new USD 1+ other++ Aliases and account types+ If an account with a type declaration (see Declaring accounts > Account+ types) is renamed by an alias, normally the account type remains in ef-+ fect.++ However, renaming in a way that reshapes the account tree (eg renaming+ parent accounts but not their children, or vice versa) could prevent+ child accounts from inheriting the account type of their parents.++ Secondly, if an account's type is being inferred from its name, renam-+ ing it by an alias could prevent or alter that.++ If you are using account aliases and the type: query is not matching+ accounts as you expect, try troubleshooting with the accounts command,+ eg something like:++ $ hledger accounts --alias assets=bassetts type:a++ commodity directive+ The commodity directive performs several functions:++ 1. It declares which commodity symbols may be used in the journal, en-+ abling useful error checking with strict mode or the check command.+ See Commodity error checking below.++ 2. It declares how all amounts in this commodity should be displayed,+ eg how many decimals to show. See Commodity display style above.++ 3. (If no decimal-mark directive is in effect:) It sets the decimal+ mark to expect (period or comma) when parsing amounts in this com-+ modity, in this file and files it includes, from the directive until+ end of current file. See Decimal marks above.++ 4. It declares the precision with which this commodity's amounts should+ be compared when checking for balanced transactions, anywhere in+ this file and files it includes, until end of current file.++ Declaring commodities solves several common parsing/display problems,+ so we recommend it.++ Note that effects 3 and 4 above end at the end of the directive's file,+ and will not affect sibling or parent files. So if you are relying on+ them (especially 4) and using multiple files, placing your commodity+ directives in a top-level parent file might be important. Or, keep+ your decimal marks unambiguous and your entries well balanced and pre-+ cise.++ (Related: #793)++ Commodity directive syntax+ A commodity directive is normally the word commodity followed by a sam-+ ple amount (and optionally a comment). Only the amount's symbol and+ format is significant. Eg:++ commodity $1000.00+ commodity 1.000,00 EUR+ commodity 1 000 000.0000 ; the no-symbol commodity++ Commodities do not have tags (tags in the comment will be ignored).++ A commodity directive's sample amount must always include a period or+ comma decimal mark (this rule helps disambiguate decimal marks and+ digit group marks). If you don't want to show any decimal digits,+ write the decimal mark at the end:++ commodity 1000. AAAA ; show AAAA with no decimals++ Commodity symbols containing spaces, numbers, or punctuation must be+ enclosed in double quotes, as usual:++ commodity 1.0000 "AAAA 2023"++ Commodity directives normally include a sample amount, but can declare+ only a symbol (ie, just function 1 above):++ commodity $+ commodity INR+ commodity "AAAA 2023"+ commodity "" ; the no-symbol commodity++ Commodity directives may also be written with an indented format subdi-+ rective, as in Ledger. The symbol is repeated and must be the same in+ both places. Other subdirectives are currently ignored:++ ; 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+ an unsupported subdirective ; ignored by hledger++ Commodity error checking+ In strict mode (-s/--strict) (or when you run hledger check commodi-+ ties), hledger will report an error if an undeclared commodity symbol+ is used. (With one exception: zero amounts are always allowed to have+ no commodity symbol.) It works like account error checking (described+ above).++ decimal-mark directive+ You can use a decimal-mark directive - usually one per file, at the top+ of the file - to declare which character represents a decimal mark when+ parsing amounts in this file. It can look like++ decimal-mark .++ or++ decimal-mark ,++ This prevents any ambiguity when parsing numbers in the file, so we+ recommend it, especially if the file contains digit group marks (eg+ thousands separators).++ include directive+ You can pull in the content of additional files by writing an include+ directive, like this:++ include FILEPATH++ Only journal files can include, and only journal, timeclock or timedot+ files can be included (not CSV files, currently).++ If the file path does not begin with a slash, it is relative to the+ current file's folder.++ A tilde means home directory, eg: include ~/main.journal.++ The path may contain glob patterns to match multiple files, eg: include+ *.journal.++ There is limited support for recursive wildcards: **/ (the slash is re-+ quired) matches 0 or more subdirectories. It's not super convenient+ since you have to avoid include cycles and including directories, but+ this can be done, eg: include */**/*.journal.++ The path may also be prefixed to force a specific file format, overrid-+ ing the file extension (as described in Data formats): include time-+ dot:~/notes/2023*.md.++ P directive+ The P directive declares a market price, which is a conversion rate be-+ tween two commodities on a certain date. This allows value reports to+ convert amounts of one commodity to their value in another, on or after+ that date. These prices are often obtained from a stock exchange,+ cryptocurrency exchange, the or foreign exchange market.++ 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. Ex-+ amples:++ # one euro was worth $1.35 from 2009-01-01 onward:+ P 2009-01-01 $1.35++ # and $1.40 from 2010-01-01 onward:+ P 2010-01-01 $1.40++ The -V, -X and --value flags use these market prices to show amount+ values in another commodity. See Value reporting.++ payee directive+ payee PAYEE NAME++ This 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 ; a comment++ Payees do not have tags (tags in the comment will be ignored).++ To declare the empty payee name, use "".++ payee ""++ Ledger-style indented subdirectives, if any, are currently ignored.++ tag directive+ tag TAGNAME++ This directive can be used to declare a limited set of tag names al-+ lowed in tags. TAGNAME should be a valid tag name (no spaces). Eg:++ tag item-id++ Any indented subdirectives are currently ignored.++ The "tags" check will report an error if any undeclared tag name is+ used. It is quite easy to accidentally create a tag through normal use+ of colons in comments; if you want to prevent this, you can declare and+ check your tags .++ Periodic transactions+ The ~ directive declares a "periodic rule" which generates temporary+ extra transactions, usually recurring at some interval, when hledger is+ run with the --forecast flag. These "forecast transactions" are useful+ for forecasting future activity. They exist only for the duration of+ the report, and only when --forecast is used; they are not saved in the+ journal file by hledger.++ Periodic rules also have a second use: with the --budget flag they set+ budget goals for budgeting.++ Periodic rules can be a little tricky, so before you use them, read+ this whole section, or at least the following tips:++ 1. Two spaces accidentally added or omitted will cause you trouble -+ read about this below.++ 2. For troubleshooting, show the generated transactions with hledger+ print --forecast tag:generated or hledger register --forecast+ tag:generated.++ 3. Forecasted transactions will begin only after the last non-fore-+ casted transaction's date.++ 4. Forecasted transactions will end 6 months from today, by default.+ See below for the exact start/end rules.++ 5. period expressions can be tricky. Their documentation needs im-+ provement, but is worth studying.++ 6. Some period expressions with a repeating interval must begin on a+ natural boundary of that interval. Eg in weekly from DATE, DATE+ must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an+ error.++ 7. Other period expressions with an interval are automatically expanded+ to cover a whole number of that interval. (This is done to improve+ reports, but it also affects periodic transactions. Yes, it's a bit+ inconsistent with the above.) Eg: ~ every 10th day of month from+ 2023/01, which is equivalent to ~ every 10th day of month from+ 2023/01/01, will be adjusted to start on 2019/12/10.++ 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.):++ # every first of month+ ~ monthly+ expenses:rent $2000+ assets:bank:checking++ # every 15th of month in 2023's first quarter:+ ~ monthly from 2023-04-15 to 2023-06-16+ expenses:utilities $400+ assets:bank:checking++ The period expression is the same syntax used for specifying multi-pe-+ riod reports, just interpreted differently; there, it specifies report+ periods; here it specifies recurrence dates (the periods' start dates).++ Periodic rules and relative dates+ Partial or relative dates (like 12/31, 25, tomorrow, last week, next+ quarter) are usually not recommended in periodic rules, since the re-+ sults will change as time passes. If used, they will be interpreted+ relative to, in order of preference:++ 1. the first day of the default year specified by a recent Y directive++ 2. or the date specified with --today++ 3. or the date on which you are running the report.++ They will not be affected at all by report period or forecast period+ dates.++ 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 2023"+ ; ||+ ; vv+ ~ every 2 months in 2023, we will review+ assets:bank:checking $1500+ income:acme inc++ So,++ o Do write two spaces between your period expression and your transac-+ tion description, if any.++ o Don't accidentally write two spaces in the middle of your period ex-+ pression.++ Auto postings+ The = directive declares an "auto posting rule", which adds extra post-+ ings to existing transactions. (Remember, postings are the account+ name & amount lines below a transaction's date & description.)++ In the journal, an auto posting rule looks quite like a transaction,+ but instead of date and description it has = (mnemonic: "match") and a+ query, like this:++ = QUERY+ ACCOUNT AMOUNT+ ...++ Queries are just like command line queries; an account name substring+ is most common. Query terms containing spaces should be enclosed in+ single or double quotes.++ Each = rule works like this: when hledger is run with the --auto flag,+ wherever the QUERY matches a posting in the journal, the rule's post-+ ings are added to that transaction, immediately below the matched post-+ ing. Note these generated postings are temporary, existing only for+ the duration of the report, and only when --auto is used; they are not+ saved in the journal file by hledger.++ Generated postings' amounts can depend on the matched posting's amount.+ So auto postings can be useful for, eg, adding tax postings with a+ standard percentage. AMOUNT can be:++ o a number with no commodity symbol, like 2. The matched posting's+ commodity symbol will be added to this.++ o a normal amount with a commodity symbol, like $2. This will be used+ as-is.++ o an asterisk followed by a number, like *2. This will multiply the+ matched posting's amount (and total price, if any) by the number.++ o an asterisk followed by an amount with commodity symbol, like *$2.+ This multiplies and also replaces the commodity symbol with this new+ one.++ 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++ Note that depending fully on generated data such as this has some draw-+ backs - it's less portable, less future-proof, less auditable by oth-+ ers, and less robust (eg your balance assertions will depend on whether+ you use or don't use --auto). An alternative is to use auto postings+ in "one time" fashion - use them to help build a complex journal entry,+ view it with hledger print --auto, and then copy that output into the+ journal file to make it permanent.++ 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.++ This also means that you cannot have more than one auto-posting with a+ missing amount applied to a given transaction, as it will be unable to+ infer amounts.++ 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".++ Auto postings on forecast transactions only+ Tip: you can can make auto postings that will apply to forecast trans-+ actions but not recorded transactions, by adding tag:_generated-trans-+ action to their QUERY. This can be useful when generating new journal+ entries to be saved in the journal.++ Other syntax+ hledger journal format supports quite a few other features, mainly to+ make interoperating with or converting from Ledger easier. Note some+ of the features below are powerful and can be useful in special cases,+ but in general, features in this section are considered less important+ or even not recommended for most users. Downsides are mentioned to+ help you decide if you want to use them.++ Balance assignments+ Ledger-style balance assignments are also supported. These are like+ balance assertions, but with no posting amount on the left side of the+ equals sign; instead it is calculated automatically so as to satisfy+ the assertion. This can be a convenience during data entry, eg when+ 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).++ Downsides: using balance assignments makes your journal less explicit;+ to know the exact amount posted, you have to run hledger or do the cal-+ culations yourself, instead of just reading it. Also balance assign-+ ments' forcing of balances can hide errors. These things make your fi-+ nancial data less portable, less future-proof, and less trustworthy in+ an audit.++ Balance assignments and costs+ A cost in a balance assignment will cause the calculated amount to have+ that cost attached:++ 2019/1/1+ (a) = $1 @ 2++ $ hledger print --explicit+ 2019-01-01+ (a) $1 @ 2 = $1 @ 2++ Balance assignments and multiple files+ Balance assignments handle multiple files like balance assertions.+ They see balance from other files previously included from the current+ file, but not from previous sibling or parent files.++ Bracketed posting dates+ For setting posting dates and secondary posting dates, Ledger's brack-+ eted date syntax is also supported: [DATE], [DATE=DATE2] or [=DATE2] in+ posting comments. hledger will attempt to parse any square-bracketed+ sequence of the 0123456789/-.= characters in this way. With this syn-+ tax, DATE infers its year from the transaction and DATE2 infers its+ year from DATE.++ Downsides: another syntax to learn, redundant with hledger's+ date:/date2: tags, and confusingly similar to Ledger's lot date syntax.++ D directive+ D AMOUNT++ This 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+ current file.++ For compatibility/historical reasons, D also acts like a commodity di-+ rective (setting the commodity's decimal mark for parsing and display+ style for output). So its argument is not just a commodity symbol, but+ a full amount demonstrating the style. The amount must include a deci-+ mal mark (either period or comma). 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++ Interactions with other directives:++ For setting a commodity's display style, a commodity directive has+ highest priority, then a D directive.++ For detecting a commodity's decimal mark during parsing, decimal-mark+ has highest priority, then commodity, then D.++ For checking commodity symbols with the check command, a commodity di-+ rective is required (hledger check commodities ignores D directives).++ Downsides: omitting commodity symbols makes your financial data less+ explicit, less portable, and less trustworthy in an audit. It is usu-+ ally an unsustainable shortcut; sooner or later you will want to track+ multiple commodities. D is overloaded with functions redundant with+ commodity and decimal-mark. And it works differently from Ledger's D.++ apply account directive+ This directive sets a default parent account, which will be prepended+ to all accounts in following entries, until an end apply account direc-+ tive or end of current file. Eg:++ apply account home++ 2010/1/1+ food $10+ cash++ end apply account++ is equivalent to:++ 2010/01/01+ home:food $10+ home:cash $-10++ account directives are also affected, and so is any included content.++ Account names entered via hledger add or hledger-web are not affected.++ Account aliases, if any, are applied after the parent account is+ prepended.++ Downsides: this can make your financial data less explicit, less+ portable, and less trustworthy in an audit.++ Y directive+ Y YEAR++ or (deprecated backward-compatible forms):++ year YEAR apply year YEAR++ The space is optional. This sets a default year to be used for subse-+ quent dates which don't specify a year. Eg:++ Y2009 ; set default year to 2009++ 12/15 ; equivalent to 2009/12/15+ expenses 1+ assets++ year 2010 ; change default year to 2010++ 2009/1/30 ; specifies the year, not affected+ expenses 1+ assets++ 1/31 ; equivalent to 2010/1/31+ expenses 1+ assets++ Downsides: omitting the year (from primary transaction dates, at least)+ makes your financial data less explicit, less portable, and less trust-+ worthy in an audit. Such dates can get separated from their corre-+ sponding Y directive, eg when evaluating a region of the journal in+ your editor. A missing Y directive makes reports dependent on today's+ date.++ Secondary dates+ 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".++ Downsides: makes your financial data more complicated, less portable,+ and less trustworthy in an audit. Keeping the meaning of the two dates+ consistent requires discipline, and you have to remember which report-+ ing mode is appropriate for a given report. Posting dates are simpler+ and better.++ Star comments+ Lines beginning with * (star/asterisk) are also comment lines. This+ feature allows Emacs users to insert org headings in their journal, al-+ lowing them to fold/unfold/navigate it like an outline when viewed with+ org mode.++ Downsides: another, unconventional comment syntax to learn. Decreases+ your journal's portability. And switching to Emacs org mode just for+ folding/unfolding meant losing the benefits of ledger mode; nowadays+ you can add outshine mode to ledger mode to get folding without losing+ ledger mode's features.++ Valuation expressions+ Ledger allows a valuation function or value to be written in double+ parentheses after an amount. hledger ignores these.++ Virtual postings+ A posting with parentheses around the account name, like (some:account)+ 10, is called an unbalanced virtual posting. These postings do not+ participate in transaction balancing. (And if you write them without+ an amount, a zero amount is always inferred.) These can occasionally+ be convenient for special circumstances, but they violate double entry+ bookkeeping and make your data less portable across applications, so+ many people avoid using them at all.++ A posting with brackets around the account name ([some:account]) is+ called a balanced virtual posting. The balanced virtual postings in a+ transaction must add up to zero, just like ordinary postings, but sepa-+ rately from them. These are not part of double entry bookkeeping ei-+ ther, but they are at least balanced. An example:++ 2022-01-01 buy food with cash, update budget envelope subaccounts, & something else+ assets:cash $-10 ; <- these balance each other+ expenses:food $7 ; <-+ expenses:food $3 ; <-+ [assets:checking:budget:food] $-10 ; <- and these balance each other+ [assets:checking:available] $10 ; <-+ (something:else) $5 ; <- this is not required to balance++ Ordinary postings, whose account names are neither parenthesised nor+ bracketed, are called real postings. You can exclude virtual postings+ from reports with the -R/--real flag or a real:1 query.++ Other Ledger directives+ These other Ledger directives are currently accepted but ignored. This+ allows hledger to read more Ledger files, but be aware that hledger's+ reports may differ from Ledger's if you use these.++ apply fixed COMM AMT+ apply tag TAG+ assert EXPR+ bucket / A ACCT+ capture ACCT REGEX+ check EXPR+ define VAR=EXPR+ end apply fixed+ end apply tag+ end apply year+ end tag+ eval / expr EXPR+ python+ PYTHONCODE+ tag NAME+ value EXPR+ --command-line-flags++ See also https://hledger.org/ledger.html for a detailed hledger/Ledger+ syntax comparison.++ Other cost/lot notations+ A slight digression for Ledger and Beancount users. Ledger has a num-+ ber of cost/lot-related notations:++ o @ UNITCOST and @@ TOTALCOST++ o expresses a conversion rate, as in hledger++ o when buying, also creates a lot than can be selected at selling+ time++ o (@) UNITCOST and (@@) TOTALCOST (virtual cost)++ o like the above, but also means "this cost was exceptional, don't+ use it when inferring market prices".++ Currently, hledger treats the above like @ and @@; the parentheses are+ ignored.++ o {=FIXEDUNITCOST} and {{=FIXEDTOTALCOST}} (fixed price)++ o when buying, means "this cost is also the fixed price, don't let it+ fluctuate in value reports"++ o {UNITCOST} and {{TOTALCOST}} (lot price)++ o can be used identically to @ UNITCOST and @@ TOTALCOST, also cre-+ ates a lot++ o when selling, combined with @ ..., specifies an investment lot by+ its cost basis; does not check if that lot is present++ o and related: [YYYY/MM/DD] (lot date)++ o when buying, attaches this acquisition date to the lot++ o when selling, selects a lot by its acquisition date++ o (SOME TEXT) (lot note)++ o when buying, attaches this note to the lot++ o when selling, selects a lot by its note++ Currently, hledger accepts any or all of the above in any order after+ the posting amount, but ignores them. (This can break transaction bal-+ ancing.)++ For Beancount users, the notation and behaviour is different:++ o @ UNITCOST and @@ TOTALCOST++ o expresses a cost without creating a lot, as in hledger++ o when buying (augmenting) or selling (reducing) a lot, combined with+ {...}: documents the cost/selling price (not used for transaction+ balancing)++ o {UNITCOST} and {{TOTALCOST}}++ o when buying (augmenting), expresses the cost for transaction bal-+ ancing, and also creates a lot with this cost basis attached++ o when selling (reducing),++ o selects a lot by its cost basis++ o raises an error if that lot is not present or can not be selected+ unambiguously (depending on booking method configured)++ o expresses the selling price for transaction balancing++ Currently, hledger accepts the {UNITCOST}/{{TOTALCOST}} notation but+ ignores it.++ o variations: {}, {YYYY-MM-DD}, {"LABEL"}, {UNITCOST, "LABEL"}, {UNIT-+ COST, YYYY-MM-DD, "LABEL"} etc.++ Currently, hledger rejects these.++CSV+ hledger can read CSV files (Character Separated Value - usually comma,+ semicolon, or tab) containing dated records, automatically converting+ each record into a transaction.++ (To learn about writing CSV, see CSV output.)++ For best error messages when reading CSV/TSV/SSV files, make sure they+ have a corresponding .csv, .tsv or .ssv file extension or use a hledger+ file prefix (see File Extension below).++ Each CSV file must be described by a corresponding rules file.+ This contains rules describing the CSV data (header line, fields lay-+ out, date format etc.), how to construct hledger transactions from it,+ and how to categorise transactions based on description or other at-+ tributes.++ By default, hledger expects this rules file to be named like the CSV+ file, with an extra .rules extension added, in the same directory. Eg+ when asked to read foo/FILE.csv, hledger looks for foo/FILE.csv.rules.+ You can specify a different rules file with the --rules-file option.++ 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++ There's an introductory Importing CSV data tutorial on hledger.org, and+ more CSV rules examples below, and a larger collection at+ https://github.com/simonmichael/hledger/tree/master/examples/csv.++ CSV rules cheatsheet+ The following kinds of rule can appear in the rules file, in any order.+ (Blank lines and lines beginning with # or ; or * are ignored.)++ source optionally declare which file to read data+ from+ separator declare the field separator, instead of rely-+ ing on file extension+ skip skip one or more header lines at start of file+ date-format declare how to parse CSV dates/date-times+ timezone declare the time zone of ambiguous CSV+ date-times+ newest-first improve txn order when: there are multiple+ records, newest first, all with the same date+ intra-day-reversed improve txn order when: same-day txns are in+ opposite order to the overall file+ decimal-mark declare the decimal mark used in CSV amounts,+ when ambiguous+ fields list name CSV fields for easy reference, and op-+ tionally assign their values to hledger fields+ Field assignment assign a CSV value or interpolated text value+ to a hledger field+ if block conditionally assign values to hledger fields,+ or skip a record or end (skip rest of file)+ if table conditionally assign values to hledger fields,+ using compact syntax+ balance-type select which type of balance assertions/as-+ signments to generate+ include inline another CSV rules file++ Working with CSV tips can be found below, including How CSV rules are+ evaluated.++ source+ If you tell hledger to read a csv file with -f foo.csv, it will look+ for rules in foo.csv.rules. Or, you can tell it to read the rules+ file, with -f foo.csv.rules, and it will look for data in foo.csv+ (since 1.30).++ These are mostly equivalent, but the second method provides some extra+ features. For one, the data file can be missing, without causing an+ error; it is just considered empty. And, you can specify a different+ data file by adding a "source" rule:++ source ./Checking1.csv++ If you specify just a file name with no path, hledger will look for it+ in your system's downloads directory (~/Downloads, currently):++ source Checking1.csv++ And if you specify a glob pattern, hledger will read the most recent of+ the matched files (useful with repeated downloads):++ source Checking1*.csv++ See also "Working with CSV > Reading files specified by rule".++ 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.++ skip+ skip N++ The word skip followed by a number (or no number, meaning 1) tells+ hledger to ignore this many non-empty lines at the start of the input+ data. You'll need this whenever your CSV data contains header lines.+ Note, empty and blank lines are skipped automatically, so you don't+ need to count those.++ skip has a second meaning: it can be used inside if blocks (described+ below), to skip one or more records whenever the condition is true.+ Records skipped in this way are ignored, except they are still required+ to be valid CSV.++ 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-style+ date parsing pattern - see https://hackage.haskell.org/pack-+ age/time/docs/Data-Time-Format.html#v:formatTime. The pattern 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++ timezone+ timezone TIMEZONE++ When CSV contains date-times that are implicitly in some time zone+ other than yours, but containing no explicit time zone information, you+ can use this rule to declare the CSV's native time zone, which helps+ prevent off-by-one dates.++ When the CSV date-times do contain time zone information, you don't+ need this rule; instead, use %Z in date-format (or %z, %EZ, %Ez; see+ the formatTime link above).++ In either of these cases, hledger will do a time-zone-aware conversion,+ localising the CSV date-times to your current system time zone. If you+ prefer to localise to some other time zone, eg for reproducibility, you+ can (on unix at least) set the output timezone with the TZ environment+ variable, eg:++ $ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv++ timezone currently does not understand timezone names, except "UTC",+ "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", or "PDT". For+ others, use numeric format: +HHMM or -HHMM.++ newest-first+ hledger tries to ensure that the generated transactions will be ordered+ chronologically, including same-day transactions. Usually it can+ auto-detect how the CSV records are ordered. But if it encounters CSV+ where all records are on the same date, it assumes that the records are+ oldest first. If in fact the CSV's records are normally newest first,+ like:++ 2022-10-01, txn 3...+ 2022-10-01, txn 2...+ 2022-10-01, txn 1...++ you can add the newest-first rule to help hledger generate the transac-+ tions in correct order.++ # same-day CSV records are newest first+ newest-first++ intra-day-reversed+ If CSV records within a single day are ordered opposite to the overall+ record order, you can add the intra-day-reversed rule to improve the+ order of journal entries. Eg, here the overall record order is newest+ first, but same-day records are oldest first:++ 2022-10-02, txn 3...+ 2022-10-02, txn 4...+ 2022-10-01, txn 1...+ 2022-10-01, txn 2...++ # transactions within each day are reversed with respect to the overall date order+ intra-day-reversed++ 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.++ fields list+ fields FIELDNAME1, FIELDNAME2, ...++ A fields list (the word fields followed by comma-separated field names)+ is optional, but convenient. It does two things:++ 1. It names the CSV field in each column. This can be convenient if+ you are referencing them in other rules, so you can say %SomeField+ instead of remembering %13.++ 2. Whenever you use one of the special hledger field names (described+ below), it assigns the CSV value in this position to that hledger+ field. This is the quickest way to populate hledger's fields and+ build a transaction.++ Here's an example that says "use the 1st, 2nd and 4th fields as the+ transaction's date, description and amount; name the last two fields+ for later reference; and ignore the others":++ fields date, description, , amount, , , somefield, anotherfield++ In a fields list, the separator is always comma; it is unrelated to the+ CSV file's separator. Also:++ o 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 Field names may contain _ (underscore) or - (hyphen).++ o Fields you don't care about can be given a dummy name or an empty+ name.++ If the CSV contains column headings, it's convenient to use these for+ your field names, suitably modified (eg lower-cased with spaces re-+ placed by underscores).++ Sometimes you may want to alter a CSV field name to avoid assigning to+ a hledger field with the same name. Eg you could call the CSV's "bal-+ ance" field balance_ to avoid directly setting hledger's balance field+ (and generating a balance assertion).++ Field assignment+ HLEDGERFIELD 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 either by their 1-based position in the+ CSV record (%N) or by the name they were given in the fields list+ (%CSVFIELD), and regular expression match groups (\N).++ 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 " be-+ comes 1 when interpolated) (#1051).++ o Interpolations always refer to a CSV field - you can't interpolate a+ hledger field. (See Referencing other fields below).++ Field names+ Note the two kinds of field names mentioned here, and used only in+ hledger CSV rules files:++ 1. CSV field names (CSVFIELD in these docs): you can optionally name+ the CSV columns for easy reference (since hledger doesn't yet auto-+ matically recognise column headings in a CSV file), by writing arbi-+ trary names in a fields list, eg:++ fields When, What, Some_Id, Net, Total, Foo, Bar++ 2. Special hledger field names (HLEDGERFIELD in these docs): you must+ set at least some of these to generate the hledger transaction from+ a CSV record, by writing them as the left hand side of a field as-+ signment, eg:++ date %When+ code %Some_Id+ description %What+ comment %Foo %Bar+ amount1 $ %Total++ or directly in a fields list:++ fields date, description, code, , amount1, Foo, Bar+ currency $+ comment %Foo %Bar++ Here are all the special hledger field names available, and what hap-+ pens when you assign values to them:++ 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.++ You can assign multi-line comments by writing literal \n in the code.+ A comment starting with \n will begin on a new line.++ Comments can contain 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, in conditional rules.++ If a posting's account name is left unset but its amount is set (see+ below), a default account name will be chosen (like "expenses:unknown"+ or "income:unknown").++ amount field+ There are several ways to set posting amounts from CSV, useful in dif-+ ferent situations.++ 1. amount is the oldest and simplest. Assigning to this sets the+ amount of the first and second postings. In the second posting, the+ amount will be negated; also, if it has a cost attached, it will be+ converted to cost.++ 2. amount-in and amount-out work exactly like the above, but should be+ used when the CSV has two amount fields (such as "Debit" and+ "Credit", or "Inflow" and "Outflow"). Whichever field has a+ non-zero value will be used as the amount of the first and second+ postings. Here are some tips to avoid confusion:++ o It's not "amount-in for posting 1 and amount-out for posting 2",+ it is "extract a single amount from the amount-in or amount-out+ field, and use that for posting 1 and (negated) for posting 2".++ o Don't use both amount and amount-in/amount-out in the same rules+ file; choose based on whether the amount is in a single CSV field+ or spread across two fields.++ o In each record, at most one of the two CSV fields should contain+ a non-zero amount; the other field must contain a zero or noth-+ ing.++ o hledger assumes both CSV fields contain unsigned numbers, and it+ automatically negates the amount-out values.++ o If the data doesn't fit these requirements, you'll probably need+ an if rule (see below).++ 3. amountN (where N is a number from 1 to 99) sets the amount of only a+ single posting: the Nth posting in the transaction. You'll usually+ need at least two such assignments to make a balanced transaction.+ You can also generate more than two postings, to represent more com-+ plex transactions. The posting numbers don't have to be consecu-+ tive; with if rules, higher posting numbers can be useful to ensure+ a certain order of postings.++ 4. amountN-in and amountN-out work exactly like the above, but should+ be used when the CSV has two amount fields. This is analogous to+ amount-in and amount-out, and those tips also apply here.++ 5. Remember that a fields list can also do assignments. So in a fields+ list if you name a CSV field "amount", that counts as assigning to+ amount. (If you don't want that, call it something else in the+ fields list, like "amount_".)++ 6. The above don't handle every situation; if you need more flexibil-+ ity, use an if rule to set amounts conditionally. See "Working with+ CSV > Setting amounts" below for more on this and on amount-setting+ generally.++ currency field+ currency sets a currency symbol, to be prepended to all postings'+ 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 the Working with CSV tips below for more about setting amounts and+ currency.++ if block+ Rules can be applied conditionally, depending on patterns in the CSV+ data. This allows flexibility; in particular, it is how you can cate-+ gorise transactions, selecting an appropriate account name based on+ their description (for example). There are two ways to write condi-+ tional rules: "if blocks", described here, and "if tables", described+ below.++ An if block is the word if and one or more "matcher" expressions (can+ be a word or phrase), one per line, starting either on the same or next+ line; followed by one or more indented rules. Eg,++ if MATCHER+ RULE++ or++ if+ MATCHER+ MATCHER+ MATCHER+ RULE+ RULE++ If any of the matchers succeeds, all of the indented rules will be ap-+ plied. They are usually field assignments, but the following special+ rules may also be used within an if block:++ o skip - skips the matched CSV record (generating no transaction from+ it)++ o end - skips the rest of the current CSV file.++ Some examples:++ # if the record contains "groceries", set account2 to "expenses:groceries"+ if groceries+ account2 expenses:groceries++ # if the record contains any of these phrases, set account2 and a transaction comment as shown+ if+ monthly service fee+ atm transaction fee+ banking thru software+ account2 expenses:business:banking+ comment XXX deductible ? check it++ # if an empty record is seen (assuming five fields), ignore the rest of the CSV file+ if ,,,,+ end++ Matchers+ There are two kinds:++ 1. A record matcher is a word or single-line text fragment or regular+ expression (REGEX), which hledger will try to match case-insensi-+ tively anywhere within the CSV record.+ Eg: whole foods++ 2. A field matcher is preceded with a percent sign and CSV field name+ (%CSVFIELD REGEX). hledger will try to match these just within the+ named CSV field.+ Eg: %date 2023++ The regular expression is (as usual in hledger) a POSIX extended regu-+ lar expression, that also supports GNU word boundaries (\b, \B, \<,+ \>), and nothing else. If you have trouble, see "Regular expressions"+ in the hledger manual (https://hledger.org/hledger.html#regular-expres-+ sions).++ What matchers match+ With record matchers, it's important to know that the record matched is+ not the original CSV record, but a modified one: separators will be+ converted to commas, and enclosing double quotes (but not enclosing+ whitespace) are removed. So for example, when reading an SSV file, if+ the original record was:++ 2023-01-01; "Acme, Inc."; 1,000++ the regex would see, and try to match, this modified record text:++ 2023-01-01,Acme, Inc., 1,000++ Combining matchers+ When an if block has multiple matchers, they are combined as follows:++ o By default they are OR'd (any of them can match)++ o When a matcher is preceded by ampersand (&, at the start of the line)+ it will be AND'ed with the previous matcher (all in the AND'ed group+ must match)++ o Added in 1.32 When a matcher is preceded by an exclamation mark (!),+ it is negated (it must not match).++ Note currently there is a limitation: you can't use both & and ! on the+ same line (you can't AND a negated matcher).++ Match groups+ Added in 1.32++ Matchers can define match groups: parenthesised portions of the regular+ expression which are available for reference in field assignments.+ Groups are enclosed in regular parentheses (( and )) and can be nested.+ Each group is available in field assignments using the token \N, where+ N is an index into the match groups for this conditional block (e.g.+ \1, \2, etc.).++ Example: Warp credit card payment postings to the beginning of the+ billing period (Month start), to match how they are presented in state-+ ments, using posting dates:++ if %date (....-..)-..+ comment2 date:\1-01++ Another example: Read the expense account from the CSV field, but throw+ away a prefix:++ if %account1 liabilities:family:(expenses:.*)+ account1 \1++ if table+ "if tables" are an alternative to if blocks; they can express many+ matchers and field assignments in a more compact tabular format, like+ this:++ if,HLEDGERFIELD1,HLEDGERFIELD2,...+ MATCHERA,VALUE1,VALUE2,...+ MATCHERB,VALUE1,VALUE2,...+ ; Comment line that explains MATCHERC+ MATCHERC,VALUE1,VALUE2,...+ <empty line>++ The first character after if is taken to be this if table's field sepa-+ rator. It is unrelated to the separator used in the CSV file. It+ should be a non-alphanumeric character like , or | that does not appear+ anywhere else in the table (it should not be used in field names or+ matchers or values, and it cannot be escaped with a backslash).++ Each line must contain the same number of separators; empty values are+ allowed. Whitespace can be used in the matcher lines for readability+ (but not in the if line, currently). You can use the comment lines in+ the table body. The table must be terminated by an empty line (or end+ of file).++ An if table like the above is interpreted as follows: try all of the+ matchers; whenever a matcher succeeds, assign all of the values on that+ line to the corresponding hledger fields; If multiple lines match,+ later lines will override fields assigned by the earlier ones - just+ like the sequence of if blocks would behave.++ If table presented above is equivalent to this sequence of if blocks:++ if MATCHERA+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++ if MATCHERB+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++ ; Comment line which explains MATCHERC+ if MATCHERC+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++ Example:++ if,account2,comment+ atm transaction fee,expenses:business:banking,deductible? check it+ %description groceries,expenses:groceries,+ ;; Comment line that desribes why this particular date is special+ 2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out++ 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++ 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++ Working with CSV+ Some 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 eradman.com/entrproject:++ $ 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+ Note that hledger will only accept valid CSV conforming to RFC 4180,+ and equivalent SSV and TSV formats (like RFC 4180 but with semicolon or+ tab as separators). This means, eg:++ o Values may be enclosed in double quotes, or not. Enclosing in single+ quotes is not allowed. (Eg 'A','B' is rejected.)++ o When values are enclosed in double quotes, spaces outside the quotes+ are not allowed. (Eg "A", "B" is rejected.)++ o When values are not enclosed in quotes, they may not contain double+ quotes. (Eg A"A, B is rejected.)++ If your CSV/SSV/TSV is not valid in this sense, you'll need to trans-+ form it before reading with hledger. Try using sed, or a more permis-+ sive CSV parser like python's csv lib.++ File Extension+ To help hledger choose the CSV file reader and show the right error+ messages (and choose the right field separator character by default),+ it's best if CSV/SSV/TSV files are named with a .csv, .ssv or .tsv+ filename extension. (More about this at Data formats.)++ When reading files with the "wrong" extension, you can ensure the CSV+ reader (and the default field separator) by prefixing the file path+ with csv:, ssv: or tsv:: Eg:++ $ hledger -f ssv:foo.dat print++ You can also override the default field separator with a separator rule+ if needed.++ Reading CSV from standard input+ You'll need the file format prefix when reading CSV from stdin also,+ since hledger assumes journal format by default. Eg:++ $ cat foo.dat | hledger -f ssv:- print++ Reading multiple CSV files+ If you use multiple -f options to read multiple CSV files at once,+ hledger will look for a correspondingly-named rules file for each CSV+ file. But if you use the --rules-file option, that rules file will be+ used for all the CSV files.++ Reading files specified by rule+ Instead of specifying a CSV file in the command line, you can specify a+ rules file, as in hledger -f foo.csv.rules CMD. By default this will+ read data from foo.csv in the same directory, but you can add a source+ rule to specify a different data file, perhaps located in your web+ browser's download directory.++ This feature was added in hledger 1.30, so you won't see it in most CSV+ rules examples. But it helps remove some of the busywork of managing+ CSV downloads. Most of your financial institutions's default CSV file-+ names are different and can be recognised by a glob pattern. So you+ can put a rule like source Checking1*.csv in foo-checking.csv.rules,+ and then periodically follow a workflow like:++ 1. Download CSV from Foo's website, using your browser's defaults++ 2. Run hledger import foo-checking.csv.rules to import any new transac-+ tions++ After import, you can: discard the CSV, or leave it where it is for a+ while, or move it into your archives, as you prefer. If you do noth-+ ing, next time your browser will save something like Checking1-2.csv,+ and hledger will use that because of the * wild card and because it is+ the most recent.++ Valid transactions+ After reading a CSV file, hledger post-processes and validates the gen-+ erated journal entries as it would for a journal file - balancing them,+ applying balance assignments, and canonicalising amount styles. Any+ errors at this stage will be reported in the usual way, displaying the+ problem entry.++ There is one exception: balance assertions, if you have generated them,+ will not be checked, since normally these will work only when the CSV+ data is part of the main journal. If you do need to check balance as-+ sertions generated from CSV right away, pipe into another hledger:++ $ hledger -f file.csv print | hledger -f- print++ Deduplicating, importing+ When you download a CSV file periodically, eg to get your latest bank+ transactions, the new file may overlap with the old one, containing+ some of the same records.++ The import command will (a) detect the new transactions, and (b) append+ just those transactions to your main journal. It is idempotent, so you+ don't have to remember how many times you ran it or with which version+ of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This+ is the easiest way to import CSV data. Eg:++ # download the latest CSV files, then run this command.+ # Note, no -f flags needed here.+ $ hledger import *.csv [--dry]++ This method works for most CSV files. (Where records have a stable+ chronological order, and new records appear only at the new end.)++ A number of other tools and workflows, hledger-specific and otherwise,+ exist for converting, deduplicating, classifying and managing CSV data.+ See:++ o https://hledger.org/cookbook.html#setups-and-workflows++ o https://plaintextaccounting.org -> data import/conversion++ Setting amounts+ Continuing from amount field above, here are more tips for amount-set-+ ting:++ 1. If the amount is in a single CSV field:+ a. If its sign indicates direction of flow:+ Assign it to amountN, to set the Nth posting's amount. N is usu-+ ally 1 or 2 but can go up to 99.++ b. If another field indicates direction of flow:+ Use one or more conditional rules to set the appropriate amount+ sign. Eg:++ # assume a withdrawal unless Type contains "deposit":+ amount1 -%Amount+ if %Type deposit+ amount1 %Amount++ 2. If the amount is in two CSV fields (such as Debit and Credit, or In+ and Out):+ a. If both fields are unsigned:+ Assign one field to amountN-in and the other to amountN-out.+ hledger will automatically negate the "out" field, and will use+ whichever field value is non-zero as posting N's amount.++ b. If either field is signed:+ You will probably need to override hledger's sign for one or the+ other field, as in the following example:++ # Negate the -out value, but only if it is not empty:+ fields date, description, amount1-in, amount1-out+ if %amount1-out [1-9]+ amount1-out -%amount1-out++ c. If both fields can contain a non-zero value (or both can be+ empty):+ The -in/-out rules normally choose the value which is+ non-zero/non-empty. Some value pairs can be ambiguous, such as 1+ and none. For such cases, use conditional rules to help select the+ amount. Eg, to handle the above you could select the value con-+ taining non-zero digits:++ fields date, description, in, out+ if %in [1-9]+ amount1 %in+ if %out [1-9]+ amount1 %out++ 3. If you want posting 2's amount converted to cost:+ Use the unnumbered amount (or amount-in and amount-out) syntax.++ 4. If the CSV has only balance amounts, not transaction amounts:+ Assign to balanceN, to set a balance assignment on the Nth posting,+ causing the posting's amount to be calculated automatically. balance+ with no number is equivalent to balance1. In this situation hledger is+ more likely to guess the wrong default account name, so you may need to+ set that explicitly.++ Amount signs+ There is some special handling making it easier to parse and to reverse+ amount signs. (This only works for whole amounts, not for cost amounts+ such as COST in amount1 AMT @ COST):++ 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+ "".++ It's not possible (without preprocessing the CSV) to set an amount to+ its absolute value, ie discard its sign.++ Setting currency/commodity+ If the currency/commodity symbol is included in the CSV's amount+ field(s):++ 2023-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++ 2023-01-01 foo+ expenses:unknown $123.00+ income:unknown $-123.00++ If the currency is provided as a separate CSV field:++ 2023-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++ 2023-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++ 2023-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 re-+ peated, the last one wins:++ o skip (at top level)++ o date-format++ o newest-first++ o fields - names the CSV fields, optionally sets up initial assignments+ to hledger fields++ Then for each CSV record in turn:++ o test all if blocks. If any of them contain a end rule, skip all re-+ maining CSV records. Otherwise if any of them contain a skip rule,+ skip that many CSV records. If there are multiple matched skip+ rules, the first one wins.++ o collect all field assignments at top level and in matched if blocks.+ When there are multiple assignments for a field, keep only the last+ one.++ o compute a value for each hledger field - either the one that was as-+ signed to it (and interpolate the %CSVFIELD references), or a default++ o generate a hledger transaction (journal entry) from these values.++ This is all part of the CSV reader, one of several readers hledger can+ use to parse input files. When all files have been read successfully,+ the transactions are passed as input to whichever hledger command the+ user specified.++ Well factored rules+ Some things than can help reduce duplication and complexity in rules+ files:++ o Extracting common rules usable with multiple CSV files into a com-+ mon.rules, and adding include common.rules to each CSV's rules file.++ o Splitting if blocks into smaller if blocks, extracting the frequently+ used parts.++ CSV rules examples+ 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.++ Coinbase+ A simple example with some CSV from Coinbase. The spot price is+ recorded using cost notation. The legacy amount field name conve-+ niently sets amount 2 (posting 2's amount) to the total cost.++ # Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes+ # 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,"","","","Received 100.00 USDC from an external account"++ # coinbase.csv.rules+ skip 1+ fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes+ date %Timestamp+ date-format %Y-%m-%dT%T%Z+ description %Notes+ account1 assets:coinbase:cc+ amount %Quantity_Transacted %Asset @ %Spot_Price_at_Transaction %Spot_Price_Currency++ $ hledger print -f coinbase.csv+ 2021-12-30 Received 100.00 USDC from an external account+ assets:coinbase:cc 100 USDC @ 0.740000 GBP+ income:unknown -74.000000 GBP++ 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:++Timeclock+ 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 op-+ tional. The timezone, if present, must be four digits and is ignored+ (currently the time is always interpreted as a local time). Lines be-+ ginning with # or ; or *, and blank lines, are ignored.++ i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:+ 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 2 spaces ; optional comment, tags:+ (some account) 0.33h++ 2015-03-31 * 22:21-23:59+ (another:account) 1.64h++ 2015-04-01 * 00:00-02:00+ (another:account) 2.01h++ 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 time-+ clock-x.el and perhaps the extras in ledgerutils.el++ o at the command line, use these bash aliases: cli 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+ timedot format is hledger's human-friendly time logging format. Com-+ pared to timeclock format, it is more convenient for quick, approxi-+ mate, and retroactive time logging, and more human-readable (you can+ see at a glance where time was spent). A quick example:++ 2023-05-01+ hom:errands .... .... ; two hours; the space is ignored+ fos:hledger:timedot .. ; half an hour+ per:admin:finance ; no time spent yet++ hledger reads this as a transaction on this day with three (unbalanced)+ postings, where each dot represents "0.25". No commodity symbol is as-+ sumed, but we typically interpret it as hours.++ $ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required+ 2023-05-01 *+ (hom:errands) 2.00 ; two hours+ (fos:hledger:timedot) 0.50 ; half an hour+ (per:admin:finance) 0++ A timedot file contains a series of transactions (usually one per day).+ Each begins with a simple date (Y-M-D, Y/M/D, or Y.M.D), optionally be+ followed on the same line by a transaction description, and/or a trans-+ action comment following a semicolon.++ After the date line are zero or more time postings, consisting of:++ o An account name - any hledger-style account name, optionally in-+ dented.++ o Two or more spaces - required if there is an amount (as in journal+ format).++ o A timedot amount, which can be++ o empty (representing zero)++ o a number, optionally followed by a unit s, m, h, d, w, mo, or y,+ representing a precise number of seconds, minutes, hours, days+ weeks, months or years (hours is assumed by default), which will be+ converted to hours according to 60s = 1m, 60m = 1h, 24h = 1d, 7d =+ 1w, 30d = 1mo, 365d = 1y.++ o one or more dots (period characters), each representing 0.25.+ These are the dots in "timedot". Spaces are ignored and can be+ used for grouping/alignment.++ o Added in 1.32 one or more letters. These are like dots but they+ also generate a tag t: (short for "type") with the letter as its+ value, and a separate posting for each of the values. This pro-+ vides a second dimension of categorisation, viewable in reports+ with --pivot t.++ o An optional comment following a semicolon (a hledger-style posting+ comment).++ There is some flexibility to help with keeping time log data and notes+ in the same file:++ o Blank lines and lines beginning with # or ; are ignored.++ o After the first date line, lines which do not contain a double space+ are parsed as postings with zero amount. (hledger's register reports+ will show these if you add -E).++ o Before the first date line, lines beginning with * (eg org headings)+ are ignored. And from the first date line onward, Emacs org mode+ heading prefixes at the start of lines (one or more *'s followed by a+ space) will be ignored. This means the time log can also be a org+ outline.++ Timedot examples+ Numbers:++ 2016/2/3+ inc:client1 4+ fos:hledger 3h+ biz:research 60m++ Dots:++ # 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 .++ $ 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++ Letters:++ # Activity types:+ # c cleanup/catchup/repair+ # e enhancement+ # s support+ # l learning/research++ 2023-11-01+ work:adm ccecces++ $ hledger -f a.timedot print+ 2023-11-01+ (work:adm) 1 ; t:c+ (work:adm) 0.5 ; t:e+ (work:adm) 0.25 ; t:s++ $ hledger -f a.timedot bal+ 1.75 work:adm+ --------------------+ 1.75++ $ hledger -f a.timedot bal --pivot t+ 1.00 c+ 0.50 e+ 0.25 s+ --------------------+ 1.75++ Org:++ * 2023 Work Diary+ ** Q1+ *** 2023-02-29+ **** DONE+ 0700 yoga+ **** UNPLANNED+ **** BEGUN+ hom:chores+ cleaning ...+ water plants+ outdoor - one full watering can+ indoor - light watering+ **** TODO+ adm:planning: trip+ *** LATER++ Using . as account name separator:++ 2016/2/4+ fos.hledger.timedot 4h+ fos.ledger ..++ $ hledger -f a.timedot --alias '/\./=:' bal -t+ 4.50 fos+ 4.00 hledger:timedot+ 0.50 ledger+ --------------------+ 4.50++PART 3: REPORTING CONCEPTS+Amount formatting+ Commodity display style+ For the amounts in each commodity, hledger chooses a consistent display+ style (symbol placement, decimal mark and digit group marks, number of+ decimal digits) to use in most reports. This is inferred as follows:++ First, if there's a D directive declaring a default commodity, that+ commodity symbol and amount format is applied to all no-symbol amounts+ in the journal.++ Then each commodity's display style is determined from its commodity+ directive. We recommend always declaring commodities with commodity+ directives, since they help ensure consistent display styles and preci-+ sions, and bring other benefits such as error checking for commodity+ symbols. Here's an example:++ # Set display styles (and decimal marks, for parsing, if there is no decimal-mark directive)+ # for the $, EUR, INR and no-symbol commodities:+ commodity $1,000.00+ commodity EUR 1.000,00+ commodity INR 9,99,99,999.00+ commodity 1 000 000.9455++ But for convenience, if a commodity directive is not present, hledger+ infers a commodity's display styles from its amounts as they are writ-+ ten in the journal (excluding cost amounts and amounts in periodic+ transaction rules or auto posting rules). It uses++ o the symbol placement and decimal mark of the first amount seen++ o the digit group marks of the first amount with digit group marks++ o and the maximum number of decimal digits seen across all amounts.++ And as fallback if no applicable amounts are found, it would use a de-+ fault style, like $1000.00 (symbol on the left with no space, period as+ decimal mark, and two decimal digits).++ Finally, commodity styles can be overridden by the -c/--commodity-style+ command line option.++ Rounding+ Amounts are stored internally as decimal numbers with up to 255 decimal+ places. They are displayed with their original journal precisions by+ print and print-like reports, and rounded to their display precision+ (the number of decimal digits specified by the commodity display style)+ by other reports. When rounding, hledger uses banker's rounding (it+ rounds to the nearest even digit). So eg 0.5 displayed with zero deci-+ mal digits appears as "0".++ Trailing decimal marks+ If you're wondering why your print report sometimes shows trailing dec-+ imal marks, with no decimal digits; it does this when showing amounts+ that have digit group marks but no decimal digits, to disambiguate them+ and allow them to be re-parsed reliably (see Decimal marks). Eg:++ commodity $1,000.00++ 2023-01-02+ (a) $1000++ $ hledger print+ 2023-01-02+ (a) $1,000.++ If this is a problem (eg when exporting to Ledger), you can avoid it by+ disabling digit group marks, eg with -c/--commodity (for each affected+ commodity):++ $ hledger print -c '$1000.00'+ 2023-01-02+ (a) $1000++ or by forcing print to always show decimal digits, with --round:++ $ hledger print -c '$1,000.00' --round=soft+ 2023-01-02+ (a) $1,000.00++ Amount parseability+ More generally, hledger output falls into three rough categories, which+ format amounts a little bit differently to suit different consumers:++ 1. "hledger-readable output" - should be readable by hledger (and by+ humans)++ o This is produced by reports that show full journal entries: print,+ import, close, rewrite etc.++ o It shows amounts with their original journal precisions, which may+ not be consistent.++ o It adds a trailing decimal mark when needed to avoid showing ambigu-+ ous amounts.++ o It can be parsed reliably (by hledger and ledger2beancount at least,+ but perhaps not by Ledger..)++ 2. "human-readable output" - usually for humans++ o This is produced by all other reports.++ o It shows amounts with standard display precisions, which will be con-+ sistent within each commodity.++ o It shows ambiguous amounts unmodified.++ o It can be parsed reliably in the context of a known report (when you+ know decimals are consistently not being shown, you can assume a sin-+ gle mark is a digit group mark).++ 3. "machine-readable output" - usually for other software++ o This is produced by all reports when an output format like csv, tsv,+ json, or sql is selected.++ o It shows amounts as 1 or 2 do, but without digit group marks.++ o It can be parsed reliably (if needed, the decimal mark can be changed+ with -c/--commodity-style).++Time periods+ Report start & end date+ By default, most hledger reports will show the full span of time repre-+ sented by the journal. The report start date will be the earliest+ transaction or posting date, and the report end date will be the latest+ transaction, posting, or market price date.++ Often you will want to see a shorter time span, such as the current+ month. You can specify a start and/or end date using -b/--begin,+ -e/--end, -p/--period or a date: query (described below). All of these+ accept the smart date syntax (below).++ Some notes:++ o End dates are exclusive, as in Ledger, so you should write the date+ after the last day you want to see in the report.++ 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 In some cases a report interval will adjust start/end dates to fall+ on interval boundaries (see below).++ Examples:++ -b 2016/3/17 begin on St. Patrick's day 2016+ -e 12/1 end at the start of december 1st of the current year+ (11/30 will be the last date included)+ -b thismonth all transactions on or after the 1st of the current month+ -p thismonth all transactions in the current month+ date:2016/3/17.. the above written as queries instead (.. can also be re-+ placed with -)+ date:..12/1+ date:thismonth..+ date:thismonth++ Smart dates+ hledger's user interfaces accept a "smart date" syntax for added conve-+ nience. Smart dates optionally can be relative to today's date, be+ written with english words, and have less-significant parts omitted+ (missing parts are inferred as 1). Some 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+ in n n periods from the current period+ days/weeks/months/quar-+ ters/years+ n n periods from the current period+ days/weeks/months/quar-+ ters/years ahead+ n -n periods from the current period+ days/weeks/months/quar-+ ters/years ago+ 20181201 8 digit YYYYMMDD with valid year month and day+ 201812 6 digit YYYYMM with valid year and month++ Some 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++ "Today's date" can be overridden with the --today option, in case it's+ needed for testing or for recreating old reports. (Except for periodic+ transaction rules, which are not affected by --today.)++ Report intervals+ A report interval can be specified so that reports like register, bal-+ ance or activity become multi-period, showing each subperiod as a sepa-+ rate row or column.++ The following standard intervals can be enabled with command-line+ flags:++ o -D/--daily++ o -W/--weekly++ o -M/--monthly++ o -Q/--quarterly++ o -Y/--yearly++ More complex intervals can be specified using -p/--period, described+ below.++ Date adjustment+ When there is a report interval (other than daily), report start/end+ dates which have been inferred, eg from the journal, are automatically+ adjusted to natural period boundaries. This is convenient for produc-+ ing simple periodic reports. More precisely:++ o an inferred start date will be adjusted earlier if needed to fall on+ a natural period boundary++ o an inferred end date will be adjusted later if needed to make the+ last period the same length as the others.++ By contrast, start/end dates which have been specified explicitly, with+ -b, -e, -p or date:, will not be adjusted (since hledger 1.29). This+ makes it possible to specify non-standard report periods, but it also+ means that if you are specifying a start date, you should pick one+ that's on a period boundary if you want to see simple report period+ headings.++ Period expressions+ The -p/--period option specifies a period expression, which is a com-+ pact way of expressing a start date, end date, and/or report interval.++ Here's a period expression with a start and end date (specifying the+ first quarter of 2009):++ -p "from 2009/1/1 to 2009/4/1"++ Several keywords like "from" and "to" are supported for readability;+ these are optional. "to" can also be written as ".." or "-". The+ spaces are also optional, as long as you don't run two dates together.+ So the following are equivalent to the above:++ -p "2009/1/1 2009/4/1"+ -p2009/1/1to2009/4/1+ -p2009/1/1..2009/4/1++ Dates are smart dates, so if the current year is 2009, these are also+ equivalent to the above:++ -p "1/1 4/1"+ -p "jan-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 date in the journal:++ -p "from 2009/1/1" everything after january+ 1, 2009+ -p "since 2009/1" the same, since is a syn-+ onym+ -p "from 2009" the same+ -p "to 2009" everything before january+ 1, 2009++ You can also specify a period by writing a single partial or full date:++ -p "2009" the year 2009; equivalent to "2009/1/1 to 2010/1/1"+ -p "2009/1" the month of january 2009; equivalent to "2009/1/1 to+ 2009/2/1"+ -p "2009/1/1" the first day of 2009; equivalent to "2009/1/1 to+ 2009/1/2"++ or by using the "Q" quarter-year syntax (case insensitive):++ -p "2009Q1" first quarter of 2009, equivalent to "2009/1/1 to+ 2009/4/1"+ -p "q4" fourth quarter of the current year++ Period expressions with a report interval+ A period expression can also begin with a report interval, separated+ from the start/end dates (if any) by a space or the word in:++ -p "weekly from 2009/1/1 to 2009/4/1"+ -p "monthly in 2008"+ -p "quarterly"++ More complex report intervals+ Some more complex intervals can be specified within period expressions,+ such as:++ o biweekly (every two weeks)++ o fortnightly++ o bimonthly (every two months)++ o every day|week|month|quarter|year++ o every N days|weeks|months|quarters|years++ Weekly on a custom day:++ o every Nth day of week (th, nd, rd, or st are all accepted after the+ number)++ o every WEEKDAYNAME (full or three-letter english weekday name, case+ insensitive)++ Monthly on a custom day:++ o every Nth day [of month]++ o every Nth WEEKDAYNAME [of month]++ Yearly on a custom day:++ o every MM/DD [of year] (month number and day of month number)++ o every MONTHNAME DDth [of year] (full or three-letter english month+ name, case insensitive, and day of month number)++ o every DDth MONTHNAME [of year] (equivalent to the above)++ Examples:++ -p "bimonthly from 2008"+ -p "every 2 weeks"+ -p "every 5 months from+ 2009/03"+ -p "every 2nd day of week" periods will go from Tue to Tue+ -p "every Tue" same+ -p "every 15th day" period boundaries will be on 15th of each+ 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+ November+ -p "every 5th November" same+ -p "every Nov 5th" same++ Show historical balances at end of the 15th day of each month (N is an+ end date, exclusive as always):++ $ hledger balance -H -p "every 16th day"++ Group postings from the start of wednesday to end of the following+ tuesday (N is both (inclusive) start date and (exclusive) end date):++ $ hledger register checking -p "every 3rd day of week"++ Multiple weekday intervals+ This special form is also supported:++ o every WEEKDAYNAME,WEEKDAYNAME,... (full or three-letter english week-+ day names, case insensitive)++ Also, weekday and weekendday are shorthand for mon,tue,wed,thu,fri and+ sat,sun.++ This is mainly intended for use with --forecast, to generate periodic+ transactions on arbitrary days of the week. It may be less useful with+ -p, since it divides each week into subperiods of unequal length, which+ is unusual. (Related: #1632)++ Examples:++ -p "every dates will be Mon, Wed, Fri; periods will be+ mon,wed,fri" Mon-Tue, Wed-Thu, Fri-Sun+ -p "every weekday" dates will be Mon, Tue, Wed, Thu, Fri; periods will+ be Mon, Tue, Wed, Thu, Fri-Sun+ -p "every weekend- dates will be Sat, Sun; periods will be Sat, Sun-Fri+ day"++Depth+ With the --depth NUM option (short form: -NUM), reports will show ac-+ counts only to the specified depth, hiding deeper subaccounts. Use+ this when you want a summary with less detail. This flag has the same+ effect as a depth: query argument: depth:2, --depth=2 or -2 are equiva-+ lent.++Queries+ One of hledger's strengths is being able to quickly report on a precise+ subset of your data. Most hledger commands accept query arguments, to+ restrict their scope. Multiple query terms can be provided to build up+ a more complex query.++ o By default, a query term is interpreted as a case-insensitive sub-+ string pattern for matching account names:++ car:fuel+ dining groceries+ o Patterns containing spaces or other special characters must be en-+ closed in single or double quotes:++ 'personal care'+ o These patterns are actually regular expressions, so you can add reg-+ exp metacharacters for more precision (see "Regular expressions"+ above for details):++ '^expenses\b'+ 'food$'+ 'fuel|repair'+ 'accounts (payable|receivable)'+ o To match something other than account name, add one of the query type+ prefixes described in "Query types" below:++ date:202312-+ status:+ desc:amazon+ cur:USD+ cur:\\$+ amt:'>0'+ o Add a not: prefix to negate a term:++ not:status:'*'+ not:desc:'opening|closing'+ not:cur:USD+ o Terms with different types are AND-ed, terms with the same type are+ OR-ed (mostly; see "Combining query terms" below). The following+ query:++ date:2022 desc:amazon desc:amzn++ is interpreted as:++ date is in 2022 AND ( transaction description contains "amazon" OR+ "amzn" )++ 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 or REGEX+ Match account names containing this case insensitive regular expres-+ sion. This is the default query type, so we usually don't bother writ-+ ing the "acct:" prefix.++ 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 es-+ caping. 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 in-+ terval. 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.++ expr:"TERM AND NOT (TERM OR TERM)" (eg)+ Match with a boolean combination of queries (which must be enclosed in+ quotes). See Combining query terms below.++ 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.++ type:TYPECODES+ Match by account type (see Declaring accounts > Account types). TYPE-+ CODES is one or more of the single-letter account type codes ALERXCV,+ case insensitive. Note type:A and type:E will also match their respec-+ tive subtypes C (Cash) and V (Conversion). Certain kinds of account+ alias can disrupt account types, see Rewriting accounts > Aliases and+ account types.++ tag:REGEX[=REGEX]+ Match by tag name, and optionally also by tag value. (To match only by+ value, use tag:.=REGEX.)++ When querying by tag, note that:++ o Accounts also inherit the tags of their parent accounts++ o Postings also inherit the tags of their account and their transaction++ o Transactions also acquire the tags of their postings.++ (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+ When given multiple space-separated 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.++ The print command is a little different, showing 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.++ We also support more complex boolean queries with the expr: prefix.+ This allows one to combine query terms using and, or, not keywords+ (case insensitive), and to group them by enclosing in parentheses.++ Some examples:++ o Exclude account names containing 'food':++ expr:"not food" (not:food is equivalent)++ o Match things which have 'cool' in the description and the 'A' tag:++ expr:"desc:cool and tag:A" (expr:"desc:cool tag:A" is equivalent)++ o Match things which either do not reference the 'expenses:food' ac-+ count, or do have the 'A' tag:++ expr:"not expenses:food or tag:A"++ o Match things which either do not reference the 'expenses:food' ac-+ count, or which reference the 'expenses:drink' account and also have+ the 'A' tag:++ expr:"expenses:food or (expenses:drink and tag:A)"++ expr: has a restriction: date: queries may not be used inside or ex-+ pressions. That would allow disjoint report periods or disjoint result+ sets, with unclear semantics for our reports.++ Queries and command options+ Some queries can also be expressed as command-line options: depth:2 is+ equivalent to --depth 2, date:2023 is equivalent to -p 2023, etc. When+ you mix command options and query arguments, generally the resulting+ 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 re-+ ports, cur: and amt: match the old commodity symbol and the old amount+ quantity, not the new ones. (Except in hledger 1.22, #1625.)++Pivoting+ Normally, hledger groups and sums amounts within each account. The+ --pivot FIELD option substitutes some other transaction field for ac-+ count names, causing amounts to be grouped and summed by that field's+ value instead. FIELD can be any of the transaction fields acct, sta-+ tus, code, desc, payee, note, or a tag name. When pivoting on a tag+ and a posting has multiple values of that tag, only the first value is+ displayed. Values containing colon:separated:parts will be displayed+ hierarchically, like account names. Multiple, colon-delimited fields+ can be pivoted simultaneously, generating a hierarchical account name.++ Some examples:++ 2016/02/16 Yearly Dues Payment+ assets:bank account 2 EUR+ income:dues -2 EUR ; member: John Doe, kind: Lifetime++ Normal balance report showing account names:++ $ hledger balance+ 2 EUR assets:bank account+ -2 EUR income:dues+ --------------------+ 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):++ $ 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++ Hierarchical reports can be generated with multiple pivots:++ $ hledger balance Income:Dues --pivot kind:member+ -2 EUR Lifetime:John Doe+ --------------------+ -2 EUR++Generating data+ hledger has several features for generating data, such as:++ o Periodic transaction rules can generate single or repeating transac-+ tions following a template. These are usually dated in the future,+ eg to help with forecasting. They are activated by the --forecast+ option.++ o The balance command's --budget option uses these same periodic rules+ to generate goals for the budget report.++ o Auto posting rules can generate extra postings on certain matched+ transactions. They are always applied to forecast transactions; with+ the --auto flag they are applied to transactions recorded in the+ journal as well.++ o The --infer-equity flag infers missing conversion equity postings+ from @/@@ costs. And the inverse --infer-costs flag infers missing+ @/@@ costs from conversion equity postings.++ Generated data of this kind is temporary, existing only at report time.+ But you can see it in the output of hledger print, and you can save+ that to your journal, in effect converting it from temporary generated+ data to permanent recorded data. This could be useful as a data entry+ aid.++ If you are wondering what data is being generated and why, add the+ --verbose-tags flag. In hledger print output you will see extra tags+ like generated-transaction, generated-posting, and modified on gener-+ ated/modified data. Also, even without --verbose-tags, generated data+ always has equivalen hidden tags (with an underscore prefix), so eg you+ could match generated transactions with tag:_generated-transaction.++Forecasting+ Forecasting, or speculative future reporting, can be useful for esti-+ mating future balances, or for exploring different future scenarios.++ The simplest and most flexible way to do it with hledger is to manually+ record a bunch of future-dated transactions. You could keep these in a+ separate future.journal and include that with -f only when you want to+ see them.++ --forecast+ There is another way: with the --forecast option, hledger can generate+ temporary "forecast transactions" for reporting purposes, according to+ periodic transaction rules defined in the journal. Each rule can gen-+ erate multiple recurring transactions, so by changing one rule you can+ change many forecasted transactions.++ Forecast transactions usually start after ordinary transactions end.+ By default, they begin after your latest-dated ordinary transaction, or+ today, whichever is later, and they end six months from today. (The+ exact rules are a little more complicated, and are given below.)++ This is the "forecast period", which need not be the same as the report+ period. You can override it - eg to forecast farther into the future,+ or to force forecast transactions to overlap your ordinary transactions+ - by giving the --forecast option a period expression argument, like+ --forecast=..2099 or --forecast=2023-02-15... Note that the = is re-+ quired.++ Inspecting forecast transactions+ print is the best command for inspecting and troubleshooting forecast+ transactions. Eg:++ ~ monthly from 2022-12-20 rent+ assets:bank:checking+ expenses:rent $1000++ $ hledger print --forecast --today=2023/4/21+ 2023-05-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ 2023-06-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ 2023-07-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ 2023-08-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ 2023-09-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ Here there are no ordinary transactions, so the forecasted transactions+ begin on the first occurence after today's date. (You won't normally+ use --today; it's just to make these examples reproducible.)++ Forecast reports+ Forecast transactions affect all reports, as you would expect. Eg:++ $ hledger areg rent --forecast --today=2023/4/21+ Transactions in expenses:rent and subaccounts:+ 2023-05-20 rent as:ba:checking $1000 $1000+ 2023-06-20 rent as:ba:checking $1000 $2000+ 2023-07-20 rent as:ba:checking $1000 $3000+ 2023-08-20 rent as:ba:checking $1000 $4000+ 2023-09-20 rent as:ba:checking $1000 $5000++ $ hledger bal -M expenses --forecast --today=2023/4/21+ Balance changes in 2023-05-01..2023-09-30:++ || May Jun Jul Aug Sep+ ===============++===================================+ expenses:rent || $1000 $1000 $1000 $1000 $1000+ ---------------++-----------------------------------+ || $1000 $1000 $1000 $1000 $1000++ Forecast tags+ Forecast transactions generated by --forecast have a hidden tag, _gen-+ erated-transaction. So if you ever need to match forecast transac-+ tions, you could use tag:_generated-transaction (or just tag:generated)+ in a query.++ For troubleshooting, you can add the --verbose-tags flag. Then, visi-+ ble generated-transaction tags will be added also, so you can view them+ with the print command. Their value indicates which periodic rule was+ responsible.++ Forecast period, in detail+ Forecast start/end dates are chosen so as to do something useful by de-+ fault in almost all situations, while also being flexible. Here are+ (with luck) the exact rules, to help with troubleshooting:++ The forecast period starts on:++ o the later of++ o the start date in the periodic transaction rule++ o the start date in --forecast's argument++ o otherwise (if those are not available): the later of++ o the report start date specified with -b/-p/date:++ o the day after the latest ordinary transaction in the journal++ o otherwise (if none of these are available): today.++ The forecast period ends on:++ o the earlier of++ o the end date in the periodic transaction rule++ o the end date in --forecast's argument++ o otherwise: the report end date specified with -e/-p/date:++ o otherwise: 180 days (~6 months) from today.++ Forecast troubleshooting+ When --forecast is not doing what you expect, one of these tips should+ help:++ o Remember to use the --forecast option.++ o Remember to have at least one periodic transaction rule in your jour-+ nal.++ o Test with print --forecast.++ o Check for typos or too-restrictive start/end dates in your periodic+ transaction rule.++ o Leave at least 2 spaces between the rule's period expression and de-+ scription fields.++ o Check for future-dated ordinary transactions suppressing forecasted+ transactions.++ o Try setting explicit report start and/or end dates with -b, -e, -p or+ date:++ o Try adding the -E flag to encourage display of empty periods/zero+ transactions.++ o Try setting explicit forecast start and/or end dates with --fore-+ cast=START..END++ o Consult Forecast period, in detail, above.++ o Check inside the engine: add --debug=2 (eg).++Budgeting+ With the balance command's --budget report, each periodic transaction+ rule generates recurring budget goals in specified accounts, and goals+ and actual performance can be compared. See the balance command's doc+ below.++ You can generate budget goals and forecast transactions at the same+ time, from the same or different periodic transaction rules: hledger+ bal -M --budget --forecast ...++ See also: Budgeting and Forecasting.++Cost reporting+ In some transactions - for example a currency conversion, or a purchase+ or sale of stock - one commodity is exchanged for another. In these+ transactions there is a conversion rate, also called the cost (when+ buying) or selling price (when selling). In hledger docs we just say+ "cost", for convenience; feel free to mentally translate to "conversion+ rate" or "selling price" if helpful.++ Recording costs+ We'll explore several ways of recording transactions involving costs.+ These are also summarised at hledger Cookbook > Cost notation.++ Costs can be recorded explicitly in the journal, using the @ UNITCOST+ or @@ TOTALCOST notation described in Journal > Costs:++ Variant 1++ 2022-01-01+ assets:dollars $-135+ assets:euros 100 @ $1.35 ; $1.35 per euro (unit cost)++ Variant 2++ 2022-01-01+ assets:dollars $-135+ assets:euros 100 @@ $135 ; $135 total cost++ Typically, writing the unit cost (variant 1) is preferable; it can be+ more effort, requiring more attention to decimal digits; but it reveals+ the per-unit cost basis, and makes stock sales easier.++ Costs can also be left implicit, and hledger will infer the cost that+ is consistent with a balanced transaction:++ Variant 3++ 2022-01-01+ assets:dollars $-135+ assets:euros 100++ Here, hledger will attach a @@ 100 cost to the first amount (you can+ see it with hledger print -x). This form looks convenient, but there+ are downsides:++ o It sacrifices some error checking. For example, if you accidentally+ wrote 10 instead of 100, hledger would not be able to detect the mis-+ take.++ o It is sensitive to the order of postings - if they were reversed, a+ different entry would be inferred and reports would be different.++ o The per-unit cost basis is not easy to read.++ So generally this kind of entry is not recommended. You can make sure+ you have none of these by using -s (strict mode), or by running hledger+ check balanced.++ Reporting at cost+ Now when you add the -B/--cost flag to reports ("B" is from Ledger's+ -B/--basis/--cost flag), any amounts which have been annotated with+ costs will be converted to their cost's commodity (in the report out-+ put). Ie they will be displayed "at cost" or "at sale price".++ Some things to note:++ o Costs are attached to specific posting amounts in specific transac-+ tions, and once recorded they do not change. This contrasts with+ market prices, which are ambient and fluctuating.++ o Conversion to cost is performed before conversion to market value+ (described below).++ Equity conversion postings+ There is a problem with the entries above - they are not conventional+ Double Entry Bookkeeping (DEB) notation, and because of the "magical"+ transformation of one commodity into another, they cause an imbalance+ in the Accounting Equation. This shows up as a non-zero grand total in+ balance reports like hledger bse.++ For most hledger users, this doesn't matter in practice and can safely+ be ignored ! But if you'd like to learn more, keep reading.++ Conventional DEB uses an extra pair of equity postings to balance the+ transaction. Of course you can do this in hledger as well:++ Variant 4++ 2022-01-01+ assets:dollars $-135+ assets:euros 100+ equity:conversion $135+ equity:conversion -100++ Now the transaction is perfectly balanced according to standard DEB,+ and hledger bse's total will not be disrupted.++ And, hledger can still infer the cost for cost reporting, but it's not+ done by default - you must add the --infer-costs flag like so:++ $ hledger print --infer-costs+ 2022-01-01 one hundred euros purchased at $1.35 each+ assets:dollars $-135 @@ 100+ assets:euros 100+ equity:conversion $135+ equity:conversion -100++ $ hledger bal --infer-costs -B+ -100 assets:dollars+ 100 assets:euros+ --------------------+ 0++ Here are some downsides of this kind of entry:++ o The per-unit cost basis is not easy to read.++ o Instead of -B you must remember to type -B --infer-costs.++ o --infer-costs works only where hledger can identify the two eq-+ uity:conversion postings and match them up with the two non-equity+ postings. So writing the journal entry in a particular format be-+ comes more important. More on this below.++ Inferring equity conversion postings+ Can we go in the other direction ? Yes, if you have transactions writ-+ ten with the @/@@ cost notation, hledger can infer the missing equity+ postings, if you add the --infer-equity flag. Eg:++ 2022-01-01+ assets:dollars -$135+ assets:euros 100 @ $1.35++ $ hledger print --infer-equity+ 2022-01-01+ assets:dollars $-135+ assets:euros 100 @ $1.35+ equity:conversion:$-: -100+ equity:conversion:$-:$ $135.00++ The equity account names will be "equity:conversion:A-B:A" and "eq-+ uity:conversion:A-B:B" where A is the alphabetically first commodity+ symbol. You can customise the "equity:conversion" part by declaring an+ account with the V/Conversion account type.++ Combining costs and equity conversion postings+ Finally, you can use both the @/@@ cost notation and equity postings at+ the same time. This in theory gives the best of all worlds - preserv-+ ing the accounting equation, revealing the per-unit cost basis, and+ providing more flexibility in how you write the entry:++ Variant 5++ 2022-01-01 one hundred euros purchased at $1.35 each+ assets:dollars $-135+ equity:conversion $135+ equity:conversion -100+ assets:euros 100 @ $1.35++ All the other variants above can (usually) be rewritten to this final+ form with:++ $ hledger print -x --infer-costs --infer-equity++ Downsides:++ o The precise format of the journal entry becomes more important. If+ hledger can't detect and match up the cost and equity postings, it+ will give a transaction balancing error.++ o The add command does not yet accept this kind of entry (#2056).++ o This is the most verbose form.++ Requirements for detecting equity conversion postings+ --infer-costs has certain requirements (unlike --infer-equity, which+ always works). It will infer costs only in transactions with:++ o Two non-equity postings, in different commodities. Their order is+ significant: the cost will be added to the first of them.++ o Two postings to equity conversion accounts, next to one another,+ which balance the two non-equity postings. This balancing is checked+ to the same precision (number of decimal places) used in the conver-+ sion posting's amount. Equity conversion accounts are:++ o any accounts declared with account type V/Conversion, or their sub-+ accounts++ o otherwise, accounts named equity:conversion, equity:trade, or eq-+ uity:trading, or their subaccounts.++ And multiple such four-posting groups can coexist within a single+ transaction. When --infer-costs fails, it does not infer a cost in+ that transaction, and does not raise an error (ie, it infers costs+ where it can).++ Reading variant 5 journal entries, combining cost notation and equity+ postings, has all the same requirements. When reading such an entry+ fails, hledger raises an "unbalanced transaction" error.++ Infer cost and equity by default ?+ Should --infer-costs and --infer-equity be enabled by default ? Try+ using them always, eg with a shell alias:++ alias h="hledger --infer-equity --infer-costs"++ and let us know what problems you find.++Value reporting+ Instead of reporting amounts in their original commodity, hledger can+ convert them to cost/sale amount (using the conversion rate recorded in+ the transaction), and/or to market value (using some market price on a+ certain date). This is controlled by the --value=TYPE[,COMMODITY] op-+ tion, which will be described below. We also provide the simpler -V+ 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+ Market prices can change from day to day. hledger will use the prices+ on a particular valuation date (or on more than one date). By default+ hledger uses "end" dates for valuation. More specifically:++ o For single period reports (including normal print and register re-+ ports):++ o If an explicit report end date is specified, that is used++ o Otherwise the latest transaction date or P directive date is used+ (even if it's in the future)++ o For multiperiod reports, each period is valued on its last day.++ This can be customised with the --value option described below, which+ can select either "then", "end", "now", or "custom" dates. (Note, this+ has a bug in hledger-ui <=1.31: turning on valuation with the V key al-+ ways resets it to "end".)++ Finding market price+ To convert a commodity A to its market value in another commodity B,+ hledger looks for a suitable market price (exchange rate) as follows,+ 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-prices flag) inferred from costs.++ 2. A reverse market price: the inverse of a declared or inferred market+ price from B to A.++ 3. A forward chain of market prices: a synthetic price formed by com-+ 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-prices: 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 costs as additional market prices (as+ Ledger does) ? Adding the --infer-market-prices flag to -V, -X or+ --value enables this.++ So for example, hledger bs -V --infer-market-prices will get market+ prices both from P directives and from transactions. 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 Value reporting section carefully, and try adding+ --debug or --debug=2 to troubleshoot.++ --infer-market-prices can infer market prices from:++ o multicommodity transactions with explicit prices (@/@@)++ o multicommodity transactions with implicit prices (no @, two commodi-+ ties, unbalanced). (With these, the order of postings matters.+ hledger print -x can be useful for troubleshooting.)++ o multicommodity transactions with equity postings, if cost is inferred+ with --infer-costs.++ There is a limitation (bug) currently: when a valuation commodity is+ not specified, prices inferred with --infer-market-prices do not help+ select a default valuation commodity, as P prices would. So conversion+ might not happen because no valuation commodity was detected (--debug=2+ will show this). To be safe, specify the valuation commmodity, eg:++ o -X EUR --infer-market-prices, not -V --infer-market-prices++ o --value=then,EUR --infer-market-prices, not --value=then --infer-mar-+ ket-prices++ Signed costs and market prices can be confusing. For reference, here+ is the current behaviour, since hledger 1.25. (If you think it should+ work differently, see #1870.)++ 2022-01-01 Positive Unit prices+ a A 1+ b B -1 @ A 1++ 2022-01-01 Positive Total prices+ a A 1+ b B -1 @@ A 1+++ 2022-01-02 Negative unit prices+ a A 1+ b B 1 @ A -1++ 2022-01-02 Negative total prices+ a A 1+ b B 1 @@ A -1+++ 2022-01-03 Double Negative unit prices+ a A -1+ b B -1 @ A -1++ 2022-01-03 Double Negative total prices+ a A -1+ b B -1 @@ A -1++ All of the transactions above are considered balanced (and on each day,+ the two transactions are considered equivalent). Here are the market+ prices inferred for B:++ $ hledger -f- --infer-market-prices prices+ P 2022-01-01 B A 1+ P 2022-01-01 B A 1.0+ P 2022-01-02 B A -1+ P 2022-01-02 B A -1.0+ P 2022-01-03 B A -1+ P 2022-01-03 B A -1.0++ 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-prices flag is used: the price commodity from the+ latest transaction-inferred price for A on or before valuation date.++ This means:++ o If you have P directives, they determine which commodities -V will+ convert, and to what.++ o If you have no P directives, and use the --infer-market-prices flag,+ costs determine it.++ Amounts for which no valuation commodity can be found are not con-+ verted.++ --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.++ Valuation examples+ Here are some quick examples of -V:++ ; one euro is worth this many dollars from nov 1+ P 2016/11/01 $1.10++ ; purchase some euros on nov 3+ 2016/11/3+ assets:euros 100+ assets:checking++ ; the euro is worth fewer dollars by dec 21+ P 2016/12/21 $1.03++ How many euros do I have ?++ $ hledger -f t.j bal -N euros+ 100 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++ 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++ Interaction of valuation and queries+ When matching postings based on queries in the presence of valuation,+ the following happens:++ 1. The query is separated into two parts:++ 1. the currency (cur:) or amount (amt:).++ 2. all other parts.++ 2. The postings are matched to the currency and amount queries based on+ pre-valued amounts.++ 3. Valuation is applied to the postings.++ 4. The postings are matched to the other parts of the query based on+ post-valued amounts.++ Related: #1625++ Effect of valuation on reports+ Here is a reference for how valuation is supposed to affect each part+ of hledger's reports. (It's wide, you may need to scroll sideways.)+ It may be useful when troubleshooting. If you find problems, please+ report them, ideally with a reproducible example. Related: #329,+ #1083.++ First, a quick 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).++ Report -B, --cost -V, -X --value=then --value=end --value=DATE,+ type --value=now+ --------------------------------------------------------------------------------------------+ print+ posting cost value at re- value at posting value at re- value at+ amounts port end or date port or DATE/today+ today journal end+ balance unchanged unchanged unchanged unchanged unchanged+ asser-+ tions/as-+ signments++ register+ starting cost value at re- valued at day value at re- value at+ balance port or each historical port or DATE/today+ (-H) journal end posting was made journal end+ starting cost value at day valued at day value at day value at+ balance before re- each historical before re- DATE/today+ (-H) with port or posting was made port or+ report journal journal+ interval start start+ posting cost value at re- value at posting value at re- value at+ amounts port or date port or DATE/today+ journal end journal end+ summary summarised value at pe- sum of postings value at pe- value at+ posting cost riod ends in interval, val- riod ends DATE/today+ amounts ued at interval+ with re- start+ port in-+ terval+ running sum/average sum/average sum/average of sum/average sum/average+ total/av- of displayed of displayed displayed values of displayed of displayed+ erage values values values values++ balance+ (bs, bse,+ cf, is)+ balance sums of value at re- value at posting value at re- value at+ changes costs port end or date port or DATE/today of+ 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+ (--bud-+ get)+ grand to- sum of dis- sum of dis- sum of displayed sum of dis- sum of dis-+ tal played val- played val- valued played val- played values+ ues ues ues++ balance+ (bs, bse,+ cf, is)+ with re-+ port in-+ terval+ starting sums of value at re- sums of values of value at re- sums of post-+ balances costs of port start postings before port start ings before+ (-H) postings be- of sums of report start at of sums of report start+ fore report all postings respective post- all postings+ start before re- ing dates before re-+ port start port start+ balance sums of same as sums of values of balance value at+ changes costs of --value=end postings in pe- change in DATE/today of+ (bal, is, postings in riod at respec- each period, sums of post-+ bs period tive posting valued at ings+ --change, dates period ends+ cf+ --change)+ end bal- sums of same as sums of values of period end value at+ ances costs of --value=end postings from be- balances, DATE/today of+ (bal -H, postings fore period start valued at sums of post-+ is --H, from before to period end at period ends ings+ bs, cf) report start respective post-+ to period ing dates+ end+ budget like balance like balance like balance like bal- like balance+ amounts changes/end changes/end changes/end bal- ances changes/end+ (--bud- balances balances ances balances+ get)+ row to- sums, aver- sums, aver- sums, averages of sums, aver- sums, aver-+ tals, row ages of dis- ages of dis- displayed values ages of dis- ages of dis-+ averages played val- played val- played val- played values+ (-T, -A) ues ues ues+ column sums of dis- sums of dis- sums of displayed sums of dis- sums of dis-+ totals played val- played val- values played val- played values+ ues ues ues+ grand to- sum, average sum, average sum, average of sum, average sum, average+ tal, of column of column column totals of column of column to-+ grand av- totals totals totals tals+ erage+++ --cumulative is omitted to save space, it works like -H but with a zero+ starting balance.++PART 4: COMMANDS+ Commands overview+ Here are the built-in commands:++ DATA ENTRY+ These data entry commands are the only ones which can modify your jour-+ nal file.++ o add - add transactions using terminal prompts++ o import - add new transactions from other files, eg CSV files++ DATA CREATION+ o close - generate balance-zeroing/restoring transactions++ o rewrite - generate auto postings, like print --auto++ DATA MANAGEMENT+ o check - check for various kinds of error in the data++ o diff - compare account transactions in two journal files++ REPORTS, FINANCIAL+ 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++ REPORTS, VERSATILE+ o balance (bal) - show balance changes, end balances, budgets, gains..++ o print - show transactions or export journal data++ o register (reg) - show postings in one or more accounts & running to-+ tal++ o roi - show return on investments++ REPORTS, BASIC+ o accounts - show account names++ o activity - show bar charts of posting counts per period++ o codes - show transaction codes++ o commodities - show commodity/currency symbols++ o descriptions - show transaction descriptions++ o files - show input file paths++ o notes - show note parts of transaction descriptions++ o payees - show payee parts of transaction descriptions++ o prices - show market prices++ o stats - show journal statistics++ o tags - show tag names++ o test - run self tests++ HELP+ o help - show the hledger manual with info/man/pager++ o demo - show small hledger demos in the terminal++ ADD-ONS+ And here are some typical add-on commands. Some of these are installed+ by the hledger-install script. If installed, they will appear in+ hledger's commands list:++ o ui - run hledger's terminal UI++ o web - run hledger's web UI++ o iadd - add transactions using a TUI (currently hard to build)++ o interest - generate interest transactions++ o stockquotes - download market prices from AlphaVantage++ o Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,+ pijul, plot, and more..++ Next, each command is described in detail, in alphabetical order.++ accounts+ Show account names.++ This command lists account names. By default it shows all known ac-+ counts, either used in transactions or declared with account direc-+ tives.++ With query arguments, only matched account names and account names ref-+ erenced by matched postings are shown.++ Or it can show just the used accounts (--used/-u), the declared ac-+ counts (--declared/-d), the accounts declared but not used (--unused),+ the accounts used but not declared (--undeclared), or the first account+ matched by an account name pattern, if any (--find).++ It shows a flat list by default. With --tree, it uses indentation to+ show the account hierarchy. In flat mode you can add --drop N to omit+ the first few account name components. Account names can be+ depth-clipped with depth:N or --depth N or -N.++ With --types, it also shows each account's type, if it's known. (See+ Declaring accounts > Account types.)++ With --positions, it also shows the file and line number of each ac-+ count's declaration, if any, and the account's overall declaration or-+ der; these may be useful when troubleshooting account display order.++ With --directives, it adds the account keyword, showing valid account+ directives which can be pasted into a journal file. This is useful to-+ gether with --undeclared when updating your account declarations to+ satisfy hledger check accounts.++ The --find flag can be used to look up a single account name, in the+ same way that the aregister command does. It returns the alphanumeri-+ cally-first matched account name, or if none can be found, it fails+ with a non-zero exit code.++ Examples:++ $ hledger accounts+ assets:bank:checking+ assets:bank:saving+ assets:cash+ expenses:food+ expenses:supplies+ income:gifts+ income:salary+ liabilities:debts++ $ hledger accounts --undeclared --directives >> $LEDGER_FILE+ $ hledger check accounts++ 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+ 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 main journal file (which should be in+ journal format). Existing transactions are not changed. This is one+ of the few hledger commands that writes to the journal file (see also+ import).++ To use it, just run hledger add and follow the prompts. You can add as+ many transactions as you like; when you are finished, enter . or press+ control-d or control-c to exit.++ Features:++ o add tries to provide useful defaults, using the most similar (by de-+ scription) recent transaction (filtered by the query, if any) as a+ template.++ o You can also set the initial defaults with command line arguments.++ o Readline-style edit keys can be used during data entry.++ o The tab key will auto-complete whenever possible - accounts, pay-+ ees/descriptions, dates (yesterday, today, tomorrow). If the input+ area is empty, it will insert the default value.++ o If the journal defines a default commodity, it will be added to any+ 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 https://hledger.org/add.html for a detailed tutorial):++ $ 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> $++ If you enter a number with no commodity symbol, and you have declared a+ default commodity with a D directive, you might expect add to add this+ symbol for you. It does not do this; we assume that if you are using a+ D directive you prefer not to see the commodity symbol repeated on+ amounts in the journal.++ aregister+ (areg)++ Show the transactions and running historical balance of a single ac-+ count, with each transaction displayed as one line.++ aregister shows the overall transactions affecting a particular account+ (and any subaccounts). Each report line represents one transaction in+ this account. Transactions before the report start date are always in-+ cluded in the running balance (--historical mode is always on).++ This is a more "real world", bank-like view than the register command+ (which shows individual postings, possibly from multiple accounts, not+ necessarily in historical mode). As a quick rule of thumb: - use areg-+ ister for reviewing and reconciling real-world asset/liability accounts+ - use register for reviewing detailed revenues/expenses.++ aregister requires one argument: the account to report on. You can+ write either the full account name, or a case-insensitive regular ex-+ pression which will select the alphabetically first matched account.++ When there are multiple matches, the alphabetically-first choice can be+ surprising; eg if you have assets:per:checking 1 and assets:biz:check-+ ing 2 accounts, hledger areg checking would select assets:biz:checking+ 2. It's just a convenience to save typing, so if in doubt, write the+ full account name, or a distinctive substring that matches uniquely.++ 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.++ For performance reasons, column widths are chosen based on the first+ 1000 lines; this means unusually wide values in later lines can cause+ visual discontinuities as column widths are adjusted. If you want to+ ensure perfect alignment, at the cost of more time and memory, use the+ --align-all flag.++ This command also supports the output destination and output format op-+ tions. The output formats supported are txt, csv, tsv (Added in 1.32),+ and json.++ aregister and posting dates+ aregister always shows one line (and date and amount) per transaction.+ But sometimes transactions have postings with different dates. Also,+ not all of a transaction's postings may be within the report period.+ To resolve this, aregister shows the earliest of the transaction's date+ and posting dates that is in-period, and the sum of the in-period post-+ ings. In other words it will show a combined line item with just the+ earliest date, and the running balance will (temporarily, until the+ transaction's last posting) be inaccurate. Use register -H if you need+ to see the individual postings.++ There is also a --txn-dates flag, which filters strictly by transaction+ date, ignoring posting dates. This too can cause an inaccurate running+ 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)++ o or unrealised capital gain/loss (--gain)++ o or balance changes from sibling postings (--related/-r)++ o or postings count (--count)++ ..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 (--in-+ vert)++ o rows and columns swapped (--transpose)++ o another field used as account name (--pivot)++ o custom-formatted line items (single-period reports only) (--format)++ o commodities displayed on the same line or multiple lines (--layout)++ This command supports the output destination and output format options,+ with output formats txt, csv, tsv (Added in 1.32), json, and (multi-pe-+ riod reports only:) html. In txt output in a colour-supporting termi-+ nal, 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. ("Simple" here+ means just one column of numbers, covering a single period. You can+ also have multi-period reports, described later.)++ For real-world accounts, these numbers will normally be their end bal-+ ance 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 -f examples/sample.journal bal+ $1 assets:bank:saving+ $-2 assets:cash+ $1 expenses:food+ $1 expenses:supplies+ $-1 income:gifts+ $-1 income:salary+ $1 liabilities:debts+ --------------------+ 0++ Accounts with a zero balance (and no non-zero subaccounts, in tree mode+ - see below) are hidden by default. Use -E/--empty to show them (re-+ vealing 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.++ Balance report line format+ 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 -f examples/sample.journal 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 specifies the formatting applied to each ac-+ count/balance pair. It may contain any suitable text, with data fields+ interpolated like so:++ %[MIN][.MAX](FIELDNAME)++ o MIN pads with spaces to at least this width (optional)++ o MAX truncates at this width (optional)++ o FIELDNAME must be enclosed in parentheses, and can be one of:++ o depth_spacer - a number of spaces equal to the account's depth, or+ if MIN is specified, MIN * depth spaces.++ o account - the account's name++ o total - the account's balance/posted total, right justified++ Also, FMT can begin with an optional prefix to control how multi-com-+ modity amounts are rendered:++ o %_ - render on multiple lines, bottom-aligned (the default)++ o %^ - render on multiple lines, top-aligned++ o %, - render on one line, comma-separated++ There are some quirks. Eg in one-line mode, %(depth_spacer) has no ef-+ fect, instead %(account) has indentation built in. Experimentation+ may be needed to get pleasing results.++ Some example formats:++ o %(total) - the account's total++ o %-20.20(account) - the account's name, left justified, padded to 20+ characters and clipped at 20 characters++ o %,%-50(account) %25(total) - account name padded to 50 characters,+ total padded to 20 characters, with multiple commodities rendered on+ one line++ o %20(total) %2(depth_spacer)%-(account) - the default format for the+ single-column balance report++ 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 -f examples/sample.journal 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 -f examples/sample.journal balance+ $-1 assets+ $1 bank:saving+ $-2 cash+ $2 expenses+ $1 food+ $1 supplies+ $-2 income+ $-1 gifts+ $-1 salary+ $1 liabilities:debts+ --------------------+ 0++ 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:NUM query, or --depth NUM option, or just -NUM (eg: -3)+ balance reports will show accounts only to the specified depth, hiding+ the deeper subaccounts. This can be useful for getting an overview+ without too much detail.++ Account balances at the depth limit always include the balances from+ any deeper subaccounts (even in list mode). Eg, limiting to depth 1:++ $ hledger -f examples/sample.journal balance -1+ $-1 assets+ $2 expenses+ $-2 income+ $1 liabilities+ --------------------+ 0++ Dropping top-level accounts+ You can also hide one or more top-level account name parts, using+ --drop NUM. This can be useful for hiding repetitive top-level account+ names:++ $ hledger -f examples/sample.journal bal expenses --drop 1+ $1 food+ $1 supplies+ --------------------+ $2++ Showing declared accounts+ With --declared, accounts which have been declared with an account di-+ rective will be included in the balance report, even if they have no+ transactions. (Since they will have a zero balance, you will also need+ -E/--empty to see them.)++ More precisely, leaf declared accounts (with no subaccounts) will be+ included, since those are usually the more useful in reports.++ The idea of this is to be able to see a useful "complete" balance re-+ port, even when you don't have transactions in all of your declared ac-+ counts yet.++ Sorting by amount+ With -S/--sort-amount, accounts with the largest (most positive) bal-+ ances are shown first. Eg: hledger bal expenses -MAS shows your+ biggest averaged monthly expenses first. When more than one commodity+ is present, they will be sorted by the alphabetically earliest commod-+ ity first, and then by subsequent commodities (if an amount is missing+ a commodity, it is treated as 0).++ Revenues and liability balances are typically negative, however, so -S+ shows these in reverse order. To work around this, you can add --in-+ vert to flip the signs. (Or, use one of the higher-level reports,+ 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.++ 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:++ 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 -f examples/sample.journal bal --quarterly income expenses -E+ Balance changes in 2008:++ || 2008q1 2008q2 2008q3 2008q4+ ===================++=================================+ expenses:food || 0 $1 0 0+ expenses:supplies || 0 $1 0 0+ income:gifts || 0 $-1 0 0+ income:salary || $-1 0 0 0+ -------------------++---------------------------------+ || $-1 $1 0 0++ 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.++ 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 Filter to a single currency with cur:++ o Convert to a single currency with -V [--infer-market-price]++ o Use a more compact layout like --layout=bare++ 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++ 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 ac-+ count during some period.++ An end balance is the amount accumulated in an account as of some date+ (and some time, but hledger doesn't store that; assume end of day in+ 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+ The balance command is quite flexible; here is the full detail on how+ to control what it reports. If the following seems complicated, don't+ worry - this is for advanced reporting, and it does take time and ex-+ perimentation to get familiar with all the report modes.++ There are three important option groups:++ hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]+ ...++ Calculation type+ The basic calculation to perform for each table cell. It is one of:++ o --sum : sum the posting amounts (default)++ o --budget : sum the amounts, but also show the budget goal amount (for+ each account/period)++ o --valuechange : show the change in period-end historical balance val-+ ues (caused by deposits, withdrawals, and/or market price fluctua-+ tions)++ o --gain : show the unrealised capital gain/loss, (the current valued+ balance minus each amount's original cost)++ o --count : show the count of postings++ Accumulation type+ How amounts should accumulate across a report's subperiods/columns.+ Another way to say it: which time period's postings should contribute+ to each cell's calculation. It is one of:++ o --change : calculate with postings from column start to column end,+ ie "just this column". Typically used to see revenues/expenses.+ (default for balance, cashflow, incomestatement)++ o --cumulative : calculate with postings from report start to column+ end, ie "previous columns plus this column". Typically used to show+ changes accumulated since the report's start date. Not often used.++ o --historical/-H : calculate with postings from journal start to col-+ umn end, ie "all postings from before report start date until this+ column's end". Typically used to see historical end balances of as-+ sets/liabilities/equity. (default for balancesheet, balancesheete-+ quity)++ Valuation type+ Which kind of value or cost conversion should be applied, if any, be-+ fore displaying the report. It is one of:++ o no valuation type : don't convert to cost or value (default)++ o --value=cost[,COMM] : convert amounts to cost (then optionally to+ some other commodity)++ o --value=then[,COMM] : convert amounts to market value on transaction+ dates++ o --value=end[,COMM] : convert amounts to market value on period end+ date(s)+ (default with --valuechange, --gain)++ o --value=now[,COMM] : convert amounts to market value on today's date++ o --value=YYYY-MM-DD[,COMM] : convert amounts to market value on an-+ other date++ or one of the equivalent simpler flags:++ o -B/--cost : like --value=cost (though, note --cost and --value are+ independent options which can both be used at once)++ o -V/--market : like --value=end++ o -X COMM/--exchange COMM : like --value=end,COMM++ See Cost reporting and Value reporting for more about these.++ Combining balance report types+ Most combinations of these options should produce reasonable reports,+ but if you find any that seem wrong or misleading, let us know. The+ 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=+ tion:> YYYY-MM-DD+ Accumu- /now+ lation:v+ -----------------------------------------------------------------------------------+ --change change in period sum of post- period-end DATE-value of+ ing-date market value of change change in pe-+ values in period in period riod+ --cumu- change from re- sum of post- period-end DATE-value of+ lative port start to ing-date market value of change change from+ period end values from re- from report report start+ port start to pe- start to period to period end+ riod end end+ --his- change from sum of post- period-end DATE-value of+ torical journal start to ing-date market value of change change from+ /-H period end (his- values from jour- from journal journal start+ torical end bal- nal start to pe- start to period to period end+ ance) riod end end++ Budget report+ The --budget report type is like a regular balance report, but with two+ main differences:++ o Budget goals and performance percentages are also shown, in brackets++ o Accounts which don't have budget goals are hidden by default.++ This is useful for comparing planned and actual income, expenses, time+ usage, etc.++ Periodic transaction rules are used to define budget goals. For exam-+ ple, here's a periodic rule defining monthly goals for bus travel and+ food expenses:++ ;; Budget+ ~ monthly+ (expenses:bus) $30+ (expenses:food) $400++ After recording some actual expenses,++ ;; Two months worth of expenses+ 2017-11-01+ income $-1950+ expenses:bus $35+ expenses:food:groceries $310+ expenses:food:dining $42+ expenses:movies $38+ assets:bank:checking++ 2017-12-01+ income $-2100+ expenses:bus $53+ expenses:food:groceries $380+ expenses:food:dining $32+ expenses:gifts $100+ assets:bank:checking++ we can see a budget report like this:++ $ hledger bal -M --budget+ Budget performance in 2017-11-01..2017-12-31:++ || Nov Dec+ ===============++============================================+ <unbudgeted> || $-425 $-565+ expenses || $425 [ 99% of $430] $565 [131% of $430]+ expenses:bus || $35 [117% of $30] $53 [177% of $30]+ expenses:food || $352 [ 88% of $400] $412 [103% of $400]+ ---------------++--------------------------------------------+ || 0 [ 0% of $430] 0 [ 0% of $430]++ This is "goal-based budgeting"; you define goals for accounts and peri-+ ods, often recurring, and hledger shows performance relative to the+ goals. This contrasts with "envelope budgeting", which is more de-+ tailed and strict - useful when cash is tight, but also quite a bit+ more work. https://plaintextaccounting.org/Budgeting has more on this+ topic.++ Using the budget report+ Historically this report has been confusing and fragile. hledger's+ version should be relatively robust and intuitive, but you may still+ find surprises. Here are more notes to help with learning and trou-+ bleshooting.++ o In the above example, expenses:bus and expenses:food are shown be-+ cause they have budget goals during the report period.++ o Their parent expenses is also shown, with budget goals aggregated+ from the children.++ o The subaccounts expenses:food:groceries and expenses:food:dining are+ not shown since they have no budget goal of their own, but they con-+ tribute to expenses:food's actual amount.++ o Unbudgeted accounts expenses:movies and expenses:gifts are also not+ shown, but they contribute to expenses's actual amount.++ o The other unbudgeted accounts income and assets:bank:checking are+ grouped as <unbudgeted>.++ o --depth or depth: can be used to limit report depth in the usual way+ (but will not reveal unbudgeted subaccounts).++ o Amounts are always inclusive of subaccounts (even in -l/--list mode).++ o Numbers displayed in a --budget report will not always agree with the+ totals, because of hidden unbudgeted accounts; this is normal.+ -E/--empty can be used to reveal the hidden accounts.++ o In the periodic rules used for setting budget goals, unbalanced post-+ ings are convenient.++ o You can filter budget reports with the usual queries, eg to focus on+ particular accounts. It's common to restrict them to just expenses.+ (The <unbudgeted> account is occasionally hard to exclude; this is+ because of date surprises, discussed below.)++ o When you have multiple currencies, you may want to convert them to+ one (-X COMM --infer-market-prices) and/or show just one at a time+ (cur:COMM). If you do need to show multiple currencies at once,+ --layout bare can be helpful.++ o You can "roll over" amounts (actual and budgeted) to the next period+ with --cumulative.++ See also: https://hledger.org/budgeting.html.++ Budget date surprises+ With small data, or when starting out, some of the generated budget+ goal transaction dates might fall outside the report periods. Eg with+ the following journal and report, the first period appears to have no+ expenses:food budget. (Also the <unbudgeted> account should be ex-+ cluded by the expenses query, but isn't.):++ ~ monthly in 2020+ (expenses:food) $500++ 2020-01-15+ expenses:food $400+ assets:checking++ $ hledger bal --budget expenses+ Budget performance in 2020-01-15:++ || 2020-01-15+ ===============++====================+ <unbudgeted> || $400+ expenses:food || 0 [ 0% of $500]+ ---------------++--------------------+ || $400 [80% of $500]++ In this case, the budget goal transactions are generated on first days+ of of month (this can be seen with hledger print --forecast tag:gener-+ ated expenses). Whereas the report period defaults to just the 15th+ day of january (this can be seen from the report table's column head-+ ings).++ To fix this kind of thing, be more explicit about the report period+ (and/or the periodic rules' dates). In this case, adding -b 2020 does+ the trick.++ Selecting budget goals+ By default, the budget report uses all available periodic transaction+ rules to generate goals. This includes rules with a different report+ interval from your report. Eg if you have daily, weekly and monthly+ periodic rules, all of these will contribute to the goals in a monthly+ budget report.++ You can select a subset of periodic rules by providing an argument to+ the --budget flag. --budget=DESCPAT will match all periodic rules+ whose description contains DESCPAT, a case-insensitive substring (not a+ regular expression or query). This means you can give your periodic+ rules descriptions (remember that two spaces are needed between period+ expression and description), and then select from multiple budgets de-+ fined in your journal.++ Budgeting vs forecasting+ --forecast and --budget both use the periodic transaction rules in the+ journal to generate temporary transactions for reporting purposes.+ However they are separate features - though you can use both at the+ same time if you want. Here are some differences between them:++ --forecast --budget+ --------------------------------------------------------------------------+ is a general option; it enables fore- is a balance command option; it+ casting with all reports selects the balance report's+ budget mode+ generates visible transactions which generates invisible transactions+ appear in reports which produce goal amounts+ generates forecast transactions from generates budget goal transac-+ after the last regular transaction, to tions throughout the report pe-+ the end of the report period; or with riod, optionally restricted by+ an argument --forecast=PERIODEXPR gen- periods specified in the peri-+ erates them throughout the specified odic transaction rules+ period, both optionally restricted by+ periods specified in the periodic+ transaction rules+ uses all periodic rules uses all periodic rules; or with+ an argument --budget=DESCPAT+ uses just the rules matched by+ DESCPAT++ Balance report layout+ The --layout option affects how balance reports show multi-commodity+ amounts and commodity symbols, which can improve readability. It can+ also normalise the data for easy consumption by other programs. It has+ four possible values:++ o --layout=wide[,WIDTH]: commodities are shown on a single line, op-+ tionally elided to WIDTH++ o --layout=tall: each commodity is shown on a separate line++ o --layout=bare: commodity symbols are in their own column, amounts are+ bare numbers++ o --layout=tidy: data is normalised to easily-consumed "tidy" form,+ with one row per data value++ Here are the --layout modes supported by each output format Only CSV+ output supports all of them:++ - txt csv html json sql+ -------------------------------------+ wide Y Y Y+ tall Y Y Y+ bare Y Y Y+ tidy Y++ Examples:++ Wide layout+ With many commodities, reports can be very wide:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide+ Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total+ ==================++====================================================================================================================================================================================================================+ Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT+ ------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT++ A width limit reduces the width, but some commodities will be hidden:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32+ Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total+ ==================++===========================================================================================================================+ Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..+ ------------------++---------------------------------------------------------------------------------------------------------------------------+ || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..++ Tall layout+ Each commodity gets a new line (may be different in each column), and+ account names are repeated:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall+ Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total+ ==================++==================================================+ Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD+ Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT+ Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD+ Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA+ Assets:US:ETrade || 18.00 VHT 294.00 VHT+ ------------------++--------------------------------------------------+ || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD+ || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT+ || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD+ || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA+ || 18.00 VHT 294.00 VHT++ Bare layout+ Commodity symbols are kept in one column, each commodity has its own+ row, amounts are bare numbers, account names are repeated:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare+ Balance changes in 2012-01-01..2014-12-31:++ || Commodity 2012 2013 2014 Total+ ==================++=============================================+ Assets:US:ETrade || GLD 0 70.00 0 70.00+ Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00+ Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50+ Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00+ Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00+ ------------------++---------------------------------------------+ || GLD 0 70.00 0 70.00+ || ITOT 10.00 18.00 -11.00 17.00+ || USD 337.18 -98.12 4881.44 5120.50+ || VEA 12.00 10.00 14.00 36.00+ || VHT 106.00 18.00 170.00 294.00++ Bare layout also affects CSV output, which is useful for producing data+ that is easier to consume, eg for making charts:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare+ "account","commodity","balance"+ "Assets:US:ETrade","GLD","70.00"+ "Assets:US:ETrade","ITOT","17.00"+ "Assets:US:ETrade","USD","5120.50"+ "Assets:US:ETrade","VEA","36.00"+ "Assets:US:ETrade","VHT","294.00"+ "total","GLD","70.00"+ "total","ITOT","17.00"+ "total","USD","5120.50"+ "total","VEA","36.00"+ "total","VHT","294.00"++ Bare layout will sometimes display an extra row for the no-symbol com-+ modity, because of zero amounts (hledger treats zeroes as commod-+ ity-less, usually). This can break hledger-bar confusingly+ (workaround: add a cur: query to exclude the no-symbol row).++ Tidy layout+ This produces normalised "tidy data" (see+ https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)+ where every variable has its own column and each row represents a sin-+ gle data point. This is the easiest kind of data for other software to+ consume:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy+ "account","period","start_date","end_date","commodity","value"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","GLD","0"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","ITOT","10.00"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","USD","337.18"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","VEA","12.00"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","VHT","106.00"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","GLD","70.00"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","ITOT","18.00"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","USD","-98.12"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","VEA","10.00"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","VHT","18.00"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","GLD","0"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","ITOT","-11.00"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","USD","4881.44"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VEA","14.00"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"++ Some 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++ 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.++ This report shows accounts declared with the Asset, Cash or Liability+ type (see account types). Or if no such accounts are declared, it+ shows top-level accounts named asset or liability (case insensitive,+ plurals allowed) and their subaccounts.++ Example:++ $ hledger balancesheet+ Balance Sheet 2008-12-31++ || 2008-12-31+ ====================++============+ Assets ||+ --------------------++------------+ assets:bank:saving || $1+ assets:cash || $-2+ --------------------++------------+ || $-1+ ====================++============+ Liabilities ||+ --------------------++------------+ liabilities:debts || $-1+ --------------------++------------+ || $-1+ ====================++============+ Net: || 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 op-+ tions The output formats supported are txt, csv, tsv (Added in 1.32),+ html, and json.++ 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.++ This report shows accounts declared with the Asset, Cash, Liability or+ Equity type (see account types). Or if no such accounts are declared,+ it shows top-level accounts named asset, liability or equity (case in-+ sensitive, plurals allowed) and their subaccounts.++ Example:++ $ hledger balancesheetequity+ Balance Sheet With Equity 2008-12-31++ || 2008-12-31+ ====================++============+ Assets ||+ --------------------++------------+ assets:bank:saving || $1+ assets:cash || $-2+ --------------------++------------+ || $-1+ ====================++============+ Liabilities ||+ --------------------++------------+ liabilities:debts || $-1+ --------------------++------------+ || $-1+ ====================++============+ Equity ||+ --------------------++------------+ --------------------++------------+ || 0+ ====================++============+ Net: || 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 report is the easiest way to see if the accounting equation (A+L+E+ = 0) is satisfied (after you have done a close --retain to merge rev-+ enues and expenses with equity, and perhaps added --infer-equity to+ balance your commodity conversions).++ This command also supports the output destination and output format op-+ tions The output formats supported are txt, csv, tsv, html, and json.++ cashflow+ (cf)++ This command displays a (simple) cashflow statement, showing the in-+ flows and outflows affecting "cash" (ie, liquid, easily convertible)+ assets. Amounts are shown with normal positive sign, as in conven-+ tional financial statements.++ This report shows accounts declared with the Cash type (see account+ types). Or if no such accounts are declared, it shows accounts++ o under a top-level account named asset (case insensitive, plural al-+ lowed)++ o whose name contains some variation of cash, bank, checking or saving.++ More precisely: all accounts matching this case insensitive regular ex-+ pression:++ ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)++ and their subaccounts.++ An example cashflow report:++ $ hledger cashflow+ Cashflow Statement 2008++ || 2008+ ====================++======+ Cash flows ||+ --------------------++------+ assets:bank:saving || $1+ assets:cash || $-2+ --------------------++------+ || $-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 op-+ tions The output formats supported are txt, csv, tsv (Added in 1.32),+ html, and json.++ 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++ If you are an Emacs user, you can also configure flycheck-hledger to+ run these checks, providing instant feedback as you edit the journal.++ Here are the checks currently available:++ Default checks+ These checks are run automatically by (almost) all hledger commands:++ o parseable - data files are in a supported format, with no syntax er-+ rors and no invalid include directives.++ o autobalanced - all transactions are balanced, after converting to+ cost. Missing amounts and missing costs are inferred automatically+ where possible.++ o assertions - all balance assertions in the journal are passing.+ (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 balanced - all transactions are balanced after converting to cost,+ without inferring missing costs. If conversion costs are required,+ they must be explicit.++ o accounts - all account names used by transactions have been declared++ o commodities - all commodity symbols used have been declared++ Other checks+ These checks can be run only by giving their names as arguments to+ check. They are more specialised and not desirable for everyone:++ o ordereddates - transactions are ordered by date within each file++ o payees - all payees used by transactions have been declared++ o recentassertions - all accounts with balance assertions have a bal-+ ance assertion within 7 days of their latest posting++ o tags - all tags used by transactions have been declared++ o uniqueleafnames - all account leaf names are unique++ Custom checks+ A few more checks are are available as separate add-on commands, in+ 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.++ More about specific checks+ hledger check recentassertions will complain if any balance-asserted+ account has postings more than 7 days after its latest balance asser-+ tion. This aims to prevent the situation where you are regularly up-+ dating your journal, but forgetting to check your balances against the+ real world, then one day must dig back through months of data to find+ an error. It assumes that adding a balance assertion requires/reminds+ you to check the real-world balance. (That may not be true if you+ auto-generate balance assertions from bank data; in that case, I recom-+ mend to import transactions uncleared, and when you manually review and+ clear them, also check the latest assertion against the real-world bal-+ ance.)++ close+ (equity)++ close generates several kinds of "closing" and/or "opening" transac-+ tions, useful in certain situations, including migrating balances to a+ new journal file, retaining earnings into equity, consolidating bal-+ ances, or viewing lots. Like print, it prints valid journal entries.+ You can append or copy these to your journal file(s) when you are happy+ with how they look.++ close currently has six modes, selected by a single mode flag:++ close --migrate+ This is the most common mode. It prints a "closing balances" transac-+ tion that zeroes out all asset and liability balances (by default), and+ an opposite "opening balances" transaction that restores them again.+ The balancing account will be equity:opening/closing balances (or an-+ other specified by --close-acct or --open-acct).++ This is useful when migrating balances to a new journal file at the+ start of a new year. Essentially, you run hledger close --mi-+ grate=NEWYEAR -e NEWYEAR and then copy the closing transaction to the+ end of the old file and the opening transaction to the start of the new+ file. The opening transaction sets correct starting balances in the+ new file when it is used alone, and the closing transaction keeps bal-+ ances correct when you use both old and new files together, by can-+ celling out the following opening transaction and preventing buildup of+ duplicated opening balances. Think of the closing/opening pair as+ "moving the balances into the next file".++ You can close a different set of accounts by providing a query. Eg if+ you want to include equity, you can add assets liabilities equity or+ type:ALE arguments. (The balancing account is always excluded.) Rev-+ enues and expenses usually are not migrated to a new file directly; see+ --retain below.++ The generated transactions will have a start: tag, with its value set+ to --migrate's NEW argument if any, for easier matching or exclusion.+ When NEW is not specified, it will be inferred if possible by incre-+ menting a number (eg a year number) within the default journal's main+ file name. The other modes behave similarly.++ close --close+ This prints just the closing balances transaction of --migrate. It is+ the default behaviour if you specify no mode flag. Using the customi-+ sation options below, you can move balances from any set of accounts to+ a different account.++ close --open+ This prints just the opening balances transaction of --migrate. It is+ similar to Ledger's equity command.++ close --assert+ This prints a "closing balances" transaction (with balances: tag), that+ just declares balance assertions for the current balances without+ changing them. It could be useful as documention and to guard against+ changes.++ close --assign+ This prints an "opening balances" transaction that restores the account+ balances using balance assignments. Balance assignments work regard-+ less of any previous balance, so a preceding closing balances transac-+ tion is not needed.++ However, omitting the closing balances transaction would unbalance eq-+ uity. This is relatively harmless for personal reports, but it dis-+ turbs the accounting equation, removing a source of error detection.+ So --migrate is generally the best way to set to set balances in new+ files, for now.++ close --retain+ This is like --close with different defaults: it prints a "retain earn-+ ings" transaction (with retain: tag), that transfers revenue and ex-+ pense balances to equity:retained earnings.++ This is a different kind of closing, called "retaining earnings" or+ "closing the books"; it is traditionally performed by businesses at the+ end of each accounting period, to consolidate revenues and expenses+ into the main equity balance. ("Revenues" and "expenses" are actually+ equity by another name, kept separate temporarily for reporting pur-+ poses.)++ In personal accounting you generally don't need to do this, unless you+ want the balancesheetequity report to show a zero total, demonstrating+ that the accounting equation (A-L=E) is satisfied.++ close customisation+ In all modes, the following things can be overridden:++ o the accounts to be closed/opened, with account query arguments++ o the balancing account, with --close-acct=ACCT and/or --open-acct=ACCT++ o the transaction descriptions, with --close-desc=DESC and+ --open-desc=DESC++ o the transaction's tag value, with a --MODE=NEW option argument++ o the closing/opening dates, with -e OPENDATE++ By default, the closing date is yesterday, or the journal's end date,+ whichever is later; and the opening date is always one day after the+ closing date. You can change these by specifying a report end date;+ the closing date will be the last day of the report period. Eg -e 2024+ means "close on 2023-12-31, open on 2024-01-01".++ With --x/--explicit, the balancing amount will be shown explicitly, and+ if it involves multiple commodities, a separate posting will be gener-+ ated for each of them (similar to print -x).++ With --interleaved, each individual transfer is shown with source and+ destination postings next to each other (perhaps useful for trou-+ bleshooting).++ With --show-costs, balances' costs are also shown, with different costs+ kept separate. This may generate very large journal entries, if you+ have many currency conversions or investment transactions. close+ --show-costs is currently the best way to view investment lots with+ hledger. (To move or dispose of lots, see the more capable+ hledger-move script.)++ close and balance assertions+ close adds balance assertions verifying that the accounts have been re-+ set to zero in a closing transaction or restored to their previous bal-+ ances in an opening transaction. These provide useful error checking,+ but you can ignore them temporarily with -I, or remove them if you pre-+ fer.++ Single-commodity, subaccount-exclusive balance assertions (=) are gen-+ erated by default. This can be changed with --assertion-type='==*'+ (eg).++ When running close you should probably avoid using -C, -R, status:+ (filtering by status or realness) or --auto (generating postings),+ since the generated balance assertions would then require these.++ Transactions with multiple dates (eg posting dates) spanning the file+ boundary also can disrupt the balance assertions:++ 2023-12-30 a purchase made in december, cleared in january+ expenses:food 5+ assets:bank:checking -5 ; date: 2023-01-02++ To solve this you can transfer the money to and from a temporary ac-+ count, splitting the multi-day transaction into two single-day transac-+ tions:++ ; in 2022.journal:+ 2022-12-30 a purchase made in december, cleared in january+ expenses:food 5+ equity:pending -5++ ; in 2023.journal:+ 2023-01-02 last year's transaction cleared+ equity:pending 5 = 0+ assets:bank:checking -5++ close examples+ Retain earnings+ Record 2022's revenues/expenses as retained earnings on 2022-12-31, ap-+ pending the generated transaction to the journal:++ $ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal++ After this, to see 2022's revenues and expenses you must exclude the+ retain earnings transaction:++ $ hledger -f 2022.journal is not:desc:'retain earnings'++ Migrate balances to a new file+ Close assets/liabilities on 2022-12-31 and re-open them on 2023-01-01:++ $ hledger close --migrate -f 2022.journal -p 2022+ # copy/paste the closing transaction to the end of 2022.journal+ # copy/paste the opening transaction to the start of 2023.journal++ After this, to see 2022's end-of-year balances you must exclude the+ closing balances transaction:++ $ hledger -f 2022.journal bs not:desc:'closing balances'++ For more flexibility, it helps to tag closing and opening transactions+ with eg start:NEWYEAR, then you can ensure correct balances by exclud-+ ing all opening/closing transactions except the first, like so:++ $ hledger bs -Y -f 2021.j -f 2022.j -f 2023.j expr:'tag:start=2021 or not tag:start'+ $ hledger bs -Y -f 2021.j -f 2022.j expr:'tag:start=2021 or not tag:start'+ $ hledger bs -Y -f 2022.j -f 2023.j expr:'tag:start=2022 or not tag:start'+ $ hledger bs -Y -f 2021.j expr:'tag:start=2021 or not tag:start'+ $ hledger bs -Y -f 2022.j expr:'tag:start=2022 or not tag:start'+ $ hledger bs -Y -f 2023.j # unclosed file, no query needed++ More detailed close examples+ See examples/multi-year.++ 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:++ 2022/1/1 (123) Supermarket+ Food $5.00+ Checking++ 2022/1/2 (124) Post Office+ Postage $8.32+ Checking++ 2022/1/3 Supermarket+ Food $11.23+ Checking++ 2022/1/4 (126) Post Office+ Postage $3.21+ Checking++ $ hledger codes+ 123+ 124+ 126++ $ hledger codes -E+ 123+ 124++ 126++ commodities+ List all commodity/currency symbols used or declared in the journal.++ demo+ Play demos of hledger usage in the terminal, if asciinema is installed.++ Run this command with no argument to list the demos. To play a demo,+ write its number or a prefix or substring of its title. Tips:++ Make your terminal window large enough to see the demo clearly.++ Use the -s/--speed SPEED option to set your preferred playback speed,+ eg -s4 to play at 4x original speed or -s.5 to play at half speed. The+ default speed is 2x.++ Other asciinema options can be added following a double dash, eg --+ -i.1 to limit pauses or -- -h to list asciinema's other options.++ During playback, several keys are available: SPACE to pause/unpause, .+ to step forward (while paused), CTRL-c quit.++ Examples:++ $ hledger demo # list available demos+ $ hledger demo 1 # play the first demo at default speed (2x)+ $ hledger demo install -s4 # play the "install" demo at 4x speed++ 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+ 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+ List all files included in the journal. With a REGEX argument, only+ file names matching the regular expression (case sensitive) are shown.++ help+ Show the hledger user manual in the terminal, with info, man, or a+ pager. With a TOPIC argument, open it at that topic if possible.+ TOPIC can be any heading in the manual, or a heading prefix, case in-+ sensitive. Eg: commands, print, forecast, journal, amount, "auto post-+ ings".++ This command shows the hledger manual built in to your hledger version.+ It can be useful when offline, or when you prefer the terminal to a web+ browser, or when the appropriate hledger manual or viewing tools are+ not installed on your system.++ By default it chooses the best viewer found in $PATH, trying (in this+ order): info, man, $PAGER, less, more. You can force the use of info,+ man, or a pager with the -i, -m, or -p flags, If no viewer can be+ found, or the command is run non-interactively, it just prints the man-+ ual to stdout.++ If using info, note that version 6 or greater is needed for TOPIC+ lookup. If you are on mac you will likely have info 4.8, and should+ consider installing a newer version, eg with brew install texinfo+ (#1770).++ Examples++ $ hledger help --help # show how the help command works+ $ hledger help # show the hledger manual with info, man or $PAGER+ $ hledger help journal # show the journal topic in the hledger manual+ $ hledger help -m journal # show it with man, even if info is installed++ import+ Read new transactions added to each FILE provided as arguments since+ last run, and add them to the journal. Or with --dry-run, just print+ the transactions that would be added. Or with --catchup, just mark all+ of the FILEs' current transactions as imported, without importing them.++ This command may append new transactions to the main journal file+ (which should be in journal format). Existing transactions are not+ changed. This is one of the few hledger commands that writes to the+ journal file (see also add).++ Unlike other hledger commands, with import the journal file is an out-+ 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+ import tries to import only the transactions which are new since the+ last import, ignoring any that it has seen in previous runs. So if+ your bank's CSV includes the last three months of data, you can down-+ load and import it every month (or week, or day) and only the new+ transactions will be imported each time.++ It works as follows. For each imported FILE (usually CSV, but they+ could be any of hledger's input formats):++ o It tries to recall the latest date seen previously, reading it from a+ hidden .latest.FILE in the same directory.++ o Then it processes FILE, ignoring any transactions on or before the+ "latest seen" date.++ And after a successful import, it updates the .latest.FILE(s) for next+ time (unless --dry-run was used).++ This is a limited kind of deduplication, let's call it "date skipping".+ Within each input file, it avoids reprocessing the same dates across+ successive runs. This is a simple system that works for most+ real-world CSV files; it assumes these are true, or true enough:++ 1. new items always have the newest dates++ 2. item dates are stable across successive downloads++ 3. the order of same-date items is stable across downloads++ 4. the name of the input file is stable across downloads++ If you have a bank whose CSV dates or ordering occasionally change, you+ can reduce the chance of this happening in new transactions by import-+ ing more often, and in old transactions it doesn't matter. And remem-+ ber you can use CSV rules files as input, which is one way to ensure a+ stable file name.++ import doesn't detect other kinds of duplication, such as duplicate+ transactions within a single run. (In part, because legitimate dupli-+ cate transactions can easily occur in real-world data.) So, say you+ downloaded but forgot to import bank.1.csv, and a week later you down-+ loaded bank.2.csv with overlapping data. Now you should not import+ both of these at once (hledger import bank.1.csv bank.2.csv); the over-+ lapping transactions which appear twice would not be deduplicated since+ this is considered a single import. Instead, import these files one at+ a time, and also use the same filename each time for a common "latest+ seen" state:++ $ mv bank.1.csv bank.csv; hledger import bank.csv+ $ mv bank.2.csv bank.csv; hledger import bank.csv++ Normally you can ignore the .latest.* files, but if needed, you can+ delete them (to make all transactions unseen), or construct/modify them+ (to catch up to a certain date). The format is just a single ISO-for-+ mat date (YYYY-MM-DD), possibly repeated on multiple lines. It means+ "I have seen transactions up to this date, and this many of them occur-+ ring on that date".++ hledger print --new also uses and updates these .latest.* files, but it+ is less often used.++ Related: CSV > Working with CSV > Deduplicating, importing.++ Import testing+ With --dry-run, the transactions that will be imported are printed to+ 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'++ Note: when importing from multiple files at once, it's currently possi-+ ble for some .latest files to be updated successfully, while the actual+ import fails because of a problem in one of the files, leaving them out+ of sync (and causing some transactions to be missed). To prevent this,+ do a --dry-run first and fix any problems before the real import.++ 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+ (is)++ This command displays an income statement, showing revenues and ex-+ penses during one or more periods. Amounts are shown with normal posi-+ tive sign, as in conventional financial statements.++ This report shows accounts declared with the Revenue or Expense type+ (see account types). Or if no such accounts are declared, it shows+ top-level accounts named revenue or income or expense (case insensi-+ tive, plurals allowed) and their subaccounts.++ Example:++ $ hledger incomestatement+ Income Statement 2008++ || 2008+ ===================++======+ Revenues ||+ -------------------++------+ income:gifts || $1+ income:salary || $1+ -------------------++------+ || $2+ ===================++======+ Expenses ||+ -------------------++------+ expenses:food || $1+ expenses:supplies || $1+ -------------------++------+ || $2+ ===================++======+ Net: || 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 op-+ tions The output formats supported are txt, csv, tsv (Added in 1.32),+ html, and json.++ notes+ List the unique notes that appear in transactions.++ This command lists the unique notes that appear in transactions, in al-+ phabetic order. You can add a query to select a subset of transac-+ tions. The note is the part of the transaction description after a |+ character (or if there is no |, the whole description).++ Example:++ $ hledger notes+ Petrol+ Snacks++ payees+ 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+ Print the market prices declared with P directives. With --infer-mar-+ ket-prices, also show any additional prices inferred from costs. With+ --show-reverse, also show additional prices inferred by reversing known+ prices.++ Price amounts are always displayed with their full precision, except+ for reverse prices which are limited to 8 decimal digits.++ Prices can be filtered by a date:, cur: or amt: query.++ Generally if you run this command with --infer-market-prices --show-re-+ verse, it will show the same prices used internally to calculate value+ reports. But if in doubt, you can inspect those directly by running+ the value report with --debug=2.++ 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).++ 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/regenerate your journal you should take care to also copy+ over the directives and inter-transaction comments.++ Eg:++ $ hledger print -f examples/sample.journal date:200806+ 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++ print explicitness+ Normally, whether posting amounts are implicit or explicit is pre-+ served. For example, when an amount is omitted in the journal, it will+ not appear in the output. Similarly, if a conversion cost is implied+ but not written, it will not appear in the output.++ You can use the -x/--explicit flag to force explicit display of all+ amounts and costs. This can be useful for troubleshooting or for mak-+ ing your journal more readable and robust against data entry errors.+ -x is also implied by using any of -B,-V,-X,--value.++ The -x/--explicit flag will cause any postings with a multi-commodity+ amount (which can arise when a multi-commodity transaction has an im-+ plicit amount) to be split into multiple single-commodity postings,+ keeping the output parseable.++ print amount style+ Amounts are shown right-aligned within each transaction (but not+ aligned across all transactions; you can do that with ledger-mode in+ Emacs).++ Amounts will be (mostly) normalised to their commodity display style:+ their symbol placement, decimal mark, and digit group marks will be+ made consistent. By default, decimal digits are shown as they are+ written in the journal.++ With the --round (Added in 1.32) option, print will try increasingly+ hard to display decimal digits according to the commodity display+ styles:++ o --round=none show amounts with original precisions (default)++ o --round=soft add/remove decimal zeros in amounts (except costs)++ o --round=hard round amounts (except costs), possibly hiding signifi-+ cant digits++ o --round=all round all amounts and costs++ soft is good for non-lossy cleanup, formatting amounts more consis-+ tently where it's safe to do so.++ hard and all can cause print to show invalid unbalanced journal en-+ tries; they may be useful eg for stronger cleanup, with manual fixups+ when needed.++ print parseability+ 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 (though the same can be achieved with expr: queries+ now):++ # 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 Value reporting affects posting amounts but not balance assertion or+ balance assignment amounts, potentially causing those to fail.++ o Auto postings can generate postings with too many missing amounts.++ o Account aliases can generate bad account names.++ print, other features+ With -B/--cost, amounts with costs are shown converted to cost.++ With --new, print shows only transactions it has not seen on a previous+ run. This uses the same deduplication system as the import command.+ (See import's docs for details.)++ With -m DESC/--match=DESC, print shows one recent transaction whose de-+ scription is most similar to DESC. DESC should contain at least two+ characters. If there is no similar-enough match, no transaction will+ be shown and the program exit code will be non-zero.++ print output format+ This command also supports the output destination and output format op-+ tions The output formats supported are txt, beancount (Added in 1.32),+ csv, tsv (Added in 1.32), json and sql.++ The beancount format tries to produce Beancount-compatible output, as+ follows:++ o Transaction and postings with unmarked status are converted to+ cleared (*) status.++ o Transactions' payee and note are backslash-escaped and dou-+ ble-quote-escaped and wrapped in double quotes.++ o Transaction tags are copied to Beancount #tag format.++ o Commodity symbols are converted to upper case, and a small number of+ currency symbols like $ are converted to the corresponding currency+ names.++ o Account name parts are capitalised and unsupported characters are re-+ placed with -. If an account name part does not begin with a letter,+ or if the first part is not Assets, Liabilities, Equity, Income, or+ Expenses, an error is raised. (Use --alias options to bring your ac-+ counts into compliance.)++ o An open directive is generated for each account used, on the earliest+ transaction date.++ Some limitations:++ o Balance assertions are removed.++ o Balance assignments become missing amounts.++ o Virtual and balanced virtual postings become regular postings.++ o Directives are not converted.++ 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.)++ 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.++ For performance reasons, column widths are chosen based on the first+ 1000 lines; this means unusually wide values in later lines can cause+ visual discontinuities as column widths are adjusted. If you want to+ ensure perfect alignment, at the cost of more time and memory, use the+ --align-all flag.++ The --historical/-H flag adds the balance from any undisplayed prior+ postings to the running total. This is useful when you want to see+ only recent activity, with a historically accurate running balance:++ $ hledger register checking -b 2008/6 --historical+ 2008/06/01 gift assets:bank:checking $1 $2+ 2008/06/02 save assets:bank:checking $-1 $1+ 2008/12/31 pay off assets:bank:checking $-1 0++ The --depth option limits the amount of sub-account detail displayed.++ The --average/-A flag shows the running average posting amount instead+ of the running total (so, the final number displayed is the average for+ the whole report period). This flag implies --empty (see below). It+ is affected by --historical. It works best when showing just one ac-+ count and one commodity.++ The --related/-r flag shows the other postings in the transactions of+ the postings which would normally be shown.++ The --invert flag negates all amounts. For example, it can be used on+ an income account where amounts are normally displayed as negative num-+ bers. It's also useful to show postings on the checking account to-+ gether with the related account:++ $ hledger register --related --invert assets:checking++ With a reporting interval, register shows summary postings, one per in-+ terval, aggregating the postings to each account:++ $ hledger register --monthly income+ 2008/01 income:salary $-1 $-1+ 2008/06 income:gifts $-1 $-2++ Periods with no activity, and summary postings with a zero amount, are+ not shown by default; use the --empty/-E flag to see them:++ $ hledger register --monthly income -E+ 2008/01 income:salary $-1 $-1+ 2008/02 0 $-1+ 2008/03 0 $-1+ 2008/04 0 $-1+ 2008/05 0 $-1+ 2008/06 income:gifts $-1 $-2+ 2008/07 0 $-2+ 2008/08 0 $-2+ 2008/09 0 $-2+ 2008/10 0 $-2+ 2008/11 0 $-2+ 2008/12 0 $-2++ Often, you'll want to see just one line per interval. The --depth op-+ tion helps with this, causing subaccounts to be aggregated:++ $ hledger register --monthly assets --depth 1h+ 2008/01 assets $1 $1+ 2008/06 assets $-1 0+ 2008/12 assets $-1 $-1++ Note when using report intervals, if you specify start/end dates these+ will be adjusted outward if necessary to contain a whole number of in-+ tervals. This ensures that the first and last intervals are full+ length and comparable to the others in the report.++ With -m DESC/--match=DESC, register does a fuzzy search for one recent+ posting whose description is most similar to DESC. DESC should contain+ at least two characters. If there is no similar-enough match, no post-+ ing will be shown and the program exit code will be non-zero.++ Custom register output+ register uses the full terminal width by default, except on windows.+ You can override this by setting the COLUMNS environment variable (not+ a bash shell variable) or by using the --width/-w option.++ The description and account columns normally share the space equally+ (about half of (width - 40) each). You can adjust this by adding a de-+ scription width as part of --width's argument, comma-separated: --width+ W,D . Here's a diagram (won't display correctly in --help):++ <--------------------------------- width (W) ---------------------------------->+ date (10) description (D) account (W-41-D) amount (12) balance (12)+ DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA++ and some examples:++ $ hledger reg # use terminal width (or 80 on windows)+ $ hledger reg -w 100 # use width 100+ $ COLUMNS=100 hledger reg # set with one-time environment variable+ $ export COLUMNS=100; hledger reg # set till session end (or window resize)+ $ hledger reg -w 100,40 # set overall width 100, description width 40+ $ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40++ This command also supports the output destination and output format op-+ tions The output formats supported are txt, csv, tsv (Added in 1.32),+ and json.++ rewrite+ Print all transactions, rewriting the postings of matched transactions.+ For now the only rewrite available is adding new postings, like print+ --auto.++ This is a start at a generic rewriter of transaction entries. It reads+ the default journal and prints the transactions, like print, but adds+ one or more specified postings to any transactions matching QUERY. The+ posting amounts can be fixed, or a multiplier of the existing transac-+ tion's first posting amount.++ Examples:++ $ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'+ $ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'+ $ hledger-rewrite.hs -f rewrites.hledger++ rewrites.hledger may consist of entries like:++ = ^income amt:<0 date:2017+ (liabilities:tax) *0.33 ; tax on income+ (reserve:grocery) *0.25 ; reserve 25% for grocery+ (reserve:) *0.25 ; reserve 25% for grocery++ Note the single quotes to protect the dollar sign from bash, and the+ two spaces between account and amount.++ More:++ $ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...+ $ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'+ $ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'+ $ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'++ Argument for --add-posting option is a usual posting of transaction+ with an exception for amount specification. More precisely, you can+ use '*' (star symbol) before the amount to indicate that that this is a+ factor for an amount of original matched posting. If the amount in-+ cludes a commodity name, the new posting amount will be in the new com-+ modity; otherwise, it will be in the matched posting amount's commod-+ ity.++ Re-write rules in a file+ During the run this tool will execute so called "Automated Transac-+ tions" found in any journal it process. I.e instead of specifying this+ operations in command line you can put them in a journal file.++ $ rewrite-rules.journal++ Make contents look like this:++ = ^income+ (liabilities:tax) *.33++ = expenses:gifts+ budget:gifts *-1+ assets:budget *1++ Note that '=' (equality symbol) that is used instead of date in trans-+ actions you usually write. It indicates the query by which you want to+ match the posting to add new ones.++ $ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal++ This is something similar to the commands pipeline:++ $ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \+ | hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \+ --add-posting 'assets:budget *1' \+ > rewritten-tidy-output.journal++ It is important to understand that relative order of such entries in+ journal is important. You can re-use result of previously added post-+ ings.++ Diff output format+ To use this tool for batch modification of your journal files you may+ find useful output in form of unified diff.++ $ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'++ Output might look like:++ --- /tmp/examples/sample.journal+ +++ /tmp/examples/sample.journal+ @@ -18,3 +18,4 @@+ 2008/01/01 income+ - assets:bank:checking $1+ + assets:bank:checking $1+ income:salary+ + (liabilities:tax) 0+ @@ -22,3 +23,4 @@+ 2008/06/01 gift+ - assets:bank:checking $1+ + assets:bank:checking $1+ income:gifts+ + (liabilities:tax) 0++ If you'll pass this through patch tool you'll get transactions contain-+ ing the posting that matches your query be updated. Note that multiple+ files might be update according to list of input files specified via+ --file options and include directives inside of these files.++ Be careful. Whole transaction being re-formatted in a style of output+ from hledger print.++ See also:++ https://github.com/simonmichael/hledger/issues/99++ rewrite vs. print --auto+ This command predates print --auto, and currently does much the same+ thing, but with these differences:++ o with multiple files, rewrite lets rules in any file affect all other+ files. print --auto uses standard directive scoping; rules affect+ only child files.++ o rewrite's query limits which transactions can be rewritten; all are+ printed. print --auto's query limits which transactions are printed.++ o rewrite applies rules specified on command line or in the journal.+ print --auto applies rules specified in the journal.++ roi+ 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 ac-+ count 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, also known as money-weighted rate of return) and time-weighted+ rate of return (TWR) for your investments for the time period re-+ quested. IRR is always annualized due to the way it is computed, but+ TWR is reported both as a rate over the chosen reporting period and as+ an annual rate.++ Price directives will be taken into account if you supply appropriate+ --cost or --value flags (see VALUATION).++ Note, in some cases this report can fail, for these reasons:++ o Error (NotBracketed): No solution for Internal Rate of Return (IRR).+ Possible causes: IRR is huge (>1000000%), balance of investment be-+ comes negative at some point in time.++ o Error (SearchFailed): Failed to find solution for Internal Rate of+ Return (IRR). Either search does not converge to a solution, or con-+ verges too slowly.++ Examples:++ o Using roi to compute total return of investment in stocks:+ https://github.com/simonmichael/hledger/blob/master/examples/invest-+ ing/roi-unrealised.ledger++ o Cookbook > Return on Investment: https://hledger.org/roi.html++ 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 as-+ sets, 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 re-+ turn.++ 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, and the+ time between them. Investment at a particular fixed interest rate is+ going to give you more interest than the same amount invested at the+ same interest rate, but made later in time. If you are withdrawing+ from your investment, your future gains would be smaller (in absolute+ numbers), and will be a smaller percentage of your initial investment,+ so your IRR will be smaller. And if you are adding to your investment,+ you will receive bigger absolute gains, which will be a bigger percent-+ age of your initial investment, so your IRR will be larger.++ 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 ac-+ count for the effect of your in-flows and out-flows, but unlike IRR it+ will try to compute the true rate of return of the underlying asset,+ compensating for the effect that deposits and withdrawas have on the+ apparent rate of growth of your investment.++ TWR represents your investment as an imaginary "unit fund" where+ in-flows/ out-flows lead to buying or selling "units" of your invest-+ ment and changes in its value change the value of "investment unit".+ Change in "unit price" over the reporting period gives you rate of re-+ turn of your investment, and make TWR less sensitive than IRR to the+ effects of cash in-flows and out-flows.++ References:++ o Explanation of rate of return++ o Explanation of IRR++ o Explanation of TWR++ o IRR vs TWR++ o Examples of computing IRR and TWR and discussion of the limitations+ of both metrics++ stats+ Show journal and performance statistics.++ The stats command shows summary information for the whole journal, or a+ matched part of it. With a reporting interval, it shows a report for+ each report period.++ The default output is fairly impersonal, though it reveals the main+ file name. With -v/--verbose, more details are shown, like file paths,+ included files, and commodity names.++ It also shows some run time statistics:++ o elapsed time++ o throughput: the number of transactions processed per second++ o live: the peak memory in use by the program to do its work++ o alloc: the peak memory allocation from the OS as seen by GHC. Mea-+ suring this externally, eg with GNU time, is more accurate; usually+ that will be a larger number; sometimes (with swapping?) smaller.++ The stats command's run time is similar to that of a balance report.++ Example:++ $ hledger stats -f examples/1ktxns-1kaccts.journal+ Main file : .../1ktxns-1kaccts.journal+ Included files : 0+ Txns span : 2000-01-01 to 2002-09-27 (1000 days)+ Last txn : 2002-09-26 (7827 days ago)+ Txns : 1000 (1.0 per day)+ Txns last 30 days : 0 (0.0 per day)+ Txns last 7 days : 0 (0.0 per day)+ Payees/descriptions : 1000+ Accounts : 1000 (depth 10)+ Commodities : 26+ Market prices : 1000+ Runtime stats : 0.12 s elapsed, 8266 txns/s, 4 MB live, 16 MB alloc++ This command supports the -o/--output-file option (but not -O/--out-+ put-format).++ tags+ List the tags used in the journal, or their values.++ This command lists the tag names used in the journal, whether on trans-+ actions, postings, or account declarations.++ With a TAGREGEX argument, only tag names matching this regular expres-+ sion (case insensitive, infix matched) are shown.++ With QUERY arguments, only transactions and accounts matching this+ query are considered. If the query involves transaction fields (date:,+ desc:, amt:, ...), the search is restricted to the matched transactions+ and their accounts.++ With the --values flag, the tags' unique non-empty values are listed+ instead. With -E/--empty, blank/empty values are also shown.++ With --parsed, tags or values are shown in the order they were parsed,+ with duplicates included. (Except, tags from account declarations are+ always shown first.)++ Tip: remember, accounts also acquire tags from their parents, postings+ also acquire tags from their account and transaction, transactions also+ acquire tags from their postings.++ 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).++PART 5: COMMON TASKS+ Here are some quick examples of how to do some basic tasks with+ hledger.++ Getting help+ Here's how to list commands and view options and command docs:++ $ hledger # show available commands+ $ hledger --help # show common options+ $ hledger CMD --help # show CMD's options, common options and CMD's documentation++ You can also view your hledger version's manual in several formats by+ using the help command. Eg:++ $ hledger help # show the hledger manual with info, man or $PAGER (best available)+ $ hledger help journal # show the journal topic in the hledger manual+ $ hledger help --help # find out more about the help command++ To view manuals and introductory docs on the web, visit+ https://hledger.org. Chat and mail list support and discussion+ archives can be found at https://hledger.org/support.++ Constructing command lines+ hledger has a flexible command line interface. We strive to keep it+ simple and ergonomic, but if you run into one of the sharp edges de-+ scribed in OPTIONS, here are some tips that might help:++ o command-specific options must go after the command (it's fine to put+ common options there too: 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 line 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+ (see below). 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 2023.journal+ $ echo "export LEDGER_FILE=$HOME/finance/2023.journal" >> ~/.profile+ $ source ~/.profile+ $ hledger stats+ Main file : /Users/simon/finance/2023.journal+ Included files :+ Transactions span : to (0 days)+ Last transaction : none+ Transactions : 0 (0.0 per day)+ Transactions last 30 days: 0 (0.0 per day)+ Transactions last 7 days : 0 (0.0 per day)+ Payees/descriptions : 0+ Accounts : 0 (depth 0)+ Commodities : 0 ()+ Market prices : 0 ()++ Setting LEDGER_FILE+ How to set LEDGER_FILE permanently depends on your setup:++ On unix and mac, running these commands in the terminal will work for+ many people; adapt as needed:++ $ echo 'export LEDGER_FILE=~/finance/2023.journal' >> ~/.profile+ $ source ~/.profile++ When correctly configured, in a new terminal window env | grep+ LEDGER_FILE will show your file, and so will hledger files.++ On mac, this additional step might be helpful for GUI applications+ (like Emacs started from the dock): add an entry to ~/.MacOSX/environ-+ ment.plist like++ {+ "LEDGER_FILE" : "~/finance/2023.journal"+ }++ and then run killall Dock in a terminal window (or restart the ma-+ chine).++ On Windows, see https://www.java.com/en/download/help/path.html, or try+ running these commands in a powershell window (let us know if it per-+ sists across a reboot, and if you need to be an Administrator):++ > CD+ > MKDIR finance+ > SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal"++ Setting opening balances+ Pick a starting date for which you can look up the balances of some+ real-world assets (bank accounts, wallet..) and liabilities (credit+ cards..).++ To avoid a lot of data entry, you may want to start with just one or+ two accounts, like your checking account or cash wallet; and pick a re-+ cent starting date, like today or the start of the week. You can al-+ ways come back later and add more accounts and older transactions, eg+ going back to january 1st.++ Add an opening balances transaction to the journal, declaring the bal-+ ances on this date. Here are two ways to do it:++ o The first way: open the journal in any text editor and save an entry+ like this:++ 2023-01-01 * opening balances+ assets:bank:checking $1000 = $1000+ assets:bank:savings $2000 = $2000+ assets:cash $100 = $100+ liabilities:creditcard $-50 = $-50+ equity:opening/closing balances++ 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/2023.journal+ Any command line arguments will be used as defaults.+ Use tab key to complete, readline keys to edit, enter to accept defaults.+ An optional (CODE) may follow transaction dates.+ An optional ; COMMENT may follow descriptions or amounts.+ If you make a mistake, enter < at any prompt to go one step backward.+ To end a transaction, enter . when prompted.+ To quit, enter . at a date prompt or press control-d or control-c.+ Date [2023-02-07]: 2023-01-01+ Description: * opening balances+ Account 1: assets:bank:checking+ Amount 1: $1000+ Account 2: assets:bank:savings+ Amount 2 [$-1000]: $2000+ Account 3: assets:cash+ Amount 3 [$-3000]: $100+ Account 4: liabilities:creditcard+ Amount 4 [$-3100]: $-50+ Account 5: equity:opening/closing balances+ Amount 5 [$-3050]:+ Account 6 (or . or enter to finish this transaction): .+ 2023-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++ Save this transaction to the journal ? [y]:+ Saved.+ Starting the next transaction (. or ctrl-D/ctrl-C to quit)+ Date [2023-01-01]: .++ If you're using version control, this could be a good time to commit+ the journal. Eg:++ $ git commit -m 'initial balances' 2023.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:++ 2023/1/10 * gift received+ assets:cash $20+ income:gifts++ 2023.1.12 * farmers market+ expenses:food $13+ assets:cash++ 2023-01-15 paycheck+ income:salary+ assets:bank:checking $1000++ Reconciling+ Periodically you should reconcile - compare your hledger-reported bal-+ ances against external sources of truth, like bank statements or your+ bank's website - to be sure that your ledger accurately represents the+ real-world balances (and, that the real-world institutions have not+ made a mistake!). This gets easy and fast with (1) practice and (2)+ frequency. If you do it daily, it can take 2-10 minutes. If you let+ it pile up, expect it to take longer as you hunt down errors and dis-+ crepancies.++ A typical workflow:++ 1. Reconcile cash. Count what's in your wallet. Compare with what+ hledger reports (hledger bal cash). If they are different, try to+ remember the missing transaction, or look for the error in the al-+ ready-recorded transactions. A register report can be helpful+ (hledger reg cash). If you can't find the error, add an adjustment+ transaction. Eg if you have $105 after the above, and can't explain+ the missing $2, it could be:++ 2023-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ 2. Reconcile checking. Log in to your bank's website. Compare today's+ (cleared) balance with hledger's cleared balance (hledger bal check-+ ing -C). If they are different, track down the error or record the+ missing transaction(s) or add an adjustment transaction, similar to+ the above. Unlike the cash case, you can usually compare the trans-+ action history and running balance from your bank with the one re-+ ported by hledger reg checking -C. This will be easier if you gen-+ erally record transaction dates quite similar to your bank's clear-+ ing dates.++ 3. Repeat for other asset/liability accounts.++ Tip: instead of the register command, use hledger-ui to see a live-up-+ dating register while you edit the journal: hledger-ui --watch --regis-+ ter checking -C++ After reconciling, it could be a good time to mark the reconciled+ transactions' status as "cleared and confirmed", if you want to track+ that, by adding the * marker. Eg in the paycheck transaction above,+ insert * between 2023-01-15 and paycheck++ If you're using version control, this can be another good time to com-+ mit:++ $ git commit -m 'txns' 2023.journal++ Reporting+ Here are some basic reports.++ Show all transactions:++ $ hledger print+ 2023-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++ 2023-01-10 * gift received+ assets:cash $20+ income:gifts++ 2023-01-12 * farmers market+ expenses:food $13+ assets:cash++ 2023-01-15 * paycheck+ income:salary+ assets:bank:checking $1000++ 2023-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ 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 -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 -2+ Balance Sheet 2023-01-16++ || 2023-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 2023-01-01-2023-01-16++ || 2023-01-01-2023-01-16+ ===============++=======================+ Revenues ||+ ---------------++-----------------------+ income:gifts || $20+ income:salary || $1000+ ---------------++-----------------------+ || $1020+ ===============++=======================+ Expenses ||+ ---------------++-----------------------+ expenses:food || $13+ expenses:misc || $2+ ---------------++-----------------------+ || $15+ ===============++=======================+ Net: || $1005++ The final total is your net income during this period.++ Show transactions affecting your wallet, with running total:++ $ hledger register cash+ 2023-01-01 opening balances assets:cash $100 $100+ 2023-01-10 gift received assets:cash $20 $120+ 2023-01-12 farmers market assets:cash $-13 $107+ 2023-01-16 adjust cash assets:cash $-2 $105++ Show weekly posting counts as a bar chart:++ $ hledger activity -W+ 2019-12-30 *****+ 2023-01-06 ****+ 2023-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.++BUGS+ We welcome bug reports in the hledger issue tracker (shortcut:+ http://bugs.hledger.org), or on the #hledger chat or hledger mail list+ (https://hledger.org/support).++ Some known issues and limitations:++ The need to precede add-on command options with -- when invoked from+ hledger is awkward. (See Command options, Constructing command lines.)++ A UTF-8-aware system locale must be configured to work with non-ascii+ data. (See Unicode characters, Troubleshooting.)++ On Microsoft Windows, depending whether you are running in a CMD window+ or a Cygwin/MSYS/Mintty window and how you installed hledger, non-ascii+ characters and colours may not be supported, and the tab key may not be+ supported by hledger add. (Running in a WSL window should resolve+ these.)++ When processing large data files, hledger uses more memory than Ledger.++ Troubleshooting+ Here are some common issues you might encounter when you run hledger,+ and how to resolve them (and remember also you can usually get quick+ Support):++ PATH issues: I get an error like "No command 'hledger' found"+ Depending how you installed hledger, the executables may not be in your+ shell's PATH. Eg on unix systems, stack installs hledger in ~/.lo-+ cal/bin and cabal installs it in ~/.cabal/bin. You may need to add one+ of these directories to your shell's PATH, and/or open a new terminal+ window.++ LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not using+ it+ o LEDGER_FILE should be a real environment variable, not just a shell+ variable. Eg on unix, the command env | grep LEDGER_FILE should show+ it. You may need to use export (see https://stackover-+ flow.com/a/7411509).++ o You may need to force your shell to see the new configuration. A+ simple way is to close your terminal window and open a new one.++ LANG issues: I get errors like "Illegal byte sequence" or "Invalid or+ incomplete multibyte or wide character" or "commitAndReleaseBuffer: in-+ valid argument (invalid character)"+ Programs compiled with GHC (hledger, haskell build tools, etc.) need+ the system locale to be UTF-8-aware, or they will fail when they en-+ counter non-ascii characters. To fix it, set the LANG environment+ variable to a locale which supports UTF-8 and which is installed on+ your system.++ On unix, locale -a lists the installed locales. Look for one which+ mentions utf8, UTF-8 or similar. Some examples: C.UTF-8, en_US.utf-8,+ fr_FR.utf8. If necessary, use your system package manager to install+ one. Then select it by setting the LANG environment variable. Note,+ exact spelling and capitalisation of the locale name may be important:+ Here's one common way to configure this permanently for your shell:++ $ echo "export LANG=en_US.utf8" >>~/.profile+ # close and re-open terminal window++ If you are using Nix (not NixOS) for GHC and Hledger, you might need to+ set the LOCALE_ARCHIVE variable:++ $ echo "export LOCALE_ARCHIVE=${glibcLocales}/lib/locale/locale-archive" >>~/.profile+ # close and re-open terminal window++ COMPATIBILITY ISSUES: hledger gives an error with my Ledger file+ Not all of Ledger's journal file syntax or feature set is supported.+ See hledger and Ledger for full details.++++AUTHORS+ Simon Michael <simon@joyful.com> and contributors.+ See http://hledger.org/CREDITS.html+++COPYRIGHT+ Copyright 2007-2023 Simon Michael and contributors.+++LICENSE+ Released under GNU GPL v3 or later.+++SEE ALSO+ hledger(1), hledger-ui(1), hledger-web(1), ledger(1)++hledger-1.33.1 May 2024 HLEDGER(1)
hledger.1 view
@@ -1,6 +1,6 @@ .\"t -.TH "HLEDGER" "1" "April 2024" "hledger-1.33 " "hledger User Manuals"+.TH "HLEDGER" "1" "May 2024" "hledger-1.33.1 " "hledger User Manuals" @@ -23,7 +23,7 @@ hledger is inspired by and largely compatible with ledger(1), and largely interconvertible with beancount(1). .PP-This manual is for hledger\[aq]s command line interface, version 1.33.+This manual is for hledger\[aq]s command line interface, version 1.33.1. It also describes the common options, file formats and concepts used by all hledger programs. It might accidentally teach you some bookkeeping/accounting as well!
hledger.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: hledger-version: 1.33+version: 1.33.1 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 -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path- cpp-options: -DVERSION="1.33"+ cpp-options: -DVERSION="1.33.1" build-depends: Decimal >=0.5.1 , Diff >=0.2@@ -153,13 +153,13 @@ , githash >=0.1.6.2 , hashable >=1.2.4 , haskeline >=0.6- , hledger-lib ==1.33.*+ , hledger-lib >=1.33.1 && <1.34 , lucid , math-functions >=0.3.3.0 , megaparsec >=7.0.0 && <9.7 , microlens >=0.4 , mtl >=2.2.1- , process >=1.6.19.0+ , process , regex-tdfa , safe >=0.3.20 , shakespeare >=2.0.2.2@@ -188,7 +188,7 @@ hs-source-dirs: app ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path- cpp-options: -DVERSION="1.33"+ cpp-options: -DVERSION="1.33.1" build-depends: Decimal >=0.5.1 , aeson >=1 && <2.3@@ -204,12 +204,12 @@ , githash >=0.1.6.2 , haskeline >=0.6 , hledger- , hledger-lib ==1.33.*+ , hledger-lib >=1.33.1 && <1.34 , math-functions >=0.3.3.0 , megaparsec >=7.0.0 && <9.7 , microlens >=0.4 , mtl >=2.2.1- , process >=1.6.19.0+ , process , regex-tdfa , safe >=0.3.20 , shakespeare >=2.0.2.2@@ -239,7 +239,7 @@ hs-source-dirs: test ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path- cpp-options: -DVERSION="1.33"+ cpp-options: -DVERSION="1.33.1" build-depends: Decimal >=0.5.1 , aeson >=1 && <2.3@@ -255,12 +255,12 @@ , githash >=0.1.6.2 , haskeline >=0.6 , hledger- , hledger-lib ==1.33.*+ , hledger-lib >=1.33.1 && <1.34 , math-functions >=0.3.3.0 , megaparsec >=7.0.0 && <9.7 , microlens >=0.4 , mtl >=2.2.1- , process >=1.6.19.0+ , process , regex-tdfa , safe >=0.3.20 , shakespeare >=2.0.2.2@@ -304,13 +304,13 @@ , githash >=0.1.6.2 , haskeline >=0.6 , hledger- , hledger-lib ==1.33.*+ , hledger-lib >=1.33.1 && <1.34 , html , math-functions >=0.3.3.0 , megaparsec >=7.0.0 && <9.7 , microlens >=0.4 , mtl >=2.2.1- , process >=1.6.19.0+ , process , regex-tdfa , safe >=0.3.20 , shakespeare >=2.0.2.2
hledger.info view
@@ -23,11811 +23,11811 @@ and largely compatible with ledger(1), and largely interconvertible with beancount(1). - This manual is for hledger's command line interface, version 1.33.-It also describes the common options, file formats and concepts used by-all hledger programs. It might accidentally teach you some-bookkeeping/accounting as well! You don't need to know everything in-here to use hledger productively, but when you have a question about-functionality, this doc should answer it. It is detailed, so do skip-ahead or skim when needed. You can read it on hledger.org, or as an-info manual or man page on your system. You can also get it from-hledger itself with-'hledger --man', 'hledger --info' or 'hledger help [TOPIC]'.-- The main function of the hledger CLI is to read plain text files-describing financial transactions, crunch the numbers, and print a-useful report on the terminal (or save it as HTML, CSV, JSON or SQL).-Many reports are available, as subcommands. hledger will also detect-other 'hledger-*' executables as extra subcommands.-- hledger usually reads from (and appends to) a journal file specified-by the 'LEDGER_FILE' environment variable (defaulting to-'$HOME/.hledger.journal'); or you can specify files with '-f' options.-It can also read timeclock files, timedot files, or any CSV/SSV/TSV file-with a date field.-- Here is a small journal file describing one transaction:--2015-10-16 bought food- expenses:food $10- assets:cash-- Transactions are dated movements of money (etc.) between two or more-_accounts_: bank accounts, your wallet, revenue/expense categories,-people, etc. You can choose any account names you wish, using ':' to-indicate subaccounts. There must be at least two spaces between account-name and amount. Positive amounts are inflow to that account (_debit_),-negatives are outflow from it (_credit_). (Some reports show revenue,-liability and equity account balances as negative numbers as a result;-this is normal.)-- hledger's add command can help you add transactions, or you can-install other data entry UIs like hledger-web or hledger-iadd. For more-extensive/efficient changes, use a text editor: Emacs + ledger-mode, VIM-+ vim-ledger, or VS Code + hledger-vscode are some good choices (see-https://hledger.org/editors.html).-- To get started, run 'hledger add' and follow the prompts, or save-some entries like the above in '$HOME/.hledger.journal', then try-commands like:--$ hledger print -x-$ hledger aregister assets-$ hledger balance-$ hledger balancesheet-$ hledger incomestatement-- Run 'hledger' to list the commands. See also the "Starting a journal-file" and "Setting opening balances" sections in PART 5: COMMON TASKS.--* Menu:--* PART 1 USER INTERFACE::-* Input::-* Commands::-* Options::-* Command line tips::-* Output::-* Environment::-* PART 2 DATA FORMATS::-* Journal::-* CSV::-* Timeclock::-* Timedot::-* PART 3 REPORTING CONCEPTS::-* Amount formatting::-* Time periods::-* Depth::-* Queries::-* Pivoting::-* Generating data::-* Forecasting::-* Budgeting::-* Cost reporting::-* Value reporting::-* PART 4 COMMANDS::-* PART 5 COMMON TASKS::-* BUGS::---File: hledger.info, Node: PART 1 USER INTERFACE, Next: Input, Prev: Top, Up: Top--1 PART 1: USER INTERFACE-************************---File: hledger.info, Node: Input, Next: Commands, Prev: PART 1 USER INTERFACE, Up: Top--2 Input-*******--hledger reads one or more data files, each time you run it. You can-specify a file with '-f', like so--$ hledger -f FILE print-- Files are most often in hledger's journal format, with the '.journal'-file extension ('.hledger' or '.j' also work); these files describe-transactions, like an accounting general journal.-- When no file is specified, hledger looks for '.hledger.journal' in-your home directory.-- But most people prefer to keep financial files in a dedicated folder,-perhaps with version control. Also, starting a new journal file each-year is common (it's not required, but helps keep things fast and-organised). So we usually configure a different journal file, by-setting the 'LEDGER_FILE' environment variable, to something like-'~/finance/2023.journal'. For more about how to do that on your system,-see Common tasks > Setting LEDGER_FILE.--* Menu:--* Text encoding::-* Data formats::-* Standard input::-* Multiple files::-* Strict mode::---File: hledger.info, Node: Text encoding, Next: Data formats, Up: Input--2.1 Text encoding-=================--Data files containing non-ascii characters must use UTF-8 encoding. An-optional byte order mark (BOM) is allowed, at the beginning of the file-(only).-- Also, your system should be configured with a locale that can decode-UTF-8 text. On some unix systems, you may need set the 'LANG'-environment variable, eg. You can read more about this in Unicode-characters, below.-- On unix systems you can check a file's encoding with the 'file'-command. If you need to import from a UTF-16-encoded CSV file, say, you-can convert it to UTF-8 with the 'iconv' command.---File: hledger.info, Node: Data formats, Next: Standard input, Prev: Text encoding, Up: Input--2.2 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: Automatically used for- files with extensions:-----------------------------------------------------------------------------'journal' hledger journal files and some '.journal' '.j'- Ledger journals, for '.hledger' '.ledger'- transactions-'timeclock' timeclock files, for precise '.timeclock'- time logging-'timedot' timedot files, for approximate '.timedot'- time logging-'csv' Comma or other character '.csv'- separated values, for data- import-'ssv' Semicolon separated values '.ssv'-'tsv' Tab separated values '.tsv'-'rules' CSV/SSV/TSV/other separated '.rules'- values, alternate way-- These formats are described in more detail below.-- hledger detects the format automatically based on the file extensions-shown above. If it can't recognise the file extension, it assumes-'journal' format. So for non-journal files, it's important to use a-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 containing-tab separated values:--$ hledger -f tsv:/some/file.dat stats---File: hledger.info, Node: Standard input, Next: Multiple files, Prev: Data formats, Up: Input--2.3 Standard input-==================--The file name '-' means standard input:--$ cat FILE | hledger -f- print-- If reading non-journal data in this way, you'll need to add a file-format prefix, like:--$ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:----File: hledger.info, Node: Multiple files, Next: Strict mode, Prev: Standard input, Up: Input--2.4 Multiple files-==================--You can specify multiple '-f' options, to read multiple files as one big-journal. When doing this, note that certain features (described below)-will be affected:-- * Balance assertions will not see the effect of transactions in- previous files. (Usually this doesn't matter as each file will set- the corresponding opening balances.)- * Some directives will not affect previous or subsequent files.-- If needed, you can work around these by using a single parent file-which includes the others, or concatenating the files into one, eg: 'cat-a.journal b.journal | hledger -f- CMD'.---File: hledger.info, Node: Strict mode, Prev: Multiple files, Up: Input--2.5 Strict mode-===============--hledger checks input files for valid data. By default, the most-important errors are detected, while still accepting easy journal files-without a lot of declarations:-- * Are the input files parseable, with valid syntax ?- * Are all transactions balanced ?- * Do all balance assertions pass ?-- With the '-s'/'--strict' flag, additional checks are performed:-- * Are all accounts posted to, declared with an 'account' directive ?- (Account error checking)- * Are all commodities declared with a 'commodity' directive ?- (Commodity error checking)- * Are all commodity conversions declared explicitly ?-- You can use the check command to run individual checks - the ones-listed above and some more.---File: hledger.info, Node: Commands, Next: Options, Prev: Input, Up: Top--3 Commands-**********--hledger provides various subcommands for getting things done. Most of-these commands do not change the journal file; they just read it and-output a report. A few commands assist with adding data and file-management.-- To show the commands list, run 'hledger' with no arguments. The-commands are described in detail in PART 4: COMMANDS, below.-- To use a particular command, run 'hledger CMD [CMDOPTS] [CMDARGS]',-- * CMD is the full command name, or its standard abbreviation shown in- the commands list, or any unambiguous prefix of the name.-- * CMDOPTS are command-specific options, if any. Command-specific- options must be written after the command name. Eg: 'hledger print- -x'.-- * CMDARGS are additional arguments to the command, if any. Most- hledger commands accept arguments representing a query, to limit- the data in some way. Eg: 'hledger reg assets:checking'.-- To list a command's options, arguments, and documentation in the-terminal, run 'hledger CMD -h'. Eg: 'hledger bal -h'.--* Menu:--* Add-on commands::---File: hledger.info, Node: Add-on commands, Up: Commands--3.1 Add-on commands-===================--In addition to the built-in commands, you can install _add-on commands_:-programs or scripts named "hledger-SOMETHING", which will also appear in-hledger's commands list. If you used the hledger-install script, you-will have several add-ons installed already. Some more can be found in-hledger's bin/ directory, documented at-https://hledger.org/scripts.html.-- More precisely, add-on commands are programs or scripts in your-shell's PATH, whose name starts with "hledger-" and ends with no-extension or a recognised extension (".bat", ".com", ".exe", ".hs",-".js", ".lhs", ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"),-and (on unix and mac) which has executable permission for the current-user.-- You can run add-on commands using hledger, much like built-in-commands: 'hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]'. But note-the double hyphen argument, required before add-on-specific options.-Eg: 'hledger ui -- --watch' or 'hledger web -- --serve'. If this causes-difficulty, you can always run the add-on directly, without using-'hledger': 'hledger-ui --watch' or 'hledger-web --serve'.---File: hledger.info, Node: Options, Next: Command line tips, Prev: Commands, Up: Top--4 Options-*********--Run 'hledger -h' to see general command line help, and general options-which are common to most hledger commands. These options can be written-anywhere on the command line. They can be grouped into help, input, and-reporting options:--* Menu:--* General help options::-* General input options::-* General reporting options::---File: hledger.info, Node: General help options, Next: General input options, Up: Options--4.1 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)---File: hledger.info, Node: General input options, Next: General reporting options, Prev: General help options, Up: Options--4.2 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-'--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)---File: hledger.info, Node: General reporting options, Prev: General input options, Up: Options--4.3 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- following 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)-'--today=DATE'-- override today's date (affects relative smart dates, for- tests/examples)-'-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- commodities-'-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-equity'-- infer conversion equity postings from costs-'--infer-costs'-- infer costs from conversion equity postings-'--infer-market-prices'-- use costs as additional market prices, as if they were P directives-'--forecast'-- generate transactions from periodic rules, between the latest- recorded txn and 6 months from today, or during the specified- PERIOD (= is required). Auto posting rules will be applied to- these transactions as well. Also, in hledger-ui make future-dated- transactions visible.-'--auto'-- generate extra postings by applying auto posting rules to all txns- (not just forecast txns)-'--verbose-tags'-- add visible tags indicating transactions or postings which have- been generated/modified-'--commodity-style'-- Override the commodity style in the output for the specified- commodity. For example 'EUR1.000,00'.-'--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.-'--pretty[=WHEN]'-- Show prettier output, e.g. using unicode box-drawing characters.- Accepts 'yes' (the default) or 'no' ('y', 'n', 'always', 'never'- also work). If you provide an argument you must use '=', e.g.- '-pretty=yes'.-- 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.---File: hledger.info, Node: Command line tips, Next: Output, Prev: Options, Up: Top--5 Command line tips-*******************--Here are some details useful to know about for hledger command lines-(and elsewhere). Feel free to skip this section until you need it.--* Menu:--* Option repetition::-* Special characters::-* Unicode characters::-* Regular expressions::-* Argument files::---File: hledger.info, Node: Option repetition, Next: Special characters, Up: Command line tips--5.1 Option repetition-=====================--If options are repeated in a command line, hledger will generally use-the last (right-most) occurence.---File: hledger.info, Node: Special characters, Next: Unicode characters, Prev: Option repetition, Up: Command line tips--5.2 Special characters-======================--* Menu:--* Single escaping shell metacharacters::-* Double escaping regular expression metacharacters::-* Triple escaping for add-on commands::-* Less escaping::---File: hledger.info, Node: Single escaping shell metacharacters, Next: Double escaping regular expression metacharacters, Up: Special characters--5.2.1 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 double 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.---File: hledger.info, Node: Double escaping regular expression metacharacters, Next: Triple escaping for add-on commands, Prev: Single escaping shell metacharacters, Up: Special characters--5.2.2 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:\\$---File: hledger.info, Node: Triple escaping for add-on commands, Next: Less escaping, Prev: Double escaping regular expression metacharacters, Up: Special characters--5.2.3 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-arguments intended for by the add-on command, so those need an extra-level of shell-escaping. Eg to match a literal '$' sign while using the-bash shell and running an add-on command ('ui'):--$ hledger ui cur:'\\$'-- or:--$ hledger ui cur:\\\\$-- If you wondered why _four_ backslashes, perhaps this helps:--unescaped: '$'-escaped: '\$'-double-escaped: '\\$'-triple-escaped: '\\\\$'-- Or, you can avoid the extra escaping by running the add-on executable-directly:--$ hledger-ui cur:\\$---File: hledger.info, Node: Less escaping, Prev: Triple escaping for add-on commands, Up: Special characters--5.2.4 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:-- * an @argumentfile- * hledger-ui's filter field- * hledger-web's search form- * GHCI's prompt (used by developers).---File: hledger.info, Node: Unicode characters, Next: Regular expressions, Prev: Special characters, Up: Command line tips--5.3 Unicode characters-======================--hledger is expected to handle non-ascii characters correctly:-- * 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.)-- * 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:-- * 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 Troubleshooting. This step is essential - without it, hledger- will quit on encountering a non-ascii character (as with all- GHC-compiled programs).-- * your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)- must support unicode-- * the terminal must be using a font which includes the required- unicode glyphs-- * the terminal should be configured to display wide characters as- double width (for report alignment)-- * on Windows, for best results you should run hledger in the same- kind of environment in which it was built. Eg hledger built in the- standard CMD.EXE environment (like the binaries on our download- page) might show display problems when run in a cygwin or msys- terminal, and vice versa. (See eg #961).---File: hledger.info, Node: Regular expressions, Next: Argument files, Prev: Unicode characters, Up: Command line tips--5.4 Regular expressions-=======================--A regular expression (regexp) is a small piece of text where certain-characters (like '.', '^', '$', '+', '*', '()', '|', '[]', '\') have-special meanings, forming a tiny language for matching text precisely --very useful in hledger and elsewhere. To learn all about them, visit-regular-expressions.info.-- hledger supports regexps whenever you are entering a pattern to match-something, eg in query arguments, account aliases, CSV if rules,-hledger-web's search form, hledger-ui's '/' search, etc. You may need-to wrap them in quotes, especially at the command line (see Special-characters above). Here are some examples:-- Account name queries (quoted for command line use):--Regular expression: Matches:-------------------- -------------------------------------------------------------bank assets:bank, assets:bank:savings, expenses:art:banksy, ...-:bank assets:bank:savings, expenses:art:banksy-:bank: assets:bank:savings-'^bank' none of those ( ^ matches beginning of text )-'bank$' assets:bank ( $ matches end of text )-'big \$ bank' big $ bank ( \ disables following character's special meaning )-'\bbank\b' assets:bank, assets:bank:savings ( \b matches word boundaries )-'(sav|check)ing' saving or checking ( (|) matches either alternative )-'saving|checking' saving or checking ( outer parentheses are not needed )-'savings?' saving or savings ( ? matches 0 or 1 of the preceding thing )-'my +bank' my bank, my bank, ... ( + matches 1 or more of the preceding thing )-'my *bank' mybank, my bank, my bank, ... ( * matches 0 or more of the preceding thing )-'b.nk' bank, bonk, b nk, ... ( . matches any character )-- Some other queries:--desc:'amazon|amzn|audible' Amazon transactions-cur:EUR amounts with commodity symbol containing EUR-cur:'\$' amounts with commodity symbol containing $-cur:'^\$$' only $ amounts, not eg AU$ or CA$-cur:....? amounts with 4-or-more-character symbols-tag:.=202[1-3] things with any tag whose value contains 2021, 2022 or 2023-- Account name aliases: accept '.' instead of ':' as account separator:--alias /\./=: replaces all periods in account names with colons-- Show multiple top-level accounts combined as one:----alias='/^[^:]+/=combined' ( [^:] matches any character other than : )-- Show accounts with the second-level part removed:----alias '/^([^:]+):[^:]+/ = \1'- match a top-level account and a second-level account- and replace those with just the top-level account- ( \1 in the replacement text means "whatever was matched- by the first parenthesised part of the regexp"-- CSV rules: match CSV records containing dining-related MCC codes:--if \?MCC581[124]-- Match CSV records with a specific amount around the end/start of-month:--if %amount \b3\.99-& %date (29|30|31|01|02|03)$--* Menu:--* hledger's regular expressions::---File: hledger.info, Node: hledger's regular expressions, Up: Regular expressions--5.4.1 hledger's regular expressions--------------------------------------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. backreferences are supported when doing text replacement in account- aliases or CSV rules, where backreferences can be used in the- replacement string to reference capturing groups in the search- regexp. Otherwise, if you write '\1', it will match the digit '1'.- 6. they do not support mode modifiers ('(?s)'), character classes- ('\w', '\d'), or anything else not mentioned above.-- Some things to note:-- * In the 'alias' directive and '--alias' option, regular expressions- must be enclosed in forward slashes ('/REGEX/'). Elsewhere in- hledger, these are not required.-- * 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:\$'.-- * On the command line, some metacharacters like '$' have a special- meaning to the shell and so must be escaped at least once more.- See Special characters.---File: hledger.info, Node: Argument files, Prev: Regular expressions, Up: Command line tips--5.5 Argument files-==================--You can save a set of command line options and arguments in a file, and-then reuse them by writing '@FILENAME' as a command line argument. Eg:-'hledger bal @foo.args'.-- Inside the argument file, each line should contain just one option or-argument. Don't use spaces except inside quotes (or you'll see a-confusing error); write '=' (or nothing) between a flag and its-argument. For the special characters mentioned above, use one less-level of quoting than you would at the command prompt.---File: hledger.info, Node: Output, Next: Environment, Prev: Command line tips, Up: Top--6 Output-********--* Menu:--* Output destination::-* Output format::-* Commodity styles::-* Colour::-* Box-drawing::-* Paging::-* Debug output::---File: hledger.info, Node: Output destination, Next: Output format, Up: Output--6.1 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-provide 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)---File: hledger.info, Node: Output format, Next: Commodity styles, Prev: Output destination, Up: Output--6.2 Output format-=================--Some commands offer other kinds of output, not just text on the-terminal. Here are those commands and the formats currently supported:--- txt csv/tsv html json sql---------------------------------------------------------------------------------aregister Y Y Y Y-balance Y _1_ Y _1_ Y _1,2_ Y-balancesheet Y _1_ Y _1_ Y _1_ Y-balancesheetequityY _1_ Y _1_ Y _1_ Y-cashflow Y _1_ Y _1_ Y _1_ Y-incomestatement Y _1_ Y _1_ Y _1_ Y-print Y Y Y Y-register Y Y Y-- * _1 Also affected by the balance commands' '--layout' option._- * _2 'balance' does not support html output without a report interval- or with '--budget'._-- The output format is selected by the '-O/--output-format=FMT' option:--$ hledger print -O csv # print CSV on stdout-- or by the filename extension of an output file specified with the-'-o/--output-file=FILE.FMT' option:--$ hledger balancesheet -o foo.csv # write CSV to foo.csv-- The '-O' option can be combined with '-o' to override the file-extension, if needed:--$ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt-- Some notes about the various output formats:--* Menu:--* CSV output::-* HTML output::-* JSON output::-* SQL output::---File: hledger.info, Node: CSV output, Next: HTML output, Up: Output format--6.2.1 CSV output------------------- * In CSV output, digit group marks (such as thousands separators) are- disabled automatically.---File: hledger.info, Node: HTML output, Next: JSON output, Prev: CSV output, Up: Output format--6.2.2 HTML output-------------------- * HTML output can be styled by an optional 'hledger.css' file in the- same directory.---File: hledger.info, Node: JSON output, Next: SQL output, Prev: HTML output, Up: Output format--6.2.3 JSON output-------------------- * This is not yet much used; real-world feedback is welcome.-- * Our JSON is rather large and verbose, since it is a faithful- representation 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.-- * 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)---File: hledger.info, Node: SQL output, Prev: JSON output, Up: Output format--6.2.4 SQL output------------------- * This is not yet much used; real-world feedback is welcome.-- * SQL output is expected to work at least with SQLite, MySQL and- Postgres.-- * For SQLite, it will be more useful if you modify the generated 'id'- field to be a PRIMARY KEY. Eg:-- $ hledger print -O sql | sed 's/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g' | ...-- * SQL output is structured with the expectations that statements will- be executed in the empty database. If you already have tables- created via SQL output of hledger, you would probably want to- either clear tables of existing data (via 'delete' or 'truncate'- SQL statements) or drop tables completely as otherwise your- postings will be duped.---File: hledger.info, Node: Commodity styles, Next: Colour, Prev: Output format, Up: Output--6.3 Commodity styles-====================--When displaying amounts, hledger infers a standard display style for-each commodity/currency, as described below in Commodity display style.-- If needed, this can be overridden by a '-c/--commodity-style' option-(except for cost amounts and amounts displayed by the 'print' command,-which are always displayed with all decimal digits). For example, the-following will force dollar amounts to be displayed as shown:--$ hledger print -c '$1.000,0'-- This option can repeated to set the display style for multiple-commodities/currencies. Its argument is as described in the commodity-directive.-- In some cases hledger will adjust number formatting to improve their-parseability (such as adding trailing decimal marks when needed).---File: hledger.info, Node: Colour, Next: Box-drawing, Prev: Commodity styles, Up: Output--6.4 Colour-==========--In terminal output, some commands can produce colour when the terminal-supports it:-- * if the '--color/--colour' option is given a value of 'yes' or- 'always' (or 'no' or 'never'), colour will (or will not) be used;- * otherwise, if the 'NO_COLOR' environment variable is set, colour- will not be used;- * otherwise, colour will be used if the output (terminal or file)- supports it.---File: hledger.info, Node: Box-drawing, Next: Paging, Prev: Colour, Up: Output--6.5 Box-drawing-===============--In terminal output, you can enable unicode box-drawing characters to-render prettier tables:-- * if the '--pretty' option is given a value of 'yes' or 'always' (or- 'no' or 'never'), unicode characters will (or will not) be used;- * otherwise, unicode characters will not be used.---File: hledger.info, Node: Paging, Next: Debug output, Prev: Box-drawing, Up: Output--6.6 Paging-==========--When showing long output in the terminal, hledger will try to use the-pager specified by the 'PAGER' environment variable, or 'less', or-'more'. (A pager is a helper program that shows one page at a time-rather than scrolling everything off screen). Currently it does this-only for help output, not for reports; specifically,-- * when listing commands, with 'hledger'- * when showing help with 'hledger [CMD] --help',- * when viewing manuals with 'hledger help' or 'hledger --man'.-- Note the pager is expected to handle ANSI codes, which hledger uses-eg for bold emphasis. For the common pager 'less' (and its 'more'-compatibility mode), we add 'R' to the 'LESS' and 'MORE' environment-variables to make this work. If you use a different pager, you might-need to configure it similarly, to avoid seeing junk on screen (let us-know). Otherwise, you can set the 'NO_COLOR' environment variable to 1-to disable all ANSI output (see Colour).---File: hledger.info, Node: Debug output, Prev: Paging, Up: Output--6.7 Debug output-================--We intend hledger to be relatively easy to troubleshoot, introspect and-develop. You can add '--debug[=N]' to any hledger command line to see-additional debug output. N ranges from 1 (least output, the default) to-9 (maximum output). Typically you would start with 1 and increase until-you are seeing enough. Debug output goes to stderr, and is not affected-by '-o/--output-file' (unless you redirect stderr to stdout, eg:-'2>&1'). It will be interleaved with normal output, which can help-reveal when parts of the code are evaluated. To capture debug output in-a log file instead, you can usually redirect stderr, eg:--hledger bal --debug=3 2>hledger.log---File: hledger.info, Node: Environment, Next: PART 2 DATA FORMATS, Prev: Output, Up: Top--7 Environment-*************--These environment variables affect hledger:-- *COLUMNS* This is normally set by your terminal; some hledger-commands ('register') will format their output to this width. If not-set, they will try to use the available terminal width.-- *LEDGER_FILE* The main journal file to use when not specified with-'-f/--file'. Default: '$HOME/.hledger.journal'.-- *NO_COLOR* If this environment variable is set (with any value),-hledger will not use ANSI color codes in terminal output, unless-overridden by an explicit '--color/--colour' option.---File: hledger.info, Node: PART 2 DATA FORMATS, Next: Journal, Prev: Environment, Up: Top--8 PART 2: DATA FORMATS-**********************---File: hledger.info, Node: Journal, Next: CSV, Prev: PART 2 DATA FORMATS, Up: Top--9 Journal-*********--hledger's usual data source is a plain text file containing journal-entries in hledger 'journal' format. If you're looking for a quick-reference, jump ahead to the journal cheatsheet (or use the table of-contents at https://hledger.org/hledger.html).-- This file represents an accounting General Journal. The '.journal'-file extension is most often used, though not strictly 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 compatible with most of Ledger's journal-format, but not all of it. The differences and interoperation tips are-described at hledger and Ledger. With some care, and by avoiding-incompatible features, you can keep your hledger journal readable by-Ledger and vice versa. This can useful eg for comparing the behaviour-of one app against the other.-- 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-configuration at hledger.org for the full list.-- A hledger journal file can contain three kinds of thing: comment-lines, transactions, and/or directives (including periodic transaction-rules and auto posting rules). Understanding the journal file format-will also give you a good understanding of hledger's data model. Here's-a quick cheatsheet/overview, followed by detailed descriptions of each-part.--* Menu:--* Journal cheatsheet::-* Comments::-* Transactions::-* Dates::-* Status::-* Code::-* Description::-* Transaction comments::-* Postings::-* Account names::-* Amounts::-* Balance assertions::-* Posting comments::-* Transaction balancing::-* Tags::-* Directives::-* account directive::-* alias directive::-* commodity directive::-* decimal-mark directive::-* include directive::-* P directive::-* payee directive::-* tag directive::-* Periodic transactions::-* Auto postings::-* Other syntax::---File: hledger.info, Node: Journal cheatsheet, Next: Comments, Up: Journal--9.1 Journal cheatsheet-======================--# Here is the main syntax of hledger's journal format-# (omitting extra Ledger compatibility syntax).--###############################################################################--# 1. These are comment lines, for notes or temporarily disabling things.-; They begin with # or ;--comment-Or, lines can be enclosed within "comment" / "end comment".-This is a block of -commented lines.-end comment--# Some journal entries can have semicolon comments at end of line ; like this-# Some of them require 2 or more spaces before the semicolon.--###############################################################################--# 2. Directives customise processing or output in some way.-# You don't need any directives to get started.-# But they can add more error checking, or change how things are displayed.-# They begin with a word, letter, or symbol. -# They are most often placed at the top, before transactions.--account assets ; Declare valid account names and display order.-account assets:savings ; A subaccount. This one represents a bank account.-account assets:checking ; Another. Note, 2+ spaces after the account name.-account assets:receivable ; Accounting type is inferred from english names,-account passifs ; or declared with a "type" tag, type:L-account expenses ; type:X- ; A follow-on comment line, indented.-account expenses:rent ; Expense and revenue categories are also accounts.- ; Subaccounts inherit their parent's type.--commodity $0.00 ; Declare valid commodities and their display styles.-commodity 1.000,00 EUR--decimal-mark . ; The decimal mark used in this file (if ambiguous).--payee Whole Foods ; Declare a valid payee name.--tag trip ; Declare a valid tag name.--P 2024-03-01 AAPL $179 ; Declare a market price for AAPL in $ on this date.--include other.journal ; Include another journal file here.--# Declare a recurring "periodic transaction", for budget/forecast reports-~ monthly set budget goals ; <- Note, 2+ spaces before the description.- (expenses:rent) $1000- (expenses:food) $500--# Declare an auto posting rule, to modify existing transactions in reports-= revenues:consulting- liabilities:tax:2024:us *0.25 ; Add a tax liability & expense- expenses:tax:2024:us *-0.25 ; for 25% of the revenue.--###############################################################################--# 3. Transactions are what it's all about.-# They are dated events, usually movements of money between 2 or more accounts.-# They begin with a numeric date.-# Here is their basic shape:-#-# DATE DESCRIPTION ; The transaction's date and optional description.-# ACCOUNT1 AMOUNT ; A posting of an amount to/from this account, indented.-# ACCOUNT2 AMOUNT ; A second posting, balancing the first.-# ... ; More if needed. Amounts must sum to zero.-# ; Note, 2+ spaces between account names and amounts.--2024-01-01 opening balances ; At the start, declare pre-existing balances this way.- assets:savings $10000 ; Account names can be anything. lower case is easy to type.- assets:checking $1000 ; assets, liabilities, equity, revenues, expenses are common.- liabilities:credit card $-500 ; liabilities, equity, revenues balances are usually negative.- equity:start ; One amount can be left blank. $-10500 is inferred here.- ; Some of these accounts we didn't declare above,- ; so -s/--strict would complain.--2024-01-03 ! (12345) pay rent- ; Additional transaction comment lines, indented.- ; There can be a ! or * after the date meaning "pending" or "cleared".- ; There can be a parenthesised (code) after the date/status.- ; Amounts' sign shows direction of flow.- assets:checking $-500 ; Minus means removed from this account (credit).- expenses:rent $500 ; Plus means added to this account (debit).--; Keeping transactions in date order is optional (but helps error checking).--2024-01-02 Gringott's Bank | withdrawal ; Description can be PAYEE | NOTE- assets:bank:gold -10 gold- assets:pouch 10 gold--2024-01-02 shopping- expenses:clothing 1 gold- expenses:wands 5 gold- assets:pouch -6 gold--2024-01-02 receive gift- revenues:gifts -3 "Chocolate Frogs" ; Complex commodity symbols- assets:pouch 3 "Chocolate Frogs" ; must be in double quotes.--2024-01-15 buy some shares, in two lots ; Cost can be noted.- assets:investments:2024-01-15 2.0 AAAA @ $1.50 ; @ means per-unit cost- assets:investments:2024-01-15-02 3.0 AAAA @@ $4 ; @@ means total cost- ; ^ Per-lot subaccounts are sometimes useful.- assets:checking $-7--2024-01-15 assert some account balances on this date- ; Balances can be asserted in any transaction, with =, for extra error checking.- ; Assertion txns like this one can be made with hledger close --assert --show-costs- ;- assets:savings $0 = $10000- assets:checking $0 = $493- assets:bank:gold 0 gold = -10 gold- assets:pouch 0 gold = 4 gold- assets:pouch 0 "Chocolate Frogs" = 3 "Chocolate Frogs"- assets:investments:2024-01-15 0.0 AAAA = 2.0 AAAA @ $1.50- assets:investments:2024-01-15-02 0.0 AAAA = 3.0 AAAA @@ $4- liabilities:credit card $0 = $-500--2024-02-01 note some event, or a transaction not yet fully entered, on this date- ; Postings are not required.--; Some other date formats are allowed (but, consistent YYYY-MM-DD is useful).-2024.01.01-2024/1/1---File: hledger.info, Node: Comments, Next: Transactions, Prev: Journal cheatsheet, Up: Journal--9.2 Comments-============--Lines in the journal will be ignored if they begin with a hash ('#') or-a semicolon (';'). (See also Other syntax.) hledger will also ignore-regions beginning with a 'comment' line and ending with an 'end comment'-line (or file end). Here's a suggestion for choosing between them:-- * '#' for top-level notes- * ';' for commenting out things temporarily- * 'comment' for quickly commenting large regions (remember it's- there, or you might get confused)-- Eg:--# a comment line-; another commentline-comment-A multi-line comment block,-continuing until "end comment" directive-or the end of the current file.-end comment-- Some hledger entries can have same-line comments attached to them,-from ; (semicolon) to end of line. See Transaction comments, Posting-comments, and Account comments below.---File: hledger.info, Node: Transactions, Next: Dates, Prev: Comments, Up: Journal--9.3 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-simple date in column 0. This can be followed by any of the following-optional fields, separated by spaces:-- * a status character (empty, '!', or '*')- * a code (any short number or text, enclosed in parentheses)- * a description (any remaining text until end of line or a semicolon)- * a comment (any remaining text following a semicolon until end of- line, and any following indented lines beginning with a semicolon)- * 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---File: hledger.info, Node: Dates, Next: Status, Prev: Transactions, Up: Journal--9.4 Dates-=========--* Menu:--* Simple dates::-* Posting dates::---File: hledger.info, Node: Simple dates, Next: Posting dates, Up: Dates--9.4.1 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-current transaction, the default year set with a 'Y' 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.)---File: hledger.info, Node: Posting dates, Prev: Simple dates, Up: Dates--9.4.2 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.-The 'date:' tag must have a valid simple date value if it is present, eg-a 'date:' tag with no value is not allowed.---File: hledger.info, Node: Status, Next: Code, Prev: Dates, Up: Journal--9.5 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 (and you can combine these, eg-'-UP' to match all except cleared things). Or you can use the-'status:', 'status:!', and 'status:*' queries, or the U, P, C keys in-hledger-ui.-- (Note: in Ledger the "unmarked" state is called "uncleared"; in-hledger we renamed it to "unmarked" for semantic clarity.)-- Status marks are optional, but can be helpful eg for reconciling with-real-world accounts. Some editor modes provide highlighting and-shortcuts for working with status. Eg in Emacs ledger-mode, you can-toggle transaction status with C-c C-e, or posting status with C-c C-c.-- 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- reconciliation)-cleared complete, reconciled as far as possible, and considered- correct-- 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.---File: hledger.info, Node: Code, Next: Description, Prev: Status, Up: Journal--9.6 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.---File: hledger.info, Node: Description, Next: Transaction comments, Prev: Code, Up: Journal--9.7 Description-===============--After the date, status mark and/or code fields, the rest of the line (or-until a comment is begun with ';') is the transaction's description.-Here you can describe the transaction (called the "narration" in-traditional bookkeeping), or you can record a payee/payer name, or you-can leave it empty.-- Transaction descriptions show up in print output and in register-reports, and can be listed with the descriptions command.-- You can query by description with 'desc:DESCREGEX', or pivot on-description with '--pivot desc'.--* Menu:--* Payee and note::---File: hledger.info, Node: Payee and note, Up: Description--9.7.1 Payee and note-----------------------Sometimes people want a dedicated payee/payer field that can be queried-and checked more strictly. If you want that, you can write a '|' (pipe)-character in the description. This divides it into a "payee" field on-the left, and a "note" field on the right. (Either can be empty.)-- You can query these with 'payee:PAYEEREGEX' and 'note:NOTEREGEX',-list their values with the payees and notes commands, or pivot on-'payee' or 'note'.-- Note: in transactions with no '|' character, description, payee, and-note all have the same value. Once a '|' is added, they become-distinct. (If you'd like to change this behaviour, please propose it on-the mail list.)-- If you want more strict error checking, you can declare the valid-payee names with payee directives, and then enforce these with hledger-check payees. (Note: because of the above, for this you'll need to-ensure every transaction description contains a '|' and therefore a-checkable payee name, even if it's empty.)---File: hledger.info, Node: Transaction comments, Next: Postings, Prev: Description, Up: Journal--9.8 Transaction comments-========================--Text following ';', after a transaction description, and/or on indented-lines immediately below it, form comments for that transaction. They-are reproduced by 'print' but otherwise ignored, except they may contain-tags, which are not ignored.--2012-01-01 something ; a transaction comment- ; a second line of transaction comment- expenses 1- assets---File: hledger.info, Node: Postings, Next: Account names, Prev: Transaction comments, Up: Journal--9.9 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:-- * (optional) a status character (empty, '!', or '*'), followed by a- space- * (required) an account name (any text, optionally containing *single- spaces*, until end of line or a double space)- * (optional) *two or more spaces* (or tabs) followed by an amount.-- If the amount is positive, it is being added to the account; if-negative, it is being removed from the account.-- The posting amounts in a transaction must sum up to zero, indicating-that the inflows and outflows are equal. We call this a balanced-transaction. (You can read more about the nitty-gritty details of "sum-up to zero" in Transaction balancing below.)-- As a convenience, you can optionally leave one amount blank; hledger-will infer what it should be so as to balance the transaction.--* Menu:--* Debits and credits::-* The two space delimiter::---File: hledger.info, Node: Debits and credits, Next: The two space delimiter, Up: Postings--9.9.1 Debits and credits---------------------------The traditional accounting concepts of debit and credit of course exist-in hledger, but we represent them with numeric sign, as described above.-Positive and negative posting amounts represent debits and credits-respectively.-- You don't need to remember that, but if you would like to - eg for-helping newcomers or for talking with your accountant - here's a handy-mnemonic:-- _'debit / plus / left / short words'_-_'credit / minus / right / longer words'_---File: hledger.info, Node: The two space delimiter, Prev: Debits and credits, Up: Postings--9.9.2 The two space delimiter--------------------------------Be sure to notice the unusual separator between the account name and the-following amount. Because hledger allows account names with spaces in-them, you must separate the account name and amount (if any) by *two or-more spaces* (or tabs). It's easy to forget at first. If you ever see-the amount being treated as part of the account name, you'll know you-probably need to add another space between them.---File: hledger.info, Node: Account names, Next: Amounts, Prev: Postings, Up: Journal--9.10 Account names-==================--Accounts are the main way of categorising things in hledger. As in-Double Entry Bookkeeping, they can represent real world accounts (such-as a bank account), or more abstract categories such as "money borrowed-from Frank" or "money spent on electricity".-- You can use any account names you like, but we usually start with the-traditional accounting categories, which in english are 'assets',-'liabilities', 'equity', 'revenues', 'expenses'. (You might see these-referred to as A, L, E, R, X for short.)-- For more precise reporting, we usually divide the top level accounts-into more detailed subaccounts, by writing a full colon between account-name parts. For example, from the account names 'assets:bank:checking'-and 'expenses:food', hledger will infer this hierarchy of five accounts:--assets-assets:bank-assets:bank:checking-expenses-expenses:food-- Shown as an outline, the hierarchical tree structure is more clear:--assets- bank- checking-expenses- food-- hledger reports can summarise the account tree to any depth, so you-can go as deep as you like with subcategories, but keeping your account-names relatively simple may be best when starting out.-- Account names may be capitalised or not; they may contain letters,-numbers, symbols, or single spaces. Note, when an account name and an-amount are written on the same line, they must be separated by *two or-more spaces* (or tabs).-- Parentheses or brackets enclosing the full account name indicate-virtual postings, described below. Parentheses or brackets internal to-the account name have no special meaning.-- Account names can be altered temporarily or permanently by account-aliases.---File: hledger.info, Node: Amounts, Next: Balance assertions, Prev: Account names, Up: Journal--9.11 Amounts-============--After the account name, there is usually an amount. (Remember: 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-"quantity"):--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-commodity 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--* Menu:--* Decimal marks::-* Digit group marks::-* Commodity::-* Costs::---File: hledger.info, Node: Decimal marks, Next: Digit group marks, Up: Amounts--9.11.1 Decimal marks-----------------------A _decimal mark_ can be written as a period or a comma:--1.23-1,23-- Both of these are common in international number formats, so hledger-is not biased towards one or the other. Because hledger also supports-digit group marks (eg thousands separators), this means that a number-like '1,000' or '1.000' containing just one period or comma is-ambiguous. In such cases, hledger by default assumes it is a decimal-mark, and will parse both of those as 1.-- To help hledger parse such ambiguous numbers more accurately, if you-use digit group marks, we recommend declaring the decimal mark-explicitly. The best way is to add a 'decimal-mark' directive at the-top of each data file, like this:--decimal-mark .-- Or you can declare it per commodity with 'commodity' directives,-described below.-- hledger also accepts numbers like '10.' with no digits after the-decimal mark (and will sometimes display numbers that way to-disambiguate them - see Trailing decimal marks).---File: hledger.info, Node: Digit group marks, Next: Commodity, Prev: Decimal marks, Up: Amounts--9.11.2 Digit group marks---------------------------In the integer part of the amount quantity (left of the decimal mark),-groups of digits can optionally be separated by a _digit group mark_ - a-comma or period (whichever is not used as decimal mark), or a space-(several Unicode space variants, like no-break space, are also-accepted). So these are all valid amounts in a journal file:-- $1,000,000.00- EUR 2.000.000,00-INR 9,99,99,999.00- 1 000 000.00 ; <- ordinary space - 1 000 000.00 ; <- no-break space---File: hledger.info, Node: Commodity, Next: Costs, Prev: Digit group marks, Up: Amounts--9.11.3 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-punctuation), 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.-- By default, the format of amounts in the journal influences how-hledger displays them in output. This is explained in Commodity display-style below.---File: hledger.info, Node: Costs, Prev: Commodity, Up: Amounts--9.11.4 Costs---------------After a posting amount, you can note its cost (when buying) or selling-price (when selling) in another commodity, by writing either '@-UNITPRICE' or '@@ TOTALPRICE' after it. This indicates a conversion-transaction, where one commodity is exchanged for another.-- (You might also see this called "transaction price" in hledger docs,-discussions, or code; that term was directionally neutral and reminded-that it is a price specific to a transaction, but we now just call it-"cost", with the understanding that the transaction could be a purchase-or a sale.)-- Costs are usually written explicitly with '@' or '@@', but can also-be inferred automatically for simple multi-commodity transactions.-Note, if costs are inferred, the order of postings is significant; the-first posting will have a cost attached, in the commodity of the second.-- As an example, here are several ways to record purchases of a foreign-currency in hledger, using the cost notation either explicitly or-implicitly:-- 1. Write the price per unit, as '@ UNITPRICE' after the amount:-- 2009/1/1- assets:euros €100 @ $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 €100 @@ $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.- Note the effect of posting order: the price is added to first- posting, making it '€100 @@ $135', as in example 2:-- 2009/1/1- assets:euros €100 ; one hundred euros purchased- assets:dollars $-135 ; for $135-- Amounts can be converted to cost at report time using the '-B/--cost'-flag; this is discussed more in the Cost reporting section.-- Note that the cost normally should be a positive amount, though it's-not required to be. This can be a little confusing, see discussion at--infer-market-prices: market prices from transactions.---File: hledger.info, Node: Balance assertions, Next: Posting comments, Prev: Amounts, Up: Journal--9.12 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 protect 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, described below).--* Menu:--* Assertions and ordering::-* Assertions and multiple included files::-* Assertions and multiple -f files::-* Assertions and costs::-* Assertions and commodities::-* Assertions and subaccounts::-* Assertions and virtual postings::-* Assertions and auto postings::-* Assertions and precision::---File: hledger.info, Node: Assertions and ordering, Next: Assertions and multiple included files, Up: Balance assertions--9.12.1 Assertions and ordering---------------------------------hledger calculates and checks an account's balance assertions in date-order (and when there are multiple assertions on the same day, in parse-order). Note this is different from Ledger, which checks assertions-always in parse order, ignoring dates.-- This means in hledger you can freely reorder transactions, postings,-or files, and balance assertions will usually keep working. The-exception is when you reorder multiple postings on the same day, to the-same account, which have balance assertions; those will likely need-updating.---File: hledger.info, Node: Assertions and multiple included files, Next: Assertions and multiple -f files, Prev: Assertions and ordering, Up: Balance assertions--9.12.2 Assertions and multiple included files------------------------------------------------Multiple files included with the 'include' directive are processed as if-concatenated into one file, preserving their order and the posting order-within each file. It means that balance assertions in later files will-see balance from earlier files.-- And if you have multiple postings to an account on the same day,-split across multiple files, and you want to assert the account's-balance on that day, you'll need to put the assertion in the right file-- the last one in the sequence, probably.---File: hledger.info, Node: Assertions and multiple -f files, Next: Assertions and costs, Prev: Assertions and multiple included files, Up: Balance assertions--9.12.3 Assertions and multiple -f files------------------------------------------Unlike 'include', when multiple files are specified on the command line-with multiple '-f/--file' options, balance assertions will not see-balance from earlier files. This can be useful when you do not want-problems in earlier files to disrupt valid assertions in later files.-- If you do want assertions to see balance from earlier files, use-'include', or concatenate the files temporarily.---File: hledger.info, Node: Assertions and costs, Next: Assertions and commodities, Prev: Assertions and multiple -f files, Up: Balance assertions--9.12.4 Assertions and costs------------------------------Balance assertions ignore costs, and should normally be written without-one:--2019/1/1- (a) $1 @ €1 = $1-- We do allow costs to be written in balance assertion amounts,-however, and print shows them, but 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-costs), and because balance _assignments_ do use costs (see below).---File: hledger.info, Node: Assertions and commodities, Next: Assertions and subaccounts, Prev: Assertions and costs, Up: Balance assertions--9.12.5 Assertions and commodities------------------------------------The balance assertions described so far are "*single commodity balance-assertions*": they assert and check the balance in one commodity,-ignoring any others that may be present. This is how balance assertions-work in Ledger also.-- If an account contains multiple commodities, you can assert their-balances by writing multiple postings with balance assertions, one for-each commodity:--2013/1/1- usd $-1- eur €-1- both--2013/1/2- both 0 = $1- both 0 = €1-- In hledger you can make a stronger "*sole commodity balance-assertion*" by writing two equals signs ('== EXPECTEDBALANCE'). This-also asserts that there are no other commodities in the account besides-the asserted one (or at least, that their current balance is zero):--2013/1/1- usd $-1 == $-1 ; these sole commodity assertions succeed- eur €-1 == €-1- both ;== $1 ; this one would fail because 'both' contains $ and €-- It's less easy to make a "*sole commodities balance assertion*" (note-the plural) - ie, asserting that an account contains two or more-specified commodities and no others. It can be done by-- 1. isolating each commodity in a subaccount, and asserting those- 2. and also asserting there are no commodities in the parent account- itself:--2013/1/1- usd $-1- eur €-1- both 0 == 0 ; nothing up my sleeve- both:usd $1 == $1 ; a dollar here- both:eur €1 == €1 ; a euro there---File: hledger.info, Node: Assertions and subaccounts, Next: Assertions and virtual postings, Prev: Assertions and commodities, Up: Balance assertions--9.12.6 Assertions and subaccounts------------------------------------All of the balance assertions above (both '=' and '==') are-"*subaccount-exclusive balance assertions*"; they ignore any balances-that exist in deeper subaccounts.-- In hledger you can make "*subaccount-inclusive balance assertions*"-by adding a star after the equals ('=*' or '==*'):--2019/1/1- equity:start- assets:checking $10- assets:savings $10- assets $0 ==* $20 ; assets + subaccounts contains $20 and nothing else---File: hledger.info, Node: Assertions and virtual postings, Next: Assertions and auto postings, Prev: Assertions and subaccounts, Up: Balance assertions--9.12.7 Assertions and virtual postings-----------------------------------------Balance assertions always consider both real and virtual postings; they-are not affected by the '--real/-R' flag or 'real:' query.---File: hledger.info, Node: Assertions and auto postings, Next: Assertions and precision, Prev: Assertions and virtual postings, Up: Balance assertions--9.12.8 Assertions and auto postings--------------------------------------Balance assertions _are_ affected by the '--auto' flag, which generates-auto postings, which can alter account balances. Because auto postings-are optional in hledger, accounts affected by them effectively have two-balances. But balance assertions can only test one or the other of-these. So to avoid making fragile assertions, either:-- * assert the balance calculated with '--auto', and always use- '--auto' with that file- * or assert the balance calculated without '--auto', and never use- '--auto' with that file- * or avoid balance assertions on accounts affected by auto postings- (or avoid auto postings entirely).---File: hledger.info, Node: Assertions and precision, Prev: Assertions and auto postings, Up: Balance assertions--9.12.9 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 assertions. Balance-assertion failure messages show exact amounts.---File: hledger.info, Node: Posting comments, Next: Transaction balancing, Prev: Balance assertions, Up: Journal--9.13 Posting comments-=====================--Text following ';', at the end of a posting line, and/or on indented-lines immediately below it, form comments for that posting. They are-reproduced by 'print' but otherwise ignored, except they may contain-tags, which are not ignored.--2012-01-01- expenses 1 ; a comment for posting 1- assets- ; a comment for posting 2- ; a second comment line for posting 2---File: hledger.info, Node: Transaction balancing, Next: Tags, Prev: Posting comments, Up: Journal--9.14 Transaction balancing-==========================--How exactly does hledger decide when a transaction is balanced ? The-general goal is that if you look at the journal entry and calculate the-amounts' sum perfectly with pencil and paper, hledger should agree with-you.-- Real world transactions, especially for investments or-cryptocurrencies, often involve imprecise costs, complex decimals,-and/or infinitely-recurring decimals, which are difficult or-inconvenient to handle on a computer. So to be a practical accounting-system, hledger allows some imprecision when checking transaction-balancedness. The question is, how much imprecision should be allowed ?-- hledger currently decides it based on the commodity display styles:-if the postings' sum would appear to be zero when displayed with the-standard display precisions, the transaction is considered balanced.-- Or equivalently: if the journal entry is displayed with amounts-rounded to the standard display precisions (with 'hledger print---round=hard'), and a human with pencil and paper would agree that those-displayed amounts add up to zero, the transaction is considered-balanced.-- This has some advantages: it is fairly intuitive, general not-hard-coded, yet configurable when needed. On the downside it means that-transaction balancedness is related to commodity display precisions, so-eg when using '-c/--commodity-style' to display things with more than-usual precision, you might need to fix some of your journal entries (ie,-add decimal digits to make them balance more precisely).-- Other PTA tools (Ledger, Beancount..) have their own ways of doing-it. Possible improvements are discussed at #1964.-- Note: if you have multiple journal files, and are relying on-commodity directives to make imprecise journal entries balance, the-directives' placement might be important - see 'commodity' directive.---File: hledger.info, Node: Tags, Next: Directives, Prev: Transaction balancing, Up: Journal--9.15 Tags-=========--Tags are a way to add extra labels or data fields to transactions,-postings, or accounts, which you can then search or pivot on.-- A tag is a word, optionally hyphenated, immediately followed by a-full colon, in the comment of a transaction, a posting, or an account-directive. Eg: '2024-01-01 a transaction ; foo:' Note this is an-exception to the usual rule that things in comments are ignored.-- You can write multiple tags on one line, separated by comma. Or you-can write each tag on its own comment line (no comma needed in this-case).-- For example, here are five different tags: one on the-'assets:checking' account, two on the transaction, and two on the-'expenses:food' posting:--account assets:checking ; accounttag:--2017/1/16 bought groceries ; transactiontag-1:- ; transactiontag-2:- assets:checking $-1- expenses:food $1 ; postingtag:, another-posting-tag:-- Postings also inherit tags from their transaction and their account.-And transactions also acquire tags from their postings (and postings'-accounts). So in the example above, the expenses posting effectively-has all five tags (by inheriting from the account and transaction), and-the transaction also has all five tags (by acquiring from the expenses-posting).--* Menu:--* Tag names::-* Special tags::-* Tag values::---File: hledger.info, Node: Tag names, Next: Special tags, Up: Tags--9.15.1 Tag names-------------------Most non-whitespace characters are allowed in tag names. Eg '😀:' is a-valid tag.-- You can list the tag names used in your journal with the tags-command:-'hledger tags [NAMEREGEX]'-- In commands which use a query, you can match by tag name. Eg:-'hledger print tag:NAMEREGEX'-- You can declare valid tag names with the tag directive and then check-them with the check command.---File: hledger.info, Node: Special tags, Next: Tag values, Prev: Tag names, Up: Tags--9.15.2 Special tags----------------------Some tag names have special significance to hledger. There's not much-harm in using them yourself, but some could produce an error message,-particularly the 'date:' and 'type:' tags. They are explained-elsewhere, but here is a quick list for reference:-- Tags you can set to influence hledger's behaviour:-- date -- overrides a posting's date- date2 -- overrides a posting's secondary date- type -- declares an account's type-- Tags hledger adds to indicate generated data:-- t -- appears on postings generated by timedot letters- assert -- appears on txns generated by close --assert- retain -- appears on txns generated by close --retain- start -- appears on txns generated by close --migrate/--close/--open/--assign- generated-transaction -- appears on generated periodic txns (with --verbose-tags)- generated-posting -- appears on generated auto postings (with --verbose-tags)- modified -- appears on txns which have had auto postings added (with --verbose-tags)-Not displayed, but queryable:- _generated-transaction -- exists on generated periodic txns (always)- _generated-posting -- exists on generated auto postings (always)- _modified -- exists on txns which have had auto postings added (always)-- Tags hledger uses internally:-- _conversion-matched -- exists on postings which have been matched with a nearby @/@@ cost annotation---File: hledger.info, Node: Tag values, Prev: Special tags, Up: Tags--9.15.3 Tag values--------------------Tags can have a value, which is any text after the colon up until a-comma or end of line, with surrounding whitespace removed. Ending at-comma allows us to write multiple tags on one line, but also means that-tag values can not contain commas.-- Eg in the following posting, the three tags' values are "value 1",-"value 2", and "" (empty) respectively:-- expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz-- Multiple tags with the same name are additive rather than overriding:-when the same tag name is seen again with a new value, the new-name:value pair is added to the tags. It is not possible to override a-previous tag's value or remove a tag.-- You can list all the values used for a particular tag in the journal-with-'hledger tags TAGNAME --values'-- You can match on tag values with a query like-'tag:NAMEREGEX=VALUEREGEX'---File: hledger.info, Node: Directives, Next: account directive, Prev: Tags, Up: Journal--9.16 Directives-===============--Besides transactions, there is something else you can put in a 'journal'-file: directives. These are declarations, beginning with a keyword,-that modify hledger's behaviour. Some directives can have more specific-subdirectives, indented below them. hledger's directives are similar to-Ledger's in many cases, but there are also many differences. Directives-are not required, but can be useful. Here are the main directives:--purpose directive----------------------------------------------------------------------------*READING DATA:*-Rewrite account names 'alias'-Comment out sections of the file 'comment'-Declare file's decimal mark, to help 'decimal-mark'-parse amounts accurately-Include other data files 'include'-*GENERATING DATA:*-Generate recurring transactions or '~'-budget goals-Generate extra postings on existing '='-transactions-*CHECKING FOR ERRORS:*-Define valid entities to provide more 'account', 'commodity',-error checking 'payee', 'tag'-*REPORTING:*-Declare accounts' type and display 'account'-order-Declare commodity display styles 'commodity'-Declare market prices 'P'--* Menu:--* Directives and multiple files::-* Directive effects::---File: hledger.info, Node: Directives and multiple files, Next: Directive effects, Up: Directives--9.16.1 Directives and multiple files---------------------------------------Directives vary in their scope, ie which journal entries and which input-files they affect. Most often, a directive will affect the following-entries and included files if any, until the end of the current file --and no further. You might find this inconvenient! For example, 'alias'-directives do not affect parent or sibling files. But there are usually-workarounds; for example, put 'alias' directives in your top-most file,-before including other files.-- The restriction, though it may be annoying at first, is in a good-cause; it allows reports to be stable and deterministic, independent of-the order of input. Without it, reports could show different numbers-depending on the order of -f options, or the positions of include-directives in your files.---File: hledger.info, Node: Directive effects, Prev: Directives and multiple files, Up: Directives--9.16.2 Directive effects---------------------------Here are all hledger's directives, with their effects and scope-summarised - nine main directives, plus four others which we consider-non-essential:--directivewhat it does ends- at- file- end?-----------------------------------------------------------------------------*'account'*Declares an account, for checking all entries in all files; andN- its display order and type. Subdirectives: any text, ignored.-*'alias'*Rewrites account names, in following entries until end of Y- current file or 'end aliases'. Command line equivalent:- '--alias'-*'comment'*Ignores part of the journal file, until end of current file orY- 'end comment'.-*'commodity'*Declares up to four things: 1. a commodity symbol, for checkingN,N,Y,Y- all amounts in all files 2. the display style for all amounts- of this commodity 3. the decimal mark for parsing amounts of- this commodity, in the rest of this file and its children, if- there is no 'decimal-mark' directive 4. the precision to use- for balanced-transaction checking in this commodity, in this- file and its children. Takes precedence over 'D'.- Subdirectives: 'format' (ignored). Command line equivalent:- '-c/--commodity-style'-*'decimal-mark'*Declares the decimal mark, for parsing amounts of all Y- commodities in following entries until next 'decimal-mark' or- end of current file. Included files can override. Takes- precedence over 'commodity' and 'D'.-*'include'*Includes entries and directives from another file, as if theyN- were written inline. Command line alternative: multiple- '-f/--file'-*'payee'*Declares a payee name, for checking all entries in all files. N-*'P'*Declares the market price of a commodity on some date, for value N- reports.-*'~'*Declares a periodic transaction rule that generates future N-(tilde)transactions with '--forecast' and budget goals with 'balance- --budget'.-Other-syntax:-*'applyPrepends a common parent account to all account names, in Y-account'*following entries until end of current file or 'end apply- account'.-*'D'*Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N- there is no 'commodity' directive for this commodity: its- decimal mark, balancing precision, and display style, as above.-*'Y'*Sets a default year to use for any yearless dates, in following Y- entries until end of current file.-*'='*Declares an auto posting rule that generates extra postings on partly-(equals)matched transactions with '--auto', in current, parent, and- child files (but not sibling files, see #1212).-*OtherOther directives from Ledger's file format are accepted but-Ledgerignored.-directives*---File: hledger.info, Node: account directive, Next: alias directive, Prev: Directives, Up: Journal--9.17 'account' directive-========================--'account' directives can be used to declare accounts (ie, the places-that amounts are transferred from and to). Though not required, these-declarations can provide several benefits:-- * They can document your intended chart of accounts, providing a- reference.- * They can store additional account information as comments, or as- tags which can be used to filter or pivot reports.- * They can restrict which accounts may be posted to by transactions,- eg in strict mode, which helps prevent errors.- * They influence account display order in reports, allowing- non-alphabetic sorting (eg Revenues to appear above Expenses).- * They can help hledger know your accounts' types (asset, liability,- equity, revenue, expense), enabling reports like balancesheet and- incomestatement.- * They help with account name completion (in hledger add,- hledger-web, hledger-iadd, ledger-mode, etc.)-- They are written as the word 'account' followed by a hledger-style-account name. Eg:--account assets:bank:checking-- Ledger-style indented subdirectives are also accepted, but ignored:--account assets:bank:checking- format subdirective ; currently ignored--* Menu:--* Account comments::-* Account error checking::-* Account display order::-* Account types::---File: hledger.info, Node: Account comments, Next: Account error checking, Up: account directive--9.17.1 Account comments--------------------------Text following *two or more spaces* and ';' at the end of an account-directive line, and/or following ';' on indented lines immediately below-it, form comments for that account. They are ignored except they may-contain tags, which are not ignored.-- The two-space requirement for same-line account comments is because-';' is allowed in account names.--account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon- ; next-line comment- ; some tags - type:A, acctnum:12345---File: hledger.info, Node: Account error checking, Next: Account display order, Prev: Account comments, Up: account directive--9.17.2 Account error checking--------------------------------By default, accounts need not be declared; they come into existence when-a posting references them. This is convenient, but it means hledger-can't warn you when you mis-spell an account name in the journal.-Usually you'll find that error later, as an extra account in balance-reports, or an incorrect 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:-- * The declaration is case-sensitive; transactions must use the- correct account name capitalisation.- * The account directive's scope is "whole file and below" (see- directives). This means it affects all of the current file, and- any files it includes, but not parent or sibling files. The- position of account directives within the file does not matter,- though it's usual to put them at the top.- * Accounts can only be declared in 'journal' files, but will affect- included files of all types.- * It's currently not possible to declare "all possible subaccounts"- with a wildcard; every account posted to must be declared.---File: hledger.info, Node: Account display order, Next: Account types, Prev: Account error checking, Up: account directive--9.17.3 Account display order-------------------------------Account directives also cause hledger to display accounts in a-particular order, not just alphabetically. Eg, here is a conventional-ordering for the top-level accounts:--account assets-account liabilities-account equity-account revenues-account expenses-- Now hledger displays them in that order:--$ hledger accounts-assets-liabilities-equity-revenues-expenses-- If there are undeclared accounts, those will be displayed last, in-alphabetical order.-- Sorting is done within each group of sibling accounts, at each level-of the account tree. Eg, a declaration like 'account parent:child'-influences 'child''s position among its siblings.-- Note, it does not affect 'parent''s position; for that, you need an-'account parent' declaration.-- Sibling accounts are always displayed together; hledger won't display-'x:y' in between 'a:b' and 'a:c'.-- An account directive both declares an account as a valid posting-target, and declares its display order; you can't easily do one without-the other.---File: hledger.info, Node: Account types, Prev: Account display order, Up: account directive--9.17.4 Account types-----------------------hledger knows that accounts come in several types: assets, liabilities,-expenses and so on. This enables easy reports like balancesheet and-incomestatement, and filtering by account type with the 'type:' query.-- As a convenience, hledger will detect these account types-automatically if you are using common english-language top-level account-names (described below). But it's more robust to declare accounts'-types explicitly, by adding 'type:' tags to their account directives.-The tag's value should be one of the five main account types:-- * 'A' or 'Asset' (things you own)- * 'L' or 'Liability' (things you owe)- * 'E' or 'Equity' (investment/ownership; balanced counterpart of- assets & liabilities)- * 'R' or 'Revenue' (what you received money from, AKA income;- technically part of Equity)- * 'X' or 'Expense' (what you spend money on; technically part of- Equity)-- or, it can be (these are used less often):-- * 'C' or 'Cash' (a subtype of Asset, indicating liquid assets for the- cashflow report)- * 'V' or 'Conversion' (a subtype of Equity, for conversions (see Cost- reporting).)-- Subaccounts inherit their parent's type, or they can override it.-Here is a typical set of account type declarations:--account assets ; type: A-account liabilities ; type: L-account equity ; type: E-account revenues ; type: R-account expenses ; type: X--account assets:bank ; type: C-account assets:cash ; type: C--account equity:conversion ; type: V-- Here are some tips for working with account types.-- * The rules for inferring types from account names are as follows.- These are just a convenience that sometimes help new users get- going; if they don't work for you, just ignore them and declare- your account types. See also Regular expressions.-- If account's name contains this (CI) regular expression: | its type is:- --------------------------------------------------------------------|-------------- ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash- ^assets?(:|$) | Asset- ^(debts?|liabilit(y|ies))(:|$) | Liability- ^equity:(trad(e|ing)|conversion)s?(:|$) | Conversion- ^equity(:|$) | Equity- ^(income|revenue)s?(:|$) | Revenue- ^expenses?(:|$) | Expense-- * If you declare any account types, it's a good idea to declare an- account for all of the account types, because a mixture of declared- and name-inferred types can disrupt certain reports.-- * Certain uses of account aliases can disrupt account types. See- Rewriting accounts > Aliases and account types.-- * As mentioned above, subaccounts will inherit a type from their- parent account. More precisely, an account's type is decided by- the first of these that exists:-- 1. A 'type:' declaration for this account.- 2. A 'type:' declaration in the parent accounts above it,- preferring the nearest.- 3. An account type inferred from this account's name.- 4. An account type inferred from a parent account's name,- preferring the nearest parent.- 5. Otherwise, it will have no type.-- * For troubleshooting, you can list accounts and their types with:-- $ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]---File: hledger.info, Node: alias directive, Next: commodity directive, Prev: account directive, Up: Journal--9.18 'alias' directive-======================--You can define account alias rules which rewrite your account names, or-parts of them, before generating reports. This can be useful for:-- * expanding shorthand account names to their full form, allowing- easier data entry and a less verbose journal- * adapting old journals to your current chart of accounts- * experimenting with new account organisations, like a new hierarchy- * combining two accounts into one, eg to see their sum or difference- on one line- * 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.-- Account aliases are very powerful. They are generally easy to use-correctly, but you can also generate invalid account names with them;-more on this below.-- See also Rewrite account names.--* Menu:--* Basic aliases::-* Regex aliases::-* Combining aliases::-* Aliases and multiple files::-* end aliases directive::-* Aliases can generate bad account names::-* Aliases and account types::---File: hledger.info, Node: Basic aliases, Next: Regex aliases, Up: alias directive--9.18.1 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.-Subaccounts 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"---File: hledger.info, Node: Regex aliases, Next: Combining aliases, Prev: Basic aliases, Up: alias directive--9.18.2 Regex aliases-----------------------There is also a more powerful variant that uses a regular expression,-indicated by wrapping the pattern in forward slashes. (This is the only-place where hledger requires forward slashes around a regular-expression.)-- Eg:--alias /REGEX/ = REPLACEMENT-- or:--$ hledger --alias '/REGEX/=REPLACEMENT' ...-- Any part of an account name matched by REGEX will be replaced by-REPLACEMENT. REGEX is case-insensitive as usual.-- If you need to match a forward slash, escape it with a backslash, eg-'/\/=:'.-- If REGEX contains parenthesised match groups, these can be referenced-by the usual backslash and number in REPLACEMENT:--alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3-; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"-- REPLACEMENT continues to the end of line (or on command line, to end-of option argument), so it can contain trailing whitespace.---File: hledger.info, Node: Combining aliases, Next: Aliases and multiple files, Prev: Regex aliases, Up: alias directive--9.18.3 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:-- * the nearest alias declaration before/above the entry is applied- first- * the next alias before/above that will be be applied next, and so on- * aliases defined after/below the entry do not affect it.-- This gives nearby aliases precedence over distant ones, and helps-provide semantic stability - aliases will keep working the same way-independent of which files are being read and in which order.-- In case of trouble, adding '--debug=6' to the command line will show-which aliases are being applied when.---File: hledger.info, Node: Aliases and multiple files, Next: end aliases directive, Prev: Combining aliases, Up: alias directive--9.18.4 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--2023-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--2023-01-01 ; affected by aliases above- foo 1- bar--include c.journal ; also affected---File: hledger.info, Node: end aliases directive, Next: Aliases can generate bad account names, Prev: Aliases and multiple files, Up: alias directive--9.18.5 'end aliases' directive---------------------------------You can clear (forget) all currently defined aliases (seen in the-journal so far, or defined on the command line) with this directive:--end aliases---File: hledger.info, Node: Aliases can generate bad account names, Next: Aliases and account types, Prev: end aliases directive, Up: alias directive--9.18.6 Aliases can generate bad account names------------------------------------------------Be aware that account aliases can produce malformed account names, which-could cause confusing reports or invalid 'print' output. For example,-you could erase all account names:--2021-01-01- a:aa 1- b--$ hledger print --alias '/.*/='-2021-01-01- 1-- The above 'print' output is not a valid journal. Or you could insert-an illegal double space, causing 'print' output that would give a-different journal when reparsed:--2021-01-01- old 1- other--$ hledger print --alias old="new USD" | hledger -f- print-2021-01-01- new USD 1- other---File: hledger.info, Node: Aliases and account types, Prev: Aliases can generate bad account names, Up: alias directive--9.18.7 Aliases and account types-----------------------------------If an account with a type declaration (see Declaring accounts > Account-types) is renamed by an alias, normally the account type remains in-effect.-- However, renaming in a way that reshapes the account tree (eg-renaming parent accounts but not their children, or vice versa) could-prevent child accounts from inheriting the account type of their-parents.-- Secondly, if an account's type is being inferred from its name,-renaming it by an alias could prevent or alter that.-- If you are using account aliases and the 'type:' query is not-matching accounts as you expect, try troubleshooting with the accounts-command, eg something like:--$ hledger accounts --alias assets=bassetts type:a---File: hledger.info, Node: commodity directive, Next: decimal-mark directive, Prev: alias directive, Up: Journal--9.19 'commodity' directive-==========================--The 'commodity' directive performs several functions:-- 1. It declares which commodity symbols may be used in the journal,- enabling useful error checking with strict mode or the check- command. See Commodity error checking below.-- 2. It declares how all amounts in this commodity should be displayed,- eg how many decimals to show. See Commodity display style above.-- 3. (If no 'decimal-mark' directive is in effect:) It sets the decimal- mark to expect (period or comma) when parsing amounts in this- commodity, in this file and files it includes, from the directive- until end of current file. See Decimal marks above.-- 4. It declares the precision with which this commodity's amounts- should be compared when checking for balanced transactions,- anywhere in this file and files it includes, until end of current- file.-- Declaring commodities solves several common parsing/display problems,-so we recommend it.-- Note that effects 3 and 4 above end at the end of the directive's-file, and will not affect sibling or parent files. So if you are-relying on them (especially 4) and using multiple files, placing your-commodity directives in a top-level parent file might be important. Or,-keep your decimal marks unambiguous and your entries well balanced and-precise.-- (Related: #793)--* Menu:--* Commodity directive syntax::-* Commodity error checking::---File: hledger.info, Node: Commodity directive syntax, Next: Commodity error checking, Up: commodity directive--9.19.1 Commodity directive syntax------------------------------------A commodity directive is normally the word 'commodity' followed by a-sample amount (and optionally a comment). Only the amount's symbol and-format is significant. Eg:--commodity $1000.00-commodity 1.000,00 EUR-commodity 1 000 000.0000 ; the no-symbol commodity-- Commodities do not have tags (tags in the comment will be ignored).-- A commodity directive's sample amount must always include a period or-comma decimal mark (this rule helps disambiguate decimal marks and digit-group marks). If you don't want to show any decimal digits, write the-decimal mark at the end:--commodity 1000. AAAA ; show AAAA with no decimals-- Commodity symbols containing spaces, numbers, or punctuation must be-enclosed in double quotes, as usual:--commodity 1.0000 "AAAA 2023"-- Commodity directives normally include a sample amount, but can-declare only a symbol (ie, just function 1 above):--commodity $-commodity INR-commodity "AAAA 2023"-commodity "" ; the no-symbol commodity-- Commodity directives may also be written with an indented 'format'-subdirective, as in Ledger. The symbol is repeated and must be the same-in both places. Other subdirectives are currently ignored:--; 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- an unsupported subdirective ; ignored by hledger---File: hledger.info, Node: Commodity error checking, Prev: Commodity directive syntax, Up: commodity directive--9.19.2 Commodity error checking----------------------------------In strict mode ('-s'/'--strict') (or when you run 'hledger check-commodities'), hledger will report an error if an undeclared commodity-symbol is used. (With one exception: zero amounts are always allowed to-have no commodity symbol.) It works like account error checking-(described above).---File: hledger.info, Node: decimal-mark directive, Next: include directive, Prev: commodity directive, Up: Journal--9.20 'decimal-mark' directive-=============================--You can use a 'decimal-mark' directive - usually one per file, at the-top of the file - to declare which character represents a decimal mark-when parsing amounts in this file. It can look like--decimal-mark .-- or--decimal-mark ,-- This prevents any ambiguity when parsing numbers in the file, so we-recommend it, especially if the file contains digit group marks (eg-thousands separators).---File: hledger.info, Node: include directive, Next: P directive, Prev: decimal-mark directive, Up: Journal--9.21 'include' directive-========================--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,-overriding the file extension (as described in Data formats): 'include-timedot:~/notes/2023*.md'.---File: hledger.info, Node: P directive, Next: payee directive, Prev: include directive, Up: Journal--9.22 'P' directive-==================--The 'P' directive declares a market price, which is a conversion rate-between two commodities on a certain date. This allows value reports to-convert amounts of one commodity to their value in another, on or after-that date. These prices are often obtained from a stock exchange,-cryptocurrency exchange, the or foreign exchange market.-- 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 € $1.35--# and $1.40 from 2010-01-01 onward:-P 2010-01-01 € $1.40-- The '-V', '-X' and '--value' flags use these market prices to show-amount values in another commodity. See Value reporting.---File: hledger.info, Node: payee directive, Next: tag directive, Prev: P directive, Up: Journal--9.23 'payee' directive-======================--'payee PAYEE NAME'-- This 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 ; a comment-- Payees do not have tags (tags in the comment will be ignored).-- To declare the empty payee name, use '""'.--payee ""-- Ledger-style indented subdirectives, if any, are currently ignored.---File: hledger.info, Node: tag directive, Next: Periodic transactions, Prev: payee directive, Up: Journal--9.24 'tag' directive-====================--'tag TAGNAME'-- This directive can be used to declare a limited set of tag names-allowed in tags. TAGNAME should be a valid tag name (no spaces). Eg:--tag item-id-- Any indented subdirectives are currently ignored.-- The "tags" check will report an error if any undeclared tag name is-used. It is quite easy to accidentally create a tag through normal use-of colons in comments; if you want to prevent this, you can declare and-check your tags .---File: hledger.info, Node: Periodic transactions, Next: Auto postings, Prev: tag directive, Up: Journal--9.25 Periodic transactions-==========================--The '~' directive declares a "periodic rule" which generates temporary-extra transactions, usually recurring at some interval, when hledger is-run with the '--forecast' flag. These "forecast transactions" are-useful for forecasting future activity. They exist only for the-duration of the report, and only when '--forecast' is used; they are not-saved in the journal file by hledger.-- Periodic rules also have a second use: with the '--budget' flag they-set budget goals for budgeting.-- Periodic rules can be a little tricky, so before you use them, read-this whole section, or at least the following 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-forecasted 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 2023/01', which is equivalent to '~ every 10th- day of month from 2023/01/01', will be adjusted to start on- 2019/12/10.--* Menu:--* Periodic rule syntax::-* Periodic rules and relative dates::-* Two spaces between period expression and description!::---File: hledger.info, Node: Periodic rule syntax, Next: Periodic rules and relative dates, Up: Periodic transactions--9.25.1 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.):--# every first of month-~ monthly- expenses:rent $2000- assets:bank:checking--# every 15th of month in 2023's first quarter:-~ monthly from 2023-04-15 to 2023-06-16- expenses:utilities $400- assets:bank:checking-- The period expression is the same syntax used for specifying-multi-period reports, just interpreted differently; there, it specifies-report periods; here it specifies recurrence dates (the periods' start-dates).---File: hledger.info, Node: Periodic rules and relative dates, Next: Two spaces between period expression and description!, Prev: Periodic rule syntax, Up: Periodic transactions--9.25.2 Periodic rules and relative dates-------------------------------------------Partial or relative dates (like '12/31', '25', 'tomorrow', 'last week',-'next quarter') are usually not recommended in periodic rules, since the-results will change as time passes. If used, they will be interpreted-relative to, in order of preference:-- 1. the first day of the default year specified by a recent 'Y'- directive- 2. or the date specified with '--today'- 3. or the date on which you are running the report.-- They will not be affected at all by report period or forecast period-dates.---File: hledger.info, Node: Two spaces between period expression and description!, Prev: Periodic rules and relative dates, Up: Periodic transactions--9.25.3 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-accidentally alter their meaning, as in this example:--; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2023"-; ||-; vv-~ every 2 months in 2023, we will review- assets:bank:checking $1500- income:acme inc-- So,-- * Do write two spaces between your period expression and your- transaction description, if any.- * Don't accidentally write two spaces in the middle of your period- expression.---File: hledger.info, Node: Auto postings, Next: Other syntax, Prev: Periodic transactions, Up: Journal--9.26 Auto postings-==================--The '=' directive declares an "auto posting rule", which adds extra-postings to existing transactions. (Remember, postings are the account-name & amount lines below a transaction's date & description.)-- In the journal, an auto posting rule looks quite like a transaction,-but instead of date and description it has '=' (mnemonic: "match") and a-query, like this:--= QUERY- ACCOUNT AMOUNT- ...-- Queries are just like command line queries; an account name substring-is most common. Query terms containing spaces should be enclosed in-single or double quotes.-- Each '=' rule works like this: when hledger is run with the '--auto'-flag, wherever the QUERY matches a posting in the journal, the rule's-postings are added to that transaction, immediately below the matched-posting. Note these generated postings are temporary, existing only for-the duration of the report, and only when '--auto' is used; they are not-saved in the journal file by hledger.-- Generated postings' amounts can depend on the matched posting's-amount. So auto postings can be useful for, eg, adding tax postings-with a standard percentage. AMOUNT can be:-- * a number with no commodity symbol, like '2'. The matched posting's- commodity symbol will be added to this.-- * a normal amount with a commodity symbol, like '$2'. This will be- used as-is.-- * an asterisk followed by a number, like '*2'. This will multiply- the matched posting's amount (and total price, if any) by the- number.-- * an asterisk followed by an amount with commodity symbol, like- '*$2'. This multiplies and also replaces the commodity symbol with- this new one.-- 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-- Note that depending fully on generated data such as this has some-drawbacks - it's less portable, less future-proof, less auditable by-others, and less robust (eg your balance assertions will depend on-whether you use or don't use '--auto'). An alternative is to use auto-postings in "one time" fashion - use them to help build a complex-journal entry, view it with 'hledger print --auto', and then copy that-output into the journal file to make it permanent.--* Menu:--* Auto postings and multiple files::---File: hledger.info, Node: Auto postings and multiple files, Up: Auto postings--9.26.1 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).--* Menu:--* Auto postings and dates::-* Auto postings and transaction balancing / inferred amounts / balance assertions::-* Auto posting tags::-* Auto postings on forecast transactions only::---File: hledger.info, Node: Auto postings and dates, Next: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings and multiple files--9.26.1.1 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.---File: hledger.info, Node: Auto postings and transaction balancing / inferred amounts / balance assertions, Next: Auto posting tags, Prev: Auto postings and dates, Up: Auto postings and multiple files--9.26.1.2 Auto postings and transaction balancing / inferred-...........................................................--amounts / balance assertions Currently, auto postings are added:-- * after missing amounts are inferred, and transactions are checked- for balancedness,- * 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.-- This also means that you cannot have more than one auto-posting with-a missing amount applied to a given transaction, as it will be unable to-infer amounts.---File: hledger.info, Node: Auto posting tags, Next: Auto postings on forecast transactions only, Prev: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings and multiple files--9.26.1.3 Auto posting tags-..........................--Automated postings will have some extra tags:-- * 'generated-posting:= QUERY' - shows this was generated by an auto- posting rule, and the query- * '_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:-- * 'modified:' - this transaction was modified- * '_modified:' - a hidden tag not appearing in the comment; this- transaction was modified "just now".---File: hledger.info, Node: Auto postings on forecast transactions only, Prev: Auto posting tags, Up: Auto postings and multiple files--9.26.1.4 Auto postings on forecast transactions only-....................................................--Tip: you can can make auto postings that will apply to forecast-transactions but not recorded transactions, by adding-'tag:_generated-transaction' to their QUERY. This can be useful when-generating new journal entries to be saved in the journal.---File: hledger.info, Node: Other syntax, Prev: Auto postings, Up: Journal--9.27 Other syntax-=================--hledger journal format supports quite a few other features, mainly to-make interoperating with or converting from Ledger easier. Note some of-the features below are powerful and can be useful in special cases, but-in general, features in this section are considered less important or-even not recommended for most users. Downsides are mentioned to help-you decide if you want to use them.--* Menu:--* Balance assignments::-* Bracketed posting dates::-* D directive::-* apply account directive::-* Y directive::-* Secondary dates::-* Star comments::-* Valuation expressions::-* Virtual postings::-* Other Ledger directives::-* Other cost/lot notations::---File: hledger.info, Node: Balance assignments, Next: Bracketed posting dates, Up: Other syntax--9.27.1 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-assignment).-- Downsides: using balance assignments makes your journal less-explicit; to know the exact amount posted, you have to run hledger or do-the calculations yourself, instead of just reading it. Also balance-assignments' forcing of balances can hide errors. These things make-your financial data less portable, less future-proof, and less-trustworthy in an audit.--* Menu:--* Balance assignments and costs::-* Balance assignments and multiple files::---File: hledger.info, Node: Balance assignments and costs, Next: Balance assignments and multiple files, Up: Balance assignments--9.27.1.1 Balance assignments and costs-......................................--A cost in a balance assignment will cause the calculated amount to have-that cost attached:--2019/1/1- (a) = $1 @ €2--$ hledger print --explicit-2019-01-01- (a) $1 @ €2 = $1 @ €2---File: hledger.info, Node: Balance assignments and multiple files, Prev: Balance assignments and costs, Up: Balance assignments--9.27.1.2 Balance assignments and multiple files-...............................................--Balance assignments handle multiple files like balance assertions. They-see balance from other files previously included from the current file,-but not from previous sibling or parent files.---File: hledger.info, Node: Bracketed posting dates, Next: D directive, Prev: Balance assignments, Up: Other syntax--9.27.2 Bracketed posting dates---------------------------------For setting posting dates and secondary posting dates, Ledger's-bracketed date syntax is also supported: '[DATE]', '[DATE=DATE2]' or-'[=DATE2]' in posting comments. hledger will attempt to parse any-square-bracketed sequence of the '0123456789/-.=' characters in this-way. With this syntax, DATE infers its year from the transaction and-DATE2 infers its year from DATE.-- Downsides: another syntax to learn, redundant with hledger's-'date:'/'date2:' tags, and confusingly similar to Ledger's lot date-syntax.---File: hledger.info, Node: D directive, Next: apply account directive, Prev: Bracketed posting dates, Up: Other syntax--9.27.3 'D' directive-----------------------'D AMOUNT'-- This directive sets a default commodity, to be used for any-subsequent commodityless amounts (ie, plain numbers) seen while parsing-the journal. This effect lasts until the next 'D' directive, or the end-of the current file.-- For compatibility/historical reasons, 'D' also acts like a-'commodity' directive (setting the commodity's decimal mark for parsing-and display style for output). So its argument is not just a commodity-symbol, but a full amount demonstrating the style. The amount must-include a decimal mark (either period or comma). Eg:--; 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-- Interactions with other directives:-- For setting a commodity's display style, a 'commodity' directive has-highest priority, then a 'D' directive.-- For detecting a commodity's decimal mark during parsing,-'decimal-mark' has highest priority, then 'commodity', then 'D'.-- For checking commodity symbols with the check command, a 'commodity'-directive is required ('hledger check commodities' ignores 'D'-directives).-- Downsides: omitting commodity symbols makes your financial data less-explicit, less portable, and less trustworthy in an audit. It is-usually an unsustainable shortcut; sooner or later you will want to-track multiple commodities. D is overloaded with functions redundant-with 'commodity' and 'decimal-mark'. And it works differently from-Ledger's 'D'.---File: hledger.info, Node: apply account directive, Next: Y directive, Prev: D directive, Up: Other syntax--9.27.4 'apply account' directive-----------------------------------This directive sets a default parent account, which will be prepended to-all accounts in following entries, until an 'end apply account'-directive or end of current file. Eg:--apply account home--2010/1/1- food $10- cash--end apply account-- is equivalent to:--2010/01/01- home:food $10- home:cash $-10-- 'account' directives are also affected, and so is any 'include'd-content.-- Account names entered via hledger add or hledger-web are not-affected.-- Account aliases, if any, are applied after the parent account is-prepended.-- Downsides: this can make your financial data less explicit, less-portable, and less trustworthy in an audit.---File: hledger.info, Node: Y directive, Next: Secondary dates, Prev: apply account directive, Up: Other syntax--9.27.5 'Y' directive-----------------------'Y YEAR'-- or (deprecated backward-compatible forms):-- 'year YEAR' 'apply year YEAR'-- The space is optional. This sets a default year to be used for-subsequent dates which don't specify a year. Eg:--Y2009 ; set default year to 2009--12/15 ; equivalent to 2009/12/15- expenses 1- assets--year 2010 ; change default year to 2010--2009/1/30 ; specifies the year, not affected- expenses 1- assets--1/31 ; equivalent to 2010/1/31- expenses 1- assets-- Downsides: omitting the year (from primary transaction dates, at-least) makes your financial data less explicit, less portable, and less-trustworthy in an audit. Such dates can get separated from their-corresponding Y directive, eg when evaluating a region of the journal in-your editor. A missing Y directive makes reports dependent on today's-date.---File: hledger.info, Node: Secondary dates, Next: Star comments, Prev: Y directive, Up: Other syntax--9.27.6 Secondary dates-------------------------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".-- Downsides: makes your financial data more complicated, less portable,-and less trustworthy in an audit. Keeping the meaning of the two dates-consistent requires discipline, and you have to remember which reporting-mode is appropriate for a given report. Posting dates are simpler and-better.---File: hledger.info, Node: Star comments, Next: Valuation expressions, Prev: Secondary dates, Up: Other syntax--9.27.7 Star comments-----------------------Lines beginning with '*' (star/asterisk) are also comment lines. This-feature allows Emacs users to insert org headings in their journal,-allowing them to fold/unfold/navigate it like an outline when viewed-with org mode.-- Downsides: another, unconventional comment syntax to learn.-Decreases your journal's portability. And switching to Emacs org mode-just for folding/unfolding meant losing the benefits of ledger mode;-nowadays you can add outshine mode to ledger mode to get folding without-losing ledger mode's features.---File: hledger.info, Node: Valuation expressions, Next: Virtual postings, Prev: Star comments, Up: Other syntax--9.27.8 Valuation expressions-------------------------------Ledger allows a valuation function or value to be written in double-parentheses after an amount. hledger ignores these.---File: hledger.info, Node: Virtual postings, Next: Other Ledger directives, Prev: Valuation expressions, Up: Other syntax--9.27.9 Virtual postings--------------------------A posting with parentheses around the account name, like '(some:account)-10', is called an _unbalanced virtual posting_. These postings do not-participate in transaction balancing. (And if you write them without an-amount, a zero amount is always inferred.) These can occasionally be-convenient for special circumstances, but they violate double entry-bookkeeping and make your data less portable across applications, so-many people avoid using them at all.-- A posting with brackets around the account name ('[some:account]') is-called a _balanced virtual posting_. The balanced virtual postings in a-transaction must add up to zero, just like ordinary postings, but-separately from them. These are not part of double entry bookkeeping-either, but they are at least balanced. An example:--2022-01-01 buy food with cash, update budget envelope subaccounts, & something else- assets:cash $-10 ; <- these balance each other- expenses:food $7 ; <-- expenses:food $3 ; <-- [assets:checking:budget:food] $-10 ; <- and these balance each other- [assets:checking:available] $10 ; <-- (something:else) $5 ; <- this is not required to balance-- Ordinary postings, whose account names are neither parenthesised nor-bracketed, are called _real postings_. You can exclude virtual postings-from reports with the '-R/--real' flag or a 'real:1' query.---File: hledger.info, Node: Other Ledger directives, Next: Other cost/lot notations, Prev: Virtual postings, Up: Other syntax--9.27.10 Other Ledger directives----------------------------------These other Ledger directives are currently accepted but ignored. This-allows hledger to read more Ledger files, but be aware that hledger's-reports may differ from Ledger's if you use these.--apply fixed COMM AMT-apply tag TAG-assert EXPR-bucket / A ACCT-capture ACCT REGEX-check EXPR-define VAR=EXPR-end apply fixed-end apply tag-end apply year-end tag-eval / expr EXPR-python- PYTHONCODE-tag NAME-value EXPR---command-line-flags-- See also https://hledger.org/ledger.html for a detailed-hledger/Ledger syntax comparison.---File: hledger.info, Node: Other cost/lot notations, Prev: Other Ledger directives, Up: Other syntax--9.27.11 Other cost/lot notations-----------------------------------A slight digression for Ledger and Beancount users. Ledger has a number-of cost/lot-related notations:-- * '@ UNITCOST' and '@@ TOTALCOST'- * expresses a conversion rate, as in hledger- * when buying, also creates a lot than can be selected at- selling time-- * '(@) UNITCOST' and '(@@) TOTALCOST' (virtual cost)- * like the above, but also means "this cost was exceptional,- don't use it when inferring market prices".-- Currently, hledger treats the above like '@' and '@@'; the-parentheses are ignored.-- * '{=FIXEDUNITCOST}' and '{{=FIXEDTOTALCOST}}' (fixed price)- * when buying, means "this cost is also the fixed price, don't- let it fluctuate in value reports"-- * '{UNITCOST}' and '{{TOTALCOST}}' (lot price)- * can be used identically to '@ UNITCOST' and '@@ TOTALCOST',- also creates a lot- * when selling, combined with '@ ...', specifies an investment- lot by its cost basis; does not check if that lot is present-- * and related: '[YYYY/MM/DD]' (lot date)- * when buying, attaches this acquisition date to the lot- * when selling, selects a lot by its acquisition date-- * '(SOME TEXT)' (lot note)- * when buying, attaches this note to the lot- * when selling, selects a lot by its note-- Currently, hledger accepts any or all of the above in any order after-the posting amount, but ignores them. (This can break transaction-balancing.)-- For Beancount users, the notation and behaviour is different:-- * '@ UNITCOST' and '@@ TOTALCOST'- * expresses a cost without creating a lot, as in hledger- * when buying (augmenting) or selling (reducing) a lot, combined- with '{...}': documents the cost/selling price (not used for- transaction balancing)-- * '{UNITCOST}' and '{{TOTALCOST}}'- * when buying (augmenting), expresses the cost for transaction- balancing, and also creates a lot with this cost basis- attached- * when selling (reducing),- * selects a lot by its cost basis- * raises an error if that lot is not present or can not be- selected unambiguously (depending on booking method- configured)- * expresses the selling price for transaction balancing-- Currently, hledger accepts the '{UNITCOST}'/'{{TOTALCOST}}' notation-but ignores it.-- * variations: '{}', '{YYYY-MM-DD}', '{"LABEL"}', '{UNITCOST,- "LABEL"}', '{UNITCOST, YYYY-MM-DD, "LABEL"}' etc.-- Currently, hledger rejects these.---File: hledger.info, Node: CSV, Next: Timeclock, Prev: Journal, Up: Top--10 CSV-******--hledger can read CSV files (Character Separated Value - usually comma,-semicolon, or tab) containing dated records, automatically converting-each record into a transaction.-- (To learn about _writing_ CSV, see CSV output.)-- For best error messages when reading CSV/TSV/SSV files, make sure-they have a corresponding '.csv', '.tsv' or '.ssv' file extension or use-a hledger file prefix (see File Extension below).-- Each CSV file must be described by a corresponding _rules file_.-This contains rules describing the CSV data (header line, fields layout,-date format etc.), how to construct hledger transactions from it, and-how to categorise transactions based on description or other attributes.-- By default, hledger expects this rules file to be named like the CSV-file, with an extra '.rules' extension added, in the same directory. Eg-when asked to read 'foo/FILE.csv', hledger looks for-'foo/FILE.csv.rules'. You can specify a different rules file with the-'--rules-file' option.-- 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-- There's an introductory Importing CSV data tutorial on hledger.org,-and more CSV rules examples below, and a larger collection at-https://github.com/simonmichael/hledger/tree/master/examples/csv.--* Menu:--* CSV rules cheatsheet::-* source::-* separator::-* skip::-* date-format::-* timezone::-* newest-first::-* intra-day-reversed::-* decimal-mark::-* fields list::-* Field assignment::-* Field names::-* if block::-* Matchers::-* if table::-* balance-type::-* include::-* Working with CSV::-* CSV rules examples::---File: hledger.info, Node: CSV rules cheatsheet, Next: source, Up: CSV--10.1 CSV rules cheatsheet-=========================--The following kinds of rule can appear in the rules file, in any order.-(Blank lines and lines beginning with '#' or ';' or '*' are ignored.)--*'source'* optionally declare which file to read data- from-*'separator'* declare the field separator, instead of- relying on file extension-*'skip'* skip one or more header lines at start of file-*'date-format'* declare how to parse CSV dates/date-times-*'timezone'* declare the time zone of ambiguous CSV- date-times-*'newest-first'* improve txn order when: there are multiple- records, newest first, all with the same date-*'intra-day-reversed'* improve txn order when: same-day txns are in- opposite order to the overall file-*'decimal-mark'* declare the decimal mark used in CSV amounts,- when ambiguous-*'fields' list* name CSV fields for easy reference, and- optionally assign their values to hledger- fields-*Field assignment* assign a CSV value or interpolated text value- to a hledger field-*'if' block* conditionally assign values to hledger fields,- or 'skip' a record or 'end' (skip rest of- file)-*'if' table* conditionally assign values to hledger fields,- using compact syntax-*'balance-type'* select which type of balance- assertions/assignments to generate-*'include'* inline another CSV rules file-- Working with CSV tips can be found below, including How CSV rules are-evaluated.---File: hledger.info, Node: source, Next: separator, Prev: CSV rules cheatsheet, Up: CSV--10.2 'source'-=============--If you tell hledger to read a csv file with '-f foo.csv', it will look-for rules in 'foo.csv.rules'. Or, you can tell it to read the rules-file, with '-f foo.csv.rules', and it will look for data in 'foo.csv'-(since 1.30).-- These are mostly equivalent, but the second method provides some-extra features. For one, the data file can be missing, without causing-an error; it is just considered empty. And, you can specify a different-data file by adding a "source" rule:--source ./Checking1.csv-- If you specify just a file name with no path, hledger will look for-it in your system's downloads directory ('~/Downloads', currently):--source Checking1.csv-- And if you specify a glob pattern, hledger will read the most recent-of the matched files (useful with repeated downloads):--source Checking1*.csv-- See also "Working with CSV > Reading files specified by rule".---File: hledger.info, Node: separator, Next: skip, Prev: source, Up: CSV--10.3 'separator'-================--You can use the 'separator' rule to read other kinds of-character-separated 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 automatically, and you won't need this rule.---File: hledger.info, Node: skip, Next: date-format, Prev: separator, Up: CSV--10.4 'skip'-===========--skip N-- The word 'skip' followed by a number (or no number, meaning 1) tells-hledger to ignore this many non-empty lines at the start of the input-data. You'll need this whenever your CSV data contains header lines.-Note, empty and blank lines are skipped automatically, so you don't need-to count those.-- 'skip' has a second meaning: it can be used inside if blocks-(described below), to skip one or more records whenever the condition is-true. Records skipped in this way are ignored, except they are still-required to be valid CSV.---File: hledger.info, Node: date-format, Next: timezone, Prev: skip, Up: CSV--10.5 '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-style date parsing pattern - see-https://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:formatTime.-The pattern must parse the CSV date value completely. Some examples:--# 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---File: hledger.info, Node: timezone, Next: newest-first, Prev: date-format, Up: CSV--10.6 'timezone'-===============--timezone TIMEZONE-- When CSV contains date-times that are implicitly in some time zone-other than yours, but containing no explicit time zone information, you-can use this rule to declare the CSV's native time zone, which helps-prevent off-by-one dates.-- When the CSV date-times do contain time zone information, you don't-need this rule; instead, use '%Z' in 'date-format' (or '%z', '%EZ',-'%Ez'; see the formatTime link above).-- In either of these cases, hledger will do a time-zone-aware-conversion, localising the CSV date-times to your current system time-zone. If you prefer to localise to some other time zone, eg for-reproducibility, you can (on unix at least) set the output timezone with-the TZ environment variable, eg:--$ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv-- 'timezone' currently does not understand timezone names, except-"UTC", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", or "PDT".-For others, use numeric format: +HHMM or -HHMM.---File: hledger.info, Node: newest-first, Next: intra-day-reversed, Prev: timezone, Up: CSV--10.7 'newest-first'-===================--hledger tries to ensure that the generated transactions will be ordered-chronologically, including same-day transactions. Usually it can-auto-detect how the CSV records are ordered. But if it encounters CSV-where all records are on the same date, it assumes that the records are-oldest first. If in fact the CSV's records are normally newest first,-like:--2022-10-01, txn 3...-2022-10-01, txn 2...-2022-10-01, txn 1...-- you can add the 'newest-first' rule to help hledger generate the-transactions in correct order.--# same-day CSV records are newest first-newest-first---File: hledger.info, Node: intra-day-reversed, Next: decimal-mark, Prev: newest-first, Up: CSV--10.8 'intra-day-reversed'-=========================--If CSV records within a single day are ordered opposite to the overall-record order, you can add the 'intra-day-reversed' rule to improve the-order of journal entries. Eg, here the overall record order is newest-first, but same-day records are oldest first:--2022-10-02, txn 3...-2022-10-02, txn 4...-2022-10-01, txn 1...-2022-10-01, txn 2...--# transactions within each day are reversed with respect to the overall date order-intra-day-reversed---File: hledger.info, Node: decimal-mark, Next: fields list, Prev: intra-day-reversed, Up: CSV--10.9 '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.---File: hledger.info, Node: fields list, Next: Field assignment, Prev: decimal-mark, Up: CSV--10.10 'fields' list-===================--fields FIELDNAME1, FIELDNAME2, ...-- A fields list (the word 'fields' followed by comma-separated field-names) is optional, but convenient. It does two things:-- 1. It names the CSV field in each column. This can be convenient if- you are referencing them in other rules, so you can say- '%SomeField' instead of remembering '%13'.-- 2. Whenever you use one of the special hledger field names (described- below), it assigns the CSV value in this position to that hledger- field. This is the quickest way to populate hledger's fields and- build a transaction.-- Here's an example that says "use the 1st, 2nd and 4th fields as the-transaction's date, description and amount; name the last two fields for-later reference; and ignore the others":--fields date, description, , amount, , , somefield, anotherfield-- In a fields list, the separator is always comma; it is unrelated to-the CSV file's separator. Also:-- * There must be least two items in the list (at least one comma).- * Field names may not contain spaces. Spaces before/after field- names are optional.- * Field names may contain '_' (underscore) or '-' (hyphen).- * Fields you don't care about can be given a dummy name or an empty- name.-- If the CSV contains column headings, it's convenient to use these for-your field names, suitably modified (eg lower-cased with spaces replaced-by underscores).-- Sometimes you may want to alter a CSV field name to avoid assigning-to a hledger field with the same name. Eg you could call the CSV's-"balance" field 'balance_' to avoid directly setting hledger's 'balance'-field (and generating a balance assertion).---File: hledger.info, Node: Field assignment, Next: Field names, Prev: fields list, Up: CSV--10.11 Field assignment-======================--HLEDGERFIELD 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-interpolate CSV fields, referenced either by their 1-based position in-the CSV record ('%N') or by the name they were given in the fields list-('%CSVFIELD'), and regular expression match groups ('\N').-- 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:-- * Interpolation strips outer whitespace (so a CSV value like '" 1 "'- becomes '1' when interpolated) (#1051).- * Interpolations always refer to a CSV field - you can't interpolate- a hledger field. (See Referencing other fields below).---File: hledger.info, Node: Field names, Next: if block, Prev: Field assignment, Up: CSV--10.12 Field names-=================--Note the two kinds of field names mentioned here, and used only in-hledger CSV rules files:-- 1. *CSV field names* ('CSVFIELD' in these docs): you can optionally- name the CSV columns for easy reference (since hledger doesn't yet- automatically recognise column headings in a CSV file), by writing- arbitrary names in a 'fields' list, eg:-- fields When, What, Some_Id, Net, Total, Foo, Bar-- 2. Special *hledger field names* ('HLEDGERFIELD' in these docs): you- must set at least some of these to generate the hledger transaction- from a CSV record, by writing them as the left hand side of a field- assignment, eg:-- date %When- code %Some_Id- description %What- comment %Foo %Bar- amount1 $ %Total-- or directly in a 'fields' list:-- fields date, description, code, , amount1, Foo, Bar- currency $- comment %Foo %Bar-- Here are all the special hledger field names available, and what-happens when you assign values to them:--* Menu:--* date field::-* date2 field::-* status field::-* code field::-* description field::-* comment field::-* account field::-* amount field::-* currency field::-* balance field::---File: hledger.info, Node: date field, Next: date2 field, Up: Field names--10.12.1 date field---------------------Assigning to 'date' sets the transaction date.---File: hledger.info, Node: date2 field, Next: status field, Prev: date field, Up: Field names--10.12.2 date2 field----------------------'date2' sets the transaction's secondary date, if any.---File: hledger.info, Node: status field, Next: code field, Prev: date2 field, Up: Field names--10.12.3 status field-----------------------'status' sets the transaction's status, if any.---File: hledger.info, Node: code field, Next: description field, Prev: status field, Up: Field names--10.12.4 code field---------------------'code' sets the transaction's code, if any.---File: hledger.info, Node: description field, Next: comment field, Prev: code field, Up: Field names--10.12.5 description field----------------------------'description' sets the transaction's description, if any.---File: hledger.info, Node: comment field, Next: account field, Prev: description field, Up: Field names--10.12.6 comment field------------------------'comment' sets the transaction's comment, if any.-- 'commentN', where N is a number, sets the Nth posting's comment.-- You can assign multi-line comments by writing literal '\n' in the-code. A comment starting with '\n' will begin on a new line.-- Comments can contain tags, as usual.---File: hledger.info, Node: account field, Next: amount field, Prev: comment field, Up: Field names--10.12.7 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, in conditional rules.-- If a posting's account name is left unset but its amount is set (see-below), a default account name will be chosen (like "expenses:unknown"-or "income:unknown").---File: hledger.info, Node: amount field, Next: currency field, Prev: account field, Up: Field names--10.12.8 amount field-----------------------There are several ways to set posting amounts from CSV, useful in-different situations.-- 1. *'amount'* is the oldest and simplest. Assigning to this sets the- amount of the first and second postings. In the second posting,- the amount will be negated; also, if it has a cost attached, it- will be converted to cost.-- 2. *'amount-in'* and *'amount-out'* work exactly like the above, but- should be used when the CSV has two amount fields (such as "Debit"- and "Credit", or "Inflow" and "Outflow"). Whichever field has a- non-zero value will be used as the amount of the first and second- postings. Here are some tips to avoid confusion:-- * It's not "amount-in for posting 1 and amount-out for posting- 2", it is "extract a single amount from the amount-in or- amount-out field, and use that for posting 1 and (negated) for- posting 2".- * Don't use both 'amount' and 'amount-in'/'amount-out' in the- same rules file; choose based on whether the amount is in a- single CSV field or spread across two fields.- * In each record, at most one of the two CSV fields should- contain a non-zero amount; the other field must contain a zero- or nothing.- * hledger assumes both CSV fields contain unsigned numbers, and- it automatically negates the amount-out values.- * If the data doesn't fit these requirements, you'll probably- need an if rule (see below).-- 3. *'amountN'* (where N is a number from 1 to 99) sets the amount of- only a single posting: the Nth posting in the transaction. You'll- usually need at least two such assignments to make a balanced- transaction. You can also generate more than two postings, to- represent more complex transactions. The posting numbers don't- have to be consecutive; with if rules, higher posting numbers can- be useful to ensure a certain order of postings.-- 4. *'amountN-in'* and *'amountN-out'* work exactly like the above, but- should be used when the CSV has two amount fields. This is- analogous to 'amount-in' and 'amount-out', and those tips also- apply here.-- 5. Remember that a 'fields' list can also do assignments. So in a- fields list if you name a CSV field "amount", that counts as- assigning to 'amount'. (If you don't want that, call it something- else in the fields list, like "amount_".)-- 6. The above don't handle every situation; if you need more- flexibility, use an 'if' rule to set amounts conditionally. See- "Working with CSV > Setting amounts" below for more on this and on- amount-setting generally.---File: hledger.info, Node: currency field, Next: balance field, Prev: amount field, Up: Field names--10.12.9 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.---File: hledger.info, Node: balance field, Prev: currency field, Up: Field names--10.12.10 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 the Working with CSV tips below for more about setting amounts-and currency.---File: hledger.info, Node: if block, Next: Matchers, Prev: Field names, Up: CSV--10.13 'if' block-================--Rules can be applied conditionally, depending on patterns in the CSV-data. This allows flexibility; in particular, it is how you can-categorise transactions, selecting an appropriate account name based on-their description (for example). There are two ways to write-conditional rules: "if blocks", described here, and "if tables",-described below.-- An if block is the word 'if' and one or more "matcher" expressions-(can be a word or phrase), one per line, starting either on the same or-next line; followed by one or more indented rules. Eg,--if MATCHER- RULE-- or--if-MATCHER-MATCHER-MATCHER- RULE- RULE-- If any of the matchers succeeds, all of the indented rules will be-applied. They are usually field assignments, but the following special-rules may also be used within an if block:-- * 'skip' - skips the matched CSV record (generating no transaction- from it)- * 'end' - skips the rest of the current CSV file.-- Some examples:--# if the record contains "groceries", set account2 to "expenses:groceries"-if groceries- account2 expenses:groceries--# if the record contains any of these phrases, set account2 and a transaction comment as shown-if-monthly service fee-atm transaction fee-banking thru software- account2 expenses:business:banking- comment XXX deductible ? check it--# if an empty record is seen (assuming five fields), ignore the rest of the CSV file-if ,,,,- end---File: hledger.info, Node: Matchers, Next: if table, Prev: if block, Up: CSV--10.14 Matchers-==============--There are two kinds:-- 1. A record matcher is a word or single-line text fragment or regular- expression ('REGEX'), which hledger will try to match- case-insensitively anywhere within the CSV record.- Eg: 'whole foods'-- 2. A field matcher is preceded with a percent sign and CSV field name- ('%CSVFIELD REGEX'). hledger will try to match these just within- the named CSV field.- Eg: '%date 2023'-- The regular expression is (as usual in hledger) a POSIX extended-regular expression, that also supports GNU word boundaries ('\b', '\B',-'\<', '\>'), and nothing else. If you have trouble, see "Regular-expressions" in the hledger manual-(https://hledger.org/hledger.html#regular-expressions).--* Menu:--* What matchers match::-* Combining matchers::-* Match groups::---File: hledger.info, Node: What matchers match, Next: Combining matchers, Up: Matchers--10.14.1 What matchers match------------------------------With record matchers, it's important to know that the record matched is-not the original CSV record, but a modified one: separators will be-converted to commas, and enclosing double quotes (but not enclosing-whitespace) are removed. So for example, when reading an SSV file, if-the original record was:--2023-01-01; "Acme, Inc."; 1,000-- the regex would see, and try to match, this modified record text:--2023-01-01,Acme, Inc., 1,000---File: hledger.info, Node: Combining matchers, Next: Match groups, Prev: What matchers match, Up: Matchers--10.14.2 Combining matchers-----------------------------When an if block has multiple matchers, they are combined as follows:-- * By default they are OR'd (any of them can match)- * When a matcher is preceded by ampersand ('&', at the start of the- line) it will be AND'ed with the previous matcher (all in the- AND'ed group must match)- * _Added in 1.32_ When a matcher is preceded by an exclamation mark- ('!'), it is negated (it must not match).-- Note currently there is a limitation: you can't use both '&' and '!'-on the same line (you can't AND a negated matcher).---File: hledger.info, Node: Match groups, Prev: Combining matchers, Up: Matchers--10.14.3 Match groups-----------------------_Added in 1.32_-- Matchers can define match groups: parenthesised portions of the-regular expression which are available for reference in field-assignments. Groups are enclosed in regular parentheses ('(' and ')')-and can be nested. Each group is available in field assignments using-the token '\N', where N is an index into the match groups for this-conditional block (e.g. '\1', '\2', etc.).-- Example: Warp credit card payment postings to the beginning of the-billing period (Month start), to match how they are presented in-statements, using posting dates:--if %date (....-..)-..- comment2 date:\1-01-- Another example: Read the expense account from the CSV field, but-throw away a prefix:--if %account1 liabilities:family:(expenses:.*)- account1 \1---File: hledger.info, Node: if table, Next: balance-type, Prev: Matchers, Up: CSV--10.15 'if' table-================--"if tables" are an alternative to if blocks; they can express many-matchers and field assignments in a more compact tabular format, like-this:--if,HLEDGERFIELD1,HLEDGERFIELD2,...-MATCHERA,VALUE1,VALUE2,...-MATCHERB,VALUE1,VALUE2,...-; Comment line that explains MATCHERC-MATCHERC,VALUE1,VALUE2,...-<empty line>-- The first character after 'if' is taken to be this if table's field-separator. It is unrelated to the separator used in the CSV file. It-should be a non-alphanumeric character like ',' or '|' that does not-appear anywhere else in the table (it should not be used in field names-or matchers or values, and it cannot be escaped with a backslash).-- Each line must contain the same number of separators; empty values-are allowed. Whitespace can be used in the matcher lines for-readability (but not in the if line, currently). You can use the-comment lines in the table body. The table must be terminated by an-empty line (or end of file).-- An if table like the above is interpreted as follows: try all of the-matchers; whenever a matcher succeeds, assign all of the values on that-line to the corresponding hledger fields; If multiple lines match, later-lines will override fields assigned by the earlier ones - just like the-sequence of 'if' blocks would behave.-- If table presented above is equivalent to this sequence of if blocks:--if MATCHERA- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...--if MATCHERB- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...--; Comment line which explains MATCHERC-if MATCHERC- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...-- Example:--if,account2,comment-atm transaction fee,expenses:business:banking,deductible? check it-%description groceries,expenses:groceries,-;; Comment line that desribes why this particular date is special-2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out---File: hledger.info, Node: balance-type, Next: include, Prev: if table, Up: CSV--10.16 '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---File: hledger.info, Node: include, Next: Working with CSV, Prev: balance-type, Up: CSV--10.17 '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---File: hledger.info, Node: Working with CSV, Next: CSV rules examples, Prev: include, Up: CSV--10.18 Working with CSV-======================--Some tips:--* Menu:--* Rapid feedback::-* Valid CSV::-* File Extension::-* Reading CSV from standard input::-* Reading multiple CSV files::-* Reading files specified by rule::-* Valid transactions::-* Deduplicating importing::-* Setting amounts::-* Amount signs::-* Setting currency/commodity::-* Amount decimal places::-* Referencing other fields::-* How CSV rules are evaluated::-* Well factored rules::---File: hledger.info, Node: Rapid feedback, Next: Valid CSV, Up: Working with CSV--10.18.1 Rapid feedback-------------------------It's a good idea to get rapid feedback while creating/troubleshooting-CSV rules. Here's a good way, using entr from eradman.com/entrproject:--$ 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.---File: hledger.info, Node: Valid CSV, Next: File Extension, Prev: Rapid feedback, Up: Working with CSV--10.18.2 Valid CSV--------------------Note that hledger will only accept valid CSV conforming to RFC 4180, and-equivalent SSV and TSV formats (like RFC 4180 but with semicolon or tab-as separators). This means, eg:-- * Values may be enclosed in double quotes, or not. Enclosing in- single quotes is not allowed. (Eg ''A','B'' is rejected.)- * When values are enclosed in double quotes, spaces outside the- quotes are not allowed. (Eg '"A", "B"' is rejected.)- * When values are not enclosed in quotes, they may not contain double- quotes. (Eg 'A"A, B' is rejected.)-- If your CSV/SSV/TSV is not valid in this sense, you'll need to-transform it before reading with hledger. Try using sed, or a more-permissive CSV parser like python's csv lib.---File: hledger.info, Node: File Extension, Next: Reading CSV from standard input, Prev: Valid CSV, Up: Working with CSV--10.18.3 File Extension-------------------------To help hledger choose the CSV file reader and show the right error-messages (and choose the right field separator character by default),-it's best if CSV/SSV/TSV files are named with a '.csv', '.ssv' or '.tsv'-filename extension. (More about this at Data formats.)-- When reading files with the "wrong" extension, you can ensure the CSV-reader (and the default field separator) by prefixing the file path with-'csv:', 'ssv:' or 'tsv:': Eg:--$ hledger -f ssv:foo.dat print-- You can also override the default field separator with a separator-rule if needed.---File: hledger.info, Node: Reading CSV from standard input, Next: Reading multiple CSV files, Prev: File Extension, Up: Working with CSV--10.18.4 Reading CSV from standard input------------------------------------------You'll need the file format prefix when reading CSV from stdin also,-since hledger assumes journal format by default. Eg:--$ cat foo.dat | hledger -f ssv:- print---File: hledger.info, Node: Reading multiple CSV files, Next: Reading files specified by rule, Prev: Reading CSV from standard input, Up: Working with CSV--10.18.5 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.---File: hledger.info, Node: Reading files specified by rule, Next: Valid transactions, Prev: Reading multiple CSV files, Up: Working with CSV--10.18.6 Reading files specified by rule------------------------------------------Instead of specifying a CSV file in the command line, you can specify a-rules file, as in 'hledger -f foo.csv.rules CMD'. By default this will-read data from foo.csv in the same directory, but you can add a source-rule to specify a different data file, perhaps located in your web-browser's download directory.-- This feature was added in hledger 1.30, so you won't see it in most-CSV rules examples. But it helps remove some of the busywork of-managing CSV downloads. Most of your financial institutions's default-CSV filenames are different and can be recognised by a glob pattern. So-you can put a rule like 'source Checking1*.csv' in-foo-checking.csv.rules, and then periodically follow a workflow like:-- 1. Download CSV from Foo's website, using your browser's defaults- 2. Run 'hledger import foo-checking.csv.rules' to import any new- transactions-- After import, you can: discard the CSV, or leave it where it is for a-while, or move it into your archives, as you prefer. If you do nothing,-next time your browser will save something like Checking1-2.csv, and-hledger will use that because of the '*' wild card and because it is the-most recent.---File: hledger.info, Node: Valid transactions, Next: Deduplicating importing, Prev: Reading files specified by rule, Up: Working with CSV--10.18.7 Valid transactions-----------------------------After reading a CSV file, hledger post-processes and validates the-generated journal entries as it would for a journal file - balancing-them, applying balance assignments, and canonicalising amount styles.-Any errors at this stage will be reported in the usual way, displaying-the problem entry.-- 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---File: hledger.info, Node: Deduplicating importing, Next: Setting amounts, Prev: Valid transactions, Up: Working with CSV--10.18.8 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:-- * https://hledger.org/cookbook.html#setups-and-workflows- * https://plaintextaccounting.org -> data import/conversion---File: hledger.info, Node: Setting amounts, Next: Amount signs, Prev: Deduplicating importing, Up: Working with CSV--10.18.9 Setting amounts--------------------------Continuing from amount field above, here are more tips for-amount-setting:-- 1. *If the amount is in a single CSV field:*-- a. *If its sign indicates direction of flow:*- Assign it to 'amountN', to set the Nth posting's amount. N is- usually 1 or 2 but can go up to 99.-- b. *If another field indicates direction of flow:*- Use one or more conditional rules to set the appropriate- amount sign. Eg:-- # assume a withdrawal unless Type contains "deposit":- amount1 -%Amount- if %Type deposit- amount1 %Amount-- 2. *If the amount is in two CSV fields (such as Debit and Credit, or- In and Out):*-- a. *If both fields are unsigned:*- Assign one field to 'amountN-in' and the other to- 'amountN-out'. hledger will automatically negate the "out"- field, and will use whichever field value is non-zero as- posting N's amount.-- b. *If either field is signed:*- You will probably need to override hledger's sign for one or- the other field, as in the following example:-- # Negate the -out value, but only if it is not empty:- fields date, description, amount1-in, amount1-out- if %amount1-out [1-9]- amount1-out -%amount1-out-- c. *If both fields can contain a non-zero value (or both can be- empty):*- The -in/-out rules normally choose the value which is- non-zero/non-empty. Some value pairs can be ambiguous, such- as '1' and 'none'. For such cases, use conditional rules to- help select the amount. Eg, to handle the above you could- select the value containing non-zero digits:-- fields date, description, in, out- if %in [1-9]- amount1 %in- if %out [1-9]- amount1 %out-- 3. *If you want posting 2's amount converted to cost:*- Use the unnumbered 'amount' (or 'amount-in' and 'amount-out')- syntax.-- 4. *If the CSV has only balance amounts, not transaction amounts:*- Assign to 'balanceN', to set a balance assignment on the Nth- posting, causing the posting's amount to be calculated- automatically. 'balance' with no number is equivalent to- 'balance1'. In this situation hledger is more likely to guess the- wrong default account name, so you may need to set that explicitly.---File: hledger.info, Node: Amount signs, Next: Setting currency/commodity, Prev: Setting amounts, Up: Working with CSV--10.18.10 Amount signs------------------------There is some special handling making it easier to parse and to reverse-amount signs. (This only works for whole amounts, not for cost amounts-such as COST in 'amount1 AMT @ COST'):-- * *If an amount value begins with a plus sign:*- that will be removed: '+AMT' becomes 'AMT'-- * *If an amount value is parenthesised:*- it will be de-parenthesised and sign-flipped: '(AMT)' becomes- '-AMT'-- * *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'-- * *If an amount value contains just a sign (or just a set of- parentheses):*- that is removed, making it an empty value. '"+"' or '"-"' or- '"()"' becomes '""'.-- It's not possible (without preprocessing the CSV) to set an amount to-its absolute value, ie discard its sign.---File: hledger.info, Node: Setting currency/commodity, Next: Amount decimal places, Prev: Amount signs, Up: Working with CSV--10.18.11 Setting currency/commodity--------------------------------------If the currency/commodity symbol is included in the CSV's amount-field(s):--2023-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--2023-01-01 foo- expenses:unknown $123.00- income:unknown $-123.00-- If the currency is provided as a separate CSV field:--2023-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--2023-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--2023-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.---File: hledger.info, Node: Amount decimal places, Next: Referencing other fields, Prev: Setting currency/commodity, Up: Working with CSV--10.18.12 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-decimal 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).---File: hledger.info, Node: Referencing other fields, Next: How CSV rules are evaluated, Prev: Amount decimal places, Up: Working with CSV--10.18.13 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-literal "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---File: hledger.info, Node: How CSV rules are evaluated, Next: Well factored rules, Prev: Referencing other fields, Up: Working with CSV--10.18.14 How CSV rules are evaluated---------------------------------------Here's how to think of CSV rules being evaluated (if you really need-to). First,-- * '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:-- * 'skip' (at top level)- * 'date-format'- * 'newest-first'- * 'fields' - names the CSV fields, optionally sets up initial- assignments to hledger fields-- Then for each CSV record in turn:-- * 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.- * 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.- * compute a value for each hledger field - either the one that was- assigned to it (and interpolate the %CSVFIELD references), or a- default- * generate a hledger transaction (journal entry) from these values.-- This is all part of the CSV reader, one of several readers hledger-can use to parse input files. When all files have been read-successfully, the transactions are passed as input to whichever hledger-command the user specified.---File: hledger.info, Node: Well factored rules, Prev: How CSV rules are evaluated, Up: Working with CSV--10.18.15 Well factored rules-------------------------------Some things than can help reduce duplication and complexity in rules-files:-- * Extracting common rules usable with multiple CSV files into a- 'common.rules', and adding 'include common.rules' to each CSV's- rules file.-- * Splitting if blocks into smaller if blocks, extracting the- frequently used parts.---File: hledger.info, Node: CSV rules examples, Prev: Working with CSV, Up: CSV--10.19 CSV rules examples-========================--* Menu:--* Bank of Ireland::-* Coinbase::-* Amazon::-* Paypal::---File: hledger.info, Node: Bank of Ireland, Next: Coinbase, Up: CSV rules examples--10.19.1 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-necessary 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-reading directly from CSV, but they will be checked if these entries are-imported into a journal file.---File: hledger.info, Node: Coinbase, Next: Amazon, Prev: Bank of Ireland, Up: CSV rules examples--10.19.2 Coinbase-------------------A simple example with some CSV from Coinbase. The spot price is-recorded using cost notation. The legacy 'amount' field name-conveniently sets amount 2 (posting 2's amount) to the total cost.--# Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes-# 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,"","","","Received 100.00 USDC from an external account"--# coinbase.csv.rules-skip 1-fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes-date %Timestamp-date-format %Y-%m-%dT%T%Z-description %Notes-account1 assets:coinbase:cc-amount %Quantity_Transacted %Asset @ %Spot_Price_at_Transaction %Spot_Price_Currency--$ hledger print -f coinbase.csv-2021-12-30 Received 100.00 USDC from an external account- assets:coinbase:cc 100 USDC @ 0.740000 GBP- income:unknown -74.000000 GBP---File: hledger.info, Node: Amazon, Next: Paypal, Prev: Coinbase, Up: CSV rules examples--10.19.3 Amazon-----------------Here we convert amazon.com order history, and use an if block to-generate 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---File: hledger.info, Node: Paypal, Prev: Amazon, Up: CSV rules examples--10.19.4 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:---File: hledger.info, Node: Timeclock, Next: Timedot, Prev: CSV, Up: Top--11 Timeclock-************--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). Lines-beginning with '#' or ';' or '*', and blank lines, are ignored.--i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:-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 2 spaces ; optional comment, tags:- (some account) 0.33h--2015-03-31 * 22:21-23:59- (another:account) 1.64h--2015-04-01 * 00:00-02:00- (another:account) 2.01h-- 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:-- * use emacs and the built-in timeclock.el, or the extended- timeclock-x.el and perhaps the extras in ledgerutils.el-- * at the command line, use these bash aliases: 'cli alias ti="echo i- `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o `date- '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"'-- * 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.---File: hledger.info, Node: Timedot, Next: PART 3 REPORTING CONCEPTS, Prev: Timeclock, Up: Top--12 Timedot-**********--'timedot' format is hledger's human-friendly time logging format.-Compared to 'timeclock' format, it is more convenient for quick,-approximate, and retroactive time logging, and more human-readable (you-can see at a glance where time was spent). A quick example:--2023-05-01-hom:errands .... .... ; two hours; the space is ignored-fos:hledger:timedot .. ; half an hour-per:admin:finance ; no time spent yet-- hledger reads this as a transaction on this day with three-(unbalanced) postings, where each dot represents "0.25". No commodity-symbol is assumed, but we typically interpret it as hours.--$ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required-2023-05-01 *- (hom:errands) 2.00 ; two hours- (fos:hledger:timedot) 0.50 ; half an hour- (per:admin:finance) 0-- A timedot file contains a series of transactions (usually one per-day). Each begins with a *simple date* (Y-M-D, Y/M/D, or Y.M.D),-optionally be followed on the same line by a transaction description,-and/or a transaction comment following a semicolon.-- After the date line are zero or more time postings, consisting of:-- * *An account name* - any hledger-style account name, optionally- indented.-- * *Two or more spaces* - required if there is an amount (as in- journal format).-- * *A timedot amount*, which can be-- * empty (representing zero)-- * a number, optionally followed by a unit 's', 'm', 'h', 'd',- 'w', 'mo', or 'y', representing a precise number of seconds,- minutes, hours, days weeks, months or years (hours is assumed- by default), which will be converted to hours according to 60s- = 1m, 60m = 1h, 24h = 1d, 7d = 1w, 30d = 1mo, 365d = 1y.-- * one or more dots (period characters), each representing 0.25.- These are the dots in "timedot". Spaces are ignored and can- be used for grouping/alignment.-- * _Added in 1.32_ one or more letters. These are like dots but- they also generate a tag 't:' (short for "type") with the- letter as its value, and a separate posting for each of the- values. This provides a second dimension of categorisation,- viewable in reports with '--pivot t'.-- * *An optional comment* following a semicolon (a hledger-style- posting comment).-- There is some flexibility to help with keeping time log data and-notes in the same file:-- * Blank lines and lines beginning with '#' or ';' are ignored.-- * After the first date line, lines which do not contain a double- space are parsed as postings with zero amount. (hledger's register- reports will show these if you add -E).-- * Before the first date line, lines beginning with '*' (eg org- headings) are ignored. And from the first date line onward, Emacs- org mode heading prefixes at the start of lines (one or more '*''s- followed by a space) will be ignored. This means the time log can- also be a org outline.--* Menu:--* Timedot examples::---File: hledger.info, Node: Timedot examples, Up: Timedot--12.1 Timedot examples-=====================--Numbers:--2016/2/3-inc:client1 4-fos:hledger 3h-biz:research 60m-- Dots:--# 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 .--$ 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 -- Letters:--# Activity types:-# c cleanup/catchup/repair-# e enhancement-# s support-# l learning/research--2023-11-01-work:adm ccecces--$ hledger -f a.timedot print-2023-11-01- (work:adm) 1 ; t:c- (work:adm) 0.5 ; t:e- (work:adm) 0.25 ; t:s--$ hledger -f a.timedot bal- 1.75 work:adm---------------------- 1.75 --$ hledger -f a.timedot bal --pivot t- 1.00 c- 0.50 e- 0.25 s---------------------- 1.75 -- Org:--* 2023 Work Diary-** Q1-*** 2023-02-29-**** DONE-0700 yoga-**** UNPLANNED-**** BEGUN-hom:chores- cleaning ...- water plants- outdoor - one full watering can- indoor - light watering-**** TODO-adm:planning: trip-*** LATER-- Using '.' as account name separator:--2016/2/4-fos.hledger.timedot 4h-fos.ledger ..--$ hledger -f a.timedot --alias '/\./=:' bal -t- 4.50 fos- 4.00 hledger:timedot- 0.50 ledger---------------------- 4.50---File: hledger.info, Node: PART 3 REPORTING CONCEPTS, Next: Amount formatting, Prev: Timedot, Up: Top--13 PART 3: REPORTING CONCEPTS-*****************************---File: hledger.info, Node: Amount formatting, Next: Time periods, Prev: PART 3 REPORTING CONCEPTS, Up: Top--14 Amount formatting-********************--* Menu:--* Commodity display style::-* Rounding::-* Trailing decimal marks::-* Amount parseability::---File: hledger.info, Node: Commodity display style, Next: Rounding, Up: Amount formatting--14.1 Commodity display style-============================--For the amounts in each commodity, hledger chooses a consistent display-style (symbol placement, decimal mark and digit group marks, number of-decimal digits) to use in most reports. This is inferred as follows:-- First, if there's a 'D' directive declaring a default commodity, that-commodity symbol and amount format is applied to all no-symbol amounts-in the journal.-- Then each commodity's display style is determined from its-'commodity' directive. We recommend always declaring commodities with-'commodity' directives, since they help ensure consistent display styles-and precisions, and bring other benefits such as error checking for-commodity symbols. Here's an example:--# Set display styles (and decimal marks, for parsing, if there is no decimal-mark directive)-# for the $, EUR, INR and no-symbol commodities:-commodity $1,000.00-commodity EUR 1.000,00-commodity INR 9,99,99,999.00-commodity 1 000 000.9455-- But for convenience, if a 'commodity' directive is not present,-hledger infers a commodity's display styles from its amounts as they are-written in the journal (excluding cost amounts and amounts in periodic-transaction rules or auto posting rules). It uses-- * the symbol placement and decimal mark of the first amount seen- * the digit group marks of the first amount with digit group marks- * and the maximum number of decimal digits seen across all amounts.-- And as fallback if no applicable amounts are found, it would use a-default style, like '$1000.00' (symbol on the left with no space, period-as decimal mark, and two decimal digits).-- Finally, commodity styles can be overridden by the-'-c/--commodity-style' command line option.---File: hledger.info, Node: Rounding, Next: Trailing decimal marks, Prev: Commodity display style, Up: Amount formatting--14.2 Rounding-=============--Amounts are stored internally as decimal numbers with up to 255 decimal-places. They are displayed with their original journal precisions by-print and print-like reports, and rounded to their display precision-(the number of decimal digits specified by the commodity display style)-by other reports. When rounding, hledger uses banker's rounding (it-rounds to the nearest even digit). So eg 0.5 displayed with zero-decimal digits appears as "0".---File: hledger.info, Node: Trailing decimal marks, Next: Amount parseability, Prev: Rounding, Up: Amount formatting--14.3 Trailing decimal marks-===========================--If you're wondering why your 'print' report sometimes shows trailing-decimal marks, with no decimal digits; it does this when showing amounts-that have digit group marks but no decimal digits, to disambiguate them-and allow them to be re-parsed reliably (see Decimal marks). Eg:--commodity $1,000.00--2023-01-02- (a) $1000--$ hledger print-2023-01-02- (a) $1,000.-- If this is a problem (eg when exporting to Ledger), you can avoid it-by disabling digit group marks, eg with -c/-commodity (for each affected-commodity):--$ hledger print -c '$1000.00'-2023-01-02- (a) $1000-- or by forcing print to always show decimal digits, with -round:--$ hledger print -c '$1,000.00' --round=soft-2023-01-02- (a) $1,000.00---File: hledger.info, Node: Amount parseability, Prev: Trailing decimal marks, Up: Amount formatting--14.4 Amount parseability-========================--More generally, hledger output falls into three rough categories, which-format amounts a little bit differently to suit different consumers:-- *1. "hledger-readable output" - should be readable by hledger (and-by humans)*-- * This is produced by reports that show full journal entries:- 'print', 'import', 'close', 'rewrite' etc.- * It shows amounts with their original journal precisions, which may- not be consistent.- * It adds a trailing decimal mark when needed to avoid showing- ambiguous amounts.- * It can be parsed reliably (by hledger and ledger2beancount at- least, but perhaps not by Ledger..)-- *2. "human-readable output" - usually for humans*-- * This is produced by all other reports.- * It shows amounts with standard display precisions, which will be- consistent within each commodity.- * It shows ambiguous amounts unmodified.- * It can be parsed reliably in the context of a known report (when- you know decimals are consistently not being shown, you can assume- a single mark is a digit group mark).-- *3. "machine-readable output" - usually for other software*-- * This is produced by all reports when an output format like 'csv',- 'tsv', 'json', or 'sql' is selected.- * It shows amounts as 1 or 2 do, but without digit group marks.- * It can be parsed reliably (if needed, the decimal mark can be- changed with -c/-commodity-style).---File: hledger.info, Node: Time periods, Next: Depth, Prev: Amount formatting, Up: Top--15 Time periods-***************--* Menu:--* Report start & end date::-* Smart dates::-* Report intervals::-* Date adjustment::-* Period expressions::---File: hledger.info, Node: Report start & end date, Next: Smart dates, Up: Time periods--15.1 Report start & end date-============================--By default, most hledger reports will show the full span of time-represented by the journal. The report start date will be the earliest-transaction or posting date, and the report end date will be the latest-transaction, posting, or market price date.-- Often you will want to see a shorter time span, such as the current-month. You can specify a start and/or end date using '-b/--begin',-'-e/--end', '-p/--period' or a 'date:' query (described below). All of-these accept the smart date syntax (below).-- Some notes:-- * End dates are exclusive, as in Ledger, so you should write the date- _after_ the last day you want to see in the report.- * As noted in reporting options: among start/end dates specified with- _options_, the last (i.e. right-most) option takes precedence.- * 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.- * In some cases a report interval will adjust start/end dates to fall- on interval boundaries (see below).-- Examples:--'-b begin on St. Patrick's day 2016-2016/3/17'-'-e 12/1' end at the start of december 1st of the current year- (11/30 will be the last date included)-'-b all transactions on or after the 1st of the current month-thismonth'-'-p all transactions in the current month-thismonth'-'date:2016/3/17..'the above written as queries instead ('..' can also be- replaced with '-')-'date:..12/1'-'date:thismonth..'-'date:thismonth'---File: hledger.info, Node: Smart dates, Next: Report intervals, Prev: Report start & end date, Up: Time periods--15.2 Smart dates-================--hledger's user interfaces accept a "smart date" syntax for added-convenience. Smart dates optionally can be relative to today's date, be-written with english words, and have less-significant parts omitted-(missing parts are inferred as 1). Some examples:--'2004/10/1', exact date, several separators allowed. Year-'2004-01-01', is 4+ digits, month is 1-12, day is 1-31-'2004.9.1'-'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, -1, 0, 1 days from today-tomorrow'-'last/this/next -1, 0, 1 periods from the current period-day/week/month/quarter/year'-'in n n periods from the current period-days/weeks/months/quarters/years'-'n n periods from the current period-days/weeks/months/quarters/years-ahead'-'n -n periods from the current period-days/weeks/months/quarters/years-ago'-'20181201' 8 digit YYYYMMDD with valid year month and- day-'201812' 6 digit YYYYMM with valid year and month-- Some 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-- "Today's date" can be overridden with the '--today' option, in case-it's needed for testing or for recreating old reports. (Except for-periodic transaction rules, which are not affected by '--today'.)---File: hledger.info, Node: Report intervals, Next: Date adjustment, Prev: Smart dates, Up: Time periods--15.3 Report intervals-=====================--A report interval can be specified so that reports like register,-balance or activity become multi-period, showing each subperiod as a-separate row or column.-- The following standard intervals can be enabled with command-line-flags:-- * '-D/--daily'- * '-W/--weekly'- * '-M/--monthly'- * '-Q/--quarterly'- * '-Y/--yearly'-- More complex intervals can be specified using '-p/--period',-described below.---File: hledger.info, Node: Date adjustment, Next: Period expressions, Prev: Report intervals, Up: Time periods--15.4 Date adjustment-====================--When there is a report interval (other than daily), report start/end-dates which have been inferred, eg from the journal, are automatically-adjusted to natural period boundaries. This is convenient for producing-simple periodic reports. More precisely:-- * an inferred start date will be adjusted earlier if needed to fall- on a natural period boundary-- * an inferred end date will be adjusted later if needed to make the- last period the same length as the others.-- By contrast, start/end dates which have been specified explicitly,-with '-b', '-e', '-p' or 'date:', will not be adjusted (since hledger-1.29). This makes it possible to specify non-standard report periods,-but it also means that if you are specifying a start date, you should-pick one that's on a period boundary if you want to see simple report-period headings.---File: hledger.info, Node: Period expressions, Prev: Date adjustment, Up: Time periods--15.5 Period expressions-=======================--The '-p/--period' option specifies a period expression, which is a-compact way of expressing a start date, end date, and/or report-interval.-- Here's a period expression with a start and end date (specifying the-first quarter of 2009):--'-p "from 2009/1/1 to 2009/4/1"'-- Several keywords like "from" and "to" are supported for readability;-these are optional. "to" can also be written as ".." or "-". The-spaces are also optional, as long as you don't run two dates together.-So the following are equivalent to the above:--'-p "2009/1/1 2009/4/1"'-'-p2009/1/1to2009/4/1'-'-p2009/1/1..2009/4/1'-- Dates are smart dates, so if the current year is 2009, these are also-equivalent to the above:--'-p "1/1 4/1"'-'-p "jan-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 date in the journal:--'-p "from 2009/1/1"' everything after january 1, 2009-'-p "since 2009/1"' the same, since is a synonym-'-p "from 2009"' the same-'-p "to 2009"' everything before january 1, 2009-- You can also specify a period by writing a single partial or full-date:--'-p "2009"' the year 2009; equivalent to “2009/1/1 to 2010/1/1”-'-p "2009/1"' the month of january 2009; equivalent to “2009/1/1 to- 2009/2/1”-'-p the first day of 2009; equivalent to “2009/1/1 to-"2009/1/1"' 2009/1/2”-- or by using the "Q" quarter-year syntax (case insensitive):--'-p "2009Q1"' first quarter of 2009, equivalent to “2009/1/1 to- 2009/4/1”-'-p "q4"' fourth quarter of the current year--* Menu:--* Period expressions with a report interval::-* More complex report intervals::-* Multiple weekday intervals::---File: hledger.info, Node: Period expressions with a report interval, Next: More complex report intervals, Up: Period expressions--15.5.1 Period expressions with a report interval---------------------------------------------------A period expression can also begin with a report interval, separated-from the start/end dates (if any) by a space or the word 'in':--'-p "weekly from 2009/1/1 to 2009/4/1"'-'-p "monthly in 2008"'-'-p "quarterly"'---File: hledger.info, Node: More complex report intervals, Next: Multiple weekday intervals, Prev: Period expressions with a report interval, Up: Period expressions--15.5.2 More complex report intervals---------------------------------------Some more complex intervals can be specified within period expressions,-such as:-- * 'biweekly' (every two weeks)- * 'fortnightly'- * 'bimonthly' (every two months)- * 'every day|week|month|quarter|year'- * 'every N days|weeks|months|quarters|years'-- Weekly on a custom day:-- * 'every Nth day of week' ('th', 'nd', 'rd', or 'st' are all accepted- after the number)- * 'every WEEKDAYNAME' (full or three-letter english weekday name,- case insensitive)-- Monthly on a custom day:-- * 'every Nth day [of month]'- * 'every Nth WEEKDAYNAME [of month]'-- Yearly on a custom day:-- * 'every MM/DD [of year]' (month number and day of month number)- * 'every MONTHNAME DDth [of year]' (full or three-letter english- month name, case insensitive, and day of month number)- * 'every DDth MONTHNAME [of year]' (equivalent to the above)-- Examples:--'-p "bimonthly from-2008"'-'-p "every 2 weeks"'-'-p "every 5 months from-2009/03"'-'-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- November-'-p "every 5th November"' same-'-p "every Nov 5th"' same-- Show historical balances at end of the 15th day of each month (N is-an end date, exclusive as always):--$ hledger balance -H -p "every 16th day"-- Group postings from the start of wednesday to end of the following-tuesday (N is both (inclusive) start date and (exclusive) end date):--$ hledger register checking -p "every 3rd day of week"---File: hledger.info, Node: Multiple weekday intervals, Prev: More complex report intervals, Up: Period expressions--15.5.3 Multiple weekday intervals------------------------------------This special form is also supported:-- * 'every WEEKDAYNAME,WEEKDAYNAME,...' (full or three-letter english- weekday names, case insensitive)-- Also, 'weekday' and 'weekendday' are shorthand for-'mon,tue,wed,thu,fri' and 'sat,sun'.-- This is mainly intended for use with '--forecast', to generate-periodic transactions on arbitrary days of the week. It may be less-useful with '-p', since it divides each week into subperiods of unequal-length, which is unusual. (Related: #1632)-- Examples:--'-p "every dates will be Mon, Wed, Fri; periods will be-mon,wed,fri"' Mon-Tue, Wed-Thu, Fri-Sun-'-p "every dates will be Mon, Tue, Wed, Thu, Fri; periods will-weekday"' be Mon, Tue, Wed, Thu, Fri-Sun-'-p "every dates will be Sat, Sun; periods will be Sat, Sun-Fri-weekendday"'---File: hledger.info, Node: Depth, Next: Queries, Prev: Time periods, Up: Top--16 Depth-********--With the '--depth NUM' option (short form: '-NUM'), reports will show-accounts only to the specified depth, hiding deeper subaccounts. Use-this when you want a summary with less detail. This flag has the same-effect as a 'depth:' query argument: 'depth:2', '--depth=2' or '-2' are-equivalent.---File: hledger.info, Node: Queries, Next: Pivoting, Prev: Depth, Up: Top--17 Queries-**********--One of hledger's strengths is being able to quickly report on a precise-subset of your data. Most hledger commands accept query arguments, to-restrict their scope. Multiple query terms can be provided to build up-a more complex query.-- * By default, a query term is interpreted as a case-insensitive- substring pattern for matching account names:-- 'car:fuel'- 'dining groceries'-- * Patterns containing spaces or other special characters must be- enclosed in single or double quotes:-- ''personal care''-- * These patterns are actually regular expressions, so you can add- regexp metacharacters for more precision (see "Regular expressions"- above for details):-- ''^expenses\b''- ''food$''- ''fuel|repair''- ''accounts (payable|receivable)''-- * To match something other than account name, add one of the query- type prefixes described in "Query types" below:-- 'date:202312-'- 'status:'- 'desc:amazon'- 'cur:USD'- 'cur:\\$'- 'amt:'>0''-- * Add a 'not:' prefix to negate a term:-- 'not:status:'*''- 'not:desc:'opening|closing''- 'not:cur:USD'-- * Terms with different types are AND-ed, terms with the same type are- OR-ed (mostly; see "Combining query terms" below). The following- query:-- 'date:2022 desc:amazon desc:amzn'-- is interpreted as:-- _date is in 2022 AND ( transaction description contains "amazon" OR- "amzn" )_--* Menu:--* Query types::-* Combining query terms::-* Queries and command options::-* Queries and account aliases::-* Queries and valuation::---File: hledger.info, Node: Query types, Next: Combining query terms, Up: Queries--17.1 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'* or *'REGEX'*-Match account names containing this case insensitive regular expression.-This is the default query type, so we usually don't bother writing the-"acct:" prefix.-- *'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.-Otherwise, the absolute magnitudes are compared, ignoring sign.-- *'code:REGEX'*-Match by transaction code (eg check number).-- *'cur:REGEX'*-Match postings or transactions including any amounts whose-currency/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.-- *'expr:"TERM AND NOT (TERM OR TERM)"'* (eg)-Match with a boolean combination of queries (which must be enclosed in-quotes). See Combining query terms below.-- *'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.-- *'type:TYPECODES'*-Match by account type (see Declaring accounts > Account types).-'TYPECODES' is one or more of the single-letter account type codes-'ALERXCV', case insensitive. Note 'type:A' and 'type:E' will also match-their respective subtypes 'C' (Cash) and 'V' (Conversion). Certain-kinds of account alias can disrupt account types, see Rewriting accounts-> Aliases and account types.-- *'tag:REGEX[=REGEX]'*-Match by tag name, and optionally also by tag value. (To match only by-value, use 'tag:.=REGEX'.)-- When querying by tag, note that:-- * Accounts also inherit the tags of their parent accounts- * Postings also inherit the tags of their account and their- transaction- * Transactions also acquire the tags of their postings.-- (*'inacct:ACCTNAME'*-A special query term used automatically in hledger-web only: tells-hledger-web to show the transaction register for an account.)---File: hledger.info, Node: Combining query terms, Next: Queries and command options, Prev: Query types, Up: Queries--17.2 Combining query terms-==========================--When given multiple space-separated query terms, most commands select-things which match:-- * any of the description terms AND- * any of the account terms AND- * any of the status terms AND- * all the other terms.-- The print command is a little different, showing transactions which:-- * match any of the description terms AND- * have any postings matching any of the positive account terms AND- * have no postings matching any of the negative account terms AND- * match all the other terms.-- We also support more complex boolean queries with the 'expr:' prefix.-This allows one to combine query terms using 'and', 'or', 'not' keywords-(case insensitive), and to group them by enclosing in parentheses.-- Some examples:-- * Exclude account names containing 'food':-- 'expr:"not food"' ('not:food' is equivalent)-- * Match things which have 'cool' in the description and the 'A' tag:-- 'expr:"desc:cool and tag:A"' ('expr:"desc:cool tag:A"' is- equivalent)-- * Match things which either do not reference the 'expenses:food'- account, or do have the 'A' tag:-- 'expr:"not expenses:food or tag:A"'-- * Match things which either do not reference the 'expenses:food'- account, or which reference the 'expenses:drink' account and also- have the 'A' tag:-- 'expr:"expenses:food or (expenses:drink and tag:A)"'-- 'expr:' has a restriction: 'date:' queries may not be used inside-'or' expressions. That would allow disjoint report periods or disjoint-result sets, with unclear semantics for our reports.---File: hledger.info, Node: Queries and command options, Next: Queries and account aliases, Prev: Combining query terms, Up: Queries--17.3 Queries and command options-================================--Some queries can also be expressed as command-line options: 'depth:2' is-equivalent to '--depth 2', 'date:2023' is equivalent to '-p 2023', etc.-When you mix command options and query arguments, generally the-resulting query is their intersection.---File: hledger.info, Node: Queries and account aliases, Next: Queries and valuation, Prev: Queries and command options, Up: Queries--17.4 Queries and account aliases-================================--When account names are rewritten with '--alias' or 'alias', 'acct:' will-match either the old or the new account name.---File: hledger.info, Node: Queries and valuation, Prev: Queries and account aliases, Up: Queries--17.5 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, #1625.)---File: hledger.info, Node: Pivoting, Next: Generating data, Prev: Queries, Up: Top--18 Pivoting-***********--Normally, hledger groups and sums amounts within each account. The-'--pivot FIELD' option substitutes some other transaction field for-account names, causing amounts to be grouped and summed by that field's-value instead. FIELD can be any of the transaction fields 'acct',-'status', 'code', 'desc', 'payee', 'note', or a tag name. When pivoting-on a tag and a posting has multiple values of that tag, only the first-value is displayed. Values containing 'colon:separated:parts' will be-displayed hierarchically, like account names. Multiple, colon-delimited-fields can be pivoted simultaneously, generating a hierarchical account-name.-- Some examples:--2016/02/16 Yearly Dues Payment- assets:bank account 2 EUR- income:dues -2 EUR ; member: John Doe, kind: Lifetime-- Normal balance report showing account names:--$ hledger balance- 2 EUR assets:bank account- -2 EUR income:dues---------------------- 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):--$ 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-- Hierarchical reports can be generated with multiple pivots:--$ hledger balance Income:Dues --pivot kind:member- -2 EUR Lifetime:John Doe---------------------- -2 EUR---File: hledger.info, Node: Generating data, Next: Forecasting, Prev: Pivoting, Up: Top--19 Generating data-******************--hledger has several features for generating data, such as:-- * Periodic transaction rules can generate single or repeating- transactions following a template. These are usually dated in the- future, eg to help with forecasting. They are activated by the- '--forecast' option.-- * The balance command's '--budget' option uses these same periodic- rules to generate goals for the budget report.-- * Auto posting rules can generate extra postings on certain matched- transactions. They are always applied to forecast transactions;- with the '--auto' flag they are applied to transactions recorded in- the journal as well.-- * The '--infer-equity' flag infers missing conversion equity postings- from @/@@ costs. And the inverse '--infer-costs' flag infers- missing @/@@ costs from conversion equity postings.-- Generated data of this kind is temporary, existing only at report-time. But you can see it in the output of 'hledger print', and you can-save that to your journal, in effect converting it from temporary-generated data to permanent recorded data. This could be useful as a-data entry aid.-- If you are wondering what data is being generated and why, add the-'--verbose-tags' flag. In 'hledger print' output you will see extra-tags like 'generated-transaction', 'generated-posting', and 'modified'-on generated/modified data. Also, even without '--verbose-tags',-generated data always has equivalen hidden tags (with an underscore-prefix), so eg you could match generated transactions with-'tag:_generated-transaction'.---File: hledger.info, Node: Forecasting, Next: Budgeting, Prev: Generating data, Up: Top--20 Forecasting-**************--Forecasting, or speculative future reporting, can be useful for-estimating future balances, or for exploring different future scenarios.-- The simplest and most flexible way to do it with hledger is to-manually record a bunch of future-dated transactions. You could keep-these in a separate 'future.journal' and include that with '-f' only-when you want to see them.--* Menu:--* --forecast::-* Inspecting forecast transactions::-* Forecast reports::-* Forecast tags::-* Forecast period in detail::-* Forecast troubleshooting::---File: hledger.info, Node: --forecast, Next: Inspecting forecast transactions, Up: Forecasting--20.1 -forecast-==============--There is another way: with the '--forecast' option, hledger can generate-temporary "forecast transactions" for reporting purposes, according to-periodic transaction rules defined in the journal. Each rule can-generate multiple recurring transactions, so by changing one rule you-can change many forecasted transactions.-- Forecast transactions usually start after ordinary transactions end.-By default, they begin after your latest-dated ordinary transaction, or-today, whichever is later, and they end six months from today. (The-exact rules are a little more complicated, and are given below.)-- This is the "forecast period", which need not be the same as the-report period. You can override it - eg to forecast farther into the-future, or to force forecast transactions to overlap your ordinary-transactions - by giving the -forecast option a period expression-argument, like '--forecast=..2099' or '--forecast=2023-02-15..'. Note-that the '=' is required.---File: hledger.info, Node: Inspecting forecast transactions, Next: Forecast reports, Prev: --forecast, Up: Forecasting--20.2 Inspecting forecast transactions-=====================================--'print' is the best command for inspecting and troubleshooting forecast-transactions. Eg:--~ monthly from 2022-12-20 rent- assets:bank:checking- expenses:rent $1000--$ hledger print --forecast --today=2023/4/21-2023-05-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000--2023-06-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000--2023-07-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000--2023-08-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000--2023-09-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- Here there are no ordinary transactions, so the forecasted-transactions begin on the first occurence after today's date. (You-won't normally use '--today'; it's just to make these examples-reproducible.)---File: hledger.info, Node: Forecast reports, Next: Forecast tags, Prev: Inspecting forecast transactions, Up: Forecasting--20.3 Forecast reports-=====================--Forecast transactions affect all reports, as you would expect. Eg:--$ hledger areg rent --forecast --today=2023/4/21-Transactions in expenses:rent and subaccounts:-2023-05-20 rent as:ba:checking $1000 $1000-2023-06-20 rent as:ba:checking $1000 $2000-2023-07-20 rent as:ba:checking $1000 $3000-2023-08-20 rent as:ba:checking $1000 $4000-2023-09-20 rent as:ba:checking $1000 $5000--$ hledger bal -M expenses --forecast --today=2023/4/21-Balance changes in 2023-05-01..2023-09-30:-- || May Jun Jul Aug Sep -===============++===================================- expenses:rent || $1000 $1000 $1000 $1000 $1000 ----------------++------------------------------------ || $1000 $1000 $1000 $1000 $1000 ---File: hledger.info, Node: Forecast tags, Next: Forecast period in detail, Prev: Forecast reports, Up: Forecasting--20.4 Forecast tags-==================--Forecast transactions generated by -forecast have a hidden tag,-'_generated-transaction'. So if you ever need to match forecast-transactions, you could use 'tag:_generated-transaction' (or just-'tag:generated') in a query.-- For troubleshooting, you can add the '--verbose-tags' flag. Then,-visible 'generated-transaction' tags will be added also, so you can view-them with the 'print' command. Their value indicates which periodic-rule was responsible.---File: hledger.info, Node: Forecast period in detail, Next: Forecast troubleshooting, Prev: Forecast tags, Up: Forecasting--20.5 Forecast period, in detail-===============================--Forecast start/end dates are chosen so as to do something useful by-default in almost all situations, while also being flexible. Here are-(with luck) the exact rules, to help with troubleshooting:-- The forecast period starts on:-- * the later of- * the start date in the periodic transaction rule- * the start date in '--forecast''s argument-- * otherwise (if those are not available): the later of- * the report start date specified with '-b'/'-p'/'date:'- * the day after the latest ordinary transaction in the journal-- * otherwise (if none of these are available): today.-- The forecast period ends on:-- * the earlier of- * the end date in the periodic transaction rule- * the end date in '--forecast''s argument-- * otherwise: the report end date specified with '-e'/'-p'/'date:'- * otherwise: 180 days (~6 months) from today.---File: hledger.info, Node: Forecast troubleshooting, Prev: Forecast period in detail, Up: Forecasting--20.6 Forecast troubleshooting-=============================--When -forecast is not doing what you expect, one of these tips should-help:-- * Remember to use the '--forecast' option.- * Remember to have at least one periodic transaction rule in your- journal.- * Test with 'print --forecast'.- * Check for typos or too-restrictive start/end dates in your periodic- transaction rule.- * Leave at least 2 spaces between the rule's period expression and- description fields.- * Check for future-dated ordinary transactions suppressing forecasted- transactions.- * Try setting explicit report start and/or end dates with '-b', '-e',- '-p' or 'date:'- * Try adding the '-E' flag to encourage display of empty periods/zero- transactions.- * Try setting explicit forecast start and/or end dates with- '--forecast=START..END'- * Consult Forecast period, in detail, above.- * Check inside the engine: add '--debug=2' (eg).---File: hledger.info, Node: Budgeting, Next: Cost reporting, Prev: Forecasting, Up: Top--21 Budgeting-************--With the balance command's '--budget' report, each periodic transaction-rule generates recurring budget goals in specified accounts, and goals-and actual performance can be compared. See the balance command's doc-below.-- You can generate budget goals and forecast transactions at the same-time, from the same or different periodic transaction rules: 'hledger-bal -M --budget --forecast ...'-- See also: Budgeting and Forecasting.---File: hledger.info, Node: Cost reporting, Next: Value reporting, Prev: Budgeting, Up: Top--22 Cost reporting-*****************--In some transactions - for example a currency conversion, or a purchase-or sale of stock - one commodity is exchanged for another. In these-transactions there is a conversion rate, also called the cost (when-buying) or selling price (when selling). In hledger docs we just say-"cost", for convenience; feel free to mentally translate to "conversion-rate" or "selling price" if helpful.--* Menu:--* Recording costs::-* Reporting at cost::-* Equity conversion postings::-* Inferring equity conversion postings::-* Combining costs and equity conversion postings::-* Requirements for detecting equity conversion postings::-* Infer cost and equity by default ?::---File: hledger.info, Node: Recording costs, Next: Reporting at cost, Up: Cost reporting--22.1 Recording costs-====================--We'll explore several ways of recording transactions involving costs.-These are also summarised at hledger Cookbook > Cost notation.-- Costs can be recorded explicitly in the journal, using the '@-UNITCOST' or '@@ TOTALCOST' notation described in Journal > Costs:-- *Variant 1*--2022-01-01- assets:dollars $-135- assets:euros €100 @ $1.35 ; $1.35 per euro (unit cost)-- *Variant 2*--2022-01-01- assets:dollars $-135- assets:euros €100 @@ $135 ; $135 total cost-- Typically, writing the unit cost (variant 1) is preferable; it can be-more effort, requiring more attention to decimal digits; but it reveals-the per-unit cost basis, and makes stock sales easier.-- Costs can also be left implicit, and hledger will infer the cost that-is consistent with a balanced transaction:-- *Variant 3*--2022-01-01- assets:dollars $-135- assets:euros €100-- Here, hledger will attach a '@@ €100' cost to the first amount (you-can see it with 'hledger print -x'). This form looks convenient, but-there are downsides:-- * It sacrifices some error checking. For example, if you- accidentally wrote €10 instead of €100, hledger would not be able- to detect the mistake.-- * It is sensitive to the order of postings - if they were reversed, a- different entry would be inferred and reports would be different.-- * The per-unit cost basis is not easy to read.-- So generally this kind of entry is not recommended. You can make-sure you have none of these by using '-s' (strict mode), or by running-'hledger check balanced'.---File: hledger.info, Node: Reporting at cost, Next: Equity conversion postings, Prev: Recording costs, Up: Cost reporting--22.2 Reporting at cost-======================--Now when you add the '-B'/'--cost' flag to reports ("B" is from Ledger's--B/-basis/-cost flag), any amounts which have been annotated with costs-will be converted to their cost's commodity (in the report output). Ie-they will be displayed "at cost" or "at sale price".-- Some things to note:-- * Costs are attached to specific posting amounts in specific- transactions, and once recorded they do not change. This contrasts- with market prices, which are ambient and fluctuating.-- * Conversion to cost is performed before conversion to market value- (described below).---File: hledger.info, Node: Equity conversion postings, Next: Inferring equity conversion postings, Prev: Reporting at cost, Up: Cost reporting--22.3 Equity conversion postings-===============================--There is a problem with the entries above - they are not conventional-Double Entry Bookkeeping (DEB) notation, and because of the "magical"-transformation of one commodity into another, they cause an imbalance in-the Accounting Equation. This shows up as a non-zero grand total in-balance reports like 'hledger bse'.-- For most hledger users, this doesn't matter in practice and can-safely be ignored ! But if you'd like to learn more, keep reading.-- Conventional DEB uses an extra pair of equity postings to balance the-transaction. Of course you can do this in hledger as well:-- *Variant 4*--2022-01-01- assets:dollars $-135- assets:euros €100- equity:conversion $135- equity:conversion €-100-- Now the transaction is perfectly balanced according to standard DEB,-and 'hledger bse''s total will not be disrupted.-- And, hledger can still infer the cost for cost reporting, but it's-not done by default - you must add the '--infer-costs' flag like so:--$ hledger print --infer-costs-2022-01-01 one hundred euros purchased at $1.35 each- assets:dollars $-135 @@ €100- assets:euros €100- equity:conversion $135- equity:conversion €-100--$ hledger bal --infer-costs -B- €-100 assets:dollars - €100 assets:euros --------------------- - 0 -- Here are some downsides of this kind of entry:-- * The per-unit cost basis is not easy to read.-- * Instead of '-B' you must remember to type '-B --infer-costs'.-- * '--infer-costs' works only where hledger can identify the two- equity:conversion postings and match them up with the two- non-equity postings. So writing the journal entry in a particular- format becomes more important. More on this below.---File: hledger.info, Node: Inferring equity conversion postings, Next: Combining costs and equity conversion postings, Prev: Equity conversion postings, Up: Cost reporting--22.4 Inferring equity conversion postings-=========================================--Can we go in the other direction ? Yes, if you have transactions-written with the @/@@ cost notation, hledger can infer the missing-equity postings, if you add the '--infer-equity' flag. Eg:--2022-01-01- assets:dollars -$135- assets:euros €100 @ $1.35--$ hledger print --infer-equity-2022-01-01- assets:dollars $-135- assets:euros €100 @ $1.35- equity:conversion:$-€:€ €-100- equity:conversion:$-€:$ $135.00-- The equity account names will be "equity:conversion:A-B:A" and-"equity:conversion:A-B:B" where A is the alphabetically first commodity-symbol. You can customise the "equity:conversion" part by declaring an-account with the 'V'/'Conversion' account type.---File: hledger.info, Node: Combining costs and equity conversion postings, Next: Requirements for detecting equity conversion postings, Prev: Inferring equity conversion postings, Up: Cost reporting--22.5 Combining costs and equity conversion postings-===================================================--Finally, you can use both the @/@@ cost notation and equity postings at-the same time. This in theory gives the best of all worlds - preserving-the accounting equation, revealing the per-unit cost basis, and-providing more flexibility in how you write the entry:-- *Variant 5*--2022-01-01 one hundred euros purchased at $1.35 each- assets:dollars $-135- equity:conversion $135- equity:conversion €-100- assets:euros €100 @ $1.35-- All the other variants above can (usually) be rewritten to this final-form with:--$ hledger print -x --infer-costs --infer-equity-- Downsides:-- * The precise format of the journal entry becomes more important. If- hledger can't detect and match up the cost and equity postings, it- will give a transaction balancing error.-- * The add command does not yet accept this kind of entry (#2056).-- * This is the most verbose form.---File: hledger.info, Node: Requirements for detecting equity conversion postings, Next: Infer cost and equity by default ?, Prev: Combining costs and equity conversion postings, Up: Cost reporting--22.6 Requirements for detecting equity conversion postings-==========================================================--'--infer-costs' has certain requirements (unlike '--infer-equity', which-always works). It will infer costs only in transactions with:-- * Two non-equity postings, in different commodities. Their order is- significant: the cost will be added to the first of them.-- * Two postings to equity conversion accounts, next to one another,- which balance the two non-equity postings. This balancing is- checked to the same precision (number of decimal places) used in- the conversion posting's amount. Equity conversion accounts are:-- * any accounts declared with account type 'V'/'Conversion', or- their subaccounts- * otherwise, accounts named 'equity:conversion', 'equity:trade',- or 'equity:trading', or their subaccounts.-- And multiple such four-posting groups can coexist within a single-transaction. When '--infer-costs' fails, it does not infer a cost in-that transaction, and does not raise an error (ie, it infers costs where-it can).-- Reading variant 5 journal entries, combining cost notation and equity-postings, has all the same requirements. When reading such an entry-fails, hledger raises an "unbalanced transaction" error.---File: hledger.info, Node: Infer cost and equity by default ?, Prev: Requirements for detecting equity conversion postings, Up: Cost reporting--22.7 Infer cost and equity by default ?-=======================================--Should '--infer-costs' and '--infer-equity' be enabled by default ? Try-using them always, eg with a shell alias:--alias h="hledger --infer-equity --infer-costs"-- and let us know what problems you find.---File: hledger.info, Node: Value reporting, Next: PART 4 COMMANDS, Prev: Cost reporting, Up: Top--23 Value reporting-******************--Instead of reporting amounts in their original commodity, hledger can-convert them to cost/sale amount (using the conversion rate recorded in-the transaction), and/or to market value (using some market price on a-certain date). This is controlled by the '--value=TYPE[,COMMODITY]'-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:--* Menu:--* -V Value::-* -X Value in specified commodity::-* Valuation date::-* Finding market price::-* --infer-market-prices market prices from transactions::-* Valuation commodity::-* --value Flexible valuation::-* Valuation examples::-* Interaction of valuation and queries::-* Effect of valuation on reports::---File: hledger.info, Node: -V Value, Next: -X Value in specified commodity, Up: Value reporting--23.1 -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.---File: hledger.info, Node: -X Value in specified commodity, Next: Valuation date, Prev: -V Value, Up: Value reporting--23.2 -X: Value in specified commodity-=====================================--The '-X/--exchange=COMM' option is like '-V', except you tell it which-currency you want to convert to, and it tries to convert everything to-that.---File: hledger.info, Node: Valuation date, Next: Finding market price, Prev: -X Value in specified commodity, Up: Value reporting--23.3 Valuation date-===================--Market prices can change from day to day. hledger will use the prices-on a particular valuation date (or on more than one date). By default-hledger uses "end" dates for valuation. More specifically:-- * For single period reports (including normal print and register- reports):- * If an explicit report end date is specified, that is used- * Otherwise the latest transaction date or P directive date is- used (even if it's in the future)-- * For multiperiod reports, each period is valued on its last day.-- This can be customised with the -value option described below, which-can select either "then", "end", "now", or "custom" dates. (Note, this-has a bug in hledger-ui <=1.31: turning on valuation with the 'V' key-always resets it to "end".)---File: hledger.info, Node: Finding market price, Next: --infer-market-prices market prices from transactions, Prev: Valuation date, Up: Value reporting--23.4 Finding market price-=========================--To convert a commodity A to its market value in another commodity B,-hledger looks for a suitable market price (exchange rate) as follows, 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 directive, or (with the '--infer-market-prices' flag) inferred- from costs.-- 2. A _reverse market price_: the inverse of a declared or inferred- market price from B to A.-- 3. A _forward chain of market prices_: a synthetic price formed by- combining 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-converted.---File: hledger.info, Node: --infer-market-prices market prices from transactions, Next: Valuation commodity, Prev: Finding market price, Up: Value reporting--23.5 -infer-market-prices: 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 costs as additional market prices (as-Ledger does) ? Adding the '--infer-market-prices' flag to '-V', '-X' or-'--value' enables this.-- So for example, 'hledger bs -V --infer-market-prices' will get market-prices both from P directives and from transactions. If both occur on-the same day, the P directive takes precedence.-- There is a downside: value reports can sometimes be affected in-confusing/undesired ways by your journal entries. If this happens to-you, read all of this Value reporting section carefully, and try adding-'--debug' or '--debug=2' to troubleshoot.-- '--infer-market-prices' can infer market prices from:-- * multicommodity transactions with explicit prices ('@'/'@@')-- * multicommodity transactions with implicit prices (no '@', two- commodities, unbalanced). (With these, the order of postings- matters. 'hledger print -x' can be useful for troubleshooting.)-- * multicommodity transactions with equity postings, if cost is- inferred with '--infer-costs'.-- There is a limitation (bug) currently: when a valuation commodity is-not specified, prices inferred with '--infer-market-prices' do not help-select a default valuation commodity, as 'P' prices would. So-conversion might not happen because no valuation commodity was detected-('--debug=2' will show this). To be safe, specify the valuation-commmodity, eg:-- * '-X EUR --infer-market-prices', not '-V --infer-market-prices'- * '--value=then,EUR --infer-market-prices', not '--value=then- --infer-market-prices'-- Signed costs and market prices can be confusing. For reference, here-is the current behaviour, since hledger 1.25. (If you think it should-work differently, see #1870.)--2022-01-01 Positive Unit prices- a A 1- b B -1 @ A 1--2022-01-01 Positive Total prices- a A 1- b B -1 @@ A 1---2022-01-02 Negative unit prices- a A 1- b B 1 @ A -1--2022-01-02 Negative total prices- a A 1- b B 1 @@ A -1---2022-01-03 Double Negative unit prices- a A -1- b B -1 @ A -1--2022-01-03 Double Negative total prices- a A -1- b B -1 @@ A -1-- All of the transactions above are considered balanced (and on each-day, the two transactions are considered equivalent). Here are the-market prices inferred for B:--$ hledger -f- --infer-market-prices prices-P 2022-01-01 B A 1-P 2022-01-01 B A 1.0-P 2022-01-02 B A -1-P 2022-01-02 B A -1.0-P 2022-01-03 B A -1-P 2022-01-03 B A -1.0---File: hledger.info, Node: Valuation commodity, Next: --value Flexible valuation, Prev: --infer-market-prices market prices from transactions, Up: Value reporting--23.6 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-suitable 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-prices' flag is used: the price commodity from the- latest transaction-inferred price for A on or before valuation- date.-- This means:-- * If you have P directives, they determine which commodities '-V'- will convert, and to what.-- * If you have no P directives, and use the '--infer-market-prices'- flag, costs determine it.-- Amounts for which no valuation commodity can be found are not-converted.---File: hledger.info, Node: --value Flexible valuation, Next: Valuation examples, Prev: Valuation commodity, Up: Value reporting--23.7 -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 commodity,- using market prices on each posting's date.-'--value=end'-- Convert amounts to their value in the default valuation commodity,- using market prices on the last day of the report period (or if- unspecified, the journal'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 commodity- using current market prices (as of when report is generated).-'--value=YYYY-MM-DD'-- Convert amounts to their value in the default valuation commodity- 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.---File: hledger.info, Node: Valuation examples, Next: Interaction of valuation and queries, Prev: --value Flexible valuation, Up: Value reporting--23.8 Valuation examples-=======================--Here are some quick examples of '-V':--; one euro is worth this many dollars from nov 1-P 2016/11/01 € $1.10--; purchase some euros on nov 3-2016/11/3- assets:euros €100- assets:checking--; the euro is worth fewer dollars by dec 21-P 2016/12/21 € $1.03-- How many euros do I have ?--$ hledger -f t.j bal -N euros- €100 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-- 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---File: hledger.info, Node: Interaction of valuation and queries, Next: Effect of valuation on reports, Prev: Valuation examples, Up: Value reporting--23.9 Interaction of valuation and queries-=========================================--When matching postings based on queries in the presence of valuation,-the following happens:-- 1. The query is separated into two parts:- 1. the currency ('cur:') or amount ('amt:').- 2. all other parts.-- 2. The postings are matched to the currency and amount queries based- on pre-valued amounts.- 3. Valuation is applied to the postings.- 4. The postings are matched to the other parts of the query based on- post-valued amounts.-- Related: #1625---File: hledger.info, Node: Effect of valuation on reports, Prev: Interaction of valuation and queries, Up: Value reporting--23.10 Effect of valuation on reports-====================================--Here is a reference for how valuation is supposed to affect each part of-hledger's reports. (It's wide, you may need to scroll sideways.) It-may be useful when troubleshooting. If you find problems, please report-them, ideally with a reproducible example. Related: #329, #1083.-- First, a quick 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- subperiods).--Report '-B', '-V', '-X' '--value=then' '--value=end''--value=DATE',-type '--cost' '--value=now'--------------------------------------------------------------------------------*print*-posting cost value at value at posting value at value-amounts report end date report or at- or today journal DATE/today- end-balance unchanged unchanged unchanged unchanged unchanged-assertions/assignments-*register*-starting cost value at valued at day value at value-balance report or each historical report or at-(-H) journal posting was made journal DATE/today- end end-starting cost value at valued at day value at value-balance day before each historical day before at-(-H) report or posting was made report or DATE/today-with journal journal-report start start-interval-posting cost value at value at posting value at value-amounts report or date report or at- journal journal DATE/today- end end-summary summarised value at sum of postings value at value-posting cost period in interval, period at-amounts ends valued at ends DATE/today-with interval start-report-interval-running sum/average sum/average sum/average of sum/average sum/average-total/averageof of displayed values of of- displayed displayed displayed displayed- values values values values-*balance-(bs,-bse, cf,-is)*-balance sums of value at value at posting value at value-changes costs report end date report or at- or today journal DATE/today- of sums of end of of- postings sums of sums- postings of- postings-budget like like like balance like like-amounts balance balance changes balances balance-(-budget) changes changes changes-grand sum of sum of sum of displayed sum of sum of-total displayed displayed valued displayed displayed- values values values values-*balance-(bs,-bse, cf,-is) with-report-interval*-starting sums of value at sums of values value at sums-balances costs of report of postings report of-(-H) postings start of before report start of postings- before sums of start at sums of before- report all respective all report- start postings posting dates postings start- before before- report report- start start-balance sums of same as sums of values balance value-changes costs of -value=end of postings in change in at-(bal, postings period at each DATE/today-is, bs in period respective period, of--change, posting dates valued at sums-cf period of--change) ends postings-end sums of same as sums of values period end value-balances costs of -value=end of postings from balances, at-(bal -H, postings before period valued at DATE/today-is -H, from start to period period of-bs, cf) before end at ends sums- report respective of- start to posting dates postings- period end-budget like like like balance like like-amounts balance balance changes/end balances balance-(-budget) changes/end changes/end balances changes/end- balances balances balances-row sums, sums, sums, averages sums, sums,-totals, averages averages of displayed averages averages-row of of values of of-averages displayed displayed displayed displayed-(-T, -A) values values values values-column sums of sums of sums of sums of sums-totals displayed displayed displayed values displayed of- values values values displayed- values-grand sum, sum, sum, average of sum, sum,-total, average of average of column totals average of average-grand column column column of-average totals totals totals column- totals-- '--cumulative' is omitted to save space, it works like '-H' but with-a zero starting balance.---File: hledger.info, Node: PART 4 COMMANDS, Next: PART 5 COMMON TASKS, Prev: Value reporting, Up: Top--24 PART 4: COMMANDS-*******************--* Menu:--* Commands overview::-* accounts::-* activity::-* add::-* aregister::-* balance::-* balancesheet::-* balancesheetequity::-* cashflow::-* check::-* close::-* codes::-* commodities::-* demo::-* descriptions::-* diff::-* files::-* help::-* import::-* incomestatement::-* notes::-* payees::-* prices::-* print::-* register::-* rewrite::-* roi::-* stats::-* tags::-* test::---File: hledger.info, Node: Commands overview, Next: accounts, Up: PART 4 COMMANDS--24.1 Commands overview-======================--Here are the built-in commands:--* Menu:--* DATA ENTRY::-* DATA CREATION::-* DATA MANAGEMENT::-* REPORTS FINANCIAL::-* REPORTS VERSATILE::-* REPORTS BASIC::-* HELP::-* ADD-ONS::---File: hledger.info, Node: DATA ENTRY, Next: DATA CREATION, Up: Commands overview--24.1.1 DATA ENTRY--------------------These data entry commands are the only ones which can modify your-journal file.-- * add - add transactions using terminal prompts- * import - add new transactions from other files, eg CSV files---File: hledger.info, Node: DATA CREATION, Next: DATA MANAGEMENT, Prev: DATA ENTRY, Up: Commands overview--24.1.2 DATA CREATION----------------------- * close - generate balance-zeroing/restoring transactions- * rewrite - generate auto postings, like print -auto---File: hledger.info, Node: DATA MANAGEMENT, Next: REPORTS FINANCIAL, Prev: DATA CREATION, Up: Commands overview--24.1.3 DATA MANAGEMENT------------------------- * check - check for various kinds of error in the data- * diff - compare account transactions in two journal files---File: hledger.info, Node: REPORTS FINANCIAL, Next: REPORTS VERSATILE, Prev: DATA MANAGEMENT, Up: Commands overview--24.1.4 REPORTS, FINANCIAL---------------------------- * aregister (areg) - show transactions in a particular account- * balancesheet (bs) - show assets, liabilities and net worth- * balancesheetequity (bse) - show assets, liabilities and equity- * cashflow (cf) - show changes in liquid assets- * incomestatement (is) - show revenues and expenses---File: hledger.info, Node: REPORTS VERSATILE, Next: REPORTS BASIC, Prev: REPORTS FINANCIAL, Up: Commands overview--24.1.5 REPORTS, VERSATILE---------------------------- * balance (bal) - show balance changes, end balances, budgets,- gains..- * print - show transactions or export journal data- * register (reg) - show postings in one or more accounts & running- total- * roi - show return on investments---File: hledger.info, Node: REPORTS BASIC, Next: HELP, Prev: REPORTS VERSATILE, Up: Commands overview--24.1.6 REPORTS, BASIC------------------------ * accounts - show account names- * activity - show bar charts of posting counts per period- * codes - show transaction codes- * commodities - show commodity/currency symbols- * descriptions - show transaction descriptions- * files - show input file paths- * notes - show note parts of transaction descriptions- * payees - show payee parts of transaction descriptions- * prices - show market prices- * stats - show journal statistics- * tags - show tag names- * test - run self tests---File: hledger.info, Node: HELP, Next: ADD-ONS, Prev: REPORTS BASIC, Up: Commands overview--24.1.7 HELP-------------- * help - show the hledger manual with info/man/pager- * demo - show small hledger demos in the terminal---File: hledger.info, Node: ADD-ONS, Prev: HELP, Up: Commands overview--24.1.8 ADD-ONS-----------------And here are some typical add-on commands. Some of these are installed-by the hledger-install script. If installed, they will appear in-hledger's commands list:-- * ui - run hledger's terminal UI- * web - run hledger's web UI- * iadd - add transactions using a TUI (currently hard to build)- * interest - generate interest transactions- * stockquotes - download market prices from AlphaVantage- * Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,- pijul, plot, and more..-- Next, each command is described in detail, in alphabetical order.---File: hledger.info, Node: accounts, Next: activity, Prev: Commands overview, Up: PART 4 COMMANDS--24.2 accounts-=============--Show account names.-- This command lists account names. By default it shows all known-accounts, either used in transactions or declared with account-directives.-- With query arguments, only matched account names and account names-referenced by matched postings are shown.-- Or it can show just the used accounts ('--used'/'-u'), the declared-accounts ('--declared'/'-d'), the accounts declared but not used-('--unused'), the accounts used but not declared ('--undeclared'), or-the first account matched by an account name pattern, if any ('--find').-- It shows a flat list by default. With '--tree', it uses indentation-to show the account hierarchy. In flat mode you can add '--drop N' to-omit the first few account name components. Account names can be-depth-clipped with 'depth:N' or '--depth N' or '-N'.-- With '--types', it also shows each account's type, if it's known.-(See Declaring accounts > Account types.)-- With '--positions', it also shows the file and line number of each-account's declaration, if any, and the account's overall declaration-order; these may be useful when troubleshooting account display order.-- With '--directives', it adds the 'account' keyword, showing valid-account directives which can be pasted into a journal file. This is-useful together with '--undeclared' when updating your account-declarations to satisfy 'hledger check accounts'.-- The '--find' flag can be used to look up a single account name, in-the same way that the 'aregister' command does. It returns the-alphanumerically-first matched account name, or if none can be found, it-fails with a non-zero exit code.-- Examples:--$ hledger accounts-assets:bank:checking-assets:bank:saving-assets:cash-expenses:food-expenses:supplies-income:gifts-income:salary-liabilities:debts--$ hledger accounts --undeclared --directives >> $LEDGER_FILE-$ hledger check accounts---File: hledger.info, Node: activity, Next: add, Prev: accounts, Up: PART 4 COMMANDS--24.3 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 **---File: hledger.info, Node: add, Next: aregister, Prev: activity, Up: PART 4 COMMANDS--24.4 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-transactions, and appends them to the main journal file (which should be-in journal format). Existing transactions are not changed. This is one-of the few hledger commands that writes to the journal file (see also-'import').-- To use it, just run 'hledger add' and follow the prompts. You can-add as many transactions as you like; when you are finished, enter '.'-or press control-d or control-c to exit.-- Features:-- * add tries to provide useful defaults, using the most similar (by- description) recent transaction (filtered by the query, if any) as- a template.- * You can also set the initial defaults with command line arguments.- * Readline-style edit keys can be used during data entry.- * The tab key will auto-complete whenever possible - accounts,- payees/descriptions, dates ('yesterday', 'today', 'tomorrow'). If- the input area is empty, it will insert the default value.- * If the journal defines a default commodity, it will be added to any- bare numbers entered.- * A parenthesised transaction code may be entered following a date.- * Comments and tags may be entered following a description or amount.- * If you make a mistake, enter '<' at any prompt to go one step- backward.- * Input prompts are displayed in a different colour when the terminal- supports it.-- Example (see https://hledger.org/add.html for a detailed tutorial):--$ 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> $-- If you enter a number with no commodity symbol, and you have declared-a default commodity with a 'D' directive, you might expect 'add' to add-this symbol for you. It does not do this; we assume that if you are-using a 'D' directive you prefer not to see the commodity symbol-repeated on amounts in the journal.---File: hledger.info, Node: aregister, Next: balance, Prev: add, Up: PART 4 COMMANDS--24.5 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 'aregister' 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.-- When there are multiple matches, the alphabetically-first choice can-be surprising; eg if you have 'assets:per:checking 1' and-'assets:biz:checking 2' accounts, 'hledger areg checking' would select-'assets:biz:checking 2'. It's just a convenience to save typing, so if-in doubt, write the full account name, or a distinctive substring that-matches uniquely.-- 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. 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, see below)- * the names of all the other account(s) involved in this transaction- (probably abbreviated)- * the total change to this account's balance from this transaction- * 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.-- For performance reasons, column widths are chosen based on the first-1000 lines; this means unusually wide values in later lines can cause-visual discontinuities as column widths are adjusted. If you want to-ensure perfect alignment, at the cost of more time and memory, use the-'--align-all' flag.-- This command also supports the output destination and output format-options. The output formats supported are 'txt', 'csv', 'tsv' (_Added-in 1.32_), and 'json'.--* Menu:--* aregister and posting dates::---File: hledger.info, Node: aregister and posting dates, Up: aregister--24.5.1 aregister and posting dates-------------------------------------aregister always shows one line (and date and amount) per transaction.-But sometimes transactions have postings with different dates. Also,-not all of a transaction's postings may be within the report period. To-resolve this, aregister shows the earliest of the transaction's date and-posting dates that is in-period, and the sum of the in-period postings.-In other words it will show a combined line item with just the earliest-date, and the running balance will (temporarily, until the transaction's-last posting) be inaccurate. Use 'register -H' if you need to see the-individual postings.-- There is also a '--txn-dates' flag, which filters strictly by-transaction date, ignoring posting dates. This too can cause an-inaccurate running balance.---File: hledger.info, Node: balance, Next: balancesheet, Prev: aregister, Up: PART 4 COMMANDS--24.6 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',-'balancesheetequity', 'cashflow' and 'incomestatement'. When you need-more control, then use 'balance'.--* Menu:--* balance features::-* Simple balance report::-* Balance report line format::-* Filtered balance report::-* List or tree mode::-* Depth limiting::-* Dropping top-level accounts::-* Showing declared accounts::-* Sorting by amount::-* Percentages::-* Multi-period balance report::-* Balance change end balance::-* Balance report types::-* Budget report::-* Balance report layout::-* Some useful balance reports::---File: hledger.info, Node: balance features, Next: Simple balance report, Up: balance--24.6.1 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..-- * accounts as a list ('-l') or a tree ('-t')- * optionally depth-limited ('-[1-9]')- * sorted by declaration order and name, or by amount-- ..and their..-- * balance changes (the default)- * or actual and planned balance changes ('--budget')- * or value of balance changes ('-V')- * or change of balance values ('--valuechange')- * or unrealised capital gain/loss ('--gain')- * or balance changes from sibling postings ('--related'/'-r')- * or postings count ('--count')-- ..in..-- * one time period (the whole journal period by default)- * or multiple periods ('-D', '-W', '-M', '-Q', '-Y', '-p INTERVAL')-- ..either..-- * per period (the default)- * or accumulated since report start date ('--cumulative')- * or accumulated since account creation ('--historical/-H')-- ..possibly converted to..-- * cost ('--value=cost[,COMM]'/'--cost'/'-B')- * or market value, as of transaction dates ('--value=then[,COMM]')- * or at period ends ('--value=end[,COMM]')- * or now ('--value=now')- * or at some other date ('--value=YYYY-MM-DD')-- ..with..-- * totals ('-T'), averages ('-A'), percentages ('-%'), inverted sign- ('--invert')- * rows and columns swapped ('--transpose')- * another field used as account name ('--pivot')- * custom-formatted line items (single-period reports only)- ('--format')- * commodities displayed on the same line or multiple lines- ('--layout')-- This command supports the output destination and output format-options, with output formats 'txt', 'csv', 'tsv' (_Added in 1.32_),-'json', and (multi-period reports only:) 'html'. In 'txt' output in a-colour-supporting terminal, negative amounts are shown in red.---File: hledger.info, Node: Simple balance report, Next: Balance report line format, Prev: balance features, Up: balance--24.6.2 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. ("Simple" here-means just one column of numbers, covering a single period. You can-also have multi-period reports, described later.)-- For real-world accounts, these numbers will normally be their end-balance at the end of the journal period; more on this below.-- Accounts are sorted by declaration order if any, and then-alphabetically by account name. For instance (using-examples/sample.journal):--$ hledger -f examples/sample.journal bal- $1 assets:bank:saving- $-2 assets:cash- $1 expenses:food- $1 expenses:supplies- $-1 income:gifts- $-1 income:salary- $1 liabilities:debts---------------------- 0 -- 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.---File: hledger.info, Node: Balance report line format, Next: Filtered balance report, Prev: Simple balance report, Up: balance--24.6.3 Balance report line format------------------------------------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 -f examples/sample.journal 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 specifies the formatting applied to each-account/balance pair. It may contain any suitable text, with data-fields interpolated like so:-- '%[MIN][.MAX](FIELDNAME)'-- * MIN pads with spaces to at least this width (optional)-- * MAX truncates at this width (optional)-- * FIELDNAME must be enclosed in parentheses, and can be one of:-- * 'depth_spacer' - a number of spaces equal to the account's- depth, or if MIN is specified, MIN * depth spaces.- * 'account' - the account's name- * 'total' - the account's balance/posted total, right justified-- Also, FMT can begin with an optional prefix to control how-multi-commodity amounts are rendered:-- * '%_' - render on multiple lines, bottom-aligned (the default)- * '%^' - render on multiple lines, top-aligned- * '%,' - 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:-- * '%(total)' - the account's total- * '%-20.20(account)' - the account's name, left justified, padded to- 20 characters and clipped at 20 characters- * '%,%-50(account) %25(total)' - account name padded to 50- characters, total padded to 20 characters, with multiple- commodities rendered on one line- * '%20(total) %2(depth_spacer)%-(account)' - the default format for- the single-column balance report---File: hledger.info, Node: Filtered balance report, Next: List or tree mode, Prev: Balance report line format, Up: balance--24.6.4 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 -f examples/sample.journal bal --cleared assets date:200806- $-2 assets:cash---------------------- $-2 ---File: hledger.info, Node: List or tree mode, Next: Depth limiting, Prev: Filtered balance report, Up: balance--24.6.5 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 -f examples/sample.journal balance- $-1 assets- $1 bank:saving- $-2 cash- $2 expenses- $1 food- $1 supplies- $-2 income- $-1 gifts- $-1 salary- $1 liabilities:debts---------------------- 0-- Notes:-- * "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).-- * 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-plaintextaccounting-users. A tree mode report's final total is- the sum of the top-level balances shown, not of all the balances- shown.-- * Each group of sibling accounts (ie, under a common parent) is- sorted separately.---File: hledger.info, Node: Depth limiting, Next: Dropping top-level accounts, Prev: List or tree mode, Up: balance--24.6.6 Depth limiting------------------------With a 'depth:NUM' query, or '--depth NUM' option, or just '-NUM' (eg:-'-3') balance reports will show accounts only to the specified depth,-hiding the deeper subaccounts. This can be useful for getting an-overview without too much detail.-- Account balances at the depth limit always include the balances from-any deeper subaccounts (even in list mode). Eg, limiting to depth 1:--$ hledger -f examples/sample.journal balance -1- $-1 assets- $2 expenses- $-2 income- $1 liabilities---------------------- 0 ---File: hledger.info, Node: Dropping top-level accounts, Next: Showing declared accounts, Prev: Depth limiting, Up: balance--24.6.7 Dropping top-level accounts-------------------------------------You can also hide one or more top-level account name parts, using-'--drop NUM'. This can be useful for hiding repetitive top-level-account names:--$ hledger -f examples/sample.journal bal expenses --drop 1- $1 food- $1 supplies---------------------- $2 ---File: hledger.info, Node: Showing declared accounts, Next: Sorting by amount, Prev: Dropping top-level accounts, Up: balance--24.6.8 Showing declared accounts-----------------------------------With '--declared', accounts which have been declared with an account-directive will be included in the balance report, even if they have no-transactions. (Since they will have a zero balance, you will also need-'-E/--empty' to see them.)-- More precisely, _leaf_ declared accounts (with no subaccounts) will-be included, since those are usually the more useful in reports.-- The idea of this is to be able to see a useful "complete" balance-report, even when you don't have transactions in all of your declared-accounts yet.---File: hledger.info, Node: Sorting by amount, Next: Percentages, Prev: Showing declared accounts, Up: balance--24.6.9 Sorting by amount---------------------------With '-S/--sort-amount', accounts with the largest (most positive)-balances are shown first. Eg: 'hledger bal expenses -MAS' shows your-biggest averaged monthly expenses first. When more than one commodity-is present, they will be sorted by the alphabetically earliest commodity-first, and then by subsequent commodities (if an amount is missing a-commodity, it is treated as 0).-- Revenues and liability balances are typically negative, however, so-'-S' shows these in reverse order. To work around this, you can add-'--invert' to flip the signs. (Or, use one of the higher-level reports,-which flip the sign automatically. Eg: 'hledger incomestatement -MAS').---File: hledger.info, Node: Percentages, Next: Multi-period balance report, Prev: Sorting by amount, Up: balance--24.6.10 Percentages----------------------With '-%/--percent', balance reports show each account's value expressed-as a percentage of the (column) total.-- Note it is not useful to calculate percentages if the amounts in a-column 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:€---File: hledger.info, Node: Multi-period balance report, Next: Balance change end balance, Prev: Percentages, Up: balance--24.6.11 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),-'balance' shows a tabular report, with columns representing successive-time periods (and a title):--$ hledger -f examples/sample.journal bal --quarterly income expenses -E-Balance changes in 2008:-- || 2008q1 2008q2 2008q3 2008q4 -===================++=================================- expenses:food || 0 $1 0 0 - expenses:supplies || 0 $1 0 0 - income:gifts || 0 $-1 0 0 - income:salary || $-1 0 0 0 --------------------++---------------------------------- || $-1 $1 0 0 -- Notes:-- * The report's start/end dates will be expanded, if necessary, to- fully encompass the displayed subperiods (so that the first and- last subperiods have the same duration as the others).- * Leading and trailing periods (columns) containing all zeroes are- not shown, unless '-E/--empty' is used.- * Accounts (rows) containing all zeroes are not shown, unless- '-E/--empty' is used.- * Amounts with many commodities are shown in abbreviated form, unless- '--no-elide' is used.- * Average and/or total columns can be added with the '-A/--average'- and '-T/--row-total' flags.- * The '--transpose' flag can be used to exchange rows and columns.- * 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:-- * Hide the totals row with '-N/--no-total'- * Filter to a single currency with 'cur:'- * Convert to a single currency with '-V [--infer-market-price]'- * Use a more compact layout like '--layout=bare'- * Maximize the terminal window- * Reduce the terminal's font size- * View with a pager like less, eg: 'hledger bal -D --color=yes | less- -RS'- * 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')- * Output as HTML and view with a browser: 'hledger bal -D -o a.html- && open a.html'---File: hledger.info, Node: Balance change end balance, Next: Balance report types, Prev: Multi-period balance report, Up: balance--24.6.12 Balance change, end balance--------------------------------------It's important to be clear on the meaning of the numbers shown in-balance 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 postings.)---File: hledger.info, Node: Balance report types, Next: Budget report, Prev: Balance change end balance, Up: balance--24.6.13 Balance report types-------------------------------The balance command is quite flexible; here is the full detail on how to-control what it reports. If the following seems complicated, don't-worry - this is for advanced reporting, and it does take time and-experimentation to get familiar with all the report modes.-- There are three important option groups:-- 'hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]-...'--* Menu:--* Calculation type::-* Accumulation type::-* Valuation type::-* Combining balance report types::---File: hledger.info, Node: Calculation type, Next: Accumulation type, Up: Balance report types--24.6.13.1 Calculation type-..........................--The basic calculation to perform for each table cell. It is one of:-- * '--sum' : sum the posting amounts (*default*)- * '--budget' : sum the amounts, but also show the budget goal amount- (for each account/period)- * '--valuechange' : show the change in period-end historical balance- values (caused by deposits, withdrawals, and/or market price- fluctuations)- * '--gain' : show the unrealised capital gain/loss, (the current- valued balance minus each amount's original cost)- * '--count' : show the count of postings---File: hledger.info, Node: Accumulation type, Next: Valuation type, Prev: Calculation type, Up: Balance report types--24.6.13.2 Accumulation type-...........................--How amounts should accumulate across a report's subperiods/columns.-Another way to say it: which time period's postings should contribute to-each cell's calculation. It is one of:-- * '--change' : calculate with postings from column start to column- end, ie "just this column". Typically used to see- revenues/expenses. (*default for balance, cashflow,- incomestatement*)-- * '--cumulative' : calculate with postings from report start to- column end, ie "previous columns plus this column". Typically used- to show changes accumulated since the report's start date. Not- often used.-- * '--historical/-H' : calculate with postings from journal start to- column end, ie "all postings from before report start date until- this column's end". Typically used to see historical end balances- of assets/liabilities/equity. (*default for balancesheet,- balancesheetequity*)---File: hledger.info, Node: Valuation type, Next: Combining balance report types, Prev: Accumulation type, Up: Balance report types--24.6.13.3 Valuation type-........................--Which kind of value or cost conversion should be applied, if any, before-displaying the report. It is one of:-- * no valuation type : don't convert to cost or value (*default*)- * '--value=cost[,COMM]' : convert amounts to cost (then optionally to- some other commodity)- * '--value=then[,COMM]' : convert amounts to market value on- transaction dates- * '--value=end[,COMM]' : convert amounts to market value on period- end date(s)- (*default with '--valuechange', '--gain'*)- * '--value=now[,COMM]' : convert amounts to market value on today's- date- * '--value=YYYY-MM-DD[,COMM]' : convert amounts to market value on- another date-- or one of the equivalent simpler flags:-- * '-B/--cost' : like -value=cost (though, note -cost and -value are- independent options which can both be used at once)- * '-V/--market' : like -value=end- * '-X COMM/--exchange COMM' : like -value=end,COMM-- See Cost reporting and Value reporting for more about these.---File: hledger.info, Node: Combining balance report types, Prev: Valuation type, Up: Balance report types--24.6.13.4 Combining balance report types-........................................--Most combinations of these options should produce reasonable reports,-but if you find any that seem wrong or misleading, let us know. The-following restrictions are applied:-- * '--valuechange' implies '--value=end'- * '--valuechange' makes '--change' the default when used with the- 'balancesheet'/'balancesheetequity' commands- * '--cumulative' or '--historical' disables '--row-total/-T'-- For reference, here is what the combinations of accumulation and-valuation show:--Valuation:>no valuation '--value= then' '--value= end' '--value=-Accumulation:v YYYY-MM-DD- /now'-------------------------------------------------------------------------------'--change'change in sum of period-end DATE-value- period posting-date value of of change in- market values change in period- in period period-'--cumulative'change from sum of period-end DATE-value- report start to posting-date value of of change- period end market values change from from report- from report report start start to- start to period to period end period end- end-'--historicalchange from sum of period-end DATE-value-/-H' journal start posting-date value of of change- to period end market values change from from journal- (historical end from journal journal start start to- balance) start to period to period end period end- end---File: hledger.info, Node: Budget report, Next: Balance report layout, Prev: Balance report types, Up: balance--24.6.14 Budget report------------------------The '--budget' report type is like a regular balance report, but with-two main differences:-- * Budget goals and performance percentages are also shown, in- brackets- * Accounts which don't have budget goals are hidden by default.-- This is useful for comparing planned and actual income, expenses,-time usage, etc.-- Periodic transaction rules are used to define budget goals. For-example, here's a periodic rule defining monthly goals for bus travel-and food expenses:--;; Budget-~ monthly- (expenses:bus) $30- (expenses:food) $400-- After recording some actual expenses,--;; Two months worth of expenses-2017-11-01- income $-1950- expenses:bus $35- expenses:food:groceries $310- expenses:food:dining $42- expenses:movies $38- assets:bank:checking--2017-12-01- income $-2100- expenses:bus $53- expenses:food:groceries $380- expenses:food:dining $32- expenses:gifts $100- assets:bank:checking-- we can see a budget report like this:--$ hledger bal -M --budget-Budget performance in 2017-11-01..2017-12-31:-- || Nov Dec -===============++============================================- <unbudgeted> || $-425 $-565 - expenses || $425 [ 99% of $430] $565 [131% of $430] - expenses:bus || $35 [117% of $30] $53 [177% of $30] - expenses:food || $352 [ 88% of $400] $412 [103% of $400] ----------------++--------------------------------------------- || 0 [ 0% of $430] 0 [ 0% of $430] -- This is "goal-based budgeting"; you define goals for accounts and-periods, often recurring, and hledger shows performance relative to the-goals. This contrasts with "envelope budgeting", which is more detailed-and strict - useful when cash is tight, but also quite a bit more work.-https://plaintextaccounting.org/Budgeting has more on this topic.--* Menu:--* Using the budget report::-* Budget date surprises::-* Selecting budget goals::-* Budgeting vs forecasting::---File: hledger.info, Node: Using the budget report, Next: Budget date surprises, Up: Budget report--24.6.14.1 Using the budget report-.................................--Historically this report has been confusing and fragile. hledger's-version should be relatively robust and intuitive, but you may still-find surprises. Here are more notes to help with learning and-troubleshooting.-- * In the above example, 'expenses:bus' and 'expenses:food' are shown- because they have budget goals during the report period.-- * Their parent 'expenses' is also shown, with budget goals aggregated- from the children.-- * The subaccounts 'expenses:food:groceries' and- 'expenses:food:dining' are not shown since they have no budget goal- of their own, but they contribute to 'expenses:food''s actual- amount.-- * Unbudgeted accounts 'expenses:movies' and 'expenses:gifts' are also- not shown, but they contribute to 'expenses''s actual amount.-- * The other unbudgeted accounts 'income' and 'assets:bank:checking'- are grouped as '<unbudgeted>'.-- * '--depth' or 'depth:' can be used to limit report depth in the- usual way (but will not reveal unbudgeted subaccounts).-- * Amounts are always inclusive of subaccounts (even in '-l/--list'- mode).-- * Numbers displayed in a -budget report will not always agree with- the totals, because of hidden unbudgeted accounts; this is normal.- '-E/--empty' can be used to reveal the hidden accounts.-- * In the periodic rules used for setting budget goals, unbalanced- postings are convenient.-- * You can filter budget reports with the usual queries, eg to focus- on particular accounts. It's common to restrict them to just- expenses. (The '<unbudgeted>' account is occasionally hard to- exclude; this is because of date surprises, discussed below.)-- * When you have multiple currencies, you may want to convert them to- one ('-X COMM --infer-market-prices') and/or show just one at a- time ('cur:COMM'). If you do need to show multiple currencies at- once, '--layout bare' can be helpful.-- * You can "roll over" amounts (actual and budgeted) to the next- period with '--cumulative'.-- See also: https://hledger.org/budgeting.html.---File: hledger.info, Node: Budget date surprises, Next: Selecting budget goals, Prev: Using the budget report, Up: Budget report--24.6.14.2 Budget date surprises-...............................--With small data, or when starting out, some of the generated budget goal-transaction dates might fall outside the report periods. Eg with the-following journal and report, the first period appears to have no-'expenses:food' budget. (Also the '<unbudgeted>' account should be-excluded by the 'expenses' query, but isn't.):--~ monthly in 2020- (expenses:food) $500--2020-01-15- expenses:food $400- assets:checking--$ hledger bal --budget expenses-Budget performance in 2020-01-15:-- || 2020-01-15 -===============++====================- <unbudgeted> || $400 - expenses:food || 0 [ 0% of $500] ----------------++--------------------- || $400 [80% of $500] -- In this case, the budget goal transactions are generated on first-days of of month (this can be seen with 'hledger print --forecast-tag:generated expenses'). Whereas the report period defaults to just-the 15th day of january (this can be seen from the report table's column-headings).-- To fix this kind of thing, be more explicit about the report period-(and/or the periodic rules' dates). In this case, adding '-b 2020' does-the trick.---File: hledger.info, Node: Selecting budget goals, Next: Budgeting vs forecasting, Prev: Budget date surprises, Up: Budget report--24.6.14.3 Selecting budget goals-................................--By default, the budget report uses all available periodic transaction-rules to generate goals. This includes rules with a different report-interval from your report. Eg if you have daily, weekly and monthly-periodic rules, all of these will contribute to the goals in a monthly-budget report.-- You can select a subset of periodic rules by providing an argument to-the '--budget' flag. '--budget=DESCPAT' will match all periodic rules-whose description contains DESCPAT, a case-insensitive substring (not a-regular expression or query). This means you can give your periodic-rules descriptions (remember that two spaces are needed between period-expression and description), and then select from multiple budgets-defined in your journal.---File: hledger.info, Node: Budgeting vs forecasting, Prev: Selecting budget goals, Up: Budget report--24.6.14.4 Budgeting vs forecasting-..................................--'--forecast' and '--budget' both use the periodic transaction rules in-the journal to generate temporary transactions for reporting purposes.-However they are separate features - though you can use both at the same-time if you want. Here are some differences between them:---forecast -budget----------------------------------------------------------------------------is a general option; it enables is a balance command option;-forecasting with all reports it selects the balance- report's budget mode-generates visible transactions which generates invisible-appear in reports transactions which produce- goal amounts-generates forecast transactions from generates budget goal-after the last regular transaction, to transactions throughout the-the end of the report period; or with report period, optionally-an argument '--forecast=PERIODEXPR' restricted by periods-generates them throughout the specified in the periodic-specified period, both optionally transaction rules-restricted by periods specified in the-periodic transaction rules-uses all periodic rules uses all periodic rules; or- with an argument- '--budget=DESCPAT' uses just- the rules matched by DESCPAT---File: hledger.info, Node: Balance report layout, Next: Some useful balance reports, Prev: Budget report, Up: balance--24.6.15 Balance report layout--------------------------------The '--layout' option affects how balance reports show multi-commodity-amounts and commodity symbols, which can improve readability. It can-also normalise the data for easy consumption by other programs. It has-four possible values:-- * '--layout=wide[,WIDTH]': commodities are shown on a single line,- optionally elided to WIDTH- * '--layout=tall': each commodity is shown on a separate line- * '--layout=bare': commodity symbols are in their own column, amounts- are bare numbers- * '--layout=tidy': data is normalised to easily-consumed "tidy" form,- with one row per data value-- Here are the '--layout' modes supported by each output format Only-CSV output supports all of them:--- txt csv html json sql-----------------------------------------wide Y Y Y-tall Y Y Y-bare Y Y Y-tidy Y-- Examples:--* Menu:--* Wide layout::-* Tall layout::-* Bare layout::-* Tidy layout::---File: hledger.info, Node: Wide layout, Next: Tall layout, Up: Balance report layout--24.6.15.1 Wide layout-.....................--With many commodities, reports can be very wide:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide-Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total -==================++====================================================================================================================================================================================================================- Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT -------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT -- A width limit reduces the width, but some commodities will be hidden:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32-Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total -==================++===========================================================================================================================- Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. -------------------++---------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. ---File: hledger.info, Node: Tall layout, Next: Bare layout, Prev: Wide layout, Up: Balance report layout--24.6.15.2 Tall layout-.....................--Each commodity gets a new line (may be different in each column), and-account names are repeated:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall-Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total -==================++==================================================- Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD - Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT - Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD - Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA - Assets:US:ETrade || 18.00 VHT 294.00 VHT -------------------++--------------------------------------------------- || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD - || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT - || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD - || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA - || 18.00 VHT 294.00 VHT ---File: hledger.info, Node: Bare layout, Next: Tidy layout, Prev: Tall layout, Up: Balance report layout--24.6.15.3 Bare layout-.....................--Commodity symbols are kept in one column, each commodity has its own-row, amounts are bare numbers, account names are repeated:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare-Balance changes in 2012-01-01..2014-12-31:-- || Commodity 2012 2013 2014 Total -==================++=============================================- Assets:US:ETrade || GLD 0 70.00 0 70.00 - Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00 - Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50 - Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00 - Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00 -------------------++---------------------------------------------- || GLD 0 70.00 0 70.00 - || ITOT 10.00 18.00 -11.00 17.00 - || USD 337.18 -98.12 4881.44 5120.50 - || VEA 12.00 10.00 14.00 36.00 - || VHT 106.00 18.00 170.00 294.00 -- Bare layout also affects CSV output, which is useful for producing-data that is easier to consume, eg for making charts:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare-"account","commodity","balance"-"Assets:US:ETrade","GLD","70.00"-"Assets:US:ETrade","ITOT","17.00"-"Assets:US:ETrade","USD","5120.50"-"Assets:US:ETrade","VEA","36.00"-"Assets:US:ETrade","VHT","294.00"-"total","GLD","70.00"-"total","ITOT","17.00"-"total","USD","5120.50"-"total","VEA","36.00"-"total","VHT","294.00"-- Bare layout will sometimes display an extra row for the no-symbol-commodity, because of zero amounts (hledger treats zeroes as-commodity-less, usually). This can break 'hledger-bar' confusingly-(workaround: add a 'cur:' query to exclude the no-symbol row).---File: hledger.info, Node: Tidy layout, Prev: Bare layout, Up: Balance report layout--24.6.15.4 Tidy layout-.....................--This produces normalised "tidy data" (see-https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)-where every variable has its own column and each row represents a single-data point. This is the easiest kind of data for other software to-consume:--$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy-"account","period","start_date","end_date","commodity","value"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","GLD","0"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","ITOT","10.00"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","USD","337.18"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","VEA","12.00"-"Assets:US:ETrade","2012","2012-01-01","2012-12-31","VHT","106.00"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","GLD","70.00"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","ITOT","18.00"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","USD","-98.12"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","VEA","10.00"-"Assets:US:ETrade","2013","2013-01-01","2013-12-31","VHT","18.00"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","GLD","0"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","ITOT","-11.00"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","USD","4881.44"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","VEA","14.00"-"Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"---File: hledger.info, Node: Some useful balance reports, Prev: Balance report layout, Up: balance--24.6.16 Some useful balance reports--------------------------------------Some frequently used 'balance' options/reports are:-- * 'bal -M revenues expenses'- Show revenues/expenses in each month. Also available as the- 'incomestatement' command.-- * 'bal -M -H assets liabilities'- Show historical asset/liability balances at each month end. Also- available as the 'balancesheet' command.-- * 'bal -M -H assets liabilities equity'- Show historical asset/liability/equity balances at each month end.- Also available as the 'balancesheetequity' command.-- * 'bal -M assets not:receivable'- Show changes to liquid assets in each month. Also available as the- 'cashflow' command.-- Also:-- * 'bal -M expenses -2 -SA'- Show monthly expenses summarised to depth 2 and sorted by average- amount.-- * 'bal -M --budget expenses'- Show monthly expenses and budget goals.-- * 'bal -M --valuechange investments'- Show monthly change in market value of investment assets.-- * 'bal investments --valuechange -D date:lastweek amt:'>1000' -STA- [--invert]'- Show top gainers [or losers] last week---File: hledger.info, Node: balancesheet, Next: balancesheetequity, Prev: balance, Up: PART 4 COMMANDS--24.7 balancesheet-=================--(bs)-- This command displays a balance sheet, showing historical ending-balances of asset and liability accounts. (To see equity as well, use-the balancesheetequity command.) Amounts are shown with normal positive-sign, as in conventional financial statements.-- This report shows accounts declared with the 'Asset', 'Cash' or-'Liability' type (see account types). Or if no such accounts are-declared, it shows top-level accounts named 'asset' or 'liability' (case-insensitive, plurals allowed) and their subaccounts.-- Example:--$ hledger balancesheet-Balance Sheet 2008-12-31-- || 2008-12-31 -====================++============- Assets || ---------------------++------------- assets:bank:saving || $1 - assets:cash || $-2 ---------------------++------------- || $-1 -====================++============- Liabilities || ---------------------++------------- liabilities:debts || $-1 ---------------------++------------- || $-1 -====================++============- Net: || 0 -- This command is a higher-level variant of the 'balance' command, and-supports 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', 'tsv' (_Added in-1.32_), 'html', and 'json'.---File: hledger.info, Node: balancesheetequity, Next: cashflow, Prev: balancesheet, Up: PART 4 COMMANDS--24.8 balancesheetequity-=======================--(bse)-- This command displays a balance sheet, showing historical ending-balances of asset, liability and equity accounts. Amounts are shown-with normal positive sign, as in conventional financial statements.-- This report shows accounts declared with the 'Asset', 'Cash',-'Liability' or 'Equity' type (see account types). Or if no such-accounts are declared, it shows top-level accounts named 'asset',-'liability' or 'equity' (case insensitive, plurals allowed) and their-subaccounts.-- Example:--$ hledger balancesheetequity-Balance Sheet With Equity 2008-12-31-- || 2008-12-31 -====================++============- Assets || ---------------------++------------- assets:bank:saving || $1 - assets:cash || $-2 ---------------------++------------- || $-1 -====================++============- Liabilities || ---------------------++------------- liabilities:debts || $-1 ---------------------++------------- || $-1 -====================++============- Equity || ---------------------++---------------------------------++------------- || 0 -====================++============- Net: || 0 -- This command is a higher-level variant of the 'balance' command, and-supports 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 report is the easiest way to see if the accounting equation-(A+L+E = 0) is satisfied (after you have done a 'close --retain' to-merge revenues and expenses with equity, and perhaps added-'--infer-equity' to balance your commodity conversions).-- This command also supports the output destination and output format-options The output formats supported are 'txt', 'csv', 'tsv', 'html',-and 'json'.---File: hledger.info, Node: cashflow, Next: check, Prev: balancesheetequity, Up: PART 4 COMMANDS--24.9 cashflow-=============--(cf)-- This command displays a (simple) cashflow statement, showing the-inflows and outflows affecting "cash" (ie, liquid, easily convertible)-assets. Amounts are shown with normal positive sign, as in conventional-financial statements.-- This report shows accounts declared with the 'Cash' type (see account-types). Or if no such accounts are declared, it shows accounts-- * under a top-level account named 'asset' (case insensitive, plural- allowed)- * whose name contains some variation of 'cash', 'bank', 'checking' or- 'saving'.-- More precisely: all accounts matching this case insensitive regular-expression:-- '^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)'-- and their subaccounts.-- An example cashflow report:--$ hledger cashflow-Cashflow Statement 2008-- || 2008 -====================++======- Cash flows || ---------------------++------- assets:bank:saving || $1 - assets:cash || $-2 ---------------------++------- || $-1 -- This command is a higher-level variant of the 'balance' command, and-supports 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', 'tsv' (_Added in-1.32_), 'html', and 'json'.---File: hledger.info, Node: check, Next: close, Prev: cashflow, Up: PART 4 COMMANDS--24.10 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-- If you are an Emacs user, you can also configure flycheck-hledger to-run these checks, providing instant feedback as you edit the journal.-- Here are the checks currently available:--* Menu:--* Default checks::-* Strict checks::-* Other checks::-* Custom checks::-* More about specific checks::---File: hledger.info, Node: Default checks, Next: Strict checks, Up: check--24.10.1 Default checks-------------------------These checks are run automatically by (almost) all hledger commands:-- * *parseable* - data files are in a supported format, with no syntax- errors and no invalid include directives.-- * *autobalanced* - all transactions are balanced, after converting to- cost. Missing amounts and missing costs are inferred automatically- where possible.-- * *assertions* - all balance assertions in the journal are passing.- (This check can be disabled with '-I'/'--ignore-assertions'.)---File: hledger.info, Node: Strict checks, Next: Other checks, Prev: Default checks, Up: check--24.10.2 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':-- * *balanced* - all transactions are balanced after converting to- cost, without inferring missing costs. If conversion costs are- required, they must be explicit.-- * *accounts* - all account names used by transactions have been- declared-- * *commodities* - all commodity symbols used have been declared---File: hledger.info, Node: Other checks, Next: Custom checks, Prev: Strict checks, Up: check--24.10.3 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:-- * *ordereddates* - transactions are ordered by date within each file-- * *payees* - all payees used by transactions have been declared-- * *recentassertions* - all accounts with balance assertions have a- balance assertion within 7 days of their latest posting-- * *tags* - all tags used by transactions have been declared-- * *uniqueleafnames* - all account leaf names are unique---File: hledger.info, Node: Custom checks, Next: More about specific checks, Prev: Other checks, Up: check--24.10.4 Custom checks------------------------A few more checks are are available as separate add-on commands, in-https://github.com/simonmichael/hledger/tree/master/bin:-- * *hledger-check-tagfiles* - all tag values containing / (a forward- slash) exist as file paths-- * *hledger-check-fancyassertions* - more complex balance assertions- are passing-- You could make similar scripts to perform your own custom checks.-See: Cookbook -> Scripting.---File: hledger.info, Node: More about specific checks, Prev: Custom checks, Up: check--24.10.5 More about specific checks-------------------------------------'hledger check recentassertions' will complain if any balance-asserted-account has postings more than 7 days after its latest balance-assertion. This aims to prevent the situation where you are regularly-updating your journal, but forgetting to check your balances against the-real world, then one day must dig back through months of data to find an-error. It assumes that adding a balance assertion requires/reminds you-to check the real-world balance. (That may not be true if you-auto-generate balance assertions from bank data; in that case, I-recommend to import transactions uncleared, and when you manually review-and clear them, also check the latest assertion against the real-world-balance.)---File: hledger.info, Node: close, Next: codes, Prev: check, Up: PART 4 COMMANDS--24.11 close-===========--(equity)-- 'close' generates several kinds of "closing" and/or "opening"-transactions, useful in certain situations, including migrating balances-to a new journal file, retaining earnings into equity, consolidating-balances, or viewing lots. Like 'print', it prints valid journal-entries. You can append or copy these to your journal file(s) when you-are happy with how they look.-- 'close' currently has six modes, selected by a single mode flag:--* Menu:--* close --migrate::-* close --close::-* close --open::-* close --assert::-* close --assign::-* close --retain::-* close customisation::-* close and balance assertions::-* close examples::---File: hledger.info, Node: close --migrate, Next: close --close, Up: close--24.11.1 close -migrate-------------------------This is the most common mode. It prints a "closing balances"-transaction that zeroes out all asset and liability balances (by-default), and an opposite "opening balances" transaction that restores-them again. The balancing account will be 'equity:opening/closing-balances' (or another specified by '--close-acct' or '--open-acct').-- This is useful when migrating balances to a new journal file at the-start of a new year. Essentially, you run 'hledger close---migrate=NEWYEAR -e NEWYEAR' and then copy the closing transaction to-the end of the old file and the opening transaction to the start of the-new file. The opening transaction sets correct starting balances in the-new file when it is used alone, and the closing transaction keeps-balances correct when you use both old and new files together, by-cancelling out the following opening transaction and preventing buildup-of duplicated opening balances. Think of the closing/opening pair as-"moving the balances into the next file".-- You can close a different set of accounts by providing a query. Eg-if you want to include equity, you can add 'assets liabilities equity'-or 'type:ALE' arguments. (The balancing account is always excluded.)-Revenues and expenses usually are not migrated to a new file directly;-see '--retain' below.-- The generated transactions will have a 'start:' tag, with its value-set to '--migrate''s 'NEW' argument if any, for easier matching or-exclusion. When 'NEW' is not specified, it will be inferred if possible-by incrementing a number (eg a year number) within the default journal's-main file name. The other modes behave similarly.---File: hledger.info, Node: close --close, Next: close --open, Prev: close --migrate, Up: close--24.11.2 close -close-----------------------This prints just the closing balances transaction of '--migrate'. It is-the default behaviour if you specify no mode flag. Using the-customisation options below, you can move balances from any set of-accounts to a different account.---File: hledger.info, Node: close --open, Next: close --assert, Prev: close --close, Up: close--24.11.3 close -open----------------------This prints just the opening balances transaction of '--migrate'. It is-similar to Ledger's equity command.---File: hledger.info, Node: close --assert, Next: close --assign, Prev: close --open, Up: close--24.11.4 close -assert------------------------This prints a "closing balances" transaction (with 'balances:' tag),-that just declares balance assertions for the current balances without-changing them. It could be useful as documention and to guard against-changes.---File: hledger.info, Node: close --assign, Next: close --retain, Prev: close --assert, Up: close--24.11.5 close -assign------------------------This prints an "opening balances" transaction that restores the account-balances using balance assignments. Balance assignments work regardless-of any previous balance, so a preceding closing balances transaction is-not needed.-- However, omitting the closing balances transaction would unbalance-equity. This is relatively harmless for personal reports, but it-disturbs the accounting equation, removing a source of error detection.-So '--migrate' is generally the best way to set to set balances in new-files, for now.---File: hledger.info, Node: close --retain, Next: close customisation, Prev: close --assign, Up: close--24.11.6 close -retain------------------------This is like '--close' with different defaults: it prints a "retain-earnings" transaction (with 'retain:' tag), that transfers revenue and-expense balances to 'equity:retained earnings'.-- This is a different kind of closing, called "retaining earnings" or-"closing the books"; it is traditionally performed by businesses at the-end of each accounting period, to consolidate revenues and expenses into-the main equity balance. ("Revenues" and "expenses" are actually equity-by another name, kept separate temporarily for reporting purposes.)-- In personal accounting you generally don't need to do this, unless-you want the 'balancesheetequity' report to show a zero total,-demonstrating that the accounting equation (A-L=E) is satisfied.---File: hledger.info, Node: close customisation, Next: close and balance assertions, Prev: close --retain, Up: close--24.11.7 close customisation------------------------------In all modes, the following things can be overridden:-- * the accounts to be closed/opened, with account query arguments- * the balancing account, with '--close-acct=ACCT' and/or- '--open-acct=ACCT'- * the transaction descriptions, with '--close-desc=DESC' and- '--open-desc=DESC'- * the transaction's tag value, with a '--MODE=NEW' option argument- * the closing/opening dates, with '-e OPENDATE'-- By default, the closing date is yesterday, or the journal's end date,-whichever is later; and the opening date is always one day after the-closing date. You can change these by specifying a report end date; the-closing date will be the last day of the report period. Eg '-e 2024'-means "close on 2023-12-31, open on 2024-01-01".-- With '--x/--explicit', the balancing amount will be shown explicitly,-and if it involves multiple commodities, a separate posting will be-generated for each of them (similar to 'print -x').-- With '--interleaved', each individual transfer is shown with source-and destination postings next to each other (perhaps useful for-troubleshooting).-- With '--show-costs', balances' costs are also shown, with different-costs kept separate. This may generate very large journal entries, if-you have many currency conversions or investment transactions. 'close---show-costs' is currently the best way to view investment lots with-hledger. (To move or dispose of lots, see the more capable-'hledger-move' script.)---File: hledger.info, Node: close and balance assertions, Next: close examples, Prev: close customisation, Up: close--24.11.8 close and balance assertions---------------------------------------'close' adds balance assertions verifying that the accounts have been-reset to zero in a closing transaction or restored to their previous-balances in an opening transaction. These provide useful error-checking, but you can ignore them temporarily with '-I', or remove them-if you prefer.-- Single-commodity, subaccount-exclusive balance assertions ('=') are-generated by default. This can be changed with '--assertion-type='==*''-(eg).-- When running 'close' you should probably avoid using '-C', '-R',-'status:' (filtering by status or realness) or '--auto' (generating-postings), since the generated balance assertions would then require-these.-- Transactions with multiple dates (eg posting dates) spanning the file-boundary also can disrupt the balance assertions:--2023-12-30 a purchase made in december, cleared in january- expenses:food 5- assets:bank:checking -5 ; date: 2023-01-02-- To solve this you can transfer the money to and from a temporary-account, splitting the multi-day transaction into two single-day-transactions:--; in 2022.journal:-2022-12-30 a purchase made in december, cleared in january- expenses:food 5- equity:pending -5--; in 2023.journal:-2023-01-02 last year's transaction cleared- equity:pending 5 = 0- assets:bank:checking -5---File: hledger.info, Node: close examples, Prev: close and balance assertions, Up: close--24.11.9 close examples-------------------------* Menu:--* Retain earnings::-* Migrate balances to a new file::-* More detailed close examples::---File: hledger.info, Node: Retain earnings, Next: Migrate balances to a new file, Up: close examples--24.11.9.1 Retain earnings-.........................--Record 2022's revenues/expenses as retained earnings on 2022-12-31,-appending the generated transaction to the journal:--$ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal-- After this, to see 2022's revenues and expenses you must exclude the-retain earnings transaction:--$ hledger -f 2022.journal is not:desc:'retain earnings'---File: hledger.info, Node: Migrate balances to a new file, Next: More detailed close examples, Prev: Retain earnings, Up: close examples--24.11.9.2 Migrate balances to a new file-........................................--Close assets/liabilities on 2022-12-31 and re-open them on 2023-01-01:--$ hledger close --migrate -f 2022.journal -p 2022-# copy/paste the closing transaction to the end of 2022.journal-# copy/paste the opening transaction to the start of 2023.journal-- After this, to see 2022's end-of-year balances you must exclude the-closing balances transaction:--$ hledger -f 2022.journal bs not:desc:'closing balances'-- For more flexibility, it helps to tag closing and opening-transactions with eg 'start:NEWYEAR', then you can ensure correct-balances by excluding all opening/closing transactions except the first,-like so:--$ hledger bs -Y -f 2021.j -f 2022.j -f 2023.j expr:'tag:start=2021 or not tag:start'-$ hledger bs -Y -f 2021.j -f 2022.j expr:'tag:start=2021 or not tag:start'-$ hledger bs -Y -f 2022.j -f 2023.j expr:'tag:start=2022 or not tag:start'-$ hledger bs -Y -f 2021.j expr:'tag:start=2021 or not tag:start'-$ hledger bs -Y -f 2022.j expr:'tag:start=2022 or not tag:start'-$ hledger bs -Y -f 2023.j # unclosed file, no query needed---File: hledger.info, Node: More detailed close examples, Prev: Migrate balances to a new file, Up: close examples--24.11.9.3 More detailed close examples-......................................--See examples/multi-year.---File: hledger.info, Node: codes, Next: commodities, Prev: close, Up: PART 4 COMMANDS--24.12 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:--2022/1/1 (123) Supermarket - Food $5.00- Checking --2022/1/2 (124) Post Office- Postage $8.32- Checking--2022/1/3 Supermarket- Food $11.23- Checking --2022/1/4 (126) Post Office- Postage $3.21- Checking--$ hledger codes-123-124-126--$ hledger codes -E-123-124--126---File: hledger.info, Node: commodities, Next: demo, Prev: codes, Up: PART 4 COMMANDS--24.13 commodities-=================--List all commodity/currency symbols used or declared in the journal.---File: hledger.info, Node: demo, Next: descriptions, Prev: commodities, Up: PART 4 COMMANDS--24.14 demo-==========--Play demos of hledger usage in the terminal, if asciinema is installed.-- Run this command with no argument to list the demos. To play a demo,-write its number or a prefix or substring of its title. Tips:-- Make your terminal window large enough to see the demo clearly.-- Use the -s/-speed SPEED option to set your preferred playback speed,-eg '-s4' to play at 4x original speed or '-s.5' to play at half speed.-The default speed is 2x.-- Other asciinema options can be added following a double dash, eg '----i.1' to limit pauses or '-- -h' to list asciinema's other options.-- During playback, several keys are available: SPACE to pause/unpause,-. to step forward (while paused), CTRL-c quit.-- Examples:--$ hledger demo # list available demos-$ hledger demo 1 # play the first demo at default speed (2x)-$ hledger demo install -s4 # play the "install" demo at 4x speed---File: hledger.info, Node: descriptions, Next: diff, Prev: demo, Up: PART 4 COMMANDS--24.15 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 transactions.-- Example:--$ hledger descriptions-Store Name-Gas Station | Petrol-Person A---File: hledger.info, Node: diff, Next: files, Prev: descriptions, Up: PART 4 COMMANDS--24.16 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-multiple 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:---File: hledger.info, Node: files, Next: help, Prev: diff, Up: PART 4 COMMANDS--24.17 files-===========--List all files included in the journal. With a REGEX argument, only-file names matching the regular expression (case sensitive) are shown.---File: hledger.info, Node: help, Next: import, Prev: files, Up: PART 4 COMMANDS--24.18 help-==========--Show the hledger user manual in the terminal, with 'info', 'man', or a-pager. With a TOPIC argument, open it at that topic if possible. TOPIC-can be any heading in the manual, or a heading prefix, case insensitive.-Eg: 'commands', 'print', 'forecast', 'journal', 'amount', '"auto-postings"'.-- This command shows the hledger manual built in to your hledger-version. It can be useful when offline, or when you prefer the terminal-to a web browser, or when the appropriate hledger manual or viewing-tools are not installed on your system.-- By default it chooses the best viewer found in $PATH, trying (in this-order): 'info', 'man', '$PAGER', 'less', 'more'. You can force the use-of info, man, or a pager with the '-i', '-m', or '-p' flags, If no-viewer can be found, or the command is run non-interactively, it just-prints the manual to stdout.-- If using 'info', note that version 6 or greater is needed for TOPIC-lookup. If you are on mac you will likely have info 4.8, and should-consider installing a newer version, eg with 'brew install texinfo'-(#1770).-- Examples--$ hledger help --help # show how the help command works-$ hledger help # show the hledger manual with info, man or $PAGER-$ hledger help journal # show the journal topic in the hledger manual-$ hledger help -m journal # show it with man, even if info is installed---File: hledger.info, Node: import, Next: incomestatement, Prev: help, Up: PART 4 COMMANDS--24.19 import-============--Read new transactions added to each FILE provided as arguments since-last run, and add them to the journal. Or with -dry-run, just print the-transactions that would be added. Or with -catchup, just mark all of-the FILEs' current transactions as imported, without importing them.-- This command may append new transactions to the main journal file-(which should be in journal format). Existing transactions are not-changed. This is one of the few hledger commands that writes to the-journal file (see also 'add').-- Unlike other hledger commands, with 'import' the journal file is an-output file, and will be modified, though only by appending (existing-data will not be changed). The input files are specified as arguments,-so to import one or more CSV files to your main journal, you will run-'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.--* Menu:--* Deduplication::-* Import testing::-* Importing balance assignments::-* Commodity display styles::---File: hledger.info, Node: Deduplication, Next: Import testing, Up: import--24.19.1 Deduplication------------------------'import' tries to import only the transactions which are new since the-last import, ignoring any that it has seen in previous runs. So if your-bank's CSV includes the last three months of data, you can download and-'import' it every month (or week, or day) and only the new transactions-will be imported each time.-- It works as follows. For each imported 'FILE' (usually CSV, but they-could be any of hledger's input formats):-- * It tries to recall the latest date seen previously, reading it from- a hidden '.latest.FILE' in the same directory.- * Then it processes 'FILE', ignoring any transactions on or before- the "latest seen" date.-- And after a successful import, it updates the '.latest.FILE'(s) for-next time (unless '--dry-run' was used).-- This is a limited kind of deduplication, let's call it "date-skipping". Within each input file, it avoids reprocessing the same-dates across successive runs. This is a simple system that works for-most real-world CSV files; it assumes these are true, or true enough:-- 1. new items always have the newest dates- 2. item dates are stable across successive downloads- 3. the order of same-date items is stable across downloads- 4. the name of the input file is stable across downloads-- If you have a bank whose CSV dates or ordering occasionally change,-you can reduce the chance of this happening in new transactions by-importing more often, and in old transactions it doesn't matter. And-remember you can use CSV rules files as input, which is one way to-ensure a stable file name.-- 'import' doesn't detect other kinds of duplication, such as duplicate-transactions within a single run. (In part, because legitimate-duplicate transactions can easily occur in real-world data.) So, say-you downloaded but forgot to import 'bank.1.csv', and a week later you-downloaded 'bank.2.csv' with overlapping data. Now you should not-import both of these at once ('hledger import bank.1.csv bank.2.csv');-the overlapping transactions which appear twice would not be-deduplicated since this is considered a single import. Instead, import-these files one at a time, and also use the same filename each time for-a common "latest seen" state:--$ mv bank.1.csv bank.csv; hledger import bank.csv-$ mv bank.2.csv bank.csv; hledger import bank.csv-- Normally you can ignore the '.latest.*' files, but if needed, you can-delete them (to make all transactions unseen), or construct/modify them-(to catch up to a certain date). The format is just a single ISO-format-date ('YYYY-MM-DD'), possibly repeated on multiple lines. It means "I-have seen transactions up to this date, and this many of them occurring-on that date".-- 'hledger print --new' also uses and updates these '.latest.*' files,-but it is less often used.-- Related: CSV > Working with CSV > Deduplicating, importing.---File: hledger.info, Node: Import testing, Next: Importing balance assignments, Prev: Deduplication, Up: import--24.19.2 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'-- Note: when importing from multiple files at once, it's currently-possible for some .latest files to be updated successfully, while the-actual import fails because of a problem in one of the files, leaving-them out of sync (and causing some transactions to be missed). To-prevent this, do a -dry-run first and fix any problems before the real-import.---File: hledger.info, Node: Importing balance assignments, Next: Commodity display styles, Prev: Import testing, Up: import--24.19.3 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.)---File: hledger.info, Node: Commodity display styles, Prev: Importing balance assignments, Up: import--24.19.4 Commodity display styles-----------------------------------Imported amounts will be formatted according to the canonical commodity-styles (declared or inferred) in the main journal file.---File: hledger.info, Node: incomestatement, Next: notes, Prev: import, Up: PART 4 COMMANDS--24.20 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.-- This report shows accounts declared with the 'Revenue' or 'Expense'-type (see account types). Or if no such accounts are declared, it shows-top-level accounts named 'revenue' or 'income' or 'expense' (case-insensitive, plurals allowed) and their subaccounts.-- Example:--$ hledger incomestatement-Income Statement 2008-- || 2008 -===================++======- Revenues || --------------------++------- income:gifts || $1 - income:salary || $1 --------------------++------- || $2 -===================++======- Expenses || --------------------++------- expenses:food || $1 - expenses:supplies || $1 --------------------++------- || $2 -===================++======- Net: || 0 -- This command is a higher-level variant of the 'balance' command, and-supports 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', 'tsv' (_Added in-1.32_), 'html', and 'json'.---File: hledger.info, Node: notes, Next: payees, Prev: incomestatement, Up: PART 4 COMMANDS--24.21 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-transactions. 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---File: hledger.info, Node: payees, Next: prices, Prev: notes, Up: PART 4 COMMANDS--24.22 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---File: hledger.info, Node: prices, Next: print, Prev: payees, Up: PART 4 COMMANDS--24.23 prices-============--Print the market prices declared with P directives. With--infer-market-prices, also show any additional prices inferred from-costs. With -show-reverse, also show additional prices inferred by-reversing known prices.-- Price amounts are always displayed with their full precision, except-for reverse prices which are limited to 8 decimal digits.-- Prices can be filtered by a date:, cur: or amt: query.-- Generally if you run this command with -infer-market-prices--show-reverse, it will show the same prices used internally to calculate-value reports. But if in doubt, you can inspect those directly by-running the value report with -debug=2.---File: hledger.info, Node: print, Next: register, Prev: prices, Up: PART 4 COMMANDS--24.24 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).-- 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/regenerate your journal you should take care to also copy-over the directives and inter-transaction comments.-- Eg:--$ hledger print -f examples/sample.journal date:200806-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--* Menu:--* print explicitness::-* print amount style::-* print parseability::-* print other features::-* print output format::---File: hledger.info, Node: print explicitness, Next: print amount style, Up: print--24.24.1 print explicitness-----------------------------Normally, whether posting amounts are implicit or explicit is preserved.-For example, when an amount is omitted in the journal, it will not-appear in the output. Similarly, if a conversion cost is implied but-not written, it will not appear in the output.-- You can use the '-x'/'--explicit' flag to force explicit display of-all amounts and costs. This 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'.-- The '-x'/'--explicit' flag will cause any postings with a-multi-commodity amount (which can arise when a multi-commodity-transaction has an implicit amount) to be split into multiple-single-commodity postings, keeping the output parseable.---File: hledger.info, Node: print amount style, Next: print parseability, Prev: print explicitness, Up: print--24.24.2 print amount style-----------------------------Amounts are shown right-aligned within each transaction (but not aligned-across all transactions; you can do that with ledger-mode in Emacs).-- Amounts will be (mostly) normalised to their commodity display style:-their symbol placement, decimal mark, and digit group marks will be made-consistent. By default, decimal digits are shown as they are written in-the journal.-- With the '--round' (_Added in 1.32_) option, 'print' will try-increasingly hard to display decimal digits according to the commodity-display styles:-- * '--round=none' show amounts with original precisions (default)- * '--round=soft' add/remove decimal zeros in amounts (except costs)- * '--round=hard' round amounts (except costs), possibly hiding- significant digits- * '--round=all' round all amounts and costs-- 'soft' is good for non-lossy cleanup, formatting amounts more-consistently where it's safe to do so.-- 'hard' and 'all' can cause 'print' to show invalid unbalanced journal-entries; they may be useful eg for stronger cleanup, with manual fixups-when needed.---File: hledger.info, Node: print parseability, Next: print other features, Prev: print amount style, Up: print--24.24.3 print parseability-----------------------------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 (though the same can be achieved with 'expr:' queries-now):--# 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:-- * Value reporting affects posting amounts but not balance assertion- or balance assignment amounts, potentially causing those to fail.- * Auto postings can generate postings with too many missing amounts.- * Account aliases can generate bad account names.---File: hledger.info, Node: print other features, Next: print output format, Prev: print parseability, Up: print--24.24.4 print, other features--------------------------------With '-B'/'--cost', amounts with costs are shown converted to cost.-- With '--new', print shows only transactions it has not seen on a-previous run. This uses the same deduplication system as the 'import'-command. (See import's docs for details.)-- With '-m DESC'/'--match=DESC', print shows one recent transaction-whose description is most similar to DESC. DESC should contain at least-two characters. If there is no similar-enough match, no transaction-will be shown and the program exit code will be non-zero.---File: hledger.info, Node: print output format, Prev: print other features, Up: print--24.24.5 print output format------------------------------This command also supports the output destination and output format-options The output formats supported are 'txt', 'beancount' (_Added in-1.32_), 'csv', 'tsv' (_Added in 1.32_), 'json' and 'sql'.-- The 'beancount' format tries to produce Beancount-compatible output,-as follows:-- * Transaction and postings with unmarked status are converted to- cleared ('*') status.- * Transactions' payee and note are backslash-escaped and- double-quote-escaped and wrapped in double quotes.- * Transaction tags are copied to Beancount #tag format.- * Commodity symbols are converted to upper case, and a small number- of currency symbols like '$' are converted to the corresponding- currency names.- * Account name parts are capitalised and unsupported characters are- replaced with '-'. If an account name part does not begin with a- letter, or if the first part is not Assets, Liabilities, Equity,- Income, or Expenses, an error is raised. (Use '--alias' options to- bring your accounts into compliance.)- * An 'open' directive is generated for each account used, on the- earliest transaction date.-- Some limitations:-- * Balance assertions are removed.- * Balance assignments become missing amounts.- * Virtual and balanced virtual postings become regular postings.- * Directives are not converted.-- 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","","",""-- * There is one CSV record per posting, with the parent transaction's- fields repeated.- * 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.)- * The amount is separated into "commodity" (the symbol) and "amount"- (numeric quantity) fields.- * The numeric amount is repeated in either the "credit" or "debit"- column, for convenience. (Those names are not accurate in the- accounting sense; it just puts negative amounts under credit and- zero or greater amounts under debit.)---File: hledger.info, Node: register, Next: rewrite, Prev: print, Up: PART 4 COMMANDS--24.25 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.-- For performance reasons, column widths are chosen based on the first-1000 lines; this means unusually wide values in later lines can cause-visual discontinuities as column widths are adjusted. If you want to-ensure perfect alignment, at the cost of more time and memory, use the-'--align-all' flag.-- The '--historical'/'-H' flag adds the balance from any undisplayed-prior postings to the running total. This is useful when you want to-see 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-numbers. 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.-- With '-m DESC'/'--match=DESC', register does a fuzzy search for one-recent posting whose description is most similar to DESC. DESC should-contain at least two characters. If there is no similar-enough match,-no posting will be shown and the program exit code will be non-zero.--* Menu:--* Custom register output::---File: hledger.info, Node: Custom register output, Up: register--24.25.1 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', 'tsv' (_Added in-1.32_), and 'json'.---File: hledger.info, Node: rewrite, Next: roi, Prev: register, Up: PART 4 COMMANDS--24.26 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-transaction'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-commodity.--* Menu:--* Re-write rules in a file::-* Diff output format::-* rewrite vs print --auto::---File: hledger.info, Node: Re-write rules in a file, Next: Diff output format, Up: rewrite--24.26.1 Re-write rules in a file-----------------------------------During the run this tool will execute so called "Automated Transactions"-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-transactions 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-postings.---File: hledger.info, Node: Diff output format, Next: rewrite vs print --auto, Prev: Re-write rules in a file, Up: rewrite--24.26.2 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-containing 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---File: hledger.info, Node: rewrite vs print --auto, Prev: Diff output format, Up: rewrite--24.26.3 rewrite vs. print -auto----------------------------------This command predates print -auto, and currently does much the same-thing, but with these differences:-- * with multiple files, rewrite lets rules in any file affect all- other files. print -auto uses standard directive scoping; rules- affect only child files.-- * rewrite's query limits which transactions can be rewritten; all are- printed. print -auto's query limits which transactions are- printed.-- * rewrite applies rules specified on command line or in the journal.- print -auto applies rules specified in the journal.---File: hledger.info, Node: roi, Next: stats, Prev: rewrite, Up: PART 4 COMMANDS--24.27 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, also known as money-weighted rate of return) and time-weighted-rate of return (TWR) for your investments for the time period requested.-IRR is always annualized due to the way it is computed, but TWR is-reported both as a rate over the chosen reporting period and as an-annual rate.-- 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:-- * 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.- * Error (SearchFailed): Failed to find solution for Internal Rate of- Return (IRR). Either search does not converge to a solution, or- converges too slowly.-- Examples:-- * Using roi to compute total return of investment in stocks:- https://github.com/simonmichael/hledger/blob/master/examples/investing/roi-unrealised.ledger-- * Cookbook > Return on Investment: https://hledger.org/roi.html--* Menu:--* Spaces and special characters in --inv and --pnl::-* Semantics of --inv and --pnl::-* IRR and TWR explained::---File: hledger.info, Node: Spaces and special characters in --inv and --pnl, Next: Semantics of --inv and --pnl, Up: roi--24.27.1 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'"---File: hledger.info, Node: Semantics of --inv and --pnl, Next: IRR and TWR explained, Prev: Spaces and special characters in --inv and --pnl, Up: roi--24.27.2 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.-- * "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-- * "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---File: hledger.info, Node: IRR and TWR explained, Prev: Semantics of --inv and --pnl, Up: roi--24.27.3 IRR and TWR explained--------------------------------"ROI" stands for "return on investment". Traditionally this was-computed as a difference between current value of investment and its-initial value, expressed in percentage of the initial value.-- However, this approach is only practical in simple cases, where-investments receives no in-flows or out-flows of money, and where rate-of growth is fixed over time. For more complex scenarios you need-different ways to compute rate of return, and this command implements-two of them: IRR and TWR.-- Internal rate of return, or "IRR" (also called "money-weighted rate-of return") takes into account effects of in-flows and out-flows, and-the time between them. Investment at a particular fixed interest rate-is going to give you more interest than the same amount invested at the-same interest rate, but made later in time. If you are withdrawing from-your investment, your future gains would be smaller (in absolute-numbers), and will be a smaller percentage of your initial investment,-so your IRR will be smaller. And if you are adding to your investment,-you will receive bigger absolute gains, which will be a bigger-percentage of your initial investment, so your IRR will be larger.-- 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 "unrealized-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-account for the effect of your in-flows and out-flows, but unlike IRR it-will try to compute the true rate of return of the underlying asset,-compensating for the effect that deposits and withdrawas have on the-apparent rate of growth of your investment.-- 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, and make TWR less sensitive than IRR to the effects of-cash in-flows and out-flows.-- References:-- * Explanation of rate of return- * Explanation of IRR- * Explanation of TWR- * IRR vs TWR- * Examples of computing IRR and TWR and discussion of the limitations- of both metrics---File: hledger.info, Node: stats, Next: tags, Prev: roi, Up: PART 4 COMMANDS--24.28 stats-===========--Show journal and performance statistics.-- The stats command shows summary information for the whole journal, or-a matched part of it. With a reporting interval, it shows a report for-each report period.-- The default output is fairly impersonal, though it reveals the main-file name. With '-v/--verbose', more details are shown, like file-paths, included files, and commodity names.-- It also shows some run time statistics:-- * elapsed time- * throughput: the number of transactions processed per second- * live: the peak memory in use by the program to do its work- * alloc: the peak memory allocation from the OS as seen by GHC.- Measuring this externally, eg with GNU time, is more accurate;- usually that will be a larger number; sometimes (with swapping?)- smaller.-- The 'stats' command's run time is similar to that of a balance-report.-- Example:--$ hledger stats -f examples/1ktxns-1kaccts.journal -Main file : .../1ktxns-1kaccts.journal-Included files : 0-Txns span : 2000-01-01 to 2002-09-27 (1000 days)-Last txn : 2002-09-26 (7827 days ago)-Txns : 1000 (1.0 per day)-Txns last 30 days : 0 (0.0 per day)-Txns last 7 days : 0 (0.0 per day)-Payees/descriptions : 1000-Accounts : 1000 (depth 10)-Commodities : 26-Market prices : 1000-Runtime stats : 0.12 s elapsed, 8266 txns/s, 4 MB live, 16 MB alloc-- This command supports the -o/-output-file option (but not--O/-output-format).---File: hledger.info, Node: tags, Next: test, Prev: stats, Up: PART 4 COMMANDS--24.29 tags-==========--List the tags used in the journal, or their values.-- This command lists the tag names used in the journal, whether on-transactions, postings, or account declarations.-- With a TAGREGEX argument, only tag names matching this regular-expression (case insensitive, infix matched) are shown.-- With QUERY arguments, only transactions and accounts matching this-query are considered. If the query involves transaction fields (date:,-desc:, amt:, ...), the search is restricted to the matched transactions-and their accounts.-- With the -values flag, the tags' unique non-empty values are listed-instead. With -E/-empty, blank/empty values are also shown.-- With -parsed, tags or values are shown in the order they were parsed,-with duplicates included. (Except, tags from account declarations are-always shown first.)-- Tip: remember, accounts also acquire tags from their parents,-postings also acquire tags from their account and transaction,-transactions also acquire tags from their postings.---File: hledger.info, Node: test, Prev: tags, Up: PART 4 COMMANDS--24.30 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).---File: hledger.info, Node: PART 5 COMMON TASKS, Next: BUGS, Prev: PART 4 COMMANDS, Up: Top--25 PART 5: COMMON TASKS-***********************--Here are some quick examples of how to do some basic tasks with hledger.--* Menu:--* Getting help::-* Constructing command lines::-* Starting a journal file::-* Setting LEDGER_FILE::-* Setting opening balances::-* Recording transactions::-* Reconciling::-* Reporting::-* Migrating to a new file::---File: hledger.info, Node: Getting help, Next: Constructing command lines, Up: PART 5 COMMON TASKS--25.1 Getting help-=================--Here's how to list commands and view options and command docs:--$ hledger # show available commands-$ hledger --help # show common options-$ hledger CMD --help # show CMD's options, common options and CMD's documentation-- You can also view your hledger version's manual in several formats by-using the help command. Eg:--$ hledger help # show the hledger manual with info, man or $PAGER (best available)-$ hledger help journal # show the journal topic in the hledger manual-$ hledger help --help # find out more about the help command-- To view manuals and introductory docs on the web, visit-https://hledger.org. Chat and mail list support and discussion archives-can be found at https://hledger.org/support.---File: hledger.info, Node: Constructing command lines, Next: Starting a journal file, Prev: Getting help, Up: PART 5 COMMON TASKS--25.2 Constructing command lines-===============================--hledger has a flexible command line interface. We strive to keep it-simple and ergonomic, but if you run into one of the sharp edges-described in OPTIONS, here are some tips that might help:-- * command-specific options must go after the command (it's fine to- put common options there too: 'hledger CMD OPTS ARGS')- * running add-on executables directly simplifies command line parsing- ('hledger-ui OPTS ARGS')- * enclose "problematic" args in single quotes- * if needed, also add a backslash to hide regular expression- metacharacters from the shell- * to see how a misbehaving command line is being parsed, add- '--debug=2'.---File: hledger.info, Node: Starting a journal file, Next: Setting LEDGER_FILE, Prev: Constructing command lines, Up: PART 5 COMMON TASKS--25.3 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 (see below). 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 2023.journal-$ echo "export LEDGER_FILE=$HOME/finance/2023.journal" >> ~/.profile-$ source ~/.profile-$ hledger stats-Main file : /Users/simon/finance/2023.journal-Included files : -Transactions span : to (0 days)-Last transaction : none-Transactions : 0 (0.0 per day)-Transactions last 30 days: 0 (0.0 per day)-Transactions last 7 days : 0 (0.0 per day)-Payees/descriptions : 0-Accounts : 0 (depth 0)-Commodities : 0 ()-Market prices : 0 ()---File: hledger.info, Node: Setting LEDGER_FILE, Next: Setting opening balances, Prev: Starting a journal file, Up: PART 5 COMMON TASKS--25.4 Setting LEDGER_FILE-========================--How to set 'LEDGER_FILE' permanently depends on your setup:-- On unix and mac, running these commands in the terminal will work for-many people; adapt as needed:--$ echo 'export LEDGER_FILE=~/finance/2023.journal' >> ~/.profile-$ source ~/.profile-- When correctly configured, in a new terminal window 'env | grep-LEDGER_FILE' will show your file, and so will 'hledger files'.-- On mac, this additional step might be helpful for GUI applications-(like Emacs started from the dock): add an entry to-'~/.MacOSX/environment.plist' like--{- "LEDGER_FILE" : "~/finance/2023.journal"-}-- and then run 'killall Dock' in a terminal window (or restart the-machine).-- On Windows, see https://www.java.com/en/download/help/path.html, or-try running these commands in a powershell window (let us know if it-persists across a reboot, and if you need to be an Administrator):--> CD-> MKDIR finance-> SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal"---File: hledger.info, Node: Setting opening balances, Next: Recording transactions, Prev: Setting LEDGER_FILE, Up: PART 5 COMMON TASKS--25.5 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-balances on this date. Here are two ways to do it:-- * The first way: open the journal in any text editor and save an- entry like this:-- 2023-01-01 * opening balances- assets:bank:checking $1000 = $1000- assets:bank:savings $2000 = $2000- assets:cash $100 = $100- liabilities:creditcard $-50 = $-50- equity:opening/closing balances-- 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.-- * 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/2023.journal- Any command line arguments will be used as defaults.- Use tab key to complete, readline keys to edit, enter to accept defaults.- An optional (CODE) may follow transaction dates.- An optional ; COMMENT may follow descriptions or amounts.- If you make a mistake, enter < at any prompt to go one step backward.- To end a transaction, enter . when prompted.- To quit, enter . at a date prompt or press control-d or control-c.- Date [2023-02-07]: 2023-01-01- Description: * opening balances- Account 1: assets:bank:checking- Amount 1: $1000- Account 2: assets:bank:savings- Amount 2 [$-1000]: $2000- Account 3: assets:cash- Amount 3 [$-3000]: $100- Account 4: liabilities:creditcard- Amount 4 [$-3100]: $-50- Account 5: equity:opening/closing balances- Amount 5 [$-3050]: - Account 6 (or . or enter to finish this transaction): .- 2023-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050- - Save this transaction to the journal ? [y]: - Saved.- Starting the next transaction (. or ctrl-D/ctrl-C to quit)- Date [2023-01-01]: .-- If you're using version control, this could be a good time to commit-the journal. Eg:--$ git commit -m 'initial balances' 2023.journal---File: hledger.info, Node: Recording transactions, Next: Reconciling, Prev: Setting opening balances, Up: PART 5 COMMON TASKS--25.6 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:--2023/1/10 * gift received- assets:cash $20- income:gifts--2023.1.12 * farmers market- expenses:food $13- assets:cash--2023-01-15 paycheck- income:salary- assets:bank:checking $1000---File: hledger.info, Node: Reconciling, Next: Reporting, Prev: Recording transactions, Up: PART 5 COMMON TASKS--25.7 Reconciling-================--Periodically you should reconcile - compare your hledger-reported-balances 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-discrepancies.-- 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:-- 2023-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 checking -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 transaction 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---register 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 '2023-01-15' and 'paycheck'-- If you're using version control, this can be another good time to-commit:--$ git commit -m 'txns' 2023.journal---File: hledger.info, Node: Reporting, Next: Migrating to a new file, Prev: Reconciling, Up: PART 5 COMMON TASKS--25.8 Reporting-==============--Here are some basic reports.-- Show all transactions:--$ hledger print-2023-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050--2023-01-10 * gift received- assets:cash $20- income:gifts--2023-01-12 * farmers market- expenses:food $13- assets:cash--2023-01-15 * paycheck- income:salary- assets:bank:checking $1000--2023-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- 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 -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 -2-Balance Sheet 2023-01-16-- || 2023-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 2023-01-01-2023-01-16-- || 2023-01-01-2023-01-16 -===============++=======================- Revenues || ----------------++------------------------ income:gifts || $20 - income:salary || $1000 ----------------++------------------------ || $1020 -===============++=======================- Expenses || ----------------++------------------------ expenses:food || $13 - expenses:misc || $2 ----------------++------------------------ || $15 -===============++=======================- Net: || $1005 -- The final total is your net income during this period.-- Show transactions affecting your wallet, with running total:--$ hledger register cash-2023-01-01 opening balances assets:cash $100 $100-2023-01-10 gift received assets:cash $20 $120-2023-01-12 farmers market assets:cash $-13 $107-2023-01-16 adjust cash assets:cash $-2 $105-- Show weekly posting counts as a bar chart:--$ hledger activity -W-2019-12-30 *****-2023-01-06 ****-2023-01-13 ****---File: hledger.info, Node: Migrating to a new file, Prev: Reporting, Up: PART 5 COMMON TASKS--25.9 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.---File: hledger.info, Node: BUGS, Prev: PART 5 COMMON TASKS, Up: Top--26 BUGS-*******--We welcome bug reports in the hledger issue tracker (shortcut:-http://bugs.hledger.org), or on the #hledger chat or hledger mail list-(https://hledger.org/support).-- Some known issues and limitations:-- The need to precede add-on command options with '--' when invoked-from hledger is awkward. (See Command options, Constructing command-lines.)-- A UTF-8-aware system locale must be configured to work with non-ascii-data. (See Unicode characters, Troubleshooting.)-- On Microsoft Windows, depending whether you are running in a CMD-window or a Cygwin/MSYS/Mintty window and how you installed hledger,-non-ascii characters and colours may not be supported, and the tab key-may not be supported by 'hledger add'. (Running in a WSL window should-resolve these.)-- When processing large data files, hledger uses more memory than-Ledger.--* Menu:--* Troubleshooting::---File: hledger.info, Node: Troubleshooting, Up: BUGS--26.1 Troubleshooting-====================--Here are some common issues you might encounter when you run hledger,-and how to resolve them (and remember also you can usually get quick-Support):-- *PATH issues: I get an error like "No command 'hledger' found"*-Depending how you installed hledger, the executables may not be in your-shell's PATH. Eg on unix systems, stack installs hledger in-'~/.local/bin' and cabal installs it in '~/.cabal/bin'. You may need to-add one of these directories to your shell's PATH, and/or open a new-terminal window.-- *LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not-using it*-- * 'LEDGER_FILE' should be a real environment variable, not just a- shell variable. Eg on unix, the command 'env | grep LEDGER_FILE'- should show it. You may need to use 'export' (see- https://stackoverflow.com/a/7411509).- * You may need to force your shell to see the new configuration. A- simple way is to close your terminal window and open a new one.-- *LANG issues: I get errors like "Illegal byte sequence" or "Invalid-or incomplete multibyte or wide character" or "commitAndReleaseBuffer:-invalid argument (invalid character)"*-Programs compiled with GHC (hledger, haskell build tools, etc.) need-the system locale to be UTF-8-aware, or they will fail when they-encounter non-ascii characters. To fix it, set the LANG environment-variable to a locale which supports UTF-8 and which is installed on your-system.-- On unix, 'locale -a' lists the installed locales. Look for one which-mentions 'utf8', 'UTF-8' or similar. Some examples: 'C.UTF-8',-'en_US.utf-8', 'fr_FR.utf8'. If necessary, use your system package-manager to install one. Then select it by setting the 'LANG'-environment variable. Note, exact spelling and capitalisation of the-locale name may be important: Here's one common way to configure this-permanently for your shell:--$ echo "export LANG=en_US.utf8" >>~/.profile-# close and re-open terminal window-- If you are using Nix (not NixOS) for GHC and Hledger, you might need-to set the 'LOCALE_ARCHIVE' variable:--$ echo "export LOCALE_ARCHIVE=${glibcLocales}/lib/locale/locale-archive" >>~/.profile-# close and re-open terminal window-- *COMPATIBILITY ISSUES: hledger gives an error with my Ledger file*-Not all of Ledger's journal file syntax or feature set is supported.-See hledger and Ledger for full details.---Tag Table:-Node: Top208-Node: PART 1 USER INTERFACE3809-Ref: #part-1-user-interface3948-Node: Input3948-Ref: #input4058-Node: Text encoding5025-Ref: #text-encoding5139-Node: Data formats5705-Ref: #data-formats5840-Node: Standard input7429-Ref: #standard-input7569-Node: Multiple files7796-Ref: #multiple-files7935-Node: Strict mode8533-Ref: #strict-mode8643-Node: Commands9367-Ref: #commands9469-Node: Add-on commands10536-Ref: #add-on-commands10638-Node: Options11754-Ref: #options11866-Node: General help options12194-Ref: #general-help-options12340-Node: General input options12622-Ref: #general-input-options12804-Node: General reporting options13461-Ref: #general-reporting-options13622-Node: Command line tips17012-Ref: #command-line-tips17142-Node: Option repetition17401-Ref: #option-repetition17545-Node: Special characters17649-Ref: #special-characters17822-Node: Single escaping shell metacharacters17985-Ref: #single-escaping-shell-metacharacters18226-Node: Double escaping regular expression metacharacters18829-Ref: #double-escaping-regular-expression-metacharacters19140-Node: Triple escaping for add-on commands19666-Ref: #triple-escaping-for-add-on-commands19926-Node: Less escaping20570-Ref: #less-escaping20724-Node: Unicode characters21048-Ref: #unicode-characters21223-Node: Regular expressions22635-Ref: #regular-expressions22808-Node: hledger's regular expressions25904-Ref: #hledgers-regular-expressions26063-Node: Argument files27449-Ref: #argument-files27585-Node: Output28082-Ref: #output28194-Node: Output destination28321-Ref: #output-destination28452-Node: Output format28877-Ref: #output-format29023-Node: CSV output30620-Ref: #csv-output30736-Node: HTML output30839-Ref: #html-output30977-Node: JSON output31071-Ref: #json-output31209-Node: SQL output32131-Ref: #sql-output32247-Node: Commodity styles32982-Ref: #commodity-styles33122-Node: Colour33860-Ref: #colour33978-Node: Box-drawing34382-Ref: #box-drawing34500-Node: Paging34790-Ref: #paging34904-Node: Debug output35857-Ref: #debug-output35963-Node: Environment36626-Ref: #environment36750-Node: PART 2 DATA FORMATS37294-Ref: #part-2-data-formats37437-Node: Journal37437-Ref: #journal37546-Node: Journal cheatsheet39914-Ref: #journal-cheatsheet40041-Node: Comments46128-Ref: #comments46256-Node: Transactions47072-Ref: #transactions47195-Node: Dates48209-Ref: #dates48316-Node: Simple dates48361-Ref: #simple-dates48477-Node: Posting dates48977-Ref: #posting-dates49095-Node: Status50064-Ref: #status50165-Node: Code51830-Ref: #code51933-Node: Description52165-Ref: #description52296-Node: Payee and note52852-Ref: #payee-and-note52958-Node: Transaction comments53943-Ref: #transaction-comments54096-Node: Postings54459-Ref: #postings54590-Node: Debits and credits55622-Ref: #debits-and-credits55769-Node: The two space delimiter56232-Ref: #the-two-space-delimiter56389-Node: Account names56797-Ref: #account-names56927-Node: Amounts58601-Ref: #amounts58729-Node: Decimal marks59630-Ref: #decimal-marks59757-Node: Digit group marks60734-Ref: #digit-group-marks60887-Node: Commodity61369-Ref: #commodity61498-Node: Costs62486-Ref: #costs62581-Node: Balance assertions64738-Ref: #balance-assertions64891-Node: Assertions and ordering65975-Ref: #assertions-and-ordering66164-Node: Assertions and multiple included files66703-Ref: #assertions-and-multiple-included-files66963-Node: Assertions and multiple -f files67463-Ref: #assertions-and-multiple--f-files67708-Node: Assertions and costs68105-Ref: #assertions-and-costs68314-Node: Assertions and commodities68755-Ref: #assertions-and-commodities68970-Node: Assertions and subaccounts70414-Ref: #assertions-and-subaccounts70640-Node: Assertions and virtual postings71084-Ref: #assertions-and-virtual-postings71322-Node: Assertions and auto postings71454-Ref: #assertions-and-auto-postings71684-Node: Assertions and precision72329-Ref: #assertions-and-precision72511-Node: Posting comments72778-Ref: #posting-comments72941-Node: Transaction balancing73318-Ref: #transaction-balancing73477-Node: Tags75320-Ref: #tags75439-Node: Tag names76782-Ref: #tag-names76889-Node: Special tags77277-Ref: #special-tags77409-Node: Tag values78922-Ref: #tag-values79032-Node: Directives79904-Ref: #directives80031-Node: Directives and multiple files81361-Ref: #directives-and-multiple-files81539-Node: Directive effects82306-Ref: #directive-effects82460-Node: account directive85462-Ref: #account-directive85618-Node: Account comments86912-Ref: #account-comments87063-Node: Account error checking87571-Ref: #account-error-checking87764-Node: Account display order88953-Ref: #account-display-order89141-Node: Account types90151-Ref: #account-types90292-Node: alias directive93925-Ref: #alias-directive94086-Node: Basic aliases95136-Ref: #basic-aliases95267-Node: Regex aliases96011-Ref: #regex-aliases96168-Node: Combining aliases97058-Ref: #combining-aliases97236-Node: Aliases and multiple files98512-Ref: #aliases-and-multiple-files98716-Node: end aliases directive99295-Ref: #end-aliases-directive99514-Node: Aliases can generate bad account names99663-Ref: #aliases-can-generate-bad-account-names99911-Node: Aliases and account types100496-Ref: #aliases-and-account-types100688-Node: commodity directive101384-Ref: #commodity-directive101558-Node: Commodity directive syntax102971-Ref: #commodity-directive-syntax103156-Node: Commodity error checking104607-Ref: #commodity-error-checking104788-Node: decimal-mark directive105082-Ref: #decimal-mark-directive105264-Node: include directive105661-Ref: #include-directive105825-Node: P directive106737-Ref: #p-directive106882-Node: payee directive107771-Ref: #payee-directive107920-Node: tag directive108393-Ref: #tag-directive108548-Node: Periodic transactions109005-Ref: #periodic-transactions109170-Node: Periodic rule syntax111159-Ref: #periodic-rule-syntax111337-Node: Periodic rules and relative dates111982-Ref: #periodic-rules-and-relative-dates112248-Node: Two spaces between period expression and description!112759-Ref: #two-spaces-between-period-expression-and-description113036-Node: Auto postings113720-Ref: #auto-postings113868-Node: Auto postings and multiple files116698-Ref: #auto-postings-and-multiple-files116862-Node: Auto postings and dates117263-Ref: #auto-postings-and-dates117511-Node: Auto postings and transaction balancing / inferred amounts / balance assertions117686-Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions118042-Node: Auto posting tags118545-Ref: #auto-posting-tags118827-Node: Auto postings on forecast transactions only119463-Ref: #auto-postings-on-forecast-transactions-only119709-Node: Other syntax119956-Ref: #other-syntax120072-Node: Balance assignments120728-Ref: #balance-assignments120884-Node: Balance assignments and costs122256-Ref: #balance-assignments-and-costs122468-Node: Balance assignments and multiple files122678-Ref: #balance-assignments-and-multiple-files122908-Node: Bracketed posting dates123101-Ref: #bracketed-posting-dates123285-Node: D directive123799-Ref: #d-directive123967-Node: apply account directive125572-Ref: #apply-account-directive125752-Node: Y directive126439-Ref: #y-directive126599-Node: Secondary dates127427-Ref: #secondary-dates127581-Node: Star comments128395-Ref: #star-comments128555-Node: Valuation expressions129087-Ref: #valuation-expressions129264-Node: Virtual postings129386-Ref: #virtual-postings129563-Node: Other Ledger directives131010-Ref: #other-ledger-directives131206-Node: Other cost/lot notations131772-Ref: #other-costlot-notations131945-Node: CSV134534-Ref: #csv134627-Node: CSV rules cheatsheet136624-Ref: #csv-rules-cheatsheet136753-Node: source138551-Ref: #source138674-Node: separator139554-Ref: #separator139667-Node: skip140207-Ref: #skip140315-Node: date-format140859-Ref: #date-format140980-Node: timezone141704-Ref: #timezone141827-Node: newest-first142832-Ref: #newest-first142970-Node: intra-day-reversed143547-Ref: #intra-day-reversed143701-Node: decimal-mark144149-Ref: #decimal-mark144290-Node: fields list144629-Ref: #fields-list144768-Node: Field assignment146439-Ref: #field-assignment146583-Node: Field names147660-Ref: #field-names147791-Node: date field148994-Ref: #date-field149112-Node: date2 field149160-Ref: #date2-field149301-Node: status field149357-Ref: #status-field149500-Node: code field149549-Ref: #code-field149694-Node: description field149739-Ref: #description-field149899-Node: comment field149958-Ref: #comment-field150113-Node: account field150406-Ref: #account-field150556-Node: amount field151126-Ref: #amount-field151275-Node: currency field153967-Ref: #currency-field154120-Node: balance field154377-Ref: #balance-field154509-Node: if block154902-Ref: #if-block155023-Node: Matchers156431-Ref: #matchers156545-Node: What matchers match157342-Ref: #what-matchers-match157491-Node: Combining matchers157931-Ref: #combining-matchers158099-Node: Match groups158636-Ref: #match-groups158764-Node: if table159532-Ref: #if-table159654-Node: balance-type161535-Ref: #balance-type161664-Node: include162364-Ref: #include162491-Node: Working with CSV162935-Ref: #working-with-csv163082-Node: Rapid feedback163489-Ref: #rapid-feedback163622-Node: Valid CSV164074-Ref: #valid-csv164220-Node: File Extension164952-Ref: #file-extension165125-Node: Reading CSV from standard input165689-Ref: #reading-csv-from-standard-input165913-Node: Reading multiple CSV files166077-Ref: #reading-multiple-csv-files166308-Node: Reading files specified by rule166549-Ref: #reading-files-specified-by-rule166777-Node: Valid transactions167948-Ref: #valid-transactions168147-Node: Deduplicating importing168775-Ref: #deduplicating-importing168970-Node: Setting amounts170006-Ref: #setting-amounts170177-Node: Amount signs172535-Ref: #amount-signs172705-Node: Setting currency/commodity173602-Ref: #setting-currencycommodity173806-Node: Amount decimal places174980-Ref: #amount-decimal-places175186-Node: Referencing other fields175498-Ref: #referencing-other-fields175711-Node: How CSV rules are evaluated176608-Ref: #how-csv-rules-are-evaluated176825-Node: Well factored rules178278-Ref: #well-factored-rules178446-Node: CSV rules examples178770-Ref: #csv-rules-examples178905-Node: Bank of Ireland178970-Ref: #bank-of-ireland179107-Node: Coinbase180569-Ref: #coinbase180707-Node: Amazon181754-Ref: #amazon181879-Node: Paypal183598-Ref: #paypal183706-Node: Timeclock191350-Ref: #timeclock191455-Node: Timedot193631-Ref: #timedot193754-Node: Timedot examples196875-Ref: #timedot-examples196981-Node: PART 3 REPORTING CONCEPTS199152-Ref: #part-3-reporting-concepts199321-Node: Amount formatting199321-Ref: #amount-formatting199477-Node: Commodity display style199579-Ref: #commodity-display-style199733-Node: Rounding201420-Ref: #rounding201575-Node: Trailing decimal marks202025-Ref: #trailing-decimal-marks202204-Node: Amount parseability202958-Ref: #amount-parseability203114-Node: Time periods204539-Ref: #time-periods204665-Node: Report start & end date204783-Ref: #report-start-end-date204935-Node: Smart dates206594-Ref: #smart-dates206747-Node: Report intervals208615-Ref: #report-intervals208770-Node: Date adjustment209188-Ref: #date-adjustment209348-Node: Period expressions210199-Ref: #period-expressions210340-Node: Period expressions with a report interval212104-Ref: #period-expressions-with-a-report-interval212338-Node: More complex report intervals212552-Ref: #more-complex-report-intervals212797-Node: Multiple weekday intervals214598-Ref: #multiple-weekday-intervals214787-Node: Depth215609-Ref: #depth215711-Node: Queries216007-Ref: #queries216109-Node: Query types217705-Ref: #query-types217826-Node: Combining query terms221060-Ref: #combining-query-terms221237-Node: Queries and command options222800-Ref: #queries-and-command-options223005-Node: Queries and account aliases223254-Ref: #queries-and-account-aliases223459-Node: Queries and valuation223579-Ref: #queries-and-valuation223736-Node: Pivoting223941-Ref: #pivoting224055-Node: Generating data225832-Ref: #generating-data225964-Node: Forecasting227547-Ref: #forecasting227672-Node: --forecast228203-Ref: #forecast228334-Node: Inspecting forecast transactions229304-Ref: #inspecting-forecast-transactions229506-Node: Forecast reports230636-Ref: #forecast-reports230809-Node: Forecast tags231745-Ref: #forecast-tags231905-Node: Forecast period in detail232365-Ref: #forecast-period-in-detail232559-Node: Forecast troubleshooting233453-Ref: #forecast-troubleshooting233621-Node: Budgeting234524-Ref: #budgeting234644-Node: Cost reporting235081-Ref: #cost-reporting235215-Node: Recording costs235876-Ref: #recording-costs236012-Node: Reporting at cost237603-Ref: #reporting-at-cost237778-Node: Equity conversion postings238368-Ref: #equity-conversion-postings238582-Node: Inferring equity conversion postings241013-Ref: #inferring-equity-conversion-postings241276-Node: Combining costs and equity conversion postings242028-Ref: #combining-costs-and-equity-conversion-postings242338-Node: Requirements for detecting equity conversion postings243253-Ref: #requirements-for-detecting-equity-conversion-postings243575-Node: Infer cost and equity by default ?244775-Ref: #infer-cost-and-equity-by-default245004-Node: Value reporting245212-Ref: #value-reporting245354-Node: -V Value246093-Ref: #v-value246225-Node: -X Value in specified commodity246420-Ref: #x-value-in-specified-commodity246621-Node: Valuation date246770-Ref: #valuation-date246947-Node: Finding market price247730-Ref: #finding-market-price247941-Node: --infer-market-prices market prices from transactions249110-Ref: #infer-market-prices-market-prices-from-transactions249392-Node: Valuation commodity252154-Ref: #valuation-commodity252374-Node: --value Flexible valuation253587-Ref: #value-flexible-valuation253786-Node: Valuation examples255430-Ref: #valuation-examples255630-Node: Interaction of valuation and queries257562-Ref: #interaction-of-valuation-and-queries257802-Node: Effect of valuation on reports258279-Ref: #effect-of-valuation-on-reports258482-Node: PART 4 COMMANDS266177-Ref: #part-4-commands266326-Node: Commands overview266705-Ref: #commands-overview266839-Node: DATA ENTRY267018-Ref: #data-entry267142-Node: DATA CREATION267341-Ref: #data-creation267495-Node: DATA MANAGEMENT267613-Ref: #data-management267778-Node: REPORTS FINANCIAL267899-Ref: #reports-financial268074-Node: REPORTS VERSATILE268379-Ref: #reports-versatile268552-Node: REPORTS BASIC268805-Ref: #reports-basic268957-Node: HELP269466-Ref: #help269588-Node: ADD-ONS269698-Ref: #add-ons269804-Node: accounts270383-Ref: #accounts270516-Node: activity272403-Ref: #activity272522-Node: add272896-Ref: #add273006-Node: aregister275992-Ref: #aregister276113-Node: aregister and posting dates279019-Ref: #aregister-and-posting-dates279164-Node: balance279920-Ref: #balance280046-Node: balance features281036-Ref: #balance-features281176-Node: Simple balance report283086-Ref: #simple-balance-report283271-Node: Balance report line format284896-Ref: #balance-report-line-format285098-Node: Filtered balance report287256-Ref: #filtered-balance-report287448-Node: List or tree mode287775-Ref: #list-or-tree-mode287943-Node: Depth limiting289288-Ref: #depth-limiting289454-Node: Dropping top-level accounts290055-Ref: #dropping-top-level-accounts290255-Node: Showing declared accounts290565-Ref: #showing-declared-accounts290764-Node: Sorting by amount291295-Ref: #sorting-by-amount291462-Node: Percentages292132-Ref: #percentages292291-Node: Multi-period balance report292839-Ref: #multi-period-balance-report293039-Node: Balance change end balance295416-Ref: #balance-change-end-balance295625-Node: Balance report types297053-Ref: #balance-report-types297234-Node: Calculation type297732-Ref: #calculation-type297887-Node: Accumulation type298436-Ref: #accumulation-type298616-Node: Valuation type299537-Ref: #valuation-type299725-Node: Combining balance report types300726-Ref: #combining-balance-report-types300920-Node: Budget report302758-Ref: #budget-report302920-Node: Using the budget report305063-Ref: #using-the-budget-report305236-Node: Budget date surprises307339-Ref: #budget-date-surprises307539-Node: Selecting budget goals308703-Ref: #selecting-budget-goals308906-Node: Budgeting vs forecasting309651-Ref: #budgeting-vs-forecasting309828-Node: Balance report layout311328-Ref: #balance-report-layout311513-Node: Wide layout312466-Ref: #wide-layout312601-Node: Tall layout314871-Ref: #tall-layout315026-Node: Bare layout316177-Ref: #bare-layout316332-Node: Tidy layout318236-Ref: #tidy-layout318371-Node: Some useful balance reports319780-Ref: #some-useful-balance-reports319955-Node: balancesheet321040-Ref: #balancesheet321185-Node: balancesheetequity322796-Ref: #balancesheetequity322954-Node: cashflow324974-Ref: #cashflow325105-Node: check326592-Ref: #check326706-Node: Default checks327510-Ref: #default-checks327636-Node: Strict checks328133-Ref: #strict-checks328278-Node: Other checks328758-Ref: #other-checks328900-Node: Custom checks329433-Ref: #custom-checks329590-Node: More about specific checks330007-Ref: #more-about-specific-checks330169-Node: close330875-Ref: #close330986-Node: close --migrate331639-Ref: #close---migrate331766-Node: close --close333405-Ref: #close---close333549-Node: close --open333785-Ref: #close---open333926-Node: close --assert334036-Ref: #close---assert334182-Node: close --assign334403-Ref: #close---assign334551-Node: close --retain335077-Ref: #close---retain335230-Node: close customisation335975-Ref: #close-customisation336154-Node: close and balance assertions337621-Ref: #close-and-balance-assertions337818-Node: close examples339145-Ref: #close-examples339286-Node: Retain earnings339384-Ref: #retain-earnings339543-Node: Migrate balances to a new file339889-Ref: #migrate-balances-to-a-new-file340115-Node: More detailed close examples341243-Ref: #more-detailed-close-examples341441-Node: codes341467-Ref: #codes341584-Node: commodities342448-Ref: #commodities342576-Node: demo342646-Ref: #demo342767-Node: descriptions343683-Ref: #descriptions343813-Node: diff344104-Ref: #diff344219-Node: files345261-Ref: #files345370-Node: help345511-Ref: #help-1345620-Node: import346993-Ref: #import347116-Node: Deduplication348224-Ref: #deduplication348349-Node: Import testing351210-Ref: #import-testing351375-Node: Importing balance assignments352218-Ref: #importing-balance-assignments352424-Node: Commodity display styles353073-Ref: #commodity-display-styles353246-Node: incomestatement353375-Ref: #incomestatement353517-Node: notes354991-Ref: #notes355113-Node: payees355475-Ref: #payees355590-Node: prices356109-Ref: #prices356224-Node: print356877-Ref: #print356992-Node: print explicitness357968-Ref: #print-explicitness358111-Node: print amount style358890-Ref: #print-amount-style359060-Node: print parseability360130-Ref: #print-parseability360302-Node: print other features361051-Ref: #print-other-features361230-Node: print output format361751-Ref: #print-output-format361899-Node: register365038-Ref: #register365160-Node: Custom register output370191-Ref: #custom-register-output370322-Node: rewrite371669-Ref: #rewrite371787-Node: Re-write rules in a file373685-Ref: #re-write-rules-in-a-file373848-Node: Diff output format374997-Ref: #diff-output-format375180-Node: rewrite vs print --auto376272-Ref: #rewrite-vs.-print---auto376432-Node: roi376988-Ref: #roi377095-Node: Spaces and special characters in --inv and --pnl378907-Ref: #spaces-and-special-characters-in---inv-and---pnl379147-Node: Semantics of --inv and --pnl379635-Ref: #semantics-of---inv-and---pnl379874-Node: IRR and TWR explained381724-Ref: #irr-and-twr-explained381884-Node: stats385137-Ref: #stats385245-Node: tags386759-Ref: #tags-1386866-Node: test387875-Ref: #test387968-Node: PART 5 COMMON TASKS388710-Ref: #part-5-common-tasks388856-Node: Getting help389154-Ref: #getting-help389295-Node: Constructing command lines390055-Ref: #constructing-command-lines390256-Node: Starting a journal file390913-Ref: #starting-a-journal-file391115-Node: Setting LEDGER_FILE392317-Ref: #setting-ledger_file392509-Node: Setting opening balances393466-Ref: #setting-opening-balances393667-Node: Recording transactions396808-Ref: #recording-transactions396997-Node: Reconciling397553-Ref: #reconciling397705-Node: Reporting399962-Ref: #reporting400111-Node: Migrating to a new file404096-Ref: #migrating-to-a-new-file404253-Node: BUGS404552-Ref: #bugs404642-Node: Troubleshooting405521-Ref: #troubleshooting405621+ This manual is for hledger's command line interface, version 1.33.1.+It also describes the common options, file formats and concepts used by+all hledger programs. It might accidentally teach you some+bookkeeping/accounting as well! You don't need to know everything in+here to use hledger productively, but when you have a question about+functionality, this doc should answer it. It is detailed, so do skip+ahead or skim when needed. You can read it on hledger.org, or as an+info manual or man page on your system. You can also get it from+hledger itself with+'hledger --man', 'hledger --info' or 'hledger help [TOPIC]'.++ The main function of the hledger CLI is to read plain text files+describing financial transactions, crunch the numbers, and print a+useful report on the terminal (or save it as HTML, CSV, JSON or SQL).+Many reports are available, as subcommands. hledger will also detect+other 'hledger-*' executables as extra subcommands.++ hledger usually reads from (and appends to) a journal file specified+by the 'LEDGER_FILE' environment variable (defaulting to+'$HOME/.hledger.journal'); or you can specify files with '-f' options.+It can also read timeclock files, timedot files, or any CSV/SSV/TSV file+with a date field.++ Here is a small journal file describing one transaction:++2015-10-16 bought food+ expenses:food $10+ assets:cash++ Transactions are dated movements of money (etc.) between two or more+_accounts_: bank accounts, your wallet, revenue/expense categories,+people, etc. You can choose any account names you wish, using ':' to+indicate subaccounts. There must be at least two spaces between account+name and amount. Positive amounts are inflow to that account (_debit_),+negatives are outflow from it (_credit_). (Some reports show revenue,+liability and equity account balances as negative numbers as a result;+this is normal.)++ hledger's add command can help you add transactions, or you can+install other data entry UIs like hledger-web or hledger-iadd. For more+extensive/efficient changes, use a text editor: Emacs + ledger-mode, VIM++ vim-ledger, or VS Code + hledger-vscode are some good choices (see+https://hledger.org/editors.html).++ To get started, run 'hledger add' and follow the prompts, or save+some entries like the above in '$HOME/.hledger.journal', then try+commands like:++$ hledger print -x+$ hledger aregister assets+$ hledger balance+$ hledger balancesheet+$ hledger incomestatement++ Run 'hledger' to list the commands. See also the "Starting a journal+file" and "Setting opening balances" sections in PART 5: COMMON TASKS.++* Menu:++* PART 1 USER INTERFACE::+* Input::+* Commands::+* Options::+* Command line tips::+* Output::+* Environment::+* PART 2 DATA FORMATS::+* Journal::+* CSV::+* Timeclock::+* Timedot::+* PART 3 REPORTING CONCEPTS::+* Amount formatting::+* Time periods::+* Depth::+* Queries::+* Pivoting::+* Generating data::+* Forecasting::+* Budgeting::+* Cost reporting::+* Value reporting::+* PART 4 COMMANDS::+* PART 5 COMMON TASKS::+* BUGS::+++File: hledger.info, Node: PART 1 USER INTERFACE, Next: Input, Prev: Top, Up: Top++1 PART 1: USER INTERFACE+************************+++File: hledger.info, Node: Input, Next: Commands, Prev: PART 1 USER INTERFACE, Up: Top++2 Input+*******++hledger reads one or more data files, each time you run it. You can+specify a file with '-f', like so++$ hledger -f FILE print++ Files are most often in hledger's journal format, with the '.journal'+file extension ('.hledger' or '.j' also work); these files describe+transactions, like an accounting general journal.++ When no file is specified, hledger looks for '.hledger.journal' in+your home directory.++ But most people prefer to keep financial files in a dedicated folder,+perhaps with version control. Also, starting a new journal file each+year is common (it's not required, but helps keep things fast and+organised). So we usually configure a different journal file, by+setting the 'LEDGER_FILE' environment variable, to something like+'~/finance/2023.journal'. For more about how to do that on your system,+see Common tasks > Setting LEDGER_FILE.++* Menu:++* Text encoding::+* Data formats::+* Standard input::+* Multiple files::+* Strict mode::+++File: hledger.info, Node: Text encoding, Next: Data formats, Up: Input++2.1 Text encoding+=================++Data files containing non-ascii characters must use UTF-8 encoding. An+optional byte order mark (BOM) is allowed, at the beginning of the file+(only).++ Also, your system should be configured with a locale that can decode+UTF-8 text. On some unix systems, you may need set the 'LANG'+environment variable, eg. You can read more about this in Unicode+characters, below.++ On unix systems you can check a file's encoding with the 'file'+command. If you need to import from a UTF-16-encoded CSV file, say, you+can convert it to UTF-8 with the 'iconv' command.+++File: hledger.info, Node: Data formats, Next: Standard input, Prev: Text encoding, Up: Input++2.2 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: Automatically used for+ files with extensions:+---------------------------------------------------------------------------+'journal' hledger journal files and some '.journal' '.j'+ Ledger journals, for '.hledger' '.ledger'+ transactions+'timeclock' timeclock files, for precise '.timeclock'+ time logging+'timedot' timedot files, for approximate '.timedot'+ time logging+'csv' Comma or other character '.csv'+ separated values, for data+ import+'ssv' Semicolon separated values '.ssv'+'tsv' Tab separated values '.tsv'+'rules' CSV/SSV/TSV/other separated '.rules'+ values, alternate way++ These formats are described in more detail below.++ hledger detects the format automatically based on the file extensions+shown above. If it can't recognise the file extension, it assumes+'journal' format. So for non-journal files, it's important to use a+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 containing+tab separated values:++$ hledger -f tsv:/some/file.dat stats+++File: hledger.info, Node: Standard input, Next: Multiple files, Prev: Data formats, Up: Input++2.3 Standard input+==================++The file name '-' means standard input:++$ cat FILE | hledger -f- print++ If reading non-journal data in this way, you'll need to add a file+format prefix, like:++$ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:-+++File: hledger.info, Node: Multiple files, Next: Strict mode, Prev: Standard input, Up: Input++2.4 Multiple files+==================++You can specify multiple '-f' options, to read multiple files as one big+journal. When doing this, note that certain features (described below)+will be affected:++ * Balance assertions will not see the effect of transactions in+ previous files. (Usually this doesn't matter as each file will set+ the corresponding opening balances.)+ * Some directives will not affect previous or subsequent files.++ If needed, you can work around these by using a single parent file+which includes the others, or concatenating the files into one, eg: 'cat+a.journal b.journal | hledger -f- CMD'.+++File: hledger.info, Node: Strict mode, Prev: Multiple files, Up: Input++2.5 Strict mode+===============++hledger checks input files for valid data. By default, the most+important errors are detected, while still accepting easy journal files+without a lot of declarations:++ * Are the input files parseable, with valid syntax ?+ * Are all transactions balanced ?+ * Do all balance assertions pass ?++ With the '-s'/'--strict' flag, additional checks are performed:++ * Are all accounts posted to, declared with an 'account' directive ?+ (Account error checking)+ * Are all commodities declared with a 'commodity' directive ?+ (Commodity error checking)+ * Are all commodity conversions declared explicitly ?++ You can use the check command to run individual checks - the ones+listed above and some more.+++File: hledger.info, Node: Commands, Next: Options, Prev: Input, Up: Top++3 Commands+**********++hledger provides various subcommands for getting things done. Most of+these commands do not change the journal file; they just read it and+output a report. A few commands assist with adding data and file+management.++ To show the commands list, run 'hledger' with no arguments. The+commands are described in detail in PART 4: COMMANDS, below.++ To use a particular command, run 'hledger CMD [CMDOPTS] [CMDARGS]',++ * CMD is the full command name, or its standard abbreviation shown in+ the commands list, or any unambiguous prefix of the name.++ * CMDOPTS are command-specific options, if any. Command-specific+ options must be written after the command name. Eg: 'hledger print+ -x'.++ * CMDARGS are additional arguments to the command, if any. Most+ hledger commands accept arguments representing a query, to limit+ the data in some way. Eg: 'hledger reg assets:checking'.++ To list a command's options, arguments, and documentation in the+terminal, run 'hledger CMD -h'. Eg: 'hledger bal -h'.++* Menu:++* Add-on commands::+++File: hledger.info, Node: Add-on commands, Up: Commands++3.1 Add-on commands+===================++In addition to the built-in commands, you can install _add-on commands_:+programs or scripts named "hledger-SOMETHING", which will also appear in+hledger's commands list. If you used the hledger-install script, you+will have several add-ons installed already. Some more can be found in+hledger's bin/ directory, documented at+https://hledger.org/scripts.html.++ More precisely, add-on commands are programs or scripts in your+shell's PATH, whose name starts with "hledger-" and ends with no+extension or a recognised extension (".bat", ".com", ".exe", ".hs",+".js", ".lhs", ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"),+and (on unix and mac) which has executable permission for the current+user.++ You can run add-on commands using hledger, much like built-in+commands: 'hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]'. But note+the double hyphen argument, required before add-on-specific options.+Eg: 'hledger ui -- --watch' or 'hledger web -- --serve'. If this causes+difficulty, you can always run the add-on directly, without using+'hledger': 'hledger-ui --watch' or 'hledger-web --serve'.+++File: hledger.info, Node: Options, Next: Command line tips, Prev: Commands, Up: Top++4 Options+*********++Run 'hledger -h' to see general command line help, and general options+which are common to most hledger commands. These options can be written+anywhere on the command line. They can be grouped into help, input, and+reporting options:++* Menu:++* General help options::+* General input options::+* General reporting options::+++File: hledger.info, Node: General help options, Next: General input options, Up: Options++4.1 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)+++File: hledger.info, Node: General input options, Next: General reporting options, Prev: General help options, Up: Options++4.2 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+'--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)+++File: hledger.info, Node: General reporting options, Prev: General input options, Up: Options++4.3 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+ following 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)+'--today=DATE'++ override today's date (affects relative smart dates, for+ tests/examples)+'-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+ commodities+'-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-equity'++ infer conversion equity postings from costs+'--infer-costs'++ infer costs from conversion equity postings+'--infer-market-prices'++ use costs as additional market prices, as if they were P directives+'--forecast'++ generate transactions from periodic rules, between the latest+ recorded txn and 6 months from today, or during the specified+ PERIOD (= is required). Auto posting rules will be applied to+ these transactions as well. Also, in hledger-ui make future-dated+ transactions visible.+'--auto'++ generate extra postings by applying auto posting rules to all txns+ (not just forecast txns)+'--verbose-tags'++ add visible tags indicating transactions or postings which have+ been generated/modified+'--commodity-style'++ Override the commodity style in the output for the specified+ commodity. For example 'EUR1.000,00'.+'--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.+'--pretty[=WHEN]'++ Show prettier output, e.g. using unicode box-drawing characters.+ Accepts 'yes' (the default) or 'no' ('y', 'n', 'always', 'never'+ also work). If you provide an argument you must use '=', e.g.+ '-pretty=yes'.++ 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.+++File: hledger.info, Node: Command line tips, Next: Output, Prev: Options, Up: Top++5 Command line tips+*******************++Here are some details useful to know about for hledger command lines+(and elsewhere). Feel free to skip this section until you need it.++* Menu:++* Option repetition::+* Special characters::+* Unicode characters::+* Regular expressions::+* Argument files::+++File: hledger.info, Node: Option repetition, Next: Special characters, Up: Command line tips++5.1 Option repetition+=====================++If options are repeated in a command line, hledger will generally use+the last (right-most) occurence.+++File: hledger.info, Node: Special characters, Next: Unicode characters, Prev: Option repetition, Up: Command line tips++5.2 Special characters+======================++* Menu:++* Single escaping shell metacharacters::+* Double escaping regular expression metacharacters::+* Triple escaping for add-on commands::+* Less escaping::+++File: hledger.info, Node: Single escaping shell metacharacters, Next: Double escaping regular expression metacharacters, Up: Special characters++5.2.1 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 double 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.+++File: hledger.info, Node: Double escaping regular expression metacharacters, Next: Triple escaping for add-on commands, Prev: Single escaping shell metacharacters, Up: Special characters++5.2.2 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:\\$+++File: hledger.info, Node: Triple escaping for add-on commands, Next: Less escaping, Prev: Double escaping regular expression metacharacters, Up: Special characters++5.2.3 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+arguments intended for by the add-on command, so those need an extra+level of shell-escaping. Eg to match a literal '$' sign while using the+bash shell and running an add-on command ('ui'):++$ hledger ui cur:'\\$'++ or:++$ hledger ui cur:\\\\$++ If you wondered why _four_ backslashes, perhaps this helps:++unescaped: '$'+escaped: '\$'+double-escaped: '\\$'+triple-escaped: '\\\\$'++ Or, you can avoid the extra escaping by running the add-on executable+directly:++$ hledger-ui cur:\\$+++File: hledger.info, Node: Less escaping, Prev: Triple escaping for add-on commands, Up: Special characters++5.2.4 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:++ * an @argumentfile+ * hledger-ui's filter field+ * hledger-web's search form+ * GHCI's prompt (used by developers).+++File: hledger.info, Node: Unicode characters, Next: Regular expressions, Prev: Special characters, Up: Command line tips++5.3 Unicode characters+======================++hledger is expected to handle non-ascii characters correctly:++ * 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.)++ * 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:++ * 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 Troubleshooting. This step is essential - without it, hledger+ will quit on encountering a non-ascii character (as with all+ GHC-compiled programs).++ * your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)+ must support unicode++ * the terminal must be using a font which includes the required+ unicode glyphs++ * the terminal should be configured to display wide characters as+ double width (for report alignment)++ * on Windows, for best results you should run hledger in the same+ kind of environment in which it was built. Eg hledger built in the+ standard CMD.EXE environment (like the binaries on our download+ page) might show display problems when run in a cygwin or msys+ terminal, and vice versa. (See eg #961).+++File: hledger.info, Node: Regular expressions, Next: Argument files, Prev: Unicode characters, Up: Command line tips++5.4 Regular expressions+=======================++A regular expression (regexp) is a small piece of text where certain+characters (like '.', '^', '$', '+', '*', '()', '|', '[]', '\') have+special meanings, forming a tiny language for matching text precisely -+very useful in hledger and elsewhere. To learn all about them, visit+regular-expressions.info.++ hledger supports regexps whenever you are entering a pattern to match+something, eg in query arguments, account aliases, CSV if rules,+hledger-web's search form, hledger-ui's '/' search, etc. You may need+to wrap them in quotes, especially at the command line (see Special+characters above). Here are some examples:++ Account name queries (quoted for command line use):++Regular expression: Matches:+------------------- ------------------------------------------------------------+bank assets:bank, assets:bank:savings, expenses:art:banksy, ...+:bank assets:bank:savings, expenses:art:banksy+:bank: assets:bank:savings+'^bank' none of those ( ^ matches beginning of text )+'bank$' assets:bank ( $ matches end of text )+'big \$ bank' big $ bank ( \ disables following character's special meaning )+'\bbank\b' assets:bank, assets:bank:savings ( \b matches word boundaries )+'(sav|check)ing' saving or checking ( (|) matches either alternative )+'saving|checking' saving or checking ( outer parentheses are not needed )+'savings?' saving or savings ( ? matches 0 or 1 of the preceding thing )+'my +bank' my bank, my bank, ... ( + matches 1 or more of the preceding thing )+'my *bank' mybank, my bank, my bank, ... ( * matches 0 or more of the preceding thing )+'b.nk' bank, bonk, b nk, ... ( . matches any character )++ Some other queries:++desc:'amazon|amzn|audible' Amazon transactions+cur:EUR amounts with commodity symbol containing EUR+cur:'\$' amounts with commodity symbol containing $+cur:'^\$$' only $ amounts, not eg AU$ or CA$+cur:....? amounts with 4-or-more-character symbols+tag:.=202[1-3] things with any tag whose value contains 2021, 2022 or 2023++ Account name aliases: accept '.' instead of ':' as account separator:++alias /\./=: replaces all periods in account names with colons++ Show multiple top-level accounts combined as one:++--alias='/^[^:]+/=combined' ( [^:] matches any character other than : )++ Show accounts with the second-level part removed:++--alias '/^([^:]+):[^:]+/ = \1'+ match a top-level account and a second-level account+ and replace those with just the top-level account+ ( \1 in the replacement text means "whatever was matched+ by the first parenthesised part of the regexp"++ CSV rules: match CSV records containing dining-related MCC codes:++if \?MCC581[124]++ Match CSV records with a specific amount around the end/start of+month:++if %amount \b3\.99+& %date (29|30|31|01|02|03)$++* Menu:++* hledger's regular expressions::+++File: hledger.info, Node: hledger's regular expressions, Up: Regular expressions++5.4.1 hledger's regular expressions+-----------------------------------++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. backreferences are supported when doing text replacement in account+ aliases or CSV rules, where backreferences can be used in the+ replacement string to reference capturing groups in the search+ regexp. Otherwise, if you write '\1', it will match the digit '1'.+ 6. they do not support mode modifiers ('(?s)'), character classes+ ('\w', '\d'), or anything else not mentioned above.++ Some things to note:++ * In the 'alias' directive and '--alias' option, regular expressions+ must be enclosed in forward slashes ('/REGEX/'). Elsewhere in+ hledger, these are not required.++ * 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:\$'.++ * On the command line, some metacharacters like '$' have a special+ meaning to the shell and so must be escaped at least once more.+ See Special characters.+++File: hledger.info, Node: Argument files, Prev: Regular expressions, Up: Command line tips++5.5 Argument files+==================++You can save a set of command line options and arguments in a file, and+then reuse them by writing '@FILENAME' as a command line argument. Eg:+'hledger bal @foo.args'.++ Inside the argument file, each line should contain just one option or+argument. Don't use spaces except inside quotes (or you'll see a+confusing error); write '=' (or nothing) between a flag and its+argument. For the special characters mentioned above, use one less+level of quoting than you would at the command prompt.+++File: hledger.info, Node: Output, Next: Environment, Prev: Command line tips, Up: Top++6 Output+********++* Menu:++* Output destination::+* Output format::+* Commodity styles::+* Colour::+* Box-drawing::+* Paging::+* Debug output::+++File: hledger.info, Node: Output destination, Next: Output format, Up: Output++6.1 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+provide 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)+++File: hledger.info, Node: Output format, Next: Commodity styles, Prev: Output destination, Up: Output++6.2 Output format+=================++Some commands offer other kinds of output, not just text on the+terminal. Here are those commands and the formats currently supported:++- txt csv/tsv html json sql+-------------------------------------------------------------------------------+aregister Y Y Y Y+balance Y _1_ Y _1_ Y _1,2_ Y+balancesheet Y _1_ Y _1_ Y _1_ Y+balancesheetequityY _1_ Y _1_ Y _1_ Y+cashflow Y _1_ Y _1_ Y _1_ Y+incomestatement Y _1_ Y _1_ Y _1_ Y+print Y Y Y Y+register Y Y Y++ * _1 Also affected by the balance commands' '--layout' option._+ * _2 'balance' does not support html output without a report interval+ or with '--budget'._++ The output format is selected by the '-O/--output-format=FMT' option:++$ hledger print -O csv # print CSV on stdout++ or by the filename extension of an output file specified with the+'-o/--output-file=FILE.FMT' option:++$ hledger balancesheet -o foo.csv # write CSV to foo.csv++ The '-O' option can be combined with '-o' to override the file+extension, if needed:++$ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt++ Some notes about the various output formats:++* Menu:++* CSV output::+* HTML output::+* JSON output::+* SQL output::+++File: hledger.info, Node: CSV output, Next: HTML output, Up: Output format++6.2.1 CSV output+----------------++ * In CSV output, digit group marks (such as thousands separators) are+ disabled automatically.+++File: hledger.info, Node: HTML output, Next: JSON output, Prev: CSV output, Up: Output format++6.2.2 HTML output+-----------------++ * HTML output can be styled by an optional 'hledger.css' file in the+ same directory.+++File: hledger.info, Node: JSON output, Next: SQL output, Prev: HTML output, Up: Output format++6.2.3 JSON output+-----------------++ * This is not yet much used; real-world feedback is welcome.++ * Our JSON is rather large and verbose, since it is a faithful+ representation 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.++ * 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)+++File: hledger.info, Node: SQL output, Prev: JSON output, Up: Output format++6.2.4 SQL output+----------------++ * This is not yet much used; real-world feedback is welcome.++ * SQL output is expected to work at least with SQLite, MySQL and+ Postgres.++ * For SQLite, it will be more useful if you modify the generated 'id'+ field to be a PRIMARY KEY. Eg:++ $ hledger print -O sql | sed 's/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g' | ...++ * SQL output is structured with the expectations that statements will+ be executed in the empty database. If you already have tables+ created via SQL output of hledger, you would probably want to+ either clear tables of existing data (via 'delete' or 'truncate'+ SQL statements) or drop tables completely as otherwise your+ postings will be duped.+++File: hledger.info, Node: Commodity styles, Next: Colour, Prev: Output format, Up: Output++6.3 Commodity styles+====================++When displaying amounts, hledger infers a standard display style for+each commodity/currency, as described below in Commodity display style.++ If needed, this can be overridden by a '-c/--commodity-style' option+(except for cost amounts and amounts displayed by the 'print' command,+which are always displayed with all decimal digits). For example, the+following will force dollar amounts to be displayed as shown:++$ hledger print -c '$1.000,0'++ This option can repeated to set the display style for multiple+commodities/currencies. Its argument is as described in the commodity+directive.++ In some cases hledger will adjust number formatting to improve their+parseability (such as adding trailing decimal marks when needed).+++File: hledger.info, Node: Colour, Next: Box-drawing, Prev: Commodity styles, Up: Output++6.4 Colour+==========++In terminal output, some commands can produce colour when the terminal+supports it:++ * if the '--color/--colour' option is given a value of 'yes' or+ 'always' (or 'no' or 'never'), colour will (or will not) be used;+ * otherwise, if the 'NO_COLOR' environment variable is set, colour+ will not be used;+ * otherwise, colour will be used if the output (terminal or file)+ supports it.+++File: hledger.info, Node: Box-drawing, Next: Paging, Prev: Colour, Up: Output++6.5 Box-drawing+===============++In terminal output, you can enable unicode box-drawing characters to+render prettier tables:++ * if the '--pretty' option is given a value of 'yes' or 'always' (or+ 'no' or 'never'), unicode characters will (or will not) be used;+ * otherwise, unicode characters will not be used.+++File: hledger.info, Node: Paging, Next: Debug output, Prev: Box-drawing, Up: Output++6.6 Paging+==========++When showing long output in the terminal, hledger will try to use the+pager specified by the 'PAGER' environment variable, or 'less', or+'more'. (A pager is a helper program that shows one page at a time+rather than scrolling everything off screen). Currently it does this+only for help output, not for reports; specifically,++ * when listing commands, with 'hledger'+ * when showing help with 'hledger [CMD] --help',+ * when viewing manuals with 'hledger help' or 'hledger --man'.++ Note the pager is expected to handle ANSI codes, which hledger uses+eg for bold emphasis. For the common pager 'less' (and its 'more'+compatibility mode), we add 'R' to the 'LESS' and 'MORE' environment+variables to make this work. If you use a different pager, you might+need to configure it similarly, to avoid seeing junk on screen (let us+know). Otherwise, you can set the 'NO_COLOR' environment variable to 1+to disable all ANSI output (see Colour).+++File: hledger.info, Node: Debug output, Prev: Paging, Up: Output++6.7 Debug output+================++We intend hledger to be relatively easy to troubleshoot, introspect and+develop. You can add '--debug[=N]' to any hledger command line to see+additional debug output. N ranges from 1 (least output, the default) to+9 (maximum output). Typically you would start with 1 and increase until+you are seeing enough. Debug output goes to stderr, and is not affected+by '-o/--output-file' (unless you redirect stderr to stdout, eg:+'2>&1'). It will be interleaved with normal output, which can help+reveal when parts of the code are evaluated. To capture debug output in+a log file instead, you can usually redirect stderr, eg:++hledger bal --debug=3 2>hledger.log+++File: hledger.info, Node: Environment, Next: PART 2 DATA FORMATS, Prev: Output, Up: Top++7 Environment+*************++These environment variables affect hledger:++ *COLUMNS* This is normally set by your terminal; some hledger+commands ('register') will format their output to this width. If not+set, they will try to use the available terminal width.++ *LEDGER_FILE* The main journal file to use when not specified with+'-f/--file'. Default: '$HOME/.hledger.journal'.++ *NO_COLOR* If this environment variable is set (with any value),+hledger will not use ANSI color codes in terminal output, unless+overridden by an explicit '--color/--colour' option.+++File: hledger.info, Node: PART 2 DATA FORMATS, Next: Journal, Prev: Environment, Up: Top++8 PART 2: DATA FORMATS+**********************+++File: hledger.info, Node: Journal, Next: CSV, Prev: PART 2 DATA FORMATS, Up: Top++9 Journal+*********++hledger's usual data source is a plain text file containing journal+entries in hledger 'journal' format. If you're looking for a quick+reference, jump ahead to the journal cheatsheet (or use the table of+contents at https://hledger.org/hledger.html).++ This file represents an accounting General Journal. The '.journal'+file extension is most often used, though not strictly 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 compatible with most of Ledger's journal+format, but not all of it. The differences and interoperation tips are+described at hledger and Ledger. With some care, and by avoiding+incompatible features, you can keep your hledger journal readable by+Ledger and vice versa. This can useful eg for comparing the behaviour+of one app against the other.++ 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+configuration at hledger.org for the full list.++ A hledger journal file can contain three kinds of thing: comment+lines, transactions, and/or directives (including periodic transaction+rules and auto posting rules). Understanding the journal file format+will also give you a good understanding of hledger's data model. Here's+a quick cheatsheet/overview, followed by detailed descriptions of each+part.++* Menu:++* Journal cheatsheet::+* Comments::+* Transactions::+* Dates::+* Status::+* Code::+* Description::+* Transaction comments::+* Postings::+* Account names::+* Amounts::+* Balance assertions::+* Posting comments::+* Transaction balancing::+* Tags::+* Directives::+* account directive::+* alias directive::+* commodity directive::+* decimal-mark directive::+* include directive::+* P directive::+* payee directive::+* tag directive::+* Periodic transactions::+* Auto postings::+* Other syntax::+++File: hledger.info, Node: Journal cheatsheet, Next: Comments, Up: Journal++9.1 Journal cheatsheet+======================++# Here is the main syntax of hledger's journal format+# (omitting extra Ledger compatibility syntax).++###############################################################################++# 1. These are comment lines, for notes or temporarily disabling things.+; They begin with # or ;++comment+Or, lines can be enclosed within "comment" / "end comment".+This is a block of +commented lines.+end comment++# Some journal entries can have semicolon comments at end of line ; like this+# Some of them require 2 or more spaces before the semicolon.++###############################################################################++# 2. Directives customise processing or output in some way.+# You don't need any directives to get started.+# But they can add more error checking, or change how things are displayed.+# They begin with a word, letter, or symbol. +# They are most often placed at the top, before transactions.++account assets ; Declare valid account names and display order.+account assets:savings ; A subaccount. This one represents a bank account.+account assets:checking ; Another. Note, 2+ spaces after the account name.+account assets:receivable ; Accounting type is inferred from english names,+account passifs ; or declared with a "type" tag, type:L+account expenses ; type:X+ ; A follow-on comment line, indented.+account expenses:rent ; Expense and revenue categories are also accounts.+ ; Subaccounts inherit their parent's type.++commodity $0.00 ; Declare valid commodities and their display styles.+commodity 1.000,00 EUR++decimal-mark . ; The decimal mark used in this file (if ambiguous).++payee Whole Foods ; Declare a valid payee name.++tag trip ; Declare a valid tag name.++P 2024-03-01 AAPL $179 ; Declare a market price for AAPL in $ on this date.++include other.journal ; Include another journal file here.++# Declare a recurring "periodic transaction", for budget/forecast reports+~ monthly set budget goals ; <- Note, 2+ spaces before the description.+ (expenses:rent) $1000+ (expenses:food) $500++# Declare an auto posting rule, to modify existing transactions in reports+= revenues:consulting+ liabilities:tax:2024:us *0.25 ; Add a tax liability & expense+ expenses:tax:2024:us *-0.25 ; for 25% of the revenue.++###############################################################################++# 3. Transactions are what it's all about.+# They are dated events, usually movements of money between 2 or more accounts.+# They begin with a numeric date.+# Here is their basic shape:+#+# DATE DESCRIPTION ; The transaction's date and optional description.+# ACCOUNT1 AMOUNT ; A posting of an amount to/from this account, indented.+# ACCOUNT2 AMOUNT ; A second posting, balancing the first.+# ... ; More if needed. Amounts must sum to zero.+# ; Note, 2+ spaces between account names and amounts.++2024-01-01 opening balances ; At the start, declare pre-existing balances this way.+ assets:savings $10000 ; Account names can be anything. lower case is easy to type.+ assets:checking $1000 ; assets, liabilities, equity, revenues, expenses are common.+ liabilities:credit card $-500 ; liabilities, equity, revenues balances are usually negative.+ equity:start ; One amount can be left blank. $-10500 is inferred here.+ ; Some of these accounts we didn't declare above,+ ; so -s/--strict would complain.++2024-01-03 ! (12345) pay rent+ ; Additional transaction comment lines, indented.+ ; There can be a ! or * after the date meaning "pending" or "cleared".+ ; There can be a parenthesised (code) after the date/status.+ ; Amounts' sign shows direction of flow.+ assets:checking $-500 ; Minus means removed from this account (credit).+ expenses:rent $500 ; Plus means added to this account (debit).++; Keeping transactions in date order is optional (but helps error checking).++2024-01-02 Gringott's Bank | withdrawal ; Description can be PAYEE | NOTE+ assets:bank:gold -10 gold+ assets:pouch 10 gold++2024-01-02 shopping+ expenses:clothing 1 gold+ expenses:wands 5 gold+ assets:pouch -6 gold++2024-01-02 receive gift+ revenues:gifts -3 "Chocolate Frogs" ; Complex commodity symbols+ assets:pouch 3 "Chocolate Frogs" ; must be in double quotes.++2024-01-15 buy some shares, in two lots ; Cost can be noted.+ assets:investments:2024-01-15 2.0 AAAA @ $1.50 ; @ means per-unit cost+ assets:investments:2024-01-15-02 3.0 AAAA @@ $4 ; @@ means total cost+ ; ^ Per-lot subaccounts are sometimes useful.+ assets:checking $-7++2024-01-15 assert some account balances on this date+ ; Balances can be asserted in any transaction, with =, for extra error checking.+ ; Assertion txns like this one can be made with hledger close --assert --show-costs+ ;+ assets:savings $0 = $10000+ assets:checking $0 = $493+ assets:bank:gold 0 gold = -10 gold+ assets:pouch 0 gold = 4 gold+ assets:pouch 0 "Chocolate Frogs" = 3 "Chocolate Frogs"+ assets:investments:2024-01-15 0.0 AAAA = 2.0 AAAA @ $1.50+ assets:investments:2024-01-15-02 0.0 AAAA = 3.0 AAAA @@ $4+ liabilities:credit card $0 = $-500++2024-02-01 note some event, or a transaction not yet fully entered, on this date+ ; Postings are not required.++; Some other date formats are allowed (but, consistent YYYY-MM-DD is useful).+2024.01.01+2024/1/1+++File: hledger.info, Node: Comments, Next: Transactions, Prev: Journal cheatsheet, Up: Journal++9.2 Comments+============++Lines in the journal will be ignored if they begin with a hash ('#') or+a semicolon (';'). (See also Other syntax.) hledger will also ignore+regions beginning with a 'comment' line and ending with an 'end comment'+line (or file end). Here's a suggestion for choosing between them:++ * '#' for top-level notes+ * ';' for commenting out things temporarily+ * 'comment' for quickly commenting large regions (remember it's+ there, or you might get confused)++ Eg:++# a comment line+; another commentline+comment+A multi-line comment block,+continuing until "end comment" directive+or the end of the current file.+end comment++ Some hledger entries can have same-line comments attached to them,+from ; (semicolon) to end of line. See Transaction comments, Posting+comments, and Account comments below.+++File: hledger.info, Node: Transactions, Next: Dates, Prev: Comments, Up: Journal++9.3 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+simple date in column 0. This can be followed by any of the following+optional fields, separated by spaces:++ * a status character (empty, '!', or '*')+ * a code (any short number or text, enclosed in parentheses)+ * a description (any remaining text until end of line or a semicolon)+ * a comment (any remaining text following a semicolon until end of+ line, and any following indented lines beginning with a semicolon)+ * 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+++File: hledger.info, Node: Dates, Next: Status, Prev: Transactions, Up: Journal++9.4 Dates+=========++* Menu:++* Simple dates::+* Posting dates::+++File: hledger.info, Node: Simple dates, Next: Posting dates, Up: Dates++9.4.1 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+current transaction, the default year set with a 'Y' 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.)+++File: hledger.info, Node: Posting dates, Prev: Simple dates, Up: Dates++9.4.2 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.+The 'date:' tag must have a valid simple date value if it is present, eg+a 'date:' tag with no value is not allowed.+++File: hledger.info, Node: Status, Next: Code, Prev: Dates, Up: Journal++9.5 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 (and you can combine these, eg+'-UP' to match all except cleared things). Or you can use the+'status:', 'status:!', and 'status:*' queries, or the U, P, C keys in+hledger-ui.++ (Note: in Ledger the "unmarked" state is called "uncleared"; in+hledger we renamed it to "unmarked" for semantic clarity.)++ Status marks are optional, but can be helpful eg for reconciling with+real-world accounts. Some editor modes provide highlighting and+shortcuts for working with status. Eg in Emacs ledger-mode, you can+toggle transaction status with C-c C-e, or posting status with C-c C-c.++ 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+ reconciliation)+cleared complete, reconciled as far as possible, and considered+ correct++ 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.+++File: hledger.info, Node: Code, Next: Description, Prev: Status, Up: Journal++9.6 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.+++File: hledger.info, Node: Description, Next: Transaction comments, Prev: Code, Up: Journal++9.7 Description+===============++After the date, status mark and/or code fields, the rest of the line (or+until a comment is begun with ';') is the transaction's description.+Here you can describe the transaction (called the "narration" in+traditional bookkeeping), or you can record a payee/payer name, or you+can leave it empty.++ Transaction descriptions show up in print output and in register+reports, and can be listed with the descriptions command.++ You can query by description with 'desc:DESCREGEX', or pivot on+description with '--pivot desc'.++* Menu:++* Payee and note::+++File: hledger.info, Node: Payee and note, Up: Description++9.7.1 Payee and note+--------------------++Sometimes people want a dedicated payee/payer field that can be queried+and checked more strictly. If you want that, you can write a '|' (pipe)+character in the description. This divides it into a "payee" field on+the left, and a "note" field on the right. (Either can be empty.)++ You can query these with 'payee:PAYEEREGEX' and 'note:NOTEREGEX',+list their values with the payees and notes commands, or pivot on+'payee' or 'note'.++ Note: in transactions with no '|' character, description, payee, and+note all have the same value. Once a '|' is added, they become+distinct. (If you'd like to change this behaviour, please propose it on+the mail list.)++ If you want more strict error checking, you can declare the valid+payee names with payee directives, and then enforce these with hledger+check payees. (Note: because of the above, for this you'll need to+ensure every transaction description contains a '|' and therefore a+checkable payee name, even if it's empty.)+++File: hledger.info, Node: Transaction comments, Next: Postings, Prev: Description, Up: Journal++9.8 Transaction comments+========================++Text following ';', after a transaction description, and/or on indented+lines immediately below it, form comments for that transaction. They+are reproduced by 'print' but otherwise ignored, except they may contain+tags, which are not ignored.++2012-01-01 something ; a transaction comment+ ; a second line of transaction comment+ expenses 1+ assets+++File: hledger.info, Node: Postings, Next: Account names, Prev: Transaction comments, Up: Journal++9.9 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:++ * (optional) a status character (empty, '!', or '*'), followed by a+ space+ * (required) an account name (any text, optionally containing *single+ spaces*, until end of line or a double space)+ * (optional) *two or more spaces* (or tabs) followed by an amount.++ If the amount is positive, it is being added to the account; if+negative, it is being removed from the account.++ The posting amounts in a transaction must sum up to zero, indicating+that the inflows and outflows are equal. We call this a balanced+transaction. (You can read more about the nitty-gritty details of "sum+up to zero" in Transaction balancing below.)++ As a convenience, you can optionally leave one amount blank; hledger+will infer what it should be so as to balance the transaction.++* Menu:++* Debits and credits::+* The two space delimiter::+++File: hledger.info, Node: Debits and credits, Next: The two space delimiter, Up: Postings++9.9.1 Debits and credits+------------------------++The traditional accounting concepts of debit and credit of course exist+in hledger, but we represent them with numeric sign, as described above.+Positive and negative posting amounts represent debits and credits+respectively.++ You don't need to remember that, but if you would like to - eg for+helping newcomers or for talking with your accountant - here's a handy+mnemonic:++ _'debit / plus / left / short words'_+_'credit / minus / right / longer words'_+++File: hledger.info, Node: The two space delimiter, Prev: Debits and credits, Up: Postings++9.9.2 The two space delimiter+-----------------------------++Be sure to notice the unusual separator between the account name and the+following amount. Because hledger allows account names with spaces in+them, you must separate the account name and amount (if any) by *two or+more spaces* (or tabs). It's easy to forget at first. If you ever see+the amount being treated as part of the account name, you'll know you+probably need to add another space between them.+++File: hledger.info, Node: Account names, Next: Amounts, Prev: Postings, Up: Journal++9.10 Account names+==================++Accounts are the main way of categorising things in hledger. As in+Double Entry Bookkeeping, they can represent real world accounts (such+as a bank account), or more abstract categories such as "money borrowed+from Frank" or "money spent on electricity".++ You can use any account names you like, but we usually start with the+traditional accounting categories, which in english are 'assets',+'liabilities', 'equity', 'revenues', 'expenses'. (You might see these+referred to as A, L, E, R, X for short.)++ For more precise reporting, we usually divide the top level accounts+into more detailed subaccounts, by writing a full colon between account+name parts. For example, from the account names 'assets:bank:checking'+and 'expenses:food', hledger will infer this hierarchy of five accounts:++assets+assets:bank+assets:bank:checking+expenses+expenses:food++ Shown as an outline, the hierarchical tree structure is more clear:++assets+ bank+ checking+expenses+ food++ hledger reports can summarise the account tree to any depth, so you+can go as deep as you like with subcategories, but keeping your account+names relatively simple may be best when starting out.++ Account names may be capitalised or not; they may contain letters,+numbers, symbols, or single spaces. Note, when an account name and an+amount are written on the same line, they must be separated by *two or+more spaces* (or tabs).++ Parentheses or brackets enclosing the full account name indicate+virtual postings, described below. Parentheses or brackets internal to+the account name have no special meaning.++ Account names can be altered temporarily or permanently by account+aliases.+++File: hledger.info, Node: Amounts, Next: Balance assertions, Prev: Account names, Up: Journal++9.11 Amounts+============++After the account name, there is usually an amount. (Remember: 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+"quantity"):++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+commodity 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++* Menu:++* Decimal marks::+* Digit group marks::+* Commodity::+* Costs::+++File: hledger.info, Node: Decimal marks, Next: Digit group marks, Up: Amounts++9.11.1 Decimal marks+--------------------++A _decimal mark_ can be written as a period or a comma:++1.23+1,23++ Both of these are common in international number formats, so hledger+is not biased towards one or the other. Because hledger also supports+digit group marks (eg thousands separators), this means that a number+like '1,000' or '1.000' containing just one period or comma is+ambiguous. In such cases, hledger by default assumes it is a decimal+mark, and will parse both of those as 1.++ To help hledger parse such ambiguous numbers more accurately, if you+use digit group marks, we recommend declaring the decimal mark+explicitly. The best way is to add a 'decimal-mark' directive at the+top of each data file, like this:++decimal-mark .++ Or you can declare it per commodity with 'commodity' directives,+described below.++ hledger also accepts numbers like '10.' with no digits after the+decimal mark (and will sometimes display numbers that way to+disambiguate them - see Trailing decimal marks).+++File: hledger.info, Node: Digit group marks, Next: Commodity, Prev: Decimal marks, Up: Amounts++9.11.2 Digit group marks+------------------------++In the integer part of the amount quantity (left of the decimal mark),+groups of digits can optionally be separated by a _digit group mark_ - a+comma or period (whichever is not used as decimal mark), or a space+(several Unicode space variants, like no-break space, are also+accepted). So these are all valid amounts in a journal file:++ $1,000,000.00+ EUR 2.000.000,00+INR 9,99,99,999.00+ 1 000 000.00 ; <- ordinary space + 1 000 000.00 ; <- no-break space+++File: hledger.info, Node: Commodity, Next: Costs, Prev: Digit group marks, Up: Amounts++9.11.3 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+punctuation), 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.++ By default, the format of amounts in the journal influences how+hledger displays them in output. This is explained in Commodity display+style below.+++File: hledger.info, Node: Costs, Prev: Commodity, Up: Amounts++9.11.4 Costs+------------++After a posting amount, you can note its cost (when buying) or selling+price (when selling) in another commodity, by writing either '@+UNITPRICE' or '@@ TOTALPRICE' after it. This indicates a conversion+transaction, where one commodity is exchanged for another.++ (You might also see this called "transaction price" in hledger docs,+discussions, or code; that term was directionally neutral and reminded+that it is a price specific to a transaction, but we now just call it+"cost", with the understanding that the transaction could be a purchase+or a sale.)++ Costs are usually written explicitly with '@' or '@@', but can also+be inferred automatically for simple multi-commodity transactions.+Note, if costs are inferred, the order of postings is significant; the+first posting will have a cost attached, in the commodity of the second.++ As an example, here are several ways to record purchases of a foreign+currency in hledger, using the cost notation either explicitly or+implicitly:++ 1. Write the price per unit, as '@ UNITPRICE' after the amount:++ 2009/1/1+ assets:euros €100 @ $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 €100 @@ $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.+ Note the effect of posting order: the price is added to first+ posting, making it '€100 @@ $135', as in example 2:++ 2009/1/1+ assets:euros €100 ; one hundred euros purchased+ assets:dollars $-135 ; for $135++ Amounts can be converted to cost at report time using the '-B/--cost'+flag; this is discussed more in the Cost reporting section.++ Note that the cost normally should be a positive amount, though it's+not required to be. This can be a little confusing, see discussion at+-infer-market-prices: market prices from transactions.+++File: hledger.info, Node: Balance assertions, Next: Posting comments, Prev: Amounts, Up: Journal++9.12 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 protect 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, described below).++* Menu:++* Assertions and ordering::+* Assertions and multiple included files::+* Assertions and multiple -f files::+* Assertions and costs::+* Assertions and commodities::+* Assertions and subaccounts::+* Assertions and virtual postings::+* Assertions and auto postings::+* Assertions and precision::+++File: hledger.info, Node: Assertions and ordering, Next: Assertions and multiple included files, Up: Balance assertions++9.12.1 Assertions and ordering+------------------------------++hledger calculates and checks an account's balance assertions in date+order (and when there are multiple assertions on the same day, in parse+order). Note this is different from Ledger, which checks assertions+always in parse order, ignoring dates.++ This means in hledger you can freely reorder transactions, postings,+or files, and balance assertions will usually keep working. The+exception is when you reorder multiple postings on the same day, to the+same account, which have balance assertions; those will likely need+updating.+++File: hledger.info, Node: Assertions and multiple included files, Next: Assertions and multiple -f files, Prev: Assertions and ordering, Up: Balance assertions++9.12.2 Assertions and multiple included files+---------------------------------------------++Multiple files included with the 'include' directive are processed as if+concatenated into one file, preserving their order and the posting order+within each file. It means that balance assertions in later files will+see balance from earlier files.++ And if you have multiple postings to an account on the same day,+split across multiple files, and you want to assert the account's+balance on that day, you'll need to put the assertion in the right file+- the last one in the sequence, probably.+++File: hledger.info, Node: Assertions and multiple -f files, Next: Assertions and costs, Prev: Assertions and multiple included files, Up: Balance assertions++9.12.3 Assertions and multiple -f files+---------------------------------------++Unlike 'include', when multiple files are specified on the command line+with multiple '-f/--file' options, balance assertions will not see+balance from earlier files. This can be useful when you do not want+problems in earlier files to disrupt valid assertions in later files.++ If you do want assertions to see balance from earlier files, use+'include', or concatenate the files temporarily.+++File: hledger.info, Node: Assertions and costs, Next: Assertions and commodities, Prev: Assertions and multiple -f files, Up: Balance assertions++9.12.4 Assertions and costs+---------------------------++Balance assertions ignore costs, and should normally be written without+one:++2019/1/1+ (a) $1 @ €1 = $1++ We do allow costs to be written in balance assertion amounts,+however, and print shows them, but 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+costs), and because balance _assignments_ do use costs (see below).+++File: hledger.info, Node: Assertions and commodities, Next: Assertions and subaccounts, Prev: Assertions and costs, Up: Balance assertions++9.12.5 Assertions and commodities+---------------------------------++The balance assertions described so far are "*single commodity balance+assertions*": they assert and check the balance in one commodity,+ignoring any others that may be present. This is how balance assertions+work in Ledger also.++ If an account contains multiple commodities, you can assert their+balances by writing multiple postings with balance assertions, one for+each commodity:++2013/1/1+ usd $-1+ eur €-1+ both++2013/1/2+ both 0 = $1+ both 0 = €1++ In hledger you can make a stronger "*sole commodity balance+assertion*" by writing two equals signs ('== EXPECTEDBALANCE'). This+also asserts that there are no other commodities in the account besides+the asserted one (or at least, that their current balance is zero):++2013/1/1+ usd $-1 == $-1 ; these sole commodity assertions succeed+ eur €-1 == €-1+ both ;== $1 ; this one would fail because 'both' contains $ and €++ It's less easy to make a "*sole commodities balance assertion*" (note+the plural) - ie, asserting that an account contains two or more+specified commodities and no others. It can be done by++ 1. isolating each commodity in a subaccount, and asserting those+ 2. and also asserting there are no commodities in the parent account+ itself:++2013/1/1+ usd $-1+ eur €-1+ both 0 == 0 ; nothing up my sleeve+ both:usd $1 == $1 ; a dollar here+ both:eur €1 == €1 ; a euro there+++File: hledger.info, Node: Assertions and subaccounts, Next: Assertions and virtual postings, Prev: Assertions and commodities, Up: Balance assertions++9.12.6 Assertions and subaccounts+---------------------------------++All of the balance assertions above (both '=' and '==') are+"*subaccount-exclusive balance assertions*"; they ignore any balances+that exist in deeper subaccounts.++ In hledger you can make "*subaccount-inclusive balance assertions*"+by adding a star after the equals ('=*' or '==*'):++2019/1/1+ equity:start+ assets:checking $10+ assets:savings $10+ assets $0 ==* $20 ; assets + subaccounts contains $20 and nothing else+++File: hledger.info, Node: Assertions and virtual postings, Next: Assertions and auto postings, Prev: Assertions and subaccounts, Up: Balance assertions++9.12.7 Assertions and virtual postings+--------------------------------------++Balance assertions always consider both real and virtual postings; they+are not affected by the '--real/-R' flag or 'real:' query.+++File: hledger.info, Node: Assertions and auto postings, Next: Assertions and precision, Prev: Assertions and virtual postings, Up: Balance assertions++9.12.8 Assertions and auto postings+-----------------------------------++Balance assertions _are_ affected by the '--auto' flag, which generates+auto postings, which can alter account balances. Because auto postings+are optional in hledger, accounts affected by them effectively have two+balances. But balance assertions can only test one or the other of+these. So to avoid making fragile assertions, either:++ * assert the balance calculated with '--auto', and always use+ '--auto' with that file+ * or assert the balance calculated without '--auto', and never use+ '--auto' with that file+ * or avoid balance assertions on accounts affected by auto postings+ (or avoid auto postings entirely).+++File: hledger.info, Node: Assertions and precision, Prev: Assertions and auto postings, Up: Balance assertions++9.12.9 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 assertions. Balance+assertion failure messages show exact amounts.+++File: hledger.info, Node: Posting comments, Next: Transaction balancing, Prev: Balance assertions, Up: Journal++9.13 Posting comments+=====================++Text following ';', at the end of a posting line, and/or on indented+lines immediately below it, form comments for that posting. They are+reproduced by 'print' but otherwise ignored, except they may contain+tags, which are not ignored.++2012-01-01+ expenses 1 ; a comment for posting 1+ assets+ ; a comment for posting 2+ ; a second comment line for posting 2+++File: hledger.info, Node: Transaction balancing, Next: Tags, Prev: Posting comments, Up: Journal++9.14 Transaction balancing+==========================++How exactly does hledger decide when a transaction is balanced ? The+general goal is that if you look at the journal entry and calculate the+amounts' sum perfectly with pencil and paper, hledger should agree with+you.++ Real world transactions, especially for investments or+cryptocurrencies, often involve imprecise costs, complex decimals,+and/or infinitely-recurring decimals, which are difficult or+inconvenient to handle on a computer. So to be a practical accounting+system, hledger allows some imprecision when checking transaction+balancedness. The question is, how much imprecision should be allowed ?++ hledger currently decides it based on the commodity display styles:+if the postings' sum would appear to be zero when displayed with the+standard display precisions, the transaction is considered balanced.++ Or equivalently: if the journal entry is displayed with amounts+rounded to the standard display precisions (with 'hledger print+--round=hard'), and a human with pencil and paper would agree that those+displayed amounts add up to zero, the transaction is considered+balanced.++ This has some advantages: it is fairly intuitive, general not+hard-coded, yet configurable when needed. On the downside it means that+transaction balancedness is related to commodity display precisions, so+eg when using '-c/--commodity-style' to display things with more than+usual precision, you might need to fix some of your journal entries (ie,+add decimal digits to make them balance more precisely).++ Other PTA tools (Ledger, Beancount..) have their own ways of doing+it. Possible improvements are discussed at #1964.++ Note: if you have multiple journal files, and are relying on+commodity directives to make imprecise journal entries balance, the+directives' placement might be important - see 'commodity' directive.+++File: hledger.info, Node: Tags, Next: Directives, Prev: Transaction balancing, Up: Journal++9.15 Tags+=========++Tags are a way to add extra labels or data fields to transactions,+postings, or accounts, which you can then search or pivot on.++ A tag is a word, optionally hyphenated, immediately followed by a+full colon, in the comment of a transaction, a posting, or an account+directive. Eg: '2024-01-01 a transaction ; foo:' Note this is an+exception to the usual rule that things in comments are ignored.++ You can write multiple tags on one line, separated by comma. Or you+can write each tag on its own comment line (no comma needed in this+case).++ For example, here are five different tags: one on the+'assets:checking' account, two on the transaction, and two on the+'expenses:food' posting:++account assets:checking ; accounttag:++2017/1/16 bought groceries ; transactiontag-1:+ ; transactiontag-2:+ assets:checking $-1+ expenses:food $1 ; postingtag:, another-posting-tag:++ Postings also inherit tags from their transaction and their account.+And transactions also acquire tags from their postings (and postings'+accounts). So in the example above, the expenses posting effectively+has all five tags (by inheriting from the account and transaction), and+the transaction also has all five tags (by acquiring from the expenses+posting).++* Menu:++* Tag names::+* Special tags::+* Tag values::+++File: hledger.info, Node: Tag names, Next: Special tags, Up: Tags++9.15.1 Tag names+----------------++Most non-whitespace characters are allowed in tag names. Eg '😀:' is a+valid tag.++ You can list the tag names used in your journal with the tags+command:+'hledger tags [NAMEREGEX]'++ In commands which use a query, you can match by tag name. Eg:+'hledger print tag:NAMEREGEX'++ You can declare valid tag names with the tag directive and then check+them with the check command.+++File: hledger.info, Node: Special tags, Next: Tag values, Prev: Tag names, Up: Tags++9.15.2 Special tags+-------------------++Some tag names have special significance to hledger. There's not much+harm in using them yourself, but some could produce an error message,+particularly the 'date:' and 'type:' tags. They are explained+elsewhere, but here is a quick list for reference:++ Tags you can set to influence hledger's behaviour:++ date -- overrides a posting's date+ date2 -- overrides a posting's secondary date+ type -- declares an account's type++ Tags hledger adds to indicate generated data:++ t -- appears on postings generated by timedot letters+ assert -- appears on txns generated by close --assert+ retain -- appears on txns generated by close --retain+ start -- appears on txns generated by close --migrate/--close/--open/--assign+ generated-transaction -- appears on generated periodic txns (with --verbose-tags)+ generated-posting -- appears on generated auto postings (with --verbose-tags)+ modified -- appears on txns which have had auto postings added (with --verbose-tags)+Not displayed, but queryable:+ _generated-transaction -- exists on generated periodic txns (always)+ _generated-posting -- exists on generated auto postings (always)+ _modified -- exists on txns which have had auto postings added (always)++ Tags hledger uses internally:++ _conversion-matched -- exists on postings which have been matched with a nearby @/@@ cost annotation+++File: hledger.info, Node: Tag values, Prev: Special tags, Up: Tags++9.15.3 Tag values+-----------------++Tags can have a value, which is any text after the colon up until a+comma or end of line, with surrounding whitespace removed. Ending at+comma allows us to write multiple tags on one line, but also means that+tag values can not contain commas.++ Eg in the following posting, the three tags' values are "value 1",+"value 2", and "" (empty) respectively:++ expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz++ Multiple tags with the same name are additive rather than overriding:+when the same tag name is seen again with a new value, the new+name:value pair is added to the tags. It is not possible to override a+previous tag's value or remove a tag.++ You can list all the values used for a particular tag in the journal+with+'hledger tags TAGNAME --values'++ You can match on tag values with a query like+'tag:NAMEREGEX=VALUEREGEX'+++File: hledger.info, Node: Directives, Next: account directive, Prev: Tags, Up: Journal++9.16 Directives+===============++Besides transactions, there is something else you can put in a 'journal'+file: directives. These are declarations, beginning with a keyword,+that modify hledger's behaviour. Some directives can have more specific+subdirectives, indented below them. hledger's directives are similar to+Ledger's in many cases, but there are also many differences. Directives+are not required, but can be useful. Here are the main directives:++purpose directive+--------------------------------------------------------------------------+*READING DATA:*+Rewrite account names 'alias'+Comment out sections of the file 'comment'+Declare file's decimal mark, to help 'decimal-mark'+parse amounts accurately+Include other data files 'include'+*GENERATING DATA:*+Generate recurring transactions or '~'+budget goals+Generate extra postings on existing '='+transactions+*CHECKING FOR ERRORS:*+Define valid entities to provide more 'account', 'commodity',+error checking 'payee', 'tag'+*REPORTING:*+Declare accounts' type and display 'account'+order+Declare commodity display styles 'commodity'+Declare market prices 'P'++* Menu:++* Directives and multiple files::+* Directive effects::+++File: hledger.info, Node: Directives and multiple files, Next: Directive effects, Up: Directives++9.16.1 Directives and multiple files+------------------------------------++Directives vary in their scope, ie which journal entries and which input+files they affect. Most often, a directive will affect the following+entries and included files if any, until the end of the current file -+and no further. You might find this inconvenient! For example, 'alias'+directives do not affect parent or sibling files. But there are usually+workarounds; for example, put 'alias' directives in your top-most file,+before including other files.++ The restriction, though it may be annoying at first, is in a good+cause; it allows reports to be stable and deterministic, independent of+the order of input. Without it, reports could show different numbers+depending on the order of -f options, or the positions of include+directives in your files.+++File: hledger.info, Node: Directive effects, Prev: Directives and multiple files, Up: Directives++9.16.2 Directive effects+------------------------++Here are all hledger's directives, with their effects and scope+summarised - nine main directives, plus four others which we consider+non-essential:++directivewhat it does ends+ at+ file+ end?+---------------------------------------------------------------------------+*'account'*Declares an account, for checking all entries in all files; andN+ its display order and type. Subdirectives: any text, ignored.+*'alias'*Rewrites account names, in following entries until end of Y+ current file or 'end aliases'. Command line equivalent:+ '--alias'+*'comment'*Ignores part of the journal file, until end of current file orY+ 'end comment'.+*'commodity'*Declares up to four things: 1. a commodity symbol, for checkingN,N,Y,Y+ all amounts in all files 2. the display style for all amounts+ of this commodity 3. the decimal mark for parsing amounts of+ this commodity, in the rest of this file and its children, if+ there is no 'decimal-mark' directive 4. the precision to use+ for balanced-transaction checking in this commodity, in this+ file and its children. Takes precedence over 'D'.+ Subdirectives: 'format' (ignored). Command line equivalent:+ '-c/--commodity-style'+*'decimal-mark'*Declares the decimal mark, for parsing amounts of all Y+ commodities in following entries until next 'decimal-mark' or+ end of current file. Included files can override. Takes+ precedence over 'commodity' and 'D'.+*'include'*Includes entries and directives from another file, as if theyN+ were written inline. Command line alternative: multiple+ '-f/--file'+*'payee'*Declares a payee name, for checking all entries in all files. N+*'P'*Declares the market price of a commodity on some date, for value N+ reports.+*'~'*Declares a periodic transaction rule that generates future N+(tilde)transactions with '--forecast' and budget goals with 'balance+ --budget'.+Other+syntax:+*'applyPrepends a common parent account to all account names, in Y+account'*following entries until end of current file or 'end apply+ account'.+*'D'*Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N+ there is no 'commodity' directive for this commodity: its+ decimal mark, balancing precision, and display style, as above.+*'Y'*Sets a default year to use for any yearless dates, in following Y+ entries until end of current file.+*'='*Declares an auto posting rule that generates extra postings on partly+(equals)matched transactions with '--auto', in current, parent, and+ child files (but not sibling files, see #1212).+*OtherOther directives from Ledger's file format are accepted but+Ledgerignored.+directives*+++File: hledger.info, Node: account directive, Next: alias directive, Prev: Directives, Up: Journal++9.17 'account' directive+========================++'account' directives can be used to declare accounts (ie, the places+that amounts are transferred from and to). Though not required, these+declarations can provide several benefits:++ * They can document your intended chart of accounts, providing a+ reference.+ * They can store additional account information as comments, or as+ tags which can be used to filter or pivot reports.+ * They can restrict which accounts may be posted to by transactions,+ eg in strict mode, which helps prevent errors.+ * They influence account display order in reports, allowing+ non-alphabetic sorting (eg Revenues to appear above Expenses).+ * They can help hledger know your accounts' types (asset, liability,+ equity, revenue, expense), enabling reports like balancesheet and+ incomestatement.+ * They help with account name completion (in hledger add,+ hledger-web, hledger-iadd, ledger-mode, etc.)++ They are written as the word 'account' followed by a hledger-style+account name. Eg:++account assets:bank:checking++ Ledger-style indented subdirectives are also accepted, but ignored:++account assets:bank:checking+ format subdirective ; currently ignored++* Menu:++* Account comments::+* Account error checking::+* Account display order::+* Account types::+++File: hledger.info, Node: Account comments, Next: Account error checking, Up: account directive++9.17.1 Account comments+-----------------------++Text following *two or more spaces* and ';' at the end of an account+directive line, and/or following ';' on indented lines immediately below+it, form comments for that account. They are ignored except they may+contain tags, which are not ignored.++ The two-space requirement for same-line account comments is because+';' is allowed in account names.++account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon+ ; next-line comment+ ; some tags - type:A, acctnum:12345+++File: hledger.info, Node: Account error checking, Next: Account display order, Prev: Account comments, Up: account directive++9.17.2 Account error checking+-----------------------------++By default, accounts need not be declared; they come into existence when+a posting references them. This is convenient, but it means hledger+can't warn you when you mis-spell an account name in the journal.+Usually you'll find that error later, as an extra account in balance+reports, or an incorrect 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:++ * The declaration is case-sensitive; transactions must use the+ correct account name capitalisation.+ * The account directive's scope is "whole file and below" (see+ directives). This means it affects all of the current file, and+ any files it includes, but not parent or sibling files. The+ position of account directives within the file does not matter,+ though it's usual to put them at the top.+ * Accounts can only be declared in 'journal' files, but will affect+ included files of all types.+ * It's currently not possible to declare "all possible subaccounts"+ with a wildcard; every account posted to must be declared.+++File: hledger.info, Node: Account display order, Next: Account types, Prev: Account error checking, Up: account directive++9.17.3 Account display order+----------------------------++Account directives also cause hledger to display accounts in a+particular order, not just alphabetically. Eg, here is a conventional+ordering for the top-level accounts:++account assets+account liabilities+account equity+account revenues+account expenses++ Now hledger displays them in that order:++$ hledger accounts+assets+liabilities+equity+revenues+expenses++ If there are undeclared accounts, those will be displayed last, in+alphabetical order.++ Sorting is done within each group of sibling accounts, at each level+of the account tree. Eg, a declaration like 'account parent:child'+influences 'child''s position among its siblings.++ Note, it does not affect 'parent''s position; for that, you need an+'account parent' declaration.++ Sibling accounts are always displayed together; hledger won't display+'x:y' in between 'a:b' and 'a:c'.++ An account directive both declares an account as a valid posting+target, and declares its display order; you can't easily do one without+the other.+++File: hledger.info, Node: Account types, Prev: Account display order, Up: account directive++9.17.4 Account types+--------------------++hledger knows that accounts come in several types: assets, liabilities,+expenses and so on. This enables easy reports like balancesheet and+incomestatement, and filtering by account type with the 'type:' query.++ As a convenience, hledger will detect these account types+automatically if you are using common english-language top-level account+names (described below). But it's more robust to declare accounts'+types explicitly, by adding 'type:' tags to their account directives.+The tag's value should be one of the five main account types:++ * 'A' or 'Asset' (things you own)+ * 'L' or 'Liability' (things you owe)+ * 'E' or 'Equity' (investment/ownership; balanced counterpart of+ assets & liabilities)+ * 'R' or 'Revenue' (what you received money from, AKA income;+ technically part of Equity)+ * 'X' or 'Expense' (what you spend money on; technically part of+ Equity)++ or, it can be (these are used less often):++ * 'C' or 'Cash' (a subtype of Asset, indicating liquid assets for the+ cashflow report)+ * 'V' or 'Conversion' (a subtype of Equity, for conversions (see Cost+ reporting).)++ Subaccounts inherit their parent's type, or they can override it.+Here is a typical set of account type declarations:++account assets ; type: A+account liabilities ; type: L+account equity ; type: E+account revenues ; type: R+account expenses ; type: X++account assets:bank ; type: C+account assets:cash ; type: C++account equity:conversion ; type: V++ Here are some tips for working with account types.++ * The rules for inferring types from account names are as follows.+ These are just a convenience that sometimes help new users get+ going; if they don't work for you, just ignore them and declare+ your account types. See also Regular expressions.++ If account's name contains this (CI) regular expression: | its type is:+ --------------------------------------------------------------------|-------------+ ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash+ ^assets?(:|$) | Asset+ ^(debts?|liabilit(y|ies))(:|$) | Liability+ ^equity:(trad(e|ing)|conversion)s?(:|$) | Conversion+ ^equity(:|$) | Equity+ ^(income|revenue)s?(:|$) | Revenue+ ^expenses?(:|$) | Expense++ * If you declare any account types, it's a good idea to declare an+ account for all of the account types, because a mixture of declared+ and name-inferred types can disrupt certain reports.++ * Certain uses of account aliases can disrupt account types. See+ Rewriting accounts > Aliases and account types.++ * As mentioned above, subaccounts will inherit a type from their+ parent account. More precisely, an account's type is decided by+ the first of these that exists:++ 1. A 'type:' declaration for this account.+ 2. A 'type:' declaration in the parent accounts above it,+ preferring the nearest.+ 3. An account type inferred from this account's name.+ 4. An account type inferred from a parent account's name,+ preferring the nearest parent.+ 5. Otherwise, it will have no type.++ * For troubleshooting, you can list accounts and their types with:++ $ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]+++File: hledger.info, Node: alias directive, Next: commodity directive, Prev: account directive, Up: Journal++9.18 'alias' directive+======================++You can define account alias rules which rewrite your account names, or+parts of them, before generating reports. This can be useful for:++ * expanding shorthand account names to their full form, allowing+ easier data entry and a less verbose journal+ * adapting old journals to your current chart of accounts+ * experimenting with new account organisations, like a new hierarchy+ * combining two accounts into one, eg to see their sum or difference+ on one line+ * 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.++ Account aliases are very powerful. They are generally easy to use+correctly, but you can also generate invalid account names with them;+more on this below.++ See also Rewrite account names.++* Menu:++* Basic aliases::+* Regex aliases::+* Combining aliases::+* Aliases and multiple files::+* end aliases directive::+* Aliases can generate bad account names::+* Aliases and account types::+++File: hledger.info, Node: Basic aliases, Next: Regex aliases, Up: alias directive++9.18.1 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.+Subaccounts 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"+++File: hledger.info, Node: Regex aliases, Next: Combining aliases, Prev: Basic aliases, Up: alias directive++9.18.2 Regex aliases+--------------------++There is also a more powerful variant that uses a regular expression,+indicated by wrapping the pattern in forward slashes. (This is the only+place where hledger requires forward slashes around a regular+expression.)++ Eg:++alias /REGEX/ = REPLACEMENT++ or:++$ hledger --alias '/REGEX/=REPLACEMENT' ...++ Any part of an account name matched by REGEX will be replaced by+REPLACEMENT. REGEX is case-insensitive as usual.++ If you need to match a forward slash, escape it with a backslash, eg+'/\/=:'.++ If REGEX contains parenthesised match groups, these can be referenced+by the usual backslash and number in REPLACEMENT:++alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3+; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"++ REPLACEMENT continues to the end of line (or on command line, to end+of option argument), so it can contain trailing whitespace.+++File: hledger.info, Node: Combining aliases, Next: Aliases and multiple files, Prev: Regex aliases, Up: alias directive++9.18.3 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:++ * the nearest alias declaration before/above the entry is applied+ first+ * the next alias before/above that will be be applied next, and so on+ * aliases defined after/below the entry do not affect it.++ This gives nearby aliases precedence over distant ones, and helps+provide semantic stability - aliases will keep working the same way+independent of which files are being read and in which order.++ In case of trouble, adding '--debug=6' to the command line will show+which aliases are being applied when.+++File: hledger.info, Node: Aliases and multiple files, Next: end aliases directive, Prev: Combining aliases, Up: alias directive++9.18.4 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++2023-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++2023-01-01 ; affected by aliases above+ foo 1+ bar++include c.journal ; also affected+++File: hledger.info, Node: end aliases directive, Next: Aliases can generate bad account names, Prev: Aliases and multiple files, Up: alias directive++9.18.5 'end aliases' directive+------------------------------++You can clear (forget) all currently defined aliases (seen in the+journal so far, or defined on the command line) with this directive:++end aliases+++File: hledger.info, Node: Aliases can generate bad account names, Next: Aliases and account types, Prev: end aliases directive, Up: alias directive++9.18.6 Aliases can generate bad account names+---------------------------------------------++Be aware that account aliases can produce malformed account names, which+could cause confusing reports or invalid 'print' output. For example,+you could erase all account names:++2021-01-01+ a:aa 1+ b++$ hledger print --alias '/.*/='+2021-01-01+ 1++ The above 'print' output is not a valid journal. Or you could insert+an illegal double space, causing 'print' output that would give a+different journal when reparsed:++2021-01-01+ old 1+ other++$ hledger print --alias old="new USD" | hledger -f- print+2021-01-01+ new USD 1+ other+++File: hledger.info, Node: Aliases and account types, Prev: Aliases can generate bad account names, Up: alias directive++9.18.7 Aliases and account types+--------------------------------++If an account with a type declaration (see Declaring accounts > Account+types) is renamed by an alias, normally the account type remains in+effect.++ However, renaming in a way that reshapes the account tree (eg+renaming parent accounts but not their children, or vice versa) could+prevent child accounts from inheriting the account type of their+parents.++ Secondly, if an account's type is being inferred from its name,+renaming it by an alias could prevent or alter that.++ If you are using account aliases and the 'type:' query is not+matching accounts as you expect, try troubleshooting with the accounts+command, eg something like:++$ hledger accounts --alias assets=bassetts type:a+++File: hledger.info, Node: commodity directive, Next: decimal-mark directive, Prev: alias directive, Up: Journal++9.19 'commodity' directive+==========================++The 'commodity' directive performs several functions:++ 1. It declares which commodity symbols may be used in the journal,+ enabling useful error checking with strict mode or the check+ command. See Commodity error checking below.++ 2. It declares how all amounts in this commodity should be displayed,+ eg how many decimals to show. See Commodity display style above.++ 3. (If no 'decimal-mark' directive is in effect:) It sets the decimal+ mark to expect (period or comma) when parsing amounts in this+ commodity, in this file and files it includes, from the directive+ until end of current file. See Decimal marks above.++ 4. It declares the precision with which this commodity's amounts+ should be compared when checking for balanced transactions,+ anywhere in this file and files it includes, until end of current+ file.++ Declaring commodities solves several common parsing/display problems,+so we recommend it.++ Note that effects 3 and 4 above end at the end of the directive's+file, and will not affect sibling or parent files. So if you are+relying on them (especially 4) and using multiple files, placing your+commodity directives in a top-level parent file might be important. Or,+keep your decimal marks unambiguous and your entries well balanced and+precise.++ (Related: #793)++* Menu:++* Commodity directive syntax::+* Commodity error checking::+++File: hledger.info, Node: Commodity directive syntax, Next: Commodity error checking, Up: commodity directive++9.19.1 Commodity directive syntax+---------------------------------++A commodity directive is normally the word 'commodity' followed by a+sample amount (and optionally a comment). Only the amount's symbol and+format is significant. Eg:++commodity $1000.00+commodity 1.000,00 EUR+commodity 1 000 000.0000 ; the no-symbol commodity++ Commodities do not have tags (tags in the comment will be ignored).++ A commodity directive's sample amount must always include a period or+comma decimal mark (this rule helps disambiguate decimal marks and digit+group marks). If you don't want to show any decimal digits, write the+decimal mark at the end:++commodity 1000. AAAA ; show AAAA with no decimals++ Commodity symbols containing spaces, numbers, or punctuation must be+enclosed in double quotes, as usual:++commodity 1.0000 "AAAA 2023"++ Commodity directives normally include a sample amount, but can+declare only a symbol (ie, just function 1 above):++commodity $+commodity INR+commodity "AAAA 2023"+commodity "" ; the no-symbol commodity++ Commodity directives may also be written with an indented 'format'+subdirective, as in Ledger. The symbol is repeated and must be the same+in both places. Other subdirectives are currently ignored:++; 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+ an unsupported subdirective ; ignored by hledger+++File: hledger.info, Node: Commodity error checking, Prev: Commodity directive syntax, Up: commodity directive++9.19.2 Commodity error checking+-------------------------------++In strict mode ('-s'/'--strict') (or when you run 'hledger check+commodities'), hledger will report an error if an undeclared commodity+symbol is used. (With one exception: zero amounts are always allowed to+have no commodity symbol.) It works like account error checking+(described above).+++File: hledger.info, Node: decimal-mark directive, Next: include directive, Prev: commodity directive, Up: Journal++9.20 'decimal-mark' directive+=============================++You can use a 'decimal-mark' directive - usually one per file, at the+top of the file - to declare which character represents a decimal mark+when parsing amounts in this file. It can look like++decimal-mark .++ or++decimal-mark ,++ This prevents any ambiguity when parsing numbers in the file, so we+recommend it, especially if the file contains digit group marks (eg+thousands separators).+++File: hledger.info, Node: include directive, Next: P directive, Prev: decimal-mark directive, Up: Journal++9.21 'include' directive+========================++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,+overriding the file extension (as described in Data formats): 'include+timedot:~/notes/2023*.md'.+++File: hledger.info, Node: P directive, Next: payee directive, Prev: include directive, Up: Journal++9.22 'P' directive+==================++The 'P' directive declares a market price, which is a conversion rate+between two commodities on a certain date. This allows value reports to+convert amounts of one commodity to their value in another, on or after+that date. These prices are often obtained from a stock exchange,+cryptocurrency exchange, the or foreign exchange market.++ 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 € $1.35++# and $1.40 from 2010-01-01 onward:+P 2010-01-01 € $1.40++ The '-V', '-X' and '--value' flags use these market prices to show+amount values in another commodity. See Value reporting.+++File: hledger.info, Node: payee directive, Next: tag directive, Prev: P directive, Up: Journal++9.23 'payee' directive+======================++'payee PAYEE NAME'++ This 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 ; a comment++ Payees do not have tags (tags in the comment will be ignored).++ To declare the empty payee name, use '""'.++payee ""++ Ledger-style indented subdirectives, if any, are currently ignored.+++File: hledger.info, Node: tag directive, Next: Periodic transactions, Prev: payee directive, Up: Journal++9.24 'tag' directive+====================++'tag TAGNAME'++ This directive can be used to declare a limited set of tag names+allowed in tags. TAGNAME should be a valid tag name (no spaces). Eg:++tag item-id++ Any indented subdirectives are currently ignored.++ The "tags" check will report an error if any undeclared tag name is+used. It is quite easy to accidentally create a tag through normal use+of colons in comments; if you want to prevent this, you can declare and+check your tags .+++File: hledger.info, Node: Periodic transactions, Next: Auto postings, Prev: tag directive, Up: Journal++9.25 Periodic transactions+==========================++The '~' directive declares a "periodic rule" which generates temporary+extra transactions, usually recurring at some interval, when hledger is+run with the '--forecast' flag. These "forecast transactions" are+useful for forecasting future activity. They exist only for the+duration of the report, and only when '--forecast' is used; they are not+saved in the journal file by hledger.++ Periodic rules also have a second use: with the '--budget' flag they+set budget goals for budgeting.++ Periodic rules can be a little tricky, so before you use them, read+this whole section, or at least the following 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-forecasted 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 2023/01', which is equivalent to '~ every 10th+ day of month from 2023/01/01', will be adjusted to start on+ 2019/12/10.++* Menu:++* Periodic rule syntax::+* Periodic rules and relative dates::+* Two spaces between period expression and description!::+++File: hledger.info, Node: Periodic rule syntax, Next: Periodic rules and relative dates, Up: Periodic transactions++9.25.1 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.):++# every first of month+~ monthly+ expenses:rent $2000+ assets:bank:checking++# every 15th of month in 2023's first quarter:+~ monthly from 2023-04-15 to 2023-06-16+ expenses:utilities $400+ assets:bank:checking++ The period expression is the same syntax used for specifying+multi-period reports, just interpreted differently; there, it specifies+report periods; here it specifies recurrence dates (the periods' start+dates).+++File: hledger.info, Node: Periodic rules and relative dates, Next: Two spaces between period expression and description!, Prev: Periodic rule syntax, Up: Periodic transactions++9.25.2 Periodic rules and relative dates+----------------------------------------++Partial or relative dates (like '12/31', '25', 'tomorrow', 'last week',+'next quarter') are usually not recommended in periodic rules, since the+results will change as time passes. If used, they will be interpreted+relative to, in order of preference:++ 1. the first day of the default year specified by a recent 'Y'+ directive+ 2. or the date specified with '--today'+ 3. or the date on which you are running the report.++ They will not be affected at all by report period or forecast period+dates.+++File: hledger.info, Node: Two spaces between period expression and description!, Prev: Periodic rules and relative dates, Up: Periodic transactions++9.25.3 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+accidentally alter their meaning, as in this example:++; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2023"+; ||+; vv+~ every 2 months in 2023, we will review+ assets:bank:checking $1500+ income:acme inc++ So,++ * Do write two spaces between your period expression and your+ transaction description, if any.+ * Don't accidentally write two spaces in the middle of your period+ expression.+++File: hledger.info, Node: Auto postings, Next: Other syntax, Prev: Periodic transactions, Up: Journal++9.26 Auto postings+==================++The '=' directive declares an "auto posting rule", which adds extra+postings to existing transactions. (Remember, postings are the account+name & amount lines below a transaction's date & description.)++ In the journal, an auto posting rule looks quite like a transaction,+but instead of date and description it has '=' (mnemonic: "match") and a+query, like this:++= QUERY+ ACCOUNT AMOUNT+ ...++ Queries are just like command line queries; an account name substring+is most common. Query terms containing spaces should be enclosed in+single or double quotes.++ Each '=' rule works like this: when hledger is run with the '--auto'+flag, wherever the QUERY matches a posting in the journal, the rule's+postings are added to that transaction, immediately below the matched+posting. Note these generated postings are temporary, existing only for+the duration of the report, and only when '--auto' is used; they are not+saved in the journal file by hledger.++ Generated postings' amounts can depend on the matched posting's+amount. So auto postings can be useful for, eg, adding tax postings+with a standard percentage. AMOUNT can be:++ * a number with no commodity symbol, like '2'. The matched posting's+ commodity symbol will be added to this.++ * a normal amount with a commodity symbol, like '$2'. This will be+ used as-is.++ * an asterisk followed by a number, like '*2'. This will multiply+ the matched posting's amount (and total price, if any) by the+ number.++ * an asterisk followed by an amount with commodity symbol, like+ '*$2'. This multiplies and also replaces the commodity symbol with+ this new one.++ 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++ Note that depending fully on generated data such as this has some+drawbacks - it's less portable, less future-proof, less auditable by+others, and less robust (eg your balance assertions will depend on+whether you use or don't use '--auto'). An alternative is to use auto+postings in "one time" fashion - use them to help build a complex+journal entry, view it with 'hledger print --auto', and then copy that+output into the journal file to make it permanent.++* Menu:++* Auto postings and multiple files::+++File: hledger.info, Node: Auto postings and multiple files, Up: Auto postings++9.26.1 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).++* Menu:++* Auto postings and dates::+* Auto postings and transaction balancing / inferred amounts / balance assertions::+* Auto posting tags::+* Auto postings on forecast transactions only::+++File: hledger.info, Node: Auto postings and dates, Next: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings and multiple files++9.26.1.1 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.+++File: hledger.info, Node: Auto postings and transaction balancing / inferred amounts / balance assertions, Next: Auto posting tags, Prev: Auto postings and dates, Up: Auto postings and multiple files++9.26.1.2 Auto postings and transaction balancing / inferred+...........................................................++amounts / balance assertions Currently, auto postings are added:++ * after missing amounts are inferred, and transactions are checked+ for balancedness,+ * 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.++ This also means that you cannot have more than one auto-posting with+a missing amount applied to a given transaction, as it will be unable to+infer amounts.+++File: hledger.info, Node: Auto posting tags, Next: Auto postings on forecast transactions only, Prev: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings and multiple files++9.26.1.3 Auto posting tags+..........................++Automated postings will have some extra tags:++ * 'generated-posting:= QUERY' - shows this was generated by an auto+ posting rule, and the query+ * '_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:++ * 'modified:' - this transaction was modified+ * '_modified:' - a hidden tag not appearing in the comment; this+ transaction was modified "just now".+++File: hledger.info, Node: Auto postings on forecast transactions only, Prev: Auto posting tags, Up: Auto postings and multiple files++9.26.1.4 Auto postings on forecast transactions only+....................................................++Tip: you can can make auto postings that will apply to forecast+transactions but not recorded transactions, by adding+'tag:_generated-transaction' to their QUERY. This can be useful when+generating new journal entries to be saved in the journal.+++File: hledger.info, Node: Other syntax, Prev: Auto postings, Up: Journal++9.27 Other syntax+=================++hledger journal format supports quite a few other features, mainly to+make interoperating with or converting from Ledger easier. Note some of+the features below are powerful and can be useful in special cases, but+in general, features in this section are considered less important or+even not recommended for most users. Downsides are mentioned to help+you decide if you want to use them.++* Menu:++* Balance assignments::+* Bracketed posting dates::+* D directive::+* apply account directive::+* Y directive::+* Secondary dates::+* Star comments::+* Valuation expressions::+* Virtual postings::+* Other Ledger directives::+* Other cost/lot notations::+++File: hledger.info, Node: Balance assignments, Next: Bracketed posting dates, Up: Other syntax++9.27.1 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+assignment).++ Downsides: using balance assignments makes your journal less+explicit; to know the exact amount posted, you have to run hledger or do+the calculations yourself, instead of just reading it. Also balance+assignments' forcing of balances can hide errors. These things make+your financial data less portable, less future-proof, and less+trustworthy in an audit.++* Menu:++* Balance assignments and costs::+* Balance assignments and multiple files::+++File: hledger.info, Node: Balance assignments and costs, Next: Balance assignments and multiple files, Up: Balance assignments++9.27.1.1 Balance assignments and costs+......................................++A cost in a balance assignment will cause the calculated amount to have+that cost attached:++2019/1/1+ (a) = $1 @ €2++$ hledger print --explicit+2019-01-01+ (a) $1 @ €2 = $1 @ €2+++File: hledger.info, Node: Balance assignments and multiple files, Prev: Balance assignments and costs, Up: Balance assignments++9.27.1.2 Balance assignments and multiple files+...............................................++Balance assignments handle multiple files like balance assertions. They+see balance from other files previously included from the current file,+but not from previous sibling or parent files.+++File: hledger.info, Node: Bracketed posting dates, Next: D directive, Prev: Balance assignments, Up: Other syntax++9.27.2 Bracketed posting dates+------------------------------++For setting posting dates and secondary posting dates, Ledger's+bracketed date syntax is also supported: '[DATE]', '[DATE=DATE2]' or+'[=DATE2]' in posting comments. hledger will attempt to parse any+square-bracketed sequence of the '0123456789/-.=' characters in this+way. With this syntax, DATE infers its year from the transaction and+DATE2 infers its year from DATE.++ Downsides: another syntax to learn, redundant with hledger's+'date:'/'date2:' tags, and confusingly similar to Ledger's lot date+syntax.+++File: hledger.info, Node: D directive, Next: apply account directive, Prev: Bracketed posting dates, Up: Other syntax++9.27.3 'D' directive+--------------------++'D AMOUNT'++ This directive sets a default commodity, to be used for any+subsequent commodityless amounts (ie, plain numbers) seen while parsing+the journal. This effect lasts until the next 'D' directive, or the end+of the current file.++ For compatibility/historical reasons, 'D' also acts like a+'commodity' directive (setting the commodity's decimal mark for parsing+and display style for output). So its argument is not just a commodity+symbol, but a full amount demonstrating the style. The amount must+include a decimal mark (either period or comma). Eg:++; 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++ Interactions with other directives:++ For setting a commodity's display style, a 'commodity' directive has+highest priority, then a 'D' directive.++ For detecting a commodity's decimal mark during parsing,+'decimal-mark' has highest priority, then 'commodity', then 'D'.++ For checking commodity symbols with the check command, a 'commodity'+directive is required ('hledger check commodities' ignores 'D'+directives).++ Downsides: omitting commodity symbols makes your financial data less+explicit, less portable, and less trustworthy in an audit. It is+usually an unsustainable shortcut; sooner or later you will want to+track multiple commodities. D is overloaded with functions redundant+with 'commodity' and 'decimal-mark'. And it works differently from+Ledger's 'D'.+++File: hledger.info, Node: apply account directive, Next: Y directive, Prev: D directive, Up: Other syntax++9.27.4 'apply account' directive+--------------------------------++This directive sets a default parent account, which will be prepended to+all accounts in following entries, until an 'end apply account'+directive or end of current file. Eg:++apply account home++2010/1/1+ food $10+ cash++end apply account++ is equivalent to:++2010/01/01+ home:food $10+ home:cash $-10++ 'account' directives are also affected, and so is any 'include'd+content.++ Account names entered via hledger add or hledger-web are not+affected.++ Account aliases, if any, are applied after the parent account is+prepended.++ Downsides: this can make your financial data less explicit, less+portable, and less trustworthy in an audit.+++File: hledger.info, Node: Y directive, Next: Secondary dates, Prev: apply account directive, Up: Other syntax++9.27.5 'Y' directive+--------------------++'Y YEAR'++ or (deprecated backward-compatible forms):++ 'year YEAR' 'apply year YEAR'++ The space is optional. This sets a default year to be used for+subsequent dates which don't specify a year. Eg:++Y2009 ; set default year to 2009++12/15 ; equivalent to 2009/12/15+ expenses 1+ assets++year 2010 ; change default year to 2010++2009/1/30 ; specifies the year, not affected+ expenses 1+ assets++1/31 ; equivalent to 2010/1/31+ expenses 1+ assets++ Downsides: omitting the year (from primary transaction dates, at+least) makes your financial data less explicit, less portable, and less+trustworthy in an audit. Such dates can get separated from their+corresponding Y directive, eg when evaluating a region of the journal in+your editor. A missing Y directive makes reports dependent on today's+date.+++File: hledger.info, Node: Secondary dates, Next: Star comments, Prev: Y directive, Up: Other syntax++9.27.6 Secondary dates+----------------------++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".++ Downsides: makes your financial data more complicated, less portable,+and less trustworthy in an audit. Keeping the meaning of the two dates+consistent requires discipline, and you have to remember which reporting+mode is appropriate for a given report. Posting dates are simpler and+better.+++File: hledger.info, Node: Star comments, Next: Valuation expressions, Prev: Secondary dates, Up: Other syntax++9.27.7 Star comments+--------------------++Lines beginning with '*' (star/asterisk) are also comment lines. This+feature allows Emacs users to insert org headings in their journal,+allowing them to fold/unfold/navigate it like an outline when viewed+with org mode.++ Downsides: another, unconventional comment syntax to learn.+Decreases your journal's portability. And switching to Emacs org mode+just for folding/unfolding meant losing the benefits of ledger mode;+nowadays you can add outshine mode to ledger mode to get folding without+losing ledger mode's features.+++File: hledger.info, Node: Valuation expressions, Next: Virtual postings, Prev: Star comments, Up: Other syntax++9.27.8 Valuation expressions+----------------------------++Ledger allows a valuation function or value to be written in double+parentheses after an amount. hledger ignores these.+++File: hledger.info, Node: Virtual postings, Next: Other Ledger directives, Prev: Valuation expressions, Up: Other syntax++9.27.9 Virtual postings+-----------------------++A posting with parentheses around the account name, like '(some:account)+10', is called an _unbalanced virtual posting_. These postings do not+participate in transaction balancing. (And if you write them without an+amount, a zero amount is always inferred.) These can occasionally be+convenient for special circumstances, but they violate double entry+bookkeeping and make your data less portable across applications, so+many people avoid using them at all.++ A posting with brackets around the account name ('[some:account]') is+called a _balanced virtual posting_. The balanced virtual postings in a+transaction must add up to zero, just like ordinary postings, but+separately from them. These are not part of double entry bookkeeping+either, but they are at least balanced. An example:++2022-01-01 buy food with cash, update budget envelope subaccounts, & something else+ assets:cash $-10 ; <- these balance each other+ expenses:food $7 ; <-+ expenses:food $3 ; <-+ [assets:checking:budget:food] $-10 ; <- and these balance each other+ [assets:checking:available] $10 ; <-+ (something:else) $5 ; <- this is not required to balance++ Ordinary postings, whose account names are neither parenthesised nor+bracketed, are called _real postings_. You can exclude virtual postings+from reports with the '-R/--real' flag or a 'real:1' query.+++File: hledger.info, Node: Other Ledger directives, Next: Other cost/lot notations, Prev: Virtual postings, Up: Other syntax++9.27.10 Other Ledger directives+-------------------------------++These other Ledger directives are currently accepted but ignored. This+allows hledger to read more Ledger files, but be aware that hledger's+reports may differ from Ledger's if you use these.++apply fixed COMM AMT+apply tag TAG+assert EXPR+bucket / A ACCT+capture ACCT REGEX+check EXPR+define VAR=EXPR+end apply fixed+end apply tag+end apply year+end tag+eval / expr EXPR+python+ PYTHONCODE+tag NAME+value EXPR+--command-line-flags++ See also https://hledger.org/ledger.html for a detailed+hledger/Ledger syntax comparison.+++File: hledger.info, Node: Other cost/lot notations, Prev: Other Ledger directives, Up: Other syntax++9.27.11 Other cost/lot notations+--------------------------------++A slight digression for Ledger and Beancount users. Ledger has a number+of cost/lot-related notations:++ * '@ UNITCOST' and '@@ TOTALCOST'+ * expresses a conversion rate, as in hledger+ * when buying, also creates a lot than can be selected at+ selling time++ * '(@) UNITCOST' and '(@@) TOTALCOST' (virtual cost)+ * like the above, but also means "this cost was exceptional,+ don't use it when inferring market prices".++ Currently, hledger treats the above like '@' and '@@'; the+parentheses are ignored.++ * '{=FIXEDUNITCOST}' and '{{=FIXEDTOTALCOST}}' (fixed price)+ * when buying, means "this cost is also the fixed price, don't+ let it fluctuate in value reports"++ * '{UNITCOST}' and '{{TOTALCOST}}' (lot price)+ * can be used identically to '@ UNITCOST' and '@@ TOTALCOST',+ also creates a lot+ * when selling, combined with '@ ...', specifies an investment+ lot by its cost basis; does not check if that lot is present++ * and related: '[YYYY/MM/DD]' (lot date)+ * when buying, attaches this acquisition date to the lot+ * when selling, selects a lot by its acquisition date++ * '(SOME TEXT)' (lot note)+ * when buying, attaches this note to the lot+ * when selling, selects a lot by its note++ Currently, hledger accepts any or all of the above in any order after+the posting amount, but ignores them. (This can break transaction+balancing.)++ For Beancount users, the notation and behaviour is different:++ * '@ UNITCOST' and '@@ TOTALCOST'+ * expresses a cost without creating a lot, as in hledger+ * when buying (augmenting) or selling (reducing) a lot, combined+ with '{...}': documents the cost/selling price (not used for+ transaction balancing)++ * '{UNITCOST}' and '{{TOTALCOST}}'+ * when buying (augmenting), expresses the cost for transaction+ balancing, and also creates a lot with this cost basis+ attached+ * when selling (reducing),+ * selects a lot by its cost basis+ * raises an error if that lot is not present or can not be+ selected unambiguously (depending on booking method+ configured)+ * expresses the selling price for transaction balancing++ Currently, hledger accepts the '{UNITCOST}'/'{{TOTALCOST}}' notation+but ignores it.++ * variations: '{}', '{YYYY-MM-DD}', '{"LABEL"}', '{UNITCOST,+ "LABEL"}', '{UNITCOST, YYYY-MM-DD, "LABEL"}' etc.++ Currently, hledger rejects these.+++File: hledger.info, Node: CSV, Next: Timeclock, Prev: Journal, Up: Top++10 CSV+******++hledger can read CSV files (Character Separated Value - usually comma,+semicolon, or tab) containing dated records, automatically converting+each record into a transaction.++ (To learn about _writing_ CSV, see CSV output.)++ For best error messages when reading CSV/TSV/SSV files, make sure+they have a corresponding '.csv', '.tsv' or '.ssv' file extension or use+a hledger file prefix (see File Extension below).++ Each CSV file must be described by a corresponding _rules file_.+This contains rules describing the CSV data (header line, fields layout,+date format etc.), how to construct hledger transactions from it, and+how to categorise transactions based on description or other attributes.++ By default, hledger expects this rules file to be named like the CSV+file, with an extra '.rules' extension added, in the same directory. Eg+when asked to read 'foo/FILE.csv', hledger looks for+'foo/FILE.csv.rules'. You can specify a different rules file with the+'--rules-file' option.++ 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++ There's an introductory Importing CSV data tutorial on hledger.org,+and more CSV rules examples below, and a larger collection at+https://github.com/simonmichael/hledger/tree/master/examples/csv.++* Menu:++* CSV rules cheatsheet::+* source::+* separator::+* skip::+* date-format::+* timezone::+* newest-first::+* intra-day-reversed::+* decimal-mark::+* fields list::+* Field assignment::+* Field names::+* if block::+* Matchers::+* if table::+* balance-type::+* include::+* Working with CSV::+* CSV rules examples::+++File: hledger.info, Node: CSV rules cheatsheet, Next: source, Up: CSV++10.1 CSV rules cheatsheet+=========================++The following kinds of rule can appear in the rules file, in any order.+(Blank lines and lines beginning with '#' or ';' or '*' are ignored.)++*'source'* optionally declare which file to read data+ from+*'separator'* declare the field separator, instead of+ relying on file extension+*'skip'* skip one or more header lines at start of file+*'date-format'* declare how to parse CSV dates/date-times+*'timezone'* declare the time zone of ambiguous CSV+ date-times+*'newest-first'* improve txn order when: there are multiple+ records, newest first, all with the same date+*'intra-day-reversed'* improve txn order when: same-day txns are in+ opposite order to the overall file+*'decimal-mark'* declare the decimal mark used in CSV amounts,+ when ambiguous+*'fields' list* name CSV fields for easy reference, and+ optionally assign their values to hledger+ fields+*Field assignment* assign a CSV value or interpolated text value+ to a hledger field+*'if' block* conditionally assign values to hledger fields,+ or 'skip' a record or 'end' (skip rest of+ file)+*'if' table* conditionally assign values to hledger fields,+ using compact syntax+*'balance-type'* select which type of balance+ assertions/assignments to generate+*'include'* inline another CSV rules file++ Working with CSV tips can be found below, including How CSV rules are+evaluated.+++File: hledger.info, Node: source, Next: separator, Prev: CSV rules cheatsheet, Up: CSV++10.2 'source'+=============++If you tell hledger to read a csv file with '-f foo.csv', it will look+for rules in 'foo.csv.rules'. Or, you can tell it to read the rules+file, with '-f foo.csv.rules', and it will look for data in 'foo.csv'+(since 1.30).++ These are mostly equivalent, but the second method provides some+extra features. For one, the data file can be missing, without causing+an error; it is just considered empty. And, you can specify a different+data file by adding a "source" rule:++source ./Checking1.csv++ If you specify just a file name with no path, hledger will look for+it in your system's downloads directory ('~/Downloads', currently):++source Checking1.csv++ And if you specify a glob pattern, hledger will read the most recent+of the matched files (useful with repeated downloads):++source Checking1*.csv++ See also "Working with CSV > Reading files specified by rule".+++File: hledger.info, Node: separator, Next: skip, Prev: source, Up: CSV++10.3 'separator'+================++You can use the 'separator' rule to read other kinds of+character-separated 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 automatically, and you won't need this rule.+++File: hledger.info, Node: skip, Next: date-format, Prev: separator, Up: CSV++10.4 'skip'+===========++skip N++ The word 'skip' followed by a number (or no number, meaning 1) tells+hledger to ignore this many non-empty lines at the start of the input+data. You'll need this whenever your CSV data contains header lines.+Note, empty and blank lines are skipped automatically, so you don't need+to count those.++ 'skip' has a second meaning: it can be used inside if blocks+(described below), to skip one or more records whenever the condition is+true. Records skipped in this way are ignored, except they are still+required to be valid CSV.+++File: hledger.info, Node: date-format, Next: timezone, Prev: skip, Up: CSV++10.5 '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-style date parsing pattern - see+https://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:formatTime.+The pattern must parse the CSV date value completely. Some examples:++# 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+++File: hledger.info, Node: timezone, Next: newest-first, Prev: date-format, Up: CSV++10.6 'timezone'+===============++timezone TIMEZONE++ When CSV contains date-times that are implicitly in some time zone+other than yours, but containing no explicit time zone information, you+can use this rule to declare the CSV's native time zone, which helps+prevent off-by-one dates.++ When the CSV date-times do contain time zone information, you don't+need this rule; instead, use '%Z' in 'date-format' (or '%z', '%EZ',+'%Ez'; see the formatTime link above).++ In either of these cases, hledger will do a time-zone-aware+conversion, localising the CSV date-times to your current system time+zone. If you prefer to localise to some other time zone, eg for+reproducibility, you can (on unix at least) set the output timezone with+the TZ environment variable, eg:++$ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv++ 'timezone' currently does not understand timezone names, except+"UTC", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", or "PDT".+For others, use numeric format: +HHMM or -HHMM.+++File: hledger.info, Node: newest-first, Next: intra-day-reversed, Prev: timezone, Up: CSV++10.7 'newest-first'+===================++hledger tries to ensure that the generated transactions will be ordered+chronologically, including same-day transactions. Usually it can+auto-detect how the CSV records are ordered. But if it encounters CSV+where all records are on the same date, it assumes that the records are+oldest first. If in fact the CSV's records are normally newest first,+like:++2022-10-01, txn 3...+2022-10-01, txn 2...+2022-10-01, txn 1...++ you can add the 'newest-first' rule to help hledger generate the+transactions in correct order.++# same-day CSV records are newest first+newest-first+++File: hledger.info, Node: intra-day-reversed, Next: decimal-mark, Prev: newest-first, Up: CSV++10.8 'intra-day-reversed'+=========================++If CSV records within a single day are ordered opposite to the overall+record order, you can add the 'intra-day-reversed' rule to improve the+order of journal entries. Eg, here the overall record order is newest+first, but same-day records are oldest first:++2022-10-02, txn 3...+2022-10-02, txn 4...+2022-10-01, txn 1...+2022-10-01, txn 2...++# transactions within each day are reversed with respect to the overall date order+intra-day-reversed+++File: hledger.info, Node: decimal-mark, Next: fields list, Prev: intra-day-reversed, Up: CSV++10.9 '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.+++File: hledger.info, Node: fields list, Next: Field assignment, Prev: decimal-mark, Up: CSV++10.10 'fields' list+===================++fields FIELDNAME1, FIELDNAME2, ...++ A fields list (the word 'fields' followed by comma-separated field+names) is optional, but convenient. It does two things:++ 1. It names the CSV field in each column. This can be convenient if+ you are referencing them in other rules, so you can say+ '%SomeField' instead of remembering '%13'.++ 2. Whenever you use one of the special hledger field names (described+ below), it assigns the CSV value in this position to that hledger+ field. This is the quickest way to populate hledger's fields and+ build a transaction.++ Here's an example that says "use the 1st, 2nd and 4th fields as the+transaction's date, description and amount; name the last two fields for+later reference; and ignore the others":++fields date, description, , amount, , , somefield, anotherfield++ In a fields list, the separator is always comma; it is unrelated to+the CSV file's separator. Also:++ * There must be least two items in the list (at least one comma).+ * Field names may not contain spaces. Spaces before/after field+ names are optional.+ * Field names may contain '_' (underscore) or '-' (hyphen).+ * Fields you don't care about can be given a dummy name or an empty+ name.++ If the CSV contains column headings, it's convenient to use these for+your field names, suitably modified (eg lower-cased with spaces replaced+by underscores).++ Sometimes you may want to alter a CSV field name to avoid assigning+to a hledger field with the same name. Eg you could call the CSV's+"balance" field 'balance_' to avoid directly setting hledger's 'balance'+field (and generating a balance assertion).+++File: hledger.info, Node: Field assignment, Next: Field names, Prev: fields list, Up: CSV++10.11 Field assignment+======================++HLEDGERFIELD 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+interpolate CSV fields, referenced either by their 1-based position in+the CSV record ('%N') or by the name they were given in the fields list+('%CSVFIELD'), and regular expression match groups ('\N').++ 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:++ * Interpolation strips outer whitespace (so a CSV value like '" 1 "'+ becomes '1' when interpolated) (#1051).+ * Interpolations always refer to a CSV field - you can't interpolate+ a hledger field. (See Referencing other fields below).+++File: hledger.info, Node: Field names, Next: if block, Prev: Field assignment, Up: CSV++10.12 Field names+=================++Note the two kinds of field names mentioned here, and used only in+hledger CSV rules files:++ 1. *CSV field names* ('CSVFIELD' in these docs): you can optionally+ name the CSV columns for easy reference (since hledger doesn't yet+ automatically recognise column headings in a CSV file), by writing+ arbitrary names in a 'fields' list, eg:++ fields When, What, Some_Id, Net, Total, Foo, Bar++ 2. Special *hledger field names* ('HLEDGERFIELD' in these docs): you+ must set at least some of these to generate the hledger transaction+ from a CSV record, by writing them as the left hand side of a field+ assignment, eg:++ date %When+ code %Some_Id+ description %What+ comment %Foo %Bar+ amount1 $ %Total++ or directly in a 'fields' list:++ fields date, description, code, , amount1, Foo, Bar+ currency $+ comment %Foo %Bar++ Here are all the special hledger field names available, and what+happens when you assign values to them:++* Menu:++* date field::+* date2 field::+* status field::+* code field::+* description field::+* comment field::+* account field::+* amount field::+* currency field::+* balance field::+++File: hledger.info, Node: date field, Next: date2 field, Up: Field names++10.12.1 date field+------------------++Assigning to 'date' sets the transaction date.+++File: hledger.info, Node: date2 field, Next: status field, Prev: date field, Up: Field names++10.12.2 date2 field+-------------------++'date2' sets the transaction's secondary date, if any.+++File: hledger.info, Node: status field, Next: code field, Prev: date2 field, Up: Field names++10.12.3 status field+--------------------++'status' sets the transaction's status, if any.+++File: hledger.info, Node: code field, Next: description field, Prev: status field, Up: Field names++10.12.4 code field+------------------++'code' sets the transaction's code, if any.+++File: hledger.info, Node: description field, Next: comment field, Prev: code field, Up: Field names++10.12.5 description field+-------------------------++'description' sets the transaction's description, if any.+++File: hledger.info, Node: comment field, Next: account field, Prev: description field, Up: Field names++10.12.6 comment field+---------------------++'comment' sets the transaction's comment, if any.++ 'commentN', where N is a number, sets the Nth posting's comment.++ You can assign multi-line comments by writing literal '\n' in the+code. A comment starting with '\n' will begin on a new line.++ Comments can contain tags, as usual.+++File: hledger.info, Node: account field, Next: amount field, Prev: comment field, Up: Field names++10.12.7 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, in conditional rules.++ If a posting's account name is left unset but its amount is set (see+below), a default account name will be chosen (like "expenses:unknown"+or "income:unknown").+++File: hledger.info, Node: amount field, Next: currency field, Prev: account field, Up: Field names++10.12.8 amount field+--------------------++There are several ways to set posting amounts from CSV, useful in+different situations.++ 1. *'amount'* is the oldest and simplest. Assigning to this sets the+ amount of the first and second postings. In the second posting,+ the amount will be negated; also, if it has a cost attached, it+ will be converted to cost.++ 2. *'amount-in'* and *'amount-out'* work exactly like the above, but+ should be used when the CSV has two amount fields (such as "Debit"+ and "Credit", or "Inflow" and "Outflow"). Whichever field has a+ non-zero value will be used as the amount of the first and second+ postings. Here are some tips to avoid confusion:++ * It's not "amount-in for posting 1 and amount-out for posting+ 2", it is "extract a single amount from the amount-in or+ amount-out field, and use that for posting 1 and (negated) for+ posting 2".+ * Don't use both 'amount' and 'amount-in'/'amount-out' in the+ same rules file; choose based on whether the amount is in a+ single CSV field or spread across two fields.+ * In each record, at most one of the two CSV fields should+ contain a non-zero amount; the other field must contain a zero+ or nothing.+ * hledger assumes both CSV fields contain unsigned numbers, and+ it automatically negates the amount-out values.+ * If the data doesn't fit these requirements, you'll probably+ need an if rule (see below).++ 3. *'amountN'* (where N is a number from 1 to 99) sets the amount of+ only a single posting: the Nth posting in the transaction. You'll+ usually need at least two such assignments to make a balanced+ transaction. You can also generate more than two postings, to+ represent more complex transactions. The posting numbers don't+ have to be consecutive; with if rules, higher posting numbers can+ be useful to ensure a certain order of postings.++ 4. *'amountN-in'* and *'amountN-out'* work exactly like the above, but+ should be used when the CSV has two amount fields. This is+ analogous to 'amount-in' and 'amount-out', and those tips also+ apply here.++ 5. Remember that a 'fields' list can also do assignments. So in a+ fields list if you name a CSV field "amount", that counts as+ assigning to 'amount'. (If you don't want that, call it something+ else in the fields list, like "amount_".)++ 6. The above don't handle every situation; if you need more+ flexibility, use an 'if' rule to set amounts conditionally. See+ "Working with CSV > Setting amounts" below for more on this and on+ amount-setting generally.+++File: hledger.info, Node: currency field, Next: balance field, Prev: amount field, Up: Field names++10.12.9 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.+++File: hledger.info, Node: balance field, Prev: currency field, Up: Field names++10.12.10 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 the Working with CSV tips below for more about setting amounts+and currency.+++File: hledger.info, Node: if block, Next: Matchers, Prev: Field names, Up: CSV++10.13 'if' block+================++Rules can be applied conditionally, depending on patterns in the CSV+data. This allows flexibility; in particular, it is how you can+categorise transactions, selecting an appropriate account name based on+their description (for example). There are two ways to write+conditional rules: "if blocks", described here, and "if tables",+described below.++ An if block is the word 'if' and one or more "matcher" expressions+(can be a word or phrase), one per line, starting either on the same or+next line; followed by one or more indented rules. Eg,++if MATCHER+ RULE++ or++if+MATCHER+MATCHER+MATCHER+ RULE+ RULE++ If any of the matchers succeeds, all of the indented rules will be+applied. They are usually field assignments, but the following special+rules may also be used within an if block:++ * 'skip' - skips the matched CSV record (generating no transaction+ from it)+ * 'end' - skips the rest of the current CSV file.++ Some examples:++# if the record contains "groceries", set account2 to "expenses:groceries"+if groceries+ account2 expenses:groceries++# if the record contains any of these phrases, set account2 and a transaction comment as shown+if+monthly service fee+atm transaction fee+banking thru software+ account2 expenses:business:banking+ comment XXX deductible ? check it++# if an empty record is seen (assuming five fields), ignore the rest of the CSV file+if ,,,,+ end+++File: hledger.info, Node: Matchers, Next: if table, Prev: if block, Up: CSV++10.14 Matchers+==============++There are two kinds:++ 1. A record matcher is a word or single-line text fragment or regular+ expression ('REGEX'), which hledger will try to match+ case-insensitively anywhere within the CSV record.+ Eg: 'whole foods'++ 2. A field matcher is preceded with a percent sign and CSV field name+ ('%CSVFIELD REGEX'). hledger will try to match these just within+ the named CSV field.+ Eg: '%date 2023'++ The regular expression is (as usual in hledger) a POSIX extended+regular expression, that also supports GNU word boundaries ('\b', '\B',+'\<', '\>'), and nothing else. If you have trouble, see "Regular+expressions" in the hledger manual+(https://hledger.org/hledger.html#regular-expressions).++* Menu:++* What matchers match::+* Combining matchers::+* Match groups::+++File: hledger.info, Node: What matchers match, Next: Combining matchers, Up: Matchers++10.14.1 What matchers match+---------------------------++With record matchers, it's important to know that the record matched is+not the original CSV record, but a modified one: separators will be+converted to commas, and enclosing double quotes (but not enclosing+whitespace) are removed. So for example, when reading an SSV file, if+the original record was:++2023-01-01; "Acme, Inc."; 1,000++ the regex would see, and try to match, this modified record text:++2023-01-01,Acme, Inc., 1,000+++File: hledger.info, Node: Combining matchers, Next: Match groups, Prev: What matchers match, Up: Matchers++10.14.2 Combining matchers+--------------------------++When an if block has multiple matchers, they are combined as follows:++ * By default they are OR'd (any of them can match)+ * When a matcher is preceded by ampersand ('&', at the start of the+ line) it will be AND'ed with the previous matcher (all in the+ AND'ed group must match)+ * _Added in 1.32_ When a matcher is preceded by an exclamation mark+ ('!'), it is negated (it must not match).++ Note currently there is a limitation: you can't use both '&' and '!'+on the same line (you can't AND a negated matcher).+++File: hledger.info, Node: Match groups, Prev: Combining matchers, Up: Matchers++10.14.3 Match groups+--------------------++_Added in 1.32_++ Matchers can define match groups: parenthesised portions of the+regular expression which are available for reference in field+assignments. Groups are enclosed in regular parentheses ('(' and ')')+and can be nested. Each group is available in field assignments using+the token '\N', where N is an index into the match groups for this+conditional block (e.g. '\1', '\2', etc.).++ Example: Warp credit card payment postings to the beginning of the+billing period (Month start), to match how they are presented in+statements, using posting dates:++if %date (....-..)-..+ comment2 date:\1-01++ Another example: Read the expense account from the CSV field, but+throw away a prefix:++if %account1 liabilities:family:(expenses:.*)+ account1 \1+++File: hledger.info, Node: if table, Next: balance-type, Prev: Matchers, Up: CSV++10.15 'if' table+================++"if tables" are an alternative to if blocks; they can express many+matchers and field assignments in a more compact tabular format, like+this:++if,HLEDGERFIELD1,HLEDGERFIELD2,...+MATCHERA,VALUE1,VALUE2,...+MATCHERB,VALUE1,VALUE2,...+; Comment line that explains MATCHERC+MATCHERC,VALUE1,VALUE2,...+<empty line>++ The first character after 'if' is taken to be this if table's field+separator. It is unrelated to the separator used in the CSV file. It+should be a non-alphanumeric character like ',' or '|' that does not+appear anywhere else in the table (it should not be used in field names+or matchers or values, and it cannot be escaped with a backslash).++ Each line must contain the same number of separators; empty values+are allowed. Whitespace can be used in the matcher lines for+readability (but not in the if line, currently). You can use the+comment lines in the table body. The table must be terminated by an+empty line (or end of file).++ An if table like the above is interpreted as follows: try all of the+matchers; whenever a matcher succeeds, assign all of the values on that+line to the corresponding hledger fields; If multiple lines match, later+lines will override fields assigned by the earlier ones - just like the+sequence of 'if' blocks would behave.++ If table presented above is equivalent to this sequence of if blocks:++if MATCHERA+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++if MATCHERB+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++; Comment line which explains MATCHERC+if MATCHERC+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++ Example:++if,account2,comment+atm transaction fee,expenses:business:banking,deductible? check it+%description groceries,expenses:groceries,+;; Comment line that desribes why this particular date is special+2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out+++File: hledger.info, Node: balance-type, Next: include, Prev: if table, Up: CSV++10.16 '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+++File: hledger.info, Node: include, Next: Working with CSV, Prev: balance-type, Up: CSV++10.17 '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+++File: hledger.info, Node: Working with CSV, Next: CSV rules examples, Prev: include, Up: CSV++10.18 Working with CSV+======================++Some tips:++* Menu:++* Rapid feedback::+* Valid CSV::+* File Extension::+* Reading CSV from standard input::+* Reading multiple CSV files::+* Reading files specified by rule::+* Valid transactions::+* Deduplicating importing::+* Setting amounts::+* Amount signs::+* Setting currency/commodity::+* Amount decimal places::+* Referencing other fields::+* How CSV rules are evaluated::+* Well factored rules::+++File: hledger.info, Node: Rapid feedback, Next: Valid CSV, Up: Working with CSV++10.18.1 Rapid feedback+----------------------++It's a good idea to get rapid feedback while creating/troubleshooting+CSV rules. Here's a good way, using entr from eradman.com/entrproject:++$ 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.+++File: hledger.info, Node: Valid CSV, Next: File Extension, Prev: Rapid feedback, Up: Working with CSV++10.18.2 Valid CSV+-----------------++Note that hledger will only accept valid CSV conforming to RFC 4180, and+equivalent SSV and TSV formats (like RFC 4180 but with semicolon or tab+as separators). This means, eg:++ * Values may be enclosed in double quotes, or not. Enclosing in+ single quotes is not allowed. (Eg ''A','B'' is rejected.)+ * When values are enclosed in double quotes, spaces outside the+ quotes are not allowed. (Eg '"A", "B"' is rejected.)+ * When values are not enclosed in quotes, they may not contain double+ quotes. (Eg 'A"A, B' is rejected.)++ If your CSV/SSV/TSV is not valid in this sense, you'll need to+transform it before reading with hledger. Try using sed, or a more+permissive CSV parser like python's csv lib.+++File: hledger.info, Node: File Extension, Next: Reading CSV from standard input, Prev: Valid CSV, Up: Working with CSV++10.18.3 File Extension+----------------------++To help hledger choose the CSV file reader and show the right error+messages (and choose the right field separator character by default),+it's best if CSV/SSV/TSV files are named with a '.csv', '.ssv' or '.tsv'+filename extension. (More about this at Data formats.)++ When reading files with the "wrong" extension, you can ensure the CSV+reader (and the default field separator) by prefixing the file path with+'csv:', 'ssv:' or 'tsv:': Eg:++$ hledger -f ssv:foo.dat print++ You can also override the default field separator with a separator+rule if needed.+++File: hledger.info, Node: Reading CSV from standard input, Next: Reading multiple CSV files, Prev: File Extension, Up: Working with CSV++10.18.4 Reading CSV from standard input+---------------------------------------++You'll need the file format prefix when reading CSV from stdin also,+since hledger assumes journal format by default. Eg:++$ cat foo.dat | hledger -f ssv:- print+++File: hledger.info, Node: Reading multiple CSV files, Next: Reading files specified by rule, Prev: Reading CSV from standard input, Up: Working with CSV++10.18.5 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.+++File: hledger.info, Node: Reading files specified by rule, Next: Valid transactions, Prev: Reading multiple CSV files, Up: Working with CSV++10.18.6 Reading files specified by rule+---------------------------------------++Instead of specifying a CSV file in the command line, you can specify a+rules file, as in 'hledger -f foo.csv.rules CMD'. By default this will+read data from foo.csv in the same directory, but you can add a source+rule to specify a different data file, perhaps located in your web+browser's download directory.++ This feature was added in hledger 1.30, so you won't see it in most+CSV rules examples. But it helps remove some of the busywork of+managing CSV downloads. Most of your financial institutions's default+CSV filenames are different and can be recognised by a glob pattern. So+you can put a rule like 'source Checking1*.csv' in+foo-checking.csv.rules, and then periodically follow a workflow like:++ 1. Download CSV from Foo's website, using your browser's defaults+ 2. Run 'hledger import foo-checking.csv.rules' to import any new+ transactions++ After import, you can: discard the CSV, or leave it where it is for a+while, or move it into your archives, as you prefer. If you do nothing,+next time your browser will save something like Checking1-2.csv, and+hledger will use that because of the '*' wild card and because it is the+most recent.+++File: hledger.info, Node: Valid transactions, Next: Deduplicating importing, Prev: Reading files specified by rule, Up: Working with CSV++10.18.7 Valid transactions+--------------------------++After reading a CSV file, hledger post-processes and validates the+generated journal entries as it would for a journal file - balancing+them, applying balance assignments, and canonicalising amount styles.+Any errors at this stage will be reported in the usual way, displaying+the problem entry.++ 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+++File: hledger.info, Node: Deduplicating importing, Next: Setting amounts, Prev: Valid transactions, Up: Working with CSV++10.18.8 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:++ * https://hledger.org/cookbook.html#setups-and-workflows+ * https://plaintextaccounting.org -> data import/conversion+++File: hledger.info, Node: Setting amounts, Next: Amount signs, Prev: Deduplicating importing, Up: Working with CSV++10.18.9 Setting amounts+-----------------------++Continuing from amount field above, here are more tips for+amount-setting:++ 1. *If the amount is in a single CSV field:*++ a. *If its sign indicates direction of flow:*+ Assign it to 'amountN', to set the Nth posting's amount. N is+ usually 1 or 2 but can go up to 99.++ b. *If another field indicates direction of flow:*+ Use one or more conditional rules to set the appropriate+ amount sign. Eg:++ # assume a withdrawal unless Type contains "deposit":+ amount1 -%Amount+ if %Type deposit+ amount1 %Amount++ 2. *If the amount is in two CSV fields (such as Debit and Credit, or+ In and Out):*++ a. *If both fields are unsigned:*+ Assign one field to 'amountN-in' and the other to+ 'amountN-out'. hledger will automatically negate the "out"+ field, and will use whichever field value is non-zero as+ posting N's amount.++ b. *If either field is signed:*+ You will probably need to override hledger's sign for one or+ the other field, as in the following example:++ # Negate the -out value, but only if it is not empty:+ fields date, description, amount1-in, amount1-out+ if %amount1-out [1-9]+ amount1-out -%amount1-out++ c. *If both fields can contain a non-zero value (or both can be+ empty):*+ The -in/-out rules normally choose the value which is+ non-zero/non-empty. Some value pairs can be ambiguous, such+ as '1' and 'none'. For such cases, use conditional rules to+ help select the amount. Eg, to handle the above you could+ select the value containing non-zero digits:++ fields date, description, in, out+ if %in [1-9]+ amount1 %in+ if %out [1-9]+ amount1 %out++ 3. *If you want posting 2's amount converted to cost:*+ Use the unnumbered 'amount' (or 'amount-in' and 'amount-out')+ syntax.++ 4. *If the CSV has only balance amounts, not transaction amounts:*+ Assign to 'balanceN', to set a balance assignment on the Nth+ posting, causing the posting's amount to be calculated+ automatically. 'balance' with no number is equivalent to+ 'balance1'. In this situation hledger is more likely to guess the+ wrong default account name, so you may need to set that explicitly.+++File: hledger.info, Node: Amount signs, Next: Setting currency/commodity, Prev: Setting amounts, Up: Working with CSV++10.18.10 Amount signs+---------------------++There is some special handling making it easier to parse and to reverse+amount signs. (This only works for whole amounts, not for cost amounts+such as COST in 'amount1 AMT @ COST'):++ * *If an amount value begins with a plus sign:*+ that will be removed: '+AMT' becomes 'AMT'++ * *If an amount value is parenthesised:*+ it will be de-parenthesised and sign-flipped: '(AMT)' becomes+ '-AMT'++ * *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'++ * *If an amount value contains just a sign (or just a set of+ parentheses):*+ that is removed, making it an empty value. '"+"' or '"-"' or+ '"()"' becomes '""'.++ It's not possible (without preprocessing the CSV) to set an amount to+its absolute value, ie discard its sign.+++File: hledger.info, Node: Setting currency/commodity, Next: Amount decimal places, Prev: Amount signs, Up: Working with CSV++10.18.11 Setting currency/commodity+-----------------------------------++If the currency/commodity symbol is included in the CSV's amount+field(s):++2023-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++2023-01-01 foo+ expenses:unknown $123.00+ income:unknown $-123.00++ If the currency is provided as a separate CSV field:++2023-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++2023-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++2023-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.+++File: hledger.info, Node: Amount decimal places, Next: Referencing other fields, Prev: Setting currency/commodity, Up: Working with CSV++10.18.12 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+decimal 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).+++File: hledger.info, Node: Referencing other fields, Next: How CSV rules are evaluated, Prev: Amount decimal places, Up: Working with CSV++10.18.13 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+literal "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+++File: hledger.info, Node: How CSV rules are evaluated, Next: Well factored rules, Prev: Referencing other fields, Up: Working with CSV++10.18.14 How CSV rules are evaluated+------------------------------------++Here's how to think of CSV rules being evaluated (if you really need+to). First,++ * '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:++ * 'skip' (at top level)+ * 'date-format'+ * 'newest-first'+ * 'fields' - names the CSV fields, optionally sets up initial+ assignments to hledger fields++ Then for each CSV record in turn:++ * 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.+ * 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.+ * compute a value for each hledger field - either the one that was+ assigned to it (and interpolate the %CSVFIELD references), or a+ default+ * generate a hledger transaction (journal entry) from these values.++ This is all part of the CSV reader, one of several readers hledger+can use to parse input files. When all files have been read+successfully, the transactions are passed as input to whichever hledger+command the user specified.+++File: hledger.info, Node: Well factored rules, Prev: How CSV rules are evaluated, Up: Working with CSV++10.18.15 Well factored rules+----------------------------++Some things than can help reduce duplication and complexity in rules+files:++ * Extracting common rules usable with multiple CSV files into a+ 'common.rules', and adding 'include common.rules' to each CSV's+ rules file.++ * Splitting if blocks into smaller if blocks, extracting the+ frequently used parts.+++File: hledger.info, Node: CSV rules examples, Prev: Working with CSV, Up: CSV++10.19 CSV rules examples+========================++* Menu:++* Bank of Ireland::+* Coinbase::+* Amazon::+* Paypal::+++File: hledger.info, Node: Bank of Ireland, Next: Coinbase, Up: CSV rules examples++10.19.1 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+necessary 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+reading directly from CSV, but they will be checked if these entries are+imported into a journal file.+++File: hledger.info, Node: Coinbase, Next: Amazon, Prev: Bank of Ireland, Up: CSV rules examples++10.19.2 Coinbase+----------------++A simple example with some CSV from Coinbase. The spot price is+recorded using cost notation. The legacy 'amount' field name+conveniently sets amount 2 (posting 2's amount) to the total cost.++# Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes+# 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,"","","","Received 100.00 USDC from an external account"++# coinbase.csv.rules+skip 1+fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes+date %Timestamp+date-format %Y-%m-%dT%T%Z+description %Notes+account1 assets:coinbase:cc+amount %Quantity_Transacted %Asset @ %Spot_Price_at_Transaction %Spot_Price_Currency++$ hledger print -f coinbase.csv+2021-12-30 Received 100.00 USDC from an external account+ assets:coinbase:cc 100 USDC @ 0.740000 GBP+ income:unknown -74.000000 GBP+++File: hledger.info, Node: Amazon, Next: Paypal, Prev: Coinbase, Up: CSV rules examples++10.19.3 Amazon+--------------++Here we convert amazon.com order history, and use an if block to+generate 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+++File: hledger.info, Node: Paypal, Prev: Amazon, Up: CSV rules examples++10.19.4 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:+++File: hledger.info, Node: Timeclock, Next: Timedot, Prev: CSV, Up: Top++11 Timeclock+************++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). Lines+beginning with '#' or ';' or '*', and blank lines, are ignored.++i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:+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 2 spaces ; optional comment, tags:+ (some account) 0.33h++2015-03-31 * 22:21-23:59+ (another:account) 1.64h++2015-04-01 * 00:00-02:00+ (another:account) 2.01h++ 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:++ * use emacs and the built-in timeclock.el, or the extended+ timeclock-x.el and perhaps the extras in ledgerutils.el++ * at the command line, use these bash aliases: 'cli alias ti="echo i+ `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o `date+ '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"'++ * 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.+++File: hledger.info, Node: Timedot, Next: PART 3 REPORTING CONCEPTS, Prev: Timeclock, Up: Top++12 Timedot+**********++'timedot' format is hledger's human-friendly time logging format.+Compared to 'timeclock' format, it is more convenient for quick,+approximate, and retroactive time logging, and more human-readable (you+can see at a glance where time was spent). A quick example:++2023-05-01+hom:errands .... .... ; two hours; the space is ignored+fos:hledger:timedot .. ; half an hour+per:admin:finance ; no time spent yet++ hledger reads this as a transaction on this day with three+(unbalanced) postings, where each dot represents "0.25". No commodity+symbol is assumed, but we typically interpret it as hours.++$ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required+2023-05-01 *+ (hom:errands) 2.00 ; two hours+ (fos:hledger:timedot) 0.50 ; half an hour+ (per:admin:finance) 0++ A timedot file contains a series of transactions (usually one per+day). Each begins with a *simple date* (Y-M-D, Y/M/D, or Y.M.D),+optionally be followed on the same line by a transaction description,+and/or a transaction comment following a semicolon.++ After the date line are zero or more time postings, consisting of:++ * *An account name* - any hledger-style account name, optionally+ indented.++ * *Two or more spaces* - required if there is an amount (as in+ journal format).++ * *A timedot amount*, which can be++ * empty (representing zero)++ * a number, optionally followed by a unit 's', 'm', 'h', 'd',+ 'w', 'mo', or 'y', representing a precise number of seconds,+ minutes, hours, days weeks, months or years (hours is assumed+ by default), which will be converted to hours according to 60s+ = 1m, 60m = 1h, 24h = 1d, 7d = 1w, 30d = 1mo, 365d = 1y.++ * one or more dots (period characters), each representing 0.25.+ These are the dots in "timedot". Spaces are ignored and can+ be used for grouping/alignment.++ * _Added in 1.32_ one or more letters. These are like dots but+ they also generate a tag 't:' (short for "type") with the+ letter as its value, and a separate posting for each of the+ values. This provides a second dimension of categorisation,+ viewable in reports with '--pivot t'.++ * *An optional comment* following a semicolon (a hledger-style+ posting comment).++ There is some flexibility to help with keeping time log data and+notes in the same file:++ * Blank lines and lines beginning with '#' or ';' are ignored.++ * After the first date line, lines which do not contain a double+ space are parsed as postings with zero amount. (hledger's register+ reports will show these if you add -E).++ * Before the first date line, lines beginning with '*' (eg org+ headings) are ignored. And from the first date line onward, Emacs+ org mode heading prefixes at the start of lines (one or more '*''s+ followed by a space) will be ignored. This means the time log can+ also be a org outline.++* Menu:++* Timedot examples::+++File: hledger.info, Node: Timedot examples, Up: Timedot++12.1 Timedot examples+=====================++Numbers:++2016/2/3+inc:client1 4+fos:hledger 3h+biz:research 60m++ Dots:++# 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 .++$ 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 ++ Letters:++# Activity types:+# c cleanup/catchup/repair+# e enhancement+# s support+# l learning/research++2023-11-01+work:adm ccecces++$ hledger -f a.timedot print+2023-11-01+ (work:adm) 1 ; t:c+ (work:adm) 0.5 ; t:e+ (work:adm) 0.25 ; t:s++$ hledger -f a.timedot bal+ 1.75 work:adm+--------------------+ 1.75 ++$ hledger -f a.timedot bal --pivot t+ 1.00 c+ 0.50 e+ 0.25 s+--------------------+ 1.75 ++ Org:++* 2023 Work Diary+** Q1+*** 2023-02-29+**** DONE+0700 yoga+**** UNPLANNED+**** BEGUN+hom:chores+ cleaning ...+ water plants+ outdoor - one full watering can+ indoor - light watering+**** TODO+adm:planning: trip+*** LATER++ Using '.' as account name separator:++2016/2/4+fos.hledger.timedot 4h+fos.ledger ..++$ hledger -f a.timedot --alias '/\./=:' bal -t+ 4.50 fos+ 4.00 hledger:timedot+ 0.50 ledger+--------------------+ 4.50+++File: hledger.info, Node: PART 3 REPORTING CONCEPTS, Next: Amount formatting, Prev: Timedot, Up: Top++13 PART 3: REPORTING CONCEPTS+*****************************+++File: hledger.info, Node: Amount formatting, Next: Time periods, Prev: PART 3 REPORTING CONCEPTS, Up: Top++14 Amount formatting+********************++* Menu:++* Commodity display style::+* Rounding::+* Trailing decimal marks::+* Amount parseability::+++File: hledger.info, Node: Commodity display style, Next: Rounding, Up: Amount formatting++14.1 Commodity display style+============================++For the amounts in each commodity, hledger chooses a consistent display+style (symbol placement, decimal mark and digit group marks, number of+decimal digits) to use in most reports. This is inferred as follows:++ First, if there's a 'D' directive declaring a default commodity, that+commodity symbol and amount format is applied to all no-symbol amounts+in the journal.++ Then each commodity's display style is determined from its+'commodity' directive. We recommend always declaring commodities with+'commodity' directives, since they help ensure consistent display styles+and precisions, and bring other benefits such as error checking for+commodity symbols. Here's an example:++# Set display styles (and decimal marks, for parsing, if there is no decimal-mark directive)+# for the $, EUR, INR and no-symbol commodities:+commodity $1,000.00+commodity EUR 1.000,00+commodity INR 9,99,99,999.00+commodity 1 000 000.9455++ But for convenience, if a 'commodity' directive is not present,+hledger infers a commodity's display styles from its amounts as they are+written in the journal (excluding cost amounts and amounts in periodic+transaction rules or auto posting rules). It uses++ * the symbol placement and decimal mark of the first amount seen+ * the digit group marks of the first amount with digit group marks+ * and the maximum number of decimal digits seen across all amounts.++ And as fallback if no applicable amounts are found, it would use a+default style, like '$1000.00' (symbol on the left with no space, period+as decimal mark, and two decimal digits).++ Finally, commodity styles can be overridden by the+'-c/--commodity-style' command line option.+++File: hledger.info, Node: Rounding, Next: Trailing decimal marks, Prev: Commodity display style, Up: Amount formatting++14.2 Rounding+=============++Amounts are stored internally as decimal numbers with up to 255 decimal+places. They are displayed with their original journal precisions by+print and print-like reports, and rounded to their display precision+(the number of decimal digits specified by the commodity display style)+by other reports. When rounding, hledger uses banker's rounding (it+rounds to the nearest even digit). So eg 0.5 displayed with zero+decimal digits appears as "0".+++File: hledger.info, Node: Trailing decimal marks, Next: Amount parseability, Prev: Rounding, Up: Amount formatting++14.3 Trailing decimal marks+===========================++If you're wondering why your 'print' report sometimes shows trailing+decimal marks, with no decimal digits; it does this when showing amounts+that have digit group marks but no decimal digits, to disambiguate them+and allow them to be re-parsed reliably (see Decimal marks). Eg:++commodity $1,000.00++2023-01-02+ (a) $1000++$ hledger print+2023-01-02+ (a) $1,000.++ If this is a problem (eg when exporting to Ledger), you can avoid it+by disabling digit group marks, eg with -c/-commodity (for each affected+commodity):++$ hledger print -c '$1000.00'+2023-01-02+ (a) $1000++ or by forcing print to always show decimal digits, with -round:++$ hledger print -c '$1,000.00' --round=soft+2023-01-02+ (a) $1,000.00+++File: hledger.info, Node: Amount parseability, Prev: Trailing decimal marks, Up: Amount formatting++14.4 Amount parseability+========================++More generally, hledger output falls into three rough categories, which+format amounts a little bit differently to suit different consumers:++ *1. "hledger-readable output" - should be readable by hledger (and+by humans)*++ * This is produced by reports that show full journal entries:+ 'print', 'import', 'close', 'rewrite' etc.+ * It shows amounts with their original journal precisions, which may+ not be consistent.+ * It adds a trailing decimal mark when needed to avoid showing+ ambiguous amounts.+ * It can be parsed reliably (by hledger and ledger2beancount at+ least, but perhaps not by Ledger..)++ *2. "human-readable output" - usually for humans*++ * This is produced by all other reports.+ * It shows amounts with standard display precisions, which will be+ consistent within each commodity.+ * It shows ambiguous amounts unmodified.+ * It can be parsed reliably in the context of a known report (when+ you know decimals are consistently not being shown, you can assume+ a single mark is a digit group mark).++ *3. "machine-readable output" - usually for other software*++ * This is produced by all reports when an output format like 'csv',+ 'tsv', 'json', or 'sql' is selected.+ * It shows amounts as 1 or 2 do, but without digit group marks.+ * It can be parsed reliably (if needed, the decimal mark can be+ changed with -c/-commodity-style).+++File: hledger.info, Node: Time periods, Next: Depth, Prev: Amount formatting, Up: Top++15 Time periods+***************++* Menu:++* Report start & end date::+* Smart dates::+* Report intervals::+* Date adjustment::+* Period expressions::+++File: hledger.info, Node: Report start & end date, Next: Smart dates, Up: Time periods++15.1 Report start & end date+============================++By default, most hledger reports will show the full span of time+represented by the journal. The report start date will be the earliest+transaction or posting date, and the report end date will be the latest+transaction, posting, or market price date.++ Often you will want to see a shorter time span, such as the current+month. You can specify a start and/or end date using '-b/--begin',+'-e/--end', '-p/--period' or a 'date:' query (described below). All of+these accept the smart date syntax (below).++ Some notes:++ * End dates are exclusive, as in Ledger, so you should write the date+ _after_ the last day you want to see in the report.+ * As noted in reporting options: among start/end dates specified with+ _options_, the last (i.e. right-most) option takes precedence.+ * 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.+ * In some cases a report interval will adjust start/end dates to fall+ on interval boundaries (see below).++ Examples:++'-b begin on St. Patrick's day 2016+2016/3/17'+'-e 12/1' end at the start of december 1st of the current year+ (11/30 will be the last date included)+'-b all transactions on or after the 1st of the current month+thismonth'+'-p all transactions in the current month+thismonth'+'date:2016/3/17..'the above written as queries instead ('..' can also be+ replaced with '-')+'date:..12/1'+'date:thismonth..'+'date:thismonth'+++File: hledger.info, Node: Smart dates, Next: Report intervals, Prev: Report start & end date, Up: Time periods++15.2 Smart dates+================++hledger's user interfaces accept a "smart date" syntax for added+convenience. Smart dates optionally can be relative to today's date, be+written with english words, and have less-significant parts omitted+(missing parts are inferred as 1). Some examples:++'2004/10/1', exact date, several separators allowed. Year+'2004-01-01', is 4+ digits, month is 1-12, day is 1-31+'2004.9.1'+'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, -1, 0, 1 days from today+tomorrow'+'last/this/next -1, 0, 1 periods from the current period+day/week/month/quarter/year'+'in n n periods from the current period+days/weeks/months/quarters/years'+'n n periods from the current period+days/weeks/months/quarters/years+ahead'+'n -n periods from the current period+days/weeks/months/quarters/years+ago'+'20181201' 8 digit YYYYMMDD with valid year month and+ day+'201812' 6 digit YYYYMM with valid year and month++ Some 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++ "Today's date" can be overridden with the '--today' option, in case+it's needed for testing or for recreating old reports. (Except for+periodic transaction rules, which are not affected by '--today'.)+++File: hledger.info, Node: Report intervals, Next: Date adjustment, Prev: Smart dates, Up: Time periods++15.3 Report intervals+=====================++A report interval can be specified so that reports like register,+balance or activity become multi-period, showing each subperiod as a+separate row or column.++ The following standard intervals can be enabled with command-line+flags:++ * '-D/--daily'+ * '-W/--weekly'+ * '-M/--monthly'+ * '-Q/--quarterly'+ * '-Y/--yearly'++ More complex intervals can be specified using '-p/--period',+described below.+++File: hledger.info, Node: Date adjustment, Next: Period expressions, Prev: Report intervals, Up: Time periods++15.4 Date adjustment+====================++When there is a report interval (other than daily), report start/end+dates which have been inferred, eg from the journal, are automatically+adjusted to natural period boundaries. This is convenient for producing+simple periodic reports. More precisely:++ * an inferred start date will be adjusted earlier if needed to fall+ on a natural period boundary++ * an inferred end date will be adjusted later if needed to make the+ last period the same length as the others.++ By contrast, start/end dates which have been specified explicitly,+with '-b', '-e', '-p' or 'date:', will not be adjusted (since hledger+1.29). This makes it possible to specify non-standard report periods,+but it also means that if you are specifying a start date, you should+pick one that's on a period boundary if you want to see simple report+period headings.+++File: hledger.info, Node: Period expressions, Prev: Date adjustment, Up: Time periods++15.5 Period expressions+=======================++The '-p/--period' option specifies a period expression, which is a+compact way of expressing a start date, end date, and/or report+interval.++ Here's a period expression with a start and end date (specifying the+first quarter of 2009):++'-p "from 2009/1/1 to 2009/4/1"'++ Several keywords like "from" and "to" are supported for readability;+these are optional. "to" can also be written as ".." or "-". The+spaces are also optional, as long as you don't run two dates together.+So the following are equivalent to the above:++'-p "2009/1/1 2009/4/1"'+'-p2009/1/1to2009/4/1'+'-p2009/1/1..2009/4/1'++ Dates are smart dates, so if the current year is 2009, these are also+equivalent to the above:++'-p "1/1 4/1"'+'-p "jan-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 date in the journal:++'-p "from 2009/1/1"' everything after january 1, 2009+'-p "since 2009/1"' the same, since is a synonym+'-p "from 2009"' the same+'-p "to 2009"' everything before january 1, 2009++ You can also specify a period by writing a single partial or full+date:++'-p "2009"' the year 2009; equivalent to “2009/1/1 to 2010/1/1”+'-p "2009/1"' the month of january 2009; equivalent to “2009/1/1 to+ 2009/2/1”+'-p the first day of 2009; equivalent to “2009/1/1 to+"2009/1/1"' 2009/1/2”++ or by using the "Q" quarter-year syntax (case insensitive):++'-p "2009Q1"' first quarter of 2009, equivalent to “2009/1/1 to+ 2009/4/1”+'-p "q4"' fourth quarter of the current year++* Menu:++* Period expressions with a report interval::+* More complex report intervals::+* Multiple weekday intervals::+++File: hledger.info, Node: Period expressions with a report interval, Next: More complex report intervals, Up: Period expressions++15.5.1 Period expressions with a report interval+------------------------------------------------++A period expression can also begin with a report interval, separated+from the start/end dates (if any) by a space or the word 'in':++'-p "weekly from 2009/1/1 to 2009/4/1"'+'-p "monthly in 2008"'+'-p "quarterly"'+++File: hledger.info, Node: More complex report intervals, Next: Multiple weekday intervals, Prev: Period expressions with a report interval, Up: Period expressions++15.5.2 More complex report intervals+------------------------------------++Some more complex intervals can be specified within period expressions,+such as:++ * 'biweekly' (every two weeks)+ * 'fortnightly'+ * 'bimonthly' (every two months)+ * 'every day|week|month|quarter|year'+ * 'every N days|weeks|months|quarters|years'++ Weekly on a custom day:++ * 'every Nth day of week' ('th', 'nd', 'rd', or 'st' are all accepted+ after the number)+ * 'every WEEKDAYNAME' (full or three-letter english weekday name,+ case insensitive)++ Monthly on a custom day:++ * 'every Nth day [of month]'+ * 'every Nth WEEKDAYNAME [of month]'++ Yearly on a custom day:++ * 'every MM/DD [of year]' (month number and day of month number)+ * 'every MONTHNAME DDth [of year]' (full or three-letter english+ month name, case insensitive, and day of month number)+ * 'every DDth MONTHNAME [of year]' (equivalent to the above)++ Examples:++'-p "bimonthly from+2008"'+'-p "every 2 weeks"'+'-p "every 5 months from+2009/03"'+'-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+ November+'-p "every 5th November"' same+'-p "every Nov 5th"' same++ Show historical balances at end of the 15th day of each month (N is+an end date, exclusive as always):++$ hledger balance -H -p "every 16th day"++ Group postings from the start of wednesday to end of the following+tuesday (N is both (inclusive) start date and (exclusive) end date):++$ hledger register checking -p "every 3rd day of week"+++File: hledger.info, Node: Multiple weekday intervals, Prev: More complex report intervals, Up: Period expressions++15.5.3 Multiple weekday intervals+---------------------------------++This special form is also supported:++ * 'every WEEKDAYNAME,WEEKDAYNAME,...' (full or three-letter english+ weekday names, case insensitive)++ Also, 'weekday' and 'weekendday' are shorthand for+'mon,tue,wed,thu,fri' and 'sat,sun'.++ This is mainly intended for use with '--forecast', to generate+periodic transactions on arbitrary days of the week. It may be less+useful with '-p', since it divides each week into subperiods of unequal+length, which is unusual. (Related: #1632)++ Examples:++'-p "every dates will be Mon, Wed, Fri; periods will be+mon,wed,fri"' Mon-Tue, Wed-Thu, Fri-Sun+'-p "every dates will be Mon, Tue, Wed, Thu, Fri; periods will+weekday"' be Mon, Tue, Wed, Thu, Fri-Sun+'-p "every dates will be Sat, Sun; periods will be Sat, Sun-Fri+weekendday"'+++File: hledger.info, Node: Depth, Next: Queries, Prev: Time periods, Up: Top++16 Depth+********++With the '--depth NUM' option (short form: '-NUM'), reports will show+accounts only to the specified depth, hiding deeper subaccounts. Use+this when you want a summary with less detail. This flag has the same+effect as a 'depth:' query argument: 'depth:2', '--depth=2' or '-2' are+equivalent.+++File: hledger.info, Node: Queries, Next: Pivoting, Prev: Depth, Up: Top++17 Queries+**********++One of hledger's strengths is being able to quickly report on a precise+subset of your data. Most hledger commands accept query arguments, to+restrict their scope. Multiple query terms can be provided to build up+a more complex query.++ * By default, a query term is interpreted as a case-insensitive+ substring pattern for matching account names:++ 'car:fuel'+ 'dining groceries'++ * Patterns containing spaces or other special characters must be+ enclosed in single or double quotes:++ ''personal care''++ * These patterns are actually regular expressions, so you can add+ regexp metacharacters for more precision (see "Regular expressions"+ above for details):++ ''^expenses\b''+ ''food$''+ ''fuel|repair''+ ''accounts (payable|receivable)''++ * To match something other than account name, add one of the query+ type prefixes described in "Query types" below:++ 'date:202312-'+ 'status:'+ 'desc:amazon'+ 'cur:USD'+ 'cur:\\$'+ 'amt:'>0''++ * Add a 'not:' prefix to negate a term:++ 'not:status:'*''+ 'not:desc:'opening|closing''+ 'not:cur:USD'++ * Terms with different types are AND-ed, terms with the same type are+ OR-ed (mostly; see "Combining query terms" below). The following+ query:++ 'date:2022 desc:amazon desc:amzn'++ is interpreted as:++ _date is in 2022 AND ( transaction description contains "amazon" OR+ "amzn" )_++* Menu:++* Query types::+* Combining query terms::+* Queries and command options::+* Queries and account aliases::+* Queries and valuation::+++File: hledger.info, Node: Query types, Next: Combining query terms, Up: Queries++17.1 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'* or *'REGEX'*+Match account names containing this case insensitive regular expression.+This is the default query type, so we usually don't bother writing the+"acct:" prefix.++ *'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.+Otherwise, the absolute magnitudes are compared, ignoring sign.++ *'code:REGEX'*+Match by transaction code (eg check number).++ *'cur:REGEX'*+Match postings or transactions including any amounts whose+currency/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.++ *'expr:"TERM AND NOT (TERM OR TERM)"'* (eg)+Match with a boolean combination of queries (which must be enclosed in+quotes). See Combining query terms below.++ *'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.++ *'type:TYPECODES'*+Match by account type (see Declaring accounts > Account types).+'TYPECODES' is one or more of the single-letter account type codes+'ALERXCV', case insensitive. Note 'type:A' and 'type:E' will also match+their respective subtypes 'C' (Cash) and 'V' (Conversion). Certain+kinds of account alias can disrupt account types, see Rewriting accounts+> Aliases and account types.++ *'tag:REGEX[=REGEX]'*+Match by tag name, and optionally also by tag value. (To match only by+value, use 'tag:.=REGEX'.)++ When querying by tag, note that:++ * Accounts also inherit the tags of their parent accounts+ * Postings also inherit the tags of their account and their+ transaction+ * Transactions also acquire the tags of their postings.++ (*'inacct:ACCTNAME'*+A special query term used automatically in hledger-web only: tells+hledger-web to show the transaction register for an account.)+++File: hledger.info, Node: Combining query terms, Next: Queries and command options, Prev: Query types, Up: Queries++17.2 Combining query terms+==========================++When given multiple space-separated query terms, most commands select+things which match:++ * any of the description terms AND+ * any of the account terms AND+ * any of the status terms AND+ * all the other terms.++ The print command is a little different, showing transactions which:++ * match any of the description terms AND+ * have any postings matching any of the positive account terms AND+ * have no postings matching any of the negative account terms AND+ * match all the other terms.++ We also support more complex boolean queries with the 'expr:' prefix.+This allows one to combine query terms using 'and', 'or', 'not' keywords+(case insensitive), and to group them by enclosing in parentheses.++ Some examples:++ * Exclude account names containing 'food':++ 'expr:"not food"' ('not:food' is equivalent)++ * Match things which have 'cool' in the description and the 'A' tag:++ 'expr:"desc:cool and tag:A"' ('expr:"desc:cool tag:A"' is+ equivalent)++ * Match things which either do not reference the 'expenses:food'+ account, or do have the 'A' tag:++ 'expr:"not expenses:food or tag:A"'++ * Match things which either do not reference the 'expenses:food'+ account, or which reference the 'expenses:drink' account and also+ have the 'A' tag:++ 'expr:"expenses:food or (expenses:drink and tag:A)"'++ 'expr:' has a restriction: 'date:' queries may not be used inside+'or' expressions. That would allow disjoint report periods or disjoint+result sets, with unclear semantics for our reports.+++File: hledger.info, Node: Queries and command options, Next: Queries and account aliases, Prev: Combining query terms, Up: Queries++17.3 Queries and command options+================================++Some queries can also be expressed as command-line options: 'depth:2' is+equivalent to '--depth 2', 'date:2023' is equivalent to '-p 2023', etc.+When you mix command options and query arguments, generally the+resulting query is their intersection.+++File: hledger.info, Node: Queries and account aliases, Next: Queries and valuation, Prev: Queries and command options, Up: Queries++17.4 Queries and account aliases+================================++When account names are rewritten with '--alias' or 'alias', 'acct:' will+match either the old or the new account name.+++File: hledger.info, Node: Queries and valuation, Prev: Queries and account aliases, Up: Queries++17.5 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, #1625.)+++File: hledger.info, Node: Pivoting, Next: Generating data, Prev: Queries, Up: Top++18 Pivoting+***********++Normally, hledger groups and sums amounts within each account. The+'--pivot FIELD' option substitutes some other transaction field for+account names, causing amounts to be grouped and summed by that field's+value instead. FIELD can be any of the transaction fields 'acct',+'status', 'code', 'desc', 'payee', 'note', or a tag name. When pivoting+on a tag and a posting has multiple values of that tag, only the first+value is displayed. Values containing 'colon:separated:parts' will be+displayed hierarchically, like account names. Multiple, colon-delimited+fields can be pivoted simultaneously, generating a hierarchical account+name.++ Some examples:++2016/02/16 Yearly Dues Payment+ assets:bank account 2 EUR+ income:dues -2 EUR ; member: John Doe, kind: Lifetime++ Normal balance report showing account names:++$ hledger balance+ 2 EUR assets:bank account+ -2 EUR income:dues+--------------------+ 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):++$ 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++ Hierarchical reports can be generated with multiple pivots:++$ hledger balance Income:Dues --pivot kind:member+ -2 EUR Lifetime:John Doe+--------------------+ -2 EUR+++File: hledger.info, Node: Generating data, Next: Forecasting, Prev: Pivoting, Up: Top++19 Generating data+******************++hledger has several features for generating data, such as:++ * Periodic transaction rules can generate single or repeating+ transactions following a template. These are usually dated in the+ future, eg to help with forecasting. They are activated by the+ '--forecast' option.++ * The balance command's '--budget' option uses these same periodic+ rules to generate goals for the budget report.++ * Auto posting rules can generate extra postings on certain matched+ transactions. They are always applied to forecast transactions;+ with the '--auto' flag they are applied to transactions recorded in+ the journal as well.++ * The '--infer-equity' flag infers missing conversion equity postings+ from @/@@ costs. And the inverse '--infer-costs' flag infers+ missing @/@@ costs from conversion equity postings.++ Generated data of this kind is temporary, existing only at report+time. But you can see it in the output of 'hledger print', and you can+save that to your journal, in effect converting it from temporary+generated data to permanent recorded data. This could be useful as a+data entry aid.++ If you are wondering what data is being generated and why, add the+'--verbose-tags' flag. In 'hledger print' output you will see extra+tags like 'generated-transaction', 'generated-posting', and 'modified'+on generated/modified data. Also, even without '--verbose-tags',+generated data always has equivalen hidden tags (with an underscore+prefix), so eg you could match generated transactions with+'tag:_generated-transaction'.+++File: hledger.info, Node: Forecasting, Next: Budgeting, Prev: Generating data, Up: Top++20 Forecasting+**************++Forecasting, or speculative future reporting, can be useful for+estimating future balances, or for exploring different future scenarios.++ The simplest and most flexible way to do it with hledger is to+manually record a bunch of future-dated transactions. You could keep+these in a separate 'future.journal' and include that with '-f' only+when you want to see them.++* Menu:++* --forecast::+* Inspecting forecast transactions::+* Forecast reports::+* Forecast tags::+* Forecast period in detail::+* Forecast troubleshooting::+++File: hledger.info, Node: --forecast, Next: Inspecting forecast transactions, Up: Forecasting++20.1 -forecast+==============++There is another way: with the '--forecast' option, hledger can generate+temporary "forecast transactions" for reporting purposes, according to+periodic transaction rules defined in the journal. Each rule can+generate multiple recurring transactions, so by changing one rule you+can change many forecasted transactions.++ Forecast transactions usually start after ordinary transactions end.+By default, they begin after your latest-dated ordinary transaction, or+today, whichever is later, and they end six months from today. (The+exact rules are a little more complicated, and are given below.)++ This is the "forecast period", which need not be the same as the+report period. You can override it - eg to forecast farther into the+future, or to force forecast transactions to overlap your ordinary+transactions - by giving the -forecast option a period expression+argument, like '--forecast=..2099' or '--forecast=2023-02-15..'. Note+that the '=' is required.+++File: hledger.info, Node: Inspecting forecast transactions, Next: Forecast reports, Prev: --forecast, Up: Forecasting++20.2 Inspecting forecast transactions+=====================================++'print' is the best command for inspecting and troubleshooting forecast+transactions. Eg:++~ monthly from 2022-12-20 rent+ assets:bank:checking+ expenses:rent $1000++$ hledger print --forecast --today=2023/4/21+2023-05-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++2023-06-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++2023-07-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++2023-08-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++2023-09-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ Here there are no ordinary transactions, so the forecasted+transactions begin on the first occurence after today's date. (You+won't normally use '--today'; it's just to make these examples+reproducible.)+++File: hledger.info, Node: Forecast reports, Next: Forecast tags, Prev: Inspecting forecast transactions, Up: Forecasting++20.3 Forecast reports+=====================++Forecast transactions affect all reports, as you would expect. Eg:++$ hledger areg rent --forecast --today=2023/4/21+Transactions in expenses:rent and subaccounts:+2023-05-20 rent as:ba:checking $1000 $1000+2023-06-20 rent as:ba:checking $1000 $2000+2023-07-20 rent as:ba:checking $1000 $3000+2023-08-20 rent as:ba:checking $1000 $4000+2023-09-20 rent as:ba:checking $1000 $5000++$ hledger bal -M expenses --forecast --today=2023/4/21+Balance changes in 2023-05-01..2023-09-30:++ || May Jun Jul Aug Sep +===============++===================================+ expenses:rent || $1000 $1000 $1000 $1000 $1000 +---------------++-----------------------------------+ || $1000 $1000 $1000 $1000 $1000 +++File: hledger.info, Node: Forecast tags, Next: Forecast period in detail, Prev: Forecast reports, Up: Forecasting++20.4 Forecast tags+==================++Forecast transactions generated by -forecast have a hidden tag,+'_generated-transaction'. So if you ever need to match forecast+transactions, you could use 'tag:_generated-transaction' (or just+'tag:generated') in a query.++ For troubleshooting, you can add the '--verbose-tags' flag. Then,+visible 'generated-transaction' tags will be added also, so you can view+them with the 'print' command. Their value indicates which periodic+rule was responsible.+++File: hledger.info, Node: Forecast period in detail, Next: Forecast troubleshooting, Prev: Forecast tags, Up: Forecasting++20.5 Forecast period, in detail+===============================++Forecast start/end dates are chosen so as to do something useful by+default in almost all situations, while also being flexible. Here are+(with luck) the exact rules, to help with troubleshooting:++ The forecast period starts on:++ * the later of+ * the start date in the periodic transaction rule+ * the start date in '--forecast''s argument++ * otherwise (if those are not available): the later of+ * the report start date specified with '-b'/'-p'/'date:'+ * the day after the latest ordinary transaction in the journal++ * otherwise (if none of these are available): today.++ The forecast period ends on:++ * the earlier of+ * the end date in the periodic transaction rule+ * the end date in '--forecast''s argument++ * otherwise: the report end date specified with '-e'/'-p'/'date:'+ * otherwise: 180 days (~6 months) from today.+++File: hledger.info, Node: Forecast troubleshooting, Prev: Forecast period in detail, Up: Forecasting++20.6 Forecast troubleshooting+=============================++When -forecast is not doing what you expect, one of these tips should+help:++ * Remember to use the '--forecast' option.+ * Remember to have at least one periodic transaction rule in your+ journal.+ * Test with 'print --forecast'.+ * Check for typos or too-restrictive start/end dates in your periodic+ transaction rule.+ * Leave at least 2 spaces between the rule's period expression and+ description fields.+ * Check for future-dated ordinary transactions suppressing forecasted+ transactions.+ * Try setting explicit report start and/or end dates with '-b', '-e',+ '-p' or 'date:'+ * Try adding the '-E' flag to encourage display of empty periods/zero+ transactions.+ * Try setting explicit forecast start and/or end dates with+ '--forecast=START..END'+ * Consult Forecast period, in detail, above.+ * Check inside the engine: add '--debug=2' (eg).+++File: hledger.info, Node: Budgeting, Next: Cost reporting, Prev: Forecasting, Up: Top++21 Budgeting+************++With the balance command's '--budget' report, each periodic transaction+rule generates recurring budget goals in specified accounts, and goals+and actual performance can be compared. See the balance command's doc+below.++ You can generate budget goals and forecast transactions at the same+time, from the same or different periodic transaction rules: 'hledger+bal -M --budget --forecast ...'++ See also: Budgeting and Forecasting.+++File: hledger.info, Node: Cost reporting, Next: Value reporting, Prev: Budgeting, Up: Top++22 Cost reporting+*****************++In some transactions - for example a currency conversion, or a purchase+or sale of stock - one commodity is exchanged for another. In these+transactions there is a conversion rate, also called the cost (when+buying) or selling price (when selling). In hledger docs we just say+"cost", for convenience; feel free to mentally translate to "conversion+rate" or "selling price" if helpful.++* Menu:++* Recording costs::+* Reporting at cost::+* Equity conversion postings::+* Inferring equity conversion postings::+* Combining costs and equity conversion postings::+* Requirements for detecting equity conversion postings::+* Infer cost and equity by default ?::+++File: hledger.info, Node: Recording costs, Next: Reporting at cost, Up: Cost reporting++22.1 Recording costs+====================++We'll explore several ways of recording transactions involving costs.+These are also summarised at hledger Cookbook > Cost notation.++ Costs can be recorded explicitly in the journal, using the '@+UNITCOST' or '@@ TOTALCOST' notation described in Journal > Costs:++ *Variant 1*++2022-01-01+ assets:dollars $-135+ assets:euros €100 @ $1.35 ; $1.35 per euro (unit cost)++ *Variant 2*++2022-01-01+ assets:dollars $-135+ assets:euros €100 @@ $135 ; $135 total cost++ Typically, writing the unit cost (variant 1) is preferable; it can be+more effort, requiring more attention to decimal digits; but it reveals+the per-unit cost basis, and makes stock sales easier.++ Costs can also be left implicit, and hledger will infer the cost that+is consistent with a balanced transaction:++ *Variant 3*++2022-01-01+ assets:dollars $-135+ assets:euros €100++ Here, hledger will attach a '@@ €100' cost to the first amount (you+can see it with 'hledger print -x'). This form looks convenient, but+there are downsides:++ * It sacrifices some error checking. For example, if you+ accidentally wrote €10 instead of €100, hledger would not be able+ to detect the mistake.++ * It is sensitive to the order of postings - if they were reversed, a+ different entry would be inferred and reports would be different.++ * The per-unit cost basis is not easy to read.++ So generally this kind of entry is not recommended. You can make+sure you have none of these by using '-s' (strict mode), or by running+'hledger check balanced'.+++File: hledger.info, Node: Reporting at cost, Next: Equity conversion postings, Prev: Recording costs, Up: Cost reporting++22.2 Reporting at cost+======================++Now when you add the '-B'/'--cost' flag to reports ("B" is from Ledger's+-B/-basis/-cost flag), any amounts which have been annotated with costs+will be converted to their cost's commodity (in the report output). Ie+they will be displayed "at cost" or "at sale price".++ Some things to note:++ * Costs are attached to specific posting amounts in specific+ transactions, and once recorded they do not change. This contrasts+ with market prices, which are ambient and fluctuating.++ * Conversion to cost is performed before conversion to market value+ (described below).+++File: hledger.info, Node: Equity conversion postings, Next: Inferring equity conversion postings, Prev: Reporting at cost, Up: Cost reporting++22.3 Equity conversion postings+===============================++There is a problem with the entries above - they are not conventional+Double Entry Bookkeeping (DEB) notation, and because of the "magical"+transformation of one commodity into another, they cause an imbalance in+the Accounting Equation. This shows up as a non-zero grand total in+balance reports like 'hledger bse'.++ For most hledger users, this doesn't matter in practice and can+safely be ignored ! But if you'd like to learn more, keep reading.++ Conventional DEB uses an extra pair of equity postings to balance the+transaction. Of course you can do this in hledger as well:++ *Variant 4*++2022-01-01+ assets:dollars $-135+ assets:euros €100+ equity:conversion $135+ equity:conversion €-100++ Now the transaction is perfectly balanced according to standard DEB,+and 'hledger bse''s total will not be disrupted.++ And, hledger can still infer the cost for cost reporting, but it's+not done by default - you must add the '--infer-costs' flag like so:++$ hledger print --infer-costs+2022-01-01 one hundred euros purchased at $1.35 each+ assets:dollars $-135 @@ €100+ assets:euros €100+ equity:conversion $135+ equity:conversion €-100++$ hledger bal --infer-costs -B+ €-100 assets:dollars + €100 assets:euros +-------------------- + 0 ++ Here are some downsides of this kind of entry:++ * The per-unit cost basis is not easy to read.++ * Instead of '-B' you must remember to type '-B --infer-costs'.++ * '--infer-costs' works only where hledger can identify the two+ equity:conversion postings and match them up with the two+ non-equity postings. So writing the journal entry in a particular+ format becomes more important. More on this below.+++File: hledger.info, Node: Inferring equity conversion postings, Next: Combining costs and equity conversion postings, Prev: Equity conversion postings, Up: Cost reporting++22.4 Inferring equity conversion postings+=========================================++Can we go in the other direction ? Yes, if you have transactions+written with the @/@@ cost notation, hledger can infer the missing+equity postings, if you add the '--infer-equity' flag. Eg:++2022-01-01+ assets:dollars -$135+ assets:euros €100 @ $1.35++$ hledger print --infer-equity+2022-01-01+ assets:dollars $-135+ assets:euros €100 @ $1.35+ equity:conversion:$-€:€ €-100+ equity:conversion:$-€:$ $135.00++ The equity account names will be "equity:conversion:A-B:A" and+"equity:conversion:A-B:B" where A is the alphabetically first commodity+symbol. You can customise the "equity:conversion" part by declaring an+account with the 'V'/'Conversion' account type.+++File: hledger.info, Node: Combining costs and equity conversion postings, Next: Requirements for detecting equity conversion postings, Prev: Inferring equity conversion postings, Up: Cost reporting++22.5 Combining costs and equity conversion postings+===================================================++Finally, you can use both the @/@@ cost notation and equity postings at+the same time. This in theory gives the best of all worlds - preserving+the accounting equation, revealing the per-unit cost basis, and+providing more flexibility in how you write the entry:++ *Variant 5*++2022-01-01 one hundred euros purchased at $1.35 each+ assets:dollars $-135+ equity:conversion $135+ equity:conversion €-100+ assets:euros €100 @ $1.35++ All the other variants above can (usually) be rewritten to this final+form with:++$ hledger print -x --infer-costs --infer-equity++ Downsides:++ * The precise format of the journal entry becomes more important. If+ hledger can't detect and match up the cost and equity postings, it+ will give a transaction balancing error.++ * The add command does not yet accept this kind of entry (#2056).++ * This is the most verbose form.+++File: hledger.info, Node: Requirements for detecting equity conversion postings, Next: Infer cost and equity by default ?, Prev: Combining costs and equity conversion postings, Up: Cost reporting++22.6 Requirements for detecting equity conversion postings+==========================================================++'--infer-costs' has certain requirements (unlike '--infer-equity', which+always works). It will infer costs only in transactions with:++ * Two non-equity postings, in different commodities. Their order is+ significant: the cost will be added to the first of them.++ * Two postings to equity conversion accounts, next to one another,+ which balance the two non-equity postings. This balancing is+ checked to the same precision (number of decimal places) used in+ the conversion posting's amount. Equity conversion accounts are:++ * any accounts declared with account type 'V'/'Conversion', or+ their subaccounts+ * otherwise, accounts named 'equity:conversion', 'equity:trade',+ or 'equity:trading', or their subaccounts.++ And multiple such four-posting groups can coexist within a single+transaction. When '--infer-costs' fails, it does not infer a cost in+that transaction, and does not raise an error (ie, it infers costs where+it can).++ Reading variant 5 journal entries, combining cost notation and equity+postings, has all the same requirements. When reading such an entry+fails, hledger raises an "unbalanced transaction" error.+++File: hledger.info, Node: Infer cost and equity by default ?, Prev: Requirements for detecting equity conversion postings, Up: Cost reporting++22.7 Infer cost and equity by default ?+=======================================++Should '--infer-costs' and '--infer-equity' be enabled by default ? Try+using them always, eg with a shell alias:++alias h="hledger --infer-equity --infer-costs"++ and let us know what problems you find.+++File: hledger.info, Node: Value reporting, Next: PART 4 COMMANDS, Prev: Cost reporting, Up: Top++23 Value reporting+******************++Instead of reporting amounts in their original commodity, hledger can+convert them to cost/sale amount (using the conversion rate recorded in+the transaction), and/or to market value (using some market price on a+certain date). This is controlled by the '--value=TYPE[,COMMODITY]'+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:++* Menu:++* -V Value::+* -X Value in specified commodity::+* Valuation date::+* Finding market price::+* --infer-market-prices market prices from transactions::+* Valuation commodity::+* --value Flexible valuation::+* Valuation examples::+* Interaction of valuation and queries::+* Effect of valuation on reports::+++File: hledger.info, Node: -V Value, Next: -X Value in specified commodity, Up: Value reporting++23.1 -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.+++File: hledger.info, Node: -X Value in specified commodity, Next: Valuation date, Prev: -V Value, Up: Value reporting++23.2 -X: Value in specified commodity+=====================================++The '-X/--exchange=COMM' option is like '-V', except you tell it which+currency you want to convert to, and it tries to convert everything to+that.+++File: hledger.info, Node: Valuation date, Next: Finding market price, Prev: -X Value in specified commodity, Up: Value reporting++23.3 Valuation date+===================++Market prices can change from day to day. hledger will use the prices+on a particular valuation date (or on more than one date). By default+hledger uses "end" dates for valuation. More specifically:++ * For single period reports (including normal print and register+ reports):+ * If an explicit report end date is specified, that is used+ * Otherwise the latest transaction date or P directive date is+ used (even if it's in the future)++ * For multiperiod reports, each period is valued on its last day.++ This can be customised with the -value option described below, which+can select either "then", "end", "now", or "custom" dates. (Note, this+has a bug in hledger-ui <=1.31: turning on valuation with the 'V' key+always resets it to "end".)+++File: hledger.info, Node: Finding market price, Next: --infer-market-prices market prices from transactions, Prev: Valuation date, Up: Value reporting++23.4 Finding market price+=========================++To convert a commodity A to its market value in another commodity B,+hledger looks for a suitable market price (exchange rate) as follows, 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 directive, or (with the '--infer-market-prices' flag) inferred+ from costs.++ 2. A _reverse market price_: the inverse of a declared or inferred+ market price from B to A.++ 3. A _forward chain of market prices_: a synthetic price formed by+ combining 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+converted.+++File: hledger.info, Node: --infer-market-prices market prices from transactions, Next: Valuation commodity, Prev: Finding market price, Up: Value reporting++23.5 -infer-market-prices: 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 costs as additional market prices (as+Ledger does) ? Adding the '--infer-market-prices' flag to '-V', '-X' or+'--value' enables this.++ So for example, 'hledger bs -V --infer-market-prices' will get market+prices both from P directives and from transactions. If both occur on+the same day, the P directive takes precedence.++ There is a downside: value reports can sometimes be affected in+confusing/undesired ways by your journal entries. If this happens to+you, read all of this Value reporting section carefully, and try adding+'--debug' or '--debug=2' to troubleshoot.++ '--infer-market-prices' can infer market prices from:++ * multicommodity transactions with explicit prices ('@'/'@@')++ * multicommodity transactions with implicit prices (no '@', two+ commodities, unbalanced). (With these, the order of postings+ matters. 'hledger print -x' can be useful for troubleshooting.)++ * multicommodity transactions with equity postings, if cost is+ inferred with '--infer-costs'.++ There is a limitation (bug) currently: when a valuation commodity is+not specified, prices inferred with '--infer-market-prices' do not help+select a default valuation commodity, as 'P' prices would. So+conversion might not happen because no valuation commodity was detected+('--debug=2' will show this). To be safe, specify the valuation+commmodity, eg:++ * '-X EUR --infer-market-prices', not '-V --infer-market-prices'+ * '--value=then,EUR --infer-market-prices', not '--value=then+ --infer-market-prices'++ Signed costs and market prices can be confusing. For reference, here+is the current behaviour, since hledger 1.25. (If you think it should+work differently, see #1870.)++2022-01-01 Positive Unit prices+ a A 1+ b B -1 @ A 1++2022-01-01 Positive Total prices+ a A 1+ b B -1 @@ A 1+++2022-01-02 Negative unit prices+ a A 1+ b B 1 @ A -1++2022-01-02 Negative total prices+ a A 1+ b B 1 @@ A -1+++2022-01-03 Double Negative unit prices+ a A -1+ b B -1 @ A -1++2022-01-03 Double Negative total prices+ a A -1+ b B -1 @@ A -1++ All of the transactions above are considered balanced (and on each+day, the two transactions are considered equivalent). Here are the+market prices inferred for B:++$ hledger -f- --infer-market-prices prices+P 2022-01-01 B A 1+P 2022-01-01 B A 1.0+P 2022-01-02 B A -1+P 2022-01-02 B A -1.0+P 2022-01-03 B A -1+P 2022-01-03 B A -1.0+++File: hledger.info, Node: Valuation commodity, Next: --value Flexible valuation, Prev: --infer-market-prices market prices from transactions, Up: Value reporting++23.6 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+suitable 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-prices' flag is used: the price commodity from the+ latest transaction-inferred price for A on or before valuation+ date.++ This means:++ * If you have P directives, they determine which commodities '-V'+ will convert, and to what.++ * If you have no P directives, and use the '--infer-market-prices'+ flag, costs determine it.++ Amounts for which no valuation commodity can be found are not+converted.+++File: hledger.info, Node: --value Flexible valuation, Next: Valuation examples, Prev: Valuation commodity, Up: Value reporting++23.7 -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 commodity,+ using market prices on each posting's date.+'--value=end'++ Convert amounts to their value in the default valuation commodity,+ using market prices on the last day of the report period (or if+ unspecified, the journal'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 commodity+ using current market prices (as of when report is generated).+'--value=YYYY-MM-DD'++ Convert amounts to their value in the default valuation commodity+ 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.+++File: hledger.info, Node: Valuation examples, Next: Interaction of valuation and queries, Prev: --value Flexible valuation, Up: Value reporting++23.8 Valuation examples+=======================++Here are some quick examples of '-V':++; one euro is worth this many dollars from nov 1+P 2016/11/01 € $1.10++; purchase some euros on nov 3+2016/11/3+ assets:euros €100+ assets:checking++; the euro is worth fewer dollars by dec 21+P 2016/12/21 € $1.03++ How many euros do I have ?++$ hledger -f t.j bal -N euros+ €100 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++ 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+++File: hledger.info, Node: Interaction of valuation and queries, Next: Effect of valuation on reports, Prev: Valuation examples, Up: Value reporting++23.9 Interaction of valuation and queries+=========================================++When matching postings based on queries in the presence of valuation,+the following happens:++ 1. The query is separated into two parts:+ 1. the currency ('cur:') or amount ('amt:').+ 2. all other parts.++ 2. The postings are matched to the currency and amount queries based+ on pre-valued amounts.+ 3. Valuation is applied to the postings.+ 4. The postings are matched to the other parts of the query based on+ post-valued amounts.++ Related: #1625+++File: hledger.info, Node: Effect of valuation on reports, Prev: Interaction of valuation and queries, Up: Value reporting++23.10 Effect of valuation on reports+====================================++Here is a reference for how valuation is supposed to affect each part of+hledger's reports. (It's wide, you may need to scroll sideways.) It+may be useful when troubleshooting. If you find problems, please report+them, ideally with a reproducible example. Related: #329, #1083.++ First, a quick 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+ subperiods).++Report '-B', '-V', '-X' '--value=then' '--value=end''--value=DATE',+type '--cost' '--value=now'+------------------------------------------------------------------------------+*print*+posting cost value at value at posting value at value+amounts report end date report or at+ or today journal DATE/today+ end+balance unchanged unchanged unchanged unchanged unchanged+assertions/assignments+*register*+starting cost value at valued at day value at value+balance report or each historical report or at+(-H) journal posting was made journal DATE/today+ end end+starting cost value at valued at day value at value+balance day before each historical day before at+(-H) report or posting was made report or DATE/today+with journal journal+report start start+interval+posting cost value at value at posting value at value+amounts report or date report or at+ journal journal DATE/today+ end end+summary summarised value at sum of postings value at value+posting cost period in interval, period at+amounts ends valued at ends DATE/today+with interval start+report+interval+running sum/average sum/average sum/average of sum/average sum/average+total/averageof of displayed values of of+ displayed displayed displayed displayed+ values values values values+*balance+(bs,+bse, cf,+is)*+balance sums of value at value at posting value at value+changes costs report end date report or at+ or today journal DATE/today+ of sums of end of of+ postings sums of sums+ postings of+ postings+budget like like like balance like like+amounts balance balance changes balances balance+(-budget) changes changes changes+grand sum of sum of sum of displayed sum of sum of+total displayed displayed valued displayed displayed+ values values values values+*balance+(bs,+bse, cf,+is) with+report+interval*+starting sums of value at sums of values value at sums+balances costs of report of postings report of+(-H) postings start of before report start of postings+ before sums of start at sums of before+ report all respective all report+ start postings posting dates postings start+ before before+ report report+ start start+balance sums of same as sums of values balance value+changes costs of -value=end of postings in change in at+(bal, postings period at each DATE/today+is, bs in period respective period, of+-change, posting dates valued at sums+cf period of+-change) ends postings+end sums of same as sums of values period end value+balances costs of -value=end of postings from balances, at+(bal -H, postings before period valued at DATE/today+is -H, from start to period period of+bs, cf) before end at ends sums+ report respective of+ start to posting dates postings+ period end+budget like like like balance like like+amounts balance balance changes/end balances balance+(-budget) changes/end changes/end balances changes/end+ balances balances balances+row sums, sums, sums, averages sums, sums,+totals, averages averages of displayed averages averages+row of of values of of+averages displayed displayed displayed displayed+(-T, -A) values values values values+column sums of sums of sums of sums of sums+totals displayed displayed displayed values displayed of+ values values values displayed+ values+grand sum, sum, sum, average of sum, sum,+total, average of average of column totals average of average+grand column column column of+average totals totals totals column+ totals++ '--cumulative' is omitted to save space, it works like '-H' but with+a zero starting balance.+++File: hledger.info, Node: PART 4 COMMANDS, Next: PART 5 COMMON TASKS, Prev: Value reporting, Up: Top++24 PART 4: COMMANDS+*******************++* Menu:++* Commands overview::+* accounts::+* activity::+* add::+* aregister::+* balance::+* balancesheet::+* balancesheetequity::+* cashflow::+* check::+* close::+* codes::+* commodities::+* demo::+* descriptions::+* diff::+* files::+* help::+* import::+* incomestatement::+* notes::+* payees::+* prices::+* print::+* register::+* rewrite::+* roi::+* stats::+* tags::+* test::+++File: hledger.info, Node: Commands overview, Next: accounts, Up: PART 4 COMMANDS++24.1 Commands overview+======================++Here are the built-in commands:++* Menu:++* DATA ENTRY::+* DATA CREATION::+* DATA MANAGEMENT::+* REPORTS FINANCIAL::+* REPORTS VERSATILE::+* REPORTS BASIC::+* HELP::+* ADD-ONS::+++File: hledger.info, Node: DATA ENTRY, Next: DATA CREATION, Up: Commands overview++24.1.1 DATA ENTRY+-----------------++These data entry commands are the only ones which can modify your+journal file.++ * add - add transactions using terminal prompts+ * import - add new transactions from other files, eg CSV files+++File: hledger.info, Node: DATA CREATION, Next: DATA MANAGEMENT, Prev: DATA ENTRY, Up: Commands overview++24.1.2 DATA CREATION+--------------------++ * close - generate balance-zeroing/restoring transactions+ * rewrite - generate auto postings, like print -auto+++File: hledger.info, Node: DATA MANAGEMENT, Next: REPORTS FINANCIAL, Prev: DATA CREATION, Up: Commands overview++24.1.3 DATA MANAGEMENT+----------------------++ * check - check for various kinds of error in the data+ * diff - compare account transactions in two journal files+++File: hledger.info, Node: REPORTS FINANCIAL, Next: REPORTS VERSATILE, Prev: DATA MANAGEMENT, Up: Commands overview++24.1.4 REPORTS, FINANCIAL+-------------------------++ * aregister (areg) - show transactions in a particular account+ * balancesheet (bs) - show assets, liabilities and net worth+ * balancesheetequity (bse) - show assets, liabilities and equity+ * cashflow (cf) - show changes in liquid assets+ * incomestatement (is) - show revenues and expenses+++File: hledger.info, Node: REPORTS VERSATILE, Next: REPORTS BASIC, Prev: REPORTS FINANCIAL, Up: Commands overview++24.1.5 REPORTS, VERSATILE+-------------------------++ * balance (bal) - show balance changes, end balances, budgets,+ gains..+ * print - show transactions or export journal data+ * register (reg) - show postings in one or more accounts & running+ total+ * roi - show return on investments+++File: hledger.info, Node: REPORTS BASIC, Next: HELP, Prev: REPORTS VERSATILE, Up: Commands overview++24.1.6 REPORTS, BASIC+---------------------++ * accounts - show account names+ * activity - show bar charts of posting counts per period+ * codes - show transaction codes+ * commodities - show commodity/currency symbols+ * descriptions - show transaction descriptions+ * files - show input file paths+ * notes - show note parts of transaction descriptions+ * payees - show payee parts of transaction descriptions+ * prices - show market prices+ * stats - show journal statistics+ * tags - show tag names+ * test - run self tests+++File: hledger.info, Node: HELP, Next: ADD-ONS, Prev: REPORTS BASIC, Up: Commands overview++24.1.7 HELP+-----------++ * help - show the hledger manual with info/man/pager+ * demo - show small hledger demos in the terminal+++File: hledger.info, Node: ADD-ONS, Prev: HELP, Up: Commands overview++24.1.8 ADD-ONS+--------------++And here are some typical add-on commands. Some of these are installed+by the hledger-install script. If installed, they will appear in+hledger's commands list:++ * ui - run hledger's terminal UI+ * web - run hledger's web UI+ * iadd - add transactions using a TUI (currently hard to build)+ * interest - generate interest transactions+ * stockquotes - download market prices from AlphaVantage+ * Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,+ pijul, plot, and more..++ Next, each command is described in detail, in alphabetical order.+++File: hledger.info, Node: accounts, Next: activity, Prev: Commands overview, Up: PART 4 COMMANDS++24.2 accounts+=============++Show account names.++ This command lists account names. By default it shows all known+accounts, either used in transactions or declared with account+directives.++ With query arguments, only matched account names and account names+referenced by matched postings are shown.++ Or it can show just the used accounts ('--used'/'-u'), the declared+accounts ('--declared'/'-d'), the accounts declared but not used+('--unused'), the accounts used but not declared ('--undeclared'), or+the first account matched by an account name pattern, if any ('--find').++ It shows a flat list by default. With '--tree', it uses indentation+to show the account hierarchy. In flat mode you can add '--drop N' to+omit the first few account name components. Account names can be+depth-clipped with 'depth:N' or '--depth N' or '-N'.++ With '--types', it also shows each account's type, if it's known.+(See Declaring accounts > Account types.)++ With '--positions', it also shows the file and line number of each+account's declaration, if any, and the account's overall declaration+order; these may be useful when troubleshooting account display order.++ With '--directives', it adds the 'account' keyword, showing valid+account directives which can be pasted into a journal file. This is+useful together with '--undeclared' when updating your account+declarations to satisfy 'hledger check accounts'.++ The '--find' flag can be used to look up a single account name, in+the same way that the 'aregister' command does. It returns the+alphanumerically-first matched account name, or if none can be found, it+fails with a non-zero exit code.++ Examples:++$ hledger accounts+assets:bank:checking+assets:bank:saving+assets:cash+expenses:food+expenses:supplies+income:gifts+income:salary+liabilities:debts++$ hledger accounts --undeclared --directives >> $LEDGER_FILE+$ hledger check accounts+++File: hledger.info, Node: activity, Next: add, Prev: accounts, Up: PART 4 COMMANDS++24.3 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 **+++File: hledger.info, Node: add, Next: aregister, Prev: activity, Up: PART 4 COMMANDS++24.4 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+transactions, and appends them to the main journal file (which should be+in journal format). Existing transactions are not changed. This is one+of the few hledger commands that writes to the journal file (see also+'import').++ To use it, just run 'hledger add' and follow the prompts. You can+add as many transactions as you like; when you are finished, enter '.'+or press control-d or control-c to exit.++ Features:++ * add tries to provide useful defaults, using the most similar (by+ description) recent transaction (filtered by the query, if any) as+ a template.+ * You can also set the initial defaults with command line arguments.+ * Readline-style edit keys can be used during data entry.+ * The tab key will auto-complete whenever possible - accounts,+ payees/descriptions, dates ('yesterday', 'today', 'tomorrow'). If+ the input area is empty, it will insert the default value.+ * If the journal defines a default commodity, it will be added to any+ bare numbers entered.+ * A parenthesised transaction code may be entered following a date.+ * Comments and tags may be entered following a description or amount.+ * If you make a mistake, enter '<' at any prompt to go one step+ backward.+ * Input prompts are displayed in a different colour when the terminal+ supports it.++ Example (see https://hledger.org/add.html for a detailed tutorial):++$ 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> $++ If you enter a number with no commodity symbol, and you have declared+a default commodity with a 'D' directive, you might expect 'add' to add+this symbol for you. It does not do this; we assume that if you are+using a 'D' directive you prefer not to see the commodity symbol+repeated on amounts in the journal.+++File: hledger.info, Node: aregister, Next: balance, Prev: add, Up: PART 4 COMMANDS++24.5 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 'aregister' 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.++ When there are multiple matches, the alphabetically-first choice can+be surprising; eg if you have 'assets:per:checking 1' and+'assets:biz:checking 2' accounts, 'hledger areg checking' would select+'assets:biz:checking 2'. It's just a convenience to save typing, so if+in doubt, write the full account name, or a distinctive substring that+matches uniquely.++ 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. 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, see below)+ * the names of all the other account(s) involved in this transaction+ (probably abbreviated)+ * the total change to this account's balance from this transaction+ * 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.++ For performance reasons, column widths are chosen based on the first+1000 lines; this means unusually wide values in later lines can cause+visual discontinuities as column widths are adjusted. If you want to+ensure perfect alignment, at the cost of more time and memory, use the+'--align-all' flag.++ This command also supports the output destination and output format+options. The output formats supported are 'txt', 'csv', 'tsv' (_Added+in 1.32_), and 'json'.++* Menu:++* aregister and posting dates::+++File: hledger.info, Node: aregister and posting dates, Up: aregister++24.5.1 aregister and posting dates+----------------------------------++aregister always shows one line (and date and amount) per transaction.+But sometimes transactions have postings with different dates. Also,+not all of a transaction's postings may be within the report period. To+resolve this, aregister shows the earliest of the transaction's date and+posting dates that is in-period, and the sum of the in-period postings.+In other words it will show a combined line item with just the earliest+date, and the running balance will (temporarily, until the transaction's+last posting) be inaccurate. Use 'register -H' if you need to see the+individual postings.++ There is also a '--txn-dates' flag, which filters strictly by+transaction date, ignoring posting dates. This too can cause an+inaccurate running balance.+++File: hledger.info, Node: balance, Next: balancesheet, Prev: aregister, Up: PART 4 COMMANDS++24.6 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',+'balancesheetequity', 'cashflow' and 'incomestatement'. When you need+more control, then use 'balance'.++* Menu:++* balance features::+* Simple balance report::+* Balance report line format::+* Filtered balance report::+* List or tree mode::+* Depth limiting::+* Dropping top-level accounts::+* Showing declared accounts::+* Sorting by amount::+* Percentages::+* Multi-period balance report::+* Balance change end balance::+* Balance report types::+* Budget report::+* Balance report layout::+* Some useful balance reports::+++File: hledger.info, Node: balance features, Next: Simple balance report, Up: balance++24.6.1 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..++ * accounts as a list ('-l') or a tree ('-t')+ * optionally depth-limited ('-[1-9]')+ * sorted by declaration order and name, or by amount++ ..and their..++ * balance changes (the default)+ * or actual and planned balance changes ('--budget')+ * or value of balance changes ('-V')+ * or change of balance values ('--valuechange')+ * or unrealised capital gain/loss ('--gain')+ * or balance changes from sibling postings ('--related'/'-r')+ * or postings count ('--count')++ ..in..++ * one time period (the whole journal period by default)+ * or multiple periods ('-D', '-W', '-M', '-Q', '-Y', '-p INTERVAL')++ ..either..++ * per period (the default)+ * or accumulated since report start date ('--cumulative')+ * or accumulated since account creation ('--historical/-H')++ ..possibly converted to..++ * cost ('--value=cost[,COMM]'/'--cost'/'-B')+ * or market value, as of transaction dates ('--value=then[,COMM]')+ * or at period ends ('--value=end[,COMM]')+ * or now ('--value=now')+ * or at some other date ('--value=YYYY-MM-DD')++ ..with..++ * totals ('-T'), averages ('-A'), percentages ('-%'), inverted sign+ ('--invert')+ * rows and columns swapped ('--transpose')+ * another field used as account name ('--pivot')+ * custom-formatted line items (single-period reports only)+ ('--format')+ * commodities displayed on the same line or multiple lines+ ('--layout')++ This command supports the output destination and output format+options, with output formats 'txt', 'csv', 'tsv' (_Added in 1.32_),+'json', and (multi-period reports only:) 'html'. In 'txt' output in a+colour-supporting terminal, negative amounts are shown in red.+++File: hledger.info, Node: Simple balance report, Next: Balance report line format, Prev: balance features, Up: balance++24.6.2 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. ("Simple" here+means just one column of numbers, covering a single period. You can+also have multi-period reports, described later.)++ For real-world accounts, these numbers will normally be their end+balance at the end of the journal period; more on this below.++ Accounts are sorted by declaration order if any, and then+alphabetically by account name. For instance (using+examples/sample.journal):++$ hledger -f examples/sample.journal bal+ $1 assets:bank:saving+ $-2 assets:cash+ $1 expenses:food+ $1 expenses:supplies+ $-1 income:gifts+ $-1 income:salary+ $1 liabilities:debts+--------------------+ 0 ++ 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.+++File: hledger.info, Node: Balance report line format, Next: Filtered balance report, Prev: Simple balance report, Up: balance++24.6.3 Balance report line format+---------------------------------++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 -f examples/sample.journal 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 specifies the formatting applied to each+account/balance pair. It may contain any suitable text, with data+fields interpolated like so:++ '%[MIN][.MAX](FIELDNAME)'++ * MIN pads with spaces to at least this width (optional)++ * MAX truncates at this width (optional)++ * FIELDNAME must be enclosed in parentheses, and can be one of:++ * 'depth_spacer' - a number of spaces equal to the account's+ depth, or if MIN is specified, MIN * depth spaces.+ * 'account' - the account's name+ * 'total' - the account's balance/posted total, right justified++ Also, FMT can begin with an optional prefix to control how+multi-commodity amounts are rendered:++ * '%_' - render on multiple lines, bottom-aligned (the default)+ * '%^' - render on multiple lines, top-aligned+ * '%,' - 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:++ * '%(total)' - the account's total+ * '%-20.20(account)' - the account's name, left justified, padded to+ 20 characters and clipped at 20 characters+ * '%,%-50(account) %25(total)' - account name padded to 50+ characters, total padded to 20 characters, with multiple+ commodities rendered on one line+ * '%20(total) %2(depth_spacer)%-(account)' - the default format for+ the single-column balance report+++File: hledger.info, Node: Filtered balance report, Next: List or tree mode, Prev: Balance report line format, Up: balance++24.6.4 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 -f examples/sample.journal bal --cleared assets date:200806+ $-2 assets:cash+--------------------+ $-2 +++File: hledger.info, Node: List or tree mode, Next: Depth limiting, Prev: Filtered balance report, Up: balance++24.6.5 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 -f examples/sample.journal balance+ $-1 assets+ $1 bank:saving+ $-2 cash+ $2 expenses+ $1 food+ $1 supplies+ $-2 income+ $-1 gifts+ $-1 salary+ $1 liabilities:debts+--------------------+ 0++ Notes:++ * "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).++ * 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-plaintextaccounting-users. A tree mode report's final total is+ the sum of the top-level balances shown, not of all the balances+ shown.++ * Each group of sibling accounts (ie, under a common parent) is+ sorted separately.+++File: hledger.info, Node: Depth limiting, Next: Dropping top-level accounts, Prev: List or tree mode, Up: balance++24.6.6 Depth limiting+---------------------++With a 'depth:NUM' query, or '--depth NUM' option, or just '-NUM' (eg:+'-3') balance reports will show accounts only to the specified depth,+hiding the deeper subaccounts. This can be useful for getting an+overview without too much detail.++ Account balances at the depth limit always include the balances from+any deeper subaccounts (even in list mode). Eg, limiting to depth 1:++$ hledger -f examples/sample.journal balance -1+ $-1 assets+ $2 expenses+ $-2 income+ $1 liabilities+--------------------+ 0 +++File: hledger.info, Node: Dropping top-level accounts, Next: Showing declared accounts, Prev: Depth limiting, Up: balance++24.6.7 Dropping top-level accounts+----------------------------------++You can also hide one or more top-level account name parts, using+'--drop NUM'. This can be useful for hiding repetitive top-level+account names:++$ hledger -f examples/sample.journal bal expenses --drop 1+ $1 food+ $1 supplies+--------------------+ $2 +++File: hledger.info, Node: Showing declared accounts, Next: Sorting by amount, Prev: Dropping top-level accounts, Up: balance++24.6.8 Showing declared accounts+--------------------------------++With '--declared', accounts which have been declared with an account+directive will be included in the balance report, even if they have no+transactions. (Since they will have a zero balance, you will also need+'-E/--empty' to see them.)++ More precisely, _leaf_ declared accounts (with no subaccounts) will+be included, since those are usually the more useful in reports.++ The idea of this is to be able to see a useful "complete" balance+report, even when you don't have transactions in all of your declared+accounts yet.+++File: hledger.info, Node: Sorting by amount, Next: Percentages, Prev: Showing declared accounts, Up: balance++24.6.9 Sorting by amount+------------------------++With '-S/--sort-amount', accounts with the largest (most positive)+balances are shown first. Eg: 'hledger bal expenses -MAS' shows your+biggest averaged monthly expenses first. When more than one commodity+is present, they will be sorted by the alphabetically earliest commodity+first, and then by subsequent commodities (if an amount is missing a+commodity, it is treated as 0).++ Revenues and liability balances are typically negative, however, so+'-S' shows these in reverse order. To work around this, you can add+'--invert' to flip the signs. (Or, use one of the higher-level reports,+which flip the sign automatically. Eg: 'hledger incomestatement -MAS').+++File: hledger.info, Node: Percentages, Next: Multi-period balance report, Prev: Sorting by amount, Up: balance++24.6.10 Percentages+-------------------++With '-%/--percent', balance reports show each account's value expressed+as a percentage of the (column) total.++ Note it is not useful to calculate percentages if the amounts in a+column 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:€+++File: hledger.info, Node: Multi-period balance report, Next: Balance change end balance, Prev: Percentages, Up: balance++24.6.11 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),+'balance' shows a tabular report, with columns representing successive+time periods (and a title):++$ hledger -f examples/sample.journal bal --quarterly income expenses -E+Balance changes in 2008:++ || 2008q1 2008q2 2008q3 2008q4 +===================++=================================+ expenses:food || 0 $1 0 0 + expenses:supplies || 0 $1 0 0 + income:gifts || 0 $-1 0 0 + income:salary || $-1 0 0 0 +-------------------++---------------------------------+ || $-1 $1 0 0 ++ Notes:++ * The report's start/end dates will be expanded, if necessary, to+ fully encompass the displayed subperiods (so that the first and+ last subperiods have the same duration as the others).+ * Leading and trailing periods (columns) containing all zeroes are+ not shown, unless '-E/--empty' is used.+ * Accounts (rows) containing all zeroes are not shown, unless+ '-E/--empty' is used.+ * Amounts with many commodities are shown in abbreviated form, unless+ '--no-elide' is used.+ * Average and/or total columns can be added with the '-A/--average'+ and '-T/--row-total' flags.+ * The '--transpose' flag can be used to exchange rows and columns.+ * 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:++ * Hide the totals row with '-N/--no-total'+ * Filter to a single currency with 'cur:'+ * Convert to a single currency with '-V [--infer-market-price]'+ * Use a more compact layout like '--layout=bare'+ * Maximize the terminal window+ * Reduce the terminal's font size+ * View with a pager like less, eg: 'hledger bal -D --color=yes | less+ -RS'+ * 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')+ * Output as HTML and view with a browser: 'hledger bal -D -o a.html+ && open a.html'+++File: hledger.info, Node: Balance change end balance, Next: Balance report types, Prev: Multi-period balance report, Up: balance++24.6.12 Balance change, end balance+-----------------------------------++It's important to be clear on the meaning of the numbers shown in+balance 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 postings.)+++File: hledger.info, Node: Balance report types, Next: Budget report, Prev: Balance change end balance, Up: balance++24.6.13 Balance report types+----------------------------++The balance command is quite flexible; here is the full detail on how to+control what it reports. If the following seems complicated, don't+worry - this is for advanced reporting, and it does take time and+experimentation to get familiar with all the report modes.++ There are three important option groups:++ 'hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]+...'++* Menu:++* Calculation type::+* Accumulation type::+* Valuation type::+* Combining balance report types::+++File: hledger.info, Node: Calculation type, Next: Accumulation type, Up: Balance report types++24.6.13.1 Calculation type+..........................++The basic calculation to perform for each table cell. It is one of:++ * '--sum' : sum the posting amounts (*default*)+ * '--budget' : sum the amounts, but also show the budget goal amount+ (for each account/period)+ * '--valuechange' : show the change in period-end historical balance+ values (caused by deposits, withdrawals, and/or market price+ fluctuations)+ * '--gain' : show the unrealised capital gain/loss, (the current+ valued balance minus each amount's original cost)+ * '--count' : show the count of postings+++File: hledger.info, Node: Accumulation type, Next: Valuation type, Prev: Calculation type, Up: Balance report types++24.6.13.2 Accumulation type+...........................++How amounts should accumulate across a report's subperiods/columns.+Another way to say it: which time period's postings should contribute to+each cell's calculation. It is one of:++ * '--change' : calculate with postings from column start to column+ end, ie "just this column". Typically used to see+ revenues/expenses. (*default for balance, cashflow,+ incomestatement*)++ * '--cumulative' : calculate with postings from report start to+ column end, ie "previous columns plus this column". Typically used+ to show changes accumulated since the report's start date. Not+ often used.++ * '--historical/-H' : calculate with postings from journal start to+ column end, ie "all postings from before report start date until+ this column's end". Typically used to see historical end balances+ of assets/liabilities/equity. (*default for balancesheet,+ balancesheetequity*)+++File: hledger.info, Node: Valuation type, Next: Combining balance report types, Prev: Accumulation type, Up: Balance report types++24.6.13.3 Valuation type+........................++Which kind of value or cost conversion should be applied, if any, before+displaying the report. It is one of:++ * no valuation type : don't convert to cost or value (*default*)+ * '--value=cost[,COMM]' : convert amounts to cost (then optionally to+ some other commodity)+ * '--value=then[,COMM]' : convert amounts to market value on+ transaction dates+ * '--value=end[,COMM]' : convert amounts to market value on period+ end date(s)+ (*default with '--valuechange', '--gain'*)+ * '--value=now[,COMM]' : convert amounts to market value on today's+ date+ * '--value=YYYY-MM-DD[,COMM]' : convert amounts to market value on+ another date++ or one of the equivalent simpler flags:++ * '-B/--cost' : like -value=cost (though, note -cost and -value are+ independent options which can both be used at once)+ * '-V/--market' : like -value=end+ * '-X COMM/--exchange COMM' : like -value=end,COMM++ See Cost reporting and Value reporting for more about these.+++File: hledger.info, Node: Combining balance report types, Prev: Valuation type, Up: Balance report types++24.6.13.4 Combining balance report types+........................................++Most combinations of these options should produce reasonable reports,+but if you find any that seem wrong or misleading, let us know. The+following restrictions are applied:++ * '--valuechange' implies '--value=end'+ * '--valuechange' makes '--change' the default when used with the+ 'balancesheet'/'balancesheetequity' commands+ * '--cumulative' or '--historical' disables '--row-total/-T'++ For reference, here is what the combinations of accumulation and+valuation show:++Valuation:>no valuation '--value= then' '--value= end' '--value=+Accumulation:v YYYY-MM-DD+ /now'+-----------------------------------------------------------------------------+'--change'change in sum of period-end DATE-value+ period posting-date value of of change in+ market values change in period+ in period period+'--cumulative'change from sum of period-end DATE-value+ report start to posting-date value of of change+ period end market values change from from report+ from report report start start to+ start to period to period end period end+ end+'--historicalchange from sum of period-end DATE-value+/-H' journal start posting-date value of of change+ to period end market values change from from journal+ (historical end from journal journal start start to+ balance) start to period to period end period end+ end+++File: hledger.info, Node: Budget report, Next: Balance report layout, Prev: Balance report types, Up: balance++24.6.14 Budget report+---------------------++The '--budget' report type is like a regular balance report, but with+two main differences:++ * Budget goals and performance percentages are also shown, in+ brackets+ * Accounts which don't have budget goals are hidden by default.++ This is useful for comparing planned and actual income, expenses,+time usage, etc.++ Periodic transaction rules are used to define budget goals. For+example, here's a periodic rule defining monthly goals for bus travel+and food expenses:++;; Budget+~ monthly+ (expenses:bus) $30+ (expenses:food) $400++ After recording some actual expenses,++;; Two months worth of expenses+2017-11-01+ income $-1950+ expenses:bus $35+ expenses:food:groceries $310+ expenses:food:dining $42+ expenses:movies $38+ assets:bank:checking++2017-12-01+ income $-2100+ expenses:bus $53+ expenses:food:groceries $380+ expenses:food:dining $32+ expenses:gifts $100+ assets:bank:checking++ we can see a budget report like this:++$ hledger bal -M --budget+Budget performance in 2017-11-01..2017-12-31:++ || Nov Dec +===============++============================================+ <unbudgeted> || $-425 $-565 + expenses || $425 [ 99% of $430] $565 [131% of $430] + expenses:bus || $35 [117% of $30] $53 [177% of $30] + expenses:food || $352 [ 88% of $400] $412 [103% of $400] +---------------++--------------------------------------------+ || 0 [ 0% of $430] 0 [ 0% of $430] ++ This is "goal-based budgeting"; you define goals for accounts and+periods, often recurring, and hledger shows performance relative to the+goals. This contrasts with "envelope budgeting", which is more detailed+and strict - useful when cash is tight, but also quite a bit more work.+https://plaintextaccounting.org/Budgeting has more on this topic.++* Menu:++* Using the budget report::+* Budget date surprises::+* Selecting budget goals::+* Budgeting vs forecasting::+++File: hledger.info, Node: Using the budget report, Next: Budget date surprises, Up: Budget report++24.6.14.1 Using the budget report+.................................++Historically this report has been confusing and fragile. hledger's+version should be relatively robust and intuitive, but you may still+find surprises. Here are more notes to help with learning and+troubleshooting.++ * In the above example, 'expenses:bus' and 'expenses:food' are shown+ because they have budget goals during the report period.++ * Their parent 'expenses' is also shown, with budget goals aggregated+ from the children.++ * The subaccounts 'expenses:food:groceries' and+ 'expenses:food:dining' are not shown since they have no budget goal+ of their own, but they contribute to 'expenses:food''s actual+ amount.++ * Unbudgeted accounts 'expenses:movies' and 'expenses:gifts' are also+ not shown, but they contribute to 'expenses''s actual amount.++ * The other unbudgeted accounts 'income' and 'assets:bank:checking'+ are grouped as '<unbudgeted>'.++ * '--depth' or 'depth:' can be used to limit report depth in the+ usual way (but will not reveal unbudgeted subaccounts).++ * Amounts are always inclusive of subaccounts (even in '-l/--list'+ mode).++ * Numbers displayed in a -budget report will not always agree with+ the totals, because of hidden unbudgeted accounts; this is normal.+ '-E/--empty' can be used to reveal the hidden accounts.++ * In the periodic rules used for setting budget goals, unbalanced+ postings are convenient.++ * You can filter budget reports with the usual queries, eg to focus+ on particular accounts. It's common to restrict them to just+ expenses. (The '<unbudgeted>' account is occasionally hard to+ exclude; this is because of date surprises, discussed below.)++ * When you have multiple currencies, you may want to convert them to+ one ('-X COMM --infer-market-prices') and/or show just one at a+ time ('cur:COMM'). If you do need to show multiple currencies at+ once, '--layout bare' can be helpful.++ * You can "roll over" amounts (actual and budgeted) to the next+ period with '--cumulative'.++ See also: https://hledger.org/budgeting.html.+++File: hledger.info, Node: Budget date surprises, Next: Selecting budget goals, Prev: Using the budget report, Up: Budget report++24.6.14.2 Budget date surprises+...............................++With small data, or when starting out, some of the generated budget goal+transaction dates might fall outside the report periods. Eg with the+following journal and report, the first period appears to have no+'expenses:food' budget. (Also the '<unbudgeted>' account should be+excluded by the 'expenses' query, but isn't.):++~ monthly in 2020+ (expenses:food) $500++2020-01-15+ expenses:food $400+ assets:checking++$ hledger bal --budget expenses+Budget performance in 2020-01-15:++ || 2020-01-15 +===============++====================+ <unbudgeted> || $400 + expenses:food || 0 [ 0% of $500] +---------------++--------------------+ || $400 [80% of $500] ++ In this case, the budget goal transactions are generated on first+days of of month (this can be seen with 'hledger print --forecast+tag:generated expenses'). Whereas the report period defaults to just+the 15th day of january (this can be seen from the report table's column+headings).++ To fix this kind of thing, be more explicit about the report period+(and/or the periodic rules' dates). In this case, adding '-b 2020' does+the trick.+++File: hledger.info, Node: Selecting budget goals, Next: Budgeting vs forecasting, Prev: Budget date surprises, Up: Budget report++24.6.14.3 Selecting budget goals+................................++By default, the budget report uses all available periodic transaction+rules to generate goals. This includes rules with a different report+interval from your report. Eg if you have daily, weekly and monthly+periodic rules, all of these will contribute to the goals in a monthly+budget report.++ You can select a subset of periodic rules by providing an argument to+the '--budget' flag. '--budget=DESCPAT' will match all periodic rules+whose description contains DESCPAT, a case-insensitive substring (not a+regular expression or query). This means you can give your periodic+rules descriptions (remember that two spaces are needed between period+expression and description), and then select from multiple budgets+defined in your journal.+++File: hledger.info, Node: Budgeting vs forecasting, Prev: Selecting budget goals, Up: Budget report++24.6.14.4 Budgeting vs forecasting+..................................++'--forecast' and '--budget' both use the periodic transaction rules in+the journal to generate temporary transactions for reporting purposes.+However they are separate features - though you can use both at the same+time if you want. Here are some differences between them:++-forecast -budget+--------------------------------------------------------------------------+is a general option; it enables is a balance command option;+forecasting with all reports it selects the balance+ report's budget mode+generates visible transactions which generates invisible+appear in reports transactions which produce+ goal amounts+generates forecast transactions from generates budget goal+after the last regular transaction, to transactions throughout the+the end of the report period; or with report period, optionally+an argument '--forecast=PERIODEXPR' restricted by periods+generates them throughout the specified in the periodic+specified period, both optionally transaction rules+restricted by periods specified in the+periodic transaction rules+uses all periodic rules uses all periodic rules; or+ with an argument+ '--budget=DESCPAT' uses just+ the rules matched by DESCPAT+++File: hledger.info, Node: Balance report layout, Next: Some useful balance reports, Prev: Budget report, Up: balance++24.6.15 Balance report layout+-----------------------------++The '--layout' option affects how balance reports show multi-commodity+amounts and commodity symbols, which can improve readability. It can+also normalise the data for easy consumption by other programs. It has+four possible values:++ * '--layout=wide[,WIDTH]': commodities are shown on a single line,+ optionally elided to WIDTH+ * '--layout=tall': each commodity is shown on a separate line+ * '--layout=bare': commodity symbols are in their own column, amounts+ are bare numbers+ * '--layout=tidy': data is normalised to easily-consumed "tidy" form,+ with one row per data value++ Here are the '--layout' modes supported by each output format Only+CSV output supports all of them:++- txt csv html json sql+---------------------------------------+wide Y Y Y+tall Y Y Y+bare Y Y Y+tidy Y++ Examples:++* Menu:++* Wide layout::+* Tall layout::+* Bare layout::+* Tidy layout::+++File: hledger.info, Node: Wide layout, Next: Tall layout, Up: Balance report layout++24.6.15.1 Wide layout+.....................++With many commodities, reports can be very wide:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide+Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total +==================++====================================================================================================================================================================================================================+ Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT +------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT ++ A width limit reduces the width, but some commodities will be hidden:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32+Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total +==================++===========================================================================================================================+ Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. +------------------++---------------------------------------------------------------------------------------------------------------------------+ || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more.. +++File: hledger.info, Node: Tall layout, Next: Bare layout, Prev: Wide layout, Up: Balance report layout++24.6.15.2 Tall layout+.....................++Each commodity gets a new line (may be different in each column), and+account names are repeated:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall+Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total +==================++==================================================+ Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD + Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT + Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD + Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA + Assets:US:ETrade || 18.00 VHT 294.00 VHT +------------------++--------------------------------------------------+ || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD + || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT + || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD + || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA + || 18.00 VHT 294.00 VHT +++File: hledger.info, Node: Bare layout, Next: Tidy layout, Prev: Tall layout, Up: Balance report layout++24.6.15.3 Bare layout+.....................++Commodity symbols are kept in one column, each commodity has its own+row, amounts are bare numbers, account names are repeated:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare+Balance changes in 2012-01-01..2014-12-31:++ || Commodity 2012 2013 2014 Total +==================++=============================================+ Assets:US:ETrade || GLD 0 70.00 0 70.00 + Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00 + Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50 + Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00 + Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00 +------------------++---------------------------------------------+ || GLD 0 70.00 0 70.00 + || ITOT 10.00 18.00 -11.00 17.00 + || USD 337.18 -98.12 4881.44 5120.50 + || VEA 12.00 10.00 14.00 36.00 + || VHT 106.00 18.00 170.00 294.00 ++ Bare layout also affects CSV output, which is useful for producing+data that is easier to consume, eg for making charts:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare+"account","commodity","balance"+"Assets:US:ETrade","GLD","70.00"+"Assets:US:ETrade","ITOT","17.00"+"Assets:US:ETrade","USD","5120.50"+"Assets:US:ETrade","VEA","36.00"+"Assets:US:ETrade","VHT","294.00"+"total","GLD","70.00"+"total","ITOT","17.00"+"total","USD","5120.50"+"total","VEA","36.00"+"total","VHT","294.00"++ Bare layout will sometimes display an extra row for the no-symbol+commodity, because of zero amounts (hledger treats zeroes as+commodity-less, usually). This can break 'hledger-bar' confusingly+(workaround: add a 'cur:' query to exclude the no-symbol row).+++File: hledger.info, Node: Tidy layout, Prev: Bare layout, Up: Balance report layout++24.6.15.4 Tidy layout+.....................++This produces normalised "tidy data" (see+https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)+where every variable has its own column and each row represents a single+data point. This is the easiest kind of data for other software to+consume:++$ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy+"account","period","start_date","end_date","commodity","value"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","GLD","0"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","ITOT","10.00"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","USD","337.18"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","VEA","12.00"+"Assets:US:ETrade","2012","2012-01-01","2012-12-31","VHT","106.00"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","GLD","70.00"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","ITOT","18.00"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","USD","-98.12"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","VEA","10.00"+"Assets:US:ETrade","2013","2013-01-01","2013-12-31","VHT","18.00"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","GLD","0"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","ITOT","-11.00"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","USD","4881.44"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","VEA","14.00"+"Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"+++File: hledger.info, Node: Some useful balance reports, Prev: Balance report layout, Up: balance++24.6.16 Some useful balance reports+-----------------------------------++Some frequently used 'balance' options/reports are:++ * 'bal -M revenues expenses'+ Show revenues/expenses in each month. Also available as the+ 'incomestatement' command.++ * 'bal -M -H assets liabilities'+ Show historical asset/liability balances at each month end. Also+ available as the 'balancesheet' command.++ * 'bal -M -H assets liabilities equity'+ Show historical asset/liability/equity balances at each month end.+ Also available as the 'balancesheetequity' command.++ * 'bal -M assets not:receivable'+ Show changes to liquid assets in each month. Also available as the+ 'cashflow' command.++ Also:++ * 'bal -M expenses -2 -SA'+ Show monthly expenses summarised to depth 2 and sorted by average+ amount.++ * 'bal -M --budget expenses'+ Show monthly expenses and budget goals.++ * 'bal -M --valuechange investments'+ Show monthly change in market value of investment assets.++ * 'bal investments --valuechange -D date:lastweek amt:'>1000' -STA+ [--invert]'+ Show top gainers [or losers] last week+++File: hledger.info, Node: balancesheet, Next: balancesheetequity, Prev: balance, Up: PART 4 COMMANDS++24.7 balancesheet+=================++(bs)++ This command displays a balance sheet, showing historical ending+balances of asset and liability accounts. (To see equity as well, use+the balancesheetequity command.) Amounts are shown with normal positive+sign, as in conventional financial statements.++ This report shows accounts declared with the 'Asset', 'Cash' or+'Liability' type (see account types). Or if no such accounts are+declared, it shows top-level accounts named 'asset' or 'liability' (case+insensitive, plurals allowed) and their subaccounts.++ Example:++$ hledger balancesheet+Balance Sheet 2008-12-31++ || 2008-12-31 +====================++============+ Assets || +--------------------++------------+ assets:bank:saving || $1 + assets:cash || $-2 +--------------------++------------+ || $-1 +====================++============+ Liabilities || +--------------------++------------+ liabilities:debts || $-1 +--------------------++------------+ || $-1 +====================++============+ Net: || 0 ++ This command is a higher-level variant of the 'balance' command, and+supports 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', 'tsv' (_Added in+1.32_), 'html', and 'json'.+++File: hledger.info, Node: balancesheetequity, Next: cashflow, Prev: balancesheet, Up: PART 4 COMMANDS++24.8 balancesheetequity+=======================++(bse)++ This command displays a balance sheet, showing historical ending+balances of asset, liability and equity accounts. Amounts are shown+with normal positive sign, as in conventional financial statements.++ This report shows accounts declared with the 'Asset', 'Cash',+'Liability' or 'Equity' type (see account types). Or if no such+accounts are declared, it shows top-level accounts named 'asset',+'liability' or 'equity' (case insensitive, plurals allowed) and their+subaccounts.++ Example:++$ hledger balancesheetequity+Balance Sheet With Equity 2008-12-31++ || 2008-12-31 +====================++============+ Assets || +--------------------++------------+ assets:bank:saving || $1 + assets:cash || $-2 +--------------------++------------+ || $-1 +====================++============+ Liabilities || +--------------------++------------+ liabilities:debts || $-1 +--------------------++------------+ || $-1 +====================++============+ Equity || +--------------------++------------+--------------------++------------+ || 0 +====================++============+ Net: || 0 ++ This command is a higher-level variant of the 'balance' command, and+supports 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 report is the easiest way to see if the accounting equation+(A+L+E = 0) is satisfied (after you have done a 'close --retain' to+merge revenues and expenses with equity, and perhaps added+'--infer-equity' to balance your commodity conversions).++ This command also supports the output destination and output format+options The output formats supported are 'txt', 'csv', 'tsv', 'html',+and 'json'.+++File: hledger.info, Node: cashflow, Next: check, Prev: balancesheetequity, Up: PART 4 COMMANDS++24.9 cashflow+=============++(cf)++ This command displays a (simple) cashflow statement, showing the+inflows and outflows affecting "cash" (ie, liquid, easily convertible)+assets. Amounts are shown with normal positive sign, as in conventional+financial statements.++ This report shows accounts declared with the 'Cash' type (see account+types). Or if no such accounts are declared, it shows accounts++ * under a top-level account named 'asset' (case insensitive, plural+ allowed)+ * whose name contains some variation of 'cash', 'bank', 'checking' or+ 'saving'.++ More precisely: all accounts matching this case insensitive regular+expression:++ '^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)'++ and their subaccounts.++ An example cashflow report:++$ hledger cashflow+Cashflow Statement 2008++ || 2008 +====================++======+ Cash flows || +--------------------++------+ assets:bank:saving || $1 + assets:cash || $-2 +--------------------++------+ || $-1 ++ This command is a higher-level variant of the 'balance' command, and+supports 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', 'tsv' (_Added in+1.32_), 'html', and 'json'.+++File: hledger.info, Node: check, Next: close, Prev: cashflow, Up: PART 4 COMMANDS++24.10 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++ If you are an Emacs user, you can also configure flycheck-hledger to+run these checks, providing instant feedback as you edit the journal.++ Here are the checks currently available:++* Menu:++* Default checks::+* Strict checks::+* Other checks::+* Custom checks::+* More about specific checks::+++File: hledger.info, Node: Default checks, Next: Strict checks, Up: check++24.10.1 Default checks+----------------------++These checks are run automatically by (almost) all hledger commands:++ * *parseable* - data files are in a supported format, with no syntax+ errors and no invalid include directives.++ * *autobalanced* - all transactions are balanced, after converting to+ cost. Missing amounts and missing costs are inferred automatically+ where possible.++ * *assertions* - all balance assertions in the journal are passing.+ (This check can be disabled with '-I'/'--ignore-assertions'.)+++File: hledger.info, Node: Strict checks, Next: Other checks, Prev: Default checks, Up: check++24.10.2 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':++ * *balanced* - all transactions are balanced after converting to+ cost, without inferring missing costs. If conversion costs are+ required, they must be explicit.++ * *accounts* - all account names used by transactions have been+ declared++ * *commodities* - all commodity symbols used have been declared+++File: hledger.info, Node: Other checks, Next: Custom checks, Prev: Strict checks, Up: check++24.10.3 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:++ * *ordereddates* - transactions are ordered by date within each file++ * *payees* - all payees used by transactions have been declared++ * *recentassertions* - all accounts with balance assertions have a+ balance assertion within 7 days of their latest posting++ * *tags* - all tags used by transactions have been declared++ * *uniqueleafnames* - all account leaf names are unique+++File: hledger.info, Node: Custom checks, Next: More about specific checks, Prev: Other checks, Up: check++24.10.4 Custom checks+---------------------++A few more checks are are available as separate add-on commands, in+https://github.com/simonmichael/hledger/tree/master/bin:++ * *hledger-check-tagfiles* - all tag values containing / (a forward+ slash) exist as file paths++ * *hledger-check-fancyassertions* - more complex balance assertions+ are passing++ You could make similar scripts to perform your own custom checks.+See: Cookbook -> Scripting.+++File: hledger.info, Node: More about specific checks, Prev: Custom checks, Up: check++24.10.5 More about specific checks+----------------------------------++'hledger check recentassertions' will complain if any balance-asserted+account has postings more than 7 days after its latest balance+assertion. This aims to prevent the situation where you are regularly+updating your journal, but forgetting to check your balances against the+real world, then one day must dig back through months of data to find an+error. It assumes that adding a balance assertion requires/reminds you+to check the real-world balance. (That may not be true if you+auto-generate balance assertions from bank data; in that case, I+recommend to import transactions uncleared, and when you manually review+and clear them, also check the latest assertion against the real-world+balance.)+++File: hledger.info, Node: close, Next: codes, Prev: check, Up: PART 4 COMMANDS++24.11 close+===========++(equity)++ 'close' generates several kinds of "closing" and/or "opening"+transactions, useful in certain situations, including migrating balances+to a new journal file, retaining earnings into equity, consolidating+balances, or viewing lots. Like 'print', it prints valid journal+entries. You can append or copy these to your journal file(s) when you+are happy with how they look.++ 'close' currently has six modes, selected by a single mode flag:++* Menu:++* close --migrate::+* close --close::+* close --open::+* close --assert::+* close --assign::+* close --retain::+* close customisation::+* close and balance assertions::+* close examples::+++File: hledger.info, Node: close --migrate, Next: close --close, Up: close++24.11.1 close -migrate+----------------------++This is the most common mode. It prints a "closing balances"+transaction that zeroes out all asset and liability balances (by+default), and an opposite "opening balances" transaction that restores+them again. The balancing account will be 'equity:opening/closing+balances' (or another specified by '--close-acct' or '--open-acct').++ This is useful when migrating balances to a new journal file at the+start of a new year. Essentially, you run 'hledger close+--migrate=NEWYEAR -e NEWYEAR' and then copy the closing transaction to+the end of the old file and the opening transaction to the start of the+new file. The opening transaction sets correct starting balances in the+new file when it is used alone, and the closing transaction keeps+balances correct when you use both old and new files together, by+cancelling out the following opening transaction and preventing buildup+of duplicated opening balances. Think of the closing/opening pair as+"moving the balances into the next file".++ You can close a different set of accounts by providing a query. Eg+if you want to include equity, you can add 'assets liabilities equity'+or 'type:ALE' arguments. (The balancing account is always excluded.)+Revenues and expenses usually are not migrated to a new file directly;+see '--retain' below.++ The generated transactions will have a 'start:' tag, with its value+set to '--migrate''s 'NEW' argument if any, for easier matching or+exclusion. When 'NEW' is not specified, it will be inferred if possible+by incrementing a number (eg a year number) within the default journal's+main file name. The other modes behave similarly.+++File: hledger.info, Node: close --close, Next: close --open, Prev: close --migrate, Up: close++24.11.2 close -close+--------------------++This prints just the closing balances transaction of '--migrate'. It is+the default behaviour if you specify no mode flag. Using the+customisation options below, you can move balances from any set of+accounts to a different account.+++File: hledger.info, Node: close --open, Next: close --assert, Prev: close --close, Up: close++24.11.3 close -open+-------------------++This prints just the opening balances transaction of '--migrate'. It is+similar to Ledger's equity command.+++File: hledger.info, Node: close --assert, Next: close --assign, Prev: close --open, Up: close++24.11.4 close -assert+---------------------++This prints a "closing balances" transaction (with 'balances:' tag),+that just declares balance assertions for the current balances without+changing them. It could be useful as documention and to guard against+changes.+++File: hledger.info, Node: close --assign, Next: close --retain, Prev: close --assert, Up: close++24.11.5 close -assign+---------------------++This prints an "opening balances" transaction that restores the account+balances using balance assignments. Balance assignments work regardless+of any previous balance, so a preceding closing balances transaction is+not needed.++ However, omitting the closing balances transaction would unbalance+equity. This is relatively harmless for personal reports, but it+disturbs the accounting equation, removing a source of error detection.+So '--migrate' is generally the best way to set to set balances in new+files, for now.+++File: hledger.info, Node: close --retain, Next: close customisation, Prev: close --assign, Up: close++24.11.6 close -retain+---------------------++This is like '--close' with different defaults: it prints a "retain+earnings" transaction (with 'retain:' tag), that transfers revenue and+expense balances to 'equity:retained earnings'.++ This is a different kind of closing, called "retaining earnings" or+"closing the books"; it is traditionally performed by businesses at the+end of each accounting period, to consolidate revenues and expenses into+the main equity balance. ("Revenues" and "expenses" are actually equity+by another name, kept separate temporarily for reporting purposes.)++ In personal accounting you generally don't need to do this, unless+you want the 'balancesheetequity' report to show a zero total,+demonstrating that the accounting equation (A-L=E) is satisfied.+++File: hledger.info, Node: close customisation, Next: close and balance assertions, Prev: close --retain, Up: close++24.11.7 close customisation+---------------------------++In all modes, the following things can be overridden:++ * the accounts to be closed/opened, with account query arguments+ * the balancing account, with '--close-acct=ACCT' and/or+ '--open-acct=ACCT'+ * the transaction descriptions, with '--close-desc=DESC' and+ '--open-desc=DESC'+ * the transaction's tag value, with a '--MODE=NEW' option argument+ * the closing/opening dates, with '-e OPENDATE'++ By default, the closing date is yesterday, or the journal's end date,+whichever is later; and the opening date is always one day after the+closing date. You can change these by specifying a report end date; the+closing date will be the last day of the report period. Eg '-e 2024'+means "close on 2023-12-31, open on 2024-01-01".++ With '--x/--explicit', the balancing amount will be shown explicitly,+and if it involves multiple commodities, a separate posting will be+generated for each of them (similar to 'print -x').++ With '--interleaved', each individual transfer is shown with source+and destination postings next to each other (perhaps useful for+troubleshooting).++ With '--show-costs', balances' costs are also shown, with different+costs kept separate. This may generate very large journal entries, if+you have many currency conversions or investment transactions. 'close+--show-costs' is currently the best way to view investment lots with+hledger. (To move or dispose of lots, see the more capable+'hledger-move' script.)+++File: hledger.info, Node: close and balance assertions, Next: close examples, Prev: close customisation, Up: close++24.11.8 close and balance assertions+------------------------------------++'close' adds balance assertions verifying that the accounts have been+reset to zero in a closing transaction or restored to their previous+balances in an opening transaction. These provide useful error+checking, but you can ignore them temporarily with '-I', or remove them+if you prefer.++ Single-commodity, subaccount-exclusive balance assertions ('=') are+generated by default. This can be changed with '--assertion-type='==*''+(eg).++ When running 'close' you should probably avoid using '-C', '-R',+'status:' (filtering by status or realness) or '--auto' (generating+postings), since the generated balance assertions would then require+these.++ Transactions with multiple dates (eg posting dates) spanning the file+boundary also can disrupt the balance assertions:++2023-12-30 a purchase made in december, cleared in january+ expenses:food 5+ assets:bank:checking -5 ; date: 2023-01-02++ To solve this you can transfer the money to and from a temporary+account, splitting the multi-day transaction into two single-day+transactions:++; in 2022.journal:+2022-12-30 a purchase made in december, cleared in january+ expenses:food 5+ equity:pending -5++; in 2023.journal:+2023-01-02 last year's transaction cleared+ equity:pending 5 = 0+ assets:bank:checking -5+++File: hledger.info, Node: close examples, Prev: close and balance assertions, Up: close++24.11.9 close examples+----------------------++* Menu:++* Retain earnings::+* Migrate balances to a new file::+* More detailed close examples::+++File: hledger.info, Node: Retain earnings, Next: Migrate balances to a new file, Up: close examples++24.11.9.1 Retain earnings+.........................++Record 2022's revenues/expenses as retained earnings on 2022-12-31,+appending the generated transaction to the journal:++$ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal++ After this, to see 2022's revenues and expenses you must exclude the+retain earnings transaction:++$ hledger -f 2022.journal is not:desc:'retain earnings'+++File: hledger.info, Node: Migrate balances to a new file, Next: More detailed close examples, Prev: Retain earnings, Up: close examples++24.11.9.2 Migrate balances to a new file+........................................++Close assets/liabilities on 2022-12-31 and re-open them on 2023-01-01:++$ hledger close --migrate -f 2022.journal -p 2022+# copy/paste the closing transaction to the end of 2022.journal+# copy/paste the opening transaction to the start of 2023.journal++ After this, to see 2022's end-of-year balances you must exclude the+closing balances transaction:++$ hledger -f 2022.journal bs not:desc:'closing balances'++ For more flexibility, it helps to tag closing and opening+transactions with eg 'start:NEWYEAR', then you can ensure correct+balances by excluding all opening/closing transactions except the first,+like so:++$ hledger bs -Y -f 2021.j -f 2022.j -f 2023.j expr:'tag:start=2021 or not tag:start'+$ hledger bs -Y -f 2021.j -f 2022.j expr:'tag:start=2021 or not tag:start'+$ hledger bs -Y -f 2022.j -f 2023.j expr:'tag:start=2022 or not tag:start'+$ hledger bs -Y -f 2021.j expr:'tag:start=2021 or not tag:start'+$ hledger bs -Y -f 2022.j expr:'tag:start=2022 or not tag:start'+$ hledger bs -Y -f 2023.j # unclosed file, no query needed+++File: hledger.info, Node: More detailed close examples, Prev: Migrate balances to a new file, Up: close examples++24.11.9.3 More detailed close examples+......................................++See examples/multi-year.+++File: hledger.info, Node: codes, Next: commodities, Prev: close, Up: PART 4 COMMANDS++24.12 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:++2022/1/1 (123) Supermarket + Food $5.00+ Checking ++2022/1/2 (124) Post Office+ Postage $8.32+ Checking++2022/1/3 Supermarket+ Food $11.23+ Checking ++2022/1/4 (126) Post Office+ Postage $3.21+ Checking++$ hledger codes+123+124+126++$ hledger codes -E+123+124++126+++File: hledger.info, Node: commodities, Next: demo, Prev: codes, Up: PART 4 COMMANDS++24.13 commodities+=================++List all commodity/currency symbols used or declared in the journal.+++File: hledger.info, Node: demo, Next: descriptions, Prev: commodities, Up: PART 4 COMMANDS++24.14 demo+==========++Play demos of hledger usage in the terminal, if asciinema is installed.++ Run this command with no argument to list the demos. To play a demo,+write its number or a prefix or substring of its title. Tips:++ Make your terminal window large enough to see the demo clearly.++ Use the -s/-speed SPEED option to set your preferred playback speed,+eg '-s4' to play at 4x original speed or '-s.5' to play at half speed.+The default speed is 2x.++ Other asciinema options can be added following a double dash, eg '--+-i.1' to limit pauses or '-- -h' to list asciinema's other options.++ During playback, several keys are available: SPACE to pause/unpause,+. to step forward (while paused), CTRL-c quit.++ Examples:++$ hledger demo # list available demos+$ hledger demo 1 # play the first demo at default speed (2x)+$ hledger demo install -s4 # play the "install" demo at 4x speed+++File: hledger.info, Node: descriptions, Next: diff, Prev: demo, Up: PART 4 COMMANDS++24.15 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 transactions.++ Example:++$ hledger descriptions+Store Name+Gas Station | Petrol+Person A+++File: hledger.info, Node: diff, Next: files, Prev: descriptions, Up: PART 4 COMMANDS++24.16 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+multiple 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:+++File: hledger.info, Node: files, Next: help, Prev: diff, Up: PART 4 COMMANDS++24.17 files+===========++List all files included in the journal. With a REGEX argument, only+file names matching the regular expression (case sensitive) are shown.+++File: hledger.info, Node: help, Next: import, Prev: files, Up: PART 4 COMMANDS++24.18 help+==========++Show the hledger user manual in the terminal, with 'info', 'man', or a+pager. With a TOPIC argument, open it at that topic if possible. TOPIC+can be any heading in the manual, or a heading prefix, case insensitive.+Eg: 'commands', 'print', 'forecast', 'journal', 'amount', '"auto+postings"'.++ This command shows the hledger manual built in to your hledger+version. It can be useful when offline, or when you prefer the terminal+to a web browser, or when the appropriate hledger manual or viewing+tools are not installed on your system.++ By default it chooses the best viewer found in $PATH, trying (in this+order): 'info', 'man', '$PAGER', 'less', 'more'. You can force the use+of info, man, or a pager with the '-i', '-m', or '-p' flags, If no+viewer can be found, or the command is run non-interactively, it just+prints the manual to stdout.++ If using 'info', note that version 6 or greater is needed for TOPIC+lookup. If you are on mac you will likely have info 4.8, and should+consider installing a newer version, eg with 'brew install texinfo'+(#1770).++ Examples++$ hledger help --help # show how the help command works+$ hledger help # show the hledger manual with info, man or $PAGER+$ hledger help journal # show the journal topic in the hledger manual+$ hledger help -m journal # show it with man, even if info is installed+++File: hledger.info, Node: import, Next: incomestatement, Prev: help, Up: PART 4 COMMANDS++24.19 import+============++Read new transactions added to each FILE provided as arguments since+last run, and add them to the journal. Or with -dry-run, just print the+transactions that would be added. Or with -catchup, just mark all of+the FILEs' current transactions as imported, without importing them.++ This command may append new transactions to the main journal file+(which should be in journal format). Existing transactions are not+changed. This is one of the few hledger commands that writes to the+journal file (see also 'add').++ Unlike other hledger commands, with 'import' the journal file is an+output file, and will be modified, though only by appending (existing+data will not be changed). The input files are specified as arguments,+so to import one or more CSV files to your main journal, you will run+'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.++* Menu:++* Deduplication::+* Import testing::+* Importing balance assignments::+* Commodity display styles::+++File: hledger.info, Node: Deduplication, Next: Import testing, Up: import++24.19.1 Deduplication+---------------------++'import' tries to import only the transactions which are new since the+last import, ignoring any that it has seen in previous runs. So if your+bank's CSV includes the last three months of data, you can download and+'import' it every month (or week, or day) and only the new transactions+will be imported each time.++ It works as follows. For each imported 'FILE' (usually CSV, but they+could be any of hledger's input formats):++ * It tries to recall the latest date seen previously, reading it from+ a hidden '.latest.FILE' in the same directory.+ * Then it processes 'FILE', ignoring any transactions on or before+ the "latest seen" date.++ And after a successful import, it updates the '.latest.FILE'(s) for+next time (unless '--dry-run' was used).++ This is a limited kind of deduplication, let's call it "date+skipping". Within each input file, it avoids reprocessing the same+dates across successive runs. This is a simple system that works for+most real-world CSV files; it assumes these are true, or true enough:++ 1. new items always have the newest dates+ 2. item dates are stable across successive downloads+ 3. the order of same-date items is stable across downloads+ 4. the name of the input file is stable across downloads++ If you have a bank whose CSV dates or ordering occasionally change,+you can reduce the chance of this happening in new transactions by+importing more often, and in old transactions it doesn't matter. And+remember you can use CSV rules files as input, which is one way to+ensure a stable file name.++ 'import' doesn't detect other kinds of duplication, such as duplicate+transactions within a single run. (In part, because legitimate+duplicate transactions can easily occur in real-world data.) So, say+you downloaded but forgot to import 'bank.1.csv', and a week later you+downloaded 'bank.2.csv' with overlapping data. Now you should not+import both of these at once ('hledger import bank.1.csv bank.2.csv');+the overlapping transactions which appear twice would not be+deduplicated since this is considered a single import. Instead, import+these files one at a time, and also use the same filename each time for+a common "latest seen" state:++$ mv bank.1.csv bank.csv; hledger import bank.csv+$ mv bank.2.csv bank.csv; hledger import bank.csv++ Normally you can ignore the '.latest.*' files, but if needed, you can+delete them (to make all transactions unseen), or construct/modify them+(to catch up to a certain date). The format is just a single ISO-format+date ('YYYY-MM-DD'), possibly repeated on multiple lines. It means "I+have seen transactions up to this date, and this many of them occurring+on that date".++ 'hledger print --new' also uses and updates these '.latest.*' files,+but it is less often used.++ Related: CSV > Working with CSV > Deduplicating, importing.+++File: hledger.info, Node: Import testing, Next: Importing balance assignments, Prev: Deduplication, Up: import++24.19.2 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'++ Note: when importing from multiple files at once, it's currently+possible for some .latest files to be updated successfully, while the+actual import fails because of a problem in one of the files, leaving+them out of sync (and causing some transactions to be missed). To+prevent this, do a -dry-run first and fix any problems before the real+import.+++File: hledger.info, Node: Importing balance assignments, Next: Commodity display styles, Prev: Import testing, Up: import++24.19.3 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.)+++File: hledger.info, Node: Commodity display styles, Prev: Importing balance assignments, Up: import++24.19.4 Commodity display styles+--------------------------------++Imported amounts will be formatted according to the canonical commodity+styles (declared or inferred) in the main journal file.+++File: hledger.info, Node: incomestatement, Next: notes, Prev: import, Up: PART 4 COMMANDS++24.20 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.++ This report shows accounts declared with the 'Revenue' or 'Expense'+type (see account types). Or if no such accounts are declared, it shows+top-level accounts named 'revenue' or 'income' or 'expense' (case+insensitive, plurals allowed) and their subaccounts.++ Example:++$ hledger incomestatement+Income Statement 2008++ || 2008 +===================++======+ Revenues || +-------------------++------+ income:gifts || $1 + income:salary || $1 +-------------------++------+ || $2 +===================++======+ Expenses || +-------------------++------+ expenses:food || $1 + expenses:supplies || $1 +-------------------++------+ || $2 +===================++======+ Net: || 0 ++ This command is a higher-level variant of the 'balance' command, and+supports 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', 'tsv' (_Added in+1.32_), 'html', and 'json'.+++File: hledger.info, Node: notes, Next: payees, Prev: incomestatement, Up: PART 4 COMMANDS++24.21 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+transactions. 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+++File: hledger.info, Node: payees, Next: prices, Prev: notes, Up: PART 4 COMMANDS++24.22 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+++File: hledger.info, Node: prices, Next: print, Prev: payees, Up: PART 4 COMMANDS++24.23 prices+============++Print the market prices declared with P directives. With+-infer-market-prices, also show any additional prices inferred from+costs. With -show-reverse, also show additional prices inferred by+reversing known prices.++ Price amounts are always displayed with their full precision, except+for reverse prices which are limited to 8 decimal digits.++ Prices can be filtered by a date:, cur: or amt: query.++ Generally if you run this command with -infer-market-prices+-show-reverse, it will show the same prices used internally to calculate+value reports. But if in doubt, you can inspect those directly by+running the value report with -debug=2.+++File: hledger.info, Node: print, Next: register, Prev: prices, Up: PART 4 COMMANDS++24.24 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).++ 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/regenerate your journal you should take care to also copy+over the directives and inter-transaction comments.++ Eg:++$ hledger print -f examples/sample.journal date:200806+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++* Menu:++* print explicitness::+* print amount style::+* print parseability::+* print other features::+* print output format::+++File: hledger.info, Node: print explicitness, Next: print amount style, Up: print++24.24.1 print explicitness+--------------------------++Normally, whether posting amounts are implicit or explicit is preserved.+For example, when an amount is omitted in the journal, it will not+appear in the output. Similarly, if a conversion cost is implied but+not written, it will not appear in the output.++ You can use the '-x'/'--explicit' flag to force explicit display of+all amounts and costs. This 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'.++ The '-x'/'--explicit' flag will cause any postings with a+multi-commodity amount (which can arise when a multi-commodity+transaction has an implicit amount) to be split into multiple+single-commodity postings, keeping the output parseable.+++File: hledger.info, Node: print amount style, Next: print parseability, Prev: print explicitness, Up: print++24.24.2 print amount style+--------------------------++Amounts are shown right-aligned within each transaction (but not aligned+across all transactions; you can do that with ledger-mode in Emacs).++ Amounts will be (mostly) normalised to their commodity display style:+their symbol placement, decimal mark, and digit group marks will be made+consistent. By default, decimal digits are shown as they are written in+the journal.++ With the '--round' (_Added in 1.32_) option, 'print' will try+increasingly hard to display decimal digits according to the commodity+display styles:++ * '--round=none' show amounts with original precisions (default)+ * '--round=soft' add/remove decimal zeros in amounts (except costs)+ * '--round=hard' round amounts (except costs), possibly hiding+ significant digits+ * '--round=all' round all amounts and costs++ 'soft' is good for non-lossy cleanup, formatting amounts more+consistently where it's safe to do so.++ 'hard' and 'all' can cause 'print' to show invalid unbalanced journal+entries; they may be useful eg for stronger cleanup, with manual fixups+when needed.+++File: hledger.info, Node: print parseability, Next: print other features, Prev: print amount style, Up: print++24.24.3 print parseability+--------------------------++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 (though the same can be achieved with 'expr:' queries+now):++# 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:++ * Value reporting affects posting amounts but not balance assertion+ or balance assignment amounts, potentially causing those to fail.+ * Auto postings can generate postings with too many missing amounts.+ * Account aliases can generate bad account names.+++File: hledger.info, Node: print other features, Next: print output format, Prev: print parseability, Up: print++24.24.4 print, other features+-----------------------------++With '-B'/'--cost', amounts with costs are shown converted to cost.++ With '--new', print shows only transactions it has not seen on a+previous run. This uses the same deduplication system as the 'import'+command. (See import's docs for details.)++ With '-m DESC'/'--match=DESC', print shows one recent transaction+whose description is most similar to DESC. DESC should contain at least+two characters. If there is no similar-enough match, no transaction+will be shown and the program exit code will be non-zero.+++File: hledger.info, Node: print output format, Prev: print other features, Up: print++24.24.5 print output format+---------------------------++This command also supports the output destination and output format+options The output formats supported are 'txt', 'beancount' (_Added in+1.32_), 'csv', 'tsv' (_Added in 1.32_), 'json' and 'sql'.++ The 'beancount' format tries to produce Beancount-compatible output,+as follows:++ * Transaction and postings with unmarked status are converted to+ cleared ('*') status.+ * Transactions' payee and note are backslash-escaped and+ double-quote-escaped and wrapped in double quotes.+ * Transaction tags are copied to Beancount #tag format.+ * Commodity symbols are converted to upper case, and a small number+ of currency symbols like '$' are converted to the corresponding+ currency names.+ * Account name parts are capitalised and unsupported characters are+ replaced with '-'. If an account name part does not begin with a+ letter, or if the first part is not Assets, Liabilities, Equity,+ Income, or Expenses, an error is raised. (Use '--alias' options to+ bring your accounts into compliance.)+ * An 'open' directive is generated for each account used, on the+ earliest transaction date.++ Some limitations:++ * Balance assertions are removed.+ * Balance assignments become missing amounts.+ * Virtual and balanced virtual postings become regular postings.+ * Directives are not converted.++ 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","","",""++ * There is one CSV record per posting, with the parent transaction's+ fields repeated.+ * 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.)+ * The amount is separated into "commodity" (the symbol) and "amount"+ (numeric quantity) fields.+ * The numeric amount is repeated in either the "credit" or "debit"+ column, for convenience. (Those names are not accurate in the+ accounting sense; it just puts negative amounts under credit and+ zero or greater amounts under debit.)+++File: hledger.info, Node: register, Next: rewrite, Prev: print, Up: PART 4 COMMANDS++24.25 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.++ For performance reasons, column widths are chosen based on the first+1000 lines; this means unusually wide values in later lines can cause+visual discontinuities as column widths are adjusted. If you want to+ensure perfect alignment, at the cost of more time and memory, use the+'--align-all' flag.++ The '--historical'/'-H' flag adds the balance from any undisplayed+prior postings to the running total. This is useful when you want to+see 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+numbers. 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.++ With '-m DESC'/'--match=DESC', register does a fuzzy search for one+recent posting whose description is most similar to DESC. DESC should+contain at least two characters. If there is no similar-enough match,+no posting will be shown and the program exit code will be non-zero.++* Menu:++* Custom register output::+++File: hledger.info, Node: Custom register output, Up: register++24.25.1 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', 'tsv' (_Added in+1.32_), and 'json'.+++File: hledger.info, Node: rewrite, Next: roi, Prev: register, Up: PART 4 COMMANDS++24.26 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+transaction'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+commodity.++* Menu:++* Re-write rules in a file::+* Diff output format::+* rewrite vs print --auto::+++File: hledger.info, Node: Re-write rules in a file, Next: Diff output format, Up: rewrite++24.26.1 Re-write rules in a file+--------------------------------++During the run this tool will execute so called "Automated Transactions"+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+transactions 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+postings.+++File: hledger.info, Node: Diff output format, Next: rewrite vs print --auto, Prev: Re-write rules in a file, Up: rewrite++24.26.2 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+containing 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+++File: hledger.info, Node: rewrite vs print --auto, Prev: Diff output format, Up: rewrite++24.26.3 rewrite vs. print -auto+-------------------------------++This command predates print -auto, and currently does much the same+thing, but with these differences:++ * with multiple files, rewrite lets rules in any file affect all+ other files. print -auto uses standard directive scoping; rules+ affect only child files.++ * rewrite's query limits which transactions can be rewritten; all are+ printed. print -auto's query limits which transactions are+ printed.++ * rewrite applies rules specified on command line or in the journal.+ print -auto applies rules specified in the journal.+++File: hledger.info, Node: roi, Next: stats, Prev: rewrite, Up: PART 4 COMMANDS++24.27 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, also known as money-weighted rate of return) and time-weighted+rate of return (TWR) for your investments for the time period requested.+IRR is always annualized due to the way it is computed, but TWR is+reported both as a rate over the chosen reporting period and as an+annual rate.++ 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:++ * 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.+ * Error (SearchFailed): Failed to find solution for Internal Rate of+ Return (IRR). Either search does not converge to a solution, or+ converges too slowly.++ Examples:++ * Using roi to compute total return of investment in stocks:+ https://github.com/simonmichael/hledger/blob/master/examples/investing/roi-unrealised.ledger++ * Cookbook > Return on Investment: https://hledger.org/roi.html++* Menu:++* Spaces and special characters in --inv and --pnl::+* Semantics of --inv and --pnl::+* IRR and TWR explained::+++File: hledger.info, Node: Spaces and special characters in --inv and --pnl, Next: Semantics of --inv and --pnl, Up: roi++24.27.1 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'"+++File: hledger.info, Node: Semantics of --inv and --pnl, Next: IRR and TWR explained, Prev: Spaces and special characters in --inv and --pnl, Up: roi++24.27.2 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.++ * "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++ * "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+++File: hledger.info, Node: IRR and TWR explained, Prev: Semantics of --inv and --pnl, Up: roi++24.27.3 IRR and TWR explained+-----------------------------++"ROI" stands for "return on investment". Traditionally this was+computed as a difference between current value of investment and its+initial value, expressed in percentage of the initial value.++ However, this approach is only practical in simple cases, where+investments receives no in-flows or out-flows of money, and where rate+of growth is fixed over time. For more complex scenarios you need+different ways to compute rate of return, and this command implements+two of them: IRR and TWR.++ Internal rate of return, or "IRR" (also called "money-weighted rate+of return") takes into account effects of in-flows and out-flows, and+the time between them. Investment at a particular fixed interest rate+is going to give you more interest than the same amount invested at the+same interest rate, but made later in time. If you are withdrawing from+your investment, your future gains would be smaller (in absolute+numbers), and will be a smaller percentage of your initial investment,+so your IRR will be smaller. And if you are adding to your investment,+you will receive bigger absolute gains, which will be a bigger+percentage of your initial investment, so your IRR will be larger.++ 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 "unrealized+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+account for the effect of your in-flows and out-flows, but unlike IRR it+will try to compute the true rate of return of the underlying asset,+compensating for the effect that deposits and withdrawas have on the+apparent rate of growth of your investment.++ 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, and make TWR less sensitive than IRR to the effects of+cash in-flows and out-flows.++ References:++ * Explanation of rate of return+ * Explanation of IRR+ * Explanation of TWR+ * IRR vs TWR+ * Examples of computing IRR and TWR and discussion of the limitations+ of both metrics+++File: hledger.info, Node: stats, Next: tags, Prev: roi, Up: PART 4 COMMANDS++24.28 stats+===========++Show journal and performance statistics.++ The stats command shows summary information for the whole journal, or+a matched part of it. With a reporting interval, it shows a report for+each report period.++ The default output is fairly impersonal, though it reveals the main+file name. With '-v/--verbose', more details are shown, like file+paths, included files, and commodity names.++ It also shows some run time statistics:++ * elapsed time+ * throughput: the number of transactions processed per second+ * live: the peak memory in use by the program to do its work+ * alloc: the peak memory allocation from the OS as seen by GHC.+ Measuring this externally, eg with GNU time, is more accurate;+ usually that will be a larger number; sometimes (with swapping?)+ smaller.++ The 'stats' command's run time is similar to that of a balance+report.++ Example:++$ hledger stats -f examples/1ktxns-1kaccts.journal +Main file : .../1ktxns-1kaccts.journal+Included files : 0+Txns span : 2000-01-01 to 2002-09-27 (1000 days)+Last txn : 2002-09-26 (7827 days ago)+Txns : 1000 (1.0 per day)+Txns last 30 days : 0 (0.0 per day)+Txns last 7 days : 0 (0.0 per day)+Payees/descriptions : 1000+Accounts : 1000 (depth 10)+Commodities : 26+Market prices : 1000+Runtime stats : 0.12 s elapsed, 8266 txns/s, 4 MB live, 16 MB alloc++ This command supports the -o/-output-file option (but not+-O/-output-format).+++File: hledger.info, Node: tags, Next: test, Prev: stats, Up: PART 4 COMMANDS++24.29 tags+==========++List the tags used in the journal, or their values.++ This command lists the tag names used in the journal, whether on+transactions, postings, or account declarations.++ With a TAGREGEX argument, only tag names matching this regular+expression (case insensitive, infix matched) are shown.++ With QUERY arguments, only transactions and accounts matching this+query are considered. If the query involves transaction fields (date:,+desc:, amt:, ...), the search is restricted to the matched transactions+and their accounts.++ With the -values flag, the tags' unique non-empty values are listed+instead. With -E/-empty, blank/empty values are also shown.++ With -parsed, tags or values are shown in the order they were parsed,+with duplicates included. (Except, tags from account declarations are+always shown first.)++ Tip: remember, accounts also acquire tags from their parents,+postings also acquire tags from their account and transaction,+transactions also acquire tags from their postings.+++File: hledger.info, Node: test, Prev: tags, Up: PART 4 COMMANDS++24.30 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).+++File: hledger.info, Node: PART 5 COMMON TASKS, Next: BUGS, Prev: PART 4 COMMANDS, Up: Top++25 PART 5: COMMON TASKS+***********************++Here are some quick examples of how to do some basic tasks with hledger.++* Menu:++* Getting help::+* Constructing command lines::+* Starting a journal file::+* Setting LEDGER_FILE::+* Setting opening balances::+* Recording transactions::+* Reconciling::+* Reporting::+* Migrating to a new file::+++File: hledger.info, Node: Getting help, Next: Constructing command lines, Up: PART 5 COMMON TASKS++25.1 Getting help+=================++Here's how to list commands and view options and command docs:++$ hledger # show available commands+$ hledger --help # show common options+$ hledger CMD --help # show CMD's options, common options and CMD's documentation++ You can also view your hledger version's manual in several formats by+using the help command. Eg:++$ hledger help # show the hledger manual with info, man or $PAGER (best available)+$ hledger help journal # show the journal topic in the hledger manual+$ hledger help --help # find out more about the help command++ To view manuals and introductory docs on the web, visit+https://hledger.org. Chat and mail list support and discussion archives+can be found at https://hledger.org/support.+++File: hledger.info, Node: Constructing command lines, Next: Starting a journal file, Prev: Getting help, Up: PART 5 COMMON TASKS++25.2 Constructing command lines+===============================++hledger has a flexible command line interface. We strive to keep it+simple and ergonomic, but if you run into one of the sharp edges+described in OPTIONS, here are some tips that might help:++ * command-specific options must go after the command (it's fine to+ put common options there too: 'hledger CMD OPTS ARGS')+ * running add-on executables directly simplifies command line parsing+ ('hledger-ui OPTS ARGS')+ * enclose "problematic" args in single quotes+ * if needed, also add a backslash to hide regular expression+ metacharacters from the shell+ * to see how a misbehaving command line is being parsed, add+ '--debug=2'.+++File: hledger.info, Node: Starting a journal file, Next: Setting LEDGER_FILE, Prev: Constructing command lines, Up: PART 5 COMMON TASKS++25.3 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 (see below). 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 2023.journal+$ echo "export LEDGER_FILE=$HOME/finance/2023.journal" >> ~/.profile+$ source ~/.profile+$ hledger stats+Main file : /Users/simon/finance/2023.journal+Included files : +Transactions span : to (0 days)+Last transaction : none+Transactions : 0 (0.0 per day)+Transactions last 30 days: 0 (0.0 per day)+Transactions last 7 days : 0 (0.0 per day)+Payees/descriptions : 0+Accounts : 0 (depth 0)+Commodities : 0 ()+Market prices : 0 ()+++File: hledger.info, Node: Setting LEDGER_FILE, Next: Setting opening balances, Prev: Starting a journal file, Up: PART 5 COMMON TASKS++25.4 Setting LEDGER_FILE+========================++How to set 'LEDGER_FILE' permanently depends on your setup:++ On unix and mac, running these commands in the terminal will work for+many people; adapt as needed:++$ echo 'export LEDGER_FILE=~/finance/2023.journal' >> ~/.profile+$ source ~/.profile++ When correctly configured, in a new terminal window 'env | grep+LEDGER_FILE' will show your file, and so will 'hledger files'.++ On mac, this additional step might be helpful for GUI applications+(like Emacs started from the dock): add an entry to+'~/.MacOSX/environment.plist' like++{+ "LEDGER_FILE" : "~/finance/2023.journal"+}++ and then run 'killall Dock' in a terminal window (or restart the+machine).++ On Windows, see https://www.java.com/en/download/help/path.html, or+try running these commands in a powershell window (let us know if it+persists across a reboot, and if you need to be an Administrator):++> CD+> MKDIR finance+> SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal"+++File: hledger.info, Node: Setting opening balances, Next: Recording transactions, Prev: Setting LEDGER_FILE, Up: PART 5 COMMON TASKS++25.5 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+balances on this date. Here are two ways to do it:++ * The first way: open the journal in any text editor and save an+ entry like this:++ 2023-01-01 * opening balances+ assets:bank:checking $1000 = $1000+ assets:bank:savings $2000 = $2000+ assets:cash $100 = $100+ liabilities:creditcard $-50 = $-50+ equity:opening/closing balances++ 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.++ * 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/2023.journal+ Any command line arguments will be used as defaults.+ Use tab key to complete, readline keys to edit, enter to accept defaults.+ An optional (CODE) may follow transaction dates.+ An optional ; COMMENT may follow descriptions or amounts.+ If you make a mistake, enter < at any prompt to go one step backward.+ To end a transaction, enter . when prompted.+ To quit, enter . at a date prompt or press control-d or control-c.+ Date [2023-02-07]: 2023-01-01+ Description: * opening balances+ Account 1: assets:bank:checking+ Amount 1: $1000+ Account 2: assets:bank:savings+ Amount 2 [$-1000]: $2000+ Account 3: assets:cash+ Amount 3 [$-3000]: $100+ Account 4: liabilities:creditcard+ Amount 4 [$-3100]: $-50+ Account 5: equity:opening/closing balances+ Amount 5 [$-3050]: + Account 6 (or . or enter to finish this transaction): .+ 2023-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050+ + Save this transaction to the journal ? [y]: + Saved.+ Starting the next transaction (. or ctrl-D/ctrl-C to quit)+ Date [2023-01-01]: .++ If you're using version control, this could be a good time to commit+the journal. Eg:++$ git commit -m 'initial balances' 2023.journal+++File: hledger.info, Node: Recording transactions, Next: Reconciling, Prev: Setting opening balances, Up: PART 5 COMMON TASKS++25.6 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:++2023/1/10 * gift received+ assets:cash $20+ income:gifts++2023.1.12 * farmers market+ expenses:food $13+ assets:cash++2023-01-15 paycheck+ income:salary+ assets:bank:checking $1000+++File: hledger.info, Node: Reconciling, Next: Reporting, Prev: Recording transactions, Up: PART 5 COMMON TASKS++25.7 Reconciling+================++Periodically you should reconcile - compare your hledger-reported+balances 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+discrepancies.++ 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:++ 2023-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 checking -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 transaction 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+--register 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 '2023-01-15' and 'paycheck'++ If you're using version control, this can be another good time to+commit:++$ git commit -m 'txns' 2023.journal+++File: hledger.info, Node: Reporting, Next: Migrating to a new file, Prev: Reconciling, Up: PART 5 COMMON TASKS++25.8 Reporting+==============++Here are some basic reports.++ Show all transactions:++$ hledger print+2023-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++2023-01-10 * gift received+ assets:cash $20+ income:gifts++2023-01-12 * farmers market+ expenses:food $13+ assets:cash++2023-01-15 * paycheck+ income:salary+ assets:bank:checking $1000++2023-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ 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 -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 -2+Balance Sheet 2023-01-16++ || 2023-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 2023-01-01-2023-01-16++ || 2023-01-01-2023-01-16 +===============++=======================+ Revenues || +---------------++-----------------------+ income:gifts || $20 + income:salary || $1000 +---------------++-----------------------+ || $1020 +===============++=======================+ Expenses || +---------------++-----------------------+ expenses:food || $13 + expenses:misc || $2 +---------------++-----------------------+ || $15 +===============++=======================+ Net: || $1005 ++ The final total is your net income during this period.++ Show transactions affecting your wallet, with running total:++$ hledger register cash+2023-01-01 opening balances assets:cash $100 $100+2023-01-10 gift received assets:cash $20 $120+2023-01-12 farmers market assets:cash $-13 $107+2023-01-16 adjust cash assets:cash $-2 $105++ Show weekly posting counts as a bar chart:++$ hledger activity -W+2019-12-30 *****+2023-01-06 ****+2023-01-13 ****+++File: hledger.info, Node: Migrating to a new file, Prev: Reporting, Up: PART 5 COMMON TASKS++25.9 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.+++File: hledger.info, Node: BUGS, Prev: PART 5 COMMON TASKS, Up: Top++26 BUGS+*******++We welcome bug reports in the hledger issue tracker (shortcut:+http://bugs.hledger.org), or on the #hledger chat or hledger mail list+(https://hledger.org/support).++ Some known issues and limitations:++ The need to precede add-on command options with '--' when invoked+from hledger is awkward. (See Command options, Constructing command+lines.)++ A UTF-8-aware system locale must be configured to work with non-ascii+data. (See Unicode characters, Troubleshooting.)++ On Microsoft Windows, depending whether you are running in a CMD+window or a Cygwin/MSYS/Mintty window and how you installed hledger,+non-ascii characters and colours may not be supported, and the tab key+may not be supported by 'hledger add'. (Running in a WSL window should+resolve these.)++ When processing large data files, hledger uses more memory than+Ledger.++* Menu:++* Troubleshooting::+++File: hledger.info, Node: Troubleshooting, Up: BUGS++26.1 Troubleshooting+====================++Here are some common issues you might encounter when you run hledger,+and how to resolve them (and remember also you can usually get quick+Support):++ *PATH issues: I get an error like "No command 'hledger' found"*+Depending how you installed hledger, the executables may not be in your+shell's PATH. Eg on unix systems, stack installs hledger in+'~/.local/bin' and cabal installs it in '~/.cabal/bin'. You may need to+add one of these directories to your shell's PATH, and/or open a new+terminal window.++ *LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not+using it*++ * 'LEDGER_FILE' should be a real environment variable, not just a+ shell variable. Eg on unix, the command 'env | grep LEDGER_FILE'+ should show it. You may need to use 'export' (see+ https://stackoverflow.com/a/7411509).+ * You may need to force your shell to see the new configuration. A+ simple way is to close your terminal window and open a new one.++ *LANG issues: I get errors like "Illegal byte sequence" or "Invalid+or incomplete multibyte or wide character" or "commitAndReleaseBuffer:+invalid argument (invalid character)"*+Programs compiled with GHC (hledger, haskell build tools, etc.) need+the system locale to be UTF-8-aware, or they will fail when they+encounter non-ascii characters. To fix it, set the LANG environment+variable to a locale which supports UTF-8 and which is installed on your+system.++ On unix, 'locale -a' lists the installed locales. Look for one which+mentions 'utf8', 'UTF-8' or similar. Some examples: 'C.UTF-8',+'en_US.utf-8', 'fr_FR.utf8'. If necessary, use your system package+manager to install one. Then select it by setting the 'LANG'+environment variable. Note, exact spelling and capitalisation of the+locale name may be important: Here's one common way to configure this+permanently for your shell:++$ echo "export LANG=en_US.utf8" >>~/.profile+# close and re-open terminal window++ If you are using Nix (not NixOS) for GHC and Hledger, you might need+to set the 'LOCALE_ARCHIVE' variable:++$ echo "export LOCALE_ARCHIVE=${glibcLocales}/lib/locale/locale-archive" >>~/.profile+# close and re-open terminal window++ *COMPATIBILITY ISSUES: hledger gives an error with my Ledger file*+Not all of Ledger's journal file syntax or feature set is supported.+See hledger and Ledger for full details.+++Tag Table:+Node: Top208+Node: PART 1 USER INTERFACE3811+Ref: #part-1-user-interface3950+Node: Input3950+Ref: #input4060+Node: Text encoding5027+Ref: #text-encoding5141+Node: Data formats5707+Ref: #data-formats5842+Node: Standard input7431+Ref: #standard-input7571+Node: Multiple files7798+Ref: #multiple-files7937+Node: Strict mode8535+Ref: #strict-mode8645+Node: Commands9369+Ref: #commands9471+Node: Add-on commands10538+Ref: #add-on-commands10640+Node: Options11756+Ref: #options11868+Node: General help options12196+Ref: #general-help-options12342+Node: General input options12624+Ref: #general-input-options12806+Node: General reporting options13463+Ref: #general-reporting-options13624+Node: Command line tips17014+Ref: #command-line-tips17144+Node: Option repetition17403+Ref: #option-repetition17547+Node: Special characters17651+Ref: #special-characters17824+Node: Single escaping shell metacharacters17987+Ref: #single-escaping-shell-metacharacters18228+Node: Double escaping regular expression metacharacters18831+Ref: #double-escaping-regular-expression-metacharacters19142+Node: Triple escaping for add-on commands19668+Ref: #triple-escaping-for-add-on-commands19928+Node: Less escaping20572+Ref: #less-escaping20726+Node: Unicode characters21050+Ref: #unicode-characters21225+Node: Regular expressions22637+Ref: #regular-expressions22810+Node: hledger's regular expressions25906+Ref: #hledgers-regular-expressions26065+Node: Argument files27451+Ref: #argument-files27587+Node: Output28084+Ref: #output28196+Node: Output destination28323+Ref: #output-destination28454+Node: Output format28879+Ref: #output-format29025+Node: CSV output30622+Ref: #csv-output30738+Node: HTML output30841+Ref: #html-output30979+Node: JSON output31073+Ref: #json-output31211+Node: SQL output32133+Ref: #sql-output32249+Node: Commodity styles32984+Ref: #commodity-styles33124+Node: Colour33862+Ref: #colour33980+Node: Box-drawing34384+Ref: #box-drawing34502+Node: Paging34792+Ref: #paging34906+Node: Debug output35859+Ref: #debug-output35965+Node: Environment36628+Ref: #environment36752+Node: PART 2 DATA FORMATS37296+Ref: #part-2-data-formats37439+Node: Journal37439+Ref: #journal37548+Node: Journal cheatsheet39916+Ref: #journal-cheatsheet40043+Node: Comments46130+Ref: #comments46258+Node: Transactions47074+Ref: #transactions47197+Node: Dates48211+Ref: #dates48318+Node: Simple dates48363+Ref: #simple-dates48479+Node: Posting dates48979+Ref: #posting-dates49097+Node: Status50066+Ref: #status50167+Node: Code51832+Ref: #code51935+Node: Description52167+Ref: #description52298+Node: Payee and note52854+Ref: #payee-and-note52960+Node: Transaction comments53945+Ref: #transaction-comments54098+Node: Postings54461+Ref: #postings54592+Node: Debits and credits55624+Ref: #debits-and-credits55771+Node: The two space delimiter56234+Ref: #the-two-space-delimiter56391+Node: Account names56799+Ref: #account-names56929+Node: Amounts58603+Ref: #amounts58731+Node: Decimal marks59632+Ref: #decimal-marks59759+Node: Digit group marks60736+Ref: #digit-group-marks60889+Node: Commodity61371+Ref: #commodity61500+Node: Costs62488+Ref: #costs62583+Node: Balance assertions64740+Ref: #balance-assertions64893+Node: Assertions and ordering65977+Ref: #assertions-and-ordering66166+Node: Assertions and multiple included files66705+Ref: #assertions-and-multiple-included-files66965+Node: Assertions and multiple -f files67465+Ref: #assertions-and-multiple--f-files67710+Node: Assertions and costs68107+Ref: #assertions-and-costs68316+Node: Assertions and commodities68757+Ref: #assertions-and-commodities68972+Node: Assertions and subaccounts70416+Ref: #assertions-and-subaccounts70642+Node: Assertions and virtual postings71086+Ref: #assertions-and-virtual-postings71324+Node: Assertions and auto postings71456+Ref: #assertions-and-auto-postings71686+Node: Assertions and precision72331+Ref: #assertions-and-precision72513+Node: Posting comments72780+Ref: #posting-comments72943+Node: Transaction balancing73320+Ref: #transaction-balancing73479+Node: Tags75322+Ref: #tags75441+Node: Tag names76784+Ref: #tag-names76891+Node: Special tags77279+Ref: #special-tags77411+Node: Tag values78924+Ref: #tag-values79034+Node: Directives79906+Ref: #directives80033+Node: Directives and multiple files81363+Ref: #directives-and-multiple-files81541+Node: Directive effects82308+Ref: #directive-effects82462+Node: account directive85464+Ref: #account-directive85620+Node: Account comments86914+Ref: #account-comments87065+Node: Account error checking87573+Ref: #account-error-checking87766+Node: Account display order88955+Ref: #account-display-order89143+Node: Account types90153+Ref: #account-types90294+Node: alias directive93927+Ref: #alias-directive94088+Node: Basic aliases95138+Ref: #basic-aliases95269+Node: Regex aliases96013+Ref: #regex-aliases96170+Node: Combining aliases97060+Ref: #combining-aliases97238+Node: Aliases and multiple files98514+Ref: #aliases-and-multiple-files98718+Node: end aliases directive99297+Ref: #end-aliases-directive99516+Node: Aliases can generate bad account names99665+Ref: #aliases-can-generate-bad-account-names99913+Node: Aliases and account types100498+Ref: #aliases-and-account-types100690+Node: commodity directive101386+Ref: #commodity-directive101560+Node: Commodity directive syntax102973+Ref: #commodity-directive-syntax103158+Node: Commodity error checking104609+Ref: #commodity-error-checking104790+Node: decimal-mark directive105084+Ref: #decimal-mark-directive105266+Node: include directive105663+Ref: #include-directive105827+Node: P directive106739+Ref: #p-directive106884+Node: payee directive107773+Ref: #payee-directive107922+Node: tag directive108395+Ref: #tag-directive108550+Node: Periodic transactions109007+Ref: #periodic-transactions109172+Node: Periodic rule syntax111161+Ref: #periodic-rule-syntax111339+Node: Periodic rules and relative dates111984+Ref: #periodic-rules-and-relative-dates112250+Node: Two spaces between period expression and description!112761+Ref: #two-spaces-between-period-expression-and-description113038+Node: Auto postings113722+Ref: #auto-postings113870+Node: Auto postings and multiple files116700+Ref: #auto-postings-and-multiple-files116864+Node: Auto postings and dates117265+Ref: #auto-postings-and-dates117513+Node: Auto postings and transaction balancing / inferred amounts / balance assertions117688+Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions118044+Node: Auto posting tags118547+Ref: #auto-posting-tags118829+Node: Auto postings on forecast transactions only119465+Ref: #auto-postings-on-forecast-transactions-only119711+Node: Other syntax119958+Ref: #other-syntax120074+Node: Balance assignments120730+Ref: #balance-assignments120886+Node: Balance assignments and costs122258+Ref: #balance-assignments-and-costs122470+Node: Balance assignments and multiple files122680+Ref: #balance-assignments-and-multiple-files122910+Node: Bracketed posting dates123103+Ref: #bracketed-posting-dates123287+Node: D directive123801+Ref: #d-directive123969+Node: apply account directive125574+Ref: #apply-account-directive125754+Node: Y directive126441+Ref: #y-directive126601+Node: Secondary dates127429+Ref: #secondary-dates127583+Node: Star comments128397+Ref: #star-comments128557+Node: Valuation expressions129089+Ref: #valuation-expressions129266+Node: Virtual postings129388+Ref: #virtual-postings129565+Node: Other Ledger directives131012+Ref: #other-ledger-directives131208+Node: Other cost/lot notations131774+Ref: #other-costlot-notations131947+Node: CSV134536+Ref: #csv134629+Node: CSV rules cheatsheet136626+Ref: #csv-rules-cheatsheet136755+Node: source138553+Ref: #source138676+Node: separator139556+Ref: #separator139669+Node: skip140209+Ref: #skip140317+Node: date-format140861+Ref: #date-format140982+Node: timezone141706+Ref: #timezone141829+Node: newest-first142834+Ref: #newest-first142972+Node: intra-day-reversed143549+Ref: #intra-day-reversed143703+Node: decimal-mark144151+Ref: #decimal-mark144292+Node: fields list144631+Ref: #fields-list144770+Node: Field assignment146441+Ref: #field-assignment146585+Node: Field names147662+Ref: #field-names147793+Node: date field148996+Ref: #date-field149114+Node: date2 field149162+Ref: #date2-field149303+Node: status field149359+Ref: #status-field149502+Node: code field149551+Ref: #code-field149696+Node: description field149741+Ref: #description-field149901+Node: comment field149960+Ref: #comment-field150115+Node: account field150408+Ref: #account-field150558+Node: amount field151128+Ref: #amount-field151277+Node: currency field153969+Ref: #currency-field154122+Node: balance field154379+Ref: #balance-field154511+Node: if block154904+Ref: #if-block155025+Node: Matchers156433+Ref: #matchers156547+Node: What matchers match157344+Ref: #what-matchers-match157493+Node: Combining matchers157933+Ref: #combining-matchers158101+Node: Match groups158638+Ref: #match-groups158766+Node: if table159534+Ref: #if-table159656+Node: balance-type161537+Ref: #balance-type161666+Node: include162366+Ref: #include162493+Node: Working with CSV162937+Ref: #working-with-csv163084+Node: Rapid feedback163491+Ref: #rapid-feedback163624+Node: Valid CSV164076+Ref: #valid-csv164222+Node: File Extension164954+Ref: #file-extension165127+Node: Reading CSV from standard input165691+Ref: #reading-csv-from-standard-input165915+Node: Reading multiple CSV files166079+Ref: #reading-multiple-csv-files166310+Node: Reading files specified by rule166551+Ref: #reading-files-specified-by-rule166779+Node: Valid transactions167950+Ref: #valid-transactions168149+Node: Deduplicating importing168777+Ref: #deduplicating-importing168972+Node: Setting amounts170008+Ref: #setting-amounts170179+Node: Amount signs172537+Ref: #amount-signs172707+Node: Setting currency/commodity173604+Ref: #setting-currencycommodity173808+Node: Amount decimal places174982+Ref: #amount-decimal-places175188+Node: Referencing other fields175500+Ref: #referencing-other-fields175713+Node: How CSV rules are evaluated176610+Ref: #how-csv-rules-are-evaluated176827+Node: Well factored rules178280+Ref: #well-factored-rules178448+Node: CSV rules examples178772+Ref: #csv-rules-examples178907+Node: Bank of Ireland178972+Ref: #bank-of-ireland179109+Node: Coinbase180571+Ref: #coinbase180709+Node: Amazon181756+Ref: #amazon181881+Node: Paypal183600+Ref: #paypal183708+Node: Timeclock191352+Ref: #timeclock191457+Node: Timedot193633+Ref: #timedot193756+Node: Timedot examples196877+Ref: #timedot-examples196983+Node: PART 3 REPORTING CONCEPTS199154+Ref: #part-3-reporting-concepts199323+Node: Amount formatting199323+Ref: #amount-formatting199479+Node: Commodity display style199581+Ref: #commodity-display-style199735+Node: Rounding201422+Ref: #rounding201577+Node: Trailing decimal marks202027+Ref: #trailing-decimal-marks202206+Node: Amount parseability202960+Ref: #amount-parseability203116+Node: Time periods204541+Ref: #time-periods204667+Node: Report start & end date204785+Ref: #report-start-end-date204937+Node: Smart dates206596+Ref: #smart-dates206749+Node: Report intervals208617+Ref: #report-intervals208772+Node: Date adjustment209190+Ref: #date-adjustment209350+Node: Period expressions210201+Ref: #period-expressions210342+Node: Period expressions with a report interval212106+Ref: #period-expressions-with-a-report-interval212340+Node: More complex report intervals212554+Ref: #more-complex-report-intervals212799+Node: Multiple weekday intervals214600+Ref: #multiple-weekday-intervals214789+Node: Depth215611+Ref: #depth215713+Node: Queries216009+Ref: #queries216111+Node: Query types217707+Ref: #query-types217828+Node: Combining query terms221062+Ref: #combining-query-terms221239+Node: Queries and command options222802+Ref: #queries-and-command-options223007+Node: Queries and account aliases223256+Ref: #queries-and-account-aliases223461+Node: Queries and valuation223581+Ref: #queries-and-valuation223738+Node: Pivoting223943+Ref: #pivoting224057+Node: Generating data225834+Ref: #generating-data225966+Node: Forecasting227549+Ref: #forecasting227674+Node: --forecast228205+Ref: #forecast228336+Node: Inspecting forecast transactions229306+Ref: #inspecting-forecast-transactions229508+Node: Forecast reports230638+Ref: #forecast-reports230811+Node: Forecast tags231747+Ref: #forecast-tags231907+Node: Forecast period in detail232367+Ref: #forecast-period-in-detail232561+Node: Forecast troubleshooting233455+Ref: #forecast-troubleshooting233623+Node: Budgeting234526+Ref: #budgeting234646+Node: Cost reporting235083+Ref: #cost-reporting235217+Node: Recording costs235878+Ref: #recording-costs236014+Node: Reporting at cost237605+Ref: #reporting-at-cost237780+Node: Equity conversion postings238370+Ref: #equity-conversion-postings238584+Node: Inferring equity conversion postings241015+Ref: #inferring-equity-conversion-postings241278+Node: Combining costs and equity conversion postings242030+Ref: #combining-costs-and-equity-conversion-postings242340+Node: Requirements for detecting equity conversion postings243255+Ref: #requirements-for-detecting-equity-conversion-postings243577+Node: Infer cost and equity by default ?244777+Ref: #infer-cost-and-equity-by-default245006+Node: Value reporting245214+Ref: #value-reporting245356+Node: -V Value246095+Ref: #v-value246227+Node: -X Value in specified commodity246422+Ref: #x-value-in-specified-commodity246623+Node: Valuation date246772+Ref: #valuation-date246949+Node: Finding market price247732+Ref: #finding-market-price247943+Node: --infer-market-prices market prices from transactions249112+Ref: #infer-market-prices-market-prices-from-transactions249394+Node: Valuation commodity252156+Ref: #valuation-commodity252376+Node: --value Flexible valuation253589+Ref: #value-flexible-valuation253788+Node: Valuation examples255432+Ref: #valuation-examples255632+Node: Interaction of valuation and queries257564+Ref: #interaction-of-valuation-and-queries257804+Node: Effect of valuation on reports258281+Ref: #effect-of-valuation-on-reports258484+Node: PART 4 COMMANDS266179+Ref: #part-4-commands266328+Node: Commands overview266707+Ref: #commands-overview266841+Node: DATA ENTRY267020+Ref: #data-entry267144+Node: DATA CREATION267343+Ref: #data-creation267497+Node: DATA MANAGEMENT267615+Ref: #data-management267780+Node: REPORTS FINANCIAL267901+Ref: #reports-financial268076+Node: REPORTS VERSATILE268381+Ref: #reports-versatile268554+Node: REPORTS BASIC268807+Ref: #reports-basic268959+Node: HELP269468+Ref: #help269590+Node: ADD-ONS269700+Ref: #add-ons269806+Node: accounts270385+Ref: #accounts270518+Node: activity272405+Ref: #activity272524+Node: add272898+Ref: #add273008+Node: aregister275994+Ref: #aregister276115+Node: aregister and posting dates279021+Ref: #aregister-and-posting-dates279166+Node: balance279922+Ref: #balance280048+Node: balance features281038+Ref: #balance-features281178+Node: Simple balance report283088+Ref: #simple-balance-report283273+Node: Balance report line format284898+Ref: #balance-report-line-format285100+Node: Filtered balance report287258+Ref: #filtered-balance-report287450+Node: List or tree mode287777+Ref: #list-or-tree-mode287945+Node: Depth limiting289290+Ref: #depth-limiting289456+Node: Dropping top-level accounts290057+Ref: #dropping-top-level-accounts290257+Node: Showing declared accounts290567+Ref: #showing-declared-accounts290766+Node: Sorting by amount291297+Ref: #sorting-by-amount291464+Node: Percentages292134+Ref: #percentages292293+Node: Multi-period balance report292841+Ref: #multi-period-balance-report293041+Node: Balance change end balance295418+Ref: #balance-change-end-balance295627+Node: Balance report types297055+Ref: #balance-report-types297236+Node: Calculation type297734+Ref: #calculation-type297889+Node: Accumulation type298438+Ref: #accumulation-type298618+Node: Valuation type299539+Ref: #valuation-type299727+Node: Combining balance report types300728+Ref: #combining-balance-report-types300922+Node: Budget report302760+Ref: #budget-report302922+Node: Using the budget report305065+Ref: #using-the-budget-report305238+Node: Budget date surprises307341+Ref: #budget-date-surprises307541+Node: Selecting budget goals308705+Ref: #selecting-budget-goals308908+Node: Budgeting vs forecasting309653+Ref: #budgeting-vs-forecasting309830+Node: Balance report layout311330+Ref: #balance-report-layout311515+Node: Wide layout312468+Ref: #wide-layout312603+Node: Tall layout314873+Ref: #tall-layout315028+Node: Bare layout316179+Ref: #bare-layout316334+Node: Tidy layout318238+Ref: #tidy-layout318373+Node: Some useful balance reports319782+Ref: #some-useful-balance-reports319957+Node: balancesheet321042+Ref: #balancesheet321187+Node: balancesheetequity322798+Ref: #balancesheetequity322956+Node: cashflow324976+Ref: #cashflow325107+Node: check326594+Ref: #check326708+Node: Default checks327512+Ref: #default-checks327638+Node: Strict checks328135+Ref: #strict-checks328280+Node: Other checks328760+Ref: #other-checks328902+Node: Custom checks329435+Ref: #custom-checks329592+Node: More about specific checks330009+Ref: #more-about-specific-checks330171+Node: close330877+Ref: #close330988+Node: close --migrate331641+Ref: #close---migrate331768+Node: close --close333407+Ref: #close---close333551+Node: close --open333787+Ref: #close---open333928+Node: close --assert334038+Ref: #close---assert334184+Node: close --assign334405+Ref: #close---assign334553+Node: close --retain335079+Ref: #close---retain335232+Node: close customisation335977+Ref: #close-customisation336156+Node: close and balance assertions337623+Ref: #close-and-balance-assertions337820+Node: close examples339147+Ref: #close-examples339288+Node: Retain earnings339386+Ref: #retain-earnings339545+Node: Migrate balances to a new file339891+Ref: #migrate-balances-to-a-new-file340117+Node: More detailed close examples341245+Ref: #more-detailed-close-examples341443+Node: codes341469+Ref: #codes341586+Node: commodities342450+Ref: #commodities342578+Node: demo342648+Ref: #demo342769+Node: descriptions343685+Ref: #descriptions343815+Node: diff344106+Ref: #diff344221+Node: files345263+Ref: #files345372+Node: help345513+Ref: #help-1345622+Node: import346995+Ref: #import347118+Node: Deduplication348226+Ref: #deduplication348351+Node: Import testing351212+Ref: #import-testing351377+Node: Importing balance assignments352220+Ref: #importing-balance-assignments352426+Node: Commodity display styles353075+Ref: #commodity-display-styles353248+Node: incomestatement353377+Ref: #incomestatement353519+Node: notes354993+Ref: #notes355115+Node: payees355477+Ref: #payees355592+Node: prices356111+Ref: #prices356226+Node: print356879+Ref: #print356994+Node: print explicitness357970+Ref: #print-explicitness358113+Node: print amount style358892+Ref: #print-amount-style359062+Node: print parseability360132+Ref: #print-parseability360304+Node: print other features361053+Ref: #print-other-features361232+Node: print output format361753+Ref: #print-output-format361901+Node: register365040+Ref: #register365162+Node: Custom register output370193+Ref: #custom-register-output370324+Node: rewrite371671+Ref: #rewrite371789+Node: Re-write rules in a file373687+Ref: #re-write-rules-in-a-file373850+Node: Diff output format374999+Ref: #diff-output-format375182+Node: rewrite vs print --auto376274+Ref: #rewrite-vs.-print---auto376434+Node: roi376990+Ref: #roi377097+Node: Spaces and special characters in --inv and --pnl378909+Ref: #spaces-and-special-characters-in---inv-and---pnl379149+Node: Semantics of --inv and --pnl379637+Ref: #semantics-of---inv-and---pnl379876+Node: IRR and TWR explained381726+Ref: #irr-and-twr-explained381886+Node: stats385139+Ref: #stats385247+Node: tags386761+Ref: #tags-1386868+Node: test387877+Ref: #test387970+Node: PART 5 COMMON TASKS388712+Ref: #part-5-common-tasks388858+Node: Getting help389156+Ref: #getting-help389297+Node: Constructing command lines390057+Ref: #constructing-command-lines390258+Node: Starting a journal file390915+Ref: #starting-a-journal-file391117+Node: Setting LEDGER_FILE392319+Ref: #setting-ledger_file392511+Node: Setting opening balances393468+Ref: #setting-opening-balances393669+Node: Recording transactions396810+Ref: #recording-transactions396999+Node: Reconciling397555+Ref: #reconciling397707+Node: Reporting399964+Ref: #reporting400113+Node: Migrating to a new file404098+Ref: #migrating-to-a-new-file404255+Node: BUGS404554+Ref: #bugs404644+Node: Troubleshooting405523+Ref: #troubleshooting405623 End Tag Table
hledger.txt view
@@ -16,9104 +16,9104 @@ and largely compatible with ledger(1), and largely interconvertible with beancount(1). - This manual is for hledger's command line interface, version 1.33. It- also describes the common options, file formats and concepts used by- all hledger programs. It might accidentally teach you some bookkeep-- ing/accounting as well! You don't need to know everything in here to- use hledger productively, but when you have a question about function-- ality, this doc should answer it. It is detailed, so do skip ahead or- skim when needed. You can read it on hledger.org, or as an info manual- or man page on your system. You can also get it from hledger itself- with- hledger --man, hledger --info or hledger help [TOPIC].-- The main function of the hledger CLI is to read plain text files de-- scribing financial transactions, crunch the numbers, and print a useful- report on the terminal (or save it as HTML, CSV, JSON or SQL). Many- reports are available, as subcommands. hledger will also detect other- hledger-* executables as extra subcommands.-- hledger usually reads from (and appends to) a journal file specified by- the LEDGER_FILE environment variable (defaulting to- $HOME/.hledger.journal); or you can specify files with -f options. It- can also read timeclock files, timedot files, or any CSV/SSV/TSV file- with a date field.-- Here is a small journal file describing one transaction:-- 2015-10-16 bought food- expenses:food $10- assets:cash-- Transactions are dated movements of money (etc.) between two or more- accounts: bank accounts, your wallet, revenue/expense categories, peo-- ple, etc. You can choose any account names you wish, using : to indi-- cate subaccounts. There must be at least two spaces between account- name and amount. Positive amounts are inflow to that account (debit),- negatives are outflow from it (credit). (Some reports show revenue,- liability and equity account balances as negative numbers as a result;- this is normal.)-- hledger's add command can help you add transactions, or you can install- other data entry UIs like hledger-web or hledger-iadd. For more exten-- sive/efficient changes, use a text editor: Emacs + ledger-mode, VIM +- vim-ledger, or VS Code + hledger-vscode are some good choices (see- https://hledger.org/editors.html).-- To get started, run hledger add and follow the prompts, or save some- entries like the above in $HOME/.hledger.journal, then try commands- like:-- $ hledger print -x- $ hledger aregister assets- $ hledger balance- $ hledger balancesheet- $ hledger incomestatement-- Run hledger to list the commands. See also the "Starting a journal- file" and "Setting opening balances" sections in PART 5: COMMON TASKS.--PART 1: USER INTERFACE-Input- hledger reads one or more data files, each time you run it. You can- specify a file with -f, like so-- $ hledger -f FILE print-- Files are most often in hledger's journal format, with the .journal- file extension (.hledger or .j also work); these files describe trans-- actions, like an accounting general journal.-- When no file is specified, hledger looks for .hledger.journal in your- home directory.-- But most people prefer to keep financial files in a dedicated folder,- perhaps with version control. Also, starting a new journal file each- year is common (it's not required, but helps keep things fast and or-- ganised). So we usually configure a different journal file, by setting- the LEDGER_FILE environment variable, to something like ~/fi-- nance/2023.journal. For more about how to do that on your system, see- Common tasks > Setting LEDGER_FILE.-- Text encoding- Data files containing non-ascii characters must use UTF-8 encoding. An- optional byte order mark (BOM) is allowed, at the beginning of the file- (only).-- Also, your system should be configured with a locale that can decode- UTF-8 text. On some unix systems, you may need set the LANG environ-- ment variable, eg. You can read more about this in Unicode characters,- below.-- On unix systems you can check a file's encoding with the file command.- If you need to import from a UTF-16-encoded CSV file, say, you can con-- vert it to UTF-8 with the iconv command.-- 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: Automatically used for- files with extensions:- ------------------------------------------------------------------------------ journal hledger journal files and some .journal .j .hledger- Ledger journals, for transactions .ledger- timeclock timeclock files, for precise time .timeclock- logging- timedot timedot files, for approximate .timedot- time logging- csv Comma or other character sepa- .csv- rated values, for data import- ssv Semicolon separated values .ssv- tsv Tab separated values .tsv- rules CSV/SSV/TSV/other separated val- .rules- ues, alternate way-- These formats are described in more detail below.-- hledger detects the format automatically based on the file extensions- shown above. If it can't recognise the file extension, it assumes- journal format. So for non-journal files, it's important to use a- 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 containing tab- separated values:-- $ hledger -f tsv:/some/file.dat stats-- Standard input- The file name - means standard input:-- $ cat FILE | hledger -f- print-- If reading non-journal data in this way, you'll need to add a file for-- mat prefix, like:-- $ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:--- Multiple files- You can specify multiple -f options, to read multiple files as one big- journal. When doing this, note that certain features (described below)- will be affected:-- o Balance assertions will not see the effect of transactions in previ-- ous files. (Usually this doesn't matter as each file will set the- corresponding opening balances.)-- o Some directives will not affect previous or subsequent files.-- If needed, you can work around these by using a single parent file- which includes the others, or concatenating the files into one, 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 use the check command to run individual checks -- the ones- listed above and some more.--Commands- hledger provides various subcommands for getting things done. Most of- these commands do not change the journal file; they just read it and- output a report. A few commands assist with adding data and file man-- agement.-- To show the commands list, run hledger with no arguments. The commands- are described in detail in PART 4: COMMANDS, below.-- To use a particular command, run hledger CMD [CMDOPTS] [CMDARGS],-- o CMD is the full command name, or its standard abbreviation shown in- the commands list, or any unambiguous prefix of the name.-- o CMDOPTS are command-specific options, if any. Command-specific op-- tions must be written after the command name. Eg: hledger print -x.-- o CMDARGS are additional arguments to the command, if any. Most- hledger commands accept arguments representing a query, to limit the- data in some way. Eg: hledger reg assets:checking.-- To list a command's options, arguments, and documentation in the termi-- nal, run hledger CMD -h. Eg: hledger bal -h.-- Add-on commands- In addition to the built-in commands, you can install add-on commands:- programs or scripts named "hledger-SOMETHING", which will also appear- in hledger's commands list. If you used the hledger-install script,- you will have several add-ons installed already. Some more can be- found in hledger's bin/ directory, documented at- https://hledger.org/scripts.html.-- More precisely, add-on commands are programs or scripts in your shell's- PATH, whose name starts with "hledger-" and ends with no extension or a- recognised extension (".bat", ".com", ".exe", ".hs", ".js", ".lhs",- ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"), and (on unix- and mac) which has executable permission for the current user.-- You can run add-on commands using hledger, much like built-in commands:- hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]. But note the double- hyphen argument, required before add-on-specific options. Eg: hledger- ui -- --watch or hledger web -- --serve. If this causes difficulty,- you can always run the add-on directly, without using hledger:- hledger-ui --watch or hledger-web --serve.--Options- Run hledger -h to see general command line help, and general options- which are common to most hledger commands. These options can be writ-- ten anywhere on the command line. They can be grouped into help, in-- put, and reporting options:-- 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-- --pivot FIELDNAME- use some other field or tag for the account name-- -I --ignore-assertions- disable balance assertion checks (note: does not disable balance- assignments)-- -s --strict- do extra error checking (check that all posted accounts are de-- clared)-- General reporting options- -b --begin=DATE- include postings/txns on or after this date (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 ef-- fects)-- --today=DATE- override today's date (affects relative smart dates, for- tests/examples)-- -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-equity- infer conversion equity postings from costs-- --infer-costs- infer costs from conversion equity postings-- --infer-market-prices- use costs as additional market prices, as if they were P direc-- tives-- --forecast- generate transactions from periodic rules, between the latest- recorded txn and 6 months from today, or during the specified- PERIOD (= is required). Auto posting rules will be applied to- these transactions as well. Also, in hledger-ui make fu-- ture-dated transactions visible.-- --auto generate extra postings by applying auto posting rules to all- txns (not just forecast txns)-- --verbose-tags- add visible tags indicating transactions or postings which have- been generated/modified-- --commodity-style- Override the commodity style in the output for the specified- commodity. For example 'EUR1.000,00'.-- --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.-- --pretty[=WHEN]- Show prettier output, e.g. using unicode box-drawing charac-- ters. Accepts 'yes' (the default) or 'no' ('y', 'n', 'always',- 'never' also work). If you provide an argument you must use- '=', e.g. '--pretty=yes'.-- 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 line tips- Here are some details useful to know about for hledger command lines- (and elsewhere). Feel free to skip this section until you need it.-- Option repetition- If options are repeated in a command line, hledger will generally use- the last (right-most) occurence.-- Special characters- Single escaping (shell metacharacters)- In shell command lines, characters significant to your shell - such as- spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want- hledger to see them. This is done by enclosing them in single or dou-- ble quotes, or by writing a backslash before them. Eg to match an ac-- count 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 be-- low), one level of shell-escaping is lost from any options or arguments- intended for by the add-on command, so those need an extra level of- shell-escaping. Eg to match a literal $ sign while using the bash- shell and running an add-on command (ui):-- $ hledger ui cur:'\\$'-- or:-- $ hledger ui cur:\\\\$-- If you wondered why four backslashes, perhaps this helps:-- unescaped: $- escaped: \$- double-escaped: \\$- triple-escaped: \\\\$-- Or, you can avoid the extra escaping by running the add-on executable- directly:-- $ hledger-ui cur:\\$-- Less escaping- Options and arguments are sometimes used in places other than the shell- command line, where shell-escaping is not needed, so there you should- use one less level of escaping. Those places include:-- o an @argumentfile-- o hledger-ui's filter field-- o hledger-web's search form-- o GHCI's prompt (used by developers).-- Unicode characters- hledger is expected to handle non-ascii characters correctly:-- o they should be parsed correctly in input files and on the command- line, by all hledger tools (add, iadd, hledger-web's search/add/edit- forms, etc.)-- o they should be displayed correctly by all hledger tools, and- on-screen alignment should be preserved.-- This requires a well-configured environment. Here are some tips:-- o A system locale must be configured, and it must be one that can de-- code the characters being used. In bash, you can set a locale like- this: export LANG=en_US.UTF-8. There are some more details in Trou-- bleshooting. This step is essential - without it, hledger will quit- on encountering a non-ascii character (as with all GHC-compiled pro-- grams).-- o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)- must support unicode-- o the terminal must be using a font which includes the required unicode- glyphs-- o the terminal should be configured to display wide characters as dou-- ble width (for report alignment)-- o on Windows, for best results you should run hledger in the same kind- of environment in which it was built. Eg hledger built in the stan-- dard CMD.EXE environment (like the binaries on our download page)- might show display problems when run in a cygwin or msys terminal,- and vice versa. (See eg #961).-- Regular expressions- A regular expression (regexp) is a small piece of text where certain- characters (like ., ^, $, +, *, (), |, [], \) have special meanings,- forming a tiny language for matching text precisely - very useful in- hledger and elsewhere. To learn all about them, visit regular-expres-- sions.info.-- hledger supports regexps whenever you are entering a pattern to match- something, eg in query arguments, account aliases, CSV if rules,- hledger-web's search form, hledger-ui's / search, etc. You may need to- wrap them in quotes, especially at the command line (see Special char-- acters above). Here are some examples:-- Account name queries (quoted for command line use):-- Regular expression: Matches:- ------------------- ------------------------------------------------------------- bank assets:bank, assets:bank:savings, expenses:art:banksy, ...- :bank assets:bank:savings, expenses:art:banksy- :bank: assets:bank:savings- '^bank' none of those ( ^ matches beginning of text )- 'bank$' assets:bank ( $ matches end of text )- 'big \$ bank' big $ bank ( \ disables following character's special meaning )- '\bbank\b' assets:bank, assets:bank:savings ( \b matches word boundaries )- '(sav|check)ing' saving or checking ( (|) matches either alternative )- 'saving|checking' saving or checking ( outer parentheses are not needed )- 'savings?' saving or savings ( ? matches 0 or 1 of the preceding thing )- 'my +bank' my bank, my bank, ... ( + matches 1 or more of the preceding thing )- 'my *bank' mybank, my bank, my bank, ... ( * matches 0 or more of the preceding thing )- 'b.nk' bank, bonk, b nk, ... ( . matches any character )-- Some other queries:-- desc:'amazon|amzn|audible' Amazon transactions- cur:EUR amounts with commodity symbol containing EUR- cur:'\$' amounts with commodity symbol containing $- cur:'^\$$' only $ amounts, not eg AU$ or CA$- cur:....? amounts with 4-or-more-character symbols- tag:.=202[1-3] things with any tag whose value contains 2021, 2022 or 2023-- Account name aliases: accept . instead of : as account separator:-- alias /\./=: replaces all periods in account names with colons-- Show multiple top-level accounts combined as one:-- --alias='/^[^:]+/=combined' ( [^:] matches any character other than : )-- Show accounts with the second-level part removed:-- --alias '/^([^:]+):[^:]+/ = \1'- match a top-level account and a second-level account- and replace those with just the top-level account- ( \1 in the replacement text means "whatever was matched- by the first parenthesised part of the regexp"-- CSV rules: match CSV records containing dining-related MCC codes:-- if \?MCC581[124]-- Match CSV records with a specific amount around the end/start of month:-- if %amount \b3\.99- & %date (29|30|31|01|02|03)$-- hledger's regular expressions- 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. backreferences are supported when doing text replacement in account- aliases or CSV rules, where backreferences can be used in the re-- placement string to reference capturing groups in the search regexp.- Otherwise, if you write \1, it will match the digit 1.-- 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.-- Argument files- You can save a set of command line options and arguments in a file, and- then reuse them by writing @FILENAME as a command line argument. Eg:- hledger bal @foo.args.-- Inside the argument file, each line should contain just one option or- argument. Don't use spaces except inside quotes (or you'll see a con-- fusing error); write = (or nothing) between a flag and its argument.- For the special characters mentioned above, use one less level of quot-- ing than you would at the command prompt.--Output- Output destination- hledger commands send their output to the terminal by default. You can- of course redirect this, eg into a file, using standard shell syntax:-- $ hledger print > foo.txt-- Some commands (print, register, stats, the balance commands) also pro-- vide the -o/--output-file option, which does the same thing without- needing the shell. Eg:-- $ hledger print -o foo.txt- $ hledger print -o - # write to stdout (the default)-- Output format- Some commands offer other kinds of output, not just text on the termi-- nal. Here are those commands and the formats currently supported:-- - txt csv/tsv html json sql- --------------------------------------------------------------------------------------- aregister Y Y Y Y- balance Y 1 Y 1 Y 1,2 Y- balancesheet Y 1 Y 1 Y 1 Y- balancesheete- Y 1 Y 1 Y 1 Y- quity- cashflow Y 1 Y 1 Y 1 Y- incomestatement Y 1 Y 1 Y 1 Y- print Y Y Y Y- register Y Y Y-- o 1 Also affected by the balance commands' --layout option.-- o 2 balance does not support html output without a report interval or- with --budget.-- The output format is selected by the -O/--output-format=FMT option:-- $ hledger print -O csv # print CSV on stdout-- or by the filename extension of an output file specified with the- -o/--output-file=FILE.FMT option:-- $ hledger balancesheet -o foo.csv # write CSV to foo.csv-- The -O option can be combined with -o to override the file extension,- if needed:-- $ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt-- Some notes about the various output formats:-- CSV output- o In CSV output, digit group marks (such as thousands separators) are- disabled automatically.-- HTML output- o HTML output can be styled by an optional hledger.css file in the same- directory.-- JSON output- o This is not yet much used; real-world feedback is welcome.-- o Our JSON is rather large and verbose, since it is a faithful repre-- sentation of hledger's internal data types. To understand the JSON,- read the Haskell type definitions, which are mostly in- https://github.com/simonmichael/hledger/blob/mas-- ter/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)-- SQL output- o This is not yet much used; real-world feedback is welcome.-- o SQL output is expected to work at least with SQLite, MySQL and Post-- gres.-- o For SQLite, it will be more useful if you modify the generated id- field to be a PRIMARY KEY. Eg:-- $ hledger print -O sql | sed 's/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g' | ...-- 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.-- Commodity styles- When displaying amounts, hledger infers a standard display style for- each commodity/currency, as described below in Commodity display style.-- If needed, this can be overridden by a -c/--commodity-style option (ex-- cept for cost amounts and amounts displayed by the print command, which- are always displayed with all decimal digits). For example, the fol-- lowing will force dollar amounts to be displayed as shown:-- $ hledger print -c '$1.000,0'-- This option can repeated to set the display style for multiple commodi-- ties/currencies. Its argument is as described in the commodity direc-- tive.-- In some cases hledger will adjust number formatting to improve their- parseability (such as adding trailing decimal marks when needed).-- Colour- In terminal output, some commands can produce colour when the terminal- supports it:-- o if the --color/--colour option is given a value of yes or always (or- no or never), colour will (or will not) be used;-- o otherwise, if the NO_COLOR environment variable is set, colour will- not be used;-- o otherwise, colour will be used if the output (terminal or file) sup-- ports it.-- Box-drawing- In terminal output, you can enable unicode box-drawing characters to- render prettier tables:-- o if the --pretty option is given a value of yes or always (or no or- never), unicode characters will (or will not) be used;-- o otherwise, unicode characters will not be used.-- Paging- When showing long output in the terminal, hledger will try to use the- pager specified by the PAGER environment variable, or less, or more.- (A pager is a helper program that shows one page at a time rather than- scrolling everything off screen). Currently it does this only for help- output, not for reports; specifically,-- o when listing commands, with hledger-- o when showing help with hledger [CMD] --help,-- o when viewing manuals with hledger help or hledger --man.-- Note the pager is expected to handle ANSI codes, which hledger uses eg- for bold emphasis. For the common pager less (and its more compatibil-- ity mode), we add R to the LESS and MORE environment variables to make- this work. If you use a different pager, you might need to configure- it similarly, to avoid seeing junk on screen (let us know). Otherwise,- you can set the NO_COLOR environment variable to 1 to disable all ANSI- output (see Colour).-- Debug output- We intend hledger to be relatively easy to troubleshoot, introspect and- develop. You can add --debug[=N] to any hledger command line to see- additional debug output. N ranges from 1 (least output, the default)- to 9 (maximum output). Typically you would start with 1 and increase- until you are seeing enough. Debug output goes to stderr, and is not- affected by -o/--output-file (unless you redirect stderr to stdout, eg:- 2>&1). It will be interleaved with normal output, which can help re-- veal when parts of the code are evaluated. To capture debug output in- a log file instead, you can usually redirect stderr, eg:-- hledger bal --debug=3 2>hledger.log--Environment- These environment variables affect hledger:-- COLUMNS This is normally set by your terminal; some hledger commands- (register) will format their output to this width. If not set, they- will try to use the available terminal width.-- LEDGER_FILE The main journal file to use when not specified with- -f/--file. Default: $HOME/.hledger.journal.-- NO_COLOR If this environment variable is set (with any value), hledger- will not use ANSI color codes in terminal output, unless overridden by- an explicit --color/--colour option.--PART 2: DATA FORMATS-Journal- hledger's usual data source is a plain text file containing journal en-- tries in hledger journal format. If you're looking for a quick refer-- ence, jump ahead to the journal cheatsheet (or use the table of con-- tents at https://hledger.org/hledger.html).-- This file represents an accounting General Journal. The .journal file- extension is most often used, though not strictly required. The jour-- nal file contains a number of transaction entries, each describing a- transfer of money (or any commodity) between two or more named ac-- counts, in a simple format readable by both hledger and humans.-- hledger's journal format is compatible with most of Ledger's journal- format, but not all of it. The differences and interoperation tips are- described at hledger and Ledger. With some care, and by avoiding in-- compatible features, you can keep your hledger journal readable by- Ledger and vice versa. This can useful eg for comparing the behaviour- of one app against the other.-- You can use hledger without learning any more about this file; just use- the add or web or import commands to create and update it.-- Many users, though, edit the journal file with a text editor, and track- changes with a version control system such as git. Editor addons such- as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and- 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.-- A hledger journal file can contain three kinds of thing: comment lines,- transactions, and/or directives (including periodic transaction rules- and auto posting rules). Understanding the journal file format will- also give you a good understanding of hledger's data model. Here's a- quick cheatsheet/overview, followed by detailed descriptions of each- part.-- Journal cheatsheet- # Here is the main syntax of hledger's journal format- # (omitting extra Ledger compatibility syntax).-- ###############################################################################-- # 1. These are comment lines, for notes or temporarily disabling things.- ; They begin with # or ;-- comment- Or, lines can be enclosed within "comment" / "end comment".- This is a block of- commented lines.- end comment-- # Some journal entries can have semicolon comments at end of line ; like this- # Some of them require 2 or more spaces before the semicolon.-- ###############################################################################-- # 2. Directives customise processing or output in some way.- # You don't need any directives to get started.- # But they can add more error checking, or change how things are displayed.- # They begin with a word, letter, or symbol.- # They are most often placed at the top, before transactions.-- account assets ; Declare valid account names and display order.- account assets:savings ; A subaccount. This one represents a bank account.- account assets:checking ; Another. Note, 2+ spaces after the account name.- account assets:receivable ; Accounting type is inferred from english names,- account passifs ; or declared with a "type" tag, type:L- account expenses ; type:X- ; A follow-on comment line, indented.- account expenses:rent ; Expense and revenue categories are also accounts.- ; Subaccounts inherit their parent's type.-- commodity $0.00 ; Declare valid commodities and their display styles.- commodity 1.000,00 EUR-- decimal-mark . ; The decimal mark used in this file (if ambiguous).-- payee Whole Foods ; Declare a valid payee name.-- tag trip ; Declare a valid tag name.-- P 2024-03-01 AAPL $179 ; Declare a market price for AAPL in $ on this date.-- include other.journal ; Include another journal file here.-- # Declare a recurring "periodic transaction", for budget/forecast reports- ~ monthly set budget goals ; <- Note, 2+ spaces before the description.- (expenses:rent) $1000- (expenses:food) $500-- # Declare an auto posting rule, to modify existing transactions in reports- = revenues:consulting- liabilities:tax:2024:us *0.25 ; Add a tax liability & expense- expenses:tax:2024:us *-0.25 ; for 25% of the revenue.-- ###############################################################################-- # 3. Transactions are what it's all about.- # They are dated events, usually movements of money between 2 or more accounts.- # They begin with a numeric date.- # Here is their basic shape:- #- # DATE DESCRIPTION ; The transaction's date and optional description.- # ACCOUNT1 AMOUNT ; A posting of an amount to/from this account, indented.- # ACCOUNT2 AMOUNT ; A second posting, balancing the first.- # ... ; More if needed. Amounts must sum to zero.- # ; Note, 2+ spaces between account names and amounts.-- 2024-01-01 opening balances ; At the start, declare pre-existing balances this way.- assets:savings $10000 ; Account names can be anything. lower case is easy to type.- assets:checking $1000 ; assets, liabilities, equity, revenues, expenses are common.- liabilities:credit card $-500 ; liabilities, equity, revenues balances are usually negative.- equity:start ; One amount can be left blank. $-10500 is inferred here.- ; Some of these accounts we didn't declare above,- ; so -s/--strict would complain.-- 2024-01-03 ! (12345) pay rent- ; Additional transaction comment lines, indented.- ; There can be a ! or * after the date meaning "pending" or "cleared".- ; There can be a parenthesised (code) after the date/status.- ; Amounts' sign shows direction of flow.- assets:checking $-500 ; Minus means removed from this account (credit).- expenses:rent $500 ; Plus means added to this account (debit).-- ; Keeping transactions in date order is optional (but helps error checking).-- 2024-01-02 Gringott's Bank | withdrawal ; Description can be PAYEE | NOTE- assets:bank:gold -10 gold- assets:pouch 10 gold-- 2024-01-02 shopping- expenses:clothing 1 gold- expenses:wands 5 gold- assets:pouch -6 gold-- 2024-01-02 receive gift- revenues:gifts -3 "Chocolate Frogs" ; Complex commodity symbols- assets:pouch 3 "Chocolate Frogs" ; must be in double quotes.-- 2024-01-15 buy some shares, in two lots ; Cost can be noted.- assets:investments:2024-01-15 2.0 AAAA @ $1.50 ; @ means per-unit cost- assets:investments:2024-01-15-02 3.0 AAAA @@ $4 ; @@ means total cost- ; ^ Per-lot subaccounts are sometimes useful.- assets:checking $-7-- 2024-01-15 assert some account balances on this date- ; Balances can be asserted in any transaction, with =, for extra error checking.- ; Assertion txns like this one can be made with hledger close --assert --show-costs- ;- assets:savings $0 = $10000- assets:checking $0 = $493- assets:bank:gold 0 gold = -10 gold- assets:pouch 0 gold = 4 gold- assets:pouch 0 "Chocolate Frogs" = 3 "Chocolate Frogs"- assets:investments:2024-01-15 0.0 AAAA = 2.0 AAAA @ $1.50- assets:investments:2024-01-15-02 0.0 AAAA = 3.0 AAAA @@ $4- liabilities:credit card $0 = $-500-- 2024-02-01 note some event, or a transaction not yet fully entered, on this date- ; Postings are not required.-- ; Some other date formats are allowed (but, consistent YYYY-MM-DD is useful).- 2024.01.01- 2024/1/1-- Comments- Lines in the journal will be ignored if they begin with a hash (#) or a- semicolon (;). (See also Other syntax.) hledger will also ignore re-- gions beginning with a comment line and ending with an end comment line- (or file end). Here's a suggestion for choosing between them:-- o # for top-level notes-- o ; for commenting out things temporarily-- o comment for quickly commenting large regions (remember it's there, or- you might get confused)-- Eg:-- # a comment line- ; another commentline- comment- A multi-line comment block,- continuing until "end comment" directive- or the end of the current file.- end comment-- Some hledger entries can have same-line comments attached to them, from- ; (semicolon) to end of line. See Transaction comments, Posting com-- ments, and Account comments below.-- Transactions- Transactions are the main unit of information in a journal file. They- represent events, typically a movement of some quantity of commodities- between two or more named accounts.-- Each transaction is recorded as a journal entry, beginning with a sim-- ple date in column 0. This can be followed by any of the following op-- tional fields, separated by spaces:-- o a status character (empty, !, or *)-- o a code (any short number or text, enclosed in parentheses)-- o a description (any remaining text until end of line or a semicolon)-- o a comment (any remaining text following a semicolon until end of- line, and any following indented lines beginning with a semicolon)-- o 0 or more indented posting lines, describing what was transferred and- the accounts involved (indented comment lines are also allowed, but- not blank lines or non-indented lines).-- Here's a simple journal file containing one transaction:-- 2008/01/01 income- assets:bank:checking $1- income:salary $-1-- Dates- Simple dates- Dates in the journal file use simple dates format: YYYY-MM-DD or- YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be- omitted, in which case it will be inferred from the context: the cur-- rent transaction, the default year set with a Y directive, or the cur-- rent date when the command is run. Some examples: 2010-01-31,- 2010/01/31, 2010.1.31, 1/31.-- (The UI also accepts simple dates, as well as the more flexible smart- dates documented in the hledger manual.)-- Posting dates- You can give individual postings a different date from their parent- transaction, by adding a posting comment containing a tag (see below)- like date:DATE. This is probably the best way to control posting dates- precisely. Eg in this example the expense should appear in May re-- ports, and the deduction from checking should be reported on 6/1 for- easy bank reconciliation:-- 2015/5/30- expenses:food $10 ; food purchased on saturday 5/30- assets:checking ; bank cleared it on monday, date:6/1-- $ hledger -f t.j register food- 2015-05-30 expenses:food $10 $10-- $ hledger -f t.j register checking- 2015-06-01 assets:checking $-10 $-10-- DATE should be a simple date; if the year is not specified it will use- the year of the transaction's date.- The date: tag must have a valid simple date value if it is present, eg- a date: tag with no value is not allowed.-- Status- Transactions (or individual postings within a transaction) can have a- status mark, which is a single character before the transaction de-- scription (or posting account name), separated from it by a space, in-- dicating 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 (and you can combine these, eg -UP- to match all except cleared things). Or you can use the status:, sta-- tus:!, and status:* queries, or the U, P, C keys in hledger-ui.-- (Note: in Ledger the "unmarked" state is called "uncleared"; in hledger- we renamed it to "unmarked" for semantic clarity.)-- Status marks are optional, but can be helpful eg for reconciling with- real-world accounts. Some editor modes provide highlighting and short-- cuts for working with status. Eg in Emacs ledger-mode, you can toggle- transaction status with C-c C-e, or posting status with C-c C-c.-- What "uncleared", "pending", and "cleared" actually mean is up to you.- Here's one suggestion:-- status meaning- --------------------------------------------------------------------------- uncleared recorded but not yet reconciled; needs review- pending tentatively reconciled (if needed, eg during a big reconcil-- iation)- cleared complete, reconciled as far as possible, and considered cor-- rect-- With this scheme, you would use -PC to see the current balance at your- bank, -U to see things which will probably hit your bank soon (like un-- cashed checks), and no flags to see the most up-to-date state of your- finances.-- 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- After the date, status mark and/or code fields, the rest of the line- (or until a comment is begun with ;) is the transaction's description.- Here you can describe the transaction (called the "narration" in tradi-- tional bookkeeping), or you can record a payee/payer name, or you can- leave it empty.-- Transaction descriptions show up in print output and in register re-- ports, and can be listed with the descriptions command.-- You can query by description with desc:DESCREGEX, or pivot on descrip-- tion with --pivot desc.-- Payee and note- Sometimes people want a dedicated payee/payer field that can be queried- and checked more strictly. If you want that, you can write a | (pipe)- character in the description. This divides it into a "payee" field on- the left, and a "note" field on the right. (Either can be empty.)-- You can query these with payee:PAYEEREGEX and note:NOTEREGEX, list- their values with the payees and notes commands, or pivot on payee or- note.-- Note: in transactions with no | character, description, payee, and note- all have the same value. Once a | is added, they become distinct. (If- you'd like to change this behaviour, please propose it on the mail- list.)-- If you want more strict error checking, you can declare the valid payee- names with payee directives, and then enforce these with hledger check- payees. (Note: because of the above, for this you'll need to ensure- every transaction description contains a | and therefore a checkable- payee name, even if it's empty.)-- Transaction comments- Text following ;, after a transaction description, and/or on indented- lines immediately below it, form comments for that transaction. They- are reproduced by print but otherwise ignored, except they may contain- tags, which are not ignored.-- 2012-01-01 something ; a transaction comment- ; a second line of transaction comment- expenses 1- assets-- 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.-- If the amount is positive, it is being added to the account; if nega-- tive, it is being removed from the account.-- The posting amounts in a transaction must sum up to zero, indicating- that the inflows and outflows are equal. We call this a balanced- transaction. (You can read more about the nitty-gritty details of "sum- up to zero" in Transaction balancing below.)-- As a convenience, you can optionally leave one amount blank; hledger- will infer what it should be so as to balance the transaction.-- Debits and credits- The traditional accounting concepts of debit and credit of course exist- in hledger, but we represent them with numeric sign, as described- above. Positive and negative posting amounts represent debits and- credits respectively.-- You don't need to remember that, but if you would like to - eg for- helping newcomers or for talking with your accountant - here's a handy- mnemonic:-- debit / plus / left / short words- credit / minus / right / longer words-- The two space delimiter- Be sure to notice the unusual separator between the account name and- the following amount. Because hledger allows account names with spaces- in them, you must separate the account name and amount (if any) by two- or more spaces (or tabs). It's easy to forget at first. If you ever- see the amount being treated as part of the account name, you'll know- you probably need to add another space between them.-- Account names- Accounts are the main way of categorising things in hledger. As in- Double Entry Bookkeeping, they can represent real world accounts (such- as a bank account), or more abstract categories such as "money borrowed- from Frank" or "money spent on electricity".-- You can use any account names you like, but we usually start with the- traditional accounting categories, which in english are assets, liabil-- ities, equity, revenues, expenses. (You might see these referred to as- A, L, E, R, X for short.)-- For more precise reporting, we usually divide the top level accounts- into more detailed subaccounts, by writing a full colon between account- name parts. For example, from the account names assets:bank:checking- and expenses:food, hledger will infer this hierarchy of five accounts:-- assets- assets:bank- assets:bank:checking- expenses- expenses:food-- Shown as an outline, the hierarchical tree structure is more clear:-- assets- bank- checking- expenses- food-- hledger reports can summarise the account tree to any depth, so you can- go as deep as you like with subcategories, but keeping your account- names relatively simple may be best when starting out.-- Account names may be capitalised or not; they may contain letters, num-- bers, symbols, or single spaces. Note, when an account name and an- amount are written on the same line, they must be separated by two or- more spaces (or tabs).-- Parentheses or brackets enclosing the full account name indicate vir-- tual postings, described below. Parentheses or brackets internal to- the account name have no special meaning.-- Account names can be altered temporarily or permanently by account- aliases.-- Amounts- After the account name, there is usually an amount. (Remember: 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- A decimal mark can be written as a period or a comma:-- 1.23- 1,23-- Both of these are common in international number formats, so hledger is- not biased towards one or the other. Because hledger also supports- digit group marks (eg thousands separators), this means that a number- like 1,000 or 1.000 containing just one period or comma is ambiguous.- In such cases, hledger by default assumes it is a decimal mark, and- will parse both of those as 1.-- To help hledger parse such ambiguous numbers more accurately, if you- use digit group marks, we recommend declaring the decimal mark explic-- itly. The best way is to add a decimal-mark directive at the top of- each data file, like this:-- decimal-mark .-- Or you can declare it per commodity with commodity directives, de-- scribed below.-- hledger also accepts numbers like 10. with no digits after the decimal- mark (and will sometimes display numbers that way to disambiguate them- - see Trailing decimal marks).-- Digit group marks- In the integer part of the amount quantity (left of the decimal mark),- groups of digits can optionally be separated by a digit group mark - a- comma or period (whichever is not used as decimal mark), or a space- (several Unicode space variants, like no-break space, are also ac-- cepted). So these are all valid amounts in a journal file:-- $1,000,000.00- EUR 2.000.000,00- INR 9,99,99,999.00- 1 000 000.00 ; <- ordinary space- 1 000 000.00 ; <- no-break space-- 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.-- By default, the format of amounts in the journal influences how hledger- displays them in output. This is explained in Commodity display style- below.-- Costs- After a posting amount, you can note its cost (when buying) or selling- price (when selling) in another commodity, by writing either @ UNIT-- PRICE or @@ TOTALPRICE after it. This indicates a conversion transac-- tion, where one commodity is exchanged for another.-- (You might also see this called "transaction price" in hledger docs,- discussions, or code; that term was directionally neutral and reminded- that it is a price specific to a transaction, but we now just call it- "cost", with the understanding that the transaction could be a purchase- or a sale.)-- Costs are usually written explicitly with @ or @@, but can also be in-- ferred automatically for simple multi-commodity transactions. Note, if- costs are inferred, the order of postings is significant; the first- posting will have a cost attached, in the commodity of the second.-- As an example, here are several ways to record purchases of a foreign- currency in hledger, using the cost notation either explicitly or im-- plicitly:-- 1. Write the price per unit, as @ UNITPRICE after the amount:-- 2009/1/1- assets:euros 100 @ $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 100 @@ $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. Note the- effect of posting order: the price is added to first posting, making- it 100 @@ $135, as in example 2:-- 2009/1/1- assets:euros 100 ; one hundred euros purchased- assets:dollars $-135 ; for $135-- Amounts can be converted to cost at report time using the -B/--cost- flag; this is discussed more in the Cost reporting section.-- Note that the cost normally should be a positive amount, though it's- not required to be. This can be a little confusing, see discussion at- --infer-market-prices: market prices from transactions.-- 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, described below).-- Assertions and ordering- hledger calculates and checks an account's balance assertions in date- order (and when there are multiple assertions on the same day, in parse- order). Note this is different from Ledger, which checks assertions- always in parse order, ignoring dates.-- This means in hledger you can freely reorder transactions, postings, or- files, and balance assertions will usually keep working. The exception- is when you reorder multiple postings on the same day, to the same ac-- count, which have balance assertions; those will likely need updating.-- Assertions and multiple included files- Multiple files included with the include directive are processed as if- concatenated into one file, preserving their order and the posting or-- der within each file. It means that balance assertions in later files- will see balance from earlier files.-- And if you have multiple postings to an account on the same day, split- across multiple files, and you want to assert the account's balance on- that day, you'll need to put the assertion in the right file - the last- one in the sequence, probably.-- Assertions and multiple -f files- Unlike include, when multiple files are specified on the command line- with multiple -f/--file options, balance assertions will not see bal-- ance from earlier files. This can be useful when you do not want prob-- lems in earlier files to disrupt valid assertions in later files.-- If you do want assertions to see balance from earlier files, use in-- clude, or concatenate the files temporarily.-- Assertions and costs- Balance assertions ignore costs, and should normally be written without- one:-- 2019/1/1- (a) $1 @ 1 = $1-- We do allow costs to be written in balance assertion amounts, however,- and print shows them, but 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 costs), and because- balance assignments do use costs (see below).-- Assertions and commodities- The balance assertions described so far are "single commodity balance- assertions": they assert and check the balance in one commodity, ignor-- ing any others that may be present. This is how balance assertions- work in Ledger also.-- If an account contains multiple commodities, you can assert their bal-- ances by writing multiple postings with balance assertions, one for- each commodity:-- 2013/1/1- usd $-1- eur -1- both-- 2013/1/2- both 0 = $1- both 0 = 1-- In hledger you can make a stronger "sole commodity balance assertion"- by writing two equals signs (== EXPECTEDBALANCE). This also asserts- that there are no other commodities in the account besides the asserted- one (or at least, that their current balance is zero):-- 2013/1/1- usd $-1 == $-1 ; these sole commodity assertions succeed- eur -1 == -1- both ;== $1 ; this one would fail because 'both' contains $ and-- It's less easy to make a "sole commodities balance assertion" (note the- plural) - ie, asserting that an account contains two or more specified- commodities and no others. It can be done by-- 1. isolating each commodity in a subaccount, and asserting those-- 2. and also asserting there are no commodities in the parent account- itself:-- 2013/1/1- usd $-1- eur -1- both 0 == 0 ; nothing up my sleeve- both:usd $1 == $1 ; a dollar here- both:eur 1 == 1 ; a euro there-- Assertions and subaccounts- All of the balance assertions above (both = and ==) are "subaccount-ex-- clusive balance assertions"; they ignore any balances that exist in- deeper subaccounts.-- In hledger you can make "subaccount-inclusive balance assertions" by- adding a star after the equals (=* or ==*):-- 2019/1/1- equity:start- assets:checking $10- assets:savings $10- assets $0 ==* $20 ; assets + subaccounts contains $20 and nothing else-- Assertions and virtual postings- Balance assertions always consider both real and virtual postings; they- are not affected by the --real/-R flag or real: query.-- Assertions and auto postings- Balance assertions are affected by the --auto flag, which generates- auto postings, which can alter account balances. Because auto postings- are optional in hledger, accounts affected by them effectively have two- balances. But balance assertions can only test one or the other of- these. So to avoid making fragile assertions, either:-- o assert the balance calculated with --auto, and always use --auto with- that file-- o or assert the balance calculated without --auto, and never use --auto- with that file-- o or avoid balance assertions on accounts affected by auto postings (or- avoid auto postings entirely).-- Assertions and precision- Balance assertions compare the exactly calculated amounts, which are- not always what is shown by reports. Eg a commodity directive may- limit the display precision, but this will not affect balance asser-- tions. Balance assertion failure messages show exact amounts.-- Posting comments- Text following ;, at the end of a posting line, and/or on indented- lines immediately below it, form comments for that posting. They are- reproduced by print but otherwise ignored, except they may contain- tags, which are not ignored.-- 2012-01-01- expenses 1 ; a comment for posting 1- assets- ; a comment for posting 2- ; a second comment line for posting 2-- Transaction balancing- How exactly does hledger decide when a transaction is balanced ? The- general goal is that if you look at the journal entry and calculate the- amounts' sum perfectly with pencil and paper, hledger should agree with- you.-- Real world transactions, especially for investments or cryptocurren-- cies, often involve imprecise costs, complex decimals, and/or infi-- nitely-recurring decimals, which are difficult or inconvenient to han-- dle on a computer. So to be a practical accounting system, hledger al-- lows some imprecision when checking transaction balancedness. The- question is, how much imprecision should be allowed ?-- hledger currently decides it based on the commodity display styles: if- the postings' sum would appear to be zero when displayed with the stan-- dard display precisions, the transaction is considered balanced.-- Or equivalently: if the journal entry is displayed with amounts rounded- to the standard display precisions (with hledger print --round=hard),- and a human with pencil and paper would agree that those displayed- amounts add up to zero, the transaction is considered balanced.-- This has some advantages: it is fairly intuitive, general not- hard-coded, yet configurable when needed. On the downside it means- that transaction balancedness is related to commodity display preci-- sions, so eg when using -c/--commodity-style to display things with- more than usual precision, you might need to fix some of your journal- entries (ie, add decimal digits to make them balance more precisely).-- Other PTA tools (Ledger, Beancount..) have their own ways of doing it.- Possible improvements are discussed at #1964.-- Note: if you have multiple journal files, and are relying on commodity- directives to make imprecise journal entries balance, the directives'- placement might be important - see commodity directive.-- Tags- Tags are a way to add extra labels or data fields to transactions,- postings, or accounts, which you can then search or pivot on.-- A tag is a word, optionally hyphenated, immediately followed by a full- colon, in the comment of a transaction, a posting, or an account direc-- tive. Eg: 2024-01-01 a transaction ; foo: Note this is an exception- to the usual rule that things in comments are ignored.-- You can write multiple tags on one line, separated by comma. Or you- can write each tag on its own comment line (no comma needed in this- case).-- For example, here are five different tags: one on the assets:checking- account, two on the transaction, and two on the expenses:food posting:-- account assets:checking ; accounttag:-- 2017/1/16 bought groceries ; transactiontag-1:- ; transactiontag-2:- assets:checking $-1- expenses:food $1 ; postingtag:, another-posting-tag:-- Postings also inherit tags from their transaction and their account.- And transactions also acquire tags from their postings (and postings'- accounts). So in the example above, the expenses posting effectively- has all five tags (by inheriting from the account and transaction), and- the transaction also has all five tags (by acquiring from the expenses- posting).-- Tag names- Most non-whitespace characters are allowed in tag names. Eg : is a- valid tag.-- You can list the tag names used in your journal with the tags command:- hledger tags [NAMEREGEX]-- In commands which use a query, you can match by tag name. Eg:- hledger print tag:NAMEREGEX-- You can declare valid tag names with the tag directive and then check- them with the check command.-- Special tags- Some tag names have special significance to hledger. There's not much- harm in using them yourself, but some could produce an error message,- particularly the date: and type: tags. They are explained elsewhere,- but here is a quick list for reference:-- Tags you can set to influence hledger's behaviour:-- date -- overrides a posting's date- date2 -- overrides a posting's secondary date- type -- declares an account's type-- Tags hledger adds to indicate generated data:-- t -- appears on postings generated by timedot letters- assert -- appears on txns generated by close --assert- retain -- appears on txns generated by close --retain- start -- appears on txns generated by close --migrate/--close/--open/--assign- generated-transaction -- appears on generated periodic txns (with --verbose-tags)- generated-posting -- appears on generated auto postings (with --verbose-tags)- modified -- appears on txns which have had auto postings added (with --verbose-tags)- Not displayed, but queryable:- _generated-transaction -- exists on generated periodic txns (always)- _generated-posting -- exists on generated auto postings (always)- _modified -- exists on txns which have had auto postings added (always)-- Tags hledger uses internally:-- _conversion-matched -- exists on postings which have been matched with a nearby @/@@ cost annotation-- Tag values- Tags can have a value, which is any text after the colon up until a- comma or end of line, with surrounding whitespace removed. Ending at- comma allows us to write multiple tags on one line, but also means that- tag values can not contain commas.-- Eg in the following posting, the three tags' values are "value 1",- "value 2", and "" (empty) respectively:-- expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz-- Multiple tags with the same name are additive rather than overriding:- when the same tag name is seen again with a new value, the new- name:value pair is added to the tags. It is not possible to override a- previous tag's value or remove a tag.-- You can list all the values used for a particular tag in the journal- with- hledger tags TAGNAME --values-- You can match on tag values with a query like tag:NAMEREGEX=VALUEREGEX-- Directives- Besides transactions, there is something else you can put in a journal- file: directives. These are declarations, beginning with a keyword,- that modify hledger's behaviour. Some directives can have more spe-- cific subdirectives, indented below them. hledger's directives are- similar to Ledger's in many cases, but there are also many differences.- Directives are not required, but can be useful. Here are the main di-- rectives:-- purpose directive- --------------------------------------------------------------------------- READING DATA:- Rewrite account names alias- Comment out sections of the file comment- Declare file's decimal mark, to help decimal-mark- parse amounts accurately- Include other data files include- GENERATING DATA:- Generate recurring transactions or bud- ~- get goals- Generate extra postings on existing =- transactions- CHECKING FOR ERRORS:- Define valid entities to provide more account, commodity, payee, tag- error checking- REPORTING:- Declare accounts' type and display order account- Declare commodity display styles commodity- Declare market prices P-- Directives and multiple files- Directives vary in their scope, ie which journal entries and which in-- put files they affect. Most often, a directive will affect the follow-- ing entries and included files if any, until the end of the current- file - and no further. You might find this inconvenient! For example,- alias directives do not affect parent or sibling files. But there are- usually workarounds; for example, put alias directives in your top-most- file, before including other files.-- The restriction, though it may be annoying at first, is in a good- cause; it allows reports to be stable and deterministic, independent of- the order of input. Without it, reports could show different numbers- depending on the order of -f options, or the positions of include di-- rectives in your files.-- Directive effects- Here are all hledger's directives, with their effects and scope sum-- marised - nine main directives, plus four others which we consider- non-essential:-- di- what it does ends- rec- at- tive file- end?- --------------------------------------------------------------------------------------- ac- Declares an account, for checking all entries in all files; and N- count its display order and type. Subdirectives: any text, ignored.- alias Rewrites account names, in following entries until end of cur- Y- rent file or end aliases. Command line equivalent: --alias- com- Ignores part of the journal file, until end of current file or Y- ment end comment.- com- Declares up to four things: 1. a commodity symbol, for checking N,N,Y,Y- mod- all amounts in all files 2. the display style for all amounts- ity of this commodity 3. the decimal mark for parsing amounts of- this commodity, in the rest of this file and its children, if- there is no decimal-mark directive 4. the precision to use for- balanced-transaction checking in this commodity, in this file- and its children. Takes precedence over D. Subdirectives:- format (ignored). Command line equivalent: -c/--commodity-style- deci- Declares the decimal mark, for parsing amounts of all commodi- Y- mal-mark ties in following entries until next decimal-mark or end of cur-- rent file. Included files can override. Takes precedence over- commodity and D.- include Includes entries and directives from another file, as if they N- were written inline. Command line alternative: multiple- -f/--file- payee Declares a payee name, for checking all entries in all files. N- P Declares the market price of a commodity on some date, for value N- reports.- ~ Declares a periodic transaction rule that generates future N- (tilde) transactions with --forecast and budget goals with balance- --budget.- Other- syntax:- apply Prepends a common parent account to all account names, in fol- Y- account lowing entries until end of current file or end apply account.- D Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N- there is no commodity directive for this commodity: its decimal- mark, balancing precision, and display style, as above.- Y Sets a default year to use for any yearless dates, in following Y- entries until end of current file.- = Declares an auto posting rule that generates extra postings on partly- (equals) matched transactions with --auto, in current, parent, and child- files (but not sibling files, see #1212).- Other Other directives from Ledger's file format are accepted but ig-- Ledger nored.- direc-- tives-- account directive- account directives can be used to declare accounts (ie, the places that- amounts are transferred from and to). Though not required, these dec-- larations can provide several benefits:-- o They can document your intended chart of accounts, providing a refer-- ence.-- o They can store additional account information as comments, or as tags- which can be used to filter or pivot reports.-- o They can restrict which accounts may be posted to by transactions, eg- in strict mode, which helps prevent errors.-- o They influence account display order in reports, allowing non-alpha-- betic sorting (eg Revenues to appear above Expenses).-- o They can help hledger know your accounts' types (asset, liability,- equity, revenue, expense), enabling reports like balancesheet and in-- comestatement.-- o They help with account name completion (in hledger add, hledger-web,- hledger-iadd, ledger-mode, etc.)-- They are written as the word account followed by a hledger-style ac-- count name. Eg:-- account assets:bank:checking-- Ledger-style indented subdirectives are also accepted, but ignored:-- account assets:bank:checking- format subdirective ; currently ignored-- Account comments- Text following two or more spaces and ; at the end of an account direc-- tive line, and/or following ; on indented lines immediately below it,- form comments for that account. They are ignored except they may con-- tain tags, which are not ignored.-- The two-space requirement for same-line account comments is because ;- is allowed in account names.-- account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon- ; next-line comment- ; some tags - type:A, acctnum:12345-- Account error checking- By default, accounts need not be declared; they come into existence- when a posting references them. This is convenient, but it means- hledger can't warn you when you mis-spell an account name in the jour-- nal. Usually you'll find that error later, as an extra account in bal-- ance reports, or an incorrect balance when reconciling.-- In strict mode, enabled with the -s/--strict flag, hledger will report- an error if any transaction uses an account name that has not been de-- clared by an account directive. Some notes:-- o The declaration is case-sensitive; transactions must use the correct- account name capitalisation.-- o The account directive's scope is "whole file and below" (see direc-- tives). This means it affects all of the current file, and any files- it includes, but not parent or sibling files. The position of ac-- count directives within the file does not matter, though it's usual- to put them at the top.-- o Accounts can only be declared in journal files, but will affect in-- cluded files of all types.-- o It's currently not possible to declare "all possible subaccounts"- with a wildcard; every account posted to must be declared.-- Account display order- Account directives also cause hledger to display accounts in a particu-- lar order, not just alphabetically. Eg, here is a conventional order-- ing for the top-level accounts:-- account assets- account liabilities- account equity- account revenues- account expenses-- Now hledger displays them in that order:-- $ hledger accounts- assets- liabilities- equity- revenues- expenses-- If there are undeclared accounts, those will be displayed last, in al-- phabetical order.-- Sorting is done within each group of sibling accounts, at each level of- the account tree. Eg, a declaration like account parent:child influ-- ences child's position among its siblings.-- Note, it does not affect parent's position; for that, you need an ac-- count parent declaration.-- Sibling accounts are always displayed together; hledger won't display- x:y in between a:b and a:c.-- An account directive both declares an account as a valid posting tar-- get, and declares its display order; you can't easily do one without- the other.-- Account types- hledger knows that accounts come in several types: assets, liabilities,- expenses and so on. This enables easy reports like balancesheet and- incomestatement, and filtering by account type with the type: query.-- As a convenience, hledger will detect these account types automatically- if you are using common english-language top-level account names (de-- scribed below). But it's more robust to declare accounts' types ex-- plicitly, by adding type: tags to their account directives. The tag's- value should be one of the five main account types:-- o A or Asset (things you own)-- o L or Liability (things you owe)-- o E or Equity (investment/ownership; balanced counterpart of assets &- liabilities)-- o R or Revenue (what you received money from, AKA income; technically- part of Equity)-- o X or Expense (what you spend money on; technically part of Equity)-- or, it can be (these are used less often):-- o C or Cash (a subtype of Asset, indicating liquid assets for the cash-- flow report)-- o V or Conversion (a subtype of Equity, for conversions (see Cost re-- porting).)-- Subaccounts inherit their parent's type, or they can override it. Here- is a typical set of account type declarations:-- account assets ; type: A- account liabilities ; type: L- account equity ; type: E- account revenues ; type: R- account expenses ; type: X-- account assets:bank ; type: C- account assets:cash ; type: C-- account equity:conversion ; type: V-- Here are some tips for working with account types.-- o The rules for inferring types from account names are as follows.- These are just a convenience that sometimes help new users get going;- if they don't work for you, just ignore them and declare your account- types. See also Regular expressions.-- If account's name contains this (CI) regular expression: | its type is:- --------------------------------------------------------------------|-------------- ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash- ^assets?(:|$) | Asset- ^(debts?|liabilit(y|ies))(:|$) | Liability- ^equity:(trad(e|ing)|conversion)s?(:|$) | Conversion- ^equity(:|$) | Equity- ^(income|revenue)s?(:|$) | Revenue- ^expenses?(:|$) | Expense-- o If you declare any account types, it's a good idea to declare an ac-- count for all of the account types, because a mixture of declared and- name-inferred types can disrupt certain reports.-- o Certain uses of account aliases can disrupt account types. See- Rewriting accounts > Aliases and account types.-- o As mentioned above, subaccounts will inherit a type from their parent- account. More precisely, an account's type is decided by the first- of these that exists:-- 1. A type: declaration for this account.-- 2. A type: declaration in the parent accounts above it, preferring- the nearest.-- 3. An account type inferred from this account's name.-- 4. An account type inferred from a parent account's name, preferring- the nearest parent.-- 5. Otherwise, it will have no type.-- o For troubleshooting, you can list accounts and their types with:-- $ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]-- alias directive- 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-- o combining two accounts into one, eg to see their sum or difference on- one line-- 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.-- Account aliases are very powerful. They are generally easy to use cor-- rectly, but you can also generate invalid account names with them; more- on this below.-- 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 re-- place any occurrence of the old account name with the new one. Subac-- counts are also affected. Eg:-- alias checking = assets:bank:wells fargo:checking- ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"-- Regex aliases- There is also a more powerful variant that uses a regular expression,- indicated by wrapping the pattern in forward slashes. (This is the- only place where hledger requires forward slashes around a regular ex-- pression.)-- Eg:-- alias /REGEX/ = REPLACEMENT-- or:-- $ hledger --alias '/REGEX/=REPLACEMENT' ...-- Any part of an account name matched by REGEX will be replaced by RE-- PLACEMENT. REGEX is case-insensitive as usual.-- If you need to match a forward slash, escape it with a backslash, eg- /\/=:.-- If REGEX contains parenthesised match groups, these can be referenced- by the usual backslash and number in REPLACEMENT:-- alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3- ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"-- REPLACEMENT continues to the end of line (or on command line, to end of- option argument), so it can contain trailing whitespace.-- Combining aliases- You can define as many aliases as you like, using journal directives- and/or command line options.-- Recursive aliases - where an account name is rewritten by one alias,- then by another alias, and so on - are allowed. Each alias sees the- effect of previously applied aliases.-- In such cases it can be important to understand which aliases will be- applied and in which order. For (each account name in) each journal- entry, we apply:-- 1. alias directives preceding the journal entry, most recently parsed- first (ie, reading upward from the journal entry, bottom to top)-- 2. --alias options, in the order they appeared on the command line- (left to right).-- In other words, for (an account name in) a given journal entry:-- o the nearest alias declaration before/above the entry is applied first-- o the next alias before/above that will be be applied next, and so on-- o aliases defined after/below the entry do not affect it.-- This gives nearby aliases precedence over distant ones, and helps pro-- vide semantic stability - aliases will keep working the same way inde-- pendent of which files are being read and in which order.-- In case of trouble, adding --debug=6 to the command line will show- which aliases are being applied when.-- Aliases and multiple files- As explained at Directives and multiple files, alias directives do not- affect parent or sibling files. Eg in this command,-- hledger -f a.aliases -f b.journal-- account aliases defined in a.aliases will not affect b.journal. In-- cluding the aliases doesn't work either:-- include a.aliases-- 2023-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-- 2023-01-01 ; affected by aliases above- foo 1- bar-- include c.journal ; also affected-- end aliases directive- You can clear (forget) all currently defined aliases (seen in the jour-- nal so far, or defined on the command line) with this directive:-- end aliases-- Aliases can generate bad account names- Be aware that account aliases can produce malformed account names,- which could cause confusing reports or invalid print output. For exam-- ple, you could erase all account names:-- 2021-01-01- a:aa 1- b-- $ hledger print --alias '/.*/='- 2021-01-01- 1-- The above print output is not a valid journal. Or you could insert an- illegal double space, causing print output that would give a different- journal when reparsed:-- 2021-01-01- old 1- other-- $ hledger print --alias old="new USD" | hledger -f- print- 2021-01-01- new USD 1- other-- Aliases and account types- If an account with a type declaration (see Declaring accounts > Account- types) is renamed by an alias, normally the account type remains in ef-- fect.-- However, renaming in a way that reshapes the account tree (eg renaming- parent accounts but not their children, or vice versa) could prevent- child accounts from inheriting the account type of their parents.-- Secondly, if an account's type is being inferred from its name, renam-- ing it by an alias could prevent or alter that.-- If you are using account aliases and the type: query is not matching- accounts as you expect, try troubleshooting with the accounts command,- eg something like:-- $ hledger accounts --alias assets=bassetts type:a-- commodity directive- The commodity directive performs several functions:-- 1. It declares which commodity symbols may be used in the journal, en-- abling useful error checking with strict mode or the check command.- See Commodity error checking below.-- 2. It declares how all amounts in this commodity should be displayed,- eg how many decimals to show. See Commodity display style above.-- 3. (If no decimal-mark directive is in effect:) It sets the decimal- mark to expect (period or comma) when parsing amounts in this com-- modity, in this file and files it includes, from the directive until- end of current file. See Decimal marks above.-- 4. It declares the precision with which this commodity's amounts should- be compared when checking for balanced transactions, anywhere in- this file and files it includes, until end of current file.-- Declaring commodities solves several common parsing/display problems,- so we recommend it.-- Note that effects 3 and 4 above end at the end of the directive's file,- and will not affect sibling or parent files. So if you are relying on- them (especially 4) and using multiple files, placing your commodity- directives in a top-level parent file might be important. Or, keep- your decimal marks unambiguous and your entries well balanced and pre-- cise.-- (Related: #793)-- Commodity directive syntax- A commodity directive is normally the word commodity followed by a sam-- ple amount (and optionally a comment). Only the amount's symbol and- format is significant. Eg:-- commodity $1000.00- commodity 1.000,00 EUR- commodity 1 000 000.0000 ; the no-symbol commodity-- Commodities do not have tags (tags in the comment will be ignored).-- A commodity directive's sample amount must always include a period or- comma decimal mark (this rule helps disambiguate decimal marks and- digit group marks). If you don't want to show any decimal digits,- write the decimal mark at the end:-- commodity 1000. AAAA ; show AAAA with no decimals-- Commodity symbols containing spaces, numbers, or punctuation must be- enclosed in double quotes, as usual:-- commodity 1.0000 "AAAA 2023"-- Commodity directives normally include a sample amount, but can declare- only a symbol (ie, just function 1 above):-- commodity $- commodity INR- commodity "AAAA 2023"- commodity "" ; the no-symbol commodity-- Commodity directives may also be written with an indented format subdi-- rective, as in Ledger. The symbol is repeated and must be the same in- both places. Other subdirectives are currently ignored:-- ; 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- an unsupported subdirective ; ignored by hledger-- Commodity error checking- In strict mode (-s/--strict) (or when you run hledger check commodi-- ties), hledger will report an error if an undeclared commodity symbol- is used. (With one exception: zero amounts are always allowed to have- no commodity symbol.) It works like account error checking (described- above).-- decimal-mark directive- You can use a decimal-mark directive - usually one per file, at the top- of the file - to declare which character represents a decimal mark when- parsing amounts in this file. It can look like-- decimal-mark .-- or-- decimal-mark ,-- This prevents any ambiguity when parsing numbers in the file, so we- recommend it, especially if the file contains digit group marks (eg- thousands separators).-- include directive- You can pull in the content of additional files by writing an include- directive, like this:-- include FILEPATH-- Only journal files can include, and only journal, timeclock or timedot- files can be included (not CSV files, currently).-- If the file path does not begin with a slash, it is relative to the- current file's folder.-- A tilde means home directory, eg: include ~/main.journal.-- The path may contain glob patterns to match multiple files, eg: include- *.journal.-- There is limited support for recursive wildcards: **/ (the slash is re-- quired) matches 0 or more subdirectories. It's not super convenient- since you have to avoid include cycles and including directories, but- this can be done, eg: include */**/*.journal.-- The path may also be prefixed to force a specific file format, overrid-- ing the file extension (as described in Data formats): include time-- dot:~/notes/2023*.md.-- P directive- The P directive declares a market price, which is a conversion rate be-- tween two commodities on a certain date. This allows value reports to- convert amounts of one commodity to their value in another, on or after- that date. These prices are often obtained from a stock exchange,- cryptocurrency exchange, the or foreign exchange market.-- 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. Ex-- amples:-- # one euro was worth $1.35 from 2009-01-01 onward:- P 2009-01-01 $1.35-- # and $1.40 from 2010-01-01 onward:- P 2010-01-01 $1.40-- The -V, -X and --value flags use these market prices to show amount- values in another commodity. See Value reporting.-- payee directive- payee PAYEE NAME-- This 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 ; a comment-- Payees do not have tags (tags in the comment will be ignored).-- To declare the empty payee name, use "".-- payee ""-- Ledger-style indented subdirectives, if any, are currently ignored.-- tag directive- tag TAGNAME-- This directive can be used to declare a limited set of tag names al-- lowed in tags. TAGNAME should be a valid tag name (no spaces). Eg:-- tag item-id-- Any indented subdirectives are currently ignored.-- The "tags" check will report an error if any undeclared tag name is- used. It is quite easy to accidentally create a tag through normal use- of colons in comments; if you want to prevent this, you can declare and- check your tags .-- Periodic transactions- The ~ directive declares a "periodic rule" which generates temporary- extra transactions, usually recurring at some interval, when hledger is- run with the --forecast flag. These "forecast transactions" are useful- for forecasting future activity. They exist only for the duration of- the report, and only when --forecast is used; they are not saved in the- journal file by hledger.-- Periodic rules also have a second use: with the --budget flag they set- budget goals for budgeting.-- Periodic rules can be a little tricky, so before you use them, read- this whole section, or at least the following tips:-- 1. Two spaces accidentally added or omitted will cause you trouble -- read about this below.-- 2. For troubleshooting, show the generated transactions with hledger- print --forecast tag:generated or hledger register --forecast- tag:generated.-- 3. Forecasted transactions will begin only after the last non-fore-- casted transaction's date.-- 4. Forecasted transactions will end 6 months from today, by default.- See below for the exact start/end rules.-- 5. period expressions can be tricky. Their documentation needs im-- provement, but is worth studying.-- 6. Some period expressions with a repeating interval must begin on a- natural boundary of that interval. Eg in weekly from DATE, DATE- must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an- error.-- 7. Other period expressions with an interval are automatically expanded- to cover a whole number of that interval. (This is done to improve- reports, but it also affects periodic transactions. Yes, it's a bit- inconsistent with the above.) Eg: ~ every 10th day of month from- 2023/01, which is equivalent to ~ every 10th day of month from- 2023/01/01, will be adjusted to start on 2019/12/10.-- 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.):-- # every first of month- ~ monthly- expenses:rent $2000- assets:bank:checking-- # every 15th of month in 2023's first quarter:- ~ monthly from 2023-04-15 to 2023-06-16- expenses:utilities $400- assets:bank:checking-- The period expression is the same syntax used for specifying multi-pe-- riod reports, just interpreted differently; there, it specifies report- periods; here it specifies recurrence dates (the periods' start dates).-- Periodic rules and relative dates- Partial or relative dates (like 12/31, 25, tomorrow, last week, next- quarter) are usually not recommended in periodic rules, since the re-- sults will change as time passes. If used, they will be interpreted- relative to, in order of preference:-- 1. the first day of the default year specified by a recent Y directive-- 2. or the date specified with --today-- 3. or the date on which you are running the report.-- They will not be affected at all by report period or forecast period- dates.-- 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 2023"- ; ||- ; vv- ~ every 2 months in 2023, we will review- assets:bank:checking $1500- income:acme inc-- So,-- o Do write two spaces between your period expression and your transac-- tion description, if any.-- o Don't accidentally write two spaces in the middle of your period ex-- pression.-- Auto postings- The = directive declares an "auto posting rule", which adds extra post-- ings to existing transactions. (Remember, postings are the account- name & amount lines below a transaction's date & description.)-- In the journal, an auto posting rule looks quite like a transaction,- but instead of date and description it has = (mnemonic: "match") and a- query, like this:-- = QUERY- ACCOUNT AMOUNT- ...-- Queries are just like command line queries; an account name substring- is most common. Query terms containing spaces should be enclosed in- single or double quotes.-- Each = rule works like this: when hledger is run with the --auto flag,- wherever the QUERY matches a posting in the journal, the rule's post-- ings are added to that transaction, immediately below the matched post-- ing. Note these generated postings are temporary, existing only for- the duration of the report, and only when --auto is used; they are not- saved in the journal file by hledger.-- Generated postings' amounts can depend on the matched posting's amount.- So auto postings can be useful for, eg, adding tax postings with a- standard percentage. AMOUNT can be:-- o a number with no commodity symbol, like 2. The matched posting's- commodity symbol will be added to this.-- o a normal amount with a commodity symbol, like $2. This will be used- as-is.-- o an asterisk followed by a number, like *2. This will multiply the- matched posting's amount (and total price, if any) by the number.-- o an asterisk followed by an amount with commodity symbol, like *$2.- This multiplies and also replaces the commodity symbol with this new- one.-- 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-- Note that depending fully on generated data such as this has some draw-- backs - it's less portable, less future-proof, less auditable by oth-- ers, and less robust (eg your balance assertions will depend on whether- you use or don't use --auto). An alternative is to use auto postings- in "one time" fashion - use them to help build a complex journal entry,- view it with hledger print --auto, and then copy that output into the- journal file to make it permanent.-- 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.-- This also means that you cannot have more than one auto-posting with a- missing amount applied to a given transaction, as it will be unable to- infer amounts.-- 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".-- Auto postings on forecast transactions only- Tip: you can can make auto postings that will apply to forecast trans-- actions but not recorded transactions, by adding tag:_generated-trans-- action to their QUERY. This can be useful when generating new journal- entries to be saved in the journal.-- Other syntax- hledger journal format supports quite a few other features, mainly to- make interoperating with or converting from Ledger easier. Note some- of the features below are powerful and can be useful in special cases,- but in general, features in this section are considered less important- or even not recommended for most users. Downsides are mentioned to- help you decide if you want to use them.-- Balance assignments- Ledger-style balance assignments are also supported. These are like- balance assertions, but with no posting amount on the left side of the- equals sign; instead it is calculated automatically so as to satisfy- the assertion. This can be a convenience during data entry, eg when- 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).-- Downsides: using balance assignments makes your journal less explicit;- to know the exact amount posted, you have to run hledger or do the cal-- culations yourself, instead of just reading it. Also balance assign-- ments' forcing of balances can hide errors. These things make your fi-- nancial data less portable, less future-proof, and less trustworthy in- an audit.-- Balance assignments and costs- A cost in a balance assignment will cause the calculated amount to have- that cost attached:-- 2019/1/1- (a) = $1 @ 2-- $ hledger print --explicit- 2019-01-01- (a) $1 @ 2 = $1 @ 2-- Balance assignments and multiple files- Balance assignments handle multiple files like balance assertions.- They see balance from other files previously included from the current- file, but not from previous sibling or parent files.-- Bracketed posting dates- For setting posting dates and secondary posting dates, Ledger's brack-- eted date syntax is also supported: [DATE], [DATE=DATE2] or [=DATE2] in- posting comments. hledger will attempt to parse any square-bracketed- sequence of the 0123456789/-.= characters in this way. With this syn-- tax, DATE infers its year from the transaction and DATE2 infers its- year from DATE.-- Downsides: another syntax to learn, redundant with hledger's- date:/date2: tags, and confusingly similar to Ledger's lot date syntax.-- D directive- D AMOUNT-- This 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- current file.-- For compatibility/historical reasons, D also acts like a commodity di-- rective (setting the commodity's decimal mark for parsing and display- style for output). So its argument is not just a commodity symbol, but- a full amount demonstrating the style. The amount must include a deci-- mal mark (either period or comma). 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-- Interactions with other directives:-- For setting a commodity's display style, a commodity directive has- highest priority, then a D directive.-- For detecting a commodity's decimal mark during parsing, decimal-mark- has highest priority, then commodity, then D.-- For checking commodity symbols with the check command, a commodity di-- rective is required (hledger check commodities ignores D directives).-- Downsides: omitting commodity symbols makes your financial data less- explicit, less portable, and less trustworthy in an audit. It is usu-- ally an unsustainable shortcut; sooner or later you will want to track- multiple commodities. D is overloaded with functions redundant with- commodity and decimal-mark. And it works differently from Ledger's D.-- apply account directive- This directive sets a default parent account, which will be prepended- to all accounts in following entries, until an end apply account direc-- tive or end of current file. Eg:-- apply account home-- 2010/1/1- food $10- cash-- end apply account-- is equivalent to:-- 2010/01/01- home:food $10- home:cash $-10-- account directives are also affected, and so is any included content.-- Account names entered via hledger add or hledger-web are not affected.-- Account aliases, if any, are applied after the parent account is- prepended.-- Downsides: this can make your financial data less explicit, less- portable, and less trustworthy in an audit.-- Y directive- Y YEAR-- or (deprecated backward-compatible forms):-- year YEAR apply year YEAR-- The space is optional. This sets a default year to be used for subse-- quent dates which don't specify a year. Eg:-- Y2009 ; set default year to 2009-- 12/15 ; equivalent to 2009/12/15- expenses 1- assets-- year 2010 ; change default year to 2010-- 2009/1/30 ; specifies the year, not affected- expenses 1- assets-- 1/31 ; equivalent to 2010/1/31- expenses 1- assets-- Downsides: omitting the year (from primary transaction dates, at least)- makes your financial data less explicit, less portable, and less trust-- worthy in an audit. Such dates can get separated from their corre-- sponding Y directive, eg when evaluating a region of the journal in- your editor. A missing Y directive makes reports dependent on today's- date.-- Secondary dates- 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".-- Downsides: makes your financial data more complicated, less portable,- and less trustworthy in an audit. Keeping the meaning of the two dates- consistent requires discipline, and you have to remember which report-- ing mode is appropriate for a given report. Posting dates are simpler- and better.-- Star comments- Lines beginning with * (star/asterisk) are also comment lines. This- feature allows Emacs users to insert org headings in their journal, al-- lowing them to fold/unfold/navigate it like an outline when viewed with- org mode.-- Downsides: another, unconventional comment syntax to learn. Decreases- your journal's portability. And switching to Emacs org mode just for- folding/unfolding meant losing the benefits of ledger mode; nowadays- you can add outshine mode to ledger mode to get folding without losing- ledger mode's features.-- Valuation expressions- Ledger allows a valuation function or value to be written in double- parentheses after an amount. hledger ignores these.-- Virtual postings- A posting with parentheses around the account name, like (some:account)- 10, is called an unbalanced virtual posting. These postings do not- participate in transaction balancing. (And if you write them without- an amount, a zero amount is always inferred.) These can occasionally- be convenient for special circumstances, but they violate double entry- bookkeeping and make your data less portable across applications, so- many people avoid using them at all.-- A posting with brackets around the account name ([some:account]) is- called a balanced virtual posting. The balanced virtual postings in a- transaction must add up to zero, just like ordinary postings, but sepa-- rately from them. These are not part of double entry bookkeeping ei-- ther, but they are at least balanced. An example:-- 2022-01-01 buy food with cash, update budget envelope subaccounts, & something else- assets:cash $-10 ; <- these balance each other- expenses:food $7 ; <-- expenses:food $3 ; <-- [assets:checking:budget:food] $-10 ; <- and these balance each other- [assets:checking:available] $10 ; <-- (something:else) $5 ; <- this is not required to balance-- Ordinary postings, whose account names are neither parenthesised nor- bracketed, are called real postings. You can exclude virtual postings- from reports with the -R/--real flag or a real:1 query.-- Other Ledger directives- These other Ledger directives are currently accepted but ignored. This- allows hledger to read more Ledger files, but be aware that hledger's- reports may differ from Ledger's if you use these.-- apply fixed COMM AMT- apply tag TAG- assert EXPR- bucket / A ACCT- capture ACCT REGEX- check EXPR- define VAR=EXPR- end apply fixed- end apply tag- end apply year- end tag- eval / expr EXPR- python- PYTHONCODE- tag NAME- value EXPR- --command-line-flags-- See also https://hledger.org/ledger.html for a detailed hledger/Ledger- syntax comparison.-- Other cost/lot notations- A slight digression for Ledger and Beancount users. Ledger has a num-- ber of cost/lot-related notations:-- o @ UNITCOST and @@ TOTALCOST-- o expresses a conversion rate, as in hledger-- o when buying, also creates a lot than can be selected at selling- time-- o (@) UNITCOST and (@@) TOTALCOST (virtual cost)-- o like the above, but also means "this cost was exceptional, don't- use it when inferring market prices".-- Currently, hledger treats the above like @ and @@; the parentheses are- ignored.-- o {=FIXEDUNITCOST} and {{=FIXEDTOTALCOST}} (fixed price)-- o when buying, means "this cost is also the fixed price, don't let it- fluctuate in value reports"-- o {UNITCOST} and {{TOTALCOST}} (lot price)-- o can be used identically to @ UNITCOST and @@ TOTALCOST, also cre-- ates a lot-- o when selling, combined with @ ..., specifies an investment lot by- its cost basis; does not check if that lot is present-- o and related: [YYYY/MM/DD] (lot date)-- o when buying, attaches this acquisition date to the lot-- o when selling, selects a lot by its acquisition date-- o (SOME TEXT) (lot note)-- o when buying, attaches this note to the lot-- o when selling, selects a lot by its note-- Currently, hledger accepts any or all of the above in any order after- the posting amount, but ignores them. (This can break transaction bal-- ancing.)-- For Beancount users, the notation and behaviour is different:-- o @ UNITCOST and @@ TOTALCOST-- o expresses a cost without creating a lot, as in hledger-- o when buying (augmenting) or selling (reducing) a lot, combined with- {...}: documents the cost/selling price (not used for transaction- balancing)-- o {UNITCOST} and {{TOTALCOST}}-- o when buying (augmenting), expresses the cost for transaction bal-- ancing, and also creates a lot with this cost basis attached-- o when selling (reducing),-- o selects a lot by its cost basis-- o raises an error if that lot is not present or can not be selected- unambiguously (depending on booking method configured)-- o expresses the selling price for transaction balancing-- Currently, hledger accepts the {UNITCOST}/{{TOTALCOST}} notation but- ignores it.-- o variations: {}, {YYYY-MM-DD}, {"LABEL"}, {UNITCOST, "LABEL"}, {UNIT-- COST, YYYY-MM-DD, "LABEL"} etc.-- Currently, hledger rejects these.--CSV- hledger can read CSV files (Character Separated Value - usually comma,- semicolon, or tab) containing dated records, automatically converting- each record into a transaction.-- (To learn about writing CSV, see CSV output.)-- For best error messages when reading CSV/TSV/SSV files, make sure they- have a corresponding .csv, .tsv or .ssv file extension or use a hledger- file prefix (see File Extension below).-- Each CSV file must be described by a corresponding rules file.- This contains rules describing the CSV data (header line, fields lay-- out, date format etc.), how to construct hledger transactions from it,- and how to categorise transactions based on description or other at-- tributes.-- By default, hledger expects this rules file to be named like the CSV- file, with an extra .rules extension added, in the same directory. Eg- when asked to read foo/FILE.csv, hledger looks for foo/FILE.csv.rules.- You can specify a different rules file with the --rules-file option.-- 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-- There's an introductory Importing CSV data tutorial on hledger.org, and- more CSV rules examples below, and a larger collection at- https://github.com/simonmichael/hledger/tree/master/examples/csv.-- CSV rules cheatsheet- The following kinds of rule can appear in the rules file, in any order.- (Blank lines and lines beginning with # or ; or * are ignored.)-- source optionally declare which file to read data- from- separator declare the field separator, instead of rely-- ing on file extension- skip skip one or more header lines at start of file- date-format declare how to parse CSV dates/date-times- timezone declare the time zone of ambiguous CSV- date-times- newest-first improve txn order when: there are multiple- records, newest first, all with the same date- intra-day-reversed improve txn order when: same-day txns are in- opposite order to the overall file- decimal-mark declare the decimal mark used in CSV amounts,- when ambiguous- fields list name CSV fields for easy reference, and op-- tionally assign their values to hledger fields- Field assignment assign a CSV value or interpolated text value- to a hledger field- if block conditionally assign values to hledger fields,- or skip a record or end (skip rest of file)- if table conditionally assign values to hledger fields,- using compact syntax- balance-type select which type of balance assertions/as-- signments to generate- include inline another CSV rules file-- Working with CSV tips can be found below, including How CSV rules are- evaluated.-- source- If you tell hledger to read a csv file with -f foo.csv, it will look- for rules in foo.csv.rules. Or, you can tell it to read the rules- file, with -f foo.csv.rules, and it will look for data in foo.csv- (since 1.30).-- These are mostly equivalent, but the second method provides some extra- features. For one, the data file can be missing, without causing an- error; it is just considered empty. And, you can specify a different- data file by adding a "source" rule:-- source ./Checking1.csv-- If you specify just a file name with no path, hledger will look for it- in your system's downloads directory (~/Downloads, currently):-- source Checking1.csv-- And if you specify a glob pattern, hledger will read the most recent of- the matched files (useful with repeated downloads):-- source Checking1*.csv-- See also "Working with CSV > Reading files specified by rule".-- 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.-- skip- skip N-- The word skip followed by a number (or no number, meaning 1) tells- hledger to ignore this many non-empty lines at the start of the input- data. You'll need this whenever your CSV data contains header lines.- Note, empty and blank lines are skipped automatically, so you don't- need to count those.-- skip has a second meaning: it can be used inside if blocks (described- below), to skip one or more records whenever the condition is true.- Records skipped in this way are ignored, except they are still required- to be valid CSV.-- 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-style- date parsing pattern - see https://hackage.haskell.org/pack-- age/time/docs/Data-Time-Format.html#v:formatTime. The pattern 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-- timezone- timezone TIMEZONE-- When CSV contains date-times that are implicitly in some time zone- other than yours, but containing no explicit time zone information, you- can use this rule to declare the CSV's native time zone, which helps- prevent off-by-one dates.-- When the CSV date-times do contain time zone information, you don't- need this rule; instead, use %Z in date-format (or %z, %EZ, %Ez; see- the formatTime link above).-- In either of these cases, hledger will do a time-zone-aware conversion,- localising the CSV date-times to your current system time zone. If you- prefer to localise to some other time zone, eg for reproducibility, you- can (on unix at least) set the output timezone with the TZ environment- variable, eg:-- $ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv-- timezone currently does not understand timezone names, except "UTC",- "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", or "PDT". For- others, use numeric format: +HHMM or -HHMM.-- newest-first- hledger tries to ensure that the generated transactions will be ordered- chronologically, including same-day transactions. Usually it can- auto-detect how the CSV records are ordered. But if it encounters CSV- where all records are on the same date, it assumes that the records are- oldest first. If in fact the CSV's records are normally newest first,- like:-- 2022-10-01, txn 3...- 2022-10-01, txn 2...- 2022-10-01, txn 1...-- you can add the newest-first rule to help hledger generate the transac-- tions in correct order.-- # same-day CSV records are newest first- newest-first-- intra-day-reversed- If CSV records within a single day are ordered opposite to the overall- record order, you can add the intra-day-reversed rule to improve the- order of journal entries. Eg, here the overall record order is newest- first, but same-day records are oldest first:-- 2022-10-02, txn 3...- 2022-10-02, txn 4...- 2022-10-01, txn 1...- 2022-10-01, txn 2...-- # transactions within each day are reversed with respect to the overall date order- intra-day-reversed-- 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.-- fields list- fields FIELDNAME1, FIELDNAME2, ...-- A fields list (the word fields followed by comma-separated field names)- is optional, but convenient. It does two things:-- 1. It names the CSV field in each column. This can be convenient if- you are referencing them in other rules, so you can say %SomeField- instead of remembering %13.-- 2. Whenever you use one of the special hledger field names (described- below), it assigns the CSV value in this position to that hledger- field. This is the quickest way to populate hledger's fields and- build a transaction.-- Here's an example that says "use the 1st, 2nd and 4th fields as the- transaction's date, description and amount; name the last two fields- for later reference; and ignore the others":-- fields date, description, , amount, , , somefield, anotherfield-- In a fields list, the separator is always comma; it is unrelated to the- CSV file's separator. Also:-- o 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 Field names may contain _ (underscore) or - (hyphen).-- o Fields you don't care about can be given a dummy name or an empty- name.-- If the CSV contains column headings, it's convenient to use these for- your field names, suitably modified (eg lower-cased with spaces re-- placed by underscores).-- Sometimes you may want to alter a CSV field name to avoid assigning to- a hledger field with the same name. Eg you could call the CSV's "bal-- ance" field balance_ to avoid directly setting hledger's balance field- (and generating a balance assertion).-- Field assignment- HLEDGERFIELD 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 either by their 1-based position in the- CSV record (%N) or by the name they were given in the fields list- (%CSVFIELD), and regular expression match groups (\N).-- 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 " be-- comes 1 when interpolated) (#1051).-- o Interpolations always refer to a CSV field - you can't interpolate a- hledger field. (See Referencing other fields below).-- Field names- Note the two kinds of field names mentioned here, and used only in- hledger CSV rules files:-- 1. CSV field names (CSVFIELD in these docs): you can optionally name- the CSV columns for easy reference (since hledger doesn't yet auto-- matically recognise column headings in a CSV file), by writing arbi-- trary names in a fields list, eg:-- fields When, What, Some_Id, Net, Total, Foo, Bar-- 2. Special hledger field names (HLEDGERFIELD in these docs): you must- set at least some of these to generate the hledger transaction from- a CSV record, by writing them as the left hand side of a field as-- signment, eg:-- date %When- code %Some_Id- description %What- comment %Foo %Bar- amount1 $ %Total-- or directly in a fields list:-- fields date, description, code, , amount1, Foo, Bar- currency $- comment %Foo %Bar-- Here are all the special hledger field names available, and what hap-- pens when you assign values to them:-- 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.-- You can assign multi-line comments by writing literal \n in the code.- A comment starting with \n will begin on a new line.-- Comments can contain 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, in conditional rules.-- If a posting's account name is left unset but its amount is set (see- below), a default account name will be chosen (like "expenses:unknown"- or "income:unknown").-- amount field- There are several ways to set posting amounts from CSV, useful in dif-- ferent situations.-- 1. amount is the oldest and simplest. Assigning to this sets the- amount of the first and second postings. In the second posting, the- amount will be negated; also, if it has a cost attached, it will be- converted to cost.-- 2. amount-in and amount-out work exactly like the above, but should be- used when the CSV has two amount fields (such as "Debit" and- "Credit", or "Inflow" and "Outflow"). Whichever field has a- non-zero value will be used as the amount of the first and second- postings. Here are some tips to avoid confusion:-- o It's not "amount-in for posting 1 and amount-out for posting 2",- it is "extract a single amount from the amount-in or amount-out- field, and use that for posting 1 and (negated) for posting 2".-- o Don't use both amount and amount-in/amount-out in the same rules- file; choose based on whether the amount is in a single CSV field- or spread across two fields.-- o In each record, at most one of the two CSV fields should contain- a non-zero amount; the other field must contain a zero or noth-- ing.-- o hledger assumes both CSV fields contain unsigned numbers, and it- automatically negates the amount-out values.-- o If the data doesn't fit these requirements, you'll probably need- an if rule (see below).-- 3. amountN (where N is a number from 1 to 99) sets the amount of only a- single posting: the Nth posting in the transaction. You'll usually- need at least two such assignments to make a balanced transaction.- You can also generate more than two postings, to represent more com-- plex transactions. The posting numbers don't have to be consecu-- tive; with if rules, higher posting numbers can be useful to ensure- a certain order of postings.-- 4. amountN-in and amountN-out work exactly like the above, but should- be used when the CSV has two amount fields. This is analogous to- amount-in and amount-out, and those tips also apply here.-- 5. Remember that a fields list can also do assignments. So in a fields- list if you name a CSV field "amount", that counts as assigning to- amount. (If you don't want that, call it something else in the- fields list, like "amount_".)-- 6. The above don't handle every situation; if you need more flexibil-- ity, use an if rule to set amounts conditionally. See "Working with- CSV > Setting amounts" below for more on this and on amount-setting- generally.-- currency field- currency sets a currency symbol, to be prepended to all postings'- 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 the Working with CSV tips below for more about setting amounts and- currency.-- if block- Rules can be applied conditionally, depending on patterns in the CSV- data. This allows flexibility; in particular, it is how you can cate-- gorise transactions, selecting an appropriate account name based on- their description (for example). There are two ways to write condi-- tional rules: "if blocks", described here, and "if tables", described- below.-- An if block is the word if and one or more "matcher" expressions (can- be a word or phrase), one per line, starting either on the same or next- line; followed by one or more indented rules. Eg,-- if MATCHER- RULE-- or-- if- MATCHER- MATCHER- MATCHER- RULE- RULE-- If any of the matchers succeeds, all of the indented rules will be ap-- plied. They are usually field assignments, but the following special- rules may also be used within an if block:-- o skip - skips the matched CSV record (generating no transaction from- it)-- o end - skips the rest of the current CSV file.-- Some examples:-- # if the record contains "groceries", set account2 to "expenses:groceries"- if groceries- account2 expenses:groceries-- # if the record contains any of these phrases, set account2 and a transaction comment as shown- if- monthly service fee- atm transaction fee- banking thru software- account2 expenses:business:banking- comment XXX deductible ? check it-- # if an empty record is seen (assuming five fields), ignore the rest of the CSV file- if ,,,,- end-- Matchers- There are two kinds:-- 1. A record matcher is a word or single-line text fragment or regular- expression (REGEX), which hledger will try to match case-insensi-- tively anywhere within the CSV record.- Eg: whole foods-- 2. A field matcher is preceded with a percent sign and CSV field name- (%CSVFIELD REGEX). hledger will try to match these just within the- named CSV field.- Eg: %date 2023-- The regular expression is (as usual in hledger) a POSIX extended regu-- lar expression, that also supports GNU word boundaries (\b, \B, \<,- \>), and nothing else. If you have trouble, see "Regular expressions"- in the hledger manual (https://hledger.org/hledger.html#regular-expres-- sions).-- What matchers match- With record matchers, it's important to know that the record matched is- not the original CSV record, but a modified one: separators will be- converted to commas, and enclosing double quotes (but not enclosing- whitespace) are removed. So for example, when reading an SSV file, if- the original record was:-- 2023-01-01; "Acme, Inc."; 1,000-- the regex would see, and try to match, this modified record text:-- 2023-01-01,Acme, Inc., 1,000-- Combining matchers- When an if block has multiple matchers, they are combined as follows:-- o By default they are OR'd (any of them can match)-- o When a matcher is preceded by ampersand (&, at the start of the line)- it will be AND'ed with the previous matcher (all in the AND'ed group- must match)-- o Added in 1.32 When a matcher is preceded by an exclamation mark (!),- it is negated (it must not match).-- Note currently there is a limitation: you can't use both & and ! on the- same line (you can't AND a negated matcher).-- Match groups- Added in 1.32-- Matchers can define match groups: parenthesised portions of the regular- expression which are available for reference in field assignments.- Groups are enclosed in regular parentheses (( and )) and can be nested.- Each group is available in field assignments using the token \N, where- N is an index into the match groups for this conditional block (e.g.- \1, \2, etc.).-- Example: Warp credit card payment postings to the beginning of the- billing period (Month start), to match how they are presented in state-- ments, using posting dates:-- if %date (....-..)-..- comment2 date:\1-01-- Another example: Read the expense account from the CSV field, but throw- away a prefix:-- if %account1 liabilities:family:(expenses:.*)- account1 \1-- if table- "if tables" are an alternative to if blocks; they can express many- matchers and field assignments in a more compact tabular format, like- this:-- if,HLEDGERFIELD1,HLEDGERFIELD2,...- MATCHERA,VALUE1,VALUE2,...- MATCHERB,VALUE1,VALUE2,...- ; Comment line that explains MATCHERC- MATCHERC,VALUE1,VALUE2,...- <empty line>-- The first character after if is taken to be this if table's field sepa-- rator. It is unrelated to the separator used in the CSV file. It- should be a non-alphanumeric character like , or | that does not appear- anywhere else in the table (it should not be used in field names or- matchers or values, and it cannot be escaped with a backslash).-- Each line must contain the same number of separators; empty values are- allowed. Whitespace can be used in the matcher lines for readability- (but not in the if line, currently). You can use the comment lines in- the table body. The table must be terminated by an empty line (or end- of file).-- An if table like the above is interpreted as follows: try all of the- matchers; whenever a matcher succeeds, assign all of the values on that- line to the corresponding hledger fields; If multiple lines match,- later lines will override fields assigned by the earlier ones - just- like the sequence of if blocks would behave.-- If table presented above is equivalent to this sequence of if blocks:-- if MATCHERA- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...-- if MATCHERB- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...-- ; Comment line which explains MATCHERC- if MATCHERC- HLEDGERFIELD1 VALUE1- HLEDGERFIELD2 VALUE2- ...-- Example:-- if,account2,comment- atm transaction fee,expenses:business:banking,deductible? check it- %description groceries,expenses:groceries,- ;; Comment line that desribes why this particular date is special- 2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out-- 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-- 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-- Working with CSV- Some 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 eradman.com/entrproject:-- $ 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- Note that hledger will only accept valid CSV conforming to RFC 4180,- and equivalent SSV and TSV formats (like RFC 4180 but with semicolon or- tab as separators). This means, eg:-- o Values may be enclosed in double quotes, or not. Enclosing in single- quotes is not allowed. (Eg 'A','B' is rejected.)-- o When values are enclosed in double quotes, spaces outside the quotes- are not allowed. (Eg "A", "B" is rejected.)-- o When values are not enclosed in quotes, they may not contain double- quotes. (Eg A"A, B is rejected.)-- If your CSV/SSV/TSV is not valid in this sense, you'll need to trans-- form it before reading with hledger. Try using sed, or a more permis-- sive CSV parser like python's csv lib.-- File Extension- To help hledger choose the CSV file reader and show the right error- messages (and choose the right field separator character by default),- it's best if CSV/SSV/TSV files are named with a .csv, .ssv or .tsv- filename extension. (More about this at Data formats.)-- When reading files with the "wrong" extension, you can ensure the CSV- reader (and the default field separator) by prefixing the file path- with csv:, ssv: or tsv:: Eg:-- $ hledger -f ssv:foo.dat print-- You can also override the default field separator with a separator rule- if needed.-- Reading CSV from standard input- You'll need the file format prefix when reading CSV from stdin also,- since hledger assumes journal format by default. Eg:-- $ cat foo.dat | hledger -f ssv:- print-- Reading multiple CSV files- If you use multiple -f options to read multiple CSV files at once,- hledger will look for a correspondingly-named rules file for each CSV- file. But if you use the --rules-file option, that rules file will be- used for all the CSV files.-- Reading files specified by rule- Instead of specifying a CSV file in the command line, you can specify a- rules file, as in hledger -f foo.csv.rules CMD. By default this will- read data from foo.csv in the same directory, but you can add a source- rule to specify a different data file, perhaps located in your web- browser's download directory.-- This feature was added in hledger 1.30, so you won't see it in most CSV- rules examples. But it helps remove some of the busywork of managing- CSV downloads. Most of your financial institutions's default CSV file-- names are different and can be recognised by a glob pattern. So you- can put a rule like source Checking1*.csv in foo-checking.csv.rules,- and then periodically follow a workflow like:-- 1. Download CSV from Foo's website, using your browser's defaults-- 2. Run hledger import foo-checking.csv.rules to import any new transac-- tions-- After import, you can: discard the CSV, or leave it where it is for a- while, or move it into your archives, as you prefer. If you do noth-- ing, next time your browser will save something like Checking1-2.csv,- and hledger will use that because of the * wild card and because it is- the most recent.-- Valid transactions- After reading a CSV file, hledger post-processes and validates the gen-- erated journal entries as it would for a journal file - balancing them,- applying balance assignments, and canonicalising amount styles. Any- errors at this stage will be reported in the usual way, displaying the- problem entry.-- There is one exception: balance assertions, if you have generated them,- will not be checked, since normally these will work only when the CSV- data is part of the main journal. If you do need to check balance as-- sertions generated from CSV right away, pipe into another hledger:-- $ hledger -f file.csv print | hledger -f- print-- Deduplicating, importing- When you download a CSV file periodically, eg to get your latest bank- transactions, the new file may overlap with the old one, containing- some of the same records.-- The import command will (a) detect the new transactions, and (b) append- just those transactions to your main journal. It is idempotent, so you- don't have to remember how many times you ran it or with which version- of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This- is the easiest way to import CSV data. Eg:-- # download the latest CSV files, then run this command.- # Note, no -f flags needed here.- $ hledger import *.csv [--dry]-- This method works for most CSV files. (Where records have a stable- chronological order, and new records appear only at the new end.)-- A number of other tools and workflows, hledger-specific and otherwise,- exist for converting, deduplicating, classifying and managing CSV data.- See:-- o https://hledger.org/cookbook.html#setups-and-workflows-- o https://plaintextaccounting.org -> data import/conversion-- Setting amounts- Continuing from amount field above, here are more tips for amount-set-- ting:-- 1. If the amount is in a single CSV field:- a. If its sign indicates direction of flow:- Assign it to amountN, to set the Nth posting's amount. N is usu-- ally 1 or 2 but can go up to 99.-- b. If another field indicates direction of flow:- Use one or more conditional rules to set the appropriate amount- sign. Eg:-- # assume a withdrawal unless Type contains "deposit":- amount1 -%Amount- if %Type deposit- amount1 %Amount-- 2. If the amount is in two CSV fields (such as Debit and Credit, or In- and Out):- a. If both fields are unsigned:- Assign one field to amountN-in and the other to amountN-out.- hledger will automatically negate the "out" field, and will use- whichever field value is non-zero as posting N's amount.-- b. If either field is signed:- You will probably need to override hledger's sign for one or the- other field, as in the following example:-- # Negate the -out value, but only if it is not empty:- fields date, description, amount1-in, amount1-out- if %amount1-out [1-9]- amount1-out -%amount1-out-- c. If both fields can contain a non-zero value (or both can be- empty):- The -in/-out rules normally choose the value which is- non-zero/non-empty. Some value pairs can be ambiguous, such as 1- and none. For such cases, use conditional rules to help select the- amount. Eg, to handle the above you could select the value con-- taining non-zero digits:-- fields date, description, in, out- if %in [1-9]- amount1 %in- if %out [1-9]- amount1 %out-- 3. If you want posting 2's amount converted to cost:- Use the unnumbered amount (or amount-in and amount-out) syntax.-- 4. If the CSV has only balance amounts, not transaction amounts:- Assign to balanceN, to set a balance assignment on the Nth posting,- causing the posting's amount to be calculated automatically. balance- with no number is equivalent to balance1. In this situation hledger is- more likely to guess the wrong default account name, so you may need to- set that explicitly.-- Amount signs- There is some special handling making it easier to parse and to reverse- amount signs. (This only works for whole amounts, not for cost amounts- such as COST in amount1 AMT @ COST):-- 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- "".-- It's not possible (without preprocessing the CSV) to set an amount to- its absolute value, ie discard its sign.-- Setting currency/commodity- If the currency/commodity symbol is included in the CSV's amount- field(s):-- 2023-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-- 2023-01-01 foo- expenses:unknown $123.00- income:unknown $-123.00-- If the currency is provided as a separate CSV field:-- 2023-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-- 2023-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-- 2023-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 re-- peated, the last one wins:-- o skip (at top level)-- o date-format-- o newest-first-- o fields - names the CSV fields, optionally sets up initial assignments- to hledger fields-- Then for each CSV record in turn:-- o test all if blocks. If any of them contain a end rule, skip all re-- maining CSV records. Otherwise if any of them contain a skip rule,- skip that many CSV records. If there are multiple matched skip- rules, the first one wins.-- o collect all field assignments at top level and in matched if blocks.- When there are multiple assignments for a field, keep only the last- one.-- o compute a value for each hledger field - either the one that was as-- signed to it (and interpolate the %CSVFIELD references), or a default-- o generate a hledger transaction (journal entry) from these values.-- This is all part of the CSV reader, one of several readers hledger can- use to parse input files. When all files have been read successfully,- the transactions are passed as input to whichever hledger command the- user specified.-- Well factored rules- Some things than can help reduce duplication and complexity in rules- files:-- o Extracting common rules usable with multiple CSV files into a com-- mon.rules, and adding include common.rules to each CSV's rules file.-- o Splitting if blocks into smaller if blocks, extracting the frequently- used parts.-- CSV rules examples- 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.-- Coinbase- A simple example with some CSV from Coinbase. The spot price is- recorded using cost notation. The legacy amount field name conve-- niently sets amount 2 (posting 2's amount) to the total cost.-- # Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes- # 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,"","","","Received 100.00 USDC from an external account"-- # coinbase.csv.rules- skip 1- fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes- date %Timestamp- date-format %Y-%m-%dT%T%Z- description %Notes- account1 assets:coinbase:cc- amount %Quantity_Transacted %Asset @ %Spot_Price_at_Transaction %Spot_Price_Currency-- $ hledger print -f coinbase.csv- 2021-12-30 Received 100.00 USDC from an external account- assets:coinbase:cc 100 USDC @ 0.740000 GBP- income:unknown -74.000000 GBP-- 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:--Timeclock- 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 op-- tional. The timezone, if present, must be four digits and is ignored- (currently the time is always interpreted as a local time). Lines be-- ginning with # or ; or *, and blank lines, are ignored.-- i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:- 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 2 spaces ; optional comment, tags:- (some account) 0.33h-- 2015-03-31 * 22:21-23:59- (another:account) 1.64h-- 2015-04-01 * 00:00-02:00- (another:account) 2.01h-- 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 time-- clock-x.el and perhaps the extras in ledgerutils.el-- o at the command line, use these bash aliases: cli 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- timedot format is hledger's human-friendly time logging format. Com-- pared to timeclock format, it is more convenient for quick, approxi-- mate, and retroactive time logging, and more human-readable (you can- see at a glance where time was spent). A quick example:-- 2023-05-01- hom:errands .... .... ; two hours; the space is ignored- fos:hledger:timedot .. ; half an hour- per:admin:finance ; no time spent yet-- hledger reads this as a transaction on this day with three (unbalanced)- postings, where each dot represents "0.25". No commodity symbol is as-- sumed, but we typically interpret it as hours.-- $ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required- 2023-05-01 *- (hom:errands) 2.00 ; two hours- (fos:hledger:timedot) 0.50 ; half an hour- (per:admin:finance) 0-- A timedot file contains a series of transactions (usually one per day).- Each begins with a simple date (Y-M-D, Y/M/D, or Y.M.D), optionally be- followed on the same line by a transaction description, and/or a trans-- action comment following a semicolon.-- After the date line are zero or more time postings, consisting of:-- o An account name - any hledger-style account name, optionally in-- dented.-- o Two or more spaces - required if there is an amount (as in journal- format).-- o A timedot amount, which can be-- o empty (representing zero)-- o a number, optionally followed by a unit s, m, h, d, w, mo, or y,- representing a precise number of seconds, minutes, hours, days- weeks, months or years (hours is assumed by default), which will be- converted to hours according to 60s = 1m, 60m = 1h, 24h = 1d, 7d =- 1w, 30d = 1mo, 365d = 1y.-- o one or more dots (period characters), each representing 0.25.- These are the dots in "timedot". Spaces are ignored and can be- used for grouping/alignment.-- o Added in 1.32 one or more letters. These are like dots but they- also generate a tag t: (short for "type") with the letter as its- value, and a separate posting for each of the values. This pro-- vides a second dimension of categorisation, viewable in reports- with --pivot t.-- o An optional comment following a semicolon (a hledger-style posting- comment).-- There is some flexibility to help with keeping time log data and notes- in the same file:-- o Blank lines and lines beginning with # or ; are ignored.-- o After the first date line, lines which do not contain a double space- are parsed as postings with zero amount. (hledger's register reports- will show these if you add -E).-- o Before the first date line, lines beginning with * (eg org headings)- are ignored. And from the first date line onward, Emacs org mode- heading prefixes at the start of lines (one or more *'s followed by a- space) will be ignored. This means the time log can also be a org- outline.-- Timedot examples- Numbers:-- 2016/2/3- inc:client1 4- fos:hledger 3h- biz:research 60m-- Dots:-- # 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 .-- $ 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-- Letters:-- # Activity types:- # c cleanup/catchup/repair- # e enhancement- # s support- # l learning/research-- 2023-11-01- work:adm ccecces-- $ hledger -f a.timedot print- 2023-11-01- (work:adm) 1 ; t:c- (work:adm) 0.5 ; t:e- (work:adm) 0.25 ; t:s-- $ hledger -f a.timedot bal- 1.75 work:adm- --------------------- 1.75-- $ hledger -f a.timedot bal --pivot t- 1.00 c- 0.50 e- 0.25 s- --------------------- 1.75-- Org:-- * 2023 Work Diary- ** Q1- *** 2023-02-29- **** DONE- 0700 yoga- **** UNPLANNED- **** BEGUN- hom:chores- cleaning ...- water plants- outdoor - one full watering can- indoor - light watering- **** TODO- adm:planning: trip- *** LATER-- Using . as account name separator:-- 2016/2/4- fos.hledger.timedot 4h- fos.ledger ..-- $ hledger -f a.timedot --alias '/\./=:' bal -t- 4.50 fos- 4.00 hledger:timedot- 0.50 ledger- --------------------- 4.50--PART 3: REPORTING CONCEPTS-Amount formatting- Commodity display style- For the amounts in each commodity, hledger chooses a consistent display- style (symbol placement, decimal mark and digit group marks, number of- decimal digits) to use in most reports. This is inferred as follows:-- First, if there's a D directive declaring a default commodity, that- commodity symbol and amount format is applied to all no-symbol amounts- in the journal.-- Then each commodity's display style is determined from its commodity- directive. We recommend always declaring commodities with commodity- directives, since they help ensure consistent display styles and preci-- sions, and bring other benefits such as error checking for commodity- symbols. Here's an example:-- # Set display styles (and decimal marks, for parsing, if there is no decimal-mark directive)- # for the $, EUR, INR and no-symbol commodities:- commodity $1,000.00- commodity EUR 1.000,00- commodity INR 9,99,99,999.00- commodity 1 000 000.9455-- But for convenience, if a commodity directive is not present, hledger- infers a commodity's display styles from its amounts as they are writ-- ten in the journal (excluding cost amounts and amounts in periodic- transaction rules or auto posting rules). It uses-- o the symbol placement and decimal mark of the first amount seen-- o the digit group marks of the first amount with digit group marks-- o and the maximum number of decimal digits seen across all amounts.-- And as fallback if no applicable amounts are found, it would use a de-- fault style, like $1000.00 (symbol on the left with no space, period as- decimal mark, and two decimal digits).-- Finally, commodity styles can be overridden by the -c/--commodity-style- command line option.-- Rounding- Amounts are stored internally as decimal numbers with up to 255 decimal- places. They are displayed with their original journal precisions by- print and print-like reports, and rounded to their display precision- (the number of decimal digits specified by the commodity display style)- by other reports. When rounding, hledger uses banker's rounding (it- rounds to the nearest even digit). So eg 0.5 displayed with zero deci-- mal digits appears as "0".-- Trailing decimal marks- If you're wondering why your print report sometimes shows trailing dec-- imal marks, with no decimal digits; it does this when showing amounts- that have digit group marks but no decimal digits, to disambiguate them- and allow them to be re-parsed reliably (see Decimal marks). Eg:-- commodity $1,000.00-- 2023-01-02- (a) $1000-- $ hledger print- 2023-01-02- (a) $1,000.-- If this is a problem (eg when exporting to Ledger), you can avoid it by- disabling digit group marks, eg with -c/--commodity (for each affected- commodity):-- $ hledger print -c '$1000.00'- 2023-01-02- (a) $1000-- or by forcing print to always show decimal digits, with --round:-- $ hledger print -c '$1,000.00' --round=soft- 2023-01-02- (a) $1,000.00-- Amount parseability- More generally, hledger output falls into three rough categories, which- format amounts a little bit differently to suit different consumers:-- 1. "hledger-readable output" - should be readable by hledger (and by- humans)-- o This is produced by reports that show full journal entries: print,- import, close, rewrite etc.-- o It shows amounts with their original journal precisions, which may- not be consistent.-- o It adds a trailing decimal mark when needed to avoid showing ambigu-- ous amounts.-- o It can be parsed reliably (by hledger and ledger2beancount at least,- but perhaps not by Ledger..)-- 2. "human-readable output" - usually for humans-- o This is produced by all other reports.-- o It shows amounts with standard display precisions, which will be con-- sistent within each commodity.-- o It shows ambiguous amounts unmodified.-- o It can be parsed reliably in the context of a known report (when you- know decimals are consistently not being shown, you can assume a sin-- gle mark is a digit group mark).-- 3. "machine-readable output" - usually for other software-- o This is produced by all reports when an output format like csv, tsv,- json, or sql is selected.-- o It shows amounts as 1 or 2 do, but without digit group marks.-- o It can be parsed reliably (if needed, the decimal mark can be changed- with -c/--commodity-style).--Time periods- Report start & end date- By default, most hledger reports will show the full span of time repre-- sented by the journal. The report start date will be the earliest- transaction or posting date, and the report end date will be the latest- transaction, posting, or market price date.-- Often you will want to see a shorter time span, such as the current- month. You can specify a start and/or end date using -b/--begin,- -e/--end, -p/--period or a date: query (described below). All of these- accept the smart date syntax (below).-- Some notes:-- o End dates are exclusive, as in Ledger, so you should write the date- after the last day you want to see in the report.-- 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 In some cases a report interval will adjust start/end dates to fall- on interval boundaries (see below).-- Examples:-- -b 2016/3/17 begin on St. Patrick's day 2016- -e 12/1 end at the start of december 1st of the current year- (11/30 will be the last date included)- -b thismonth all transactions on or after the 1st of the current month- -p thismonth all transactions in the current month- date:2016/3/17.. the above written as queries instead (.. can also be re-- placed with -)- date:..12/1- date:thismonth..- date:thismonth-- Smart dates- hledger's user interfaces accept a "smart date" syntax for added conve-- nience. Smart dates optionally can be relative to today's date, be- written with english words, and have less-significant parts omitted- (missing parts are inferred as 1). Some 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- in n n periods from the current period- days/weeks/months/quar-- ters/years- n n periods from the current period- days/weeks/months/quar-- ters/years ahead- n -n periods from the current period- days/weeks/months/quar-- ters/years ago- 20181201 8 digit YYYYMMDD with valid year month and day- 201812 6 digit YYYYMM with valid year and month-- Some 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-- "Today's date" can be overridden with the --today option, in case it's- needed for testing or for recreating old reports. (Except for periodic- transaction rules, which are not affected by --today.)-- Report intervals- A report interval can be specified so that reports like register, bal-- ance or activity become multi-period, showing each subperiod as a sepa-- rate row or column.-- The following standard intervals can be enabled with command-line- flags:-- o -D/--daily-- o -W/--weekly-- o -M/--monthly-- o -Q/--quarterly-- o -Y/--yearly-- More complex intervals can be specified using -p/--period, described- below.-- Date adjustment- When there is a report interval (other than daily), report start/end- dates which have been inferred, eg from the journal, are automatically- adjusted to natural period boundaries. This is convenient for produc-- ing simple periodic reports. More precisely:-- o an inferred start date will be adjusted earlier if needed to fall on- a natural period boundary-- o an inferred end date will be adjusted later if needed to make the- last period the same length as the others.-- By contrast, start/end dates which have been specified explicitly, with- -b, -e, -p or date:, will not be adjusted (since hledger 1.29). This- makes it possible to specify non-standard report periods, but it also- means that if you are specifying a start date, you should pick one- that's on a period boundary if you want to see simple report period- headings.-- Period expressions- The -p/--period option specifies a period expression, which is a com-- pact way of expressing a start date, end date, and/or report interval.-- Here's a period expression with a start and end date (specifying the- first quarter of 2009):-- -p "from 2009/1/1 to 2009/4/1"-- Several keywords like "from" and "to" are supported for readability;- these are optional. "to" can also be written as ".." or "-". The- spaces are also optional, as long as you don't run two dates together.- So the following are equivalent to the above:-- -p "2009/1/1 2009/4/1"- -p2009/1/1to2009/4/1- -p2009/1/1..2009/4/1-- Dates are smart dates, so if the current year is 2009, these are also- equivalent to the above:-- -p "1/1 4/1"- -p "jan-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 date in the journal:-- -p "from 2009/1/1" everything after january- 1, 2009- -p "since 2009/1" the same, since is a syn-- onym- -p "from 2009" the same- -p "to 2009" everything before january- 1, 2009-- You can also specify a period by writing a single partial or full date:-- -p "2009" the year 2009; equivalent to "2009/1/1 to 2010/1/1"- -p "2009/1" the month of january 2009; equivalent to "2009/1/1 to- 2009/2/1"- -p "2009/1/1" the first day of 2009; equivalent to "2009/1/1 to- 2009/1/2"-- or by using the "Q" quarter-year syntax (case insensitive):-- -p "2009Q1" first quarter of 2009, equivalent to "2009/1/1 to- 2009/4/1"- -p "q4" fourth quarter of the current year-- Period expressions with a report interval- A period expression can also begin with a report interval, separated- from the start/end dates (if any) by a space or the word in:-- -p "weekly from 2009/1/1 to 2009/4/1"- -p "monthly in 2008"- -p "quarterly"-- More complex report intervals- Some more complex intervals can be specified within period expressions,- such as:-- o biweekly (every two weeks)-- o fortnightly-- o bimonthly (every two months)-- o every day|week|month|quarter|year-- o every N days|weeks|months|quarters|years-- Weekly on a custom day:-- o every Nth day of week (th, nd, rd, or st are all accepted after the- number)-- o every WEEKDAYNAME (full or three-letter english weekday name, case- insensitive)-- Monthly on a custom day:-- o every Nth day [of month]-- o every Nth WEEKDAYNAME [of month]-- Yearly on a custom day:-- o every MM/DD [of year] (month number and day of month number)-- o every MONTHNAME DDth [of year] (full or three-letter english month- name, case insensitive, and day of month number)-- o every DDth MONTHNAME [of year] (equivalent to the above)-- Examples:-- -p "bimonthly from 2008"- -p "every 2 weeks"- -p "every 5 months from- 2009/03"- -p "every 2nd day of week" periods will go from Tue to Tue- -p "every Tue" same- -p "every 15th day" period boundaries will be on 15th of each- 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- November- -p "every 5th November" same- -p "every Nov 5th" same-- Show historical balances at end of the 15th day of each month (N is an- end date, exclusive as always):-- $ hledger balance -H -p "every 16th day"-- Group postings from the start of wednesday to end of the following- tuesday (N is both (inclusive) start date and (exclusive) end date):-- $ hledger register checking -p "every 3rd day of week"-- Multiple weekday intervals- This special form is also supported:-- o every WEEKDAYNAME,WEEKDAYNAME,... (full or three-letter english week-- day names, case insensitive)-- Also, weekday and weekendday are shorthand for mon,tue,wed,thu,fri and- sat,sun.-- This is mainly intended for use with --forecast, to generate periodic- transactions on arbitrary days of the week. It may be less useful with- -p, since it divides each week into subperiods of unequal length, which- is unusual. (Related: #1632)-- Examples:-- -p "every dates will be Mon, Wed, Fri; periods will be- mon,wed,fri" Mon-Tue, Wed-Thu, Fri-Sun- -p "every weekday" dates will be Mon, Tue, Wed, Thu, Fri; periods will- be Mon, Tue, Wed, Thu, Fri-Sun- -p "every weekend- dates will be Sat, Sun; periods will be Sat, Sun-Fri- day"--Depth- With the --depth NUM option (short form: -NUM), reports will show ac-- counts only to the specified depth, hiding deeper subaccounts. Use- this when you want a summary with less detail. This flag has the same- effect as a depth: query argument: depth:2, --depth=2 or -2 are equiva-- lent.--Queries- One of hledger's strengths is being able to quickly report on a precise- subset of your data. Most hledger commands accept query arguments, to- restrict their scope. Multiple query terms can be provided to build up- a more complex query.-- o By default, a query term is interpreted as a case-insensitive sub-- string pattern for matching account names:-- car:fuel- dining groceries- o Patterns containing spaces or other special characters must be en-- closed in single or double quotes:-- 'personal care'- o These patterns are actually regular expressions, so you can add reg-- exp metacharacters for more precision (see "Regular expressions"- above for details):-- '^expenses\b'- 'food$'- 'fuel|repair'- 'accounts (payable|receivable)'- o To match something other than account name, add one of the query type- prefixes described in "Query types" below:-- date:202312-- status:- desc:amazon- cur:USD- cur:\\$- amt:'>0'- o Add a not: prefix to negate a term:-- not:status:'*'- not:desc:'opening|closing'- not:cur:USD- o Terms with different types are AND-ed, terms with the same type are- OR-ed (mostly; see "Combining query terms" below). The following- query:-- date:2022 desc:amazon desc:amzn-- is interpreted as:-- date is in 2022 AND ( transaction description contains "amazon" OR- "amzn" )-- 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 or REGEX- Match account names containing this case insensitive regular expres-- sion. This is the default query type, so we usually don't bother writ-- ing the "acct:" prefix.-- 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 es-- caping. 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 in-- terval. 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.-- expr:"TERM AND NOT (TERM OR TERM)" (eg)- Match with a boolean combination of queries (which must be enclosed in- quotes). See Combining query terms below.-- 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.-- type:TYPECODES- Match by account type (see Declaring accounts > Account types). TYPE-- CODES is one or more of the single-letter account type codes ALERXCV,- case insensitive. Note type:A and type:E will also match their respec-- tive subtypes C (Cash) and V (Conversion). Certain kinds of account- alias can disrupt account types, see Rewriting accounts > Aliases and- account types.-- tag:REGEX[=REGEX]- Match by tag name, and optionally also by tag value. (To match only by- value, use tag:.=REGEX.)-- When querying by tag, note that:-- o Accounts also inherit the tags of their parent accounts-- o Postings also inherit the tags of their account and their transaction-- o Transactions also acquire the tags of their postings.-- (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- When given multiple space-separated 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.-- The print command is a little different, showing 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.-- We also support more complex boolean queries with the expr: prefix.- This allows one to combine query terms using and, or, not keywords- (case insensitive), and to group them by enclosing in parentheses.-- Some examples:-- o Exclude account names containing 'food':-- expr:"not food" (not:food is equivalent)-- o Match things which have 'cool' in the description and the 'A' tag:-- expr:"desc:cool and tag:A" (expr:"desc:cool tag:A" is equivalent)-- o Match things which either do not reference the 'expenses:food' ac-- count, or do have the 'A' tag:-- expr:"not expenses:food or tag:A"-- o Match things which either do not reference the 'expenses:food' ac-- count, or which reference the 'expenses:drink' account and also have- the 'A' tag:-- expr:"expenses:food or (expenses:drink and tag:A)"-- expr: has a restriction: date: queries may not be used inside or ex-- pressions. That would allow disjoint report periods or disjoint result- sets, with unclear semantics for our reports.-- Queries and command options- Some queries can also be expressed as command-line options: depth:2 is- equivalent to --depth 2, date:2023 is equivalent to -p 2023, etc. When- you mix command options and query arguments, generally the resulting- 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 re-- ports, cur: and amt: match the old commodity symbol and the old amount- quantity, not the new ones. (Except in hledger 1.22, #1625.)--Pivoting- Normally, hledger groups and sums amounts within each account. The- --pivot FIELD option substitutes some other transaction field for ac-- count names, causing amounts to be grouped and summed by that field's- value instead. FIELD can be any of the transaction fields acct, sta-- tus, code, desc, payee, note, or a tag name. When pivoting on a tag- and a posting has multiple values of that tag, only the first value is- displayed. Values containing colon:separated:parts will be displayed- hierarchically, like account names. Multiple, colon-delimited fields- can be pivoted simultaneously, generating a hierarchical account name.-- Some examples:-- 2016/02/16 Yearly Dues Payment- assets:bank account 2 EUR- income:dues -2 EUR ; member: John Doe, kind: Lifetime-- Normal balance report showing account names:-- $ hledger balance- 2 EUR assets:bank account- -2 EUR income:dues- --------------------- 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):-- $ 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-- Hierarchical reports can be generated with multiple pivots:-- $ hledger balance Income:Dues --pivot kind:member- -2 EUR Lifetime:John Doe- --------------------- -2 EUR--Generating data- hledger has several features for generating data, such as:-- o Periodic transaction rules can generate single or repeating transac-- tions following a template. These are usually dated in the future,- eg to help with forecasting. They are activated by the --forecast- option.-- o The balance command's --budget option uses these same periodic rules- to generate goals for the budget report.-- o Auto posting rules can generate extra postings on certain matched- transactions. They are always applied to forecast transactions; with- the --auto flag they are applied to transactions recorded in the- journal as well.-- o The --infer-equity flag infers missing conversion equity postings- from @/@@ costs. And the inverse --infer-costs flag infers missing- @/@@ costs from conversion equity postings.-- Generated data of this kind is temporary, existing only at report time.- But you can see it in the output of hledger print, and you can save- that to your journal, in effect converting it from temporary generated- data to permanent recorded data. This could be useful as a data entry- aid.-- If you are wondering what data is being generated and why, add the- --verbose-tags flag. In hledger print output you will see extra tags- like generated-transaction, generated-posting, and modified on gener-- ated/modified data. Also, even without --verbose-tags, generated data- always has equivalen hidden tags (with an underscore prefix), so eg you- could match generated transactions with tag:_generated-transaction.--Forecasting- Forecasting, or speculative future reporting, can be useful for esti-- mating future balances, or for exploring different future scenarios.-- The simplest and most flexible way to do it with hledger is to manually- record a bunch of future-dated transactions. You could keep these in a- separate future.journal and include that with -f only when you want to- see them.-- --forecast- There is another way: with the --forecast option, hledger can generate- temporary "forecast transactions" for reporting purposes, according to- periodic transaction rules defined in the journal. Each rule can gen-- erate multiple recurring transactions, so by changing one rule you can- change many forecasted transactions.-- Forecast transactions usually start after ordinary transactions end.- By default, they begin after your latest-dated ordinary transaction, or- today, whichever is later, and they end six months from today. (The- exact rules are a little more complicated, and are given below.)-- This is the "forecast period", which need not be the same as the report- period. You can override it - eg to forecast farther into the future,- or to force forecast transactions to overlap your ordinary transactions- - by giving the --forecast option a period expression argument, like- --forecast=..2099 or --forecast=2023-02-15... Note that the = is re-- quired.-- Inspecting forecast transactions- print is the best command for inspecting and troubleshooting forecast- transactions. Eg:-- ~ monthly from 2022-12-20 rent- assets:bank:checking- expenses:rent $1000-- $ hledger print --forecast --today=2023/4/21- 2023-05-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- 2023-06-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- 2023-07-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- 2023-08-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- 2023-09-20 rent- ; generated-transaction: ~ monthly from 2022-12-20- assets:bank:checking- expenses:rent $1000-- Here there are no ordinary transactions, so the forecasted transactions- begin on the first occurence after today's date. (You won't normally- use --today; it's just to make these examples reproducible.)-- Forecast reports- Forecast transactions affect all reports, as you would expect. Eg:-- $ hledger areg rent --forecast --today=2023/4/21- Transactions in expenses:rent and subaccounts:- 2023-05-20 rent as:ba:checking $1000 $1000- 2023-06-20 rent as:ba:checking $1000 $2000- 2023-07-20 rent as:ba:checking $1000 $3000- 2023-08-20 rent as:ba:checking $1000 $4000- 2023-09-20 rent as:ba:checking $1000 $5000-- $ hledger bal -M expenses --forecast --today=2023/4/21- Balance changes in 2023-05-01..2023-09-30:-- || May Jun Jul Aug Sep- ===============++===================================- expenses:rent || $1000 $1000 $1000 $1000 $1000- ---------------++------------------------------------ || $1000 $1000 $1000 $1000 $1000-- Forecast tags- Forecast transactions generated by --forecast have a hidden tag, _gen-- erated-transaction. So if you ever need to match forecast transac-- tions, you could use tag:_generated-transaction (or just tag:generated)- in a query.-- For troubleshooting, you can add the --verbose-tags flag. Then, visi-- ble generated-transaction tags will be added also, so you can view them- with the print command. Their value indicates which periodic rule was- responsible.-- Forecast period, in detail- Forecast start/end dates are chosen so as to do something useful by de-- fault in almost all situations, while also being flexible. Here are- (with luck) the exact rules, to help with troubleshooting:-- The forecast period starts on:-- o the later of-- o the start date in the periodic transaction rule-- o the start date in --forecast's argument-- o otherwise (if those are not available): the later of-- o the report start date specified with -b/-p/date:-- o the day after the latest ordinary transaction in the journal-- o otherwise (if none of these are available): today.-- The forecast period ends on:-- o the earlier of-- o the end date in the periodic transaction rule-- o the end date in --forecast's argument-- o otherwise: the report end date specified with -e/-p/date:-- o otherwise: 180 days (~6 months) from today.-- Forecast troubleshooting- When --forecast is not doing what you expect, one of these tips should- help:-- o Remember to use the --forecast option.-- o Remember to have at least one periodic transaction rule in your jour-- nal.-- o Test with print --forecast.-- o Check for typos or too-restrictive start/end dates in your periodic- transaction rule.-- o Leave at least 2 spaces between the rule's period expression and de-- scription fields.-- o Check for future-dated ordinary transactions suppressing forecasted- transactions.-- o Try setting explicit report start and/or end dates with -b, -e, -p or- date:-- o Try adding the -E flag to encourage display of empty periods/zero- transactions.-- o Try setting explicit forecast start and/or end dates with --fore-- cast=START..END-- o Consult Forecast period, in detail, above.-- o Check inside the engine: add --debug=2 (eg).--Budgeting- With the balance command's --budget report, each periodic transaction- rule generates recurring budget goals in specified accounts, and goals- and actual performance can be compared. See the balance command's doc- below.-- You can generate budget goals and forecast transactions at the same- time, from the same or different periodic transaction rules: hledger- bal -M --budget --forecast ...-- See also: Budgeting and Forecasting.--Cost reporting- In some transactions - for example a currency conversion, or a purchase- or sale of stock - one commodity is exchanged for another. In these- transactions there is a conversion rate, also called the cost (when- buying) or selling price (when selling). In hledger docs we just say- "cost", for convenience; feel free to mentally translate to "conversion- rate" or "selling price" if helpful.-- Recording costs- We'll explore several ways of recording transactions involving costs.- These are also summarised at hledger Cookbook > Cost notation.-- Costs can be recorded explicitly in the journal, using the @ UNITCOST- or @@ TOTALCOST notation described in Journal > Costs:-- Variant 1-- 2022-01-01- assets:dollars $-135- assets:euros 100 @ $1.35 ; $1.35 per euro (unit cost)-- Variant 2-- 2022-01-01- assets:dollars $-135- assets:euros 100 @@ $135 ; $135 total cost-- Typically, writing the unit cost (variant 1) is preferable; it can be- more effort, requiring more attention to decimal digits; but it reveals- the per-unit cost basis, and makes stock sales easier.-- Costs can also be left implicit, and hledger will infer the cost that- is consistent with a balanced transaction:-- Variant 3-- 2022-01-01- assets:dollars $-135- assets:euros 100-- Here, hledger will attach a @@ 100 cost to the first amount (you can- see it with hledger print -x). This form looks convenient, but there- are downsides:-- o It sacrifices some error checking. For example, if you accidentally- wrote 10 instead of 100, hledger would not be able to detect the mis-- take.-- o It is sensitive to the order of postings - if they were reversed, a- different entry would be inferred and reports would be different.-- o The per-unit cost basis is not easy to read.-- So generally this kind of entry is not recommended. You can make sure- you have none of these by using -s (strict mode), or by running hledger- check balanced.-- Reporting at cost- Now when you add the -B/--cost flag to reports ("B" is from Ledger's- -B/--basis/--cost flag), any amounts which have been annotated with- costs will be converted to their cost's commodity (in the report out-- put). Ie they will be displayed "at cost" or "at sale price".-- Some things to note:-- o Costs are attached to specific posting amounts in specific transac-- tions, and once recorded they do not change. This contrasts with- market prices, which are ambient and fluctuating.-- o Conversion to cost is performed before conversion to market value- (described below).-- Equity conversion postings- There is a problem with the entries above - they are not conventional- Double Entry Bookkeeping (DEB) notation, and because of the "magical"- transformation of one commodity into another, they cause an imbalance- in the Accounting Equation. This shows up as a non-zero grand total in- balance reports like hledger bse.-- For most hledger users, this doesn't matter in practice and can safely- be ignored ! But if you'd like to learn more, keep reading.-- Conventional DEB uses an extra pair of equity postings to balance the- transaction. Of course you can do this in hledger as well:-- Variant 4-- 2022-01-01- assets:dollars $-135- assets:euros 100- equity:conversion $135- equity:conversion -100-- Now the transaction is perfectly balanced according to standard DEB,- and hledger bse's total will not be disrupted.-- And, hledger can still infer the cost for cost reporting, but it's not- done by default - you must add the --infer-costs flag like so:-- $ hledger print --infer-costs- 2022-01-01 one hundred euros purchased at $1.35 each- assets:dollars $-135 @@ 100- assets:euros 100- equity:conversion $135- equity:conversion -100-- $ hledger bal --infer-costs -B- -100 assets:dollars- 100 assets:euros- --------------------- 0-- Here are some downsides of this kind of entry:-- o The per-unit cost basis is not easy to read.-- o Instead of -B you must remember to type -B --infer-costs.-- o --infer-costs works only where hledger can identify the two eq-- uity:conversion postings and match them up with the two non-equity- postings. So writing the journal entry in a particular format be-- comes more important. More on this below.-- Inferring equity conversion postings- Can we go in the other direction ? Yes, if you have transactions writ-- ten with the @/@@ cost notation, hledger can infer the missing equity- postings, if you add the --infer-equity flag. Eg:-- 2022-01-01- assets:dollars -$135- assets:euros 100 @ $1.35-- $ hledger print --infer-equity- 2022-01-01- assets:dollars $-135- assets:euros 100 @ $1.35- equity:conversion:$-: -100- equity:conversion:$-:$ $135.00-- The equity account names will be "equity:conversion:A-B:A" and "eq-- uity:conversion:A-B:B" where A is the alphabetically first commodity- symbol. You can customise the "equity:conversion" part by declaring an- account with the V/Conversion account type.-- Combining costs and equity conversion postings- Finally, you can use both the @/@@ cost notation and equity postings at- the same time. This in theory gives the best of all worlds - preserv-- ing the accounting equation, revealing the per-unit cost basis, and- providing more flexibility in how you write the entry:-- Variant 5-- 2022-01-01 one hundred euros purchased at $1.35 each- assets:dollars $-135- equity:conversion $135- equity:conversion -100- assets:euros 100 @ $1.35-- All the other variants above can (usually) be rewritten to this final- form with:-- $ hledger print -x --infer-costs --infer-equity-- Downsides:-- o The precise format of the journal entry becomes more important. If- hledger can't detect and match up the cost and equity postings, it- will give a transaction balancing error.-- o The add command does not yet accept this kind of entry (#2056).-- o This is the most verbose form.-- Requirements for detecting equity conversion postings- --infer-costs has certain requirements (unlike --infer-equity, which- always works). It will infer costs only in transactions with:-- o Two non-equity postings, in different commodities. Their order is- significant: the cost will be added to the first of them.-- o Two postings to equity conversion accounts, next to one another,- which balance the two non-equity postings. This balancing is checked- to the same precision (number of decimal places) used in the conver-- sion posting's amount. Equity conversion accounts are:-- o any accounts declared with account type V/Conversion, or their sub-- accounts-- o otherwise, accounts named equity:conversion, equity:trade, or eq-- uity:trading, or their subaccounts.-- And multiple such four-posting groups can coexist within a single- transaction. When --infer-costs fails, it does not infer a cost in- that transaction, and does not raise an error (ie, it infers costs- where it can).-- Reading variant 5 journal entries, combining cost notation and equity- postings, has all the same requirements. When reading such an entry- fails, hledger raises an "unbalanced transaction" error.-- Infer cost and equity by default ?- Should --infer-costs and --infer-equity be enabled by default ? Try- using them always, eg with a shell alias:-- alias h="hledger --infer-equity --infer-costs"-- and let us know what problems you find.--Value reporting- Instead of reporting amounts in their original commodity, hledger can- convert them to cost/sale amount (using the conversion rate recorded in- the transaction), and/or to market value (using some market price on a- certain date). This is controlled by the --value=TYPE[,COMMODITY] op-- tion, which will be described below. We also provide the simpler -V- 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- Market prices can change from day to day. hledger will use the prices- on a particular valuation date (or on more than one date). By default- hledger uses "end" dates for valuation. More specifically:-- o For single period reports (including normal print and register re-- ports):-- o If an explicit report end date is specified, that is used-- o Otherwise the latest transaction date or P directive date is used- (even if it's in the future)-- o For multiperiod reports, each period is valued on its last day.-- This can be customised with the --value option described below, which- can select either "then", "end", "now", or "custom" dates. (Note, this- has a bug in hledger-ui <=1.31: turning on valuation with the V key al-- ways resets it to "end".)-- Finding market price- To convert a commodity A to its market value in another commodity B,- hledger looks for a suitable market price (exchange rate) as follows,- 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-prices flag) inferred from costs.-- 2. A reverse market price: the inverse of a declared or inferred market- price from B to A.-- 3. A forward chain of market prices: a synthetic price formed by com-- 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-prices: 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 costs as additional market prices (as- Ledger does) ? Adding the --infer-market-prices flag to -V, -X or- --value enables this.-- So for example, hledger bs -V --infer-market-prices will get market- prices both from P directives and from transactions. 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 Value reporting section carefully, and try adding- --debug or --debug=2 to troubleshoot.-- --infer-market-prices can infer market prices from:-- o multicommodity transactions with explicit prices (@/@@)-- o multicommodity transactions with implicit prices (no @, two commodi-- ties, unbalanced). (With these, the order of postings matters.- hledger print -x can be useful for troubleshooting.)-- o multicommodity transactions with equity postings, if cost is inferred- with --infer-costs.-- There is a limitation (bug) currently: when a valuation commodity is- not specified, prices inferred with --infer-market-prices do not help- select a default valuation commodity, as P prices would. So conversion- might not happen because no valuation commodity was detected (--debug=2- will show this). To be safe, specify the valuation commmodity, eg:-- o -X EUR --infer-market-prices, not -V --infer-market-prices-- o --value=then,EUR --infer-market-prices, not --value=then --infer-mar-- ket-prices-- Signed costs and market prices can be confusing. For reference, here- is the current behaviour, since hledger 1.25. (If you think it should- work differently, see #1870.)-- 2022-01-01 Positive Unit prices- a A 1- b B -1 @ A 1-- 2022-01-01 Positive Total prices- a A 1- b B -1 @@ A 1--- 2022-01-02 Negative unit prices- a A 1- b B 1 @ A -1-- 2022-01-02 Negative total prices- a A 1- b B 1 @@ A -1--- 2022-01-03 Double Negative unit prices- a A -1- b B -1 @ A -1-- 2022-01-03 Double Negative total prices- a A -1- b B -1 @@ A -1-- All of the transactions above are considered balanced (and on each day,- the two transactions are considered equivalent). Here are the market- prices inferred for B:-- $ hledger -f- --infer-market-prices prices- P 2022-01-01 B A 1- P 2022-01-01 B A 1.0- P 2022-01-02 B A -1- P 2022-01-02 B A -1.0- P 2022-01-03 B A -1- P 2022-01-03 B A -1.0-- 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-prices flag is used: the price commodity from the- latest transaction-inferred price for A on or before valuation date.-- This means:-- o If you have P directives, they determine which commodities -V will- convert, and to what.-- o If you have no P directives, and use the --infer-market-prices flag,- costs determine it.-- Amounts for which no valuation commodity can be found are not con-- verted.-- --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.-- Valuation examples- Here are some quick examples of -V:-- ; one euro is worth this many dollars from nov 1- P 2016/11/01 $1.10-- ; purchase some euros on nov 3- 2016/11/3- assets:euros 100- assets:checking-- ; the euro is worth fewer dollars by dec 21- P 2016/12/21 $1.03-- How many euros do I have ?-- $ hledger -f t.j bal -N euros- 100 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-- 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-- Interaction of valuation and queries- When matching postings based on queries in the presence of valuation,- the following happens:-- 1. The query is separated into two parts:-- 1. the currency (cur:) or amount (amt:).-- 2. all other parts.-- 2. The postings are matched to the currency and amount queries based on- pre-valued amounts.-- 3. Valuation is applied to the postings.-- 4. The postings are matched to the other parts of the query based on- post-valued amounts.-- Related: #1625-- Effect of valuation on reports- Here is a reference for how valuation is supposed to affect each part- of hledger's reports. (It's wide, you may need to scroll sideways.)- It may be useful when troubleshooting. If you find problems, please- report them, ideally with a reproducible example. Related: #329,- #1083.-- First, a quick 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).-- Report -B, --cost -V, -X --value=then --value=end --value=DATE,- type --value=now- --------------------------------------------------------------------------------------------- print- posting cost value at re- value at posting value at re- value at- amounts port end or date port or DATE/today- today journal end- balance unchanged unchanged unchanged unchanged unchanged- asser-- tions/as-- signments-- register- starting cost value at re- valued at day value at re- value at- balance port or each historical port or DATE/today- (-H) journal end posting was made journal end- starting cost value at day valued at day value at day value at- balance before re- each historical before re- DATE/today- (-H) with port or posting was made port or- report journal journal- interval start start- posting cost value at re- value at posting value at re- value at- amounts port or date port or DATE/today- journal end journal end- summary summarised value at pe- sum of postings value at pe- value at- posting cost riod ends in interval, val- riod ends DATE/today- amounts ued at interval- with re- start- port in-- terval- running sum/average sum/average sum/average of sum/average sum/average- total/av- of displayed of displayed displayed values of displayed of displayed- erage values values values values-- balance- (bs, bse,- cf, is)- balance sums of value at re- value at posting value at re- value at- changes costs port end or date port or DATE/today of- 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- (--bud-- get)- grand to- sum of dis- sum of dis- sum of displayed sum of dis- sum of dis-- tal played val- played val- valued played val- played values- ues ues ues-- balance- (bs, bse,- cf, is)- with re-- port in-- terval- starting sums of value at re- sums of values of value at re- sums of post-- balances costs of port start postings before port start ings before- (-H) postings be- of sums of report start at of sums of report start- fore report all postings respective post- all postings- start before re- ing dates before re-- port start port start- balance sums of same as sums of values of balance value at- changes costs of --value=end postings in pe- change in DATE/today of- (bal, is, postings in riod at respec- each period, sums of post-- bs period tive posting valued at ings- --change, dates period ends- cf- --change)- end bal- sums of same as sums of values of period end value at- ances costs of --value=end postings from be- balances, DATE/today of- (bal -H, postings fore period start valued at sums of post-- is --H, from before to period end at period ends ings- bs, cf) report start respective post-- to period ing dates- end- budget like balance like balance like balance like bal- like balance- amounts changes/end changes/end changes/end bal- ances changes/end- (--bud- balances balances ances balances- get)- row to- sums, aver- sums, aver- sums, averages of sums, aver- sums, aver-- tals, row ages of dis- ages of dis- displayed values ages of dis- ages of dis-- averages played val- played val- played val- played values- (-T, -A) ues ues ues- column sums of dis- sums of dis- sums of displayed sums of dis- sums of dis-- totals played val- played val- values played val- played values- ues ues ues- grand to- sum, average sum, average sum, average of sum, average sum, average- tal, of column of column column totals of column of column to-- grand av- totals totals totals tals- erage--- --cumulative is omitted to save space, it works like -H but with a zero- starting balance.--PART 4: COMMANDS- Commands overview- Here are the built-in commands:-- DATA ENTRY- These data entry commands are the only ones which can modify your jour-- nal file.-- o add - add transactions using terminal prompts-- o import - add new transactions from other files, eg CSV files-- DATA CREATION- o close - generate balance-zeroing/restoring transactions-- o rewrite - generate auto postings, like print --auto-- DATA MANAGEMENT- o check - check for various kinds of error in the data-- o diff - compare account transactions in two journal files-- REPORTS, FINANCIAL- 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-- REPORTS, VERSATILE- o balance (bal) - show balance changes, end balances, budgets, gains..-- o print - show transactions or export journal data-- o register (reg) - show postings in one or more accounts & running to-- tal-- o roi - show return on investments-- REPORTS, BASIC- o accounts - show account names-- o activity - show bar charts of posting counts per period-- o codes - show transaction codes-- o commodities - show commodity/currency symbols-- o descriptions - show transaction descriptions-- o files - show input file paths-- o notes - show note parts of transaction descriptions-- o payees - show payee parts of transaction descriptions-- o prices - show market prices-- o stats - show journal statistics-- o tags - show tag names-- o test - run self tests-- HELP- o help - show the hledger manual with info/man/pager-- o demo - show small hledger demos in the terminal-- ADD-ONS- And here are some typical add-on commands. Some of these are installed- by the hledger-install script. If installed, they will appear in- hledger's commands list:-- o ui - run hledger's terminal UI-- o web - run hledger's web UI-- o iadd - add transactions using a TUI (currently hard to build)-- o interest - generate interest transactions-- o stockquotes - download market prices from AlphaVantage-- o Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,- pijul, plot, and more..-- Next, each command is described in detail, in alphabetical order.-- accounts- Show account names.-- This command lists account names. By default it shows all known ac-- counts, either used in transactions or declared with account direc-- tives.-- With query arguments, only matched account names and account names ref-- erenced by matched postings are shown.-- Or it can show just the used accounts (--used/-u), the declared ac-- counts (--declared/-d), the accounts declared but not used (--unused),- the accounts used but not declared (--undeclared), or the first account- matched by an account name pattern, if any (--find).-- It shows a flat list by default. With --tree, it uses indentation to- show the account hierarchy. In flat mode you can add --drop N to omit- the first few account name components. Account names can be- depth-clipped with depth:N or --depth N or -N.-- With --types, it also shows each account's type, if it's known. (See- Declaring accounts > Account types.)-- With --positions, it also shows the file and line number of each ac-- count's declaration, if any, and the account's overall declaration or-- der; these may be useful when troubleshooting account display order.-- With --directives, it adds the account keyword, showing valid account- directives which can be pasted into a journal file. This is useful to-- gether with --undeclared when updating your account declarations to- satisfy hledger check accounts.-- The --find flag can be used to look up a single account name, in the- same way that the aregister command does. It returns the alphanumeri-- cally-first matched account name, or if none can be found, it fails- with a non-zero exit code.-- Examples:-- $ hledger accounts- assets:bank:checking- assets:bank:saving- assets:cash- expenses:food- expenses:supplies- income:gifts- income:salary- liabilities:debts-- $ hledger accounts --undeclared --directives >> $LEDGER_FILE- $ hledger check accounts-- 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- 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 main journal file (which should be in- journal format). Existing transactions are not changed. This is one- of the few hledger commands that writes to the journal file (see also- import).-- To use it, just run hledger add and follow the prompts. You can add as- many transactions as you like; when you are finished, enter . or press- control-d or control-c to exit.-- Features:-- o add tries to provide useful defaults, using the most similar (by de-- scription) recent transaction (filtered by the query, if any) as a- template.-- o You can also set the initial defaults with command line arguments.-- o Readline-style edit keys can be used during data entry.-- o The tab key will auto-complete whenever possible - accounts, pay-- ees/descriptions, dates (yesterday, today, tomorrow). If the input- area is empty, it will insert the default value.-- o If the journal defines a default commodity, it will be added to any- 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 https://hledger.org/add.html for a detailed tutorial):-- $ 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> $-- If you enter a number with no commodity symbol, and you have declared a- default commodity with a D directive, you might expect add to add this- symbol for you. It does not do this; we assume that if you are using a- D directive you prefer not to see the commodity symbol repeated on- amounts in the journal.-- aregister- (areg)-- Show the transactions and running historical balance of a single ac-- count, with each transaction displayed as one line.-- aregister shows the overall transactions affecting a particular account- (and any subaccounts). Each report line represents one transaction in- this account. Transactions before the report start date are always in-- cluded in the running balance (--historical mode is always on).-- This is a more "real world", bank-like view than the register command- (which shows individual postings, possibly from multiple accounts, not- necessarily in historical mode). As a quick rule of thumb: - use areg-- ister for reviewing and reconciling real-world asset/liability accounts- - use register for reviewing detailed revenues/expenses.-- aregister requires one argument: the account to report on. You can- write either the full account name, or a case-insensitive regular ex-- pression which will select the alphabetically first matched account.-- When there are multiple matches, the alphabetically-first choice can be- surprising; eg if you have assets:per:checking 1 and assets:biz:check-- ing 2 accounts, hledger areg checking would select assets:biz:checking- 2. It's just a convenience to save typing, so if in doubt, write the- full account name, or a distinctive substring that matches uniquely.-- 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.-- For performance reasons, column widths are chosen based on the first- 1000 lines; this means unusually wide values in later lines can cause- visual discontinuities as column widths are adjusted. If you want to- ensure perfect alignment, at the cost of more time and memory, use the- --align-all flag.-- This command also supports the output destination and output format op-- tions. The output formats supported are txt, csv, tsv (Added in 1.32),- and json.-- aregister and posting dates- aregister always shows one line (and date and amount) per transaction.- But sometimes transactions have postings with different dates. Also,- not all of a transaction's postings may be within the report period.- To resolve this, aregister shows the earliest of the transaction's date- and posting dates that is in-period, and the sum of the in-period post-- ings. In other words it will show a combined line item with just the- earliest date, and the running balance will (temporarily, until the- transaction's last posting) be inaccurate. Use register -H if you need- to see the individual postings.-- There is also a --txn-dates flag, which filters strictly by transaction- date, ignoring posting dates. This too can cause an inaccurate running- 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)-- o or unrealised capital gain/loss (--gain)-- o or balance changes from sibling postings (--related/-r)-- o or postings count (--count)-- ..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 (--in-- vert)-- o rows and columns swapped (--transpose)-- o another field used as account name (--pivot)-- o custom-formatted line items (single-period reports only) (--format)-- o commodities displayed on the same line or multiple lines (--layout)-- This command supports the output destination and output format options,- with output formats txt, csv, tsv (Added in 1.32), json, and (multi-pe-- riod reports only:) html. In txt output in a colour-supporting termi-- nal, 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. ("Simple" here- means just one column of numbers, covering a single period. You can- also have multi-period reports, described later.)-- For real-world accounts, these numbers will normally be their end bal-- ance 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 -f examples/sample.journal bal- $1 assets:bank:saving- $-2 assets:cash- $1 expenses:food- $1 expenses:supplies- $-1 income:gifts- $-1 income:salary- $1 liabilities:debts- --------------------- 0-- Accounts with a zero balance (and no non-zero subaccounts, in tree mode- - see below) are hidden by default. Use -E/--empty to show them (re-- vealing 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.-- Balance report line format- 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 -f examples/sample.journal 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 specifies the formatting applied to each ac-- count/balance pair. It may contain any suitable text, with data fields- interpolated like so:-- %[MIN][.MAX](FIELDNAME)-- o MIN pads with spaces to at least this width (optional)-- o MAX truncates at this width (optional)-- o FIELDNAME must be enclosed in parentheses, and can be one of:-- o depth_spacer - a number of spaces equal to the account's depth, or- if MIN is specified, MIN * depth spaces.-- o account - the account's name-- o total - the account's balance/posted total, right justified-- Also, FMT can begin with an optional prefix to control how multi-com-- modity amounts are rendered:-- o %_ - render on multiple lines, bottom-aligned (the default)-- o %^ - render on multiple lines, top-aligned-- o %, - render on one line, comma-separated-- There are some quirks. Eg in one-line mode, %(depth_spacer) has no ef-- fect, instead %(account) has indentation built in. Experimentation- may be needed to get pleasing results.-- Some example formats:-- o %(total) - the account's total-- o %-20.20(account) - the account's name, left justified, padded to 20- characters and clipped at 20 characters-- o %,%-50(account) %25(total) - account name padded to 50 characters,- total padded to 20 characters, with multiple commodities rendered on- one line-- o %20(total) %2(depth_spacer)%-(account) - the default format for the- single-column balance report-- 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 -f examples/sample.journal 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 -f examples/sample.journal balance- $-1 assets- $1 bank:saving- $-2 cash- $2 expenses- $1 food- $1 supplies- $-2 income- $-1 gifts- $-1 salary- $1 liabilities:debts- --------------------- 0-- 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:NUM query, or --depth NUM option, or just -NUM (eg: -3)- balance reports will show accounts only to the specified depth, hiding- the deeper subaccounts. This can be useful for getting an overview- without too much detail.-- Account balances at the depth limit always include the balances from- any deeper subaccounts (even in list mode). Eg, limiting to depth 1:-- $ hledger -f examples/sample.journal balance -1- $-1 assets- $2 expenses- $-2 income- $1 liabilities- --------------------- 0-- Dropping top-level accounts- You can also hide one or more top-level account name parts, using- --drop NUM. This can be useful for hiding repetitive top-level account- names:-- $ hledger -f examples/sample.journal bal expenses --drop 1- $1 food- $1 supplies- --------------------- $2-- Showing declared accounts- With --declared, accounts which have been declared with an account di-- rective will be included in the balance report, even if they have no- transactions. (Since they will have a zero balance, you will also need- -E/--empty to see them.)-- More precisely, leaf declared accounts (with no subaccounts) will be- included, since those are usually the more useful in reports.-- The idea of this is to be able to see a useful "complete" balance re-- port, even when you don't have transactions in all of your declared ac-- counts yet.-- Sorting by amount- With -S/--sort-amount, accounts with the largest (most positive) bal-- ances are shown first. Eg: hledger bal expenses -MAS shows your- biggest averaged monthly expenses first. When more than one commodity- is present, they will be sorted by the alphabetically earliest commod-- ity first, and then by subsequent commodities (if an amount is missing- a commodity, it is treated as 0).-- Revenues and liability balances are typically negative, however, so -S- shows these in reverse order. To work around this, you can add --in-- vert to flip the signs. (Or, use one of the higher-level reports,- 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.-- 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:-- 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 -f examples/sample.journal bal --quarterly income expenses -E- Balance changes in 2008:-- || 2008q1 2008q2 2008q3 2008q4- ===================++=================================- expenses:food || 0 $1 0 0- expenses:supplies || 0 $1 0 0- income:gifts || 0 $-1 0 0- income:salary || $-1 0 0 0- -------------------++---------------------------------- || $-1 $1 0 0-- 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.-- 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 Filter to a single currency with cur:-- o Convert to a single currency with -V [--infer-market-price]-- o Use a more compact layout like --layout=bare-- 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-- 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 ac-- count during some period.-- An end balance is the amount accumulated in an account as of some date- (and some time, but hledger doesn't store that; assume end of day in- 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- The balance command is quite flexible; here is the full detail on how- to control what it reports. If the following seems complicated, don't- worry - this is for advanced reporting, and it does take time and ex-- perimentation to get familiar with all the report modes.-- There are three important option groups:-- hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]- ...-- Calculation type- The basic calculation to perform for each table cell. It is one of:-- o --sum : sum the posting amounts (default)-- o --budget : sum the amounts, but also show the budget goal amount (for- each account/period)-- o --valuechange : show the change in period-end historical balance val-- ues (caused by deposits, withdrawals, and/or market price fluctua-- tions)-- o --gain : show the unrealised capital gain/loss, (the current valued- balance minus each amount's original cost)-- o --count : show the count of postings-- Accumulation type- How amounts should accumulate across a report's subperiods/columns.- Another way to say it: which time period's postings should contribute- to each cell's calculation. It is one of:-- o --change : calculate with postings from column start to column end,- ie "just this column". Typically used to see revenues/expenses.- (default for balance, cashflow, incomestatement)-- o --cumulative : calculate with postings from report start to column- end, ie "previous columns plus this column". Typically used to show- changes accumulated since the report's start date. Not often used.-- o --historical/-H : calculate with postings from journal start to col-- umn end, ie "all postings from before report start date until this- column's end". Typically used to see historical end balances of as-- sets/liabilities/equity. (default for balancesheet, balancesheete-- quity)-- Valuation type- Which kind of value or cost conversion should be applied, if any, be-- fore displaying the report. It is one of:-- o no valuation type : don't convert to cost or value (default)-- o --value=cost[,COMM] : convert amounts to cost (then optionally to- some other commodity)-- o --value=then[,COMM] : convert amounts to market value on transaction- dates-- o --value=end[,COMM] : convert amounts to market value on period end- date(s)- (default with --valuechange, --gain)-- o --value=now[,COMM] : convert amounts to market value on today's date-- o --value=YYYY-MM-DD[,COMM] : convert amounts to market value on an-- other date-- or one of the equivalent simpler flags:-- o -B/--cost : like --value=cost (though, note --cost and --value are- independent options which can both be used at once)-- o -V/--market : like --value=end-- o -X COMM/--exchange COMM : like --value=end,COMM-- See Cost reporting and Value reporting for more about these.-- Combining balance report types- Most combinations of these options should produce reasonable reports,- but if you find any that seem wrong or misleading, let us know. The- 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=- tion:> YYYY-MM-DD- Accumu- /now- lation:v- ------------------------------------------------------------------------------------ --change change in period sum of post- period-end DATE-value of- ing-date market value of change change in pe-- values in period in period riod- --cumu- change from re- sum of post- period-end DATE-value of- lative port start to ing-date market value of change change from- period end values from re- from report report start- port start to pe- start to period to period end- riod end end- --his- change from sum of post- period-end DATE-value of- torical journal start to ing-date market value of change change from- /-H period end (his- values from jour- from journal journal start- torical end bal- nal start to pe- start to period to period end- ance) riod end end-- Budget report- The --budget report type is like a regular balance report, but with two- main differences:-- o Budget goals and performance percentages are also shown, in brackets-- o Accounts which don't have budget goals are hidden by default.-- This is useful for comparing planned and actual income, expenses, time- usage, etc.-- Periodic transaction rules are used to define budget goals. For exam-- ple, here's a periodic rule defining monthly goals for bus travel and- food expenses:-- ;; Budget- ~ monthly- (expenses:bus) $30- (expenses:food) $400-- After recording some actual expenses,-- ;; Two months worth of expenses- 2017-11-01- income $-1950- expenses:bus $35- expenses:food:groceries $310- expenses:food:dining $42- expenses:movies $38- assets:bank:checking-- 2017-12-01- income $-2100- expenses:bus $53- expenses:food:groceries $380- expenses:food:dining $32- expenses:gifts $100- assets:bank:checking-- we can see a budget report like this:-- $ hledger bal -M --budget- Budget performance in 2017-11-01..2017-12-31:-- || Nov Dec- ===============++============================================- <unbudgeted> || $-425 $-565- expenses || $425 [ 99% of $430] $565 [131% of $430]- expenses:bus || $35 [117% of $30] $53 [177% of $30]- expenses:food || $352 [ 88% of $400] $412 [103% of $400]- ---------------++--------------------------------------------- || 0 [ 0% of $430] 0 [ 0% of $430]-- This is "goal-based budgeting"; you define goals for accounts and peri-- ods, often recurring, and hledger shows performance relative to the- goals. This contrasts with "envelope budgeting", which is more de-- tailed and strict - useful when cash is tight, but also quite a bit- more work. https://plaintextaccounting.org/Budgeting has more on this- topic.-- Using the budget report- Historically this report has been confusing and fragile. hledger's- version should be relatively robust and intuitive, but you may still- find surprises. Here are more notes to help with learning and trou-- bleshooting.-- o In the above example, expenses:bus and expenses:food are shown be-- cause they have budget goals during the report period.-- o Their parent expenses is also shown, with budget goals aggregated- from the children.-- o The subaccounts expenses:food:groceries and expenses:food:dining are- not shown since they have no budget goal of their own, but they con-- tribute to expenses:food's actual amount.-- o Unbudgeted accounts expenses:movies and expenses:gifts are also not- shown, but they contribute to expenses's actual amount.-- o The other unbudgeted accounts income and assets:bank:checking are- grouped as <unbudgeted>.-- o --depth or depth: can be used to limit report depth in the usual way- (but will not reveal unbudgeted subaccounts).-- o Amounts are always inclusive of subaccounts (even in -l/--list mode).-- o Numbers displayed in a --budget report will not always agree with the- totals, because of hidden unbudgeted accounts; this is normal.- -E/--empty can be used to reveal the hidden accounts.-- o In the periodic rules used for setting budget goals, unbalanced post-- ings are convenient.-- o You can filter budget reports with the usual queries, eg to focus on- particular accounts. It's common to restrict them to just expenses.- (The <unbudgeted> account is occasionally hard to exclude; this is- because of date surprises, discussed below.)-- o When you have multiple currencies, you may want to convert them to- one (-X COMM --infer-market-prices) and/or show just one at a time- (cur:COMM). If you do need to show multiple currencies at once,- --layout bare can be helpful.-- o You can "roll over" amounts (actual and budgeted) to the next period- with --cumulative.-- See also: https://hledger.org/budgeting.html.-- Budget date surprises- With small data, or when starting out, some of the generated budget- goal transaction dates might fall outside the report periods. Eg with- the following journal and report, the first period appears to have no- expenses:food budget. (Also the <unbudgeted> account should be ex-- cluded by the expenses query, but isn't.):-- ~ monthly in 2020- (expenses:food) $500-- 2020-01-15- expenses:food $400- assets:checking-- $ hledger bal --budget expenses- Budget performance in 2020-01-15:-- || 2020-01-15- ===============++====================- <unbudgeted> || $400- expenses:food || 0 [ 0% of $500]- ---------------++--------------------- || $400 [80% of $500]-- In this case, the budget goal transactions are generated on first days- of of month (this can be seen with hledger print --forecast tag:gener-- ated expenses). Whereas the report period defaults to just the 15th- day of january (this can be seen from the report table's column head-- ings).-- To fix this kind of thing, be more explicit about the report period- (and/or the periodic rules' dates). In this case, adding -b 2020 does- the trick.-- Selecting budget goals- By default, the budget report uses all available periodic transaction- rules to generate goals. This includes rules with a different report- interval from your report. Eg if you have daily, weekly and monthly- periodic rules, all of these will contribute to the goals in a monthly- budget report.-- You can select a subset of periodic rules by providing an argument to- the --budget flag. --budget=DESCPAT will match all periodic rules- whose description contains DESCPAT, a case-insensitive substring (not a- regular expression or query). This means you can give your periodic- rules descriptions (remember that two spaces are needed between period- expression and description), and then select from multiple budgets de-- fined in your journal.-- Budgeting vs forecasting- --forecast and --budget both use the periodic transaction rules in the- journal to generate temporary transactions for reporting purposes.- However they are separate features - though you can use both at the- same time if you want. Here are some differences between them:-- --forecast --budget- --------------------------------------------------------------------------- is a general option; it enables fore- is a balance command option; it- casting with all reports selects the balance report's- budget mode- generates visible transactions which generates invisible transactions- appear in reports which produce goal amounts- generates forecast transactions from generates budget goal transac-- after the last regular transaction, to tions throughout the report pe-- the end of the report period; or with riod, optionally restricted by- an argument --forecast=PERIODEXPR gen- periods specified in the peri-- erates them throughout the specified odic transaction rules- period, both optionally restricted by- periods specified in the periodic- transaction rules- uses all periodic rules uses all periodic rules; or with- an argument --budget=DESCPAT- uses just the rules matched by- DESCPAT-- Balance report layout- The --layout option affects how balance reports show multi-commodity- amounts and commodity symbols, which can improve readability. It can- also normalise the data for easy consumption by other programs. It has- four possible values:-- o --layout=wide[,WIDTH]: commodities are shown on a single line, op-- tionally elided to WIDTH-- o --layout=tall: each commodity is shown on a separate line-- o --layout=bare: commodity symbols are in their own column, amounts are- bare numbers-- o --layout=tidy: data is normalised to easily-consumed "tidy" form,- with one row per data value-- Here are the --layout modes supported by each output format Only CSV- output supports all of them:-- - txt csv html json sql- -------------------------------------- wide Y Y Y- tall Y Y Y- bare Y Y Y- tidy Y-- Examples:-- Wide layout- With many commodities, reports can be very wide:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide- Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total- ==================++====================================================================================================================================================================================================================- Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT- ------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT-- A width limit reduces the width, but some commodities will be hidden:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32- Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total- ==================++===========================================================================================================================- Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..- ------------------++---------------------------------------------------------------------------------------------------------------------------- || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..-- Tall layout- Each commodity gets a new line (may be different in each column), and- account names are repeated:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall- Balance changes in 2012-01-01..2014-12-31:-- || 2012 2013 2014 Total- ==================++==================================================- Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD- Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT- Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD- Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA- Assets:US:ETrade || 18.00 VHT 294.00 VHT- ------------------++--------------------------------------------------- || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD- || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT- || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD- || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA- || 18.00 VHT 294.00 VHT-- Bare layout- Commodity symbols are kept in one column, each commodity has its own- row, amounts are bare numbers, account names are repeated:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare- Balance changes in 2012-01-01..2014-12-31:-- || Commodity 2012 2013 2014 Total- ==================++=============================================- Assets:US:ETrade || GLD 0 70.00 0 70.00- Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00- Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50- Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00- Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00- ------------------++---------------------------------------------- || GLD 0 70.00 0 70.00- || ITOT 10.00 18.00 -11.00 17.00- || USD 337.18 -98.12 4881.44 5120.50- || VEA 12.00 10.00 14.00 36.00- || VHT 106.00 18.00 170.00 294.00-- Bare layout also affects CSV output, which is useful for producing data- that is easier to consume, eg for making charts:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare- "account","commodity","balance"- "Assets:US:ETrade","GLD","70.00"- "Assets:US:ETrade","ITOT","17.00"- "Assets:US:ETrade","USD","5120.50"- "Assets:US:ETrade","VEA","36.00"- "Assets:US:ETrade","VHT","294.00"- "total","GLD","70.00"- "total","ITOT","17.00"- "total","USD","5120.50"- "total","VEA","36.00"- "total","VHT","294.00"-- Bare layout will sometimes display an extra row for the no-symbol com-- modity, because of zero amounts (hledger treats zeroes as commod-- ity-less, usually). This can break hledger-bar confusingly- (workaround: add a cur: query to exclude the no-symbol row).-- Tidy layout- This produces normalised "tidy data" (see- https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)- where every variable has its own column and each row represents a sin-- gle data point. This is the easiest kind of data for other software to- consume:-- $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy- "account","period","start_date","end_date","commodity","value"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","GLD","0"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","ITOT","10.00"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","USD","337.18"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","VEA","12.00"- "Assets:US:ETrade","2012","2012-01-01","2012-12-31","VHT","106.00"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","GLD","70.00"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","ITOT","18.00"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","USD","-98.12"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","VEA","10.00"- "Assets:US:ETrade","2013","2013-01-01","2013-12-31","VHT","18.00"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","GLD","0"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","ITOT","-11.00"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","USD","4881.44"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VEA","14.00"- "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"-- Some 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-- 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.-- This report shows accounts declared with the Asset, Cash or Liability- type (see account types). Or if no such accounts are declared, it- shows top-level accounts named asset or liability (case insensitive,- plurals allowed) and their subaccounts.-- Example:-- $ hledger balancesheet- Balance Sheet 2008-12-31-- || 2008-12-31- ====================++============- Assets ||- --------------------++------------- assets:bank:saving || $1- assets:cash || $-2- --------------------++------------- || $-1- ====================++============- Liabilities ||- --------------------++------------- liabilities:debts || $-1- --------------------++------------- || $-1- ====================++============- Net: || 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 op-- tions The output formats supported are txt, csv, tsv (Added in 1.32),- html, and json.-- 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.-- This report shows accounts declared with the Asset, Cash, Liability or- Equity type (see account types). Or if no such accounts are declared,- it shows top-level accounts named asset, liability or equity (case in-- sensitive, plurals allowed) and their subaccounts.-- Example:-- $ hledger balancesheetequity- Balance Sheet With Equity 2008-12-31-- || 2008-12-31- ====================++============- Assets ||- --------------------++------------- assets:bank:saving || $1- assets:cash || $-2- --------------------++------------- || $-1- ====================++============- Liabilities ||- --------------------++------------- liabilities:debts || $-1- --------------------++------------- || $-1- ====================++============- Equity ||- --------------------++------------- --------------------++------------- || 0- ====================++============- Net: || 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 report is the easiest way to see if the accounting equation (A+L+E- = 0) is satisfied (after you have done a close --retain to merge rev-- enues and expenses with equity, and perhaps added --infer-equity to- balance your commodity conversions).-- This command also supports the output destination and output format op-- tions The output formats supported are txt, csv, tsv, html, and json.-- cashflow- (cf)-- This command displays a (simple) cashflow statement, showing the in-- flows and outflows affecting "cash" (ie, liquid, easily convertible)- assets. Amounts are shown with normal positive sign, as in conven-- tional financial statements.-- This report shows accounts declared with the Cash type (see account- types). Or if no such accounts are declared, it shows accounts-- o under a top-level account named asset (case insensitive, plural al-- lowed)-- o whose name contains some variation of cash, bank, checking or saving.-- More precisely: all accounts matching this case insensitive regular ex-- pression:-- ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)-- and their subaccounts.-- An example cashflow report:-- $ hledger cashflow- Cashflow Statement 2008-- || 2008- ====================++======- Cash flows ||- --------------------++------- assets:bank:saving || $1- assets:cash || $-2- --------------------++------- || $-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 op-- tions The output formats supported are txt, csv, tsv (Added in 1.32),- html, and json.-- 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-- If you are an Emacs user, you can also configure flycheck-hledger to- run these checks, providing instant feedback as you edit the journal.-- Here are the checks currently available:-- Default checks- These checks are run automatically by (almost) all hledger commands:-- o parseable - data files are in a supported format, with no syntax er-- rors and no invalid include directives.-- o autobalanced - all transactions are balanced, after converting to- cost. Missing amounts and missing costs are inferred automatically- where possible.-- o assertions - all balance assertions in the journal are passing.- (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 balanced - all transactions are balanced after converting to cost,- without inferring missing costs. If conversion costs are required,- they must be explicit.-- o accounts - all account names used by transactions have been declared-- o commodities - all commodity symbols used have been declared-- Other checks- These checks can be run only by giving their names as arguments to- check. They are more specialised and not desirable for everyone:-- o ordereddates - transactions are ordered by date within each file-- o payees - all payees used by transactions have been declared-- o recentassertions - all accounts with balance assertions have a bal-- ance assertion within 7 days of their latest posting-- o tags - all tags used by transactions have been declared-- o uniqueleafnames - all account leaf names are unique-- Custom checks- A few more checks are are available as separate add-on commands, in- 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.-- More about specific checks- hledger check recentassertions will complain if any balance-asserted- account has postings more than 7 days after its latest balance asser-- tion. This aims to prevent the situation where you are regularly up-- dating your journal, but forgetting to check your balances against the- real world, then one day must dig back through months of data to find- an error. It assumes that adding a balance assertion requires/reminds- you to check the real-world balance. (That may not be true if you- auto-generate balance assertions from bank data; in that case, I recom-- mend to import transactions uncleared, and when you manually review and- clear them, also check the latest assertion against the real-world bal-- ance.)-- close- (equity)-- close generates several kinds of "closing" and/or "opening" transac-- tions, useful in certain situations, including migrating balances to a- new journal file, retaining earnings into equity, consolidating bal-- ances, or viewing lots. Like print, it prints valid journal entries.- You can append or copy these to your journal file(s) when you are happy- with how they look.-- close currently has six modes, selected by a single mode flag:-- close --migrate- This is the most common mode. It prints a "closing balances" transac-- tion that zeroes out all asset and liability balances (by default), and- an opposite "opening balances" transaction that restores them again.- The balancing account will be equity:opening/closing balances (or an-- other specified by --close-acct or --open-acct).-- This is useful when migrating balances to a new journal file at the- start of a new year. Essentially, you run hledger close --mi-- grate=NEWYEAR -e NEWYEAR and then copy the closing transaction to the- end of the old file and the opening transaction to the start of the new- file. The opening transaction sets correct starting balances in the- new file when it is used alone, and the closing transaction keeps bal-- ances correct when you use both old and new files together, by can-- celling out the following opening transaction and preventing buildup of- duplicated opening balances. Think of the closing/opening pair as- "moving the balances into the next file".-- You can close a different set of accounts by providing a query. Eg if- you want to include equity, you can add assets liabilities equity or- type:ALE arguments. (The balancing account is always excluded.) Rev-- enues and expenses usually are not migrated to a new file directly; see- --retain below.-- The generated transactions will have a start: tag, with its value set- to --migrate's NEW argument if any, for easier matching or exclusion.- When NEW is not specified, it will be inferred if possible by incre-- menting a number (eg a year number) within the default journal's main- file name. The other modes behave similarly.-- close --close- This prints just the closing balances transaction of --migrate. It is- the default behaviour if you specify no mode flag. Using the customi-- sation options below, you can move balances from any set of accounts to- a different account.-- close --open- This prints just the opening balances transaction of --migrate. It is- similar to Ledger's equity command.-- close --assert- This prints a "closing balances" transaction (with balances: tag), that- just declares balance assertions for the current balances without- changing them. It could be useful as documention and to guard against- changes.-- close --assign- This prints an "opening balances" transaction that restores the account- balances using balance assignments. Balance assignments work regard-- less of any previous balance, so a preceding closing balances transac-- tion is not needed.-- However, omitting the closing balances transaction would unbalance eq-- uity. This is relatively harmless for personal reports, but it dis-- turbs the accounting equation, removing a source of error detection.- So --migrate is generally the best way to set to set balances in new- files, for now.-- close --retain- This is like --close with different defaults: it prints a "retain earn-- ings" transaction (with retain: tag), that transfers revenue and ex-- pense balances to equity:retained earnings.-- This is a different kind of closing, called "retaining earnings" or- "closing the books"; it is traditionally performed by businesses at the- end of each accounting period, to consolidate revenues and expenses- into the main equity balance. ("Revenues" and "expenses" are actually- equity by another name, kept separate temporarily for reporting pur-- poses.)-- In personal accounting you generally don't need to do this, unless you- want the balancesheetequity report to show a zero total, demonstrating- that the accounting equation (A-L=E) is satisfied.-- close customisation- In all modes, the following things can be overridden:-- o the accounts to be closed/opened, with account query arguments-- o the balancing account, with --close-acct=ACCT and/or --open-acct=ACCT-- o the transaction descriptions, with --close-desc=DESC and- --open-desc=DESC-- o the transaction's tag value, with a --MODE=NEW option argument-- o the closing/opening dates, with -e OPENDATE-- By default, the closing date is yesterday, or the journal's end date,- whichever is later; and the opening date is always one day after the- closing date. You can change these by specifying a report end date;- the closing date will be the last day of the report period. Eg -e 2024- means "close on 2023-12-31, open on 2024-01-01".-- With --x/--explicit, the balancing amount will be shown explicitly, and- if it involves multiple commodities, a separate posting will be gener-- ated for each of them (similar to print -x).-- With --interleaved, each individual transfer is shown with source and- destination postings next to each other (perhaps useful for trou-- bleshooting).-- With --show-costs, balances' costs are also shown, with different costs- kept separate. This may generate very large journal entries, if you- have many currency conversions or investment transactions. close- --show-costs is currently the best way to view investment lots with- hledger. (To move or dispose of lots, see the more capable- hledger-move script.)-- close and balance assertions- close adds balance assertions verifying that the accounts have been re-- set to zero in a closing transaction or restored to their previous bal-- ances in an opening transaction. These provide useful error checking,- but you can ignore them temporarily with -I, or remove them if you pre-- fer.-- Single-commodity, subaccount-exclusive balance assertions (=) are gen-- erated by default. This can be changed with --assertion-type='==*'- (eg).-- When running close you should probably avoid using -C, -R, status:- (filtering by status or realness) or --auto (generating postings),- since the generated balance assertions would then require these.-- Transactions with multiple dates (eg posting dates) spanning the file- boundary also can disrupt the balance assertions:-- 2023-12-30 a purchase made in december, cleared in january- expenses:food 5- assets:bank:checking -5 ; date: 2023-01-02-- To solve this you can transfer the money to and from a temporary ac-- count, splitting the multi-day transaction into two single-day transac-- tions:-- ; in 2022.journal:- 2022-12-30 a purchase made in december, cleared in january- expenses:food 5- equity:pending -5-- ; in 2023.journal:- 2023-01-02 last year's transaction cleared- equity:pending 5 = 0- assets:bank:checking -5-- close examples- Retain earnings- Record 2022's revenues/expenses as retained earnings on 2022-12-31, ap-- pending the generated transaction to the journal:-- $ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal-- After this, to see 2022's revenues and expenses you must exclude the- retain earnings transaction:-- $ hledger -f 2022.journal is not:desc:'retain earnings'-- Migrate balances to a new file- Close assets/liabilities on 2022-12-31 and re-open them on 2023-01-01:-- $ hledger close --migrate -f 2022.journal -p 2022- # copy/paste the closing transaction to the end of 2022.journal- # copy/paste the opening transaction to the start of 2023.journal-- After this, to see 2022's end-of-year balances you must exclude the- closing balances transaction:-- $ hledger -f 2022.journal bs not:desc:'closing balances'-- For more flexibility, it helps to tag closing and opening transactions- with eg start:NEWYEAR, then you can ensure correct balances by exclud-- ing all opening/closing transactions except the first, like so:-- $ hledger bs -Y -f 2021.j -f 2022.j -f 2023.j expr:'tag:start=2021 or not tag:start'- $ hledger bs -Y -f 2021.j -f 2022.j expr:'tag:start=2021 or not tag:start'- $ hledger bs -Y -f 2022.j -f 2023.j expr:'tag:start=2022 or not tag:start'- $ hledger bs -Y -f 2021.j expr:'tag:start=2021 or not tag:start'- $ hledger bs -Y -f 2022.j expr:'tag:start=2022 or not tag:start'- $ hledger bs -Y -f 2023.j # unclosed file, no query needed-- More detailed close examples- See examples/multi-year.-- 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:-- 2022/1/1 (123) Supermarket- Food $5.00- Checking-- 2022/1/2 (124) Post Office- Postage $8.32- Checking-- 2022/1/3 Supermarket- Food $11.23- Checking-- 2022/1/4 (126) Post Office- Postage $3.21- Checking-- $ hledger codes- 123- 124- 126-- $ hledger codes -E- 123- 124-- 126-- commodities- List all commodity/currency symbols used or declared in the journal.-- demo- Play demos of hledger usage in the terminal, if asciinema is installed.-- Run this command with no argument to list the demos. To play a demo,- write its number or a prefix or substring of its title. Tips:-- Make your terminal window large enough to see the demo clearly.-- Use the -s/--speed SPEED option to set your preferred playback speed,- eg -s4 to play at 4x original speed or -s.5 to play at half speed. The- default speed is 2x.-- Other asciinema options can be added following a double dash, eg --- -i.1 to limit pauses or -- -h to list asciinema's other options.-- During playback, several keys are available: SPACE to pause/unpause, .- to step forward (while paused), CTRL-c quit.-- Examples:-- $ hledger demo # list available demos- $ hledger demo 1 # play the first demo at default speed (2x)- $ hledger demo install -s4 # play the "install" demo at 4x speed-- 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- 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- List all files included in the journal. With a REGEX argument, only- file names matching the regular expression (case sensitive) are shown.-- help- Show the hledger user manual in the terminal, with info, man, or a- pager. With a TOPIC argument, open it at that topic if possible.- TOPIC can be any heading in the manual, or a heading prefix, case in-- sensitive. Eg: commands, print, forecast, journal, amount, "auto post-- ings".-- This command shows the hledger manual built in to your hledger version.- It can be useful when offline, or when you prefer the terminal to a web- browser, or when the appropriate hledger manual or viewing tools are- not installed on your system.-- By default it chooses the best viewer found in $PATH, trying (in this- order): info, man, $PAGER, less, more. You can force the use of info,- man, or a pager with the -i, -m, or -p flags, If no viewer can be- found, or the command is run non-interactively, it just prints the man-- ual to stdout.-- If using info, note that version 6 or greater is needed for TOPIC- lookup. If you are on mac you will likely have info 4.8, and should- consider installing a newer version, eg with brew install texinfo- (#1770).-- Examples-- $ hledger help --help # show how the help command works- $ hledger help # show the hledger manual with info, man or $PAGER- $ hledger help journal # show the journal topic in the hledger manual- $ hledger help -m journal # show it with man, even if info is installed-- import- Read new transactions added to each FILE provided as arguments since- last run, and add them to the journal. Or with --dry-run, just print- the transactions that would be added. Or with --catchup, just mark all- of the FILEs' current transactions as imported, without importing them.-- This command may append new transactions to the main journal file- (which should be in journal format). Existing transactions are not- changed. This is one of the few hledger commands that writes to the- journal file (see also add).-- Unlike other hledger commands, with import the journal file is an out-- 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- import tries to import only the transactions which are new since the- last import, ignoring any that it has seen in previous runs. So if- your bank's CSV includes the last three months of data, you can down-- load and import it every month (or week, or day) and only the new- transactions will be imported each time.-- It works as follows. For each imported FILE (usually CSV, but they- could be any of hledger's input formats):-- o It tries to recall the latest date seen previously, reading it from a- hidden .latest.FILE in the same directory.-- o Then it processes FILE, ignoring any transactions on or before the- "latest seen" date.-- And after a successful import, it updates the .latest.FILE(s) for next- time (unless --dry-run was used).-- This is a limited kind of deduplication, let's call it "date skipping".- Within each input file, it avoids reprocessing the same dates across- successive runs. This is a simple system that works for most- real-world CSV files; it assumes these are true, or true enough:-- 1. new items always have the newest dates-- 2. item dates are stable across successive downloads-- 3. the order of same-date items is stable across downloads-- 4. the name of the input file is stable across downloads-- If you have a bank whose CSV dates or ordering occasionally change, you- can reduce the chance of this happening in new transactions by import-- ing more often, and in old transactions it doesn't matter. And remem-- ber you can use CSV rules files as input, which is one way to ensure a- stable file name.-- import doesn't detect other kinds of duplication, such as duplicate- transactions within a single run. (In part, because legitimate dupli-- cate transactions can easily occur in real-world data.) So, say you- downloaded but forgot to import bank.1.csv, and a week later you down-- loaded bank.2.csv with overlapping data. Now you should not import- both of these at once (hledger import bank.1.csv bank.2.csv); the over-- lapping transactions which appear twice would not be deduplicated since- this is considered a single import. Instead, import these files one at- a time, and also use the same filename each time for a common "latest- seen" state:-- $ mv bank.1.csv bank.csv; hledger import bank.csv- $ mv bank.2.csv bank.csv; hledger import bank.csv-- Normally you can ignore the .latest.* files, but if needed, you can- delete them (to make all transactions unseen), or construct/modify them- (to catch up to a certain date). The format is just a single ISO-for-- mat date (YYYY-MM-DD), possibly repeated on multiple lines. It means- "I have seen transactions up to this date, and this many of them occur-- ring on that date".-- hledger print --new also uses and updates these .latest.* files, but it- is less often used.-- Related: CSV > Working with CSV > Deduplicating, importing.-- Import testing- With --dry-run, the transactions that will be imported are printed to- 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'-- Note: when importing from multiple files at once, it's currently possi-- ble for some .latest files to be updated successfully, while the actual- import fails because of a problem in one of the files, leaving them out- of sync (and causing some transactions to be missed). To prevent this,- do a --dry-run first and fix any problems before the real import.-- 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- (is)-- This command displays an income statement, showing revenues and ex-- penses during one or more periods. Amounts are shown with normal posi-- tive sign, as in conventional financial statements.-- This report shows accounts declared with the Revenue or Expense type- (see account types). Or if no such accounts are declared, it shows- top-level accounts named revenue or income or expense (case insensi-- tive, plurals allowed) and their subaccounts.-- Example:-- $ hledger incomestatement- Income Statement 2008-- || 2008- ===================++======- Revenues ||- -------------------++------- income:gifts || $1- income:salary || $1- -------------------++------- || $2- ===================++======- Expenses ||- -------------------++------- expenses:food || $1- expenses:supplies || $1- -------------------++------- || $2- ===================++======- Net: || 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 op-- tions The output formats supported are txt, csv, tsv (Added in 1.32),- html, and json.-- notes- List the unique notes that appear in transactions.-- This command lists the unique notes that appear in transactions, in al-- phabetic order. You can add a query to select a subset of transac-- tions. The note is the part of the transaction description after a |- character (or if there is no |, the whole description).-- Example:-- $ hledger notes- Petrol- Snacks-- payees- 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- Print the market prices declared with P directives. With --infer-mar-- ket-prices, also show any additional prices inferred from costs. With- --show-reverse, also show additional prices inferred by reversing known- prices.-- Price amounts are always displayed with their full precision, except- for reverse prices which are limited to 8 decimal digits.-- Prices can be filtered by a date:, cur: or amt: query.-- Generally if you run this command with --infer-market-prices --show-re-- verse, it will show the same prices used internally to calculate value- reports. But if in doubt, you can inspect those directly by running- the value report with --debug=2.-- 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).-- 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/regenerate your journal you should take care to also copy- over the directives and inter-transaction comments.-- Eg:-- $ hledger print -f examples/sample.journal date:200806- 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-- print explicitness- Normally, whether posting amounts are implicit or explicit is pre-- served. For example, when an amount is omitted in the journal, it will- not appear in the output. Similarly, if a conversion cost is implied- but not written, it will not appear in the output.-- You can use the -x/--explicit flag to force explicit display of all- amounts and costs. This can be useful for troubleshooting or for mak-- ing your journal more readable and robust against data entry errors.- -x is also implied by using any of -B,-V,-X,--value.-- The -x/--explicit flag will cause any postings with a multi-commodity- amount (which can arise when a multi-commodity transaction has an im-- plicit amount) to be split into multiple single-commodity postings,- keeping the output parseable.-- print amount style- Amounts are shown right-aligned within each transaction (but not- aligned across all transactions; you can do that with ledger-mode in- Emacs).-- Amounts will be (mostly) normalised to their commodity display style:- their symbol placement, decimal mark, and digit group marks will be- made consistent. By default, decimal digits are shown as they are- written in the journal.-- With the --round (Added in 1.32) option, print will try increasingly- hard to display decimal digits according to the commodity display- styles:-- o --round=none show amounts with original precisions (default)-- o --round=soft add/remove decimal zeros in amounts (except costs)-- o --round=hard round amounts (except costs), possibly hiding signifi-- cant digits-- o --round=all round all amounts and costs-- soft is good for non-lossy cleanup, formatting amounts more consis-- tently where it's safe to do so.-- hard and all can cause print to show invalid unbalanced journal en-- tries; they may be useful eg for stronger cleanup, with manual fixups- when needed.-- print parseability- 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 (though the same can be achieved with expr: queries- now):-- # 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 Value reporting affects posting amounts but not balance assertion or- balance assignment amounts, potentially causing those to fail.-- o Auto postings can generate postings with too many missing amounts.-- o Account aliases can generate bad account names.-- print, other features- With -B/--cost, amounts with costs are shown converted to cost.-- With --new, print shows only transactions it has not seen on a previous- run. This uses the same deduplication system as the import command.- (See import's docs for details.)-- With -m DESC/--match=DESC, print shows one recent transaction whose de-- scription is most similar to DESC. DESC should contain at least two- characters. If there is no similar-enough match, no transaction will- be shown and the program exit code will be non-zero.-- print output format- This command also supports the output destination and output format op-- tions The output formats supported are txt, beancount (Added in 1.32),- csv, tsv (Added in 1.32), json and sql.-- The beancount format tries to produce Beancount-compatible output, as- follows:-- o Transaction and postings with unmarked status are converted to- cleared (*) status.-- o Transactions' payee and note are backslash-escaped and dou-- ble-quote-escaped and wrapped in double quotes.-- o Transaction tags are copied to Beancount #tag format.-- o Commodity symbols are converted to upper case, and a small number of- currency symbols like $ are converted to the corresponding currency- names.-- o Account name parts are capitalised and unsupported characters are re-- placed with -. If an account name part does not begin with a letter,- or if the first part is not Assets, Liabilities, Equity, Income, or- Expenses, an error is raised. (Use --alias options to bring your ac-- counts into compliance.)-- o An open directive is generated for each account used, on the earliest- transaction date.-- Some limitations:-- o Balance assertions are removed.-- o Balance assignments become missing amounts.-- o Virtual and balanced virtual postings become regular postings.-- o Directives are not converted.-- 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.)-- 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.-- For performance reasons, column widths are chosen based on the first- 1000 lines; this means unusually wide values in later lines can cause- visual discontinuities as column widths are adjusted. If you want to- ensure perfect alignment, at the cost of more time and memory, use the- --align-all flag.-- The --historical/-H flag adds the balance from any undisplayed prior- postings to the running total. This is useful when you want to see- only recent activity, with a historically accurate running balance:-- $ hledger register checking -b 2008/6 --historical- 2008/06/01 gift assets:bank:checking $1 $2- 2008/06/02 save assets:bank:checking $-1 $1- 2008/12/31 pay off assets:bank:checking $-1 0-- The --depth option limits the amount of sub-account detail displayed.-- The --average/-A flag shows the running average posting amount instead- of the running total (so, the final number displayed is the average for- the whole report period). This flag implies --empty (see below). It- is affected by --historical. It works best when showing just one ac-- count and one commodity.-- The --related/-r flag shows the other postings in the transactions of- the postings which would normally be shown.-- The --invert flag negates all amounts. For example, it can be used on- an income account where amounts are normally displayed as negative num-- bers. It's also useful to show postings on the checking account to-- gether with the related account:-- $ hledger register --related --invert assets:checking-- With a reporting interval, register shows summary postings, one per in-- terval, aggregating the postings to each account:-- $ hledger register --monthly income- 2008/01 income:salary $-1 $-1- 2008/06 income:gifts $-1 $-2-- Periods with no activity, and summary postings with a zero amount, are- not shown by default; use the --empty/-E flag to see them:-- $ hledger register --monthly income -E- 2008/01 income:salary $-1 $-1- 2008/02 0 $-1- 2008/03 0 $-1- 2008/04 0 $-1- 2008/05 0 $-1- 2008/06 income:gifts $-1 $-2- 2008/07 0 $-2- 2008/08 0 $-2- 2008/09 0 $-2- 2008/10 0 $-2- 2008/11 0 $-2- 2008/12 0 $-2-- Often, you'll want to see just one line per interval. The --depth op-- tion helps with this, causing subaccounts to be aggregated:-- $ hledger register --monthly assets --depth 1h- 2008/01 assets $1 $1- 2008/06 assets $-1 0- 2008/12 assets $-1 $-1-- Note when using report intervals, if you specify start/end dates these- will be adjusted outward if necessary to contain a whole number of in-- tervals. This ensures that the first and last intervals are full- length and comparable to the others in the report.-- With -m DESC/--match=DESC, register does a fuzzy search for one recent- posting whose description is most similar to DESC. DESC should contain- at least two characters. If there is no similar-enough match, no post-- ing will be shown and the program exit code will be non-zero.-- Custom register output- register uses the full terminal width by default, except on windows.- You can override this by setting the COLUMNS environment variable (not- a bash shell variable) or by using the --width/-w option.-- The description and account columns normally share the space equally- (about half of (width - 40) each). You can adjust this by adding a de-- scription width as part of --width's argument, comma-separated: --width- W,D . Here's a diagram (won't display correctly in --help):-- <--------------------------------- width (W) ---------------------------------->- date (10) description (D) account (W-41-D) amount (12) balance (12)- DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA-- and some examples:-- $ hledger reg # use terminal width (or 80 on windows)- $ hledger reg -w 100 # use width 100- $ COLUMNS=100 hledger reg # set with one-time environment variable- $ export COLUMNS=100; hledger reg # set till session end (or window resize)- $ hledger reg -w 100,40 # set overall width 100, description width 40- $ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40-- This command also supports the output destination and output format op-- tions The output formats supported are txt, csv, tsv (Added in 1.32),- and json.-- rewrite- Print all transactions, rewriting the postings of matched transactions.- For now the only rewrite available is adding new postings, like print- --auto.-- This is a start at a generic rewriter of transaction entries. It reads- the default journal and prints the transactions, like print, but adds- one or more specified postings to any transactions matching QUERY. The- posting amounts can be fixed, or a multiplier of the existing transac-- tion's first posting amount.-- Examples:-- $ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'- $ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'- $ hledger-rewrite.hs -f rewrites.hledger-- rewrites.hledger may consist of entries like:-- = ^income amt:<0 date:2017- (liabilities:tax) *0.33 ; tax on income- (reserve:grocery) *0.25 ; reserve 25% for grocery- (reserve:) *0.25 ; reserve 25% for grocery-- Note the single quotes to protect the dollar sign from bash, and the- two spaces between account and amount.-- More:-- $ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...- $ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'- $ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'- $ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'-- Argument for --add-posting option is a usual posting of transaction- with an exception for amount specification. More precisely, you can- use '*' (star symbol) before the amount to indicate that that this is a- factor for an amount of original matched posting. If the amount in-- cludes a commodity name, the new posting amount will be in the new com-- modity; otherwise, it will be in the matched posting amount's commod-- ity.-- Re-write rules in a file- During the run this tool will execute so called "Automated Transac-- tions" found in any journal it process. I.e instead of specifying this- operations in command line you can put them in a journal file.-- $ rewrite-rules.journal-- Make contents look like this:-- = ^income- (liabilities:tax) *.33-- = expenses:gifts- budget:gifts *-1- assets:budget *1-- Note that '=' (equality symbol) that is used instead of date in trans-- actions you usually write. It indicates the query by which you want to- match the posting to add new ones.-- $ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal-- This is something similar to the commands pipeline:-- $ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \- | hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \- --add-posting 'assets:budget *1' \- > rewritten-tidy-output.journal-- It is important to understand that relative order of such entries in- journal is important. You can re-use result of previously added post-- ings.-- Diff output format- To use this tool for batch modification of your journal files you may- find useful output in form of unified diff.-- $ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'-- Output might look like:-- --- /tmp/examples/sample.journal- +++ /tmp/examples/sample.journal- @@ -18,3 +18,4 @@- 2008/01/01 income- - assets:bank:checking $1- + assets:bank:checking $1- income:salary- + (liabilities:tax) 0- @@ -22,3 +23,4 @@- 2008/06/01 gift- - assets:bank:checking $1- + assets:bank:checking $1- income:gifts- + (liabilities:tax) 0-- If you'll pass this through patch tool you'll get transactions contain-- ing the posting that matches your query be updated. Note that multiple- files might be update according to list of input files specified via- --file options and include directives inside of these files.-- Be careful. Whole transaction being re-formatted in a style of output- from hledger print.-- See also:-- https://github.com/simonmichael/hledger/issues/99-- rewrite vs. print --auto- This command predates print --auto, and currently does much the same- thing, but with these differences:-- o with multiple files, rewrite lets rules in any file affect all other- files. print --auto uses standard directive scoping; rules affect- only child files.-- o rewrite's query limits which transactions can be rewritten; all are- printed. print --auto's query limits which transactions are printed.-- o rewrite applies rules specified on command line or in the journal.- print --auto applies rules specified in the journal.-- roi- 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 ac-- count 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, also known as money-weighted rate of return) and time-weighted- rate of return (TWR) for your investments for the time period re-- quested. IRR is always annualized due to the way it is computed, but- TWR is reported both as a rate over the chosen reporting period and as- an annual rate.-- Price directives will be taken into account if you supply appropriate- --cost or --value flags (see VALUATION).-- Note, in some cases this report can fail, for these reasons:-- o Error (NotBracketed): No solution for Internal Rate of Return (IRR).- Possible causes: IRR is huge (>1000000%), balance of investment be-- comes negative at some point in time.-- o Error (SearchFailed): Failed to find solution for Internal Rate of- Return (IRR). Either search does not converge to a solution, or con-- verges too slowly.-- Examples:-- o Using roi to compute total return of investment in stocks:- https://github.com/simonmichael/hledger/blob/master/examples/invest-- ing/roi-unrealised.ledger-- o Cookbook > Return on Investment: https://hledger.org/roi.html-- 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 as-- sets, 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 re-- turn.-- 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, and the- time between them. Investment at a particular fixed interest rate is- going to give you more interest than the same amount invested at the- same interest rate, but made later in time. If you are withdrawing- from your investment, your future gains would be smaller (in absolute- numbers), and will be a smaller percentage of your initial investment,- so your IRR will be smaller. And if you are adding to your investment,- you will receive bigger absolute gains, which will be a bigger percent-- age of your initial investment, so your IRR will be larger.-- 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 ac-- count for the effect of your in-flows and out-flows, but unlike IRR it- will try to compute the true rate of return of the underlying asset,- compensating for the effect that deposits and withdrawas have on the- apparent rate of growth of your investment.-- TWR represents your investment as an imaginary "unit fund" where- in-flows/ out-flows lead to buying or selling "units" of your invest-- ment and changes in its value change the value of "investment unit".- Change in "unit price" over the reporting period gives you rate of re-- turn of your investment, and make TWR less sensitive than IRR to the- effects of cash in-flows and out-flows.-- References:-- o Explanation of rate of return-- o Explanation of IRR-- o Explanation of TWR-- o IRR vs TWR-- o Examples of computing IRR and TWR and discussion of the limitations- of both metrics-- stats- Show journal and performance statistics.-- The stats command shows summary information for the whole journal, or a- matched part of it. With a reporting interval, it shows a report for- each report period.-- The default output is fairly impersonal, though it reveals the main- file name. With -v/--verbose, more details are shown, like file paths,- included files, and commodity names.-- It also shows some run time statistics:-- o elapsed time-- o throughput: the number of transactions processed per second-- o live: the peak memory in use by the program to do its work-- o alloc: the peak memory allocation from the OS as seen by GHC. Mea-- suring this externally, eg with GNU time, is more accurate; usually- that will be a larger number; sometimes (with swapping?) smaller.-- The stats command's run time is similar to that of a balance report.-- Example:-- $ hledger stats -f examples/1ktxns-1kaccts.journal- Main file : .../1ktxns-1kaccts.journal- Included files : 0- Txns span : 2000-01-01 to 2002-09-27 (1000 days)- Last txn : 2002-09-26 (7827 days ago)- Txns : 1000 (1.0 per day)- Txns last 30 days : 0 (0.0 per day)- Txns last 7 days : 0 (0.0 per day)- Payees/descriptions : 1000- Accounts : 1000 (depth 10)- Commodities : 26- Market prices : 1000- Runtime stats : 0.12 s elapsed, 8266 txns/s, 4 MB live, 16 MB alloc-- This command supports the -o/--output-file option (but not -O/--out-- put-format).-- tags- List the tags used in the journal, or their values.-- This command lists the tag names used in the journal, whether on trans-- actions, postings, or account declarations.-- With a TAGREGEX argument, only tag names matching this regular expres-- sion (case insensitive, infix matched) are shown.-- With QUERY arguments, only transactions and accounts matching this- query are considered. If the query involves transaction fields (date:,- desc:, amt:, ...), the search is restricted to the matched transactions- and their accounts.-- With the --values flag, the tags' unique non-empty values are listed- instead. With -E/--empty, blank/empty values are also shown.-- With --parsed, tags or values are shown in the order they were parsed,- with duplicates included. (Except, tags from account declarations are- always shown first.)-- Tip: remember, accounts also acquire tags from their parents, postings- also acquire tags from their account and transaction, transactions also- acquire tags from their postings.-- 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).--PART 5: COMMON TASKS- Here are some quick examples of how to do some basic tasks with- hledger.-- Getting help- Here's how to list commands and view options and command docs:-- $ hledger # show available commands- $ hledger --help # show common options- $ hledger CMD --help # show CMD's options, common options and CMD's documentation-- You can also view your hledger version's manual in several formats by- using the help command. Eg:-- $ hledger help # show the hledger manual with info, man or $PAGER (best available)- $ hledger help journal # show the journal topic in the hledger manual- $ hledger help --help # find out more about the help command-- To view manuals and introductory docs on the web, visit- https://hledger.org. Chat and mail list support and discussion- archives can be found at https://hledger.org/support.-- Constructing command lines- hledger has a flexible command line interface. We strive to keep it- simple and ergonomic, but if you run into one of the sharp edges de-- scribed in OPTIONS, here are some tips that might help:-- o command-specific options must go after the command (it's fine to put- common options there too: 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 line 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- (see below). 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 2023.journal- $ echo "export LEDGER_FILE=$HOME/finance/2023.journal" >> ~/.profile- $ source ~/.profile- $ hledger stats- Main file : /Users/simon/finance/2023.journal- Included files :- Transactions span : to (0 days)- Last transaction : none- Transactions : 0 (0.0 per day)- Transactions last 30 days: 0 (0.0 per day)- Transactions last 7 days : 0 (0.0 per day)- Payees/descriptions : 0- Accounts : 0 (depth 0)- Commodities : 0 ()- Market prices : 0 ()-- Setting LEDGER_FILE- How to set LEDGER_FILE permanently depends on your setup:-- On unix and mac, running these commands in the terminal will work for- many people; adapt as needed:-- $ echo 'export LEDGER_FILE=~/finance/2023.journal' >> ~/.profile- $ source ~/.profile-- When correctly configured, in a new terminal window env | grep- LEDGER_FILE will show your file, and so will hledger files.-- On mac, this additional step might be helpful for GUI applications- (like Emacs started from the dock): add an entry to ~/.MacOSX/environ-- ment.plist like-- {- "LEDGER_FILE" : "~/finance/2023.journal"- }-- and then run killall Dock in a terminal window (or restart the ma-- chine).-- On Windows, see https://www.java.com/en/download/help/path.html, or try- running these commands in a powershell window (let us know if it per-- sists across a reboot, and if you need to be an Administrator):-- > CD- > MKDIR finance- > SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal"-- Setting opening balances- Pick a starting date for which you can look up the balances of some- real-world assets (bank accounts, wallet..) and liabilities (credit- cards..).-- To avoid a lot of data entry, you may want to start with just one or- two accounts, like your checking account or cash wallet; and pick a re-- cent starting date, like today or the start of the week. You can al-- ways come back later and add more accounts and older transactions, eg- going back to january 1st.-- Add an opening balances transaction to the journal, declaring the bal-- ances on this date. Here are two ways to do it:-- o The first way: open the journal in any text editor and save an entry- like this:-- 2023-01-01 * opening balances- assets:bank:checking $1000 = $1000- assets:bank:savings $2000 = $2000- assets:cash $100 = $100- liabilities:creditcard $-50 = $-50- equity:opening/closing balances-- 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/2023.journal- Any command line arguments will be used as defaults.- Use tab key to complete, readline keys to edit, enter to accept defaults.- An optional (CODE) may follow transaction dates.- An optional ; COMMENT may follow descriptions or amounts.- If you make a mistake, enter < at any prompt to go one step backward.- To end a transaction, enter . when prompted.- To quit, enter . at a date prompt or press control-d or control-c.- Date [2023-02-07]: 2023-01-01- Description: * opening balances- Account 1: assets:bank:checking- Amount 1: $1000- Account 2: assets:bank:savings- Amount 2 [$-1000]: $2000- Account 3: assets:cash- Amount 3 [$-3000]: $100- Account 4: liabilities:creditcard- Amount 4 [$-3100]: $-50- Account 5: equity:opening/closing balances- Amount 5 [$-3050]:- Account 6 (or . or enter to finish this transaction): .- 2023-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050-- Save this transaction to the journal ? [y]:- Saved.- Starting the next transaction (. or ctrl-D/ctrl-C to quit)- Date [2023-01-01]: .-- If you're using version control, this could be a good time to commit- the journal. Eg:-- $ git commit -m 'initial balances' 2023.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:-- 2023/1/10 * gift received- assets:cash $20- income:gifts-- 2023.1.12 * farmers market- expenses:food $13- assets:cash-- 2023-01-15 paycheck- income:salary- assets:bank:checking $1000-- Reconciling- Periodically you should reconcile - compare your hledger-reported bal-- ances against external sources of truth, like bank statements or your- bank's website - to be sure that your ledger accurately represents the- real-world balances (and, that the real-world institutions have not- made a mistake!). This gets easy and fast with (1) practice and (2)- frequency. If you do it daily, it can take 2-10 minutes. If you let- it pile up, expect it to take longer as you hunt down errors and dis-- crepancies.-- A typical workflow:-- 1. Reconcile cash. Count what's in your wallet. Compare with what- hledger reports (hledger bal cash). If they are different, try to- remember the missing transaction, or look for the error in the al-- ready-recorded transactions. A register report can be helpful- (hledger reg cash). If you can't find the error, add an adjustment- transaction. Eg if you have $105 after the above, and can't explain- the missing $2, it could be:-- 2023-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- 2. Reconcile checking. Log in to your bank's website. Compare today's- (cleared) balance with hledger's cleared balance (hledger bal check-- ing -C). If they are different, track down the error or record the- missing transaction(s) or add an adjustment transaction, similar to- the above. Unlike the cash case, you can usually compare the trans-- action history and running balance from your bank with the one re-- ported by hledger reg checking -C. This will be easier if you gen-- erally record transaction dates quite similar to your bank's clear-- ing dates.-- 3. Repeat for other asset/liability accounts.-- Tip: instead of the register command, use hledger-ui to see a live-up-- dating register while you edit the journal: hledger-ui --watch --regis-- ter checking -C-- After reconciling, it could be a good time to mark the reconciled- transactions' status as "cleared and confirmed", if you want to track- that, by adding the * marker. Eg in the paycheck transaction above,- insert * between 2023-01-15 and paycheck-- If you're using version control, this can be another good time to com-- mit:-- $ git commit -m 'txns' 2023.journal-- Reporting- Here are some basic reports.-- Show all transactions:-- $ hledger print- 2023-01-01 * opening balances- assets:bank:checking $1000- assets:bank:savings $2000- assets:cash $100- liabilities:creditcard $-50- equity:opening/closing balances $-3050-- 2023-01-10 * gift received- assets:cash $20- income:gifts-- 2023-01-12 * farmers market- expenses:food $13- assets:cash-- 2023-01-15 * paycheck- income:salary- assets:bank:checking $1000-- 2023-01-16 * adjust cash- assets:cash $-2 = $105- expenses:misc-- 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 -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 -2- Balance Sheet 2023-01-16-- || 2023-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 2023-01-01-2023-01-16-- || 2023-01-01-2023-01-16- ===============++=======================- Revenues ||- ---------------++------------------------ income:gifts || $20- income:salary || $1000- ---------------++------------------------ || $1020- ===============++=======================- Expenses ||- ---------------++------------------------ expenses:food || $13- expenses:misc || $2- ---------------++------------------------ || $15- ===============++=======================- Net: || $1005-- The final total is your net income during this period.-- Show transactions affecting your wallet, with running total:-- $ hledger register cash- 2023-01-01 opening balances assets:cash $100 $100- 2023-01-10 gift received assets:cash $20 $120- 2023-01-12 farmers market assets:cash $-13 $107- 2023-01-16 adjust cash assets:cash $-2 $105-- Show weekly posting counts as a bar chart:-- $ hledger activity -W- 2019-12-30 *****- 2023-01-06 ****- 2023-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.--BUGS- We welcome bug reports in the hledger issue tracker (shortcut:- http://bugs.hledger.org), or on the #hledger chat or hledger mail list- (https://hledger.org/support).-- Some known issues and limitations:-- The need to precede add-on command options with -- when invoked from- hledger is awkward. (See Command options, Constructing command lines.)-- A UTF-8-aware system locale must be configured to work with non-ascii- data. (See Unicode characters, Troubleshooting.)-- On Microsoft Windows, depending whether you are running in a CMD window- or a Cygwin/MSYS/Mintty window and how you installed hledger, non-ascii- characters and colours may not be supported, and the tab key may not be- supported by hledger add. (Running in a WSL window should resolve- these.)-- When processing large data files, hledger uses more memory than Ledger.-- Troubleshooting- Here are some common issues you might encounter when you run hledger,- and how to resolve them (and remember also you can usually get quick- Support):-- PATH issues: I get an error like "No command 'hledger' found"- Depending how you installed hledger, the executables may not be in your- shell's PATH. Eg on unix systems, stack installs hledger in ~/.lo-- cal/bin and cabal installs it in ~/.cabal/bin. You may need to add one- of these directories to your shell's PATH, and/or open a new terminal- window.-- LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not using- it- o LEDGER_FILE should be a real environment variable, not just a shell- variable. Eg on unix, the command env | grep LEDGER_FILE should show- it. You may need to use export (see https://stackover-- flow.com/a/7411509).-- o You may need to force your shell to see the new configuration. A- simple way is to close your terminal window and open a new one.-- LANG issues: I get errors like "Illegal byte sequence" or "Invalid or- incomplete multibyte or wide character" or "commitAndReleaseBuffer: in-- valid argument (invalid character)"- Programs compiled with GHC (hledger, haskell build tools, etc.) need- the system locale to be UTF-8-aware, or they will fail when they en-- counter non-ascii characters. To fix it, set the LANG environment- variable to a locale which supports UTF-8 and which is installed on- your system.-- On unix, locale -a lists the installed locales. Look for one which- mentions utf8, UTF-8 or similar. Some examples: C.UTF-8, en_US.utf-8,- fr_FR.utf8. If necessary, use your system package manager to install- one. Then select it by setting the LANG environment variable. Note,- exact spelling and capitalisation of the locale name may be important:- Here's one common way to configure this permanently for your shell:-- $ echo "export LANG=en_US.utf8" >>~/.profile- # close and re-open terminal window-- If you are using Nix (not NixOS) for GHC and Hledger, you might need to- set the LOCALE_ARCHIVE variable:-- $ echo "export LOCALE_ARCHIVE=${glibcLocales}/lib/locale/locale-archive" >>~/.profile- # close and re-open terminal window-- COMPATIBILITY ISSUES: hledger gives an error with my Ledger file- Not all of Ledger's journal file syntax or feature set is supported.- See hledger and Ledger for full details.----AUTHORS- Simon Michael <simon@joyful.com> and contributors.- See http://hledger.org/CREDITS.html---COPYRIGHT- Copyright 2007-2023 Simon Michael and contributors.---LICENSE- Released under GNU GPL v3 or later.---SEE ALSO- hledger(1), hledger-ui(1), hledger-web(1), ledger(1)--hledger-1.33 April 2024 HLEDGER(1)+ This manual is for hledger's command line interface, version 1.33.1.+ It also describes the common options, file formats and concepts used by+ all hledger programs. It might accidentally teach you some bookkeep-+ ing/accounting as well! You don't need to know everything in here to+ use hledger productively, but when you have a question about function-+ ality, this doc should answer it. It is detailed, so do skip ahead or+ skim when needed. You can read it on hledger.org, or as an info manual+ or man page on your system. You can also get it from hledger itself+ with+ hledger --man, hledger --info or hledger help [TOPIC].++ The main function of the hledger CLI is to read plain text files de-+ scribing financial transactions, crunch the numbers, and print a useful+ report on the terminal (or save it as HTML, CSV, JSON or SQL). Many+ reports are available, as subcommands. hledger will also detect other+ hledger-* executables as extra subcommands.++ hledger usually reads from (and appends to) a journal file specified by+ the LEDGER_FILE environment variable (defaulting to+ $HOME/.hledger.journal); or you can specify files with -f options. It+ can also read timeclock files, timedot files, or any CSV/SSV/TSV file+ with a date field.++ Here is a small journal file describing one transaction:++ 2015-10-16 bought food+ expenses:food $10+ assets:cash++ Transactions are dated movements of money (etc.) between two or more+ accounts: bank accounts, your wallet, revenue/expense categories, peo-+ ple, etc. You can choose any account names you wish, using : to indi-+ cate subaccounts. There must be at least two spaces between account+ name and amount. Positive amounts are inflow to that account (debit),+ negatives are outflow from it (credit). (Some reports show revenue,+ liability and equity account balances as negative numbers as a result;+ this is normal.)++ hledger's add command can help you add transactions, or you can install+ other data entry UIs like hledger-web or hledger-iadd. For more exten-+ sive/efficient changes, use a text editor: Emacs + ledger-mode, VIM ++ vim-ledger, or VS Code + hledger-vscode are some good choices (see+ https://hledger.org/editors.html).++ To get started, run hledger add and follow the prompts, or save some+ entries like the above in $HOME/.hledger.journal, then try commands+ like:++ $ hledger print -x+ $ hledger aregister assets+ $ hledger balance+ $ hledger balancesheet+ $ hledger incomestatement++ Run hledger to list the commands. See also the "Starting a journal+ file" and "Setting opening balances" sections in PART 5: COMMON TASKS.++PART 1: USER INTERFACE+Input+ hledger reads one or more data files, each time you run it. You can+ specify a file with -f, like so++ $ hledger -f FILE print++ Files are most often in hledger's journal format, with the .journal+ file extension (.hledger or .j also work); these files describe trans-+ actions, like an accounting general journal.++ When no file is specified, hledger looks for .hledger.journal in your+ home directory.++ But most people prefer to keep financial files in a dedicated folder,+ perhaps with version control. Also, starting a new journal file each+ year is common (it's not required, but helps keep things fast and or-+ ganised). So we usually configure a different journal file, by setting+ the LEDGER_FILE environment variable, to something like ~/fi-+ nance/2023.journal. For more about how to do that on your system, see+ Common tasks > Setting LEDGER_FILE.++ Text encoding+ Data files containing non-ascii characters must use UTF-8 encoding. An+ optional byte order mark (BOM) is allowed, at the beginning of the file+ (only).++ Also, your system should be configured with a locale that can decode+ UTF-8 text. On some unix systems, you may need set the LANG environ-+ ment variable, eg. You can read more about this in Unicode characters,+ below.++ On unix systems you can check a file's encoding with the file command.+ If you need to import from a UTF-16-encoded CSV file, say, you can con-+ vert it to UTF-8 with the iconv command.++ 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: Automatically used for+ files with extensions:+ -----------------------------------------------------------------------------+ journal hledger journal files and some .journal .j .hledger+ Ledger journals, for transactions .ledger+ timeclock timeclock files, for precise time .timeclock+ logging+ timedot timedot files, for approximate .timedot+ time logging+ csv Comma or other character sepa- .csv+ rated values, for data import+ ssv Semicolon separated values .ssv+ tsv Tab separated values .tsv+ rules CSV/SSV/TSV/other separated val- .rules+ ues, alternate way++ These formats are described in more detail below.++ hledger detects the format automatically based on the file extensions+ shown above. If it can't recognise the file extension, it assumes+ journal format. So for non-journal files, it's important to use a+ 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 containing tab+ separated values:++ $ hledger -f tsv:/some/file.dat stats++ Standard input+ The file name - means standard input:++ $ cat FILE | hledger -f- print++ If reading non-journal data in this way, you'll need to add a file for-+ mat prefix, like:++ $ echo 'i 2009/13/1 08:00:00' | hledger print -f timeclock:-++ Multiple files+ You can specify multiple -f options, to read multiple files as one big+ journal. When doing this, note that certain features (described below)+ will be affected:++ o Balance assertions will not see the effect of transactions in previ-+ ous files. (Usually this doesn't matter as each file will set the+ corresponding opening balances.)++ o Some directives will not affect previous or subsequent files.++ If needed, you can work around these by using a single parent file+ which includes the others, or concatenating the files into one, 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 use the check command to run individual checks -- the ones+ listed above and some more.++Commands+ hledger provides various subcommands for getting things done. Most of+ these commands do not change the journal file; they just read it and+ output a report. A few commands assist with adding data and file man-+ agement.++ To show the commands list, run hledger with no arguments. The commands+ are described in detail in PART 4: COMMANDS, below.++ To use a particular command, run hledger CMD [CMDOPTS] [CMDARGS],++ o CMD is the full command name, or its standard abbreviation shown in+ the commands list, or any unambiguous prefix of the name.++ o CMDOPTS are command-specific options, if any. Command-specific op-+ tions must be written after the command name. Eg: hledger print -x.++ o CMDARGS are additional arguments to the command, if any. Most+ hledger commands accept arguments representing a query, to limit the+ data in some way. Eg: hledger reg assets:checking.++ To list a command's options, arguments, and documentation in the termi-+ nal, run hledger CMD -h. Eg: hledger bal -h.++ Add-on commands+ In addition to the built-in commands, you can install add-on commands:+ programs or scripts named "hledger-SOMETHING", which will also appear+ in hledger's commands list. If you used the hledger-install script,+ you will have several add-ons installed already. Some more can be+ found in hledger's bin/ directory, documented at+ https://hledger.org/scripts.html.++ More precisely, add-on commands are programs or scripts in your shell's+ PATH, whose name starts with "hledger-" and ends with no extension or a+ recognised extension (".bat", ".com", ".exe", ".hs", ".js", ".lhs",+ ".lua", ".php", ".pl", ".py", ".rb", ".rkt", or ".sh"), and (on unix+ and mac) which has executable permission for the current user.++ You can run add-on commands using hledger, much like built-in commands:+ hledger ADDONCMD [-- ADDONCMDOPTS] [ADDONCMDARGS]. But note the double+ hyphen argument, required before add-on-specific options. Eg: hledger+ ui -- --watch or hledger web -- --serve. If this causes difficulty,+ you can always run the add-on directly, without using hledger:+ hledger-ui --watch or hledger-web --serve.++Options+ Run hledger -h to see general command line help, and general options+ which are common to most hledger commands. These options can be writ-+ ten anywhere on the command line. They can be grouped into help, in-+ put, and reporting options:++ 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++ --pivot FIELDNAME+ use some other field or tag for the account name++ -I --ignore-assertions+ disable balance assertion checks (note: does not disable balance+ assignments)++ -s --strict+ do extra error checking (check that all posted accounts are de-+ clared)++ General reporting options+ -b --begin=DATE+ include postings/txns on or after this date (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 ef-+ fects)++ --today=DATE+ override today's date (affects relative smart dates, for+ tests/examples)++ -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-equity+ infer conversion equity postings from costs++ --infer-costs+ infer costs from conversion equity postings++ --infer-market-prices+ use costs as additional market prices, as if they were P direc-+ tives++ --forecast+ generate transactions from periodic rules, between the latest+ recorded txn and 6 months from today, or during the specified+ PERIOD (= is required). Auto posting rules will be applied to+ these transactions as well. Also, in hledger-ui make fu-+ ture-dated transactions visible.++ --auto generate extra postings by applying auto posting rules to all+ txns (not just forecast txns)++ --verbose-tags+ add visible tags indicating transactions or postings which have+ been generated/modified++ --commodity-style+ Override the commodity style in the output for the specified+ commodity. For example 'EUR1.000,00'.++ --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.++ --pretty[=WHEN]+ Show prettier output, e.g. using unicode box-drawing charac-+ ters. Accepts 'yes' (the default) or 'no' ('y', 'n', 'always',+ 'never' also work). If you provide an argument you must use+ '=', e.g. '--pretty=yes'.++ 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 line tips+ Here are some details useful to know about for hledger command lines+ (and elsewhere). Feel free to skip this section until you need it.++ Option repetition+ If options are repeated in a command line, hledger will generally use+ the last (right-most) occurence.++ Special characters+ Single escaping (shell metacharacters)+ In shell command lines, characters significant to your shell - such as+ spaces, <, >, (, ), |, $ and \ - should be "shell-escaped" if you want+ hledger to see them. This is done by enclosing them in single or dou-+ ble quotes, or by writing a backslash before them. Eg to match an ac-+ count 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 be-+ low), one level of shell-escaping is lost from any options or arguments+ intended for by the add-on command, so those need an extra level of+ shell-escaping. Eg to match a literal $ sign while using the bash+ shell and running an add-on command (ui):++ $ hledger ui cur:'\\$'++ or:++ $ hledger ui cur:\\\\$++ If you wondered why four backslashes, perhaps this helps:++ unescaped: $+ escaped: \$+ double-escaped: \\$+ triple-escaped: \\\\$++ Or, you can avoid the extra escaping by running the add-on executable+ directly:++ $ hledger-ui cur:\\$++ Less escaping+ Options and arguments are sometimes used in places other than the shell+ command line, where shell-escaping is not needed, so there you should+ use one less level of escaping. Those places include:++ o an @argumentfile++ o hledger-ui's filter field++ o hledger-web's search form++ o GHCI's prompt (used by developers).++ Unicode characters+ hledger is expected to handle non-ascii characters correctly:++ o they should be parsed correctly in input files and on the command+ line, by all hledger tools (add, iadd, hledger-web's search/add/edit+ forms, etc.)++ o they should be displayed correctly by all hledger tools, and+ on-screen alignment should be preserved.++ This requires a well-configured environment. Here are some tips:++ o A system locale must be configured, and it must be one that can de-+ code the characters being used. In bash, you can set a locale like+ this: export LANG=en_US.UTF-8. There are some more details in Trou-+ bleshooting. This step is essential - without it, hledger will quit+ on encountering a non-ascii character (as with all GHC-compiled pro-+ grams).++ o your terminal software (eg Terminal.app, iTerm, CMD.exe, xterm..)+ must support unicode++ o the terminal must be using a font which includes the required unicode+ glyphs++ o the terminal should be configured to display wide characters as dou-+ ble width (for report alignment)++ o on Windows, for best results you should run hledger in the same kind+ of environment in which it was built. Eg hledger built in the stan-+ dard CMD.EXE environment (like the binaries on our download page)+ might show display problems when run in a cygwin or msys terminal,+ and vice versa. (See eg #961).++ Regular expressions+ A regular expression (regexp) is a small piece of text where certain+ characters (like ., ^, $, +, *, (), |, [], \) have special meanings,+ forming a tiny language for matching text precisely - very useful in+ hledger and elsewhere. To learn all about them, visit regular-expres-+ sions.info.++ hledger supports regexps whenever you are entering a pattern to match+ something, eg in query arguments, account aliases, CSV if rules,+ hledger-web's search form, hledger-ui's / search, etc. You may need to+ wrap them in quotes, especially at the command line (see Special char-+ acters above). Here are some examples:++ Account name queries (quoted for command line use):++ Regular expression: Matches:+ ------------------- ------------------------------------------------------------+ bank assets:bank, assets:bank:savings, expenses:art:banksy, ...+ :bank assets:bank:savings, expenses:art:banksy+ :bank: assets:bank:savings+ '^bank' none of those ( ^ matches beginning of text )+ 'bank$' assets:bank ( $ matches end of text )+ 'big \$ bank' big $ bank ( \ disables following character's special meaning )+ '\bbank\b' assets:bank, assets:bank:savings ( \b matches word boundaries )+ '(sav|check)ing' saving or checking ( (|) matches either alternative )+ 'saving|checking' saving or checking ( outer parentheses are not needed )+ 'savings?' saving or savings ( ? matches 0 or 1 of the preceding thing )+ 'my +bank' my bank, my bank, ... ( + matches 1 or more of the preceding thing )+ 'my *bank' mybank, my bank, my bank, ... ( * matches 0 or more of the preceding thing )+ 'b.nk' bank, bonk, b nk, ... ( . matches any character )++ Some other queries:++ desc:'amazon|amzn|audible' Amazon transactions+ cur:EUR amounts with commodity symbol containing EUR+ cur:'\$' amounts with commodity symbol containing $+ cur:'^\$$' only $ amounts, not eg AU$ or CA$+ cur:....? amounts with 4-or-more-character symbols+ tag:.=202[1-3] things with any tag whose value contains 2021, 2022 or 2023++ Account name aliases: accept . instead of : as account separator:++ alias /\./=: replaces all periods in account names with colons++ Show multiple top-level accounts combined as one:++ --alias='/^[^:]+/=combined' ( [^:] matches any character other than : )++ Show accounts with the second-level part removed:++ --alias '/^([^:]+):[^:]+/ = \1'+ match a top-level account and a second-level account+ and replace those with just the top-level account+ ( \1 in the replacement text means "whatever was matched+ by the first parenthesised part of the regexp"++ CSV rules: match CSV records containing dining-related MCC codes:++ if \?MCC581[124]++ Match CSV records with a specific amount around the end/start of month:++ if %amount \b3\.99+ & %date (29|30|31|01|02|03)$++ hledger's regular expressions+ 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. backreferences are supported when doing text replacement in account+ aliases or CSV rules, where backreferences can be used in the re-+ placement string to reference capturing groups in the search regexp.+ Otherwise, if you write \1, it will match the digit 1.++ 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.++ Argument files+ You can save a set of command line options and arguments in a file, and+ then reuse them by writing @FILENAME as a command line argument. Eg:+ hledger bal @foo.args.++ Inside the argument file, each line should contain just one option or+ argument. Don't use spaces except inside quotes (or you'll see a con-+ fusing error); write = (or nothing) between a flag and its argument.+ For the special characters mentioned above, use one less level of quot-+ ing than you would at the command prompt.++Output+ Output destination+ hledger commands send their output to the terminal by default. You can+ of course redirect this, eg into a file, using standard shell syntax:++ $ hledger print > foo.txt++ Some commands (print, register, stats, the balance commands) also pro-+ vide the -o/--output-file option, which does the same thing without+ needing the shell. Eg:++ $ hledger print -o foo.txt+ $ hledger print -o - # write to stdout (the default)++ Output format+ Some commands offer other kinds of output, not just text on the termi-+ nal. Here are those commands and the formats currently supported:++ - txt csv/tsv html json sql+ --------------------------------------------------------------------------------------+ aregister Y Y Y Y+ balance Y 1 Y 1 Y 1,2 Y+ balancesheet Y 1 Y 1 Y 1 Y+ balancesheete- Y 1 Y 1 Y 1 Y+ quity+ cashflow Y 1 Y 1 Y 1 Y+ incomestatement Y 1 Y 1 Y 1 Y+ print Y Y Y Y+ register Y Y Y++ o 1 Also affected by the balance commands' --layout option.++ o 2 balance does not support html output without a report interval or+ with --budget.++ The output format is selected by the -O/--output-format=FMT option:++ $ hledger print -O csv # print CSV on stdout++ or by the filename extension of an output file specified with the+ -o/--output-file=FILE.FMT option:++ $ hledger balancesheet -o foo.csv # write CSV to foo.csv++ The -O option can be combined with -o to override the file extension,+ if needed:++ $ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt++ Some notes about the various output formats:++ CSV output+ o In CSV output, digit group marks (such as thousands separators) are+ disabled automatically.++ HTML output+ o HTML output can be styled by an optional hledger.css file in the same+ directory.++ JSON output+ o This is not yet much used; real-world feedback is welcome.++ o Our JSON is rather large and verbose, since it is a faithful repre-+ sentation of hledger's internal data types. To understand the JSON,+ read the Haskell type definitions, which are mostly in+ https://github.com/simonmichael/hledger/blob/mas-+ ter/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)++ SQL output+ o This is not yet much used; real-world feedback is welcome.++ o SQL output is expected to work at least with SQLite, MySQL and Post-+ gres.++ o For SQLite, it will be more useful if you modify the generated id+ field to be a PRIMARY KEY. Eg:++ $ hledger print -O sql | sed 's/id serial/id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL/g' | ...++ 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.++ Commodity styles+ When displaying amounts, hledger infers a standard display style for+ each commodity/currency, as described below in Commodity display style.++ If needed, this can be overridden by a -c/--commodity-style option (ex-+ cept for cost amounts and amounts displayed by the print command, which+ are always displayed with all decimal digits). For example, the fol-+ lowing will force dollar amounts to be displayed as shown:++ $ hledger print -c '$1.000,0'++ This option can repeated to set the display style for multiple commodi-+ ties/currencies. Its argument is as described in the commodity direc-+ tive.++ In some cases hledger will adjust number formatting to improve their+ parseability (such as adding trailing decimal marks when needed).++ Colour+ In terminal output, some commands can produce colour when the terminal+ supports it:++ o if the --color/--colour option is given a value of yes or always (or+ no or never), colour will (or will not) be used;++ o otherwise, if the NO_COLOR environment variable is set, colour will+ not be used;++ o otherwise, colour will be used if the output (terminal or file) sup-+ ports it.++ Box-drawing+ In terminal output, you can enable unicode box-drawing characters to+ render prettier tables:++ o if the --pretty option is given a value of yes or always (or no or+ never), unicode characters will (or will not) be used;++ o otherwise, unicode characters will not be used.++ Paging+ When showing long output in the terminal, hledger will try to use the+ pager specified by the PAGER environment variable, or less, or more.+ (A pager is a helper program that shows one page at a time rather than+ scrolling everything off screen). Currently it does this only for help+ output, not for reports; specifically,++ o when listing commands, with hledger++ o when showing help with hledger [CMD] --help,++ o when viewing manuals with hledger help or hledger --man.++ Note the pager is expected to handle ANSI codes, which hledger uses eg+ for bold emphasis. For the common pager less (and its more compatibil-+ ity mode), we add R to the LESS and MORE environment variables to make+ this work. If you use a different pager, you might need to configure+ it similarly, to avoid seeing junk on screen (let us know). Otherwise,+ you can set the NO_COLOR environment variable to 1 to disable all ANSI+ output (see Colour).++ Debug output+ We intend hledger to be relatively easy to troubleshoot, introspect and+ develop. You can add --debug[=N] to any hledger command line to see+ additional debug output. N ranges from 1 (least output, the default)+ to 9 (maximum output). Typically you would start with 1 and increase+ until you are seeing enough. Debug output goes to stderr, and is not+ affected by -o/--output-file (unless you redirect stderr to stdout, eg:+ 2>&1). It will be interleaved with normal output, which can help re-+ veal when parts of the code are evaluated. To capture debug output in+ a log file instead, you can usually redirect stderr, eg:++ hledger bal --debug=3 2>hledger.log++Environment+ These environment variables affect hledger:++ COLUMNS This is normally set by your terminal; some hledger commands+ (register) will format their output to this width. If not set, they+ will try to use the available terminal width.++ LEDGER_FILE The main journal file to use when not specified with+ -f/--file. Default: $HOME/.hledger.journal.++ NO_COLOR If this environment variable is set (with any value), hledger+ will not use ANSI color codes in terminal output, unless overridden by+ an explicit --color/--colour option.++PART 2: DATA FORMATS+Journal+ hledger's usual data source is a plain text file containing journal en-+ tries in hledger journal format. If you're looking for a quick refer-+ ence, jump ahead to the journal cheatsheet (or use the table of con-+ tents at https://hledger.org/hledger.html).++ This file represents an accounting General Journal. The .journal file+ extension is most often used, though not strictly required. The jour-+ nal file contains a number of transaction entries, each describing a+ transfer of money (or any commodity) between two or more named ac-+ counts, in a simple format readable by both hledger and humans.++ hledger's journal format is compatible with most of Ledger's journal+ format, but not all of it. The differences and interoperation tips are+ described at hledger and Ledger. With some care, and by avoiding in-+ compatible features, you can keep your hledger journal readable by+ Ledger and vice versa. This can useful eg for comparing the behaviour+ of one app against the other.++ You can use hledger without learning any more about this file; just use+ the add or web or import commands to create and update it.++ Many users, though, edit the journal file with a text editor, and track+ changes with a version control system such as git. Editor addons such+ as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and+ 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.++ A hledger journal file can contain three kinds of thing: comment lines,+ transactions, and/or directives (including periodic transaction rules+ and auto posting rules). Understanding the journal file format will+ also give you a good understanding of hledger's data model. Here's a+ quick cheatsheet/overview, followed by detailed descriptions of each+ part.++ Journal cheatsheet+ # Here is the main syntax of hledger's journal format+ # (omitting extra Ledger compatibility syntax).++ ###############################################################################++ # 1. These are comment lines, for notes or temporarily disabling things.+ ; They begin with # or ;++ comment+ Or, lines can be enclosed within "comment" / "end comment".+ This is a block of+ commented lines.+ end comment++ # Some journal entries can have semicolon comments at end of line ; like this+ # Some of them require 2 or more spaces before the semicolon.++ ###############################################################################++ # 2. Directives customise processing or output in some way.+ # You don't need any directives to get started.+ # But they can add more error checking, or change how things are displayed.+ # They begin with a word, letter, or symbol.+ # They are most often placed at the top, before transactions.++ account assets ; Declare valid account names and display order.+ account assets:savings ; A subaccount. This one represents a bank account.+ account assets:checking ; Another. Note, 2+ spaces after the account name.+ account assets:receivable ; Accounting type is inferred from english names,+ account passifs ; or declared with a "type" tag, type:L+ account expenses ; type:X+ ; A follow-on comment line, indented.+ account expenses:rent ; Expense and revenue categories are also accounts.+ ; Subaccounts inherit their parent's type.++ commodity $0.00 ; Declare valid commodities and their display styles.+ commodity 1.000,00 EUR++ decimal-mark . ; The decimal mark used in this file (if ambiguous).++ payee Whole Foods ; Declare a valid payee name.++ tag trip ; Declare a valid tag name.++ P 2024-03-01 AAPL $179 ; Declare a market price for AAPL in $ on this date.++ include other.journal ; Include another journal file here.++ # Declare a recurring "periodic transaction", for budget/forecast reports+ ~ monthly set budget goals ; <- Note, 2+ spaces before the description.+ (expenses:rent) $1000+ (expenses:food) $500++ # Declare an auto posting rule, to modify existing transactions in reports+ = revenues:consulting+ liabilities:tax:2024:us *0.25 ; Add a tax liability & expense+ expenses:tax:2024:us *-0.25 ; for 25% of the revenue.++ ###############################################################################++ # 3. Transactions are what it's all about.+ # They are dated events, usually movements of money between 2 or more accounts.+ # They begin with a numeric date.+ # Here is their basic shape:+ #+ # DATE DESCRIPTION ; The transaction's date and optional description.+ # ACCOUNT1 AMOUNT ; A posting of an amount to/from this account, indented.+ # ACCOUNT2 AMOUNT ; A second posting, balancing the first.+ # ... ; More if needed. Amounts must sum to zero.+ # ; Note, 2+ spaces between account names and amounts.++ 2024-01-01 opening balances ; At the start, declare pre-existing balances this way.+ assets:savings $10000 ; Account names can be anything. lower case is easy to type.+ assets:checking $1000 ; assets, liabilities, equity, revenues, expenses are common.+ liabilities:credit card $-500 ; liabilities, equity, revenues balances are usually negative.+ equity:start ; One amount can be left blank. $-10500 is inferred here.+ ; Some of these accounts we didn't declare above,+ ; so -s/--strict would complain.++ 2024-01-03 ! (12345) pay rent+ ; Additional transaction comment lines, indented.+ ; There can be a ! or * after the date meaning "pending" or "cleared".+ ; There can be a parenthesised (code) after the date/status.+ ; Amounts' sign shows direction of flow.+ assets:checking $-500 ; Minus means removed from this account (credit).+ expenses:rent $500 ; Plus means added to this account (debit).++ ; Keeping transactions in date order is optional (but helps error checking).++ 2024-01-02 Gringott's Bank | withdrawal ; Description can be PAYEE | NOTE+ assets:bank:gold -10 gold+ assets:pouch 10 gold++ 2024-01-02 shopping+ expenses:clothing 1 gold+ expenses:wands 5 gold+ assets:pouch -6 gold++ 2024-01-02 receive gift+ revenues:gifts -3 "Chocolate Frogs" ; Complex commodity symbols+ assets:pouch 3 "Chocolate Frogs" ; must be in double quotes.++ 2024-01-15 buy some shares, in two lots ; Cost can be noted.+ assets:investments:2024-01-15 2.0 AAAA @ $1.50 ; @ means per-unit cost+ assets:investments:2024-01-15-02 3.0 AAAA @@ $4 ; @@ means total cost+ ; ^ Per-lot subaccounts are sometimes useful.+ assets:checking $-7++ 2024-01-15 assert some account balances on this date+ ; Balances can be asserted in any transaction, with =, for extra error checking.+ ; Assertion txns like this one can be made with hledger close --assert --show-costs+ ;+ assets:savings $0 = $10000+ assets:checking $0 = $493+ assets:bank:gold 0 gold = -10 gold+ assets:pouch 0 gold = 4 gold+ assets:pouch 0 "Chocolate Frogs" = 3 "Chocolate Frogs"+ assets:investments:2024-01-15 0.0 AAAA = 2.0 AAAA @ $1.50+ assets:investments:2024-01-15-02 0.0 AAAA = 3.0 AAAA @@ $4+ liabilities:credit card $0 = $-500++ 2024-02-01 note some event, or a transaction not yet fully entered, on this date+ ; Postings are not required.++ ; Some other date formats are allowed (but, consistent YYYY-MM-DD is useful).+ 2024.01.01+ 2024/1/1++ Comments+ Lines in the journal will be ignored if they begin with a hash (#) or a+ semicolon (;). (See also Other syntax.) hledger will also ignore re-+ gions beginning with a comment line and ending with an end comment line+ (or file end). Here's a suggestion for choosing between them:++ o # for top-level notes++ o ; for commenting out things temporarily++ o comment for quickly commenting large regions (remember it's there, or+ you might get confused)++ Eg:++ # a comment line+ ; another commentline+ comment+ A multi-line comment block,+ continuing until "end comment" directive+ or the end of the current file.+ end comment++ Some hledger entries can have same-line comments attached to them, from+ ; (semicolon) to end of line. See Transaction comments, Posting com-+ ments, and Account comments below.++ Transactions+ Transactions are the main unit of information in a journal file. They+ represent events, typically a movement of some quantity of commodities+ between two or more named accounts.++ Each transaction is recorded as a journal entry, beginning with a sim-+ ple date in column 0. This can be followed by any of the following op-+ tional fields, separated by spaces:++ o a status character (empty, !, or *)++ o a code (any short number or text, enclosed in parentheses)++ o a description (any remaining text until end of line or a semicolon)++ o a comment (any remaining text following a semicolon until end of+ line, and any following indented lines beginning with a semicolon)++ o 0 or more indented posting lines, describing what was transferred and+ the accounts involved (indented comment lines are also allowed, but+ not blank lines or non-indented lines).++ Here's a simple journal file containing one transaction:++ 2008/01/01 income+ assets:bank:checking $1+ income:salary $-1++ Dates+ Simple dates+ Dates in the journal file use simple dates format: YYYY-MM-DD or+ YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be+ omitted, in which case it will be inferred from the context: the cur-+ rent transaction, the default year set with a Y directive, or the cur-+ rent date when the command is run. Some examples: 2010-01-31,+ 2010/01/31, 2010.1.31, 1/31.++ (The UI also accepts simple dates, as well as the more flexible smart+ dates documented in the hledger manual.)++ Posting dates+ You can give individual postings a different date from their parent+ transaction, by adding a posting comment containing a tag (see below)+ like date:DATE. This is probably the best way to control posting dates+ precisely. Eg in this example the expense should appear in May re-+ ports, and the deduction from checking should be reported on 6/1 for+ easy bank reconciliation:++ 2015/5/30+ expenses:food $10 ; food purchased on saturday 5/30+ assets:checking ; bank cleared it on monday, date:6/1++ $ hledger -f t.j register food+ 2015-05-30 expenses:food $10 $10++ $ hledger -f t.j register checking+ 2015-06-01 assets:checking $-10 $-10++ DATE should be a simple date; if the year is not specified it will use+ the year of the transaction's date.+ The date: tag must have a valid simple date value if it is present, eg+ a date: tag with no value is not allowed.++ Status+ Transactions (or individual postings within a transaction) can have a+ status mark, which is a single character before the transaction de-+ scription (or posting account name), separated from it by a space, in-+ dicating 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 (and you can combine these, eg -UP+ to match all except cleared things). Or you can use the status:, sta-+ tus:!, and status:* queries, or the U, P, C keys in hledger-ui.++ (Note: in Ledger the "unmarked" state is called "uncleared"; in hledger+ we renamed it to "unmarked" for semantic clarity.)++ Status marks are optional, but can be helpful eg for reconciling with+ real-world accounts. Some editor modes provide highlighting and short-+ cuts for working with status. Eg in Emacs ledger-mode, you can toggle+ transaction status with C-c C-e, or posting status with C-c C-c.++ What "uncleared", "pending", and "cleared" actually mean is up to you.+ Here's one suggestion:++ status meaning+ --------------------------------------------------------------------------+ uncleared recorded but not yet reconciled; needs review+ pending tentatively reconciled (if needed, eg during a big reconcil-+ iation)+ cleared complete, reconciled as far as possible, and considered cor-+ rect++ With this scheme, you would use -PC to see the current balance at your+ bank, -U to see things which will probably hit your bank soon (like un-+ cashed checks), and no flags to see the most up-to-date state of your+ finances.++ 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+ After the date, status mark and/or code fields, the rest of the line+ (or until a comment is begun with ;) is the transaction's description.+ Here you can describe the transaction (called the "narration" in tradi-+ tional bookkeeping), or you can record a payee/payer name, or you can+ leave it empty.++ Transaction descriptions show up in print output and in register re-+ ports, and can be listed with the descriptions command.++ You can query by description with desc:DESCREGEX, or pivot on descrip-+ tion with --pivot desc.++ Payee and note+ Sometimes people want a dedicated payee/payer field that can be queried+ and checked more strictly. If you want that, you can write a | (pipe)+ character in the description. This divides it into a "payee" field on+ the left, and a "note" field on the right. (Either can be empty.)++ You can query these with payee:PAYEEREGEX and note:NOTEREGEX, list+ their values with the payees and notes commands, or pivot on payee or+ note.++ Note: in transactions with no | character, description, payee, and note+ all have the same value. Once a | is added, they become distinct. (If+ you'd like to change this behaviour, please propose it on the mail+ list.)++ If you want more strict error checking, you can declare the valid payee+ names with payee directives, and then enforce these with hledger check+ payees. (Note: because of the above, for this you'll need to ensure+ every transaction description contains a | and therefore a checkable+ payee name, even if it's empty.)++ Transaction comments+ Text following ;, after a transaction description, and/or on indented+ lines immediately below it, form comments for that transaction. They+ are reproduced by print but otherwise ignored, except they may contain+ tags, which are not ignored.++ 2012-01-01 something ; a transaction comment+ ; a second line of transaction comment+ expenses 1+ assets++ 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.++ If the amount is positive, it is being added to the account; if nega-+ tive, it is being removed from the account.++ The posting amounts in a transaction must sum up to zero, indicating+ that the inflows and outflows are equal. We call this a balanced+ transaction. (You can read more about the nitty-gritty details of "sum+ up to zero" in Transaction balancing below.)++ As a convenience, you can optionally leave one amount blank; hledger+ will infer what it should be so as to balance the transaction.++ Debits and credits+ The traditional accounting concepts of debit and credit of course exist+ in hledger, but we represent them with numeric sign, as described+ above. Positive and negative posting amounts represent debits and+ credits respectively.++ You don't need to remember that, but if you would like to - eg for+ helping newcomers or for talking with your accountant - here's a handy+ mnemonic:++ debit / plus / left / short words+ credit / minus / right / longer words++ The two space delimiter+ Be sure to notice the unusual separator between the account name and+ the following amount. Because hledger allows account names with spaces+ in them, you must separate the account name and amount (if any) by two+ or more spaces (or tabs). It's easy to forget at first. If you ever+ see the amount being treated as part of the account name, you'll know+ you probably need to add another space between them.++ Account names+ Accounts are the main way of categorising things in hledger. As in+ Double Entry Bookkeeping, they can represent real world accounts (such+ as a bank account), or more abstract categories such as "money borrowed+ from Frank" or "money spent on electricity".++ You can use any account names you like, but we usually start with the+ traditional accounting categories, which in english are assets, liabil-+ ities, equity, revenues, expenses. (You might see these referred to as+ A, L, E, R, X for short.)++ For more precise reporting, we usually divide the top level accounts+ into more detailed subaccounts, by writing a full colon between account+ name parts. For example, from the account names assets:bank:checking+ and expenses:food, hledger will infer this hierarchy of five accounts:++ assets+ assets:bank+ assets:bank:checking+ expenses+ expenses:food++ Shown as an outline, the hierarchical tree structure is more clear:++ assets+ bank+ checking+ expenses+ food++ hledger reports can summarise the account tree to any depth, so you can+ go as deep as you like with subcategories, but keeping your account+ names relatively simple may be best when starting out.++ Account names may be capitalised or not; they may contain letters, num-+ bers, symbols, or single spaces. Note, when an account name and an+ amount are written on the same line, they must be separated by two or+ more spaces (or tabs).++ Parentheses or brackets enclosing the full account name indicate vir-+ tual postings, described below. Parentheses or brackets internal to+ the account name have no special meaning.++ Account names can be altered temporarily or permanently by account+ aliases.++ Amounts+ After the account name, there is usually an amount. (Remember: 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+ A decimal mark can be written as a period or a comma:++ 1.23+ 1,23++ Both of these are common in international number formats, so hledger is+ not biased towards one or the other. Because hledger also supports+ digit group marks (eg thousands separators), this means that a number+ like 1,000 or 1.000 containing just one period or comma is ambiguous.+ In such cases, hledger by default assumes it is a decimal mark, and+ will parse both of those as 1.++ To help hledger parse such ambiguous numbers more accurately, if you+ use digit group marks, we recommend declaring the decimal mark explic-+ itly. The best way is to add a decimal-mark directive at the top of+ each data file, like this:++ decimal-mark .++ Or you can declare it per commodity with commodity directives, de-+ scribed below.++ hledger also accepts numbers like 10. with no digits after the decimal+ mark (and will sometimes display numbers that way to disambiguate them+ - see Trailing decimal marks).++ Digit group marks+ In the integer part of the amount quantity (left of the decimal mark),+ groups of digits can optionally be separated by a digit group mark - a+ comma or period (whichever is not used as decimal mark), or a space+ (several Unicode space variants, like no-break space, are also ac-+ cepted). So these are all valid amounts in a journal file:++ $1,000,000.00+ EUR 2.000.000,00+ INR 9,99,99,999.00+ 1 000 000.00 ; <- ordinary space+ 1 000 000.00 ; <- no-break space++ 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.++ By default, the format of amounts in the journal influences how hledger+ displays them in output. This is explained in Commodity display style+ below.++ Costs+ After a posting amount, you can note its cost (when buying) or selling+ price (when selling) in another commodity, by writing either @ UNIT-+ PRICE or @@ TOTALPRICE after it. This indicates a conversion transac-+ tion, where one commodity is exchanged for another.++ (You might also see this called "transaction price" in hledger docs,+ discussions, or code; that term was directionally neutral and reminded+ that it is a price specific to a transaction, but we now just call it+ "cost", with the understanding that the transaction could be a purchase+ or a sale.)++ Costs are usually written explicitly with @ or @@, but can also be in-+ ferred automatically for simple multi-commodity transactions. Note, if+ costs are inferred, the order of postings is significant; the first+ posting will have a cost attached, in the commodity of the second.++ As an example, here are several ways to record purchases of a foreign+ currency in hledger, using the cost notation either explicitly or im-+ plicitly:++ 1. Write the price per unit, as @ UNITPRICE after the amount:++ 2009/1/1+ assets:euros 100 @ $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 100 @@ $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. Note the+ effect of posting order: the price is added to first posting, making+ it 100 @@ $135, as in example 2:++ 2009/1/1+ assets:euros 100 ; one hundred euros purchased+ assets:dollars $-135 ; for $135++ Amounts can be converted to cost at report time using the -B/--cost+ flag; this is discussed more in the Cost reporting section.++ Note that the cost normally should be a positive amount, though it's+ not required to be. This can be a little confusing, see discussion at+ --infer-market-prices: market prices from transactions.++ 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, described below).++ Assertions and ordering+ hledger calculates and checks an account's balance assertions in date+ order (and when there are multiple assertions on the same day, in parse+ order). Note this is different from Ledger, which checks assertions+ always in parse order, ignoring dates.++ This means in hledger you can freely reorder transactions, postings, or+ files, and balance assertions will usually keep working. The exception+ is when you reorder multiple postings on the same day, to the same ac-+ count, which have balance assertions; those will likely need updating.++ Assertions and multiple included files+ Multiple files included with the include directive are processed as if+ concatenated into one file, preserving their order and the posting or-+ der within each file. It means that balance assertions in later files+ will see balance from earlier files.++ And if you have multiple postings to an account on the same day, split+ across multiple files, and you want to assert the account's balance on+ that day, you'll need to put the assertion in the right file - the last+ one in the sequence, probably.++ Assertions and multiple -f files+ Unlike include, when multiple files are specified on the command line+ with multiple -f/--file options, balance assertions will not see bal-+ ance from earlier files. This can be useful when you do not want prob-+ lems in earlier files to disrupt valid assertions in later files.++ If you do want assertions to see balance from earlier files, use in-+ clude, or concatenate the files temporarily.++ Assertions and costs+ Balance assertions ignore costs, and should normally be written without+ one:++ 2019/1/1+ (a) $1 @ 1 = $1++ We do allow costs to be written in balance assertion amounts, however,+ and print shows them, but 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 costs), and because+ balance assignments do use costs (see below).++ Assertions and commodities+ The balance assertions described so far are "single commodity balance+ assertions": they assert and check the balance in one commodity, ignor-+ ing any others that may be present. This is how balance assertions+ work in Ledger also.++ If an account contains multiple commodities, you can assert their bal-+ ances by writing multiple postings with balance assertions, one for+ each commodity:++ 2013/1/1+ usd $-1+ eur -1+ both++ 2013/1/2+ both 0 = $1+ both 0 = 1++ In hledger you can make a stronger "sole commodity balance assertion"+ by writing two equals signs (== EXPECTEDBALANCE). This also asserts+ that there are no other commodities in the account besides the asserted+ one (or at least, that their current balance is zero):++ 2013/1/1+ usd $-1 == $-1 ; these sole commodity assertions succeed+ eur -1 == -1+ both ;== $1 ; this one would fail because 'both' contains $ and++ It's less easy to make a "sole commodities balance assertion" (note the+ plural) - ie, asserting that an account contains two or more specified+ commodities and no others. It can be done by++ 1. isolating each commodity in a subaccount, and asserting those++ 2. and also asserting there are no commodities in the parent account+ itself:++ 2013/1/1+ usd $-1+ eur -1+ both 0 == 0 ; nothing up my sleeve+ both:usd $1 == $1 ; a dollar here+ both:eur 1 == 1 ; a euro there++ Assertions and subaccounts+ All of the balance assertions above (both = and ==) are "subaccount-ex-+ clusive balance assertions"; they ignore any balances that exist in+ deeper subaccounts.++ In hledger you can make "subaccount-inclusive balance assertions" by+ adding a star after the equals (=* or ==*):++ 2019/1/1+ equity:start+ assets:checking $10+ assets:savings $10+ assets $0 ==* $20 ; assets + subaccounts contains $20 and nothing else++ Assertions and virtual postings+ Balance assertions always consider both real and virtual postings; they+ are not affected by the --real/-R flag or real: query.++ Assertions and auto postings+ Balance assertions are affected by the --auto flag, which generates+ auto postings, which can alter account balances. Because auto postings+ are optional in hledger, accounts affected by them effectively have two+ balances. But balance assertions can only test one or the other of+ these. So to avoid making fragile assertions, either:++ o assert the balance calculated with --auto, and always use --auto with+ that file++ o or assert the balance calculated without --auto, and never use --auto+ with that file++ o or avoid balance assertions on accounts affected by auto postings (or+ avoid auto postings entirely).++ Assertions and precision+ Balance assertions compare the exactly calculated amounts, which are+ not always what is shown by reports. Eg a commodity directive may+ limit the display precision, but this will not affect balance asser-+ tions. Balance assertion failure messages show exact amounts.++ Posting comments+ Text following ;, at the end of a posting line, and/or on indented+ lines immediately below it, form comments for that posting. They are+ reproduced by print but otherwise ignored, except they may contain+ tags, which are not ignored.++ 2012-01-01+ expenses 1 ; a comment for posting 1+ assets+ ; a comment for posting 2+ ; a second comment line for posting 2++ Transaction balancing+ How exactly does hledger decide when a transaction is balanced ? The+ general goal is that if you look at the journal entry and calculate the+ amounts' sum perfectly with pencil and paper, hledger should agree with+ you.++ Real world transactions, especially for investments or cryptocurren-+ cies, often involve imprecise costs, complex decimals, and/or infi-+ nitely-recurring decimals, which are difficult or inconvenient to han-+ dle on a computer. So to be a practical accounting system, hledger al-+ lows some imprecision when checking transaction balancedness. The+ question is, how much imprecision should be allowed ?++ hledger currently decides it based on the commodity display styles: if+ the postings' sum would appear to be zero when displayed with the stan-+ dard display precisions, the transaction is considered balanced.++ Or equivalently: if the journal entry is displayed with amounts rounded+ to the standard display precisions (with hledger print --round=hard),+ and a human with pencil and paper would agree that those displayed+ amounts add up to zero, the transaction is considered balanced.++ This has some advantages: it is fairly intuitive, general not+ hard-coded, yet configurable when needed. On the downside it means+ that transaction balancedness is related to commodity display preci-+ sions, so eg when using -c/--commodity-style to display things with+ more than usual precision, you might need to fix some of your journal+ entries (ie, add decimal digits to make them balance more precisely).++ Other PTA tools (Ledger, Beancount..) have their own ways of doing it.+ Possible improvements are discussed at #1964.++ Note: if you have multiple journal files, and are relying on commodity+ directives to make imprecise journal entries balance, the directives'+ placement might be important - see commodity directive.++ Tags+ Tags are a way to add extra labels or data fields to transactions,+ postings, or accounts, which you can then search or pivot on.++ A tag is a word, optionally hyphenated, immediately followed by a full+ colon, in the comment of a transaction, a posting, or an account direc-+ tive. Eg: 2024-01-01 a transaction ; foo: Note this is an exception+ to the usual rule that things in comments are ignored.++ You can write multiple tags on one line, separated by comma. Or you+ can write each tag on its own comment line (no comma needed in this+ case).++ For example, here are five different tags: one on the assets:checking+ account, two on the transaction, and two on the expenses:food posting:++ account assets:checking ; accounttag:++ 2017/1/16 bought groceries ; transactiontag-1:+ ; transactiontag-2:+ assets:checking $-1+ expenses:food $1 ; postingtag:, another-posting-tag:++ Postings also inherit tags from their transaction and their account.+ And transactions also acquire tags from their postings (and postings'+ accounts). So in the example above, the expenses posting effectively+ has all five tags (by inheriting from the account and transaction), and+ the transaction also has all five tags (by acquiring from the expenses+ posting).++ Tag names+ Most non-whitespace characters are allowed in tag names. Eg : is a+ valid tag.++ You can list the tag names used in your journal with the tags command:+ hledger tags [NAMEREGEX]++ In commands which use a query, you can match by tag name. Eg:+ hledger print tag:NAMEREGEX++ You can declare valid tag names with the tag directive and then check+ them with the check command.++ Special tags+ Some tag names have special significance to hledger. There's not much+ harm in using them yourself, but some could produce an error message,+ particularly the date: and type: tags. They are explained elsewhere,+ but here is a quick list for reference:++ Tags you can set to influence hledger's behaviour:++ date -- overrides a posting's date+ date2 -- overrides a posting's secondary date+ type -- declares an account's type++ Tags hledger adds to indicate generated data:++ t -- appears on postings generated by timedot letters+ assert -- appears on txns generated by close --assert+ retain -- appears on txns generated by close --retain+ start -- appears on txns generated by close --migrate/--close/--open/--assign+ generated-transaction -- appears on generated periodic txns (with --verbose-tags)+ generated-posting -- appears on generated auto postings (with --verbose-tags)+ modified -- appears on txns which have had auto postings added (with --verbose-tags)+ Not displayed, but queryable:+ _generated-transaction -- exists on generated periodic txns (always)+ _generated-posting -- exists on generated auto postings (always)+ _modified -- exists on txns which have had auto postings added (always)++ Tags hledger uses internally:++ _conversion-matched -- exists on postings which have been matched with a nearby @/@@ cost annotation++ Tag values+ Tags can have a value, which is any text after the colon up until a+ comma or end of line, with surrounding whitespace removed. Ending at+ comma allows us to write multiple tags on one line, but also means that+ tag values can not contain commas.++ Eg in the following posting, the three tags' values are "value 1",+ "value 2", and "" (empty) respectively:++ expenses:food $10 ; foo, tag1: value 1 , tag2:value 2, bar tag3: , baz++ Multiple tags with the same name are additive rather than overriding:+ when the same tag name is seen again with a new value, the new+ name:value pair is added to the tags. It is not possible to override a+ previous tag's value or remove a tag.++ You can list all the values used for a particular tag in the journal+ with+ hledger tags TAGNAME --values++ You can match on tag values with a query like tag:NAMEREGEX=VALUEREGEX++ Directives+ Besides transactions, there is something else you can put in a journal+ file: directives. These are declarations, beginning with a keyword,+ that modify hledger's behaviour. Some directives can have more spe-+ cific subdirectives, indented below them. hledger's directives are+ similar to Ledger's in many cases, but there are also many differences.+ Directives are not required, but can be useful. Here are the main di-+ rectives:++ purpose directive+ --------------------------------------------------------------------------+ READING DATA:+ Rewrite account names alias+ Comment out sections of the file comment+ Declare file's decimal mark, to help decimal-mark+ parse amounts accurately+ Include other data files include+ GENERATING DATA:+ Generate recurring transactions or bud- ~+ get goals+ Generate extra postings on existing =+ transactions+ CHECKING FOR ERRORS:+ Define valid entities to provide more account, commodity, payee, tag+ error checking+ REPORTING:+ Declare accounts' type and display order account+ Declare commodity display styles commodity+ Declare market prices P++ Directives and multiple files+ Directives vary in their scope, ie which journal entries and which in-+ put files they affect. Most often, a directive will affect the follow-+ ing entries and included files if any, until the end of the current+ file - and no further. You might find this inconvenient! For example,+ alias directives do not affect parent or sibling files. But there are+ usually workarounds; for example, put alias directives in your top-most+ file, before including other files.++ The restriction, though it may be annoying at first, is in a good+ cause; it allows reports to be stable and deterministic, independent of+ the order of input. Without it, reports could show different numbers+ depending on the order of -f options, or the positions of include di-+ rectives in your files.++ Directive effects+ Here are all hledger's directives, with their effects and scope sum-+ marised - nine main directives, plus four others which we consider+ non-essential:++ di- what it does ends+ rec- at+ tive file+ end?+ --------------------------------------------------------------------------------------+ ac- Declares an account, for checking all entries in all files; and N+ count its display order and type. Subdirectives: any text, ignored.+ alias Rewrites account names, in following entries until end of cur- Y+ rent file or end aliases. Command line equivalent: --alias+ com- Ignores part of the journal file, until end of current file or Y+ ment end comment.+ com- Declares up to four things: 1. a commodity symbol, for checking N,N,Y,Y+ mod- all amounts in all files 2. the display style for all amounts+ ity of this commodity 3. the decimal mark for parsing amounts of+ this commodity, in the rest of this file and its children, if+ there is no decimal-mark directive 4. the precision to use for+ balanced-transaction checking in this commodity, in this file+ and its children. Takes precedence over D. Subdirectives:+ format (ignored). Command line equivalent: -c/--commodity-style+ deci- Declares the decimal mark, for parsing amounts of all commodi- Y+ mal-mark ties in following entries until next decimal-mark or end of cur-+ rent file. Included files can override. Takes precedence over+ commodity and D.+ include Includes entries and directives from another file, as if they N+ were written inline. Command line alternative: multiple+ -f/--file+ payee Declares a payee name, for checking all entries in all files. N+ P Declares the market price of a commodity on some date, for value N+ reports.+ ~ Declares a periodic transaction rule that generates future N+ (tilde) transactions with --forecast and budget goals with balance+ --budget.+ Other+ syntax:+ apply Prepends a common parent account to all account names, in fol- Y+ account lowing entries until end of current file or end apply account.+ D Sets a default commodity to use for no-symbol amounts;and, if Y,Y,N,N+ there is no commodity directive for this commodity: its decimal+ mark, balancing precision, and display style, as above.+ Y Sets a default year to use for any yearless dates, in following Y+ entries until end of current file.+ = Declares an auto posting rule that generates extra postings on partly+ (equals) matched transactions with --auto, in current, parent, and child+ files (but not sibling files, see #1212).+ Other Other directives from Ledger's file format are accepted but ig-+ Ledger nored.+ direc-+ tives++ account directive+ account directives can be used to declare accounts (ie, the places that+ amounts are transferred from and to). Though not required, these dec-+ larations can provide several benefits:++ o They can document your intended chart of accounts, providing a refer-+ ence.++ o They can store additional account information as comments, or as tags+ which can be used to filter or pivot reports.++ o They can restrict which accounts may be posted to by transactions, eg+ in strict mode, which helps prevent errors.++ o They influence account display order in reports, allowing non-alpha-+ betic sorting (eg Revenues to appear above Expenses).++ o They can help hledger know your accounts' types (asset, liability,+ equity, revenue, expense), enabling reports like balancesheet and in-+ comestatement.++ o They help with account name completion (in hledger add, hledger-web,+ hledger-iadd, ledger-mode, etc.)++ They are written as the word account followed by a hledger-style ac-+ count name. Eg:++ account assets:bank:checking++ Ledger-style indented subdirectives are also accepted, but ignored:++ account assets:bank:checking+ format subdirective ; currently ignored++ Account comments+ Text following two or more spaces and ; at the end of an account direc-+ tive line, and/or following ; on indented lines immediately below it,+ form comments for that account. They are ignored except they may con-+ tain tags, which are not ignored.++ The two-space requirement for same-line account comments is because ;+ is allowed in account names.++ account assets:bank:checking ; same-line comment, at least 2 spaces before the semicolon+ ; next-line comment+ ; some tags - type:A, acctnum:12345++ Account error checking+ By default, accounts need not be declared; they come into existence+ when a posting references them. This is convenient, but it means+ hledger can't warn you when you mis-spell an account name in the jour-+ nal. Usually you'll find that error later, as an extra account in bal-+ ance reports, or an incorrect balance when reconciling.++ In strict mode, enabled with the -s/--strict flag, hledger will report+ an error if any transaction uses an account name that has not been de-+ clared by an account directive. Some notes:++ o The declaration is case-sensitive; transactions must use the correct+ account name capitalisation.++ o The account directive's scope is "whole file and below" (see direc-+ tives). This means it affects all of the current file, and any files+ it includes, but not parent or sibling files. The position of ac-+ count directives within the file does not matter, though it's usual+ to put them at the top.++ o Accounts can only be declared in journal files, but will affect in-+ cluded files of all types.++ o It's currently not possible to declare "all possible subaccounts"+ with a wildcard; every account posted to must be declared.++ Account display order+ Account directives also cause hledger to display accounts in a particu-+ lar order, not just alphabetically. Eg, here is a conventional order-+ ing for the top-level accounts:++ account assets+ account liabilities+ account equity+ account revenues+ account expenses++ Now hledger displays them in that order:++ $ hledger accounts+ assets+ liabilities+ equity+ revenues+ expenses++ If there are undeclared accounts, those will be displayed last, in al-+ phabetical order.++ Sorting is done within each group of sibling accounts, at each level of+ the account tree. Eg, a declaration like account parent:child influ-+ ences child's position among its siblings.++ Note, it does not affect parent's position; for that, you need an ac-+ count parent declaration.++ Sibling accounts are always displayed together; hledger won't display+ x:y in between a:b and a:c.++ An account directive both declares an account as a valid posting tar-+ get, and declares its display order; you can't easily do one without+ the other.++ Account types+ hledger knows that accounts come in several types: assets, liabilities,+ expenses and so on. This enables easy reports like balancesheet and+ incomestatement, and filtering by account type with the type: query.++ As a convenience, hledger will detect these account types automatically+ if you are using common english-language top-level account names (de-+ scribed below). But it's more robust to declare accounts' types ex-+ plicitly, by adding type: tags to their account directives. The tag's+ value should be one of the five main account types:++ o A or Asset (things you own)++ o L or Liability (things you owe)++ o E or Equity (investment/ownership; balanced counterpart of assets &+ liabilities)++ o R or Revenue (what you received money from, AKA income; technically+ part of Equity)++ o X or Expense (what you spend money on; technically part of Equity)++ or, it can be (these are used less often):++ o C or Cash (a subtype of Asset, indicating liquid assets for the cash-+ flow report)++ o V or Conversion (a subtype of Equity, for conversions (see Cost re-+ porting).)++ Subaccounts inherit their parent's type, or they can override it. Here+ is a typical set of account type declarations:++ account assets ; type: A+ account liabilities ; type: L+ account equity ; type: E+ account revenues ; type: R+ account expenses ; type: X++ account assets:bank ; type: C+ account assets:cash ; type: C++ account equity:conversion ; type: V++ Here are some tips for working with account types.++ o The rules for inferring types from account names are as follows.+ These are just a convenience that sometimes help new users get going;+ if they don't work for you, just ignore them and declare your account+ types. See also Regular expressions.++ If account's name contains this (CI) regular expression: | its type is:+ --------------------------------------------------------------------|-------------+ ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|current)(:|$) | Cash+ ^assets?(:|$) | Asset+ ^(debts?|liabilit(y|ies))(:|$) | Liability+ ^equity:(trad(e|ing)|conversion)s?(:|$) | Conversion+ ^equity(:|$) | Equity+ ^(income|revenue)s?(:|$) | Revenue+ ^expenses?(:|$) | Expense++ o If you declare any account types, it's a good idea to declare an ac-+ count for all of the account types, because a mixture of declared and+ name-inferred types can disrupt certain reports.++ o Certain uses of account aliases can disrupt account types. See+ Rewriting accounts > Aliases and account types.++ o As mentioned above, subaccounts will inherit a type from their parent+ account. More precisely, an account's type is decided by the first+ of these that exists:++ 1. A type: declaration for this account.++ 2. A type: declaration in the parent accounts above it, preferring+ the nearest.++ 3. An account type inferred from this account's name.++ 4. An account type inferred from a parent account's name, preferring+ the nearest parent.++ 5. Otherwise, it will have no type.++ o For troubleshooting, you can list accounts and their types with:++ $ hledger accounts --types [ACCTPAT] [-DEPTH] [type:TYPECODES]++ alias directive+ 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++ o combining two accounts into one, eg to see their sum or difference on+ one line++ 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.++ Account aliases are very powerful. They are generally easy to use cor-+ rectly, but you can also generate invalid account names with them; more+ on this below.++ 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 re-+ place any occurrence of the old account name with the new one. Subac-+ counts are also affected. Eg:++ alias checking = assets:bank:wells fargo:checking+ ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"++ Regex aliases+ There is also a more powerful variant that uses a regular expression,+ indicated by wrapping the pattern in forward slashes. (This is the+ only place where hledger requires forward slashes around a regular ex-+ pression.)++ Eg:++ alias /REGEX/ = REPLACEMENT++ or:++ $ hledger --alias '/REGEX/=REPLACEMENT' ...++ Any part of an account name matched by REGEX will be replaced by RE-+ PLACEMENT. REGEX is case-insensitive as usual.++ If you need to match a forward slash, escape it with a backslash, eg+ /\/=:.++ If REGEX contains parenthesised match groups, these can be referenced+ by the usual backslash and number in REPLACEMENT:++ alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3+ ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking"++ REPLACEMENT continues to the end of line (or on command line, to end of+ option argument), so it can contain trailing whitespace.++ Combining aliases+ You can define as many aliases as you like, using journal directives+ and/or command line options.++ Recursive aliases - where an account name is rewritten by one alias,+ then by another alias, and so on - are allowed. Each alias sees the+ effect of previously applied aliases.++ In such cases it can be important to understand which aliases will be+ applied and in which order. For (each account name in) each journal+ entry, we apply:++ 1. alias directives preceding the journal entry, most recently parsed+ first (ie, reading upward from the journal entry, bottom to top)++ 2. --alias options, in the order they appeared on the command line+ (left to right).++ In other words, for (an account name in) a given journal entry:++ o the nearest alias declaration before/above the entry is applied first++ o the next alias before/above that will be be applied next, and so on++ o aliases defined after/below the entry do not affect it.++ This gives nearby aliases precedence over distant ones, and helps pro-+ vide semantic stability - aliases will keep working the same way inde-+ pendent of which files are being read and in which order.++ In case of trouble, adding --debug=6 to the command line will show+ which aliases are being applied when.++ Aliases and multiple files+ As explained at Directives and multiple files, alias directives do not+ affect parent or sibling files. Eg in this command,++ hledger -f a.aliases -f b.journal++ account aliases defined in a.aliases will not affect b.journal. In-+ cluding the aliases doesn't work either:++ include a.aliases++ 2023-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++ 2023-01-01 ; affected by aliases above+ foo 1+ bar++ include c.journal ; also affected++ end aliases directive+ You can clear (forget) all currently defined aliases (seen in the jour-+ nal so far, or defined on the command line) with this directive:++ end aliases++ Aliases can generate bad account names+ Be aware that account aliases can produce malformed account names,+ which could cause confusing reports or invalid print output. For exam-+ ple, you could erase all account names:++ 2021-01-01+ a:aa 1+ b++ $ hledger print --alias '/.*/='+ 2021-01-01+ 1++ The above print output is not a valid journal. Or you could insert an+ illegal double space, causing print output that would give a different+ journal when reparsed:++ 2021-01-01+ old 1+ other++ $ hledger print --alias old="new USD" | hledger -f- print+ 2021-01-01+ new USD 1+ other++ Aliases and account types+ If an account with a type declaration (see Declaring accounts > Account+ types) is renamed by an alias, normally the account type remains in ef-+ fect.++ However, renaming in a way that reshapes the account tree (eg renaming+ parent accounts but not their children, or vice versa) could prevent+ child accounts from inheriting the account type of their parents.++ Secondly, if an account's type is being inferred from its name, renam-+ ing it by an alias could prevent or alter that.++ If you are using account aliases and the type: query is not matching+ accounts as you expect, try troubleshooting with the accounts command,+ eg something like:++ $ hledger accounts --alias assets=bassetts type:a++ commodity directive+ The commodity directive performs several functions:++ 1. It declares which commodity symbols may be used in the journal, en-+ abling useful error checking with strict mode or the check command.+ See Commodity error checking below.++ 2. It declares how all amounts in this commodity should be displayed,+ eg how many decimals to show. See Commodity display style above.++ 3. (If no decimal-mark directive is in effect:) It sets the decimal+ mark to expect (period or comma) when parsing amounts in this com-+ modity, in this file and files it includes, from the directive until+ end of current file. See Decimal marks above.++ 4. It declares the precision with which this commodity's amounts should+ be compared when checking for balanced transactions, anywhere in+ this file and files it includes, until end of current file.++ Declaring commodities solves several common parsing/display problems,+ so we recommend it.++ Note that effects 3 and 4 above end at the end of the directive's file,+ and will not affect sibling or parent files. So if you are relying on+ them (especially 4) and using multiple files, placing your commodity+ directives in a top-level parent file might be important. Or, keep+ your decimal marks unambiguous and your entries well balanced and pre-+ cise.++ (Related: #793)++ Commodity directive syntax+ A commodity directive is normally the word commodity followed by a sam-+ ple amount (and optionally a comment). Only the amount's symbol and+ format is significant. Eg:++ commodity $1000.00+ commodity 1.000,00 EUR+ commodity 1 000 000.0000 ; the no-symbol commodity++ Commodities do not have tags (tags in the comment will be ignored).++ A commodity directive's sample amount must always include a period or+ comma decimal mark (this rule helps disambiguate decimal marks and+ digit group marks). If you don't want to show any decimal digits,+ write the decimal mark at the end:++ commodity 1000. AAAA ; show AAAA with no decimals++ Commodity symbols containing spaces, numbers, or punctuation must be+ enclosed in double quotes, as usual:++ commodity 1.0000 "AAAA 2023"++ Commodity directives normally include a sample amount, but can declare+ only a symbol (ie, just function 1 above):++ commodity $+ commodity INR+ commodity "AAAA 2023"+ commodity "" ; the no-symbol commodity++ Commodity directives may also be written with an indented format subdi-+ rective, as in Ledger. The symbol is repeated and must be the same in+ both places. Other subdirectives are currently ignored:++ ; 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+ an unsupported subdirective ; ignored by hledger++ Commodity error checking+ In strict mode (-s/--strict) (or when you run hledger check commodi-+ ties), hledger will report an error if an undeclared commodity symbol+ is used. (With one exception: zero amounts are always allowed to have+ no commodity symbol.) It works like account error checking (described+ above).++ decimal-mark directive+ You can use a decimal-mark directive - usually one per file, at the top+ of the file - to declare which character represents a decimal mark when+ parsing amounts in this file. It can look like++ decimal-mark .++ or++ decimal-mark ,++ This prevents any ambiguity when parsing numbers in the file, so we+ recommend it, especially if the file contains digit group marks (eg+ thousands separators).++ include directive+ You can pull in the content of additional files by writing an include+ directive, like this:++ include FILEPATH++ Only journal files can include, and only journal, timeclock or timedot+ files can be included (not CSV files, currently).++ If the file path does not begin with a slash, it is relative to the+ current file's folder.++ A tilde means home directory, eg: include ~/main.journal.++ The path may contain glob patterns to match multiple files, eg: include+ *.journal.++ There is limited support for recursive wildcards: **/ (the slash is re-+ quired) matches 0 or more subdirectories. It's not super convenient+ since you have to avoid include cycles and including directories, but+ this can be done, eg: include */**/*.journal.++ The path may also be prefixed to force a specific file format, overrid-+ ing the file extension (as described in Data formats): include time-+ dot:~/notes/2023*.md.++ P directive+ The P directive declares a market price, which is a conversion rate be-+ tween two commodities on a certain date. This allows value reports to+ convert amounts of one commodity to their value in another, on or after+ that date. These prices are often obtained from a stock exchange,+ cryptocurrency exchange, the or foreign exchange market.++ 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. Ex-+ amples:++ # one euro was worth $1.35 from 2009-01-01 onward:+ P 2009-01-01 $1.35++ # and $1.40 from 2010-01-01 onward:+ P 2010-01-01 $1.40++ The -V, -X and --value flags use these market prices to show amount+ values in another commodity. See Value reporting.++ payee directive+ payee PAYEE NAME++ This 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 ; a comment++ Payees do not have tags (tags in the comment will be ignored).++ To declare the empty payee name, use "".++ payee ""++ Ledger-style indented subdirectives, if any, are currently ignored.++ tag directive+ tag TAGNAME++ This directive can be used to declare a limited set of tag names al-+ lowed in tags. TAGNAME should be a valid tag name (no spaces). Eg:++ tag item-id++ Any indented subdirectives are currently ignored.++ The "tags" check will report an error if any undeclared tag name is+ used. It is quite easy to accidentally create a tag through normal use+ of colons in comments; if you want to prevent this, you can declare and+ check your tags .++ Periodic transactions+ The ~ directive declares a "periodic rule" which generates temporary+ extra transactions, usually recurring at some interval, when hledger is+ run with the --forecast flag. These "forecast transactions" are useful+ for forecasting future activity. They exist only for the duration of+ the report, and only when --forecast is used; they are not saved in the+ journal file by hledger.++ Periodic rules also have a second use: with the --budget flag they set+ budget goals for budgeting.++ Periodic rules can be a little tricky, so before you use them, read+ this whole section, or at least the following tips:++ 1. Two spaces accidentally added or omitted will cause you trouble -+ read about this below.++ 2. For troubleshooting, show the generated transactions with hledger+ print --forecast tag:generated or hledger register --forecast+ tag:generated.++ 3. Forecasted transactions will begin only after the last non-fore-+ casted transaction's date.++ 4. Forecasted transactions will end 6 months from today, by default.+ See below for the exact start/end rules.++ 5. period expressions can be tricky. Their documentation needs im-+ provement, but is worth studying.++ 6. Some period expressions with a repeating interval must begin on a+ natural boundary of that interval. Eg in weekly from DATE, DATE+ must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an+ error.++ 7. Other period expressions with an interval are automatically expanded+ to cover a whole number of that interval. (This is done to improve+ reports, but it also affects periodic transactions. Yes, it's a bit+ inconsistent with the above.) Eg: ~ every 10th day of month from+ 2023/01, which is equivalent to ~ every 10th day of month from+ 2023/01/01, will be adjusted to start on 2019/12/10.++ 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.):++ # every first of month+ ~ monthly+ expenses:rent $2000+ assets:bank:checking++ # every 15th of month in 2023's first quarter:+ ~ monthly from 2023-04-15 to 2023-06-16+ expenses:utilities $400+ assets:bank:checking++ The period expression is the same syntax used for specifying multi-pe-+ riod reports, just interpreted differently; there, it specifies report+ periods; here it specifies recurrence dates (the periods' start dates).++ Periodic rules and relative dates+ Partial or relative dates (like 12/31, 25, tomorrow, last week, next+ quarter) are usually not recommended in periodic rules, since the re-+ sults will change as time passes. If used, they will be interpreted+ relative to, in order of preference:++ 1. the first day of the default year specified by a recent Y directive++ 2. or the date specified with --today++ 3. or the date on which you are running the report.++ They will not be affected at all by report period or forecast period+ dates.++ 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 2023"+ ; ||+ ; vv+ ~ every 2 months in 2023, we will review+ assets:bank:checking $1500+ income:acme inc++ So,++ o Do write two spaces between your period expression and your transac-+ tion description, if any.++ o Don't accidentally write two spaces in the middle of your period ex-+ pression.++ Auto postings+ The = directive declares an "auto posting rule", which adds extra post-+ ings to existing transactions. (Remember, postings are the account+ name & amount lines below a transaction's date & description.)++ In the journal, an auto posting rule looks quite like a transaction,+ but instead of date and description it has = (mnemonic: "match") and a+ query, like this:++ = QUERY+ ACCOUNT AMOUNT+ ...++ Queries are just like command line queries; an account name substring+ is most common. Query terms containing spaces should be enclosed in+ single or double quotes.++ Each = rule works like this: when hledger is run with the --auto flag,+ wherever the QUERY matches a posting in the journal, the rule's post-+ ings are added to that transaction, immediately below the matched post-+ ing. Note these generated postings are temporary, existing only for+ the duration of the report, and only when --auto is used; they are not+ saved in the journal file by hledger.++ Generated postings' amounts can depend on the matched posting's amount.+ So auto postings can be useful for, eg, adding tax postings with a+ standard percentage. AMOUNT can be:++ o a number with no commodity symbol, like 2. The matched posting's+ commodity symbol will be added to this.++ o a normal amount with a commodity symbol, like $2. This will be used+ as-is.++ o an asterisk followed by a number, like *2. This will multiply the+ matched posting's amount (and total price, if any) by the number.++ o an asterisk followed by an amount with commodity symbol, like *$2.+ This multiplies and also replaces the commodity symbol with this new+ one.++ 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++ Note that depending fully on generated data such as this has some draw-+ backs - it's less portable, less future-proof, less auditable by oth-+ ers, and less robust (eg your balance assertions will depend on whether+ you use or don't use --auto). An alternative is to use auto postings+ in "one time" fashion - use them to help build a complex journal entry,+ view it with hledger print --auto, and then copy that output into the+ journal file to make it permanent.++ 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.++ This also means that you cannot have more than one auto-posting with a+ missing amount applied to a given transaction, as it will be unable to+ infer amounts.++ 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".++ Auto postings on forecast transactions only+ Tip: you can can make auto postings that will apply to forecast trans-+ actions but not recorded transactions, by adding tag:_generated-trans-+ action to their QUERY. This can be useful when generating new journal+ entries to be saved in the journal.++ Other syntax+ hledger journal format supports quite a few other features, mainly to+ make interoperating with or converting from Ledger easier. Note some+ of the features below are powerful and can be useful in special cases,+ but in general, features in this section are considered less important+ or even not recommended for most users. Downsides are mentioned to+ help you decide if you want to use them.++ Balance assignments+ Ledger-style balance assignments are also supported. These are like+ balance assertions, but with no posting amount on the left side of the+ equals sign; instead it is calculated automatically so as to satisfy+ the assertion. This can be a convenience during data entry, eg when+ 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).++ Downsides: using balance assignments makes your journal less explicit;+ to know the exact amount posted, you have to run hledger or do the cal-+ culations yourself, instead of just reading it. Also balance assign-+ ments' forcing of balances can hide errors. These things make your fi-+ nancial data less portable, less future-proof, and less trustworthy in+ an audit.++ Balance assignments and costs+ A cost in a balance assignment will cause the calculated amount to have+ that cost attached:++ 2019/1/1+ (a) = $1 @ 2++ $ hledger print --explicit+ 2019-01-01+ (a) $1 @ 2 = $1 @ 2++ Balance assignments and multiple files+ Balance assignments handle multiple files like balance assertions.+ They see balance from other files previously included from the current+ file, but not from previous sibling or parent files.++ Bracketed posting dates+ For setting posting dates and secondary posting dates, Ledger's brack-+ eted date syntax is also supported: [DATE], [DATE=DATE2] or [=DATE2] in+ posting comments. hledger will attempt to parse any square-bracketed+ sequence of the 0123456789/-.= characters in this way. With this syn-+ tax, DATE infers its year from the transaction and DATE2 infers its+ year from DATE.++ Downsides: another syntax to learn, redundant with hledger's+ date:/date2: tags, and confusingly similar to Ledger's lot date syntax.++ D directive+ D AMOUNT++ This 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+ current file.++ For compatibility/historical reasons, D also acts like a commodity di-+ rective (setting the commodity's decimal mark for parsing and display+ style for output). So its argument is not just a commodity symbol, but+ a full amount demonstrating the style. The amount must include a deci-+ mal mark (either period or comma). 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++ Interactions with other directives:++ For setting a commodity's display style, a commodity directive has+ highest priority, then a D directive.++ For detecting a commodity's decimal mark during parsing, decimal-mark+ has highest priority, then commodity, then D.++ For checking commodity symbols with the check command, a commodity di-+ rective is required (hledger check commodities ignores D directives).++ Downsides: omitting commodity symbols makes your financial data less+ explicit, less portable, and less trustworthy in an audit. It is usu-+ ally an unsustainable shortcut; sooner or later you will want to track+ multiple commodities. D is overloaded with functions redundant with+ commodity and decimal-mark. And it works differently from Ledger's D.++ apply account directive+ This directive sets a default parent account, which will be prepended+ to all accounts in following entries, until an end apply account direc-+ tive or end of current file. Eg:++ apply account home++ 2010/1/1+ food $10+ cash++ end apply account++ is equivalent to:++ 2010/01/01+ home:food $10+ home:cash $-10++ account directives are also affected, and so is any included content.++ Account names entered via hledger add or hledger-web are not affected.++ Account aliases, if any, are applied after the parent account is+ prepended.++ Downsides: this can make your financial data less explicit, less+ portable, and less trustworthy in an audit.++ Y directive+ Y YEAR++ or (deprecated backward-compatible forms):++ year YEAR apply year YEAR++ The space is optional. This sets a default year to be used for subse-+ quent dates which don't specify a year. Eg:++ Y2009 ; set default year to 2009++ 12/15 ; equivalent to 2009/12/15+ expenses 1+ assets++ year 2010 ; change default year to 2010++ 2009/1/30 ; specifies the year, not affected+ expenses 1+ assets++ 1/31 ; equivalent to 2010/1/31+ expenses 1+ assets++ Downsides: omitting the year (from primary transaction dates, at least)+ makes your financial data less explicit, less portable, and less trust-+ worthy in an audit. Such dates can get separated from their corre-+ sponding Y directive, eg when evaluating a region of the journal in+ your editor. A missing Y directive makes reports dependent on today's+ date.++ Secondary dates+ 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".++ Downsides: makes your financial data more complicated, less portable,+ and less trustworthy in an audit. Keeping the meaning of the two dates+ consistent requires discipline, and you have to remember which report-+ ing mode is appropriate for a given report. Posting dates are simpler+ and better.++ Star comments+ Lines beginning with * (star/asterisk) are also comment lines. This+ feature allows Emacs users to insert org headings in their journal, al-+ lowing them to fold/unfold/navigate it like an outline when viewed with+ org mode.++ Downsides: another, unconventional comment syntax to learn. Decreases+ your journal's portability. And switching to Emacs org mode just for+ folding/unfolding meant losing the benefits of ledger mode; nowadays+ you can add outshine mode to ledger mode to get folding without losing+ ledger mode's features.++ Valuation expressions+ Ledger allows a valuation function or value to be written in double+ parentheses after an amount. hledger ignores these.++ Virtual postings+ A posting with parentheses around the account name, like (some:account)+ 10, is called an unbalanced virtual posting. These postings do not+ participate in transaction balancing. (And if you write them without+ an amount, a zero amount is always inferred.) These can occasionally+ be convenient for special circumstances, but they violate double entry+ bookkeeping and make your data less portable across applications, so+ many people avoid using them at all.++ A posting with brackets around the account name ([some:account]) is+ called a balanced virtual posting. The balanced virtual postings in a+ transaction must add up to zero, just like ordinary postings, but sepa-+ rately from them. These are not part of double entry bookkeeping ei-+ ther, but they are at least balanced. An example:++ 2022-01-01 buy food with cash, update budget envelope subaccounts, & something else+ assets:cash $-10 ; <- these balance each other+ expenses:food $7 ; <-+ expenses:food $3 ; <-+ [assets:checking:budget:food] $-10 ; <- and these balance each other+ [assets:checking:available] $10 ; <-+ (something:else) $5 ; <- this is not required to balance++ Ordinary postings, whose account names are neither parenthesised nor+ bracketed, are called real postings. You can exclude virtual postings+ from reports with the -R/--real flag or a real:1 query.++ Other Ledger directives+ These other Ledger directives are currently accepted but ignored. This+ allows hledger to read more Ledger files, but be aware that hledger's+ reports may differ from Ledger's if you use these.++ apply fixed COMM AMT+ apply tag TAG+ assert EXPR+ bucket / A ACCT+ capture ACCT REGEX+ check EXPR+ define VAR=EXPR+ end apply fixed+ end apply tag+ end apply year+ end tag+ eval / expr EXPR+ python+ PYTHONCODE+ tag NAME+ value EXPR+ --command-line-flags++ See also https://hledger.org/ledger.html for a detailed hledger/Ledger+ syntax comparison.++ Other cost/lot notations+ A slight digression for Ledger and Beancount users. Ledger has a num-+ ber of cost/lot-related notations:++ o @ UNITCOST and @@ TOTALCOST++ o expresses a conversion rate, as in hledger++ o when buying, also creates a lot than can be selected at selling+ time++ o (@) UNITCOST and (@@) TOTALCOST (virtual cost)++ o like the above, but also means "this cost was exceptional, don't+ use it when inferring market prices".++ Currently, hledger treats the above like @ and @@; the parentheses are+ ignored.++ o {=FIXEDUNITCOST} and {{=FIXEDTOTALCOST}} (fixed price)++ o when buying, means "this cost is also the fixed price, don't let it+ fluctuate in value reports"++ o {UNITCOST} and {{TOTALCOST}} (lot price)++ o can be used identically to @ UNITCOST and @@ TOTALCOST, also cre-+ ates a lot++ o when selling, combined with @ ..., specifies an investment lot by+ its cost basis; does not check if that lot is present++ o and related: [YYYY/MM/DD] (lot date)++ o when buying, attaches this acquisition date to the lot++ o when selling, selects a lot by its acquisition date++ o (SOME TEXT) (lot note)++ o when buying, attaches this note to the lot++ o when selling, selects a lot by its note++ Currently, hledger accepts any or all of the above in any order after+ the posting amount, but ignores them. (This can break transaction bal-+ ancing.)++ For Beancount users, the notation and behaviour is different:++ o @ UNITCOST and @@ TOTALCOST++ o expresses a cost without creating a lot, as in hledger++ o when buying (augmenting) or selling (reducing) a lot, combined with+ {...}: documents the cost/selling price (not used for transaction+ balancing)++ o {UNITCOST} and {{TOTALCOST}}++ o when buying (augmenting), expresses the cost for transaction bal-+ ancing, and also creates a lot with this cost basis attached++ o when selling (reducing),++ o selects a lot by its cost basis++ o raises an error if that lot is not present or can not be selected+ unambiguously (depending on booking method configured)++ o expresses the selling price for transaction balancing++ Currently, hledger accepts the {UNITCOST}/{{TOTALCOST}} notation but+ ignores it.++ o variations: {}, {YYYY-MM-DD}, {"LABEL"}, {UNITCOST, "LABEL"}, {UNIT-+ COST, YYYY-MM-DD, "LABEL"} etc.++ Currently, hledger rejects these.++CSV+ hledger can read CSV files (Character Separated Value - usually comma,+ semicolon, or tab) containing dated records, automatically converting+ each record into a transaction.++ (To learn about writing CSV, see CSV output.)++ For best error messages when reading CSV/TSV/SSV files, make sure they+ have a corresponding .csv, .tsv or .ssv file extension or use a hledger+ file prefix (see File Extension below).++ Each CSV file must be described by a corresponding rules file.+ This contains rules describing the CSV data (header line, fields lay-+ out, date format etc.), how to construct hledger transactions from it,+ and how to categorise transactions based on description or other at-+ tributes.++ By default, hledger expects this rules file to be named like the CSV+ file, with an extra .rules extension added, in the same directory. Eg+ when asked to read foo/FILE.csv, hledger looks for foo/FILE.csv.rules.+ You can specify a different rules file with the --rules-file option.++ 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++ There's an introductory Importing CSV data tutorial on hledger.org, and+ more CSV rules examples below, and a larger collection at+ https://github.com/simonmichael/hledger/tree/master/examples/csv.++ CSV rules cheatsheet+ The following kinds of rule can appear in the rules file, in any order.+ (Blank lines and lines beginning with # or ; or * are ignored.)++ source optionally declare which file to read data+ from+ separator declare the field separator, instead of rely-+ ing on file extension+ skip skip one or more header lines at start of file+ date-format declare how to parse CSV dates/date-times+ timezone declare the time zone of ambiguous CSV+ date-times+ newest-first improve txn order when: there are multiple+ records, newest first, all with the same date+ intra-day-reversed improve txn order when: same-day txns are in+ opposite order to the overall file+ decimal-mark declare the decimal mark used in CSV amounts,+ when ambiguous+ fields list name CSV fields for easy reference, and op-+ tionally assign their values to hledger fields+ Field assignment assign a CSV value or interpolated text value+ to a hledger field+ if block conditionally assign values to hledger fields,+ or skip a record or end (skip rest of file)+ if table conditionally assign values to hledger fields,+ using compact syntax+ balance-type select which type of balance assertions/as-+ signments to generate+ include inline another CSV rules file++ Working with CSV tips can be found below, including How CSV rules are+ evaluated.++ source+ If you tell hledger to read a csv file with -f foo.csv, it will look+ for rules in foo.csv.rules. Or, you can tell it to read the rules+ file, with -f foo.csv.rules, and it will look for data in foo.csv+ (since 1.30).++ These are mostly equivalent, but the second method provides some extra+ features. For one, the data file can be missing, without causing an+ error; it is just considered empty. And, you can specify a different+ data file by adding a "source" rule:++ source ./Checking1.csv++ If you specify just a file name with no path, hledger will look for it+ in your system's downloads directory (~/Downloads, currently):++ source Checking1.csv++ And if you specify a glob pattern, hledger will read the most recent of+ the matched files (useful with repeated downloads):++ source Checking1*.csv++ See also "Working with CSV > Reading files specified by rule".++ 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.++ skip+ skip N++ The word skip followed by a number (or no number, meaning 1) tells+ hledger to ignore this many non-empty lines at the start of the input+ data. You'll need this whenever your CSV data contains header lines.+ Note, empty and blank lines are skipped automatically, so you don't+ need to count those.++ skip has a second meaning: it can be used inside if blocks (described+ below), to skip one or more records whenever the condition is true.+ Records skipped in this way are ignored, except they are still required+ to be valid CSV.++ 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-style+ date parsing pattern - see https://hackage.haskell.org/pack-+ age/time/docs/Data-Time-Format.html#v:formatTime. The pattern 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++ timezone+ timezone TIMEZONE++ When CSV contains date-times that are implicitly in some time zone+ other than yours, but containing no explicit time zone information, you+ can use this rule to declare the CSV's native time zone, which helps+ prevent off-by-one dates.++ When the CSV date-times do contain time zone information, you don't+ need this rule; instead, use %Z in date-format (or %z, %EZ, %Ez; see+ the formatTime link above).++ In either of these cases, hledger will do a time-zone-aware conversion,+ localising the CSV date-times to your current system time zone. If you+ prefer to localise to some other time zone, eg for reproducibility, you+ can (on unix at least) set the output timezone with the TZ environment+ variable, eg:++ $ TZ=-1000 hledger print -f foo.csv # or TZ=-1000 hledger import foo.csv++ timezone currently does not understand timezone names, except "UTC",+ "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", or "PDT". For+ others, use numeric format: +HHMM or -HHMM.++ newest-first+ hledger tries to ensure that the generated transactions will be ordered+ chronologically, including same-day transactions. Usually it can+ auto-detect how the CSV records are ordered. But if it encounters CSV+ where all records are on the same date, it assumes that the records are+ oldest first. If in fact the CSV's records are normally newest first,+ like:++ 2022-10-01, txn 3...+ 2022-10-01, txn 2...+ 2022-10-01, txn 1...++ you can add the newest-first rule to help hledger generate the transac-+ tions in correct order.++ # same-day CSV records are newest first+ newest-first++ intra-day-reversed+ If CSV records within a single day are ordered opposite to the overall+ record order, you can add the intra-day-reversed rule to improve the+ order of journal entries. Eg, here the overall record order is newest+ first, but same-day records are oldest first:++ 2022-10-02, txn 3...+ 2022-10-02, txn 4...+ 2022-10-01, txn 1...+ 2022-10-01, txn 2...++ # transactions within each day are reversed with respect to the overall date order+ intra-day-reversed++ 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.++ fields list+ fields FIELDNAME1, FIELDNAME2, ...++ A fields list (the word fields followed by comma-separated field names)+ is optional, but convenient. It does two things:++ 1. It names the CSV field in each column. This can be convenient if+ you are referencing them in other rules, so you can say %SomeField+ instead of remembering %13.++ 2. Whenever you use one of the special hledger field names (described+ below), it assigns the CSV value in this position to that hledger+ field. This is the quickest way to populate hledger's fields and+ build a transaction.++ Here's an example that says "use the 1st, 2nd and 4th fields as the+ transaction's date, description and amount; name the last two fields+ for later reference; and ignore the others":++ fields date, description, , amount, , , somefield, anotherfield++ In a fields list, the separator is always comma; it is unrelated to the+ CSV file's separator. Also:++ o 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 Field names may contain _ (underscore) or - (hyphen).++ o Fields you don't care about can be given a dummy name or an empty+ name.++ If the CSV contains column headings, it's convenient to use these for+ your field names, suitably modified (eg lower-cased with spaces re-+ placed by underscores).++ Sometimes you may want to alter a CSV field name to avoid assigning to+ a hledger field with the same name. Eg you could call the CSV's "bal-+ ance" field balance_ to avoid directly setting hledger's balance field+ (and generating a balance assertion).++ Field assignment+ HLEDGERFIELD 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 either by their 1-based position in the+ CSV record (%N) or by the name they were given in the fields list+ (%CSVFIELD), and regular expression match groups (\N).++ 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 " be-+ comes 1 when interpolated) (#1051).++ o Interpolations always refer to a CSV field - you can't interpolate a+ hledger field. (See Referencing other fields below).++ Field names+ Note the two kinds of field names mentioned here, and used only in+ hledger CSV rules files:++ 1. CSV field names (CSVFIELD in these docs): you can optionally name+ the CSV columns for easy reference (since hledger doesn't yet auto-+ matically recognise column headings in a CSV file), by writing arbi-+ trary names in a fields list, eg:++ fields When, What, Some_Id, Net, Total, Foo, Bar++ 2. Special hledger field names (HLEDGERFIELD in these docs): you must+ set at least some of these to generate the hledger transaction from+ a CSV record, by writing them as the left hand side of a field as-+ signment, eg:++ date %When+ code %Some_Id+ description %What+ comment %Foo %Bar+ amount1 $ %Total++ or directly in a fields list:++ fields date, description, code, , amount1, Foo, Bar+ currency $+ comment %Foo %Bar++ Here are all the special hledger field names available, and what hap-+ pens when you assign values to them:++ 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.++ You can assign multi-line comments by writing literal \n in the code.+ A comment starting with \n will begin on a new line.++ Comments can contain 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, in conditional rules.++ If a posting's account name is left unset but its amount is set (see+ below), a default account name will be chosen (like "expenses:unknown"+ or "income:unknown").++ amount field+ There are several ways to set posting amounts from CSV, useful in dif-+ ferent situations.++ 1. amount is the oldest and simplest. Assigning to this sets the+ amount of the first and second postings. In the second posting, the+ amount will be negated; also, if it has a cost attached, it will be+ converted to cost.++ 2. amount-in and amount-out work exactly like the above, but should be+ used when the CSV has two amount fields (such as "Debit" and+ "Credit", or "Inflow" and "Outflow"). Whichever field has a+ non-zero value will be used as the amount of the first and second+ postings. Here are some tips to avoid confusion:++ o It's not "amount-in for posting 1 and amount-out for posting 2",+ it is "extract a single amount from the amount-in or amount-out+ field, and use that for posting 1 and (negated) for posting 2".++ o Don't use both amount and amount-in/amount-out in the same rules+ file; choose based on whether the amount is in a single CSV field+ or spread across two fields.++ o In each record, at most one of the two CSV fields should contain+ a non-zero amount; the other field must contain a zero or noth-+ ing.++ o hledger assumes both CSV fields contain unsigned numbers, and it+ automatically negates the amount-out values.++ o If the data doesn't fit these requirements, you'll probably need+ an if rule (see below).++ 3. amountN (where N is a number from 1 to 99) sets the amount of only a+ single posting: the Nth posting in the transaction. You'll usually+ need at least two such assignments to make a balanced transaction.+ You can also generate more than two postings, to represent more com-+ plex transactions. The posting numbers don't have to be consecu-+ tive; with if rules, higher posting numbers can be useful to ensure+ a certain order of postings.++ 4. amountN-in and amountN-out work exactly like the above, but should+ be used when the CSV has two amount fields. This is analogous to+ amount-in and amount-out, and those tips also apply here.++ 5. Remember that a fields list can also do assignments. So in a fields+ list if you name a CSV field "amount", that counts as assigning to+ amount. (If you don't want that, call it something else in the+ fields list, like "amount_".)++ 6. The above don't handle every situation; if you need more flexibil-+ ity, use an if rule to set amounts conditionally. See "Working with+ CSV > Setting amounts" below for more on this and on amount-setting+ generally.++ currency field+ currency sets a currency symbol, to be prepended to all postings'+ 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 the Working with CSV tips below for more about setting amounts and+ currency.++ if block+ Rules can be applied conditionally, depending on patterns in the CSV+ data. This allows flexibility; in particular, it is how you can cate-+ gorise transactions, selecting an appropriate account name based on+ their description (for example). There are two ways to write condi-+ tional rules: "if blocks", described here, and "if tables", described+ below.++ An if block is the word if and one or more "matcher" expressions (can+ be a word or phrase), one per line, starting either on the same or next+ line; followed by one or more indented rules. Eg,++ if MATCHER+ RULE++ or++ if+ MATCHER+ MATCHER+ MATCHER+ RULE+ RULE++ If any of the matchers succeeds, all of the indented rules will be ap-+ plied. They are usually field assignments, but the following special+ rules may also be used within an if block:++ o skip - skips the matched CSV record (generating no transaction from+ it)++ o end - skips the rest of the current CSV file.++ Some examples:++ # if the record contains "groceries", set account2 to "expenses:groceries"+ if groceries+ account2 expenses:groceries++ # if the record contains any of these phrases, set account2 and a transaction comment as shown+ if+ monthly service fee+ atm transaction fee+ banking thru software+ account2 expenses:business:banking+ comment XXX deductible ? check it++ # if an empty record is seen (assuming five fields), ignore the rest of the CSV file+ if ,,,,+ end++ Matchers+ There are two kinds:++ 1. A record matcher is a word or single-line text fragment or regular+ expression (REGEX), which hledger will try to match case-insensi-+ tively anywhere within the CSV record.+ Eg: whole foods++ 2. A field matcher is preceded with a percent sign and CSV field name+ (%CSVFIELD REGEX). hledger will try to match these just within the+ named CSV field.+ Eg: %date 2023++ The regular expression is (as usual in hledger) a POSIX extended regu-+ lar expression, that also supports GNU word boundaries (\b, \B, \<,+ \>), and nothing else. If you have trouble, see "Regular expressions"+ in the hledger manual (https://hledger.org/hledger.html#regular-expres-+ sions).++ What matchers match+ With record matchers, it's important to know that the record matched is+ not the original CSV record, but a modified one: separators will be+ converted to commas, and enclosing double quotes (but not enclosing+ whitespace) are removed. So for example, when reading an SSV file, if+ the original record was:++ 2023-01-01; "Acme, Inc."; 1,000++ the regex would see, and try to match, this modified record text:++ 2023-01-01,Acme, Inc., 1,000++ Combining matchers+ When an if block has multiple matchers, they are combined as follows:++ o By default they are OR'd (any of them can match)++ o When a matcher is preceded by ampersand (&, at the start of the line)+ it will be AND'ed with the previous matcher (all in the AND'ed group+ must match)++ o Added in 1.32 When a matcher is preceded by an exclamation mark (!),+ it is negated (it must not match).++ Note currently there is a limitation: you can't use both & and ! on the+ same line (you can't AND a negated matcher).++ Match groups+ Added in 1.32++ Matchers can define match groups: parenthesised portions of the regular+ expression which are available for reference in field assignments.+ Groups are enclosed in regular parentheses (( and )) and can be nested.+ Each group is available in field assignments using the token \N, where+ N is an index into the match groups for this conditional block (e.g.+ \1, \2, etc.).++ Example: Warp credit card payment postings to the beginning of the+ billing period (Month start), to match how they are presented in state-+ ments, using posting dates:++ if %date (....-..)-..+ comment2 date:\1-01++ Another example: Read the expense account from the CSV field, but throw+ away a prefix:++ if %account1 liabilities:family:(expenses:.*)+ account1 \1++ if table+ "if tables" are an alternative to if blocks; they can express many+ matchers and field assignments in a more compact tabular format, like+ this:++ if,HLEDGERFIELD1,HLEDGERFIELD2,...+ MATCHERA,VALUE1,VALUE2,...+ MATCHERB,VALUE1,VALUE2,...+ ; Comment line that explains MATCHERC+ MATCHERC,VALUE1,VALUE2,...+ <empty line>++ The first character after if is taken to be this if table's field sepa-+ rator. It is unrelated to the separator used in the CSV file. It+ should be a non-alphanumeric character like , or | that does not appear+ anywhere else in the table (it should not be used in field names or+ matchers or values, and it cannot be escaped with a backslash).++ Each line must contain the same number of separators; empty values are+ allowed. Whitespace can be used in the matcher lines for readability+ (but not in the if line, currently). You can use the comment lines in+ the table body. The table must be terminated by an empty line (or end+ of file).++ An if table like the above is interpreted as follows: try all of the+ matchers; whenever a matcher succeeds, assign all of the values on that+ line to the corresponding hledger fields; If multiple lines match,+ later lines will override fields assigned by the earlier ones - just+ like the sequence of if blocks would behave.++ If table presented above is equivalent to this sequence of if blocks:++ if MATCHERA+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++ if MATCHERB+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++ ; Comment line which explains MATCHERC+ if MATCHERC+ HLEDGERFIELD1 VALUE1+ HLEDGERFIELD2 VALUE2+ ...++ Example:++ if,account2,comment+ atm transaction fee,expenses:business:banking,deductible? check it+ %description groceries,expenses:groceries,+ ;; Comment line that desribes why this particular date is special+ 2023/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out++ 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++ 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++ Working with CSV+ Some 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 eradman.com/entrproject:++ $ 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+ Note that hledger will only accept valid CSV conforming to RFC 4180,+ and equivalent SSV and TSV formats (like RFC 4180 but with semicolon or+ tab as separators). This means, eg:++ o Values may be enclosed in double quotes, or not. Enclosing in single+ quotes is not allowed. (Eg 'A','B' is rejected.)++ o When values are enclosed in double quotes, spaces outside the quotes+ are not allowed. (Eg "A", "B" is rejected.)++ o When values are not enclosed in quotes, they may not contain double+ quotes. (Eg A"A, B is rejected.)++ If your CSV/SSV/TSV is not valid in this sense, you'll need to trans-+ form it before reading with hledger. Try using sed, or a more permis-+ sive CSV parser like python's csv lib.++ File Extension+ To help hledger choose the CSV file reader and show the right error+ messages (and choose the right field separator character by default),+ it's best if CSV/SSV/TSV files are named with a .csv, .ssv or .tsv+ filename extension. (More about this at Data formats.)++ When reading files with the "wrong" extension, you can ensure the CSV+ reader (and the default field separator) by prefixing the file path+ with csv:, ssv: or tsv:: Eg:++ $ hledger -f ssv:foo.dat print++ You can also override the default field separator with a separator rule+ if needed.++ Reading CSV from standard input+ You'll need the file format prefix when reading CSV from stdin also,+ since hledger assumes journal format by default. Eg:++ $ cat foo.dat | hledger -f ssv:- print++ Reading multiple CSV files+ If you use multiple -f options to read multiple CSV files at once,+ hledger will look for a correspondingly-named rules file for each CSV+ file. But if you use the --rules-file option, that rules file will be+ used for all the CSV files.++ Reading files specified by rule+ Instead of specifying a CSV file in the command line, you can specify a+ rules file, as in hledger -f foo.csv.rules CMD. By default this will+ read data from foo.csv in the same directory, but you can add a source+ rule to specify a different data file, perhaps located in your web+ browser's download directory.++ This feature was added in hledger 1.30, so you won't see it in most CSV+ rules examples. But it helps remove some of the busywork of managing+ CSV downloads. Most of your financial institutions's default CSV file-+ names are different and can be recognised by a glob pattern. So you+ can put a rule like source Checking1*.csv in foo-checking.csv.rules,+ and then periodically follow a workflow like:++ 1. Download CSV from Foo's website, using your browser's defaults++ 2. Run hledger import foo-checking.csv.rules to import any new transac-+ tions++ After import, you can: discard the CSV, or leave it where it is for a+ while, or move it into your archives, as you prefer. If you do noth-+ ing, next time your browser will save something like Checking1-2.csv,+ and hledger will use that because of the * wild card and because it is+ the most recent.++ Valid transactions+ After reading a CSV file, hledger post-processes and validates the gen-+ erated journal entries as it would for a journal file - balancing them,+ applying balance assignments, and canonicalising amount styles. Any+ errors at this stage will be reported in the usual way, displaying the+ problem entry.++ There is one exception: balance assertions, if you have generated them,+ will not be checked, since normally these will work only when the CSV+ data is part of the main journal. If you do need to check balance as-+ sertions generated from CSV right away, pipe into another hledger:++ $ hledger -f file.csv print | hledger -f- print++ Deduplicating, importing+ When you download a CSV file periodically, eg to get your latest bank+ transactions, the new file may overlap with the old one, containing+ some of the same records.++ The import command will (a) detect the new transactions, and (b) append+ just those transactions to your main journal. It is idempotent, so you+ don't have to remember how many times you ran it or with which version+ of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This+ is the easiest way to import CSV data. Eg:++ # download the latest CSV files, then run this command.+ # Note, no -f flags needed here.+ $ hledger import *.csv [--dry]++ This method works for most CSV files. (Where records have a stable+ chronological order, and new records appear only at the new end.)++ A number of other tools and workflows, hledger-specific and otherwise,+ exist for converting, deduplicating, classifying and managing CSV data.+ See:++ o https://hledger.org/cookbook.html#setups-and-workflows++ o https://plaintextaccounting.org -> data import/conversion++ Setting amounts+ Continuing from amount field above, here are more tips for amount-set-+ ting:++ 1. If the amount is in a single CSV field:+ a. If its sign indicates direction of flow:+ Assign it to amountN, to set the Nth posting's amount. N is usu-+ ally 1 or 2 but can go up to 99.++ b. If another field indicates direction of flow:+ Use one or more conditional rules to set the appropriate amount+ sign. Eg:++ # assume a withdrawal unless Type contains "deposit":+ amount1 -%Amount+ if %Type deposit+ amount1 %Amount++ 2. If the amount is in two CSV fields (such as Debit and Credit, or In+ and Out):+ a. If both fields are unsigned:+ Assign one field to amountN-in and the other to amountN-out.+ hledger will automatically negate the "out" field, and will use+ whichever field value is non-zero as posting N's amount.++ b. If either field is signed:+ You will probably need to override hledger's sign for one or the+ other field, as in the following example:++ # Negate the -out value, but only if it is not empty:+ fields date, description, amount1-in, amount1-out+ if %amount1-out [1-9]+ amount1-out -%amount1-out++ c. If both fields can contain a non-zero value (or both can be+ empty):+ The -in/-out rules normally choose the value which is+ non-zero/non-empty. Some value pairs can be ambiguous, such as 1+ and none. For such cases, use conditional rules to help select the+ amount. Eg, to handle the above you could select the value con-+ taining non-zero digits:++ fields date, description, in, out+ if %in [1-9]+ amount1 %in+ if %out [1-9]+ amount1 %out++ 3. If you want posting 2's amount converted to cost:+ Use the unnumbered amount (or amount-in and amount-out) syntax.++ 4. If the CSV has only balance amounts, not transaction amounts:+ Assign to balanceN, to set a balance assignment on the Nth posting,+ causing the posting's amount to be calculated automatically. balance+ with no number is equivalent to balance1. In this situation hledger is+ more likely to guess the wrong default account name, so you may need to+ set that explicitly.++ Amount signs+ There is some special handling making it easier to parse and to reverse+ amount signs. (This only works for whole amounts, not for cost amounts+ such as COST in amount1 AMT @ COST):++ 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+ "".++ It's not possible (without preprocessing the CSV) to set an amount to+ its absolute value, ie discard its sign.++ Setting currency/commodity+ If the currency/commodity symbol is included in the CSV's amount+ field(s):++ 2023-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++ 2023-01-01 foo+ expenses:unknown $123.00+ income:unknown $-123.00++ If the currency is provided as a separate CSV field:++ 2023-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++ 2023-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++ 2023-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 re-+ peated, the last one wins:++ o skip (at top level)++ o date-format++ o newest-first++ o fields - names the CSV fields, optionally sets up initial assignments+ to hledger fields++ Then for each CSV record in turn:++ o test all if blocks. If any of them contain a end rule, skip all re-+ maining CSV records. Otherwise if any of them contain a skip rule,+ skip that many CSV records. If there are multiple matched skip+ rules, the first one wins.++ o collect all field assignments at top level and in matched if blocks.+ When there are multiple assignments for a field, keep only the last+ one.++ o compute a value for each hledger field - either the one that was as-+ signed to it (and interpolate the %CSVFIELD references), or a default++ o generate a hledger transaction (journal entry) from these values.++ This is all part of the CSV reader, one of several readers hledger can+ use to parse input files. When all files have been read successfully,+ the transactions are passed as input to whichever hledger command the+ user specified.++ Well factored rules+ Some things than can help reduce duplication and complexity in rules+ files:++ o Extracting common rules usable with multiple CSV files into a com-+ mon.rules, and adding include common.rules to each CSV's rules file.++ o Splitting if blocks into smaller if blocks, extracting the frequently+ used parts.++ CSV rules examples+ 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.++ Coinbase+ A simple example with some CSV from Coinbase. The spot price is+ recorded using cost notation. The legacy amount field name conve-+ niently sets amount 2 (posting 2's amount) to the total cost.++ # Timestamp,Transaction Type,Asset,Quantity Transacted,Spot Price Currency,Spot Price at Transaction,Subtotal,Total (inclusive of fees and/or spread),Fees and/or Spread,Notes+ # 2021-12-30T06:57:59Z,Receive,USDC,100,GBP,0.740000,"","","","Received 100.00 USDC from an external account"++ # coinbase.csv.rules+ skip 1+ fields Timestamp,Transaction_Type,Asset,Quantity_Transacted,Spot_Price_Currency,Spot_Price_at_Transaction,Subtotal,Total,Fees_Spread,Notes+ date %Timestamp+ date-format %Y-%m-%dT%T%Z+ description %Notes+ account1 assets:coinbase:cc+ amount %Quantity_Transacted %Asset @ %Spot_Price_at_Transaction %Spot_Price_Currency++ $ hledger print -f coinbase.csv+ 2021-12-30 Received 100.00 USDC from an external account+ assets:coinbase:cc 100 USDC @ 0.740000 GBP+ income:unknown -74.000000 GBP++ 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:++Timeclock+ 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 op-+ tional. The timezone, if present, must be four digits and is ignored+ (currently the time is always interpreted as a local time). Lines be-+ ginning with # or ; or *, and blank lines, are ignored.++ i 2015/03/30 09:00:00 some account optional description after 2 spaces ; optional comment, tags:+ 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 2 spaces ; optional comment, tags:+ (some account) 0.33h++ 2015-03-31 * 22:21-23:59+ (another:account) 1.64h++ 2015-04-01 * 00:00-02:00+ (another:account) 2.01h++ 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 time-+ clock-x.el and perhaps the extras in ledgerutils.el++ o at the command line, use these bash aliases: cli 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+ timedot format is hledger's human-friendly time logging format. Com-+ pared to timeclock format, it is more convenient for quick, approxi-+ mate, and retroactive time logging, and more human-readable (you can+ see at a glance where time was spent). A quick example:++ 2023-05-01+ hom:errands .... .... ; two hours; the space is ignored+ fos:hledger:timedot .. ; half an hour+ per:admin:finance ; no time spent yet++ hledger reads this as a transaction on this day with three (unbalanced)+ postings, where each dot represents "0.25". No commodity symbol is as-+ sumed, but we typically interpret it as hours.++ $ hledger -f a.timedot print # .timedot file extension (or timedot: prefix) is required+ 2023-05-01 *+ (hom:errands) 2.00 ; two hours+ (fos:hledger:timedot) 0.50 ; half an hour+ (per:admin:finance) 0++ A timedot file contains a series of transactions (usually one per day).+ Each begins with a simple date (Y-M-D, Y/M/D, or Y.M.D), optionally be+ followed on the same line by a transaction description, and/or a trans-+ action comment following a semicolon.++ After the date line are zero or more time postings, consisting of:++ o An account name - any hledger-style account name, optionally in-+ dented.++ o Two or more spaces - required if there is an amount (as in journal+ format).++ o A timedot amount, which can be++ o empty (representing zero)++ o a number, optionally followed by a unit s, m, h, d, w, mo, or y,+ representing a precise number of seconds, minutes, hours, days+ weeks, months or years (hours is assumed by default), which will be+ converted to hours according to 60s = 1m, 60m = 1h, 24h = 1d, 7d =+ 1w, 30d = 1mo, 365d = 1y.++ o one or more dots (period characters), each representing 0.25.+ These are the dots in "timedot". Spaces are ignored and can be+ used for grouping/alignment.++ o Added in 1.32 one or more letters. These are like dots but they+ also generate a tag t: (short for "type") with the letter as its+ value, and a separate posting for each of the values. This pro-+ vides a second dimension of categorisation, viewable in reports+ with --pivot t.++ o An optional comment following a semicolon (a hledger-style posting+ comment).++ There is some flexibility to help with keeping time log data and notes+ in the same file:++ o Blank lines and lines beginning with # or ; are ignored.++ o After the first date line, lines which do not contain a double space+ are parsed as postings with zero amount. (hledger's register reports+ will show these if you add -E).++ o Before the first date line, lines beginning with * (eg org headings)+ are ignored. And from the first date line onward, Emacs org mode+ heading prefixes at the start of lines (one or more *'s followed by a+ space) will be ignored. This means the time log can also be a org+ outline.++ Timedot examples+ Numbers:++ 2016/2/3+ inc:client1 4+ fos:hledger 3h+ biz:research 60m++ Dots:++ # 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 .++ $ 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++ Letters:++ # Activity types:+ # c cleanup/catchup/repair+ # e enhancement+ # s support+ # l learning/research++ 2023-11-01+ work:adm ccecces++ $ hledger -f a.timedot print+ 2023-11-01+ (work:adm) 1 ; t:c+ (work:adm) 0.5 ; t:e+ (work:adm) 0.25 ; t:s++ $ hledger -f a.timedot bal+ 1.75 work:adm+ --------------------+ 1.75++ $ hledger -f a.timedot bal --pivot t+ 1.00 c+ 0.50 e+ 0.25 s+ --------------------+ 1.75++ Org:++ * 2023 Work Diary+ ** Q1+ *** 2023-02-29+ **** DONE+ 0700 yoga+ **** UNPLANNED+ **** BEGUN+ hom:chores+ cleaning ...+ water plants+ outdoor - one full watering can+ indoor - light watering+ **** TODO+ adm:planning: trip+ *** LATER++ Using . as account name separator:++ 2016/2/4+ fos.hledger.timedot 4h+ fos.ledger ..++ $ hledger -f a.timedot --alias '/\./=:' bal -t+ 4.50 fos+ 4.00 hledger:timedot+ 0.50 ledger+ --------------------+ 4.50++PART 3: REPORTING CONCEPTS+Amount formatting+ Commodity display style+ For the amounts in each commodity, hledger chooses a consistent display+ style (symbol placement, decimal mark and digit group marks, number of+ decimal digits) to use in most reports. This is inferred as follows:++ First, if there's a D directive declaring a default commodity, that+ commodity symbol and amount format is applied to all no-symbol amounts+ in the journal.++ Then each commodity's display style is determined from its commodity+ directive. We recommend always declaring commodities with commodity+ directives, since they help ensure consistent display styles and preci-+ sions, and bring other benefits such as error checking for commodity+ symbols. Here's an example:++ # Set display styles (and decimal marks, for parsing, if there is no decimal-mark directive)+ # for the $, EUR, INR and no-symbol commodities:+ commodity $1,000.00+ commodity EUR 1.000,00+ commodity INR 9,99,99,999.00+ commodity 1 000 000.9455++ But for convenience, if a commodity directive is not present, hledger+ infers a commodity's display styles from its amounts as they are writ-+ ten in the journal (excluding cost amounts and amounts in periodic+ transaction rules or auto posting rules). It uses++ o the symbol placement and decimal mark of the first amount seen++ o the digit group marks of the first amount with digit group marks++ o and the maximum number of decimal digits seen across all amounts.++ And as fallback if no applicable amounts are found, it would use a de-+ fault style, like $1000.00 (symbol on the left with no space, period as+ decimal mark, and two decimal digits).++ Finally, commodity styles can be overridden by the -c/--commodity-style+ command line option.++ Rounding+ Amounts are stored internally as decimal numbers with up to 255 decimal+ places. They are displayed with their original journal precisions by+ print and print-like reports, and rounded to their display precision+ (the number of decimal digits specified by the commodity display style)+ by other reports. When rounding, hledger uses banker's rounding (it+ rounds to the nearest even digit). So eg 0.5 displayed with zero deci-+ mal digits appears as "0".++ Trailing decimal marks+ If you're wondering why your print report sometimes shows trailing dec-+ imal marks, with no decimal digits; it does this when showing amounts+ that have digit group marks but no decimal digits, to disambiguate them+ and allow them to be re-parsed reliably (see Decimal marks). Eg:++ commodity $1,000.00++ 2023-01-02+ (a) $1000++ $ hledger print+ 2023-01-02+ (a) $1,000.++ If this is a problem (eg when exporting to Ledger), you can avoid it by+ disabling digit group marks, eg with -c/--commodity (for each affected+ commodity):++ $ hledger print -c '$1000.00'+ 2023-01-02+ (a) $1000++ or by forcing print to always show decimal digits, with --round:++ $ hledger print -c '$1,000.00' --round=soft+ 2023-01-02+ (a) $1,000.00++ Amount parseability+ More generally, hledger output falls into three rough categories, which+ format amounts a little bit differently to suit different consumers:++ 1. "hledger-readable output" - should be readable by hledger (and by+ humans)++ o This is produced by reports that show full journal entries: print,+ import, close, rewrite etc.++ o It shows amounts with their original journal precisions, which may+ not be consistent.++ o It adds a trailing decimal mark when needed to avoid showing ambigu-+ ous amounts.++ o It can be parsed reliably (by hledger and ledger2beancount at least,+ but perhaps not by Ledger..)++ 2. "human-readable output" - usually for humans++ o This is produced by all other reports.++ o It shows amounts with standard display precisions, which will be con-+ sistent within each commodity.++ o It shows ambiguous amounts unmodified.++ o It can be parsed reliably in the context of a known report (when you+ know decimals are consistently not being shown, you can assume a sin-+ gle mark is a digit group mark).++ 3. "machine-readable output" - usually for other software++ o This is produced by all reports when an output format like csv, tsv,+ json, or sql is selected.++ o It shows amounts as 1 or 2 do, but without digit group marks.++ o It can be parsed reliably (if needed, the decimal mark can be changed+ with -c/--commodity-style).++Time periods+ Report start & end date+ By default, most hledger reports will show the full span of time repre-+ sented by the journal. The report start date will be the earliest+ transaction or posting date, and the report end date will be the latest+ transaction, posting, or market price date.++ Often you will want to see a shorter time span, such as the current+ month. You can specify a start and/or end date using -b/--begin,+ -e/--end, -p/--period or a date: query (described below). All of these+ accept the smart date syntax (below).++ Some notes:++ o End dates are exclusive, as in Ledger, so you should write the date+ after the last day you want to see in the report.++ 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 In some cases a report interval will adjust start/end dates to fall+ on interval boundaries (see below).++ Examples:++ -b 2016/3/17 begin on St. Patrick's day 2016+ -e 12/1 end at the start of december 1st of the current year+ (11/30 will be the last date included)+ -b thismonth all transactions on or after the 1st of the current month+ -p thismonth all transactions in the current month+ date:2016/3/17.. the above written as queries instead (.. can also be re-+ placed with -)+ date:..12/1+ date:thismonth..+ date:thismonth++ Smart dates+ hledger's user interfaces accept a "smart date" syntax for added conve-+ nience. Smart dates optionally can be relative to today's date, be+ written with english words, and have less-significant parts omitted+ (missing parts are inferred as 1). Some 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+ in n n periods from the current period+ days/weeks/months/quar-+ ters/years+ n n periods from the current period+ days/weeks/months/quar-+ ters/years ahead+ n -n periods from the current period+ days/weeks/months/quar-+ ters/years ago+ 20181201 8 digit YYYYMMDD with valid year month and day+ 201812 6 digit YYYYMM with valid year and month++ Some 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++ "Today's date" can be overridden with the --today option, in case it's+ needed for testing or for recreating old reports. (Except for periodic+ transaction rules, which are not affected by --today.)++ Report intervals+ A report interval can be specified so that reports like register, bal-+ ance or activity become multi-period, showing each subperiod as a sepa-+ rate row or column.++ The following standard intervals can be enabled with command-line+ flags:++ o -D/--daily++ o -W/--weekly++ o -M/--monthly++ o -Q/--quarterly++ o -Y/--yearly++ More complex intervals can be specified using -p/--period, described+ below.++ Date adjustment+ When there is a report interval (other than daily), report start/end+ dates which have been inferred, eg from the journal, are automatically+ adjusted to natural period boundaries. This is convenient for produc-+ ing simple periodic reports. More precisely:++ o an inferred start date will be adjusted earlier if needed to fall on+ a natural period boundary++ o an inferred end date will be adjusted later if needed to make the+ last period the same length as the others.++ By contrast, start/end dates which have been specified explicitly, with+ -b, -e, -p or date:, will not be adjusted (since hledger 1.29). This+ makes it possible to specify non-standard report periods, but it also+ means that if you are specifying a start date, you should pick one+ that's on a period boundary if you want to see simple report period+ headings.++ Period expressions+ The -p/--period option specifies a period expression, which is a com-+ pact way of expressing a start date, end date, and/or report interval.++ Here's a period expression with a start and end date (specifying the+ first quarter of 2009):++ -p "from 2009/1/1 to 2009/4/1"++ Several keywords like "from" and "to" are supported for readability;+ these are optional. "to" can also be written as ".." or "-". The+ spaces are also optional, as long as you don't run two dates together.+ So the following are equivalent to the above:++ -p "2009/1/1 2009/4/1"+ -p2009/1/1to2009/4/1+ -p2009/1/1..2009/4/1++ Dates are smart dates, so if the current year is 2009, these are also+ equivalent to the above:++ -p "1/1 4/1"+ -p "jan-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 date in the journal:++ -p "from 2009/1/1" everything after january+ 1, 2009+ -p "since 2009/1" the same, since is a syn-+ onym+ -p "from 2009" the same+ -p "to 2009" everything before january+ 1, 2009++ You can also specify a period by writing a single partial or full date:++ -p "2009" the year 2009; equivalent to "2009/1/1 to 2010/1/1"+ -p "2009/1" the month of january 2009; equivalent to "2009/1/1 to+ 2009/2/1"+ -p "2009/1/1" the first day of 2009; equivalent to "2009/1/1 to+ 2009/1/2"++ or by using the "Q" quarter-year syntax (case insensitive):++ -p "2009Q1" first quarter of 2009, equivalent to "2009/1/1 to+ 2009/4/1"+ -p "q4" fourth quarter of the current year++ Period expressions with a report interval+ A period expression can also begin with a report interval, separated+ from the start/end dates (if any) by a space or the word in:++ -p "weekly from 2009/1/1 to 2009/4/1"+ -p "monthly in 2008"+ -p "quarterly"++ More complex report intervals+ Some more complex intervals can be specified within period expressions,+ such as:++ o biweekly (every two weeks)++ o fortnightly++ o bimonthly (every two months)++ o every day|week|month|quarter|year++ o every N days|weeks|months|quarters|years++ Weekly on a custom day:++ o every Nth day of week (th, nd, rd, or st are all accepted after the+ number)++ o every WEEKDAYNAME (full or three-letter english weekday name, case+ insensitive)++ Monthly on a custom day:++ o every Nth day [of month]++ o every Nth WEEKDAYNAME [of month]++ Yearly on a custom day:++ o every MM/DD [of year] (month number and day of month number)++ o every MONTHNAME DDth [of year] (full or three-letter english month+ name, case insensitive, and day of month number)++ o every DDth MONTHNAME [of year] (equivalent to the above)++ Examples:++ -p "bimonthly from 2008"+ -p "every 2 weeks"+ -p "every 5 months from+ 2009/03"+ -p "every 2nd day of week" periods will go from Tue to Tue+ -p "every Tue" same+ -p "every 15th day" period boundaries will be on 15th of each+ 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+ November+ -p "every 5th November" same+ -p "every Nov 5th" same++ Show historical balances at end of the 15th day of each month (N is an+ end date, exclusive as always):++ $ hledger balance -H -p "every 16th day"++ Group postings from the start of wednesday to end of the following+ tuesday (N is both (inclusive) start date and (exclusive) end date):++ $ hledger register checking -p "every 3rd day of week"++ Multiple weekday intervals+ This special form is also supported:++ o every WEEKDAYNAME,WEEKDAYNAME,... (full or three-letter english week-+ day names, case insensitive)++ Also, weekday and weekendday are shorthand for mon,tue,wed,thu,fri and+ sat,sun.++ This is mainly intended for use with --forecast, to generate periodic+ transactions on arbitrary days of the week. It may be less useful with+ -p, since it divides each week into subperiods of unequal length, which+ is unusual. (Related: #1632)++ Examples:++ -p "every dates will be Mon, Wed, Fri; periods will be+ mon,wed,fri" Mon-Tue, Wed-Thu, Fri-Sun+ -p "every weekday" dates will be Mon, Tue, Wed, Thu, Fri; periods will+ be Mon, Tue, Wed, Thu, Fri-Sun+ -p "every weekend- dates will be Sat, Sun; periods will be Sat, Sun-Fri+ day"++Depth+ With the --depth NUM option (short form: -NUM), reports will show ac-+ counts only to the specified depth, hiding deeper subaccounts. Use+ this when you want a summary with less detail. This flag has the same+ effect as a depth: query argument: depth:2, --depth=2 or -2 are equiva-+ lent.++Queries+ One of hledger's strengths is being able to quickly report on a precise+ subset of your data. Most hledger commands accept query arguments, to+ restrict their scope. Multiple query terms can be provided to build up+ a more complex query.++ o By default, a query term is interpreted as a case-insensitive sub-+ string pattern for matching account names:++ car:fuel+ dining groceries+ o Patterns containing spaces or other special characters must be en-+ closed in single or double quotes:++ 'personal care'+ o These patterns are actually regular expressions, so you can add reg-+ exp metacharacters for more precision (see "Regular expressions"+ above for details):++ '^expenses\b'+ 'food$'+ 'fuel|repair'+ 'accounts (payable|receivable)'+ o To match something other than account name, add one of the query type+ prefixes described in "Query types" below:++ date:202312-+ status:+ desc:amazon+ cur:USD+ cur:\\$+ amt:'>0'+ o Add a not: prefix to negate a term:++ not:status:'*'+ not:desc:'opening|closing'+ not:cur:USD+ o Terms with different types are AND-ed, terms with the same type are+ OR-ed (mostly; see "Combining query terms" below). The following+ query:++ date:2022 desc:amazon desc:amzn++ is interpreted as:++ date is in 2022 AND ( transaction description contains "amazon" OR+ "amzn" )++ 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 or REGEX+ Match account names containing this case insensitive regular expres-+ sion. This is the default query type, so we usually don't bother writ-+ ing the "acct:" prefix.++ 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 es-+ caping. 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 in-+ terval. 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.++ expr:"TERM AND NOT (TERM OR TERM)" (eg)+ Match with a boolean combination of queries (which must be enclosed in+ quotes). See Combining query terms below.++ 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.++ type:TYPECODES+ Match by account type (see Declaring accounts > Account types). TYPE-+ CODES is one or more of the single-letter account type codes ALERXCV,+ case insensitive. Note type:A and type:E will also match their respec-+ tive subtypes C (Cash) and V (Conversion). Certain kinds of account+ alias can disrupt account types, see Rewriting accounts > Aliases and+ account types.++ tag:REGEX[=REGEX]+ Match by tag name, and optionally also by tag value. (To match only by+ value, use tag:.=REGEX.)++ When querying by tag, note that:++ o Accounts also inherit the tags of their parent accounts++ o Postings also inherit the tags of their account and their transaction++ o Transactions also acquire the tags of their postings.++ (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+ When given multiple space-separated 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.++ The print command is a little different, showing 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.++ We also support more complex boolean queries with the expr: prefix.+ This allows one to combine query terms using and, or, not keywords+ (case insensitive), and to group them by enclosing in parentheses.++ Some examples:++ o Exclude account names containing 'food':++ expr:"not food" (not:food is equivalent)++ o Match things which have 'cool' in the description and the 'A' tag:++ expr:"desc:cool and tag:A" (expr:"desc:cool tag:A" is equivalent)++ o Match things which either do not reference the 'expenses:food' ac-+ count, or do have the 'A' tag:++ expr:"not expenses:food or tag:A"++ o Match things which either do not reference the 'expenses:food' ac-+ count, or which reference the 'expenses:drink' account and also have+ the 'A' tag:++ expr:"expenses:food or (expenses:drink and tag:A)"++ expr: has a restriction: date: queries may not be used inside or ex-+ pressions. That would allow disjoint report periods or disjoint result+ sets, with unclear semantics for our reports.++ Queries and command options+ Some queries can also be expressed as command-line options: depth:2 is+ equivalent to --depth 2, date:2023 is equivalent to -p 2023, etc. When+ you mix command options and query arguments, generally the resulting+ 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 re-+ ports, cur: and amt: match the old commodity symbol and the old amount+ quantity, not the new ones. (Except in hledger 1.22, #1625.)++Pivoting+ Normally, hledger groups and sums amounts within each account. The+ --pivot FIELD option substitutes some other transaction field for ac-+ count names, causing amounts to be grouped and summed by that field's+ value instead. FIELD can be any of the transaction fields acct, sta-+ tus, code, desc, payee, note, or a tag name. When pivoting on a tag+ and a posting has multiple values of that tag, only the first value is+ displayed. Values containing colon:separated:parts will be displayed+ hierarchically, like account names. Multiple, colon-delimited fields+ can be pivoted simultaneously, generating a hierarchical account name.++ Some examples:++ 2016/02/16 Yearly Dues Payment+ assets:bank account 2 EUR+ income:dues -2 EUR ; member: John Doe, kind: Lifetime++ Normal balance report showing account names:++ $ hledger balance+ 2 EUR assets:bank account+ -2 EUR income:dues+ --------------------+ 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):++ $ 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++ Hierarchical reports can be generated with multiple pivots:++ $ hledger balance Income:Dues --pivot kind:member+ -2 EUR Lifetime:John Doe+ --------------------+ -2 EUR++Generating data+ hledger has several features for generating data, such as:++ o Periodic transaction rules can generate single or repeating transac-+ tions following a template. These are usually dated in the future,+ eg to help with forecasting. They are activated by the --forecast+ option.++ o The balance command's --budget option uses these same periodic rules+ to generate goals for the budget report.++ o Auto posting rules can generate extra postings on certain matched+ transactions. They are always applied to forecast transactions; with+ the --auto flag they are applied to transactions recorded in the+ journal as well.++ o The --infer-equity flag infers missing conversion equity postings+ from @/@@ costs. And the inverse --infer-costs flag infers missing+ @/@@ costs from conversion equity postings.++ Generated data of this kind is temporary, existing only at report time.+ But you can see it in the output of hledger print, and you can save+ that to your journal, in effect converting it from temporary generated+ data to permanent recorded data. This could be useful as a data entry+ aid.++ If you are wondering what data is being generated and why, add the+ --verbose-tags flag. In hledger print output you will see extra tags+ like generated-transaction, generated-posting, and modified on gener-+ ated/modified data. Also, even without --verbose-tags, generated data+ always has equivalen hidden tags (with an underscore prefix), so eg you+ could match generated transactions with tag:_generated-transaction.++Forecasting+ Forecasting, or speculative future reporting, can be useful for esti-+ mating future balances, or for exploring different future scenarios.++ The simplest and most flexible way to do it with hledger is to manually+ record a bunch of future-dated transactions. You could keep these in a+ separate future.journal and include that with -f only when you want to+ see them.++ --forecast+ There is another way: with the --forecast option, hledger can generate+ temporary "forecast transactions" for reporting purposes, according to+ periodic transaction rules defined in the journal. Each rule can gen-+ erate multiple recurring transactions, so by changing one rule you can+ change many forecasted transactions.++ Forecast transactions usually start after ordinary transactions end.+ By default, they begin after your latest-dated ordinary transaction, or+ today, whichever is later, and they end six months from today. (The+ exact rules are a little more complicated, and are given below.)++ This is the "forecast period", which need not be the same as the report+ period. You can override it - eg to forecast farther into the future,+ or to force forecast transactions to overlap your ordinary transactions+ - by giving the --forecast option a period expression argument, like+ --forecast=..2099 or --forecast=2023-02-15... Note that the = is re-+ quired.++ Inspecting forecast transactions+ print is the best command for inspecting and troubleshooting forecast+ transactions. Eg:++ ~ monthly from 2022-12-20 rent+ assets:bank:checking+ expenses:rent $1000++ $ hledger print --forecast --today=2023/4/21+ 2023-05-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ 2023-06-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ 2023-07-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ 2023-08-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ 2023-09-20 rent+ ; generated-transaction: ~ monthly from 2022-12-20+ assets:bank:checking+ expenses:rent $1000++ Here there are no ordinary transactions, so the forecasted transactions+ begin on the first occurence after today's date. (You won't normally+ use --today; it's just to make these examples reproducible.)++ Forecast reports+ Forecast transactions affect all reports, as you would expect. Eg:++ $ hledger areg rent --forecast --today=2023/4/21+ Transactions in expenses:rent and subaccounts:+ 2023-05-20 rent as:ba:checking $1000 $1000+ 2023-06-20 rent as:ba:checking $1000 $2000+ 2023-07-20 rent as:ba:checking $1000 $3000+ 2023-08-20 rent as:ba:checking $1000 $4000+ 2023-09-20 rent as:ba:checking $1000 $5000++ $ hledger bal -M expenses --forecast --today=2023/4/21+ Balance changes in 2023-05-01..2023-09-30:++ || May Jun Jul Aug Sep+ ===============++===================================+ expenses:rent || $1000 $1000 $1000 $1000 $1000+ ---------------++-----------------------------------+ || $1000 $1000 $1000 $1000 $1000++ Forecast tags+ Forecast transactions generated by --forecast have a hidden tag, _gen-+ erated-transaction. So if you ever need to match forecast transac-+ tions, you could use tag:_generated-transaction (or just tag:generated)+ in a query.++ For troubleshooting, you can add the --verbose-tags flag. Then, visi-+ ble generated-transaction tags will be added also, so you can view them+ with the print command. Their value indicates which periodic rule was+ responsible.++ Forecast period, in detail+ Forecast start/end dates are chosen so as to do something useful by de-+ fault in almost all situations, while also being flexible. Here are+ (with luck) the exact rules, to help with troubleshooting:++ The forecast period starts on:++ o the later of++ o the start date in the periodic transaction rule++ o the start date in --forecast's argument++ o otherwise (if those are not available): the later of++ o the report start date specified with -b/-p/date:++ o the day after the latest ordinary transaction in the journal++ o otherwise (if none of these are available): today.++ The forecast period ends on:++ o the earlier of++ o the end date in the periodic transaction rule++ o the end date in --forecast's argument++ o otherwise: the report end date specified with -e/-p/date:++ o otherwise: 180 days (~6 months) from today.++ Forecast troubleshooting+ When --forecast is not doing what you expect, one of these tips should+ help:++ o Remember to use the --forecast option.++ o Remember to have at least one periodic transaction rule in your jour-+ nal.++ o Test with print --forecast.++ o Check for typos or too-restrictive start/end dates in your periodic+ transaction rule.++ o Leave at least 2 spaces between the rule's period expression and de-+ scription fields.++ o Check for future-dated ordinary transactions suppressing forecasted+ transactions.++ o Try setting explicit report start and/or end dates with -b, -e, -p or+ date:++ o Try adding the -E flag to encourage display of empty periods/zero+ transactions.++ o Try setting explicit forecast start and/or end dates with --fore-+ cast=START..END++ o Consult Forecast period, in detail, above.++ o Check inside the engine: add --debug=2 (eg).++Budgeting+ With the balance command's --budget report, each periodic transaction+ rule generates recurring budget goals in specified accounts, and goals+ and actual performance can be compared. See the balance command's doc+ below.++ You can generate budget goals and forecast transactions at the same+ time, from the same or different periodic transaction rules: hledger+ bal -M --budget --forecast ...++ See also: Budgeting and Forecasting.++Cost reporting+ In some transactions - for example a currency conversion, or a purchase+ or sale of stock - one commodity is exchanged for another. In these+ transactions there is a conversion rate, also called the cost (when+ buying) or selling price (when selling). In hledger docs we just say+ "cost", for convenience; feel free to mentally translate to "conversion+ rate" or "selling price" if helpful.++ Recording costs+ We'll explore several ways of recording transactions involving costs.+ These are also summarised at hledger Cookbook > Cost notation.++ Costs can be recorded explicitly in the journal, using the @ UNITCOST+ or @@ TOTALCOST notation described in Journal > Costs:++ Variant 1++ 2022-01-01+ assets:dollars $-135+ assets:euros 100 @ $1.35 ; $1.35 per euro (unit cost)++ Variant 2++ 2022-01-01+ assets:dollars $-135+ assets:euros 100 @@ $135 ; $135 total cost++ Typically, writing the unit cost (variant 1) is preferable; it can be+ more effort, requiring more attention to decimal digits; but it reveals+ the per-unit cost basis, and makes stock sales easier.++ Costs can also be left implicit, and hledger will infer the cost that+ is consistent with a balanced transaction:++ Variant 3++ 2022-01-01+ assets:dollars $-135+ assets:euros 100++ Here, hledger will attach a @@ 100 cost to the first amount (you can+ see it with hledger print -x). This form looks convenient, but there+ are downsides:++ o It sacrifices some error checking. For example, if you accidentally+ wrote 10 instead of 100, hledger would not be able to detect the mis-+ take.++ o It is sensitive to the order of postings - if they were reversed, a+ different entry would be inferred and reports would be different.++ o The per-unit cost basis is not easy to read.++ So generally this kind of entry is not recommended. You can make sure+ you have none of these by using -s (strict mode), or by running hledger+ check balanced.++ Reporting at cost+ Now when you add the -B/--cost flag to reports ("B" is from Ledger's+ -B/--basis/--cost flag), any amounts which have been annotated with+ costs will be converted to their cost's commodity (in the report out-+ put). Ie they will be displayed "at cost" or "at sale price".++ Some things to note:++ o Costs are attached to specific posting amounts in specific transac-+ tions, and once recorded they do not change. This contrasts with+ market prices, which are ambient and fluctuating.++ o Conversion to cost is performed before conversion to market value+ (described below).++ Equity conversion postings+ There is a problem with the entries above - they are not conventional+ Double Entry Bookkeeping (DEB) notation, and because of the "magical"+ transformation of one commodity into another, they cause an imbalance+ in the Accounting Equation. This shows up as a non-zero grand total in+ balance reports like hledger bse.++ For most hledger users, this doesn't matter in practice and can safely+ be ignored ! But if you'd like to learn more, keep reading.++ Conventional DEB uses an extra pair of equity postings to balance the+ transaction. Of course you can do this in hledger as well:++ Variant 4++ 2022-01-01+ assets:dollars $-135+ assets:euros 100+ equity:conversion $135+ equity:conversion -100++ Now the transaction is perfectly balanced according to standard DEB,+ and hledger bse's total will not be disrupted.++ And, hledger can still infer the cost for cost reporting, but it's not+ done by default - you must add the --infer-costs flag like so:++ $ hledger print --infer-costs+ 2022-01-01 one hundred euros purchased at $1.35 each+ assets:dollars $-135 @@ 100+ assets:euros 100+ equity:conversion $135+ equity:conversion -100++ $ hledger bal --infer-costs -B+ -100 assets:dollars+ 100 assets:euros+ --------------------+ 0++ Here are some downsides of this kind of entry:++ o The per-unit cost basis is not easy to read.++ o Instead of -B you must remember to type -B --infer-costs.++ o --infer-costs works only where hledger can identify the two eq-+ uity:conversion postings and match them up with the two non-equity+ postings. So writing the journal entry in a particular format be-+ comes more important. More on this below.++ Inferring equity conversion postings+ Can we go in the other direction ? Yes, if you have transactions writ-+ ten with the @/@@ cost notation, hledger can infer the missing equity+ postings, if you add the --infer-equity flag. Eg:++ 2022-01-01+ assets:dollars -$135+ assets:euros 100 @ $1.35++ $ hledger print --infer-equity+ 2022-01-01+ assets:dollars $-135+ assets:euros 100 @ $1.35+ equity:conversion:$-: -100+ equity:conversion:$-:$ $135.00++ The equity account names will be "equity:conversion:A-B:A" and "eq-+ uity:conversion:A-B:B" where A is the alphabetically first commodity+ symbol. You can customise the "equity:conversion" part by declaring an+ account with the V/Conversion account type.++ Combining costs and equity conversion postings+ Finally, you can use both the @/@@ cost notation and equity postings at+ the same time. This in theory gives the best of all worlds - preserv-+ ing the accounting equation, revealing the per-unit cost basis, and+ providing more flexibility in how you write the entry:++ Variant 5++ 2022-01-01 one hundred euros purchased at $1.35 each+ assets:dollars $-135+ equity:conversion $135+ equity:conversion -100+ assets:euros 100 @ $1.35++ All the other variants above can (usually) be rewritten to this final+ form with:++ $ hledger print -x --infer-costs --infer-equity++ Downsides:++ o The precise format of the journal entry becomes more important. If+ hledger can't detect and match up the cost and equity postings, it+ will give a transaction balancing error.++ o The add command does not yet accept this kind of entry (#2056).++ o This is the most verbose form.++ Requirements for detecting equity conversion postings+ --infer-costs has certain requirements (unlike --infer-equity, which+ always works). It will infer costs only in transactions with:++ o Two non-equity postings, in different commodities. Their order is+ significant: the cost will be added to the first of them.++ o Two postings to equity conversion accounts, next to one another,+ which balance the two non-equity postings. This balancing is checked+ to the same precision (number of decimal places) used in the conver-+ sion posting's amount. Equity conversion accounts are:++ o any accounts declared with account type V/Conversion, or their sub-+ accounts++ o otherwise, accounts named equity:conversion, equity:trade, or eq-+ uity:trading, or their subaccounts.++ And multiple such four-posting groups can coexist within a single+ transaction. When --infer-costs fails, it does not infer a cost in+ that transaction, and does not raise an error (ie, it infers costs+ where it can).++ Reading variant 5 journal entries, combining cost notation and equity+ postings, has all the same requirements. When reading such an entry+ fails, hledger raises an "unbalanced transaction" error.++ Infer cost and equity by default ?+ Should --infer-costs and --infer-equity be enabled by default ? Try+ using them always, eg with a shell alias:++ alias h="hledger --infer-equity --infer-costs"++ and let us know what problems you find.++Value reporting+ Instead of reporting amounts in their original commodity, hledger can+ convert them to cost/sale amount (using the conversion rate recorded in+ the transaction), and/or to market value (using some market price on a+ certain date). This is controlled by the --value=TYPE[,COMMODITY] op-+ tion, which will be described below. We also provide the simpler -V+ 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+ Market prices can change from day to day. hledger will use the prices+ on a particular valuation date (or on more than one date). By default+ hledger uses "end" dates for valuation. More specifically:++ o For single period reports (including normal print and register re-+ ports):++ o If an explicit report end date is specified, that is used++ o Otherwise the latest transaction date or P directive date is used+ (even if it's in the future)++ o For multiperiod reports, each period is valued on its last day.++ This can be customised with the --value option described below, which+ can select either "then", "end", "now", or "custom" dates. (Note, this+ has a bug in hledger-ui <=1.31: turning on valuation with the V key al-+ ways resets it to "end".)++ Finding market price+ To convert a commodity A to its market value in another commodity B,+ hledger looks for a suitable market price (exchange rate) as follows,+ 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-prices flag) inferred from costs.++ 2. A reverse market price: the inverse of a declared or inferred market+ price from B to A.++ 3. A forward chain of market prices: a synthetic price formed by com-+ 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-prices: 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 costs as additional market prices (as+ Ledger does) ? Adding the --infer-market-prices flag to -V, -X or+ --value enables this.++ So for example, hledger bs -V --infer-market-prices will get market+ prices both from P directives and from transactions. 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 Value reporting section carefully, and try adding+ --debug or --debug=2 to troubleshoot.++ --infer-market-prices can infer market prices from:++ o multicommodity transactions with explicit prices (@/@@)++ o multicommodity transactions with implicit prices (no @, two commodi-+ ties, unbalanced). (With these, the order of postings matters.+ hledger print -x can be useful for troubleshooting.)++ o multicommodity transactions with equity postings, if cost is inferred+ with --infer-costs.++ There is a limitation (bug) currently: when a valuation commodity is+ not specified, prices inferred with --infer-market-prices do not help+ select a default valuation commodity, as P prices would. So conversion+ might not happen because no valuation commodity was detected (--debug=2+ will show this). To be safe, specify the valuation commmodity, eg:++ o -X EUR --infer-market-prices, not -V --infer-market-prices++ o --value=then,EUR --infer-market-prices, not --value=then --infer-mar-+ ket-prices++ Signed costs and market prices can be confusing. For reference, here+ is the current behaviour, since hledger 1.25. (If you think it should+ work differently, see #1870.)++ 2022-01-01 Positive Unit prices+ a A 1+ b B -1 @ A 1++ 2022-01-01 Positive Total prices+ a A 1+ b B -1 @@ A 1+++ 2022-01-02 Negative unit prices+ a A 1+ b B 1 @ A -1++ 2022-01-02 Negative total prices+ a A 1+ b B 1 @@ A -1+++ 2022-01-03 Double Negative unit prices+ a A -1+ b B -1 @ A -1++ 2022-01-03 Double Negative total prices+ a A -1+ b B -1 @@ A -1++ All of the transactions above are considered balanced (and on each day,+ the two transactions are considered equivalent). Here are the market+ prices inferred for B:++ $ hledger -f- --infer-market-prices prices+ P 2022-01-01 B A 1+ P 2022-01-01 B A 1.0+ P 2022-01-02 B A -1+ P 2022-01-02 B A -1.0+ P 2022-01-03 B A -1+ P 2022-01-03 B A -1.0++ 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-prices flag is used: the price commodity from the+ latest transaction-inferred price for A on or before valuation date.++ This means:++ o If you have P directives, they determine which commodities -V will+ convert, and to what.++ o If you have no P directives, and use the --infer-market-prices flag,+ costs determine it.++ Amounts for which no valuation commodity can be found are not con-+ verted.++ --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.++ Valuation examples+ Here are some quick examples of -V:++ ; one euro is worth this many dollars from nov 1+ P 2016/11/01 $1.10++ ; purchase some euros on nov 3+ 2016/11/3+ assets:euros 100+ assets:checking++ ; the euro is worth fewer dollars by dec 21+ P 2016/12/21 $1.03++ How many euros do I have ?++ $ hledger -f t.j bal -N euros+ 100 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++ 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++ Interaction of valuation and queries+ When matching postings based on queries in the presence of valuation,+ the following happens:++ 1. The query is separated into two parts:++ 1. the currency (cur:) or amount (amt:).++ 2. all other parts.++ 2. The postings are matched to the currency and amount queries based on+ pre-valued amounts.++ 3. Valuation is applied to the postings.++ 4. The postings are matched to the other parts of the query based on+ post-valued amounts.++ Related: #1625++ Effect of valuation on reports+ Here is a reference for how valuation is supposed to affect each part+ of hledger's reports. (It's wide, you may need to scroll sideways.)+ It may be useful when troubleshooting. If you find problems, please+ report them, ideally with a reproducible example. Related: #329,+ #1083.++ First, a quick 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).++ Report -B, --cost -V, -X --value=then --value=end --value=DATE,+ type --value=now+ --------------------------------------------------------------------------------------------+ print+ posting cost value at re- value at posting value at re- value at+ amounts port end or date port or DATE/today+ today journal end+ balance unchanged unchanged unchanged unchanged unchanged+ asser-+ tions/as-+ signments++ register+ starting cost value at re- valued at day value at re- value at+ balance port or each historical port or DATE/today+ (-H) journal end posting was made journal end+ starting cost value at day valued at day value at day value at+ balance before re- each historical before re- DATE/today+ (-H) with port or posting was made port or+ report journal journal+ interval start start+ posting cost value at re- value at posting value at re- value at+ amounts port or date port or DATE/today+ journal end journal end+ summary summarised value at pe- sum of postings value at pe- value at+ posting cost riod ends in interval, val- riod ends DATE/today+ amounts ued at interval+ with re- start+ port in-+ terval+ running sum/average sum/average sum/average of sum/average sum/average+ total/av- of displayed of displayed displayed values of displayed of displayed+ erage values values values values++ balance+ (bs, bse,+ cf, is)+ balance sums of value at re- value at posting value at re- value at+ changes costs port end or date port or DATE/today of+ 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+ (--bud-+ get)+ grand to- sum of dis- sum of dis- sum of displayed sum of dis- sum of dis-+ tal played val- played val- valued played val- played values+ ues ues ues++ balance+ (bs, bse,+ cf, is)+ with re-+ port in-+ terval+ starting sums of value at re- sums of values of value at re- sums of post-+ balances costs of port start postings before port start ings before+ (-H) postings be- of sums of report start at of sums of report start+ fore report all postings respective post- all postings+ start before re- ing dates before re-+ port start port start+ balance sums of same as sums of values of balance value at+ changes costs of --value=end postings in pe- change in DATE/today of+ (bal, is, postings in riod at respec- each period, sums of post-+ bs period tive posting valued at ings+ --change, dates period ends+ cf+ --change)+ end bal- sums of same as sums of values of period end value at+ ances costs of --value=end postings from be- balances, DATE/today of+ (bal -H, postings fore period start valued at sums of post-+ is --H, from before to period end at period ends ings+ bs, cf) report start respective post-+ to period ing dates+ end+ budget like balance like balance like balance like bal- like balance+ amounts changes/end changes/end changes/end bal- ances changes/end+ (--bud- balances balances ances balances+ get)+ row to- sums, aver- sums, aver- sums, averages of sums, aver- sums, aver-+ tals, row ages of dis- ages of dis- displayed values ages of dis- ages of dis-+ averages played val- played val- played val- played values+ (-T, -A) ues ues ues+ column sums of dis- sums of dis- sums of displayed sums of dis- sums of dis-+ totals played val- played val- values played val- played values+ ues ues ues+ grand to- sum, average sum, average sum, average of sum, average sum, average+ tal, of column of column column totals of column of column to-+ grand av- totals totals totals tals+ erage+++ --cumulative is omitted to save space, it works like -H but with a zero+ starting balance.++PART 4: COMMANDS+ Commands overview+ Here are the built-in commands:++ DATA ENTRY+ These data entry commands are the only ones which can modify your jour-+ nal file.++ o add - add transactions using terminal prompts++ o import - add new transactions from other files, eg CSV files++ DATA CREATION+ o close - generate balance-zeroing/restoring transactions++ o rewrite - generate auto postings, like print --auto++ DATA MANAGEMENT+ o check - check for various kinds of error in the data++ o diff - compare account transactions in two journal files++ REPORTS, FINANCIAL+ 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++ REPORTS, VERSATILE+ o balance (bal) - show balance changes, end balances, budgets, gains..++ o print - show transactions or export journal data++ o register (reg) - show postings in one or more accounts & running to-+ tal++ o roi - show return on investments++ REPORTS, BASIC+ o accounts - show account names++ o activity - show bar charts of posting counts per period++ o codes - show transaction codes++ o commodities - show commodity/currency symbols++ o descriptions - show transaction descriptions++ o files - show input file paths++ o notes - show note parts of transaction descriptions++ o payees - show payee parts of transaction descriptions++ o prices - show market prices++ o stats - show journal statistics++ o tags - show tag names++ o test - run self tests++ HELP+ o help - show the hledger manual with info/man/pager++ o demo - show small hledger demos in the terminal++ ADD-ONS+ And here are some typical add-on commands. Some of these are installed+ by the hledger-install script. If installed, they will appear in+ hledger's commands list:++ o ui - run hledger's terminal UI++ o web - run hledger's web UI++ o iadd - add transactions using a TUI (currently hard to build)++ o interest - generate interest transactions++ o stockquotes - download market prices from AlphaVantage++ o Scripts and add-ons - check-fancyassertions, edit, fifo, git, move,+ pijul, plot, and more..++ Next, each command is described in detail, in alphabetical order.++ accounts+ Show account names.++ This command lists account names. By default it shows all known ac-+ counts, either used in transactions or declared with account direc-+ tives.++ With query arguments, only matched account names and account names ref-+ erenced by matched postings are shown.++ Or it can show just the used accounts (--used/-u), the declared ac-+ counts (--declared/-d), the accounts declared but not used (--unused),+ the accounts used but not declared (--undeclared), or the first account+ matched by an account name pattern, if any (--find).++ It shows a flat list by default. With --tree, it uses indentation to+ show the account hierarchy. In flat mode you can add --drop N to omit+ the first few account name components. Account names can be+ depth-clipped with depth:N or --depth N or -N.++ With --types, it also shows each account's type, if it's known. (See+ Declaring accounts > Account types.)++ With --positions, it also shows the file and line number of each ac-+ count's declaration, if any, and the account's overall declaration or-+ der; these may be useful when troubleshooting account display order.++ With --directives, it adds the account keyword, showing valid account+ directives which can be pasted into a journal file. This is useful to-+ gether with --undeclared when updating your account declarations to+ satisfy hledger check accounts.++ The --find flag can be used to look up a single account name, in the+ same way that the aregister command does. It returns the alphanumeri-+ cally-first matched account name, or if none can be found, it fails+ with a non-zero exit code.++ Examples:++ $ hledger accounts+ assets:bank:checking+ assets:bank:saving+ assets:cash+ expenses:food+ expenses:supplies+ income:gifts+ income:salary+ liabilities:debts++ $ hledger accounts --undeclared --directives >> $LEDGER_FILE+ $ hledger check accounts++ 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+ 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 main journal file (which should be in+ journal format). Existing transactions are not changed. This is one+ of the few hledger commands that writes to the journal file (see also+ import).++ To use it, just run hledger add and follow the prompts. You can add as+ many transactions as you like; when you are finished, enter . or press+ control-d or control-c to exit.++ Features:++ o add tries to provide useful defaults, using the most similar (by de-+ scription) recent transaction (filtered by the query, if any) as a+ template.++ o You can also set the initial defaults with command line arguments.++ o Readline-style edit keys can be used during data entry.++ o The tab key will auto-complete whenever possible - accounts, pay-+ ees/descriptions, dates (yesterday, today, tomorrow). If the input+ area is empty, it will insert the default value.++ o If the journal defines a default commodity, it will be added to any+ 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 https://hledger.org/add.html for a detailed tutorial):++ $ 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> $++ If you enter a number with no commodity symbol, and you have declared a+ default commodity with a D directive, you might expect add to add this+ symbol for you. It does not do this; we assume that if you are using a+ D directive you prefer not to see the commodity symbol repeated on+ amounts in the journal.++ aregister+ (areg)++ Show the transactions and running historical balance of a single ac-+ count, with each transaction displayed as one line.++ aregister shows the overall transactions affecting a particular account+ (and any subaccounts). Each report line represents one transaction in+ this account. Transactions before the report start date are always in-+ cluded in the running balance (--historical mode is always on).++ This is a more "real world", bank-like view than the register command+ (which shows individual postings, possibly from multiple accounts, not+ necessarily in historical mode). As a quick rule of thumb: - use areg-+ ister for reviewing and reconciling real-world asset/liability accounts+ - use register for reviewing detailed revenues/expenses.++ aregister requires one argument: the account to report on. You can+ write either the full account name, or a case-insensitive regular ex-+ pression which will select the alphabetically first matched account.++ When there are multiple matches, the alphabetically-first choice can be+ surprising; eg if you have assets:per:checking 1 and assets:biz:check-+ ing 2 accounts, hledger areg checking would select assets:biz:checking+ 2. It's just a convenience to save typing, so if in doubt, write the+ full account name, or a distinctive substring that matches uniquely.++ 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.++ For performance reasons, column widths are chosen based on the first+ 1000 lines; this means unusually wide values in later lines can cause+ visual discontinuities as column widths are adjusted. If you want to+ ensure perfect alignment, at the cost of more time and memory, use the+ --align-all flag.++ This command also supports the output destination and output format op-+ tions. The output formats supported are txt, csv, tsv (Added in 1.32),+ and json.++ aregister and posting dates+ aregister always shows one line (and date and amount) per transaction.+ But sometimes transactions have postings with different dates. Also,+ not all of a transaction's postings may be within the report period.+ To resolve this, aregister shows the earliest of the transaction's date+ and posting dates that is in-period, and the sum of the in-period post-+ ings. In other words it will show a combined line item with just the+ earliest date, and the running balance will (temporarily, until the+ transaction's last posting) be inaccurate. Use register -H if you need+ to see the individual postings.++ There is also a --txn-dates flag, which filters strictly by transaction+ date, ignoring posting dates. This too can cause an inaccurate running+ 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)++ o or unrealised capital gain/loss (--gain)++ o or balance changes from sibling postings (--related/-r)++ o or postings count (--count)++ ..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 (--in-+ vert)++ o rows and columns swapped (--transpose)++ o another field used as account name (--pivot)++ o custom-formatted line items (single-period reports only) (--format)++ o commodities displayed on the same line or multiple lines (--layout)++ This command supports the output destination and output format options,+ with output formats txt, csv, tsv (Added in 1.32), json, and (multi-pe-+ riod reports only:) html. In txt output in a colour-supporting termi-+ nal, 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. ("Simple" here+ means just one column of numbers, covering a single period. You can+ also have multi-period reports, described later.)++ For real-world accounts, these numbers will normally be their end bal-+ ance 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 -f examples/sample.journal bal+ $1 assets:bank:saving+ $-2 assets:cash+ $1 expenses:food+ $1 expenses:supplies+ $-1 income:gifts+ $-1 income:salary+ $1 liabilities:debts+ --------------------+ 0++ Accounts with a zero balance (and no non-zero subaccounts, in tree mode+ - see below) are hidden by default. Use -E/--empty to show them (re-+ vealing 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.++ Balance report line format+ 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 -f examples/sample.journal 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 specifies the formatting applied to each ac-+ count/balance pair. It may contain any suitable text, with data fields+ interpolated like so:++ %[MIN][.MAX](FIELDNAME)++ o MIN pads with spaces to at least this width (optional)++ o MAX truncates at this width (optional)++ o FIELDNAME must be enclosed in parentheses, and can be one of:++ o depth_spacer - a number of spaces equal to the account's depth, or+ if MIN is specified, MIN * depth spaces.++ o account - the account's name++ o total - the account's balance/posted total, right justified++ Also, FMT can begin with an optional prefix to control how multi-com-+ modity amounts are rendered:++ o %_ - render on multiple lines, bottom-aligned (the default)++ o %^ - render on multiple lines, top-aligned++ o %, - render on one line, comma-separated++ There are some quirks. Eg in one-line mode, %(depth_spacer) has no ef-+ fect, instead %(account) has indentation built in. Experimentation+ may be needed to get pleasing results.++ Some example formats:++ o %(total) - the account's total++ o %-20.20(account) - the account's name, left justified, padded to 20+ characters and clipped at 20 characters++ o %,%-50(account) %25(total) - account name padded to 50 characters,+ total padded to 20 characters, with multiple commodities rendered on+ one line++ o %20(total) %2(depth_spacer)%-(account) - the default format for the+ single-column balance report++ 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 -f examples/sample.journal 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 -f examples/sample.journal balance+ $-1 assets+ $1 bank:saving+ $-2 cash+ $2 expenses+ $1 food+ $1 supplies+ $-2 income+ $-1 gifts+ $-1 salary+ $1 liabilities:debts+ --------------------+ 0++ 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:NUM query, or --depth NUM option, or just -NUM (eg: -3)+ balance reports will show accounts only to the specified depth, hiding+ the deeper subaccounts. This can be useful for getting an overview+ without too much detail.++ Account balances at the depth limit always include the balances from+ any deeper subaccounts (even in list mode). Eg, limiting to depth 1:++ $ hledger -f examples/sample.journal balance -1+ $-1 assets+ $2 expenses+ $-2 income+ $1 liabilities+ --------------------+ 0++ Dropping top-level accounts+ You can also hide one or more top-level account name parts, using+ --drop NUM. This can be useful for hiding repetitive top-level account+ names:++ $ hledger -f examples/sample.journal bal expenses --drop 1+ $1 food+ $1 supplies+ --------------------+ $2++ Showing declared accounts+ With --declared, accounts which have been declared with an account di-+ rective will be included in the balance report, even if they have no+ transactions. (Since they will have a zero balance, you will also need+ -E/--empty to see them.)++ More precisely, leaf declared accounts (with no subaccounts) will be+ included, since those are usually the more useful in reports.++ The idea of this is to be able to see a useful "complete" balance re-+ port, even when you don't have transactions in all of your declared ac-+ counts yet.++ Sorting by amount+ With -S/--sort-amount, accounts with the largest (most positive) bal-+ ances are shown first. Eg: hledger bal expenses -MAS shows your+ biggest averaged monthly expenses first. When more than one commodity+ is present, they will be sorted by the alphabetically earliest commod-+ ity first, and then by subsequent commodities (if an amount is missing+ a commodity, it is treated as 0).++ Revenues and liability balances are typically negative, however, so -S+ shows these in reverse order. To work around this, you can add --in-+ vert to flip the signs. (Or, use one of the higher-level reports,+ 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.++ 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:++ 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 -f examples/sample.journal bal --quarterly income expenses -E+ Balance changes in 2008:++ || 2008q1 2008q2 2008q3 2008q4+ ===================++=================================+ expenses:food || 0 $1 0 0+ expenses:supplies || 0 $1 0 0+ income:gifts || 0 $-1 0 0+ income:salary || $-1 0 0 0+ -------------------++---------------------------------+ || $-1 $1 0 0++ 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.++ 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 Filter to a single currency with cur:++ o Convert to a single currency with -V [--infer-market-price]++ o Use a more compact layout like --layout=bare++ 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++ 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 ac-+ count during some period.++ An end balance is the amount accumulated in an account as of some date+ (and some time, but hledger doesn't store that; assume end of day in+ 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+ The balance command is quite flexible; here is the full detail on how+ to control what it reports. If the following seems complicated, don't+ worry - this is for advanced reporting, and it does take time and ex-+ perimentation to get familiar with all the report modes.++ There are three important option groups:++ hledger balance [CALCULATIONTYPE] [ACCUMULATIONTYPE] [VALUATIONTYPE]+ ...++ Calculation type+ The basic calculation to perform for each table cell. It is one of:++ o --sum : sum the posting amounts (default)++ o --budget : sum the amounts, but also show the budget goal amount (for+ each account/period)++ o --valuechange : show the change in period-end historical balance val-+ ues (caused by deposits, withdrawals, and/or market price fluctua-+ tions)++ o --gain : show the unrealised capital gain/loss, (the current valued+ balance minus each amount's original cost)++ o --count : show the count of postings++ Accumulation type+ How amounts should accumulate across a report's subperiods/columns.+ Another way to say it: which time period's postings should contribute+ to each cell's calculation. It is one of:++ o --change : calculate with postings from column start to column end,+ ie "just this column". Typically used to see revenues/expenses.+ (default for balance, cashflow, incomestatement)++ o --cumulative : calculate with postings from report start to column+ end, ie "previous columns plus this column". Typically used to show+ changes accumulated since the report's start date. Not often used.++ o --historical/-H : calculate with postings from journal start to col-+ umn end, ie "all postings from before report start date until this+ column's end". Typically used to see historical end balances of as-+ sets/liabilities/equity. (default for balancesheet, balancesheete-+ quity)++ Valuation type+ Which kind of value or cost conversion should be applied, if any, be-+ fore displaying the report. It is one of:++ o no valuation type : don't convert to cost or value (default)++ o --value=cost[,COMM] : convert amounts to cost (then optionally to+ some other commodity)++ o --value=then[,COMM] : convert amounts to market value on transaction+ dates++ o --value=end[,COMM] : convert amounts to market value on period end+ date(s)+ (default with --valuechange, --gain)++ o --value=now[,COMM] : convert amounts to market value on today's date++ o --value=YYYY-MM-DD[,COMM] : convert amounts to market value on an-+ other date++ or one of the equivalent simpler flags:++ o -B/--cost : like --value=cost (though, note --cost and --value are+ independent options which can both be used at once)++ o -V/--market : like --value=end++ o -X COMM/--exchange COMM : like --value=end,COMM++ See Cost reporting and Value reporting for more about these.++ Combining balance report types+ Most combinations of these options should produce reasonable reports,+ but if you find any that seem wrong or misleading, let us know. The+ 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=+ tion:> YYYY-MM-DD+ Accumu- /now+ lation:v+ -----------------------------------------------------------------------------------+ --change change in period sum of post- period-end DATE-value of+ ing-date market value of change change in pe-+ values in period in period riod+ --cumu- change from re- sum of post- period-end DATE-value of+ lative port start to ing-date market value of change change from+ period end values from re- from report report start+ port start to pe- start to period to period end+ riod end end+ --his- change from sum of post- period-end DATE-value of+ torical journal start to ing-date market value of change change from+ /-H period end (his- values from jour- from journal journal start+ torical end bal- nal start to pe- start to period to period end+ ance) riod end end++ Budget report+ The --budget report type is like a regular balance report, but with two+ main differences:++ o Budget goals and performance percentages are also shown, in brackets++ o Accounts which don't have budget goals are hidden by default.++ This is useful for comparing planned and actual income, expenses, time+ usage, etc.++ Periodic transaction rules are used to define budget goals. For exam-+ ple, here's a periodic rule defining monthly goals for bus travel and+ food expenses:++ ;; Budget+ ~ monthly+ (expenses:bus) $30+ (expenses:food) $400++ After recording some actual expenses,++ ;; Two months worth of expenses+ 2017-11-01+ income $-1950+ expenses:bus $35+ expenses:food:groceries $310+ expenses:food:dining $42+ expenses:movies $38+ assets:bank:checking++ 2017-12-01+ income $-2100+ expenses:bus $53+ expenses:food:groceries $380+ expenses:food:dining $32+ expenses:gifts $100+ assets:bank:checking++ we can see a budget report like this:++ $ hledger bal -M --budget+ Budget performance in 2017-11-01..2017-12-31:++ || Nov Dec+ ===============++============================================+ <unbudgeted> || $-425 $-565+ expenses || $425 [ 99% of $430] $565 [131% of $430]+ expenses:bus || $35 [117% of $30] $53 [177% of $30]+ expenses:food || $352 [ 88% of $400] $412 [103% of $400]+ ---------------++--------------------------------------------+ || 0 [ 0% of $430] 0 [ 0% of $430]++ This is "goal-based budgeting"; you define goals for accounts and peri-+ ods, often recurring, and hledger shows performance relative to the+ goals. This contrasts with "envelope budgeting", which is more de-+ tailed and strict - useful when cash is tight, but also quite a bit+ more work. https://plaintextaccounting.org/Budgeting has more on this+ topic.++ Using the budget report+ Historically this report has been confusing and fragile. hledger's+ version should be relatively robust and intuitive, but you may still+ find surprises. Here are more notes to help with learning and trou-+ bleshooting.++ o In the above example, expenses:bus and expenses:food are shown be-+ cause they have budget goals during the report period.++ o Their parent expenses is also shown, with budget goals aggregated+ from the children.++ o The subaccounts expenses:food:groceries and expenses:food:dining are+ not shown since they have no budget goal of their own, but they con-+ tribute to expenses:food's actual amount.++ o Unbudgeted accounts expenses:movies and expenses:gifts are also not+ shown, but they contribute to expenses's actual amount.++ o The other unbudgeted accounts income and assets:bank:checking are+ grouped as <unbudgeted>.++ o --depth or depth: can be used to limit report depth in the usual way+ (but will not reveal unbudgeted subaccounts).++ o Amounts are always inclusive of subaccounts (even in -l/--list mode).++ o Numbers displayed in a --budget report will not always agree with the+ totals, because of hidden unbudgeted accounts; this is normal.+ -E/--empty can be used to reveal the hidden accounts.++ o In the periodic rules used for setting budget goals, unbalanced post-+ ings are convenient.++ o You can filter budget reports with the usual queries, eg to focus on+ particular accounts. It's common to restrict them to just expenses.+ (The <unbudgeted> account is occasionally hard to exclude; this is+ because of date surprises, discussed below.)++ o When you have multiple currencies, you may want to convert them to+ one (-X COMM --infer-market-prices) and/or show just one at a time+ (cur:COMM). If you do need to show multiple currencies at once,+ --layout bare can be helpful.++ o You can "roll over" amounts (actual and budgeted) to the next period+ with --cumulative.++ See also: https://hledger.org/budgeting.html.++ Budget date surprises+ With small data, or when starting out, some of the generated budget+ goal transaction dates might fall outside the report periods. Eg with+ the following journal and report, the first period appears to have no+ expenses:food budget. (Also the <unbudgeted> account should be ex-+ cluded by the expenses query, but isn't.):++ ~ monthly in 2020+ (expenses:food) $500++ 2020-01-15+ expenses:food $400+ assets:checking++ $ hledger bal --budget expenses+ Budget performance in 2020-01-15:++ || 2020-01-15+ ===============++====================+ <unbudgeted> || $400+ expenses:food || 0 [ 0% of $500]+ ---------------++--------------------+ || $400 [80% of $500]++ In this case, the budget goal transactions are generated on first days+ of of month (this can be seen with hledger print --forecast tag:gener-+ ated expenses). Whereas the report period defaults to just the 15th+ day of january (this can be seen from the report table's column head-+ ings).++ To fix this kind of thing, be more explicit about the report period+ (and/or the periodic rules' dates). In this case, adding -b 2020 does+ the trick.++ Selecting budget goals+ By default, the budget report uses all available periodic transaction+ rules to generate goals. This includes rules with a different report+ interval from your report. Eg if you have daily, weekly and monthly+ periodic rules, all of these will contribute to the goals in a monthly+ budget report.++ You can select a subset of periodic rules by providing an argument to+ the --budget flag. --budget=DESCPAT will match all periodic rules+ whose description contains DESCPAT, a case-insensitive substring (not a+ regular expression or query). This means you can give your periodic+ rules descriptions (remember that two spaces are needed between period+ expression and description), and then select from multiple budgets de-+ fined in your journal.++ Budgeting vs forecasting+ --forecast and --budget both use the periodic transaction rules in the+ journal to generate temporary transactions for reporting purposes.+ However they are separate features - though you can use both at the+ same time if you want. Here are some differences between them:++ --forecast --budget+ --------------------------------------------------------------------------+ is a general option; it enables fore- is a balance command option; it+ casting with all reports selects the balance report's+ budget mode+ generates visible transactions which generates invisible transactions+ appear in reports which produce goal amounts+ generates forecast transactions from generates budget goal transac-+ after the last regular transaction, to tions throughout the report pe-+ the end of the report period; or with riod, optionally restricted by+ an argument --forecast=PERIODEXPR gen- periods specified in the peri-+ erates them throughout the specified odic transaction rules+ period, both optionally restricted by+ periods specified in the periodic+ transaction rules+ uses all periodic rules uses all periodic rules; or with+ an argument --budget=DESCPAT+ uses just the rules matched by+ DESCPAT++ Balance report layout+ The --layout option affects how balance reports show multi-commodity+ amounts and commodity symbols, which can improve readability. It can+ also normalise the data for easy consumption by other programs. It has+ four possible values:++ o --layout=wide[,WIDTH]: commodities are shown on a single line, op-+ tionally elided to WIDTH++ o --layout=tall: each commodity is shown on a separate line++ o --layout=bare: commodity symbols are in their own column, amounts are+ bare numbers++ o --layout=tidy: data is normalised to easily-consumed "tidy" form,+ with one row per data value++ Here are the --layout modes supported by each output format Only CSV+ output supports all of them:++ - txt csv html json sql+ -------------------------------------+ wide Y Y Y+ tall Y Y Y+ bare Y Y Y+ tidy Y++ Examples:++ Wide layout+ With many commodities, reports can be very wide:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide+ Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total+ ==================++====================================================================================================================================================================================================================+ Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT+ ------------------++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || 10.00 ITOT, 337.18 USD, 12.00 VEA, 106.00 VHT 70.00 GLD, 18.00 ITOT, -98.12 USD, 10.00 VEA, 18.00 VHT -11.00 ITOT, 4881.44 USD, 14.00 VEA, 170.00 VHT 70.00 GLD, 17.00 ITOT, 5120.50 USD, 36.00 VEA, 294.00 VHT++ A width limit reduces the width, but some commodities will be hidden:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=wide,32+ Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total+ ==================++===========================================================================================================================+ Assets:US:ETrade || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..+ ------------------++---------------------------------------------------------------------------------------------------------------------------+ || 10.00 ITOT, 337.18 USD, 2 more.. 70.00 GLD, 18.00 ITOT, 3 more.. -11.00 ITOT, 3 more.. 70.00 GLD, 17.00 ITOT, 3 more..++ Tall layout+ Each commodity gets a new line (may be different in each column), and+ account names are repeated:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=tall+ Balance changes in 2012-01-01..2014-12-31:++ || 2012 2013 2014 Total+ ==================++==================================================+ Assets:US:ETrade || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD+ Assets:US:ETrade || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT+ Assets:US:ETrade || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD+ Assets:US:ETrade || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA+ Assets:US:ETrade || 18.00 VHT 294.00 VHT+ ------------------++--------------------------------------------------+ || 10.00 ITOT 70.00 GLD -11.00 ITOT 70.00 GLD+ || 337.18 USD 18.00 ITOT 4881.44 USD 17.00 ITOT+ || 12.00 VEA -98.12 USD 14.00 VEA 5120.50 USD+ || 106.00 VHT 10.00 VEA 170.00 VHT 36.00 VEA+ || 18.00 VHT 294.00 VHT++ Bare layout+ Commodity symbols are kept in one column, each commodity has its own+ row, amounts are bare numbers, account names are repeated:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -T -Y --layout=bare+ Balance changes in 2012-01-01..2014-12-31:++ || Commodity 2012 2013 2014 Total+ ==================++=============================================+ Assets:US:ETrade || GLD 0 70.00 0 70.00+ Assets:US:ETrade || ITOT 10.00 18.00 -11.00 17.00+ Assets:US:ETrade || USD 337.18 -98.12 4881.44 5120.50+ Assets:US:ETrade || VEA 12.00 10.00 14.00 36.00+ Assets:US:ETrade || VHT 106.00 18.00 170.00 294.00+ ------------------++---------------------------------------------+ || GLD 0 70.00 0 70.00+ || ITOT 10.00 18.00 -11.00 17.00+ || USD 337.18 -98.12 4881.44 5120.50+ || VEA 12.00 10.00 14.00 36.00+ || VHT 106.00 18.00 170.00 294.00++ Bare layout also affects CSV output, which is useful for producing data+ that is easier to consume, eg for making charts:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -O csv --layout=bare+ "account","commodity","balance"+ "Assets:US:ETrade","GLD","70.00"+ "Assets:US:ETrade","ITOT","17.00"+ "Assets:US:ETrade","USD","5120.50"+ "Assets:US:ETrade","VEA","36.00"+ "Assets:US:ETrade","VHT","294.00"+ "total","GLD","70.00"+ "total","ITOT","17.00"+ "total","USD","5120.50"+ "total","VEA","36.00"+ "total","VHT","294.00"++ Bare layout will sometimes display an extra row for the no-symbol com-+ modity, because of zero amounts (hledger treats zeroes as commod-+ ity-less, usually). This can break hledger-bar confusingly+ (workaround: add a cur: query to exclude the no-symbol row).++ Tidy layout+ This produces normalised "tidy data" (see+ https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)+ where every variable has its own column and each row represents a sin-+ gle data point. This is the easiest kind of data for other software to+ consume:++ $ hledger -f examples/bcexample.hledger bal assets:us:etrade -3 -Y -O csv --layout=tidy+ "account","period","start_date","end_date","commodity","value"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","GLD","0"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","ITOT","10.00"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","USD","337.18"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","VEA","12.00"+ "Assets:US:ETrade","2012","2012-01-01","2012-12-31","VHT","106.00"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","GLD","70.00"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","ITOT","18.00"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","USD","-98.12"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","VEA","10.00"+ "Assets:US:ETrade","2013","2013-01-01","2013-12-31","VHT","18.00"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","GLD","0"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","ITOT","-11.00"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","USD","4881.44"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VEA","14.00"+ "Assets:US:ETrade","2014","2014-01-01","2014-12-31","VHT","170.00"++ Some 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++ 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.++ This report shows accounts declared with the Asset, Cash or Liability+ type (see account types). Or if no such accounts are declared, it+ shows top-level accounts named asset or liability (case insensitive,+ plurals allowed) and their subaccounts.++ Example:++ $ hledger balancesheet+ Balance Sheet 2008-12-31++ || 2008-12-31+ ====================++============+ Assets ||+ --------------------++------------+ assets:bank:saving || $1+ assets:cash || $-2+ --------------------++------------+ || $-1+ ====================++============+ Liabilities ||+ --------------------++------------+ liabilities:debts || $-1+ --------------------++------------+ || $-1+ ====================++============+ Net: || 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 op-+ tions The output formats supported are txt, csv, tsv (Added in 1.32),+ html, and json.++ 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.++ This report shows accounts declared with the Asset, Cash, Liability or+ Equity type (see account types). Or if no such accounts are declared,+ it shows top-level accounts named asset, liability or equity (case in-+ sensitive, plurals allowed) and their subaccounts.++ Example:++ $ hledger balancesheetequity+ Balance Sheet With Equity 2008-12-31++ || 2008-12-31+ ====================++============+ Assets ||+ --------------------++------------+ assets:bank:saving || $1+ assets:cash || $-2+ --------------------++------------+ || $-1+ ====================++============+ Liabilities ||+ --------------------++------------+ liabilities:debts || $-1+ --------------------++------------+ || $-1+ ====================++============+ Equity ||+ --------------------++------------+ --------------------++------------+ || 0+ ====================++============+ Net: || 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 report is the easiest way to see if the accounting equation (A+L+E+ = 0) is satisfied (after you have done a close --retain to merge rev-+ enues and expenses with equity, and perhaps added --infer-equity to+ balance your commodity conversions).++ This command also supports the output destination and output format op-+ tions The output formats supported are txt, csv, tsv, html, and json.++ cashflow+ (cf)++ This command displays a (simple) cashflow statement, showing the in-+ flows and outflows affecting "cash" (ie, liquid, easily convertible)+ assets. Amounts are shown with normal positive sign, as in conven-+ tional financial statements.++ This report shows accounts declared with the Cash type (see account+ types). Or if no such accounts are declared, it shows accounts++ o under a top-level account named asset (case insensitive, plural al-+ lowed)++ o whose name contains some variation of cash, bank, checking or saving.++ More precisely: all accounts matching this case insensitive regular ex-+ pression:++ ^assets?(:.+)?:(cash|bank|che(ck|que?)(ing)?|savings?|currentcash)(:|$)++ and their subaccounts.++ An example cashflow report:++ $ hledger cashflow+ Cashflow Statement 2008++ || 2008+ ====================++======+ Cash flows ||+ --------------------++------+ assets:bank:saving || $1+ assets:cash || $-2+ --------------------++------+ || $-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 op-+ tions The output formats supported are txt, csv, tsv (Added in 1.32),+ html, and json.++ 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++ If you are an Emacs user, you can also configure flycheck-hledger to+ run these checks, providing instant feedback as you edit the journal.++ Here are the checks currently available:++ Default checks+ These checks are run automatically by (almost) all hledger commands:++ o parseable - data files are in a supported format, with no syntax er-+ rors and no invalid include directives.++ o autobalanced - all transactions are balanced, after converting to+ cost. Missing amounts and missing costs are inferred automatically+ where possible.++ o assertions - all balance assertions in the journal are passing.+ (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 balanced - all transactions are balanced after converting to cost,+ without inferring missing costs. If conversion costs are required,+ they must be explicit.++ o accounts - all account names used by transactions have been declared++ o commodities - all commodity symbols used have been declared++ Other checks+ These checks can be run only by giving their names as arguments to+ check. They are more specialised and not desirable for everyone:++ o ordereddates - transactions are ordered by date within each file++ o payees - all payees used by transactions have been declared++ o recentassertions - all accounts with balance assertions have a bal-+ ance assertion within 7 days of their latest posting++ o tags - all tags used by transactions have been declared++ o uniqueleafnames - all account leaf names are unique++ Custom checks+ A few more checks are are available as separate add-on commands, in+ 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.++ More about specific checks+ hledger check recentassertions will complain if any balance-asserted+ account has postings more than 7 days after its latest balance asser-+ tion. This aims to prevent the situation where you are regularly up-+ dating your journal, but forgetting to check your balances against the+ real world, then one day must dig back through months of data to find+ an error. It assumes that adding a balance assertion requires/reminds+ you to check the real-world balance. (That may not be true if you+ auto-generate balance assertions from bank data; in that case, I recom-+ mend to import transactions uncleared, and when you manually review and+ clear them, also check the latest assertion against the real-world bal-+ ance.)++ close+ (equity)++ close generates several kinds of "closing" and/or "opening" transac-+ tions, useful in certain situations, including migrating balances to a+ new journal file, retaining earnings into equity, consolidating bal-+ ances, or viewing lots. Like print, it prints valid journal entries.+ You can append or copy these to your journal file(s) when you are happy+ with how they look.++ close currently has six modes, selected by a single mode flag:++ close --migrate+ This is the most common mode. It prints a "closing balances" transac-+ tion that zeroes out all asset and liability balances (by default), and+ an opposite "opening balances" transaction that restores them again.+ The balancing account will be equity:opening/closing balances (or an-+ other specified by --close-acct or --open-acct).++ This is useful when migrating balances to a new journal file at the+ start of a new year. Essentially, you run hledger close --mi-+ grate=NEWYEAR -e NEWYEAR and then copy the closing transaction to the+ end of the old file and the opening transaction to the start of the new+ file. The opening transaction sets correct starting balances in the+ new file when it is used alone, and the closing transaction keeps bal-+ ances correct when you use both old and new files together, by can-+ celling out the following opening transaction and preventing buildup of+ duplicated opening balances. Think of the closing/opening pair as+ "moving the balances into the next file".++ You can close a different set of accounts by providing a query. Eg if+ you want to include equity, you can add assets liabilities equity or+ type:ALE arguments. (The balancing account is always excluded.) Rev-+ enues and expenses usually are not migrated to a new file directly; see+ --retain below.++ The generated transactions will have a start: tag, with its value set+ to --migrate's NEW argument if any, for easier matching or exclusion.+ When NEW is not specified, it will be inferred if possible by incre-+ menting a number (eg a year number) within the default journal's main+ file name. The other modes behave similarly.++ close --close+ This prints just the closing balances transaction of --migrate. It is+ the default behaviour if you specify no mode flag. Using the customi-+ sation options below, you can move balances from any set of accounts to+ a different account.++ close --open+ This prints just the opening balances transaction of --migrate. It is+ similar to Ledger's equity command.++ close --assert+ This prints a "closing balances" transaction (with balances: tag), that+ just declares balance assertions for the current balances without+ changing them. It could be useful as documention and to guard against+ changes.++ close --assign+ This prints an "opening balances" transaction that restores the account+ balances using balance assignments. Balance assignments work regard-+ less of any previous balance, so a preceding closing balances transac-+ tion is not needed.++ However, omitting the closing balances transaction would unbalance eq-+ uity. This is relatively harmless for personal reports, but it dis-+ turbs the accounting equation, removing a source of error detection.+ So --migrate is generally the best way to set to set balances in new+ files, for now.++ close --retain+ This is like --close with different defaults: it prints a "retain earn-+ ings" transaction (with retain: tag), that transfers revenue and ex-+ pense balances to equity:retained earnings.++ This is a different kind of closing, called "retaining earnings" or+ "closing the books"; it is traditionally performed by businesses at the+ end of each accounting period, to consolidate revenues and expenses+ into the main equity balance. ("Revenues" and "expenses" are actually+ equity by another name, kept separate temporarily for reporting pur-+ poses.)++ In personal accounting you generally don't need to do this, unless you+ want the balancesheetequity report to show a zero total, demonstrating+ that the accounting equation (A-L=E) is satisfied.++ close customisation+ In all modes, the following things can be overridden:++ o the accounts to be closed/opened, with account query arguments++ o the balancing account, with --close-acct=ACCT and/or --open-acct=ACCT++ o the transaction descriptions, with --close-desc=DESC and+ --open-desc=DESC++ o the transaction's tag value, with a --MODE=NEW option argument++ o the closing/opening dates, with -e OPENDATE++ By default, the closing date is yesterday, or the journal's end date,+ whichever is later; and the opening date is always one day after the+ closing date. You can change these by specifying a report end date;+ the closing date will be the last day of the report period. Eg -e 2024+ means "close on 2023-12-31, open on 2024-01-01".++ With --x/--explicit, the balancing amount will be shown explicitly, and+ if it involves multiple commodities, a separate posting will be gener-+ ated for each of them (similar to print -x).++ With --interleaved, each individual transfer is shown with source and+ destination postings next to each other (perhaps useful for trou-+ bleshooting).++ With --show-costs, balances' costs are also shown, with different costs+ kept separate. This may generate very large journal entries, if you+ have many currency conversions or investment transactions. close+ --show-costs is currently the best way to view investment lots with+ hledger. (To move or dispose of lots, see the more capable+ hledger-move script.)++ close and balance assertions+ close adds balance assertions verifying that the accounts have been re-+ set to zero in a closing transaction or restored to their previous bal-+ ances in an opening transaction. These provide useful error checking,+ but you can ignore them temporarily with -I, or remove them if you pre-+ fer.++ Single-commodity, subaccount-exclusive balance assertions (=) are gen-+ erated by default. This can be changed with --assertion-type='==*'+ (eg).++ When running close you should probably avoid using -C, -R, status:+ (filtering by status or realness) or --auto (generating postings),+ since the generated balance assertions would then require these.++ Transactions with multiple dates (eg posting dates) spanning the file+ boundary also can disrupt the balance assertions:++ 2023-12-30 a purchase made in december, cleared in january+ expenses:food 5+ assets:bank:checking -5 ; date: 2023-01-02++ To solve this you can transfer the money to and from a temporary ac-+ count, splitting the multi-day transaction into two single-day transac-+ tions:++ ; in 2022.journal:+ 2022-12-30 a purchase made in december, cleared in january+ expenses:food 5+ equity:pending -5++ ; in 2023.journal:+ 2023-01-02 last year's transaction cleared+ equity:pending 5 = 0+ assets:bank:checking -5++ close examples+ Retain earnings+ Record 2022's revenues/expenses as retained earnings on 2022-12-31, ap-+ pending the generated transaction to the journal:++ $ hledger close --retain -f 2022.journal -p 2022 >> 2022.journal++ After this, to see 2022's revenues and expenses you must exclude the+ retain earnings transaction:++ $ hledger -f 2022.journal is not:desc:'retain earnings'++ Migrate balances to a new file+ Close assets/liabilities on 2022-12-31 and re-open them on 2023-01-01:++ $ hledger close --migrate -f 2022.journal -p 2022+ # copy/paste the closing transaction to the end of 2022.journal+ # copy/paste the opening transaction to the start of 2023.journal++ After this, to see 2022's end-of-year balances you must exclude the+ closing balances transaction:++ $ hledger -f 2022.journal bs not:desc:'closing balances'++ For more flexibility, it helps to tag closing and opening transactions+ with eg start:NEWYEAR, then you can ensure correct balances by exclud-+ ing all opening/closing transactions except the first, like so:++ $ hledger bs -Y -f 2021.j -f 2022.j -f 2023.j expr:'tag:start=2021 or not tag:start'+ $ hledger bs -Y -f 2021.j -f 2022.j expr:'tag:start=2021 or not tag:start'+ $ hledger bs -Y -f 2022.j -f 2023.j expr:'tag:start=2022 or not tag:start'+ $ hledger bs -Y -f 2021.j expr:'tag:start=2021 or not tag:start'+ $ hledger bs -Y -f 2022.j expr:'tag:start=2022 or not tag:start'+ $ hledger bs -Y -f 2023.j # unclosed file, no query needed++ More detailed close examples+ See examples/multi-year.++ 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:++ 2022/1/1 (123) Supermarket+ Food $5.00+ Checking++ 2022/1/2 (124) Post Office+ Postage $8.32+ Checking++ 2022/1/3 Supermarket+ Food $11.23+ Checking++ 2022/1/4 (126) Post Office+ Postage $3.21+ Checking++ $ hledger codes+ 123+ 124+ 126++ $ hledger codes -E+ 123+ 124++ 126++ commodities+ List all commodity/currency symbols used or declared in the journal.++ demo+ Play demos of hledger usage in the terminal, if asciinema is installed.++ Run this command with no argument to list the demos. To play a demo,+ write its number or a prefix or substring of its title. Tips:++ Make your terminal window large enough to see the demo clearly.++ Use the -s/--speed SPEED option to set your preferred playback speed,+ eg -s4 to play at 4x original speed or -s.5 to play at half speed. The+ default speed is 2x.++ Other asciinema options can be added following a double dash, eg --+ -i.1 to limit pauses or -- -h to list asciinema's other options.++ During playback, several keys are available: SPACE to pause/unpause, .+ to step forward (while paused), CTRL-c quit.++ Examples:++ $ hledger demo # list available demos+ $ hledger demo 1 # play the first demo at default speed (2x)+ $ hledger demo install -s4 # play the "install" demo at 4x speed++ 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+ 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+ List all files included in the journal. With a REGEX argument, only+ file names matching the regular expression (case sensitive) are shown.++ help+ Show the hledger user manual in the terminal, with info, man, or a+ pager. With a TOPIC argument, open it at that topic if possible.+ TOPIC can be any heading in the manual, or a heading prefix, case in-+ sensitive. Eg: commands, print, forecast, journal, amount, "auto post-+ ings".++ This command shows the hledger manual built in to your hledger version.+ It can be useful when offline, or when you prefer the terminal to a web+ browser, or when the appropriate hledger manual or viewing tools are+ not installed on your system.++ By default it chooses the best viewer found in $PATH, trying (in this+ order): info, man, $PAGER, less, more. You can force the use of info,+ man, or a pager with the -i, -m, or -p flags, If no viewer can be+ found, or the command is run non-interactively, it just prints the man-+ ual to stdout.++ If using info, note that version 6 or greater is needed for TOPIC+ lookup. If you are on mac you will likely have info 4.8, and should+ consider installing a newer version, eg with brew install texinfo+ (#1770).++ Examples++ $ hledger help --help # show how the help command works+ $ hledger help # show the hledger manual with info, man or $PAGER+ $ hledger help journal # show the journal topic in the hledger manual+ $ hledger help -m journal # show it with man, even if info is installed++ import+ Read new transactions added to each FILE provided as arguments since+ last run, and add them to the journal. Or with --dry-run, just print+ the transactions that would be added. Or with --catchup, just mark all+ of the FILEs' current transactions as imported, without importing them.++ This command may append new transactions to the main journal file+ (which should be in journal format). Existing transactions are not+ changed. This is one of the few hledger commands that writes to the+ journal file (see also add).++ Unlike other hledger commands, with import the journal file is an out-+ 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+ import tries to import only the transactions which are new since the+ last import, ignoring any that it has seen in previous runs. So if+ your bank's CSV includes the last three months of data, you can down-+ load and import it every month (or week, or day) and only the new+ transactions will be imported each time.++ It works as follows. For each imported FILE (usually CSV, but they+ could be any of hledger's input formats):++ o It tries to recall the latest date seen previously, reading it from a+ hidden .latest.FILE in the same directory.++ o Then it processes FILE, ignoring any transactions on or before the+ "latest seen" date.++ And after a successful import, it updates the .latest.FILE(s) for next+ time (unless --dry-run was used).++ This is a limited kind of deduplication, let's call it "date skipping".+ Within each input file, it avoids reprocessing the same dates across+ successive runs. This is a simple system that works for most+ real-world CSV files; it assumes these are true, or true enough:++ 1. new items always have the newest dates++ 2. item dates are stable across successive downloads++ 3. the order of same-date items is stable across downloads++ 4. the name of the input file is stable across downloads++ If you have a bank whose CSV dates or ordering occasionally change, you+ can reduce the chance of this happening in new transactions by import-+ ing more often, and in old transactions it doesn't matter. And remem-+ ber you can use CSV rules files as input, which is one way to ensure a+ stable file name.++ import doesn't detect other kinds of duplication, such as duplicate+ transactions within a single run. (In part, because legitimate dupli-+ cate transactions can easily occur in real-world data.) So, say you+ downloaded but forgot to import bank.1.csv, and a week later you down-+ loaded bank.2.csv with overlapping data. Now you should not import+ both of these at once (hledger import bank.1.csv bank.2.csv); the over-+ lapping transactions which appear twice would not be deduplicated since+ this is considered a single import. Instead, import these files one at+ a time, and also use the same filename each time for a common "latest+ seen" state:++ $ mv bank.1.csv bank.csv; hledger import bank.csv+ $ mv bank.2.csv bank.csv; hledger import bank.csv++ Normally you can ignore the .latest.* files, but if needed, you can+ delete them (to make all transactions unseen), or construct/modify them+ (to catch up to a certain date). The format is just a single ISO-for-+ mat date (YYYY-MM-DD), possibly repeated on multiple lines. It means+ "I have seen transactions up to this date, and this many of them occur-+ ring on that date".++ hledger print --new also uses and updates these .latest.* files, but it+ is less often used.++ Related: CSV > Working with CSV > Deduplicating, importing.++ Import testing+ With --dry-run, the transactions that will be imported are printed to+ 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'++ Note: when importing from multiple files at once, it's currently possi-+ ble for some .latest files to be updated successfully, while the actual+ import fails because of a problem in one of the files, leaving them out+ of sync (and causing some transactions to be missed). To prevent this,+ do a --dry-run first and fix any problems before the real import.++ 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+ (is)++ This command displays an income statement, showing revenues and ex-+ penses during one or more periods. Amounts are shown with normal posi-+ tive sign, as in conventional financial statements.++ This report shows accounts declared with the Revenue or Expense type+ (see account types). Or if no such accounts are declared, it shows+ top-level accounts named revenue or income or expense (case insensi-+ tive, plurals allowed) and their subaccounts.++ Example:++ $ hledger incomestatement+ Income Statement 2008++ || 2008+ ===================++======+ Revenues ||+ -------------------++------+ income:gifts || $1+ income:salary || $1+ -------------------++------+ || $2+ ===================++======+ Expenses ||+ -------------------++------+ expenses:food || $1+ expenses:supplies || $1+ -------------------++------+ || $2+ ===================++======+ Net: || 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 op-+ tions The output formats supported are txt, csv, tsv (Added in 1.32),+ html, and json.++ notes+ List the unique notes that appear in transactions.++ This command lists the unique notes that appear in transactions, in al-+ phabetic order. You can add a query to select a subset of transac-+ tions. The note is the part of the transaction description after a |+ character (or if there is no |, the whole description).++ Example:++ $ hledger notes+ Petrol+ Snacks++ payees+ 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+ Print the market prices declared with P directives. With --infer-mar-+ ket-prices, also show any additional prices inferred from costs. With+ --show-reverse, also show additional prices inferred by reversing known+ prices.++ Price amounts are always displayed with their full precision, except+ for reverse prices which are limited to 8 decimal digits.++ Prices can be filtered by a date:, cur: or amt: query.++ Generally if you run this command with --infer-market-prices --show-re-+ verse, it will show the same prices used internally to calculate value+ reports. But if in doubt, you can inspect those directly by running+ the value report with --debug=2.++ 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).++ 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/regenerate your journal you should take care to also copy+ over the directives and inter-transaction comments.++ Eg:++ $ hledger print -f examples/sample.journal date:200806+ 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++ print explicitness+ Normally, whether posting amounts are implicit or explicit is pre-+ served. For example, when an amount is omitted in the journal, it will+ not appear in the output. Similarly, if a conversion cost is implied+ but not written, it will not appear in the output.++ You can use the -x/--explicit flag to force explicit display of all+ amounts and costs. This can be useful for troubleshooting or for mak-+ ing your journal more readable and robust against data entry errors.+ -x is also implied by using any of -B,-V,-X,--value.++ The -x/--explicit flag will cause any postings with a multi-commodity+ amount (which can arise when a multi-commodity transaction has an im-+ plicit amount) to be split into multiple single-commodity postings,+ keeping the output parseable.++ print amount style+ Amounts are shown right-aligned within each transaction (but not+ aligned across all transactions; you can do that with ledger-mode in+ Emacs).++ Amounts will be (mostly) normalised to their commodity display style:+ their symbol placement, decimal mark, and digit group marks will be+ made consistent. By default, decimal digits are shown as they are+ written in the journal.++ With the --round (Added in 1.32) option, print will try increasingly+ hard to display decimal digits according to the commodity display+ styles:++ o --round=none show amounts with original precisions (default)++ o --round=soft add/remove decimal zeros in amounts (except costs)++ o --round=hard round amounts (except costs), possibly hiding signifi-+ cant digits++ o --round=all round all amounts and costs++ soft is good for non-lossy cleanup, formatting amounts more consis-+ tently where it's safe to do so.++ hard and all can cause print to show invalid unbalanced journal en-+ tries; they may be useful eg for stronger cleanup, with manual fixups+ when needed.++ print parseability+ 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 (though the same can be achieved with expr: queries+ now):++ # 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 Value reporting affects posting amounts but not balance assertion or+ balance assignment amounts, potentially causing those to fail.++ o Auto postings can generate postings with too many missing amounts.++ o Account aliases can generate bad account names.++ print, other features+ With -B/--cost, amounts with costs are shown converted to cost.++ With --new, print shows only transactions it has not seen on a previous+ run. This uses the same deduplication system as the import command.+ (See import's docs for details.)++ With -m DESC/--match=DESC, print shows one recent transaction whose de-+ scription is most similar to DESC. DESC should contain at least two+ characters. If there is no similar-enough match, no transaction will+ be shown and the program exit code will be non-zero.++ print output format+ This command also supports the output destination and output format op-+ tions The output formats supported are txt, beancount (Added in 1.32),+ csv, tsv (Added in 1.32), json and sql.++ The beancount format tries to produce Beancount-compatible output, as+ follows:++ o Transaction and postings with unmarked status are converted to+ cleared (*) status.++ o Transactions' payee and note are backslash-escaped and dou-+ ble-quote-escaped and wrapped in double quotes.++ o Transaction tags are copied to Beancount #tag format.++ o Commodity symbols are converted to upper case, and a small number of+ currency symbols like $ are converted to the corresponding currency+ names.++ o Account name parts are capitalised and unsupported characters are re-+ placed with -. If an account name part does not begin with a letter,+ or if the first part is not Assets, Liabilities, Equity, Income, or+ Expenses, an error is raised. (Use --alias options to bring your ac-+ counts into compliance.)++ o An open directive is generated for each account used, on the earliest+ transaction date.++ Some limitations:++ o Balance assertions are removed.++ o Balance assignments become missing amounts.++ o Virtual and balanced virtual postings become regular postings.++ o Directives are not converted.++ 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.)++ 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.++ For performance reasons, column widths are chosen based on the first+ 1000 lines; this means unusually wide values in later lines can cause+ visual discontinuities as column widths are adjusted. If you want to+ ensure perfect alignment, at the cost of more time and memory, use the+ --align-all flag.++ The --historical/-H flag adds the balance from any undisplayed prior+ postings to the running total. This is useful when you want to see+ only recent activity, with a historically accurate running balance:++ $ hledger register checking -b 2008/6 --historical+ 2008/06/01 gift assets:bank:checking $1 $2+ 2008/06/02 save assets:bank:checking $-1 $1+ 2008/12/31 pay off assets:bank:checking $-1 0++ The --depth option limits the amount of sub-account detail displayed.++ The --average/-A flag shows the running average posting amount instead+ of the running total (so, the final number displayed is the average for+ the whole report period). This flag implies --empty (see below). It+ is affected by --historical. It works best when showing just one ac-+ count and one commodity.++ The --related/-r flag shows the other postings in the transactions of+ the postings which would normally be shown.++ The --invert flag negates all amounts. For example, it can be used on+ an income account where amounts are normally displayed as negative num-+ bers. It's also useful to show postings on the checking account to-+ gether with the related account:++ $ hledger register --related --invert assets:checking++ With a reporting interval, register shows summary postings, one per in-+ terval, aggregating the postings to each account:++ $ hledger register --monthly income+ 2008/01 income:salary $-1 $-1+ 2008/06 income:gifts $-1 $-2++ Periods with no activity, and summary postings with a zero amount, are+ not shown by default; use the --empty/-E flag to see them:++ $ hledger register --monthly income -E+ 2008/01 income:salary $-1 $-1+ 2008/02 0 $-1+ 2008/03 0 $-1+ 2008/04 0 $-1+ 2008/05 0 $-1+ 2008/06 income:gifts $-1 $-2+ 2008/07 0 $-2+ 2008/08 0 $-2+ 2008/09 0 $-2+ 2008/10 0 $-2+ 2008/11 0 $-2+ 2008/12 0 $-2++ Often, you'll want to see just one line per interval. The --depth op-+ tion helps with this, causing subaccounts to be aggregated:++ $ hledger register --monthly assets --depth 1h+ 2008/01 assets $1 $1+ 2008/06 assets $-1 0+ 2008/12 assets $-1 $-1++ Note when using report intervals, if you specify start/end dates these+ will be adjusted outward if necessary to contain a whole number of in-+ tervals. This ensures that the first and last intervals are full+ length and comparable to the others in the report.++ With -m DESC/--match=DESC, register does a fuzzy search for one recent+ posting whose description is most similar to DESC. DESC should contain+ at least two characters. If there is no similar-enough match, no post-+ ing will be shown and the program exit code will be non-zero.++ Custom register output+ register uses the full terminal width by default, except on windows.+ You can override this by setting the COLUMNS environment variable (not+ a bash shell variable) or by using the --width/-w option.++ The description and account columns normally share the space equally+ (about half of (width - 40) each). You can adjust this by adding a de-+ scription width as part of --width's argument, comma-separated: --width+ W,D . Here's a diagram (won't display correctly in --help):++ <--------------------------------- width (W) ---------------------------------->+ date (10) description (D) account (W-41-D) amount (12) balance (12)+ DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA++ and some examples:++ $ hledger reg # use terminal width (or 80 on windows)+ $ hledger reg -w 100 # use width 100+ $ COLUMNS=100 hledger reg # set with one-time environment variable+ $ export COLUMNS=100; hledger reg # set till session end (or window resize)+ $ hledger reg -w 100,40 # set overall width 100, description width 40+ $ hledger reg -w $COLUMNS,40 # use terminal width, & description width 40++ This command also supports the output destination and output format op-+ tions The output formats supported are txt, csv, tsv (Added in 1.32),+ and json.++ rewrite+ Print all transactions, rewriting the postings of matched transactions.+ For now the only rewrite available is adding new postings, like print+ --auto.++ This is a start at a generic rewriter of transaction entries. It reads+ the default journal and prints the transactions, like print, but adds+ one or more specified postings to any transactions matching QUERY. The+ posting amounts can be fixed, or a multiplier of the existing transac-+ tion's first posting amount.++ Examples:++ $ hledger-rewrite.hs ^income --add-posting '(liabilities:tax) *.33 ; income tax' --add-posting '(reserve:gifts) $100'+ $ hledger-rewrite.hs expenses:gifts --add-posting '(reserve:gifts) *-1"'+ $ hledger-rewrite.hs -f rewrites.hledger++ rewrites.hledger may consist of entries like:++ = ^income amt:<0 date:2017+ (liabilities:tax) *0.33 ; tax on income+ (reserve:grocery) *0.25 ; reserve 25% for grocery+ (reserve:) *0.25 ; reserve 25% for grocery++ Note the single quotes to protect the dollar sign from bash, and the+ two spaces between account and amount.++ More:++ $ hledger rewrite -- [QUERY] --add-posting "ACCT AMTEXPR" ...+ $ hledger rewrite -- ^income --add-posting '(liabilities:tax) *.33'+ $ hledger rewrite -- expenses:gifts --add-posting '(budget:gifts) *-1"'+ $ hledger rewrite -- ^income --add-posting '(budget:foreign currency) *0.25 JPY; diversify'++ Argument for --add-posting option is a usual posting of transaction+ with an exception for amount specification. More precisely, you can+ use '*' (star symbol) before the amount to indicate that that this is a+ factor for an amount of original matched posting. If the amount in-+ cludes a commodity name, the new posting amount will be in the new com-+ modity; otherwise, it will be in the matched posting amount's commod-+ ity.++ Re-write rules in a file+ During the run this tool will execute so called "Automated Transac-+ tions" found in any journal it process. I.e instead of specifying this+ operations in command line you can put them in a journal file.++ $ rewrite-rules.journal++ Make contents look like this:++ = ^income+ (liabilities:tax) *.33++ = expenses:gifts+ budget:gifts *-1+ assets:budget *1++ Note that '=' (equality symbol) that is used instead of date in trans-+ actions you usually write. It indicates the query by which you want to+ match the posting to add new ones.++ $ hledger rewrite -- -f input.journal -f rewrite-rules.journal > rewritten-tidy-output.journal++ This is something similar to the commands pipeline:++ $ hledger rewrite -- -f input.journal '^income' --add-posting '(liabilities:tax) *.33' \+ | hledger rewrite -- -f - expenses:gifts --add-posting 'budget:gifts *-1' \+ --add-posting 'assets:budget *1' \+ > rewritten-tidy-output.journal++ It is important to understand that relative order of such entries in+ journal is important. You can re-use result of previously added post-+ ings.++ Diff output format+ To use this tool for batch modification of your journal files you may+ find useful output in form of unified diff.++ $ hledger rewrite -- --diff -f examples/sample.journal '^income' --add-posting '(liabilities:tax) *.33'++ Output might look like:++ --- /tmp/examples/sample.journal+ +++ /tmp/examples/sample.journal+ @@ -18,3 +18,4 @@+ 2008/01/01 income+ - assets:bank:checking $1+ + assets:bank:checking $1+ income:salary+ + (liabilities:tax) 0+ @@ -22,3 +23,4 @@+ 2008/06/01 gift+ - assets:bank:checking $1+ + assets:bank:checking $1+ income:gifts+ + (liabilities:tax) 0++ If you'll pass this through patch tool you'll get transactions contain-+ ing the posting that matches your query be updated. Note that multiple+ files might be update according to list of input files specified via+ --file options and include directives inside of these files.++ Be careful. Whole transaction being re-formatted in a style of output+ from hledger print.++ See also:++ https://github.com/simonmichael/hledger/issues/99++ rewrite vs. print --auto+ This command predates print --auto, and currently does much the same+ thing, but with these differences:++ o with multiple files, rewrite lets rules in any file affect all other+ files. print --auto uses standard directive scoping; rules affect+ only child files.++ o rewrite's query limits which transactions can be rewritten; all are+ printed. print --auto's query limits which transactions are printed.++ o rewrite applies rules specified on command line or in the journal.+ print --auto applies rules specified in the journal.++ roi+ 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 ac-+ count 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, also known as money-weighted rate of return) and time-weighted+ rate of return (TWR) for your investments for the time period re-+ quested. IRR is always annualized due to the way it is computed, but+ TWR is reported both as a rate over the chosen reporting period and as+ an annual rate.++ Price directives will be taken into account if you supply appropriate+ --cost or --value flags (see VALUATION).++ Note, in some cases this report can fail, for these reasons:++ o Error (NotBracketed): No solution for Internal Rate of Return (IRR).+ Possible causes: IRR is huge (>1000000%), balance of investment be-+ comes negative at some point in time.++ o Error (SearchFailed): Failed to find solution for Internal Rate of+ Return (IRR). Either search does not converge to a solution, or con-+ verges too slowly.++ Examples:++ o Using roi to compute total return of investment in stocks:+ https://github.com/simonmichael/hledger/blob/master/examples/invest-+ ing/roi-unrealised.ledger++ o Cookbook > Return on Investment: https://hledger.org/roi.html++ 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 as-+ sets, 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 re-+ turn.++ 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, and the+ time between them. Investment at a particular fixed interest rate is+ going to give you more interest than the same amount invested at the+ same interest rate, but made later in time. If you are withdrawing+ from your investment, your future gains would be smaller (in absolute+ numbers), and will be a smaller percentage of your initial investment,+ so your IRR will be smaller. And if you are adding to your investment,+ you will receive bigger absolute gains, which will be a bigger percent-+ age of your initial investment, so your IRR will be larger.++ 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 ac-+ count for the effect of your in-flows and out-flows, but unlike IRR it+ will try to compute the true rate of return of the underlying asset,+ compensating for the effect that deposits and withdrawas have on the+ apparent rate of growth of your investment.++ TWR represents your investment as an imaginary "unit fund" where+ in-flows/ out-flows lead to buying or selling "units" of your invest-+ ment and changes in its value change the value of "investment unit".+ Change in "unit price" over the reporting period gives you rate of re-+ turn of your investment, and make TWR less sensitive than IRR to the+ effects of cash in-flows and out-flows.++ References:++ o Explanation of rate of return++ o Explanation of IRR++ o Explanation of TWR++ o IRR vs TWR++ o Examples of computing IRR and TWR and discussion of the limitations+ of both metrics++ stats+ Show journal and performance statistics.++ The stats command shows summary information for the whole journal, or a+ matched part of it. With a reporting interval, it shows a report for+ each report period.++ The default output is fairly impersonal, though it reveals the main+ file name. With -v/--verbose, more details are shown, like file paths,+ included files, and commodity names.++ It also shows some run time statistics:++ o elapsed time++ o throughput: the number of transactions processed per second++ o live: the peak memory in use by the program to do its work++ o alloc: the peak memory allocation from the OS as seen by GHC. Mea-+ suring this externally, eg with GNU time, is more accurate; usually+ that will be a larger number; sometimes (with swapping?) smaller.++ The stats command's run time is similar to that of a balance report.++ Example:++ $ hledger stats -f examples/1ktxns-1kaccts.journal+ Main file : .../1ktxns-1kaccts.journal+ Included files : 0+ Txns span : 2000-01-01 to 2002-09-27 (1000 days)+ Last txn : 2002-09-26 (7827 days ago)+ Txns : 1000 (1.0 per day)+ Txns last 30 days : 0 (0.0 per day)+ Txns last 7 days : 0 (0.0 per day)+ Payees/descriptions : 1000+ Accounts : 1000 (depth 10)+ Commodities : 26+ Market prices : 1000+ Runtime stats : 0.12 s elapsed, 8266 txns/s, 4 MB live, 16 MB alloc++ This command supports the -o/--output-file option (but not -O/--out-+ put-format).++ tags+ List the tags used in the journal, or their values.++ This command lists the tag names used in the journal, whether on trans-+ actions, postings, or account declarations.++ With a TAGREGEX argument, only tag names matching this regular expres-+ sion (case insensitive, infix matched) are shown.++ With QUERY arguments, only transactions and accounts matching this+ query are considered. If the query involves transaction fields (date:,+ desc:, amt:, ...), the search is restricted to the matched transactions+ and their accounts.++ With the --values flag, the tags' unique non-empty values are listed+ instead. With -E/--empty, blank/empty values are also shown.++ With --parsed, tags or values are shown in the order they were parsed,+ with duplicates included. (Except, tags from account declarations are+ always shown first.)++ Tip: remember, accounts also acquire tags from their parents, postings+ also acquire tags from their account and transaction, transactions also+ acquire tags from their postings.++ 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).++PART 5: COMMON TASKS+ Here are some quick examples of how to do some basic tasks with+ hledger.++ Getting help+ Here's how to list commands and view options and command docs:++ $ hledger # show available commands+ $ hledger --help # show common options+ $ hledger CMD --help # show CMD's options, common options and CMD's documentation++ You can also view your hledger version's manual in several formats by+ using the help command. Eg:++ $ hledger help # show the hledger manual with info, man or $PAGER (best available)+ $ hledger help journal # show the journal topic in the hledger manual+ $ hledger help --help # find out more about the help command++ To view manuals and introductory docs on the web, visit+ https://hledger.org. Chat and mail list support and discussion+ archives can be found at https://hledger.org/support.++ Constructing command lines+ hledger has a flexible command line interface. We strive to keep it+ simple and ergonomic, but if you run into one of the sharp edges de-+ scribed in OPTIONS, here are some tips that might help:++ o command-specific options must go after the command (it's fine to put+ common options there too: 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 line 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+ (see below). 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 2023.journal+ $ echo "export LEDGER_FILE=$HOME/finance/2023.journal" >> ~/.profile+ $ source ~/.profile+ $ hledger stats+ Main file : /Users/simon/finance/2023.journal+ Included files :+ Transactions span : to (0 days)+ Last transaction : none+ Transactions : 0 (0.0 per day)+ Transactions last 30 days: 0 (0.0 per day)+ Transactions last 7 days : 0 (0.0 per day)+ Payees/descriptions : 0+ Accounts : 0 (depth 0)+ Commodities : 0 ()+ Market prices : 0 ()++ Setting LEDGER_FILE+ How to set LEDGER_FILE permanently depends on your setup:++ On unix and mac, running these commands in the terminal will work for+ many people; adapt as needed:++ $ echo 'export LEDGER_FILE=~/finance/2023.journal' >> ~/.profile+ $ source ~/.profile++ When correctly configured, in a new terminal window env | grep+ LEDGER_FILE will show your file, and so will hledger files.++ On mac, this additional step might be helpful for GUI applications+ (like Emacs started from the dock): add an entry to ~/.MacOSX/environ-+ ment.plist like++ {+ "LEDGER_FILE" : "~/finance/2023.journal"+ }++ and then run killall Dock in a terminal window (or restart the ma-+ chine).++ On Windows, see https://www.java.com/en/download/help/path.html, or try+ running these commands in a powershell window (let us know if it per-+ sists across a reboot, and if you need to be an Administrator):++ > CD+ > MKDIR finance+ > SETX LEDGER_FILE "C:\Users\USERNAME\finance\2023.journal"++ Setting opening balances+ Pick a starting date for which you can look up the balances of some+ real-world assets (bank accounts, wallet..) and liabilities (credit+ cards..).++ To avoid a lot of data entry, you may want to start with just one or+ two accounts, like your checking account or cash wallet; and pick a re-+ cent starting date, like today or the start of the week. You can al-+ ways come back later and add more accounts and older transactions, eg+ going back to january 1st.++ Add an opening balances transaction to the journal, declaring the bal-+ ances on this date. Here are two ways to do it:++ o The first way: open the journal in any text editor and save an entry+ like this:++ 2023-01-01 * opening balances+ assets:bank:checking $1000 = $1000+ assets:bank:savings $2000 = $2000+ assets:cash $100 = $100+ liabilities:creditcard $-50 = $-50+ equity:opening/closing balances++ 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/2023.journal+ Any command line arguments will be used as defaults.+ Use tab key to complete, readline keys to edit, enter to accept defaults.+ An optional (CODE) may follow transaction dates.+ An optional ; COMMENT may follow descriptions or amounts.+ If you make a mistake, enter < at any prompt to go one step backward.+ To end a transaction, enter . when prompted.+ To quit, enter . at a date prompt or press control-d or control-c.+ Date [2023-02-07]: 2023-01-01+ Description: * opening balances+ Account 1: assets:bank:checking+ Amount 1: $1000+ Account 2: assets:bank:savings+ Amount 2 [$-1000]: $2000+ Account 3: assets:cash+ Amount 3 [$-3000]: $100+ Account 4: liabilities:creditcard+ Amount 4 [$-3100]: $-50+ Account 5: equity:opening/closing balances+ Amount 5 [$-3050]:+ Account 6 (or . or enter to finish this transaction): .+ 2023-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++ Save this transaction to the journal ? [y]:+ Saved.+ Starting the next transaction (. or ctrl-D/ctrl-C to quit)+ Date [2023-01-01]: .++ If you're using version control, this could be a good time to commit+ the journal. Eg:++ $ git commit -m 'initial balances' 2023.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:++ 2023/1/10 * gift received+ assets:cash $20+ income:gifts++ 2023.1.12 * farmers market+ expenses:food $13+ assets:cash++ 2023-01-15 paycheck+ income:salary+ assets:bank:checking $1000++ Reconciling+ Periodically you should reconcile - compare your hledger-reported bal-+ ances against external sources of truth, like bank statements or your+ bank's website - to be sure that your ledger accurately represents the+ real-world balances (and, that the real-world institutions have not+ made a mistake!). This gets easy and fast with (1) practice and (2)+ frequency. If you do it daily, it can take 2-10 minutes. If you let+ it pile up, expect it to take longer as you hunt down errors and dis-+ crepancies.++ A typical workflow:++ 1. Reconcile cash. Count what's in your wallet. Compare with what+ hledger reports (hledger bal cash). If they are different, try to+ remember the missing transaction, or look for the error in the al-+ ready-recorded transactions. A register report can be helpful+ (hledger reg cash). If you can't find the error, add an adjustment+ transaction. Eg if you have $105 after the above, and can't explain+ the missing $2, it could be:++ 2023-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ 2. Reconcile checking. Log in to your bank's website. Compare today's+ (cleared) balance with hledger's cleared balance (hledger bal check-+ ing -C). If they are different, track down the error or record the+ missing transaction(s) or add an adjustment transaction, similar to+ the above. Unlike the cash case, you can usually compare the trans-+ action history and running balance from your bank with the one re-+ ported by hledger reg checking -C. This will be easier if you gen-+ erally record transaction dates quite similar to your bank's clear-+ ing dates.++ 3. Repeat for other asset/liability accounts.++ Tip: instead of the register command, use hledger-ui to see a live-up-+ dating register while you edit the journal: hledger-ui --watch --regis-+ ter checking -C++ After reconciling, it could be a good time to mark the reconciled+ transactions' status as "cleared and confirmed", if you want to track+ that, by adding the * marker. Eg in the paycheck transaction above,+ insert * between 2023-01-15 and paycheck++ If you're using version control, this can be another good time to com-+ mit:++ $ git commit -m 'txns' 2023.journal++ Reporting+ Here are some basic reports.++ Show all transactions:++ $ hledger print+ 2023-01-01 * opening balances+ assets:bank:checking $1000+ assets:bank:savings $2000+ assets:cash $100+ liabilities:creditcard $-50+ equity:opening/closing balances $-3050++ 2023-01-10 * gift received+ assets:cash $20+ income:gifts++ 2023-01-12 * farmers market+ expenses:food $13+ assets:cash++ 2023-01-15 * paycheck+ income:salary+ assets:bank:checking $1000++ 2023-01-16 * adjust cash+ assets:cash $-2 = $105+ expenses:misc++ 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 -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 -2+ Balance Sheet 2023-01-16++ || 2023-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 2023-01-01-2023-01-16++ || 2023-01-01-2023-01-16+ ===============++=======================+ Revenues ||+ ---------------++-----------------------+ income:gifts || $20+ income:salary || $1000+ ---------------++-----------------------+ || $1020+ ===============++=======================+ Expenses ||+ ---------------++-----------------------+ expenses:food || $13+ expenses:misc || $2+ ---------------++-----------------------+ || $15+ ===============++=======================+ Net: || $1005++ The final total is your net income during this period.++ Show transactions affecting your wallet, with running total:++ $ hledger register cash+ 2023-01-01 opening balances assets:cash $100 $100+ 2023-01-10 gift received assets:cash $20 $120+ 2023-01-12 farmers market assets:cash $-13 $107+ 2023-01-16 adjust cash assets:cash $-2 $105++ Show weekly posting counts as a bar chart:++ $ hledger activity -W+ 2019-12-30 *****+ 2023-01-06 ****+ 2023-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.++BUGS+ We welcome bug reports in the hledger issue tracker (shortcut:+ http://bugs.hledger.org), or on the #hledger chat or hledger mail list+ (https://hledger.org/support).++ Some known issues and limitations:++ The need to precede add-on command options with -- when invoked from+ hledger is awkward. (See Command options, Constructing command lines.)++ A UTF-8-aware system locale must be configured to work with non-ascii+ data. (See Unicode characters, Troubleshooting.)++ On Microsoft Windows, depending whether you are running in a CMD window+ or a Cygwin/MSYS/Mintty window and how you installed hledger, non-ascii+ characters and colours may not be supported, and the tab key may not be+ supported by hledger add. (Running in a WSL window should resolve+ these.)++ When processing large data files, hledger uses more memory than Ledger.++ Troubleshooting+ Here are some common issues you might encounter when you run hledger,+ and how to resolve them (and remember also you can usually get quick+ Support):++ PATH issues: I get an error like "No command 'hledger' found"+ Depending how you installed hledger, the executables may not be in your+ shell's PATH. Eg on unix systems, stack installs hledger in ~/.lo-+ cal/bin and cabal installs it in ~/.cabal/bin. You may need to add one+ of these directories to your shell's PATH, and/or open a new terminal+ window.++ LEDGER_FILE issues: I configured LEDGER_FILE but hledger is not using+ it+ o LEDGER_FILE should be a real environment variable, not just a shell+ variable. Eg on unix, the command env | grep LEDGER_FILE should show+ it. You may need to use export (see https://stackover-+ flow.com/a/7411509).++ o You may need to force your shell to see the new configuration. A+ simple way is to close your terminal window and open a new one.++ LANG issues: I get errors like "Illegal byte sequence" or "Invalid or+ incomplete multibyte or wide character" or "commitAndReleaseBuffer: in-+ valid argument (invalid character)"+ Programs compiled with GHC (hledger, haskell build tools, etc.) need+ the system locale to be UTF-8-aware, or they will fail when they en-+ counter non-ascii characters. To fix it, set the LANG environment+ variable to a locale which supports UTF-8 and which is installed on+ your system.++ On unix, locale -a lists the installed locales. Look for one which+ mentions utf8, UTF-8 or similar. Some examples: C.UTF-8, en_US.utf-8,+ fr_FR.utf8. If necessary, use your system package manager to install+ one. Then select it by setting the LANG environment variable. Note,+ exact spelling and capitalisation of the locale name may be important:+ Here's one common way to configure this permanently for your shell:++ $ echo "export LANG=en_US.utf8" >>~/.profile+ # close and re-open terminal window++ If you are using Nix (not NixOS) for GHC and Hledger, you might need to+ set the LOCALE_ARCHIVE variable:++ $ echo "export LOCALE_ARCHIVE=${glibcLocales}/lib/locale/locale-archive" >>~/.profile+ # close and re-open terminal window++ COMPATIBILITY ISSUES: hledger gives an error with my Ledger file+ Not all of Ledger's journal file syntax or feature set is supported.+ See hledger and Ledger for full details.++++AUTHORS+ Simon Michael <simon@joyful.com> and contributors.+ See http://hledger.org/CREDITS.html+++COPYRIGHT+ Copyright 2007-2023 Simon Michael and contributors.+++LICENSE+ Released under GNU GPL v3 or later.+++SEE ALSO+ hledger(1), hledger-ui(1), hledger-web(1), ledger(1)++hledger-1.33.1 May 2024 HLEDGER(1)