An FX TCA provider measures what currency trades cost against a benchmark, usually the mid-rate at arrival or the fixing for fix orders, and ranks banks, platforms and algorithms by that cost. The test that separates providers is whether they measure what happened to the requests that did not fill. With last look, a bank may hold a trade request for a few milliseconds and then reject it, and the client re-trades at whatever the market has become; an average of fills never shows that cost. In a market that turned over $9.6 trillion a day in April 2025, those rejections add up: in the solution's sample data, one bank that lengthened its hold window cost an estimated $244,000 in 12 trading days while its average spread looked fine. Botminds' Transaction Cost Analysis reads the FX platforms' millisecond rejection logs every night, watches each bank's reject rate, hold time and asymmetry against its own disclosure, and drafts the question for the bank, which a person approves before anything is sent.
The regulatory, central-bank and research sources are linked where they appear. The worked example is the solution's sample data on a fictional asset manager, Quillfield Capital, and fictional banks.
One €50 million request at millisecond scale: three holds, three rejections, then a worse fill
- Held while the mid rose 0.3 pip172 ms
- Held while the mid rose 0.2 pip176 ms
- Held while the mid rose 0.2 pip178 ms
- Accepted41 ms
What should FX TCA measure?
FX TCA should measure the cost of every fill against a fair benchmark, and also the cost and frequency of every request that did not fill. The Bank for International Settlements' study group on FX execution algorithms set out the inputs: "Detailed TCA requires accurate time stamps throughout the trade life cycle. These can then be measured against granular, high-frequency price data, and further analysis of price slippage, market impact and the ratio of rejected trades" (BIS Markets Committee, FX execution algorithms and market functioning, October 2020, Box B). Rejections are named alongside slippage and impact, not as a footnote.
The same report named the difficulty that makes FX TCA harder than equity TCA. The calculations "are typically not too complicated", it said, but "accessing and processing the required data as well as choosing an adequate benchmark can be a challenge in the absence of a complete consolidated tape in the FX market." There is no single public price to measure against, so every FX TCA result rests on whose mids it used and how they were timestamped.
FX TCA in numbers: a huge market, measured in milliseconds
$9.6T
global FX turnover a day, April 2025
16.8%
of one sample bank's requests rejected in October, against a panel median of 0.8%
176ms
that bank's median hold time, up from 38 ms in the third quarter
$244K
estimated re-fill cost of its rejections in 12 trading days
What is last look in FX?
Last look is a final check a liquidity provider runs on a client's trade request before it accepts or rejects it at the quoted price. Oomen's study of the practice describes it as the process that "determines whether to accept—and if so at what rate—or reject a trader's deal request subject to the constraints of an agreed trading protocol" (Oomen, Quantitative Finance, 2017). It exists because quotes are streamed to many clients at once and prices move during the time it takes a request to arrive.
The research is balanced on whether it hurts clients. Cartea, Jaimungal and Walton showed that losses to latency arbitrageurs "are reduced if the broker can reject, ex-post, loss-making trades", which lets a provider quote tighter spreads to everyone (Mathematics and Financial Economics, 2019). Oomen found that the design of last look and the trading protocol determine the execution risk a client bears, "but the effective transaction costs borne by the trader need not be affected by it." A TCA provider should therefore measure both: the cost of fills, and the risk carried in the rejections.
The BIS group added a market-wide concern: the liquidity a client sees on screen may not be there when it tries to trade, and this "Liquidity mirage is likely to be exacerbated if the practice of last look is permitted, as is the case in the FX market."
What the FX Global Code says about last look
The FX Global Code, Principle 17, allows last look but sets conditions on it and gives clients a right to specific disclosure. A bank using last look "should disclose, at a minimum, explanations regarding whether, and if so how, changes to price in either direction may impact the decision to accept or reject the trade, the expected or typical period of time for making that decision, and more broadly the purpose for using last look" (FX Global Code, Principle 17, updated December 2024).
Three further lines in the principle are the ones an FX TCA program can test against data. Last look "should be a risk control mechanism used in order to verify validity and/or price." During the window the provider has sole discretion, "leaving the Client with potential market risk in the event the trade request is not accepted." And "Market Participants should not conduct trading activity that utilises the information from the Client's trade request during the last look window." The code is voluntary, adopted by statements of commitment; its value to a buyer is that it says what to ask for and what the answer should look like.
What is a hold time, and when is it too long?
A hold time is the interval between a bank receiving a trade request and accepting or rejecting it. The code does not set a maximum; it requires the bank to disclose the expected or typical period. Too long is therefore measured against two things: the bank's own disclosure, and its peers on the same platform for the same currency pair and size.
The sample shows why the comparison with the bank's own history matters. Thornbury Bank's median hold was 38 milliseconds in the third quarter. Its disclosure dated September 28 raised its maximum last-look window from 50 to 200 milliseconds; in the first half of October its median hold was 176 milliseconds and 36 of 214 requests, 16.8%, were rejected. Of those 36, 33 came when the price moved against the bank during the hold, which is the asymmetry Oomen's framework distinguishes. An average spread across the quarter would have shown none of it.
Reject rates: one bank against its panel, its own past and the alert line
How much do rejected requests cost?
The cost of a rejection is the difference between the price rejected and the price the client then trades at, on the amount rejected. Summed over a period and divided by the rejected notional, it gives a re-fill cost in basis points that can be compared across banks. In the sample, the agents estimated Thornbury's at 0.9 basis points on $2.71 billion of rejected requests in 12 trading days, about $244,000.
On a single order the effect is sharper. The €50 million EUR/USD buy in the first figure cost 2.1 basis points against the mid at arrival, three times the peer median of 0.7. Filling all of it at the first offers, 1.17421 from Thornbury for half and 1.17422 from Ardmore Bank for the rest, would have cost about 0.8 basis points, by the solution's estimate; the rejections and what followed cost about $7,630. The quote log also showed that sending to Ardmore after the first rejection would have saved an estimated 0.4 basis points, because Thornbury had been best by only 0.1 pip.
Two costs are harder to price and should still be counted. Information leakage, if a provider trades on the request during the hold, is exactly what Principle 17 prohibits, and it shows up as the market moving in the direction of the request during the window. And the execution risk the client carries, the price moving while it waits, is real even when the average cost is small.
FX last-look evidence on one bank, as the agents present it

