Skip to content

Instantly share code, notes, and snippets.

@waynenilsen
Last active June 30, 2017 01:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waynenilsen/051d5c0305a28aaadbfd to your computer and use it in GitHub Desktop.
Save waynenilsen/051d5c0305a28aaadbfd to your computer and use it in GitHub Desktop.
Poloniex arbitrage check
#!/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