Last active
June 30, 2017 01:58
-
-
Save waynenilsen/051d5c0305a28aaadbfd to your computer and use it in GitHub Desktop.
Poloniex arbitrage check
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
var https = require('https'); | |
var fee = 0.002; | |
var uri = "https://poloniex.com/public?command=returnTicker"; | |
function parse(ticker){ | |
var pairs = [], pair, parts; | |
for (pair in ticker){ | |
parts = pair.split('_'); | |
if(parts.indexOf("DIEM") > -1 || parts.indexOf("HUGE") > -1){ | |
continue; | |
} | |
pairs.push([parts[0], parts[1], ticker[pair].lowestAsk]); | |
pairs.push([parts[1], parts[0], 1/ticker[pair].highestBid]); | |
} | |
return pairs; | |
} | |
function build(pairs){ | |
var graph = {}; | |
var rates = {}; | |
for (var r, w, i = pairs.length; i--;){ | |
r = pairs[i][2] * (1 - fee); | |
w = Math.log10(r); | |
graph[pairs[i][0]] = graph[pairs[i][0]] || {}; | |
graph[pairs[i][0]][pairs[i][1]] = -1.0 * w; | |
rates[pairs[i][0]] = rates[pairs[i][0]] || {}; | |
rates[pairs[i][0]][pairs[i][1]] = r; | |
} | |
return { graph: graph, rates: rates }; | |
} | |
function arbitrage(data){ | |
data.graph.root = {}; | |
for (var edge in data.graph){ | |
data.graph.root[edge] = 0.0; | |
} | |
var dist = {}; | |
var pred = {}; | |
for (var edge in data.graph){ | |
dist[edge] = Infinity; | |
} | |
dist.root = 0; | |
for (var i = Object.keys(data.graph).length; i--;){ | |
for (var edge in data.graph){ | |
for (var vertex in data.graph[edge]){ | |
if (dist[vertex] > (dist[edge] + data.graph[edge][vertex])){ | |
dist[vertex] = dist[edge] + data.graph[edge][vertex]; | |
pred[vertex] = edge; | |
} | |
} | |
} | |
} | |
var arbitrage = false; | |
var cyclic = {}; | |
for (var edge in data.graph){ | |
for (var vertex in data.graph[edge]){ | |
if (dist[vertex] > (dist[edge] + data.graph[edge][vertex])){ | |
arbitrage = true; | |
dist[vertex] = dist[edge] + data.graph[edge][vertex]; | |
cyclic[vertex] = true; | |
} | |
} | |
} | |
if (!arbitrage){ | |
console.log("No arbitrage"); | |
return []; | |
} | |
var paths = []; | |
for (var key in cyclic){ | |
var visited = {}; | |
visited[key] = true; | |
var path = []; | |
var p = key; | |
do { | |
path.push(p); | |
visited[p] = true; | |
p = pred[p]; | |
} while (p && !visited[p]); | |
path.reverse(); | |
path.push(path[0]); | |
var value = 1.0; | |
for (var n = path.length-1; n--;) | |
value = value * data.rates[path[n]][path[n+1]]; | |
paths.push([path, value]); | |
} | |
return paths.filter(function(v){ | |
return v[1]; | |
}).sort(function(a, b){ | |
return b[1] > a[1]; | |
}); | |
} | |
function print(paths){ | |
for (var i = 0, l = paths.length; i<l; i++){ | |
for (var v = 1, r = [], j = 0, m = paths[i][0].length-1; j<m; j++){ | |
console.log(v + " " + paths[i][0][j] + " -> " + paths[i][0][j+1] | |
+ " = " + (v * data.rates[paths[i][0][j]][paths[i][0][j+1]])); | |
v *= data.rates[paths[i][0][j]][paths[i][0][j+1]]; | |
} | |
if (i<l-1) console.log('-'); | |
} | |
} | |
var data; | |
var req = https.request(uri, function(res, buff){ | |
data = ""; | |
res.on('data', function(chunk){ | |
data += chunk; | |
}).on('end', function(){ | |
data = build(parse(JSON.parse(data))); | |
print(arbitrage(data)); | |
}); | |
}).on('error', console.error).end(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment