Analytica Data Science SolutionsContact
ESC

to move to open

← All insights

Insight

Analyzing crypto markets in R, part 1: exchanges and arbitrage

Bitcoin's price wasn't one price. Pulling 2011–2018 exchange data into R and measuring the gaps arbitrage was supposed to close.

December 2018RFinanceData analysis

A 2018 analysis, kept for the method and the findings. The data feeds it used — Quandl's exchange series and the Poloniex API — have since shut down or changed beyond recognition, so the code is shown for its approach rather than to run as-is. The figures are the original outputs.

In 2018 I got curious about a question with real money attached: is Bitcoin’s price actually one price? Every exchange quotes its own, arbitrage is supposed to keep them honest, and I had seven years of data to check whether it did.

The toolkit was ordinary R: data.table and lubridate for wrangling, ggplot2 for the pictures, with price series pulled from Quandl’s exchange feeds and the Poloniex API. Those feeds are gone now, which is why this post carries the note above. The method outlives the plumbing.

First, the shape of the thing we’re analysing:

Bitcoin's volume-weighted price, 2012–2018: years of near-flatline, then the vertical 2017 spike toward $20,000 and the fall after.

That spike is late 2017, and everything interesting in this analysis happens in its shadow.

How far apart could one Bitcoin be from itself?

For each day I computed the maximum percentage gap between the highest and lowest price across exchanges — the raw material of arbitrage. Plotted over time, with a loess smoother:

Daily maximum price difference between exchanges, log scale, 2013–2018, with a loess curve drifting down from several percent toward one percent.

Two things jump out. The typical gap declined over the years (the market maturing, arbitrageurs doing their job), but the spread never disappeared, and single days still spiked to 10% and beyond deep into the study. The monthly view says the same thing with distributions instead of dots:

Box plots of price differences by month: medians settle near one percent, with fat upper tails in every volatile period.

Medians settle around a percent. The tails never behave. And when I asked which exchanges kept showing up at the extremes, the answer wasn’t random either:

Frequency of each exchange posting the day's maximum or minimum price: a small set of venues dominates both ends.

A handful of venues were persistently the expensive place and a handful persistently the cheap one. Textbook arbitrage says gaps like that get eaten within minutes. So why did they persist for years?

Because the friction was real: withdrawal limits and delays, fees on both sides, counterparty risk on venues of very mixed reliability, and transfer times during exactly the volatile moments when gaps opened. The chart records the size of the reward; the frictions were the moat around it. “Free money” that persists is almost always a measurement of some cost you haven’t priced.

That finding — markets are one market only when moving between them is cheap — is the whole lesson, and it generalises far past crypto. Part 2 turns from one coin on many exchanges to many coins moving together, where the correlation structure has its own surprise.

Discuss a project

Tell us what decision, workflow, or data problem you're working on. We'll tell you what the data you already have can support, and what a first engagement looks like.

Start a conversation