How to compare FX banks fairly
Compare banks on the same pair, protocol, size band and time of day, with enough requests to tell a pattern from bad luck. A bank quoting large risk-transfer tickets in a fast market will reject more than one quoting small streams in a quiet hour. The sample policy needs at least 50 requests before it calls a reject rate high, and the rankings label any bank with too few orders "too few to tell" rather than ranking it.
Three measures together give a fair picture: cost against the mid at arrival for filled trades; reject rate and median hold for all requests; and asymmetry, the share of rejections that came when the price moved against the bank. A bank that is cheap on fills but rejects one request in six is not cheap; a bank whose rejections are symmetric, spread across moves in both directions, is behaving as Principle 17's risk-control description expects.
What data an FX TCA provider needs, and what the GFXC template asks for
A provider can only measure what it is given, so the first buying question is about data. The Global Foreign Exchange Committee published a TCA Data Template in July 2021 that "suggests a standardised data set that providers of algorithmic execution can make available to their clients for the purpose of Transaction Cost Analysis" (GFXC, Algo/TCA Templates). Its fields are a practical checklist for any FX TCA feed, algorithmic or not.
Fields from the GFXC TCA Data Template, and the TCA question each answers
| Field | Level | Question it answers |
|---|---|---|
| Parent order start and end time, in UTC to the millisecond | Parent | Which mid was the arrival benchmark, and how long the order took |
| Mid at arrival | Parent | The benchmark itself, stated by the provider |
| Risk transfer price, if available | Parent | What dealing the whole amount at once would have cost: the yardstick for an algorithm |
| Traded rate excluding and including the algo fee | Parent and child | Separates price from fee |
| Action time, to the millisecond, for each fill or amendment | Child | The sequence to replay against market data |
| Child order type: aggressive, mid, passive | Child | Whether the algorithm paid the spread or earned it |
| Execution venue and its location | Child | Where the liquidity came from |
| Venue liquidity: last look, firm or mixed | Child | Which fills carried rejection risk |
| Reference market bid and offer at each action | Child | Slippage and spread on every child order |
For last look specifically, the template is not enough: it describes fills, not rejected requests. A buyer should ask each platform for its trade request log, with request time, quoted price, amount, decision, hold in milliseconds and the mid at request and at decision. That is the record the solution's agents read, and it is what makes a rejection cost computable.
The platform's own rejection log behind a cited figure

