Detecting Round Tripping in SME Lending Transaction Analysis
Published on: 2026-04-24 09:20:41

A bank statement page with one incoming and outgoing transaction pair highlighted in context.
Start with the matching decision
Exact matching is the shipped configuration for a reason. In a sweep across three synthetic six-month UK SME statements, a zero tolerance found planted events A, B, C and E. It produced zero false positives for the applicant statement and zero for the clean company.
Tolerance changes that result, but the trade is not simply “more tolerance is better”. At 0.50% tolerance with maximum group sizes of one IN and one OUT, the search found event D, a pair shaved by 0.4%. It also produced 10 false positives for the applicant statement and 11 for the clean company.
At the same 0.50% tolerance with subsets enabled through maximum sizes of three IN and two OUT, event D was not found in this fixture. False positives rose to 87 for the applicant statement and 84 for the clean company. Read those settings together: the tolerance band and subset breadth multiply the number of sums tested against that band.
That is the decision for the lender. A 0.50% band at 1:1 is the only setting in this fixture that finds event D. It buys one real event and costs about ten false positives. Broadening the search to subsets at the same tolerance costs about eighty-seven false positives. The appropriate setting depends on the review capacity and the event the lender is prepared to pursue; the count alone does not settle it.

The Fraud Pairs function block with its transaction fields, window, tolerance, group limits and search caps visible.
Configure the function
Fraud Pairs is a function block inside a data flow rule. It matches IN transactions against OUT transactions inside a time window and compares their amounts using the configured tolerance. Direction is mapped before the function runs: for example, a mapping row turns $.type = credit into IN and a debit value into OUT. The function does not read direction directly from raw data.
These are the shipped values used in the worked fixture:
| Parameter | Value | Purpose |
|---|---|---|
| window_size | 3 | Reaches three days ahead of the IN transaction |
| window_unit | day | Uses days for the window |
| working_days_only | true | Counts working days toward the window length |
| tolerance_pct | 0 | Requires exact amount equality |
| max_transaction_count_in | 3 | Tests up to three IN transactions in a set |
| max_transaction_count_out | 2 | Tests up to two OUT transactions in a set |
The transaction fields also need to be mapped: direction_field identifies the direction value, amount_field identifies the amount, and timestamp_field identifies the transaction time. The per-window pool cap is 100 transactions, and the cap for IN subsets processed per window is 2,000.
A three-day working-day window has a specific meaning. The window reaches ahead from the IN. The IN’s own day always matches. With working days enabled, Friday to Monday is one day of distance rather than three. Weekend-dated transactions still participate in matching.

A decision table divides match counts into three mutually exclusive bands and assigns a reason code to each band.
Use combinations, but know what they cost
The function tests combinations from the smallest size first. One-to-one and one-to-many matches are therefore covered before the search spends time on four- and five-way combinations. The maximum IN and OUT counts, the per-window pool cap and the subset cap control how far the search can go.
Those controls matter because every extra IN subset creates another sum to compare with the same amount band. The evidence fixture makes the cost concrete:
- At 0% tolerance with maximum IN 3 and OUT 2, the sweep found A, B, C and E, with no false positives in either the applicant or clean-company column.
- At 0.10% tolerance with the same subset limits, the planted events remained A, B, C and E, but false positives rose to 53 for the applicant and 52 for the clean company.
- At 0.25%, the same events were found and false positives rose to 69 and 68.
- At 0.50%, the result was A, B and C, with 87 and 84 false positives.
Event C explains why subset matching can matter. Three payments of GBP 18,400, GBP 12,750 and GBP 13,850 match one GBP 45,000 outgoing payment. No single incoming row matches that outgoing row. Event E uses two IN transactions, GBP 27,000 and GBP 9,500, against two OUT transactions, GBP 22,500 and GBP 14,000.
Event D is the counterexample to any claim that the shipped setting finds every pattern. It is a GBP 38,000 outgoing payment against a GBP 37,848 incoming payment, a 0.4% difference. Exact matching deliberately leaves it unfound.

An expanded matched set lists the counterparty, transaction amount and matching window for each displayed transaction.
Review the set, not only the count
There is a second cost to tolerance that a false-positive count does not capture. The search is greedy and marks rows as used, so a transaction cannot be reused across matching sets. At 0.50% tolerance with subsets, the genuine GBP 45,000 pair returned with two unrelated rows attached. An analyst opens a real finding and sees three names with nothing to do with each other.
That is worse than a clean miss in the review queue. The count says that a set was found; it does not say whether the set is coherent. Human review earns its place here. The analyst needs to open the matched IN and OUT transactions, inspect the amounts and window, and decide whether the pattern is meaningful. A tolerance setting should be tested against the quality of the displayed sets, not judged from detection counts alone.
The function returns pairs, with the IN transactions, OUT transactions, volume and window for each set. It also returns count and volume. These results give the decision flow something concrete to pass to a review decision or a broader underwriting rule.
Apply the configuration to a real fixture
The deterministic fixture contains three synthetic UK SME statements, each covering six months. Halden Trading Ltd has 497 transactions and turnover of GBP 1,927,352.83. With the shipped configuration, four round trips are found and the matched volume is GBP 189,000, or 9.8% of turnover. The outcome is decline, with reason code RT_PATTERN.
Brightloom Interiors Ltd has 483 transactions. Two matches are found, producing an outcome of refer with reason code RT_REVIEW. Carrowmere Supplies Ltd has 473 transactions and no matches, producing an outcome of pass with reason code RT_NONE.
Two February decoys remain quiet: a GBP 48,700 supplier payment a week after a GBP 48,700 receipt. They are the largest rows on the page, but the three-day window leaves them unmatched. This is a useful test case for the time boundary as well as for exact amount matching.

The result displays count 4, matched volume GBP 189,000, outcome decline and reason code RT_PATTERN.
Make completeness visible
Search limits should be part of the result interpretation. The function has a soft wall-clock budget of 10 seconds. If that budget expires, the search stops cleanly and returns what it has with stopped_early set in __coverage. The hard PHP backstop is 50 seconds and is fatal, so the soft budget is intended to finish first.
An over-full window is trimmed to the largest amounts and searched; it is never skipped. If the search was reduced, __coverage carries windows_total, windows_trimmed, windows_capped and stopped_early. If the result has no __coverage key, the search was complete. That absence is the completeness signal, not an empty field to ignore.
Turn the result into a decision
A matched set is a signal for review. It is not a finding of fraud. The decision flow can use the count, matched volume and reason code to select an outcome, then leave the analyst the underlying transactions and matching window.
For a starting configuration, use a three-day window, working days only, zero tolerance, maximum three IN transactions, maximum two OUT transactions, a 100-transaction per-window pool cap and a 2,000-subset cap. Test any change to tolerance and subset breadth against both planted events and a clean company. The fixture shows why: tolerance can recover a deliberately shaved pair, but it can also fill review with unrelated matches.
That is the practical boundary of round-tripping detection. Use exact matching as the shipped baseline, measure the cost of any tolerance, inspect the expanded sets, and keep the result as evidence for a credit decision rather than treating it as proof.