{{ message }}

Instantly share code, notes, and snippets.

# ZJONSSON/arb.js

Last active Jan 1, 2016
Bitcoin Arbitrage - Priceonomics
 // Get all possible states for a k length array function states(k) { if (k==1) return [0,1]; var ret = []; states(k-1).forEach(function(d) { ret.push([0].concat(d)); ret.push([1].concat(d)); }); return ret; } // Get all k-combinations from array function combinations(arr, k){ if (k==1) return arr; var ret = []; arr.forEach(function(d,i) { combinations(arr.slice(i+1, arr.length), k-1) .forEach(function(sub) { var next = [].concat(sub); next.unshift(d); ret.push( next ); }); }); return ret; } // Generate a LaTex fraction function frac(a,b) { if (!b || b == 1) return a; return '\\frac{'+(a || 1)+'}{'+b+'}'; } // Main calculation - callback to the JSONP request function main(input) { input = input.query.results.json; // Build rates matrix var rates = {}; Object.keys(input).forEach(function(key) { var numerator = key.slice(0,3), denominator = key.slice(4); if (!rates[numerator]) rates[numerator] = {}; rates[numerator][denominator] = input[key]; }); // List FX rates fx = Object.keys(rates); // Go through all single-pair arbs combinations(fx,2).forEach(function(d) { var ret = rates[d[0]][d[1]]*rates[d[1]][d[0]], first = frac(d[0],d[1])+' \\cdot '+frac(d[1],d[0]), second = rates[d[0]][d[1]]+'\\cdot '+rates[d[1]][d[0]]; // If return is below 1 the arb is in the inverse if (ret < 1) { first = frac(1,first); second = frac(1,second); ret = 1 / ret; } $("#dual").append('$$'+first+' = '+second+' = '+ret+ '$$'); }); // Go through all triangular combinations combinations(fx,3).forEach(function(c) { var best = {}; // Go through all possible selections of currency pairs for those three currencies states(3).forEach(function(states) { var d = {result: 1, above: [], below: []}; states.forEach(function(state,i) { var a = (state) ? c[i] : c[i+1] || c[0], b = (state) ? c[i+1] || c[0] : c[i], rate = rates[a][b]; if (state) d.above.push([a,b,rate]); else d.below.push([a,b,rate]); d.result *= state ? rate : 1/rate; }); // If the result is below 1 the arb is in the inverse if (d.result < 1) { var tmp = d.below; d.below = d.above; d.above = tmp; d.result = 1 / d.result; } // To eliminate duality-arb effect, we take the lowest triangular arb if (!best.result || d.result < best.result) best = d; });$("#triangular").append('$$'+frac( best.above.map(function(d) { return frac(d[0],d[1]);}).join(' \\cdot '), best.below.map(function(d) { return frac(d[0],d[1]);}).join(' \\cdot ') )+' = '+ frac( best.above.map(function(d) { return d[2];}).join(' \\cdot '), best.below.map(function(d) { return d[2];}).join(' \\cdot ') )+ ' = '+best.result +'$$' ); }); }


Bitcoin Arbitrage Exercise

This is my solution to the Bitcoin Arbitrage puzzle posted earlier this year by Priceonomics. A matrix of continuously-published currency rates is algorithmically skewed and the challenge is to uncover any arbitrage opportunities. Calculations are re-run every time this page is loaded/refreshed, using YQL to fetch the latest rates and MathJax to render the results.

All spot market arbitrage can be decomposed into duality-arbitrage (different prices for the same thing) and triangular-arbitrage (relative prices between three assets not unity). Any higher order arbitrage relationships (i.e. involving more than three assets) are a combination of duality- and triangular-arbs.

Duality Arbitrage

Duality arbitrage occurs when the different prices are attached to the same currency pair.

Triangular Arbitrage

A currency has no absolute value, only relative value against other assets/currencies. Triangular arbitrage occurs when the relative value of a currency towards two different assets does not match the relative value between those assets. For any triangular relationship in this exercise there are 8 combinations of currency pairs to choose from (i.e. the price of EURUSD differs from USDEUR). To avoid double-counting the duality issues identified above, we pick the triangular combination of rates that results in the minimum arbitrage possible (the rest is contaminated by duality-arb)

(c) 2013 Ziggy Jonsson - Licence MIT - (source)