What to ask an FX TCA provider: twelve questions
Ask about data, benchmarks, rejections and evidence, in that order; a provider that is vague on the first will be wrong on the rest. These questions apply equally to a third-party provider, a bank's own TCA and an in-house build.
Twelve questions to put to any FX TCA provider
- Whose mids do you use, and how are they timestamped?
With no consolidated tape, the benchmark source decides the result.
- Do you take the platforms' trade request logs, or only fills?
Without rejected requests there is no last-look measurement.
- Do you report reject rate, hold time and asymmetry per bank?
The three measures Principle 17 makes testable.
- Do you price rejections as re-fill cost?
A reject rate without a cost is hard to act on.
- Do you read each bank's last-look disclosure and flag a new version?
A window raised from 50 to 200 ms is a change the desk should see the day it happens.
- How do you treat fix orders?
An order for the fix measured against arrival will look expensive for no reason.
- Can you separate the algorithm fee from the price?
The GFXC template carries both rates for this reason.
- How large are your peer buckets, and are they like for like?
Same pair, size band, protocol and time of day.
- What is the minimum sample before a bank is ranked?
Rankings on a few dozen requests move panels on noise.
- How soon after trade date do results arrive?
A monthly report finds a changed window weeks after it cost money.
- Can every figure be traced to the source record?
The committee and the examiner will ask.
- Who can act on a finding, and is that recorded?
Panel changes should be proposed by one person and approved by another.
Where an agentic approach fits, and where it does not
Transaction Cost Analysis fits where FX TCA is weakest today: reading the request logs, following a bank's behaviour day by day, tying a change to the bank's own disclosure, and writing the case for a person to decide. In the sample, the Anomaly agent found the Thornbury pattern at 1:15 a.m., drafted an inquiry letter citing the FX Global Code, and handed it to the London FX trader, who proposed moving the bank to Review on panels above €20 million at 08:46; the head of trading approved it in New York with a reason code and an attestation that he was not the maker.
It does not replace two things. It works with the peer universe and pre-trade model a desk already has, so a firm without peer data still needs a source for it. And it never changes routing or panels or contacts a bank: every action is a person's proposal, signed by someone else and ratified by the committee. Comparing approaches across asset classes is the subject of TCA vendors compared on one order; AI transaction cost analysis follows the agents' steps one by one; and the bond equivalent of the stale benchmark problem is in fixed income TCA. The full workflow is on the Transaction Cost Analysis page.
Questions people ask
What is the difference between symmetric and asymmetric last look?
With symmetric last look, a bank rejects requests when the price has moved beyond a tolerance in either direction, for or against it. With asymmetric last look it rejects only when the move is against the bank, keeping the requests that moved in its favour. Oomen's framework distinguishes the designs; in the sample, 33 of 36 rejections came when the price moved against the bank.
Is last look legal?
Last look is permitted and widely used in spot FX. The FX Global Code, a voluntary code of good practice, expects it to be used as a risk control to check validity or price, disclosed to clients, and not used to gather information or to trade on the client's request during the window.
What is a good reject rate for an FX bank?
No published standard exists; the fair comparison is with the same bank's history and its peers on the same platform, pair and size. In the solution's sample data the panel median was 0.8% and the policy alerts above 5% or three times the panel median, on at least 50 requests.
How is FX TCA different for fix orders?
An order placed for a benchmark fixing should be measured against the fixing rate, not against arrival. In the sample, a USD/JPY fix order flagged at 3.4 basis points against arrival cost 0.2 basis points against the fix it was meant to get.
Does MiFID II best execution apply to spot FX?
Spot FX is generally outside the scope of MiFID II's best execution rules, as the BIS study group noted, though it added that some participants apply similar criteria across all products. FX forwards and swaps that are financial instruments are a different matter, and an execution policy should say which rules apply to which products.