5.45 Detecting Wash Trading with an FFT, and Why Your TWAP Needs Random Timestamps
The Fourier transform fails on price but nails a robot, because a wash bot or metronomic TWAP is the clean periodic signal price never is. Bin trades, FFT the counts, and a sharp spike is automation. The catch: your own equal-interval TWAP makes that spike, so randomize it.
The old article "The Autocorrelation Periodogram" spent its whole length explaining why the Fourier transform is the wrong tool for price: price is non-stationary, the window is never a representative infinite sample, and a real market cycle is never a clean integer number of periods in your window. All true. But flip the target from price to the timing of trades and the objection inverts. A wash-trading bot or a naive execution algo is an artificial, stationary, periodic process by construction, the one signal that satisfies every assumption the DFT demands. The transform that fails on price nails a robot cold, because a robot is the textbook clean sinusoid that price never is.
Two uses fall out of the same observation. You can run an FFT over trade timing to catch a counterparty trading on a clock, and you can run it over your own execution to make sure you are not the one getting caught.
Build a count series and transform it
Trade events arrive at irregular timestamps, so you cannot FFT them directly. Bin them. Slice time into fixed buckets, count the trades in each bucket, and you have a regularly-sampled series of trade intensity. Run the FFT on that series and read the power spectrum. A market driven by genuine, unscheduled flow gives a broad, flat-ish spectrum with no special period. A market with a bot firing on a fixed cadence gives a sharp spike at the bot's frequency, because the count series literally repeats every so many seconds.
$$ n[k] = \#\{\text{trades in bin } k\}, \qquad P(f) = \big|\,\text{FFT}(n)\,\big|^2 $$ $$ \text{spike at } f^\star \;\Longrightarrow\; \text{periodic process with period } T = 1/f^\star $$