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:GroceriesWhen 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:CreditCardPostings
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 completeAmount
A number followed by a currency:
Assets:Cash 100.00 USD
Assets:Cash -50 EUR
Assets:Cash 1,234.56 CADAmounts support arithmetic expressions:
Expenses:Food (100 / 3) USD
Expenses:Food (50 * 1.08) USD ; with taxElided 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 USDMultiple 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:CoffeeBalancing
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 USDThe 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:FoodTransaction-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 USDMulti-Currency
2024-01-15 * "Currency exchange"
Assets:EUR 100 EUR @ 1.10 USD
Assets:USD -110 USDStock Purchase
2024-01-15 * "Buy Apple stock"
Assets:Brokerage 10 AAPL {185.50 USD}
Expenses:Commission 9.99 USD
Assets:CashSplit 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 USDValidation
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