Transaction Directive¶
Overview¶
The transaction directive records a financial exchange between two or more accounts. It is the fundamental directive for recording economic activity.
Syntax¶
transaction = date WHITESPACE txn_flag
[WHITESPACE txn_strings]
[WHITESPACE tags_links]*
(NEWLINE posting)+
(NEWLINE metadata)*
txn_flag = "*" | "!" | "txn" | "P" | "#"
txn_strings = string [WHITESPACE string]
posting = WHITESPACE [posting_flag] account
[WHITESPACE amount [cost_spec] [price_annotation]]
Components¶
Date¶
The transaction date in ISO 8601 format (YYYY-MM-DD).
Flag¶
Indicates transaction status:
| Flag | Meaning | Description |
|---|---|---|
* |
Complete | Transaction verified as correct |
! |
Incomplete | Needs review or correction |
txn |
Complete | Keyword equivalent to * |
P |
Padding | Auto-generated by pad directive |
# |
Linked | Used by some plugins |
Payee and Narration¶
Transactions accept zero, one, or two strings:
; No strings
2024-01-15 *
Assets:Cash -20 USD
Expenses:Food
; One string (narration only)
2024-01-15 * "Grocery shopping"
Assets:Cash -20 USD
Expenses:Food
; Two strings (payee and narration)
2024-01-15 * "Whole Foods" "Weekly groceries"
Assets:Cash -85.50 USD
Expenses:Groceries
When two strings are provided: - First string = payee (who the transaction is with) - Second string = narration (description of transaction)
Tags and Links¶
Tags (#tag) and links (^link) appear after the strings:
2024-01-15 * "Flight to Berlin" #travel #berlin-trip ^invoice-2024-001
Expenses:Travel:Flights -450.00 USD
Liabilities:CreditCard
Postings¶
Each posting transfers an amount to or from an account.
Posting Structure¶
[flag] account [amount] [cost] [price]
Posting Flag¶
Optional flag on individual postings:
2024-01-15 * "Mixed transaction"
Assets:Checking -100 USD ; no flag
! Expenses:Food 50 USD ; flagged as incomplete
* Expenses:Coffee 50 USD ; flagged as complete
Amount¶
A number followed by a currency:
Assets:Cash 100.00 USD
Assets:Cash -50 EUR
Assets:Cash 1,234.56 CAD
Amounts support arithmetic expressions:
Expenses:Food (100 / 3) USD
Expenses:Food (50 * 1.08) USD ; with tax
Elided Amounts¶
UNDEFINED: See posting.md for the pending elision rule clarification.
2024-01-15 * "Deposit"
Assets:Checking 1000 USD
Income:Salary ; amount computed as -1000 USD
Multiple elided postings for the same currency is always an error:
; ERROR: Multiple missing amounts for USD
2024-01-15 * "Ambiguous"
Assets:Checking 100 USD
Expenses:Food
Expenses:Coffee
Balancing¶
Transactions MUST balance: the sum of all posting weights MUST equal zero for each currency.
Weight Calculation¶
| Posting Type | Weight |
|---|---|
| Simple amount | The amount |
With cost {...} |
Units × cost per unit |
With total cost {{...}} |
The total cost |
With price @ |
Units × price per unit |
With total price @@ |
The total price |
Example¶
2024-01-15 * "Buy stock"
Assets:Brokerage 10 AAPL {150 USD} ; weight: 1500 USD
Assets:Cash -1500 USD ; weight: -1500 USD
; Sum: 0 USD ✓
Cost Specification¶
Costs track the acquisition price of commodities:
; Per-unit cost
Assets:Stock 10 AAPL {150.00 USD}
; Total cost
Assets:Stock 10 AAPL {{1500.00 USD}}
; Cost with date
Assets:Stock 10 AAPL {150.00 USD, 2024-01-15}
; Cost with label
Assets:Stock 10 AAPL {150.00 USD, "lot1"}
; Full specification
Assets:Stock 10 AAPL {150.00 USD, 2024-01-15, "lot1"}
; Merge cost (average all lots)
Assets:Stock 0 AAPL {*}
See costs.md for detailed cost specification documentation.
Price Annotation¶
Prices record exchange rates without affecting balancing:
; Per-unit price
Assets:EUR 100 EUR @ 1.10 USD
; Total price
Assets:EUR 100 EUR @@ 110 USD
The price annotation does NOT affect the transaction's balance calculation when a cost is also specified.
Metadata¶
Metadata can be attached to transactions and postings:
2024-01-15 * "Purchase"
receipt: "scan.pdf"
category: "groceries"
Assets:Cash -50 USD
vendor-id: "12345"
Expenses:Food
Transaction-level metadata is indented once; posting-level metadata is indented twice.
Examples¶
Simple Transfer¶
2024-01-15 * "ATM Withdrawal"
Assets:Cash 200 USD
Assets:Checking -200 USD
Multi-Currency¶
2024-01-15 * "Currency exchange"
Assets:EUR 100 EUR @ 1.10 USD
Assets:USD -110 USD
Stock Purchase¶
2024-01-15 * "Buy Apple stock"
Assets:Brokerage 10 AAPL {185.50 USD}
Expenses:Commission 9.99 USD
Assets:Cash
Split Expense¶
2024-01-15 * "Dinner with friends" #dinner
Expenses:Food:Restaurant (75.00 / 3) USD
Assets:Receivable:Alice (75.00 / 3) USD
Assets:Receivable:Bob (75.00 / 3) USD
Assets:Cash -75.00 USD
Validation¶
The following conditions produce validation errors:
| Condition | Error Type |
|---|---|
| Transaction does not balance | ValidationError |
| Multiple postings missing amounts for same currency | ValidationError |
| Posting references account not opened | ValidationError |
| Posting references account after close | ValidationError |
Note: See validation/balance.md for rules on empty and single-posting transactions.
Implementation Notes¶
- Parse all postings before computing elided amounts
- Validate balance after all amounts are known
- Store original precision for display
- Apply tolerance rules for balance checking