Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rules for detecting special postings

Here’s an overview of ways hledger infers things based on certain configurations of postings.

1. journalClassifyLotPostings (Lots.hs)

Detects lot-related postings and tags them with _ptype. Classifications:

PatternTagConditions
acquire_ptype:acquirePositive amount + cost basis {}; OR positive lotful amount (commodity/account has lots: tag)
dispose_ptype:disposeNegative amount + cost basis; OR negative lotful amount, with no opposite-sign counterpart in a different account
transfer-from_ptype:transfer-fromNegative amount + cost basis (or lotful), AND a matching positive counterpart in a different account with same commodity and exact quantity; OR negative lotful amount with no transacted price and an equity counterpart posting (equity transfer)
transfer-to_ptype:transfer-toPositive amount + cost basis with matching negative counterpart; OR positive lotful amount with no @ cost and a matching transfer-from counterpart; OR bare positive asset posting with a matching transfer-from counterpart; OR positive lot posting with an equity counterpart (equity transfer, e.g. opening balances from close –clopen –lots)
gain_ptype:gainPosting to a Gain-type account
same-account transfer_ptype:transfer-from / transfer-toWithin the same account, positive and negative postings with the same commodity and exact absolute quantity are paired as transfers

Detection is per-transaction. Transfer detection uses precomputed maps keyed by (commodity, |quantity|) for O(n) matching.


2. journalTagCostsAndEquityAndMaybeInferCosts (Journal.hs → Transaction.hs)

Detects equity conversion postings and corresponding costful postings. Called twice in the pipeline (before balancing with addcosts=False to detect, after with addcosts=True to add costs when –infer-costs).

PatternTagConditions
conversion posting pair_conversion-postingTwo adjacent postings to accounts declared as Conversion type (type V), each with a single-commodity amount and no cost
costful posting matching conversions_cost-postingA non-conversion posting whose amount matches -ca1 and whose cost matches ca2 (or vice versa), where ca1/ca2 are the conversion pair amounts
costless posting matching conversions_cost-posting(When no costful match exists) A costless single-commodity posting whose amount matches -ca1 or -ca2; must be unambiguous (no other costless posting with the same amount)

In addcosts=True mode, the matched costless posting also gets a TotalCost added.

The _cost-posting tag causes the balancer to strip costs from that posting (preventing double-counting with conversion postings).


3. journalInferEquityFromCosts (Journal.hs → Transaction.hs → Posting.hs)

Detects costful postings that lack corresponding equity conversion postings:

PatternActionConditions
costful posting without conversionsGenerates a pair of _conversion-posting + _generated-posting tagged postingsPosting has cost amounts (@ or @@) AND is NOT already tagged _cost-posting (i.e., not already matched to existing conversion postings)

For each cost amount, two conversion postings are generated under <equityAcct>:<sorted-commodities>: with amounts that offset the cost.


Summary of all hidden tags used

TagSet byMeaning
_ptype:acquirejournalClassifyLotPostingsLot acquisition
_ptype:disposejournalClassifyLotPostingsLot disposal
_ptype:transfer-fromjournalClassifyLotPostingsLot transfer source
_ptype:transfer-tojournalClassifyLotPostingsLot transfer destination
_ptype:gainjournalClassifyLotPostings / journalInferAndCheckDisposalBalancingCapital gain/loss posting
_cost-postingjournalTagCostsAndEquityAndMaybeInferCosts / journalInferEquityFromCostsHas (or could have) cost matching conversion postings
_conversion-postingjournalTagCostsAndEquityAndMaybeInferCosts / journalInferEquityFromCostsEquity conversion posting
_generated-postingjournalInferEquityFromCostsMachine-generated posting