What Building a Consolidation Engine Taught Us About the Close
By Grant Deker · OneStream Solution Architect ·
We implement OneStream for a living. We also built Basin, our own consolidation and month-end close platform, from the engine up: trial balance import, FX translation, intercompany eliminations, topside journals, minority interest, three consolidated statements, and a sign-off that locks the period. Configuring those mechanisms on a client platform is one thing. Writing every one of them yourself is another. Here's what it taught us — and what it changes about how we approach a OneStream build.
The order of operations is the design
Basin's engine runs one sequence, every time: translate each entity's trial balance at the period-end rate, sum the entities into the group chart of accounts, subtract intercompany eliminations, apply posted topside journals, then carve out non-controlling interests. Written as a formula it looks almost boring — consolidated = gross − eliminations + adjustments — but the order is the design. Each step depends on data the step before it has finished shaping, and running one out of turn produces numbers that look right and aren't.
Translation is where this bites hardest. The two sides of an intercompany balance are often booked in different currencies, and after translation they don't always net to exactly zero. That difference has to land somewhere deliberate. If the design doesn't say where, it ends up in a plug, and a plug is where trust in the close goes to die.
OneStream makes this sequence explicit in its Consolidation dimension — Local, Translated, OwnerPreAdj, Share, Elimination, OwnerPostAdj, Top. Building the same pipeline by hand makes the first diagnostic question on any OneStream project obvious: which member did this number go wrong in? If a figure is right at Translated and wrong at Elimination, you've already ruled out half the rules in the application.
Every number has to carry its own receipt
Basin follows one rule throughout: the screens never re-derive a figure. The engine returns each consolidated account together with its per-entity contributions — local amount, rate, USD amount — plus the eliminations and journal impacts applied to it. Every account line on the P&L can be expanded to show exactly where it came from.
That rule shapes everything downstream, and it's the lesson that matters most for client work. Reviewers don't trust totals; they trust drill-downs. On a OneStream build, the drill paths and the cube views a controller uses to check a number belong in the design from the first workshop — not in a reporting phase after go-live, when the data model can no longer bend to support them.
Intercompany is a workflow problem, not a math problem
The elimination itself is trivial arithmetic. The hard part is that both sides have to show up. In Basin's sample group, one of the five entities is still waiting on its trial balance, so the intercompany pair that touches it stays unmatched and is flagged on the consolidation screen. The group still consolidates — but it tells you, plainly, that it's incomplete.
That's the behaviour worth designing for on any OneStream project: matching status that's visible early in the workflow, an owner for every open pair, and intercompany reconciliation scheduled on the close calendar before consolidation — not discovered during review.
Minority interest forces you to define "the group"
The moment an entity is less than wholly owned — the sample data includes one at 75% — you have to decide what the consolidated numbers mean. Basin consolidates the entity in full, then computes the outside shareholders' share of its translated net income and carves it out, so the P&L ends the statutory way: non-controlling interests, then the result attributable to the group.
The lesson isn't the calculation. It's that ownership is data with a history. It needs a proper home, an editor with the right permissions, and an audit trail — not a percentage typed into a spreadsheet cell that someone updates when they remember.
A multi-currency cash flow only ties when FX is explicit
Basin builds the cash flow statement the indirect way: from the net result and the movement between the prior and current balance sheets. In a multi-currency group, that only reconciles to the change in cash with an explicit effect of exchange rates on cash line — which is exactly how a real multi-currency cash flow is presented. If a group cash flow doesn't tie, look at FX first. It's almost always FX.
A lock is only a lock if the data layer enforces it
Hiding the edit buttons on a signed-off period is not a control. In Basin, the sign-off lock is enforced where the data is written, so every class of write — task updates, trial balance imports, journals, intercompany changes, FX rate edits — refuses on a locked period, whatever screen or route it comes from. Reopening a period is a separate permission, and both directions land in an append-only audit trail.
The same thinking applies to journals: lines must balance before they can be saved, the person who drafts a journal isn't the person who posts it, and a posted journal is immutable — a correction is another journal. On a OneStream project, test workflow locks and certification in UAT by actively trying to write into a locked period, not just checking that the status reads "locked."
Our Take
We didn't build Basin to replace OneStream. For enterprise finance teams, OneStream is the platform we implement and recommend; Basin is for smaller groups that haven't reached that scale yet. But building one from scratch means we've had to answer every design question ourselves — where translation differences go, what a reviewer needs to see behind a number, what a lock actually has to stop. Those are the same questions that decide whether a OneStream consolidation earns a CFO's trust.
If you'd like to see these ideas running, you can explore Basin's read-only demo — no sign-up, sample data only. And if you'd like the same discipline applied to your OneStream application, that's what an assessment is for.