1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//! Pipeline orchestration — the journal-global enrichment phases that
//! run after [`load`](crate::load) and before any filtering, conversion
//! or sorting.
//!
//! These phases must see the *whole* journal, un-filtered: the lotter
//! tracks lots FIFO across every transaction, and the translator
//! identifies pass-through accounts by their journal-wide native sum.
//! Filtering first would change those sums and corrupt the result. They
//! are also where the subtle cross-phase rules live, so they belong
//! together in one tested place rather than inlined in the CLI:
//!
//! 1. **expander** — apply `= /pattern/` auto-rules; later phases then
//! see the fully expanded journal.
//! 2. **realizer** — per-transaction fx-realized gain/loss: the trade-day
//! execution spread, where each leg's market value diverges from the
//! others. Runs on every multi-commodity transaction (buy and sell).
//! 3. **lotter** — realized capital gains via FIFO lots: the holding-
//! period market move of each disposed lot. Composes with the
//! realizer — it books capital (the market move), the realizer books
//! fx (the execution spread), so neither double-books the other.
//! 4. **translator** — currency translation adjustment (CTA) for
//! pass-through accounts. Lot-tracked assets enter at their market
//! value and leave at that same value as the `{}` cost basis, so they
//! net to zero under conversion — CTA sees no drift there.
//! 5. **revaluator** — opt-in (`-X` with `--unrealized`) mark-to-market of
//! every open foreign balance to the latest available rate, booking the
//! unrealized FX to the `fx-unrealized` accounts. Off by default, so the
//! historical (realized) view is untouched.
//!
//! `rebalance`, `filter` and `sort` are deliberately *not* here. They are
//! driven by CLI flags (pattern, date range, `-X` target, sort keys) and
//! run afterwards against the already-enriched journal. Conversion is
//! per-posting and local, so it can run after filtering; these four
//! cannot.
use crateJournal;
/// Run the journal-global enrichment phases in order, mutating
/// `journal.transactions` in place.
///
/// `target` is the resolved `-X` commodity, or `None` in native mode.
/// Phases that only make sense under conversion (realizer, translator)
/// are skipped when it is `None`; the lotter always runs when capital
/// accounts are declared (it realizes in the booked commodity either
/// way).