Skip to content

Instantly share code, notes, and snippets.

@ZJONSSON
Last active May 2, 2020 00:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZJONSSON/8175832 to your computer and use it in GitHub Desktop.
Save ZJONSSON/8175832 to your computer and use it in GitHub Desktop.
Bitcoin Arbitrage (extension)
// 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);
var levels = {};
// Determine the bid/offer from input data using high/low
fx.forEach(function(A) {
levels[A] = {};
fx.forEach(function(B) {
if (A == B) return;
var first = rates[A][B],
second = 1/rates[B][A];
levels[A][B] = {
offer : Math.max(first,second),
bid : Math.min(first,second)
};
$("#prices").append('$$ '+frac(A,B)+'='+levels[A][B].bid+' / '+levels[A][B].offer+' $$');
});
});
// Go through all triangular combinations
combinations(fx,3).forEach(function(c) {
['bid','offer'].forEach(function(side) {
var result = 1,
txtFx = [],
txtPrice =[],
msg;
c.forEach(function(base,i) {
var other = c[i+1] || c[0];
var price = levels[base][other][side];
result *= price;
txtFx.push(frac(base+'^{\\text{'+side+'}}',other));
txtPrice.push(price);
});
if (side == 'bid') msg = (result < 1) ? '(result < 1 = No Arbitrage)' : '(result > 1 = Arbitrage)';
else msg = (result > 1) ? '(result > 1 = No Arbitrage)' : '(result < 1 = Arbitrage)';
$("#triangular").append('$$ '+txtFx.join(' \\cdot ')+'='+txtPrice.join(' \\cdot ')+' = '+result+' \\text{'+msg+'}$$');
});
});
}
<!DOCTYPE html>
<meta charset="utf-8">
<style>.MathJax_Display {text-align: left !important;}</style>
<body>
<h1>Bitcoin Arbitrage Exercise (extension)</h1>
This is an extension of <a href="http://bl.ocks.org/ZJONSSON/raw/8138007/">my solution</a> to the <a href="http://priceonomics.com/jobs/puzzle/">Bitcoin Arbitrage excercise</a>. For each currency pair, two prices are given (one for each currency as a base) and their inverses are given to be different. In the first solution, we assumed that both quotations could be both bought and sold, leading to a duality arbitrage (different tradable prices for the same pair) and solved for triangular arbitrage in excess of the duality arbitrages.
In this solution we assume that the two prices implicitly form a bid/offer for each currency pair. For a given base currency the offer is determined to be the higher of (A) price against another currency and (B) the inverse of the reverse price, with bid being the lower price. In this case there is no duality arbitrage and any triangular arbitrage must be higher than the bid-offer cost of the transaction.
<h2>Triangular Arbitrage</h2>
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. Here we are assuming bid/offer spreads and each triangle is checked against both sides.
<div id="triangular"></div>
<h2>Bid/Offers calculated from inputs</h2>
<div id="prices"></div>
<hr>
(c) 2013 <a href="https://github.com/zjonsson">Ziggy Jonsson</a> - Licence <a href="http://opensource.org/licenses/MIT">MIT</a> - <a href="https://gist.github.com/ZJONSSON/8138007">(source)</a>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script src="arb.js"></script>
<script src="http://query.yahooapis.com/v1/public/yql?callback=main&format=json&q=select%20*%20from%20json%20where%20url=%22http://fx.priceonomics.com/v1/rates/%22"></script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment