Skip to content

Instantly share code, notes, and snippets.

@mattmcd
Created March 30, 2013 11:55
Show Gist options
  • Save mattmcd/5276441 to your computer and use it in GitHub Desktop.
Save mattmcd/5276441 to your computer and use it in GitHub Desktop.
Identifying FX Arbitrage as a linear programming problem using COIN-OR Linear Program Solver (CLP).
max D
subject to
D + DE + DP + DY - 0.8706 ED - 1.4279 PD - 0.00750 YD = 1
ED + EP + EY - 1.1486 DE - 1.6401 PE - 0.00861 YE = 0
PD + PE + PY - 0.7003 DP - 0.6097 EP - 0.00525 YP = 0
YD + YP + YE - 133.33 DY - 116.14 EY - 190.48 PY = 0
bounds
D <= 10000
end
#include <ClpSimplex.hpp>
#include <vector>
#include <iostream>
#include <string>
int main( int argc, const char *argv[])
{
ClpSimplex model;
int status;
// Read the linear program description
if (argc < 2) {
status = model.readLp( "fx_arbitrage.lp");
} else {
status = model.readLp( argv[1] );
}
if ( !status ) {
// Perform the optimization
model.primal();
}
// Print the solution
auto nCol = model.numberColumns();
auto colSolution = model.getColSolution();
for(int i=0; i<nCol; i++ ) {
std::cout << model.getColumnName(i)
<< ": " << colSolution[i] << std::endl;
}
return 0;
}
all: fx_solver
fx_solver: fx_solver.cpp
clang++ -std=c++0x -I/usr/include/coin -o fx_solver fx_solver.cpp -lClp
# Install CLP:
# sudo apt-get install coinor-libclp0 coinor-libclp-doc
### WARNING: CoinLpIO::readLp(): Maximization problem reformulated as minimization
Clp0006I 0 Obj 0 Primal inf 0.700329 (1) Dual inf 4e+10 (4)
Clp0006I 7 Obj -10000
Clp0000I Optimal - objective value -10000
D: 10000
DE: 2.04885e+07
DP: 0
DY: 0
ED: -1.64009e-12
PD: -1e-12
YD: 2.73313e+09
EP: 0
EY: 2.35331e+07
PE: 0
YE: 0
PY: 1e-12
YP: 0
@JWally
Copy link

JWally commented May 1, 2015

This is awesome!
Thanks for demo-ing this.

Quick question,
When I do this with all other currencies except for Euros, the results make sense. However, if I do Euros, I get the following:

{ 
  'DOLLARS -> EUROS': 0.8706251088281078,
  'DOLLARS -> POUNDS': 1940.846914326005,
  'POUNDS -> YEN': 1359.1750941025014,
  'YEN -> DOLLARS': 258895.67192464444
  }

Which, when I plug the information into a spreadsheet ; balances. However, the results don't make sense as its telling you to go

Dollars->Euros;
Dollars->Pounds->Yen->Dollars;

Leaving you $0.87 in Euros. Is this correct?
If so, is there a way to prevent this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment