ds@mcpanalytics.aiEmail your data and your question and get an answer about your own data, with the method shown.Email your data and question. Get an answer.
WHITEPAPER

Cash Flow Forecasting: A Method Guide

Updated October 2026

Published: December 26, 2025 | Read time: 9 minutes | Category: Financial Analytics

Executive Summary

Cash flow forecasting predicts when money will actually arrive and leave, which accrual profit figures do not show. The practical core is short-horizon: a rolling forecast of receipts and payments by category, with the largest uncertainty usually in when customers pay.

This paper is a method guide. It explains the direct and indirect methods, a rolling 13-week structure, how to forecast receivables by payment behavior, and how to track forecast error. The only numbers in it come from one simulation, whose code is shown; they describe that simulated setup and are not a claim about any company.

To see where your own measure is heading, with a likely range, try the free forecasting tool.

Key Points

  • Payment timing is the main uncertainty in receipts. In the simulation, assuming every invoice is paid on its due date missed weekly receipts by 53% of the total.
  • Using customer behavior helped a lot. Adding each segment's average payment delay cut the error to 17%, and spreading each invoice over the segment's observed delay distribution cut it to 11%.
  • The simulated customers differ by construction. The gain depends on real customers differing in how they pay; test it on your own receivables history.
  • Forecasts need an error record. Compare each forecast with what happened and track the error by horizon and by category.

Recommendation: start with a direct-method rolling forecast over a short horizon, model receivables from customers' own payment history, and measure forecast error every period.

1. Introduction

1.1 Why Cash Differs From Profit

A business can be profitable and run short of cash if customers pay late, inventory ties up money, or large payments cluster. Cash flow forecasting looks at the timing of money moving, not the accounting period in which it is earned.

1.2 What This Paper Covers

  • The direct and indirect methods and when each is used
  • A rolling 13-week forecast and how to maintain it
  • Forecasting receivables from customers' payment behavior, with a runnable simulation
  • Uncertainty, scenarios and tracking forecast error

2. Background

2.1 Direct and Indirect Methods

The direct method forecasts cash receipts and cash payments by category: customer collections, supplier payments, payroll, taxes, debt service and capital spending. The indirect method starts from projected profit and adjusts for non-cash items and changes in working capital. The indirect method fits financial statements and longer horizons; the direct method is usually preferred for near-term liquidity, because it works from the items that actually move cash and their dates.

2.2 Why Forecasts Go Wrong

Common sources of error are late or missing source data, static forecasts that are not updated against actuals, inconsistent assumptions between departments, and assumptions that every customer pays on the due date. Error generally grows with the horizon, because further out there are fewer known commitments and more estimated items.

3. Approach

3.1 A Rolling 13-Week Forecast

A common structure is a forecast with one column per week for the next 13 weeks. Each week, replace the elapsed week with actuals, add a new week at the end, and revise the remaining weeks for what has been learned. The routine matters as much as the model: a forecast that is updated against actuals every week is a measurement instrument, while a static one soon goes stale.

3.2 Receivables by Payment Behavior

For open invoices, the question is when each will be paid. Three levels of method, in increasing detail:

  • Assume payment on the due date. Simple, and usually optimistic.
  • Add the average delay observed for similar customers (a segment, such as fast, typical or slow payers).
  • Spread each invoice's amount across the observed delay distribution of its segment, which gives expected receipts per week and shows the range.

Only invoices that have already been paid reveal a delay, and an open invoice by definition has not been paid yet, which the third method must respect.

3.3 Payments and Other Items

Payroll, taxes, rent and debt service are mostly scheduled and can be entered by date. Variable items such as supplier payments follow purchasing and payment terms. Keep known commitments separate from estimated flows so the forecast shows which parts are firm.

3.4 Uncertainty and Scenarios

A single line hides risk. Give a base case plus a lower-receipts case, and where history allows, an interval built from past forecast errors at the same horizon. The question to answer is how low cash could get, and when.

3.5 Measuring Accuracy

A simple measure is the weighted absolute percentage error: the sum of absolute weekly errors divided by the sum of actual values. Track it by horizon (the one-week-ahead forecast against the 13-week-ahead one) and by category, so you know where to put effort.

4. A Reproducible Simulation

The simulation builds 40 synthetic companies. Each has 300 customers who belong to fast, typical or slow payers (30%, 50%, 20%) and are invoiced with 30-day terms, paying on average 2 days before the due date, 8 days after it, or 25 days after it. At a forecast date, the open invoices from the previous 90 days are forecast week by week for the next 13 weeks by the three methods above, learning delays only from invoices already paid. The measure is the sum of absolute weekly errors as a share of actual receipts.

import numpy as np

SEG_LAG = {0: (-2, 3), 1: (8, 6), 2: (25, 12)}   # days paid after the due date: (mean, sd) for fast, typical and slow payers
TERMS = 30

def make_world(rng, n_customers=300, days=450, per_day=12):
    seg = rng.choice(3, size=n_customers, p=[0.3, 0.5, 0.2])
    cust = rng.integers(0, n_customers, size=days * per_day)
    issue = np.repeat(np.arange(days), per_day) + rng.random(days * per_day)
    amount = rng.lognormal(7.0, 0.8, size=days * per_day)
    mu = np.array([SEG_LAG[s][0] for s in seg[cust]]); sd = np.array([SEG_LAG[s][1] for s in seg[cust]])
    pay = issue + TERMS + rng.normal(mu, sd)
    return dict(seg=seg[cust], issue=issue, amount=amount, pay=pay)

def wape(forecast, actual):
    return np.abs(forecast - actual).sum() / actual.sum()

