Most cash flow forecasting projects pick the model first and the question last. Someone wants “a better forecast”, a data scientist reaches for a gradient-boosted model or an LSTM, and six weeks later there is a curve that fits last year well and helps nobody. The forecast was never tied to a decision, so its accuracy has nowhere to land.
Start from the decision instead. A treasurer deciding whether to draw on a revolver next week needs a 13-week horizon and cares a lot about the downside. An FP&A team setting a quarter-end liquidity buffer needs a different horizon and a different error tolerance. Those are not the same forecast, and they do not justify the same amount of machine. Knowing which decision the number feeds tells you the horizon, the cadence, and how wrong you are allowed to be before someone acts on a bad number.
Build features from what already happened
The useful signal in cash flow forecasting usually sits in transactional data you already hold. Accounts-payable and receivable aging, payment terms by counterparty, the actual settlement dates versus the invoiced dates, payroll runs, tax and VAT cycles. These have structure. A large customer that pays on day 47 every quarter is a feature, not noise.
Construct features from that history with the same point-in-time correctness you would demand of a backtest. The single most common way ML forecasting goes wrong here is lookahead leakage: training on a reconciled, month-closed view of cash that was not available on the forecast date. If your features quietly include figures that only existed after the books closed, your backtest looks excellent and your live forecast disappoints. Build the feature set as it stood on the day, with the late-arriving items still missing, or the model learns to depend on information it will never have in production.
Seasonal structure is worth encoding explicitly rather than hoping the model infers it:
- Calendar effects: quarter-end, month-end, payroll dates, statutory tax deadlines
- Counterparty payment behaviour, including the ones who reliably pay late
- Known one-offs that recur, such as annual licence renewals or bonus runs
Beat the simple method before you reach for the complex one
Before any of this, build the boring baseline. A seasonal naive forecast, a moving average, or the treasury team’s existing spreadsheet. Then measure against it honestly. A surprising share of treasury analytics work ends here, because a well-tuned baseline is hard to beat on short horizons and the marginal accuracy from a heavier model does not pay for the complexity of running it.
We are opinionated about this. A model you cannot explain to the person relying on it, that needs constant retraining, and that beats the spreadsheet by two percent is not progress. It is a maintenance liability with good marketing. Reach for the complex model only when the simple one is clearly leaving money on the table, and when you can show where the extra accuracy comes from.
Backtest the way the forecast will actually run. Use walk-forward evaluation that retrains on data up to each forecast date and predicts forward, rather than a single random split. Score on the horizon that matters for the decision, not an average across all horizons that hides poor performance exactly where it counts.
Communicate the range, then watch it move
A treasurer cannot act on a single number that pretends to certainty. Cash flow is lumpy and partly driven by counterparties you do not control, so forecast uncertainty is information, not a failure to be hidden. Produce a distribution or a set of quantiles, then frame it in the treasurer’s terms: the chance of breaching a minimum balance, the size of buffer that covers most plausible weeks. A range someone argued with beats a point estimate nobody questioned.
Then keep watching. Payment behaviour drifts, a big customer changes terms, rates move, a recession compresses receivables. A model tuned on last year’s conditions degrades quietly, and the first sign is usually a treasurer who has stopped trusting the number. Monitor the live error against the backtested error, track whether actuals keep landing inside your stated range, and set a threshold that triggers a retrain or a review. Treat the monitoring as part of the build, not an afterthought once the model is in production.
None of this is exotic. It is framing the forecast around a real decision, being honest in the backtest, and being clear about what you do not know. That is most of the value, and most teams skip it to get to the model.