def one_world(seed):
    w = make_world(np.random.default_rng(seed))
    t0 = 400                                                    # forecast date
    paid_before = w["pay"] < t0
    # open at t0 = issued in the 90 days before t0 and not yet paid
    open_ = (w["issue"] >= t0 - 90) & (w["issue"] < t0) & ~paid_before
    weeks = np.arange(13)
    def weekly(pay_day, amt):
        idx = ((pay_day - t0) // 7).astype(int)
        out = np.zeros(13)
        for i, a in zip(idx, amt):
            if 0 <= i < 13: out[i] += a
        return out
    actual = weekly(w["pay"][open_], w["amount"][open_])
    due = w["issue"][open_] + TERMS
    amt = w["amount"][open_]
    # history that was known at t0: invoices already paid, with their lag after the due date
    hist = paid_before & (w["issue"] < t0 - 30)
    lag = w["pay"][hist] - (w["issue"][hist] + TERMS)
    # A: assume everything is paid on its due date (or immediately if already past due)
    fa = weekly(np.maximum(due, t0), amt)
    # B: due date plus the average historical lag of the customer's segment
    seg_mean = {s: lag[w["seg"][hist] == s].mean() for s in range(3)}
    fb = weekly(np.maximum(due + np.array([seg_mean[s] for s in w["seg"][open_]]), t0), amt)
    # C: spread each invoice over the segment's empirical lag distribution (expected receipts per week)
    fc = np.zeros(13)
    for s in range(3):
        sel = w["seg"][open_] == s
        seg_lags = lag[w["seg"][hist] == s]
        for d, a in zip(due[sel], amt[sel]):
            pay_days = d + seg_lags
            pay_days = pay_days[pay_days >= t0]            # an open invoice cannot have been paid before t0
            if len(pay_days) == 0: continue
            idx = ((pay_days - t0) // 7).astype(int)
            idx = idx[(idx >= 0) & (idx < 13)]
            fc += a * np.bincount(idx, minlength=13) / len(pay_days)
    return wape(fa, actual), wape(fb, actual), wape(fc, actual)

res = np.array([one_world(s) for s in range(40)])
print("weekly receipts over 13 weeks, error as a share of actual receipts (mean over 40 simulated companies)")
for name, v in zip(["pays on due date", "due date + segment average lag", "segment lag distribution"], res.mean(axis=0)):
    print(f"  {name:32s} {v:6.1%}")
print("lowest-error method in", int((res.argmin(axis=1) == 2).sum()), "of 40 companies: segment lag distribution")

Output:

weekly receipts over 13 weeks, error as a share of actual receipts (mean over 40 simulated companies)
  pays on due date                  53.2%
  due date + segment average lag    16.7%
  segment lag distribution          10.9%
lowest-error method in 39 of 40 companies: segment lag distribution

Assuming payment on the due date misjudged weekly receipts by about half. Using the segment's average delay brought the error to about 17%, and using its whole delay distribution to about 11%. The customers here were generated with different delay patterns, so segment-based methods have an advantage by construction. On real receivables the gain depends on how much customers actually differ, and the same comparison is easy to run on your own invoice and payment dates.

5. Practical Guidance

Point 1: Start Short and Direct

A weekly, direct-method forecast over about three months is enough to see liquidity risk and builds the habit of comparing forecast with actuals. Add horizon and detail once that routine works.

Point 2: Model Receivables From Payment History

Use invoice, due and payment dates to measure how long each group of customers takes to pay. Update the delays regularly, and watch for customers whose behavior is changing.

Point 3: Separate Firm From Estimated

Mark which lines are contractual or scheduled and which are estimates. When cash is tight, the estimated lines are where management attention belongs.

Point 4: Show a Downside Case

Report the lowest cash balance in a downside case and the week it occurs, with the assumptions listed, so decisions about credit lines or spending can be made before they are urgent.

Point 5: Keep an Error Log

Record forecast against actual every week, by category and horizon. Review it regularly, and change methods where the error is largest rather than everywhere at once.

6. Conclusion

A cash flow forecast is useful when it is short, direct, updated against actuals and honest about uncertainty. The largest single improvement in the simulation came from replacing the assumption that customers pay on the due date with their observed payment behavior. Check that on your own receivables, and keep measuring error so the forecast can improve.

Your turn

Bring your own data and the question you actually need answered.

MCP AnalyticsData science by email Send us your data and your question, and we will reply. ds@mcpanalytics.ai

Frequently Asked Questions

What is the difference between the direct and indirect methods?

The direct method forecasts cash receipts and payments by category with their dates. The indirect method starts from projected profit and adjusts for non-cash items and working capital changes. The direct method is usually used for near-term liquidity.

What is a 13-week cash flow forecast?

A weekly forecast of cash receipts and payments for the next 13 weeks, updated each week by replacing the elapsed week with actuals and adding a new week at the end.

How do I forecast when customers will pay?

Measure the delay between the due date and the payment date on past invoices, group customers with similar behavior, and apply each group's delay (or delay distribution) to open invoices.

How should I measure forecast accuracy?

Compare forecast and actual by period, for example as the sum of absolute errors divided by the sum of actuals, and track it by forecast horizon and by category.

How do I show uncertainty in a cash forecast?

Give a base case and a downside case with assumptions listed, and where history allows, an interval from past forecast errors at the same horizon. Report the lowest cash point and when it occurs.

References & Further Reading

  • Hyndman, R. J., & Athanasopoulos, G. (2021). Forecasting: Principles and Practice (3rd ed.). OTexts.